Uso i thread win32 con OpenGL 2.1. Quello che sto cercando di ottenere è di rendere l'immagine semplice che dice "caricamento", mentre sullo sfondo viene caricata tutta la scena 3D. Funziona ora, ma ho un problema, dove a volte una parte della mia trama cubemap prende dati da Mozilla Firefox Browser (Come diavolo succede? ???) e ignori quella piccola scatola, con texture, è solo uno sprite e è dove dovrebbe essere .: Caricamento risorse OpenGL sul secondo thread
Questo accade come 1 su 3 volte provo a caricare il mio programma. Ecco come il mio filo appare:
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:
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();
}
}
}
Io uso Nvidia 670GTX con gli ultimi driver su Winodws 8. Tutte le idee in cui il problema potrebbe essere?
[EDIT] Ho aggiunto glFinish() alla fine della mia discussione del caricatore, e ora tutto si carica normalmente. Sono rosso da qualche parte, che OpenGL non finisce immediatamente tutto il suo lavoro, quindi credo che questo fosse il caso, dove il contesto era impostato su NULL prima che potesse finire il suo lavoro.
prendere nota che opengl e thread di solito non vanno avanti –
Sì, ho molto rosso su questo. In effetti, avevo implementato due contesti prima, su uno dei rendering, sull'altro ho caricato le risorse e quando le risorse sono state caricate ho appena preso quel contesto e ne ho fatto il contesto principale, eliminando l'ultimo contesto principale. Questo ha funzionato senza problemi. – SMart
@ BЈовић: OpenGL e multithreading possono essere eseguiti, non è semplice per ottenere il diritto. – datenwolf