尝试使用 C++/OpenGL 实现 VAO 的基本示例,我遇到了一个特殊的问题,在搜索了一段时间后我还没有找到解决方案。我的程序应该将纹理(CT 图像)渲染为正方形,然后在顶部绘制多边形(使用 GL_LINE_LOOP)以勾勒出特定器官的轮廓。首先,我在初始化时为 CT 图像创建一个 VAO:
// Generates textures for CT images
void TxPlanSys::InitSimCT(SimulationCT &S){
GLuint VBO[2];
GLfloat Vertices[] = {
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f
};
GLfloat UvData[] = {
0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f
};
for(int i = 0; i < 6; i++){
Vertices[3*i] *= (S.Ny*S.dy);
Vertices[3*i+1] *= (S.Nz*S.dz);
}
// Vertex array object for image surface
glGenVertexArrays(1,&SimCtVaoID);
glBindVertexArray(SimCtVaoID);
glGenBuffers(2,VBO);
// Vertex buffer
glBindBuffer(GL_ARRAY_BUFFER,VBO[0]);
glBufferData(GL_ARRAY_BUFFER,sizeof(Vertices),Vertices,GL_STATIC_DRAW);
GLuint VertexAttributeID = 0;
glVertexAttribPointer(VertexAttributeID,3,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(VertexAttributeID);
// UV buffer
glBindBuffer(GL_ARRAY_BUFFER,VBO[1]);
glBufferData(GL_ARRAY_BUFFER,sizeof(UvData),UvData,GL_STATIC_DRAW);
GLuint UvAttributeID = 1;
glVertexAttribPointer(UvAttributeID,2,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(UvAttributeID);
// Unbind and clean up
glBindVertexArray(0);
glDeleteBuffers(2,VBO);
// Initialize textures for CT images
glGenTextures(S.Nx,&CtTextureID);
for(int n = 0; n < S.Nx; n++){
CurrentSlice = n;
MakeImage(S);
glBindTexture(GL_TEXTURE_2D,CtTextureID+n);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,S.Ny,S.Nz,0,GL_RGB,GL_UNSIGNED_BYTE,MainImage);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
}
CurrentSlice = 0;
}
接下来,我在初始化时为特定轮廓集创建一个 VAO:
void TxPlanSys::InitContour(Structure * S){
GLuint ContourVertexBuffer, ColorBuffer;
float buffer[(const int)(S->PointIndex*3)];
glGenVertexArrays(1,&ContourVaoID);
glBindVertexArray(ContourVaoID);
// Vertex buffer
glGenBuffers(1,&ContourVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER,ContourVertexBuffer);
for(int i = 0; i < S->PointIndex; i++){
buffer[3*i+2] = 0.0;
buffer[3*i] = S->SurfacePoints[3*i+1];
buffer[3*i+1] = S->SurfacePoints[3*i+2];
}
glBufferData(GL_ARRAY_BUFFER,sizeof(buffer),buffer,GL_STATIC_DRAW);
GLuint VertexAttributeID = 0;
glVertexAttribPointer(VertexAttributeID,3,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(VertexAttributeID);
// Unbind and clean up
glBindVertexArray(0);
glDeleteBuffers(1,&ContourVertexBuffer);
}
这就是事情变得不稳定的地方。我的渲染代码如下:
static void MainDisplay(){
// Clear window to black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Model-View-Projection matrix
glm::mat4 Projection = glm::perspective((3.1415f*30.0f/180.0f), MyToolkit.AspectRatio, 0.1f, 120.0f);
glm::mat4 View = glm::lookAt(
glm::vec3(MyToolkit.CameraPos[0],MyToolkit.CameraPos[1],MyToolkit.CameraPos[2]),
glm::vec3(MyToolkit.CameraPos[0],MyToolkit.CameraPos[1],0),
glm::vec3(0,1,0)
);
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 MVP = Projection * View * Model;
// Set shader & send MVP matrix to shader
glUseProgram(TPS.ImageShaderID);
glUniformMatrix4fv(TPS.ImageMvpID, 1, GL_FALSE, &MVP[0][0]);
// Draw square for image panel
glBindVertexArray(TPS.SimCtVaoID);
glBindTexture(GL_TEXTURE_2D,TPS.CtTextureID+TPS.CurrentSlice);
glDrawArrays(GL_TRIANGLES,0,6);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
glUseProgram(0);
// Set shader & send MVP matrix to shader
glUseProgram(TPS.ContourShaderID);
glUniformMatrix4fv(TPS.ContourMvpID, 1, GL_FALSE, &MVP[0][0]);
// Draw contours
glBindVertexArray(TPS.ContourVaoID);
glPointSize(3.0);
glDrawArrays(GL_POINTS,0,9);
glDrawArrays(GL_LINE_LOOP,0,9);
// Swap buffers to render
glutSwapBuffers();
}
当我只注释掉轮廓的 glDraw 命令时,CT 图像绘制得很好。同样,当我仅注释掉 CT 图像的 glDraw 命令时,轮廓绘制得很好。但是,当我尝试在同一个函数调用中渲染它们时,轮廓 VAO 会从 CT 图像 VAO 中抓取顶点缓冲区并进行渲染。
我希望我可以插入图片,但我的代表。还不够高……
在查看了几个地方并阅读了 VAO 之后,我很困惑。任何帮助将不胜感激。这是我的比赛。信息:Ubuntu 14.04,Intel i5 CPU,ATI Radeon 显卡,运行 OpenGL 4.3。谢谢!