OpenGL Transform Feedback
官网链接
使用TransFrom Feedback捕获图元数据,必须注意的几点:
必须在链接着色器之前设置要捕获的输出变量:glTransformFeedbackVaryings
顶点着色器、细分着色器、几何着色器的输出变量都可以被捕获,但只有最后一个顶点处理着色器的输出能被捕获。
开始捕获时捕获类型的设置:glBeginTransformFeedback
If a Geometry Shader is active, then it is the primitive type output by the GS.
当有几何着色器时,捕获类型是几何着色器的输出
If a Tessellation Evaluation Shader is active, then it is the primitive type generated by the tessellation process.
当有细分着色器时,捕获类型由细分着色器产生。
If neither of those are available, then it is the mode parameter of the command used to render.
没有几何着色器和细分着色器时,捕获类型就是渲染命令使用的类型。捕获的是图元数据,图元的顶点数据会自动排好序,可以直接用于Feedback rendering
GL_TRANSFORM_FEEDBACK_BUFFER 的绑定:
glBindBuffer并不会影响transform feedback的状态,必须要由glBindBufferBase或者glBindBufferRange进行绑定。由于影响的是 transform beedback的状态,所以绑定buffer之前,要先绑定transform feedback object。
The GL_TRANSFORM_FEEDBACK_BUFFER buffer binding point may be passed to glBindBuffer,but will not directly
affect transform feedback state. Instead, the indexed GL_TRANSFORM_FEEDBACK_BUFFER bindings must be used
through a call to glBindBufferBase or glBindBufferRange. This will affect the generic GL_TRANSFORM_FEEDBACK_BUFFER binding.
程序示例:
顶点着色器:
#version 440 corelayout(location = 0) in vec4 VsInPos;
layout(location = 1) in vec4 VsInColor;out vec4 color;void main()
{gl_Position = VsInPos;color = VsInColor;
}
细分控制着色器:
#version 440 corelayout(vertices = 3) out;in vec4 color[];out vec4 TCcolor[];void main()
{gl_TessLevelInner[0] = 2.0;gl_TessLevelOuter[0] = 2.0;gl_TessLevelOuter[1] = 2.0;gl_TessLevelOuter[2] = 2.0;gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;TCcolor[gl_InvocationID] = color[gl_InvocationID];
}
细分计算着色器:
#version 440 corelayout(triangles, equal_spacing, cw) in;layout (binding = 0, offset = 0) uniform atomic_uint TessCoord;in vec4 TCcolor[];flat out vec4 color;void main()
{atomicCounterIncrement(TessCoord);float u = gl_TessCoord.x;float v = gl_TessCoord.y;float w = gl_TessCoord.z;gl_Position = u * gl_in[0].gl_Position + v * gl_in[1].gl_Position + w * gl_in[2].gl_Position; color = TCcolor[0]*u + TCcolor[1]*v + TCcolor[2]*w;
}
片段着色器:
#version 440 coreout vec4 FragColor;flat in vec4 color;void main()
{FragColor = color;
}
void init()
{ShaderInfo si[] = {{ GL_VERTEX_SHADER, "tess_tfb.v"},{GL_TESS_CONTROL_SHADER, "tess_tfb.tesc"},{GL_TESS_EVALUATION_SHADER, "tess_tfb.tese"},{ GL_FRAGMENT_SHADER, "tess_tfb.g"},{GL_NONE, ""}};program = LoadShaders(si);static const char * varyings = "gl_Position";glTransformFeedbackVaryings(program, 1, &varyings, GL_INTERLEAVED_ATTRIBS);glLinkProgram(program);glUseProgram(program);glGenVertexArrays(1, &vao);glBindVertexArray(vao);glGenBuffers(1, &vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo);glBufferData(GL_ARRAY_BUFFER, sizeof(vert), vert, GL_STATIC_DRAW);glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(float)*2*4));glEnableVertexAttribArray(1);glBindVertexArray(0);// Create the atomic counter bufferglGenBuffers(1, &atomic_counter_buffer);glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomic_counter_buffer);glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY);glGenTransformFeedbacks(1, &tfb);glBindTransformFeedback(GL_TRANSFORM_FEEDBACK,tfb);glGenBuffers(1, &tfb_buffer);glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tfb_buffer);glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024 * sizeof(float), NULL, GL_DYNAMIC_READ);glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffer);glGenQueries(1, &tfb_queriy);glClearColor(0.1, 0.1, 0.1, 1.0);
}void display()
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glUseProgram(program);glPatchParameteri(GL_PATCH_VERTICES, 3);// Reset atomic counterif (output==false){GLuint * data;glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomic_counter_buffer);data = (GLuint *)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY);data[0] = 0;glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);}glBindVertexArray(vao);glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, tfb_queriy);glBeginTransformFeedback(GL_TRIANGLES);glDrawArrays(GL_PATCHES, 0, 6);glEndTransformFeedback();glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);static bool output = false;if (output == false){GLuint * data;data = (GLuint *)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY);cout << "coordCount:" << *data << endl; glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);GLint triangleCount;glGetQueryObjectiv(tfb_queriy, GL_QUERY_RESULT, &triangleCount);cout <<"Triangle: " << triangleCount << endl;vmath::vec4* tfb_coord = (vmath::vec4*)glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);for (int i = 0; i < triangleCount*3; i++){int index = 4 * i;cout << (*tfb_coord)[index+0] << " " << (*tfb_coord)[index+1] << " " << (*tfb_coord)[index+2] << endl;}glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);output = true;}glutSwapBuffers();
}
coordCount是14,是由于绘制的是两个面片,共用的边上的顶点计算了两次。
OpenGL Transform Feedback相关推荐
- OpenGL Transform Feedback转换反馈的实例
OpenGL Transform Feedback转换反馈 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include "vapp.h" ...
- OpenGL学习笔记 transform feedback缓存粒子系统示例分析
http://blog.csdn.net/coderling/article/details/44742077 transform feedback是OpenGL中比较酷炫的特性之一,他让客户端应用程 ...
- NDK OpenGL ES 3.0 开发(七):Transform Feedback
该原创文章首发于微信公众号:字节流动 什么是 Transform Feedback Transform Feedback(变换反馈)是在 OpenGLES3.0 渲染管线中,顶点处理阶段结束之后,图元 ...
- OpenGL ES之变换反馈Transform Feedback的使用流程
一.什么是 Transform Feedback ? Transform Feedback(变换反馈)是在 OpenGL ES 3.0 渲染管线中,顶点处理阶段结束之后,图元装配和光栅化之前的一个步骤 ...
- OpenGL Partical System by Transform Feedback
使用OpenGL的变换反馈(transform feedback)构造粒子系统 粒子系统是三维计算机图形学中用来模拟火,爆炸,雾,雪,流行尾迹或者发光轨迹等视觉效果的技术.粒子系统模拟这些现象的步奏简 ...
- OpenGL完整教程专栏完整目录
OpenGL完整教程专栏完整目录 专栏说明如下 专栏目录 专栏说明如下 内容:OpenGL完整教程 数量:314篇博文(2023年2月15日截止) 更新时间至:2023年2月15日(后续加上去的博文, ...
- OpenGL编程指南8-Transform Feedback例子理解
transform feedback 是,OpenGL管线中,的,顶点处理阶段结束之后,图元装配和光栅化之前的一个步骤.transform feedback,可以重新捕获即将装配为图元(点.线段.三角 ...
- opengl版本发展史及各种概念的厘清
1.版本发展 1 opengl的版本区别 1.1 opengl1.1 1995年,SGI推出了更为完善的OpenGL 1.1版本.OpenGL 1.1的性能比1.0版提高甚多.其中包括改 ...
- python 粒子动画_初试PyOpenGL四 (Python+OpenGL)GPU粒子系统与基本碰撞
我认为比较完善的GPU粒子系统应该如下,粒子初始化可以放在CPU里,但是相关数据运算首先要放在GPU里,并且运算后的数据也应该放在显存里,而不是内存里.故用第三篇实现GPU粒子系统不满足,因为他数据是 ...
最新文章
- java odbc dbf,什么是Java的最佳开源dbf驱动程序?
- 技术文章精美配图模板网站推荐-创客贴
- 《数据分析变革:大数据时代精准决策之道》一第1章 了解运营型分析
- java hascode
- jquery实现登录失败提示_浅谈jQuery的verify验证码
- Tcode SCU3查看table log的error message - 如何查找necessary PFCG role
- MYSQL中只知表名查询属于哪个SCHEMA
- linux命令查看磁盘使用情况,linux查看磁盘使用情况命令
- 跟我学Spring Cloud(Finchley版)-04-服务注册与服务发现-原理剖析
- Spring + Spring MVC + mybatis 下的 junit4 注入单元测试
- 百战java课程_java百战程序员SpringBoot视频教程
- Excel怎么快速制作二维码图片?
- 超好用的UWP应用推荐
- python单位根检验看结果_python做adf检验
- leetcode46题 php实现,Leetcode PHP题解--D46 893. Groups of Special-Equivalent Strings
- 鹅厂、狗厂、猫厂、熊厂、鸟厂、粮厂
- python 拦截windows弹窗广告_win10怎么阻止弹窗广告拦截功能的方法
- 从输入网址到收到响应的详细过程
- 美国光纤通信展归来:光时代的MPO应用无法抗拒
- 追逐梦想,意味你要牺牲一切,这就是代价!!!----蔡赟