2012-03-04 5 views
0

У меня проблема OpenGL VBO. Я загрузил старый пример VBO под названием Lesson45 от NeHe, и я изменил его, чтобы что-то проверить.OpenGL VBO не обновляется должным образом

Мой конечный результат - создать около 9 плиток, один из которых является источником. Затем, когда игрок перемещается по экрану, верхние/нижние строки/столбцы обновляют данные. Но на данный момент я хочу что-то основное:

Я создаю один VBO, а затем я хочу обновить данные в другом потоке. Пока данные загружаются, я не хочу рисовать VBO, потому что это вызовет проблемы.

Здесь я создаю VBO:

glGenBuffersARB(1, &m_nVBOVertices); 
glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOVertices); 
glBufferDataARB(GL_ARRAY_BUFFER_ARB, m_nVertexCount*3*sizeof(float), m_pVertices, GL_DYNAMIC_DRAW_ARB); 

создать нить, я создал контекст OpenGL, делюсь списки. Затем я обрабатываю данные, когда пользователь нажимает «R» на клавиатуре:

while(TerrainThreadRun) 
    { 
     //look for R 
     if(window.keys->keyDown[82] == TRUE && keyactivated == false) 
     { 
      keyactivated = true; 
      window.keys->keyDown[82] = FALSE; 
     } 

     if(keyactivated) 
     { 
      for(int i = 0; i < g_pMesh->m_nVertexCount; i++) 
      { 
       g_pMesh->m_pVertices[i].y = 800.0f; 
      } 
      while(!wglMakeCurrent(window.hDCThread,window.hRCThread))//This was removed 
       Sleep(5);//This was removed 
      glBindBufferARB(GL_ARRAY_BUFFER_ARB, g_pMesh->m_nVBOVertices);  
      glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, g_pMesh->m_nVertexCount*3*sizeof(float), g_pMesh->m_pVertices); 
      keyactivated = false; 
     } 
    } 

Чтобы привлечь данные:

if(!keyactivated) 
{ 
    glEnableClientState(GL_VERTEX_ARRAY); 

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, g_pMesh->m_nVBOVertices); 
    glVertexPointer(3, GL_FLOAT, 0, (char*)NULL); 


    glDrawArrays(GL_TRIANGLES, 0, g_pMesh->m_nVertexCount); 

    glDisableClientState(GL_VERTEX_ARRAY); 
} 

Я знаю, что с помощью расширений ARB не рекомендуется, но это просто для быстрого базового примера.

Проблема в том, что при первом нажатии «R» данные не обновляются. VBO рисует то же самое. Во второй раз, когда я нажимаю «R», он обновляет данные. Что я могу сделать, чтобы заставить ничью. Я делаю что-то неправильно?

Должны ли данные вынуждаться к видеокарте? Я что-то упускаю?

Обновление: я просмотрел свой код, и теперь я использую wglMakeCurrent только один раз, когда контекст инициализируется. В потоке, я использую его после обмена списками и на главном потоке, как списки являются общими, например:

window->hRC = wglCreateContext (window->hDC); 
if (window->hRC ==0) 
{ 
    // Failed 
} 

TerrainThreadRun = true; 
TerrainThread = CreateThread(NULL, NULL,(LPTHREAD_START_ROUTINE)TerrainThreadProc, 0, NULL, NULL); 

while(!sharedContext) 
    Sleep(100); 

if (wglMakeCurrent (window->hDC, window->hRC) == FALSE) 

А в теме:

if (!(window.hRCThread=wglCreateContext(window.hDCThread))) 
    { 
//Error 
    } 

while(wglShareLists(window.hRC, window.hRCThread) == 0) 
{ 
    DWORD err = GetLastError(); 
    Sleep(5); 
} 
sharedContext = true; 
int cnt = 0; 

while(!wglMakeCurrent(window.hDCThread,window.hRCThread)) 
    Sleep(5); 
while(TerrainThreadRun) 
{ 
    //look for R 

Второе обновление: Я пробовал использовать glMapBuffer вместо glBuferSubData, но приложение ведет себя одинаково. Вот код:

 void *ptr = (void*)glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_READ_WRITE_ARB); 
     if(ptr) 
     { 
      memcpy(ptr, g_pMesh->m_pVertices, g_pMesh->m_nVertexCount*3*sizeof(float)); 
      glUnmapMapBuffer(GL_ARRAY_BUFFER_ARB); 
     } 

Update три:

я делал некоторые вещи неправильно, поэтому я изменил их, но проблема остается той же. Вот как я делаю все сейчас:

Когда приложение загружается, я создаю два окна, каждый со своим HWND. Основываясь на них, я создаю два контекста устройства.

Тогда я разделяю списки между ними:

wglShareLists(window.hRC, window.hRCThread); 

Это делается только один раз, когда я инициализации. После этого я показываю окно OGL, которое отображает; Я делаю контекст активным. Затем я загружаю указатели на функции и создаю VBO. После выполнения основного рендеринга OGL я создаю поток. Когда поток загружен, я делаю его контекст устройства активным.

Затем мы делаем обычный материал.

Итак, мой вопрос: мне нужно обновить указатели на функции для каждого контекста устройства? Может ли это быть моей проблемой?

Как обновление, если я запускаю тестовое приложение в gDEBugger, и сначала я нажимаю «R», а затем останавливаюсь, он отображается неправильно. Я смотрю на память (текстуры, буферы и средства просмотра изображений) и контекст устройства GLContext1 (я думаю, основной поток рендеринга) имеет OLD-данные. Хотя GLContext2 (Shared-GL1) (я думаю, что контекст потока) имеет правильные данные.

Нечетная часть, если я оглядываюсь назад на GLContext1, когда программа все еще находится в режиме паузы, теперь она отображает новые данные, как будто она «обновила» ее каким-то образом. И затем, если я нажму на игру, он начнет правильно рисовать.

ответ

0

Я нашел решение, мне нужно позвонить glFinish() в рабочий поток после звонка glUnmapBuffer. Это решит проблему, и все будет прекрасно.

Смежные вопросы