我尝试构建一个OpenGL程序,该程序同时对五个值执行牛顿-拉夫森方法。实际上,我只是想学习如何使用TRANSFORM FEEDBACK
顶点着色器只是将值传递给几何着色器
const GLchar* vertexShaderSrc = R"glsl(
#version 330 core
layout (location = 0) in float result;
layout (location = 1) in float val;
layout (location = 2) in float iterTime;
layout (location = 3) in float type;
out float geoResult;
out float geoVal;
out float geoIterTime;
out float geoType;
void main()
{
geoResult = result;
geoVal = val;
geoIterTime = iterTime;
geoType = type;
})glsl";
“几何着色器”会在第一次创建五个新值以通过变换反馈进行缓冲和缓存。然后,程序对五个值进行迭代。
const GLchar* geometryShaderSrc = R"glsl(
#version 330 core
layout(points) in;
layout(points,max_vertices=100) out;
#define START_POINT 1.0f
#define REST_POINT 2.0f
in float geoResult[];
in float geoVal[];
in float geoIterTime[];
in float geoType[];
out float outResult;
out float outVal;
out float outIterTime;
out float outType;
void main(){
if(geoType[0] == START_POINT){
for(int i = 1; i<=5; ++i){
outResult = geoVal[0]/2;
outVal = geoVal[0]+50*i;
outIterTime = geoIterTime[0];
outType = REST_POINT;
EmitVertex();
}
EndPrimitive();
}
else{
outResult = geoResult[0]/2 + geoVal[0] / geoResult[0]/2;
outVal = geoVal[0];
outIterTime = geoIterTime[0] - 1;
outType = REST_POINT;
EmitVertex();
EndPrimitive();
}
} )glsl";
循环如下
while (iterTimeCount-->0)
{
glEnable(GL_RASTERIZER_DISCARD);
// specify VBO and TFO
glBindBuffer(GL_ARRAY_BUFFER, nodeBuffer[currVB]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback[currTFB]);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, sizeof(resolveNode), (const GLvoid*) 0); // result
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(resolveNode), (const GLvoid*) 4); // val
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(resolveNode), (const GLvoid*) 8); // iterTime
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(resolveNode), (const GLvoid*) 12); // type
glBeginTransformFeedback(GL_POINTS);
// specially do drawing for the first particle. the rest of the particles will be
// create and drawn by TransformFeedback
if (isFirst) {
glDrawArrays(GL_POINTS, 0, 1);
isFirst = false;
}
else {
glDrawTransformFeedback(GL_POINTS, transformFeedback[currVB]);
}
glEndTransformFeedback();
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER,
0, sizeof(feedback), feedback);
for(int i = 0; i < 5; ++i){
printf("%f\t%f\t%f\t| ",feedback[i].result,feedback[i].val,feedback[i].iterTime);
}
printf("\n\n");
// switch VBO and TBO
currVB = currTFB;
currTFB = (currTFB + 1) & 0x1;
}
专注于 feedback [i] .iterTime ,我得到10 10 8 8 8 6 6 4 4 2 2 0,应该是10 9 8 7 6 5 4 3 2 1 0。 ..