我有OpenGL VBO問題。我從NeHe下載了一個名爲Lesson45的舊VBO例子,我修改了它來檢查一些東西。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);
}
更新三:
我做事情有些不對,所以我修改了他們,但問題依舊。以下是我現在如何做的一切:
當應用程序加載時,我創建了兩個窗口,每個窗口都有自己的HWND。基於它們,我創建了兩個設備上下文。
然後我分享他們之間的名單:
wglShareLists(window.hRC, window.hRCThread);
當我初始化這樣做的只有一次。 之後,我顯示OGL窗口,該窗口呈現;我使上下文處於活動狀態。然後我加載函數指針並創建VBO。 完成主渲染OGL後,我創建了線程。當線程加載時,我使其設備上下文處於活動狀態。
然後我們做普通的東西。
所以我的問題是:我是否需要更新每個設備上下文的函數指針?這可能是我的問題嗎?
作爲更新,如果我在gDEBugger中運行我的測試應用程序,並且首先按「R」,然後暫停,它將無法正確顯示。我看看內存(紋理,緩衝區和圖像查看器)和GLContext1(我認爲主要渲染線程)設備上下文具有舊數據。雖然GLContext2(Shared-GL1)(我認爲線程上下文)具有正確的數據。
奇怪的是,如果我回頭看看GLContext1,程序仍處於暫停模式,現在它顯示新數據,就像它以某種方式「刷新」它。然後如果我按播放,它開始正確繪製。