2013-02-14 22 views
6

OpenGL 2.1 ile win32 konuları kullanıyorum. Gerçekleştirmeye çalıştığım şey, arka plan bütün 3D sahnesinin yüklenirken, basit bir şekilde "yükleme" deyip gösterilmesini sağlamaktır. Şimdi çalışıyor, ama bazen bir sorunum var, bazen benim cubemap dokumun bir kısmı Mozilla Firefox Tarayıcısından veri alıyor (Bu nasıl oluyor cehennemde oluyor ???) ve bu küçük kutuyu dokuyla görmezden geliyor, sadece bir sprite ve o .: enter image description hereOpenGL kaynak ikinci bağlantıda yükleniyor

Bu benim programı yüklemeye çalıştığınızda 1 kez 3 gibi olur olması gereken yerde öyle. Bu benim iplik görünür:

WindowsThread::WindowsThread(HGLRC graphicsContext, HDC deviceContext) : 
    graphicsContext_(graphicsContext), 
    deviceContext_(deviceContext), 
    running_(false), 
    task_(0), 
    mode_(WT_NORMAL) 
{ 
    handle_ = CreateThread(0, 0, 
     (unsigned long (__stdcall *)(void *)) this->staticRun, 
     (void*) this, CREATE_SUSPENDED, &id_); 

    if (handle_ == 0) { 
     LOGE("Unable to create thread."); 
     return; 
    } 

    if (!SetThreadPriority(handle_, THREAD_PRIORITY_NORMAL)) { 
     LOGE("Unable to set thread priority for thread."); 
     return; 
    } 
} 

WindowsThread::~WindowsThread() { 
    finishTask(); 
    running_ = false; 
    WaitForSingleObject(handle_, INFINITE); 
    CloseHandle(handle_); 
    wglDeleteContext(graphicsContext_); 
} 

void WindowsThread::start() { 
    running_ = true; 
    if (!ResumeThread(handle_)) { 
     LOGW("Unable to resume thread."); 
    } 
} 

bool WindowsThread::isRunning() { 
    return running_; 
} 

void WindowsThread::setTask(Task* task, Mode mode) { 
    finishTask(); 
    task_ = task; 
    mode_ = mode; 
} 

bool WindowsThread::hasTask() { 
    return task_ != 0; 
} 

void WindowsThread::finishTask() { 
    while (task_ != 0) { 
     Sleep(1); 
    } 
} 

void WindowsThread::stop() { 
    running_ = false; 
} 

int WindowsThread::staticRun(void* thread) { 
    return ((WindowsThread*) thread)->run(); 
} 

int WindowsThread::run() { 
    wglMakeCurrent(deviceContext_, graphicsContext_); 
    while (running_) { 
     if (task_ != 0) { 
      task_->run(); 
      task_ = 0; 
     } 
     Sleep(10); 
    } 
    wglMakeCurrent(0, 0); 
    return 1; 
} 

ThreadManager: Sorun nerede olabilir

WindowsThreadManager::WindowsThreadManager(
    System* system, UINT threadPoolSize) 
{ 
    if (threadPoolSize == 0) { 
     SYSTEM_INFO info; 
     GetSystemInfo(&info); 
     threadPoolSize = info.dwNumberOfProcessors; 
     if (threadPoolSize == 0) { 
      threadPoolSize = 1; 
     } 
    } 
    LOGI("Number of threads used: %d", threadPoolSize); 
    masterContext_ = wglGetCurrentContext(); 
    HDC hdc = wglGetCurrentDC(); 
    for (UINT i = 0; i < threadPoolSize; i++) { 
     HGLRC threadContext = wglCreateContext(hdc); 
     wglShareLists(masterContext_, threadContext); 
     WindowsThread* thread = new WindowsThread(threadContext, hdc); 
     thread->start(); 
     threads_.push_back(thread); 
    } 
} 

WindowsThreadManager::~WindowsThreadManager() { 
    for (UINT i = 0; i < threads_.size(); i++) { 
     delete threads_[i]; 
    } 
    for (UINT i = 0; i < tasks_.size(); i++) { 
     delete tasks_[i]; 
    } 
} 

void WindowsThreadManager::execute(Task* task, Mode mode) { 
    WindowsThread::Mode wtMode = WindowsThread::WT_NORMAL; 
    if (mode == TM_GRAPHICS_CONTEXT) { 
     wtMode = WindowsThread::WT_GRPAHICS_CONTEXT; 
    } 
    tasks_.push_back(task); 
    for (UINT i = 0; i < threads_.size(); i++) { 
     if (!threads_[i]->hasTask()) { 
      threads_[i]->setTask(task, wtMode); 
      return; 
     } 
    } 
    threads_[0]->setTask(task, wtMode); 
} 

void WindowsThreadManager::joinAll() { 
    for (UINT i = 0; i < threads_.size(); i++) { 
     if (threads_[i]->hasTask()) { 
      threads_[i]->finishTask(); 
     } 
    } 
} 

Ben Winodws 8. Herhangi Fikirler son sürücülü Nvidia 670GTX kullanılır?

[EDIT] Yükleyici dizimin sonunda glFinish() ekledim ve şimdi her şey normal olarak yükleniyor. Bir yer kırmızı, OpenGL hemen tüm çalışmalarını tamamlamıyor, bu yüzden sanırım işin bitmesi için bağlamın NULL olarak ayarlandığı durum buydu.

+1

opengl ve threadların genellikle –

+0

boyunca gitmediğine dikkat edin Evet, bu konuda oldukça fazla kırmızıyım. Aslına bakılırsa, önce bir tanesine, kaynak yüklediğime ve kaynak yüklendikten sonra iki bağlamı uygulamaya koymuştum. Bu bağlamı aldım ve temel bağlamı silerken ana çerçeveyi oluşturdum. Bu hiç sorun olmadan çalıştı. – SMart

+0

@ BЈовић: OpenGL ve çoklu iş parçacığı yapılabilir, doğru olması basit değildir. – datenwolf

cevap

7

Şimdi çalışır, ancak ben

Sizin doku (cehennemde yapar Bu nasıl ??? olur) bazen cubemap doku parçası Mozilla Firefox Tarayıcı verileri alan bir sorunu var daha önce bellek bölgesini kullanan başka bir işlemden kalan görüntüler içeren büyük olasılıkla başlatılmamış grafik belleğinden veri alır. Bu gibi şeyler meydana gelebilir eğer

a) sürücü bir hata vardır ve bağlı iken, bir dokusunu değiştirmek için çalışıyorsanız parçacığı

ve

b) arasında kaynak senkronize etmez diğer iş parçacığı bir doku birimine.

EDIT: Doğru senkronizasyonu kendiniz yapabilirsiniz (ve yapmalısınız). Basitçe performansı artırdığı için. Doku şu anda meşgul olmadığında, iş parçacıkları arasında iletişim kurmak için condition variables kullanın. İdeal olarak iki veya daha fazla doku kullanırsınız, yuvarlak bir robin tarzında güncelleştirirsiniz.

+0

Cevabınız, gerçekten bir sorun bulmama yardımcı oldu, teşekkürler ^^ – SMart

+0

@SMGhost: Lütfen ayrıca düzenleme eklediğimi de görün. – datenwolf

+0

Doğru bir şekilde anladım, yalnızca bir bağlam kullanmayı ve kullandığım tüm parçaları senkronize etmeyi öneriyorsunuz, böylece herhangi bir yarış durumu olmayacak mı? Ya da çoklu bağlamları kullanarak, ama yine de kendimi senkronize ediyorum, bu yüzden opengl sürücüsü yapmak zorunda kalmayacak mıydı? – SMart