2014-02-11 42 views
2

我使用兩個呈現程序將兩個不同的對象呈現在屏幕上。每個程序都有它自己的頂點和片段着色器。opengl着色器程序中的重複頂點

在下面的代碼,我創建了第一個渲染程序並使用GL_ARRAY_BUFFER到頂點加載到着色器:

boardRenderingProgram = compileBoardShaders(); 

vector<GLfloat> boardVertices = board.getBorderVertices(); 
GLfloat* borderVertices = &boardVertices[0]; 

GLuint numberOfVerts = boardVertices.size(); 

GLuint anotherVBO; 
GLuint anotherBuffer; 

glGenVertexArrays(1, &anotherVBO); 
glBindVertexArray(anotherVBO); 
glGenBuffers(1, &anotherBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, anotherBuffer); 

glBufferData(GL_ARRAY_BUFFER, numberOfVerts*3*sizeof(GLfloat), NULL, GL_STATIC_DRAW); 
glBufferSubData(GL_ARRAY_BUFFER, 0, numberOfVerts*3*sizeof(GLfloat), borderVertices); 

vert = glGetAttribLocation(boardRenderingProgram, "vBoardPosition"); 
glVertexAttribPointer(vert, 3, GL_FLOAT, GL_FALSE, 0, 0); 

glEnableVertexAttribArray(vert); 

頂點着色器的第一個程序:

#version 330 core       
layout(location = 0) in vec4 vBoardPosition;  

void main() {        
    gl_Position = vBoardPosition;    
}           

然後我做對於第二個渲染程序完全一樣,我也在第二個程序中設置旋轉和平移矩陣:

renderingProgram = compileShaders(); 

moveMatrix = glm::make_mat4(moveArray); 

currentBlockVertices = generator.getRandomBlock(blockNumber).getVertices(); 

numberOfVertices = 8; 

GLfloat* vertices = &currentBlockVertices[0]; 

glGenVertexArrays(1, &vertexArrayObject); 
glBindVertexArray(vertexArrayObject); 
glGenBuffers(1, &buffer); 
glBindBuffer(GL_ARRAY_BUFFER, buffer); 

glBufferData(GL_ARRAY_BUFFER, numberOfVertices*7*sizeof(GLfloat), NULL, GL_STATIC_DRAW); 

glBufferSubData(GL_ARRAY_BUFFER, 0, numberOfVertices*3*sizeof(GLfloat), vertices); 


vpos = glGetAttribLocation(renderingProgram, "vPosition"); 
glVertexAttribPointer(vpos, 3, GL_FLOAT, GL_FALSE, 0, 0); 

mpos = glGetUniformLocation(renderingProgram, "mMove"); 
rpos = glGetUniformLocation(renderingProgram, "mRotate"); 

glProgramUniformMatrix4fv(renderingProgram, mpos, 1, GL_FALSE, glm::value_ptr(moveMatrix)); 
glProgramUniformMatrix4fv(renderingProgram, rpos, 1, GL_FALSE, glm::value_ptr(rotateMatrix)); 

glEnableVertexAttribArray(vpos); 

頂點着色器的第二個方案:

#version 330 core       
layout(location = 0) in vec4 vPosition; 
layout(location = 1) uniform mat4 mMove;  
layout(location = 2) uniform mat4 mRotate; 

void main() {        
    gl_Position = mMove * mRotate * vPosition;  
}           

一旦這些程序創建我用下面的代碼在我的渲染功能,以吸引他們到屏幕上:

glUseProgram(boardRenderingProgram); 
glDrawArrays(GL_POINTS, 0, 8); 

glUseProgram(renderingProgram); 
glDrawArrays(GL_LINE_LOOP, 0, 8); 
SwapBuffers(hDC_); 

然而,儘管指定不同的頂點加載到每個渲染程序中,兩個渲染程序都將相同的頂點繪製到屏幕上。它似乎也是第二個創建的渲染程序決定使用哪個頂點。

我曾嘗試在設置頂點和矩陣屬性之前和之後添加額外的glUseProgram()調用,但這似乎沒有幫助。

爲什麼當我將不同的頂點加載到每個頂點時,這兩個程序繪製相同的頂點?

+0

'compileBoardShaders()'和'compileShaders()'在哪裏? – genpfault

+0

@genpfault我在代碼的其他地方聲明瞭compileShaders()和compileBoardShaders()。我在兩種着色器編譯和程序鏈接方法中都進行了調試,但都沒有失敗。我認爲,因爲我看到兩個程序都在頂點畫在屏幕上,所以這些方法沒有錯。如果它有幫助,我可以發佈兩者的代碼。 –

回答

0

好的,經過進一步的調查後,我發現加載第二個着色器時清除頂點的行是glBindVertexArray()。

繼從這裏建議: https://gamedev.stackexchange.com/questions/49749/why-doesnt-glbindvertexarray-work-in-this-case我改變了我的渲染代碼每次繪製調用之前添加glBindVertexArray():

glBindVertexArray(boardVertexArrayObject); 
glUseProgram(boardRenderingProgram); 
glDrawArrays(GL_LINES, 0, 6); 

glBindVertexArray(pieceVertexArrayObject); 
glUseProgram(renderingProgram); 
glDrawArrays(GL_LINE_LOOP, 0, 8); 
SwapBuffers(hDC_); 

顯然glBindVertexArray()應修改VBO之前和繪圖之前調用。現在代碼正常工作!

+0

'glBindVertexArray()'指定您正在使用的一個頂點緩衝區。無論什麼樣的操作。它是一臺狀態機,所以沒有什麼變化,除非你告訴它。 – Kaliber64

2
#version 330 core 
... 
layout(location = 1) uniform mat4 mMove;  
layout(location = 2) uniform mat4 mRotate; 
^^^^^^^^^^^^^^^^^^^^ 

Explicit uniform locations自OpenGL 4.3以來一直是核心。您需要在之前版本的using them之前檢查GL_ARB_explicit_uniform_location

我懷疑你的第二個着色器未能編譯。在致電glUseProgram()之前,請務必通過GL_COMPILE_STATUS/GL_LINK_STATUS檢查着色器編譯和程序鏈接是否成功。

+1

我已經將GL_COMPILE_STATUS和GL_LINK_STATUS檢查添加到了compileShaders()和compileBoardShaders(),並且好像兩個頂點着色器都正在編譯和鏈接成功。 –