OpenGL 4.4变换反馈布局说明符
OpenGL 4.4 transform feedback layout specifier
我在使用OpenGL 4.4版本的转换反馈缓冲区时遇到了问题。
我使用几何着色器输出捕获和绘制三角形。
三角形将被几何着色器中的一些算法剔除,我想捕获生成的三角形。
所以结果三角形计数应该小于输入计数。
当我指定in-shader布局说明符(xfb_buffer
等)时,没有捕获原语。
我把它改回gltransformfeedbackvardings,现在原语正在被捕获,但不是每个三角形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();
GLSL几何着色器的相关部分:
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();
}
解决方案是什么?
当您指定转换反馈限定符时,xfb_buffer
需要伴随xfb_offset
。来自OpenGL Wiki:
变量可以不使用
xfb_offset
而将xfb_buffer
赋值给它们。
简而言之,将您的着色器更改为以下内容应该可以避免调用glTransformFeedbackVaryings()
:
layout(xfb_buffer = 0, xfb_offset = 0) out vec3 xPosition;
相关文章:
- 激励'inline'说明符的真实世界示例?
- 缺少类型说明符,显式类型为"缺少错误"
- 如何使用C/C++在MacOSX中获得键盘布局
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- 为什么mpfr_printf与十六进制浮点(%a转换说明符)的printf不同
- 布局兼容类型的并集
- Qt自定义QPush按钮未显示在布局上
- 叮叮当当在修复时插入多个"覆盖"说明符
- 编译器错误:destuctor 的更宽松的抛出说明符
- 使用说明符 extern 声明的C++中的标识符链接
- 同时具有"外部"和"内联"说明符的变量
- 与 tesseract::TessBaseApi() 相关的 Tesseract-OCR 出错(预期的类型说明符)
- 按钮悬停在 QT 中垂直布局的选项卡小部件中不起作用
- 错误:不能使用"显式"说明符声明 bool'
- 调整布局上的 QGraphicsView 小部件的大小
- 基于范围的 for 循环range_declaration中各种说明符之间的性能差异
- 为什么转换函数声明不需要至少一个定义类型说明符
- 为什么C 标准专门为具有不同访问说明符的类数据成员的内存布局提供了余地
- 成员函数的附加语法/说明符如何影响类中的内存布局?
- OpenGL 4.4变换反馈布局说明符