我在使用带有OpenGL version 4.4.
的转换反馈缓冲区时遇到问题
我正在使用几何着色器输出来捕获和绘制三角形。
三角形将被几何着色器中的某些算法剔除,我想捕获生成的三角形。
因此,结果三角形计数应小于输入计数。
当我指定着色器内布局说明符(xfb_buffer
等)时,不会捕获基元。
我将其更改回glTransformFeedbackVaryings,现在正在捕获基元,但不是每个三角形的3个顶点(9个浮点数),因为结果缓冲区的大小不能被3分割,所以捕获的数量会减少。
// ---------------
// VERTEX BUFFER
// ---------------
glGenBuffers(1, &vertexBufferObjectId_);
// Init vertex data
unsigned int numVerts = width * height;
size_t vertexSize = (3 + 2) * sizeof(GLfloat); // position, texcoord
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId_);
glBufferData(GL_ARRAY_BUFFER, numVerts * vertexSize, 0, GL_STATIC_DRAW);
uint8_t* vertices = (uint8_t*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
for (unsigned int y = 0; y < height; ++y)
{
for (unsigned int x = 0; x < width; ++x)
{
*(float*)(vertices+0) = x; // x
*(float*)(vertices+4) = y; // y
*(float*)(vertices+8) = 0; // z
*(float*)(vertices+12) = (float)x / (width - 1); // u
*(float*)(vertices+16) = (float)y / (height - 1); // v
vertices += vertexSize;
}
}
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// ---------------
// INDEX BUFFER
// ---------------
glGenBuffers(1, &indexBufferObjectId_);
glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(-1); // accepts GLuint, so this will be the largest possible value
// Init index data
unsigned int numPolys = 2 * (width - 1) * (height - 1) * 2;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObjectId_);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numPolys * 3 * sizeof(GLuint), 0, GL_STATIC_DRAW);
GLuint* indices = (GLuint*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
for (unsigned int y = 0; y < height-1; ++y)
{
for (unsigned int x = 0; x < width-1; ++x)
{
// i11 is at (x,y)
// i20
// i11 i21 i31
// i02 i12 i22
// i13
uint32_t i20 = get_index(width,height,x+1,y-1);
uint32_t i11 = get_index(width,height,x,y);
uint32_t i21 = get_index(width,height,x+1,y);
uint32_t i31 = get_index(width,height,x+2,y);
uint32_t i02 = get_index(width,height,x-1,y+1);
uint32_t i12 = get_index(width,height,x,y+1);
uint32_t i22 = get_index(width,height,x+1,y+1);
uint32_t i13 = get_index(width,height,x,y+2);
// first triangle: i12,i22,i21
// i21
// i12 i22
// with adjacency: i12,i13,i22,i31,i21,i11
// i11 i21 i31
// i12 i22
// i13
*(indices++) = i12;
*(indices++) = i13;
*(indices++) = i22;
*(indices++) = i31;
*(indices++) = i21;
*(indices++) = i11;
// second triangle: i12,i21,i11
// i11 i21
// i12
// with adjacency: i12,i22,i21,i20,i11,i02
// i20
// i11 i21
// i02 i12 i22
*(indices++) = i12;
*(indices++) = i22;
*(indices++) = i21;
*(indices++) = i20;
*(indices++) = i11;
*(indices++) = i02;
}
}
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// ---------------
// TRANSFORM FEEDBACK BUFFER
// ---------------
if (feedbackVertexBufferObjectId_)
glDeleteBuffers(1, &feedbackVertexBufferObjectId_);
glGenBuffers(1, &feedbackVertexBufferObjectId_);
glBindBuffer(GL_ARRAY_BUFFER, feedbackVertexBufferObjectId_);
glBufferData(GL_ARRAY_BUFFER, numPolys * 3 * 3 * sizeof(GLfloat), 0, GL_STREAM_READ);
meshRenderShader_.enable();
// Set to write to the framebuffer.
glBindFramebuffer(GL_FRAMEBUFFER, camData.framebuffer_.framebufferId_);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// ----------------------------------
// Render projected mesh
// Binding vertex buffer
size_t vertexSize = (3 + 2) * sizeof(GLfloat);
glBindBuffer(GL_ARRAY_BUFFER, camData.mesh_.vertexBufferObjectId_);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)(sizeof(GLfloat) * 3));
// Binding index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, camData.mesh_.indexBufferObjectId_);
// Bind transform feedback and target buffer
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, camData.mesh_.feedbackVertexBufferObjectId_);
GLuint query;
glGenQueries(1, &query);
// glEnable(GL_RASTERIZER_DISCARD);
// Begin transform feedback
glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
glBeginTransformFeedback(GL_TRIANGLES);
// Set shader uniforms
meshRenderShader_.setUniformMat4("ModelViewProjection", (viewProjMatrix * camData.transform_).data());
// Binding texture
meshRenderShader_.setUniformTexture("colorTexture", camData.mesh_.textureId_, 0);
meshRenderShader_.setUniformTexture("depthTexture", camData.mesh_.depthTextureId_, 1);
meshRenderShader_.setUniform2f("depthSize", camData.intrinsic_.width, camData.intrinsic_.height);
meshRenderShader_.setUniform2f("intrinsic_f", camData.intrinsic_.fx, camData.intrinsic_.fy);
meshRenderShader_.setUniform2f("intrinsic_c", camData.intrinsic_.cx, camData.intrinsic_.cy);
// Drawing elements to textures
glDrawElements(GL_TRIANGLES_ADJACENCY, camData.mesh_.numPolys_ * 3, GL_UNSIGNED_INT, (const GLvoid*) 0);
// End transform feedback
glEndTransformFeedback();
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
// glDisable(GL_RASTERIZER_DISCARD);
// glFlush();
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &camData.mesh_.primitivesWritten_);
// glDrawTransformFeedback(GL_TRIANGLES_ADJACENCY, camData.mesh_.feedbackbufferId_);
glDeleteQueries(1, &query);
// Unbinding buffers
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER,0);
// Disable shader
meshRenderShader_.disable();
layout(xfb_buffer = 0) out vec3 xPosition;
if (cull)
{
gl_Position = ModelViewProjection * gl_in[0].gl_Position;
fTexCoord = gTexCoord[0];
xPosition = gl_Position.xyz;
EmitVertex();
gl_Position = ModelViewProjection * gl_in[2].gl_Position;
fTexCoord = gTexCoord[2];
xPosition = gl_Position.xyz;
EmitVertex();
gl_Position = ModelViewProjection * gl_in[4].gl_Position;
fTexCoord = gTexCoord[4];
xPosition = gl_Position.xyz;
EmitVertex();
EndPrimitive();
}
可以解决什么问题?