У меня проблема 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, когда программа все еще находится в режиме паузы, теперь она отображает новые данные, как будто она «обновила» ее каким-то образом. И затем, если я нажму на игру, он начнет правильно рисовать.