此处的目标是使用OpenGL和“变换反馈”以递归方式建立三维的所谓“ Phytagoras树”。此处仅通过具有法线,颜色,纹理坐标和长度(指示“杆”应伸出的距离)的单个三角形提供底座。 https://imgur.com/a/WNeBbJN 我希望这些图片能告诉你我的需要。
PS:好像有一个同学,两年前尝试过这个。但是给出的答案并不能解决我的问题。 OpenGL Transform Feedback with dynamic Geometry
这是我当前的代码: https://paste.myst.rs/sil 链接程序之前:
varyings = new CharSequence[]{"outPosition", "outNormal", "outColor", "outTextureCoordinates", "outLength"};
glTransformFeedbackVaryings(shaderProgram, varyings, GL_INTERLEAVED_ATTRIBS);
glLinkProgram(shaderProgram);
//This is the buffer we fill with the model points to process.
inputData = BufferUtils.createFloatBuffer(model.length * 2);
inputData.put(model).flip();
//And the VBO which we upload the data to.
inputVBO = glGenBuffers();
//This is the data in which the processed points will end up:
//make it big enough because all overflown data will be discarded!!
outputVBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, outputVBO);
glBufferData(GL_ARRAY_BUFFER, model.length * 50, GL_STATIC_DRAW);
//freeBuffer:
glBindBuffer(GL_ARRAY_BUFFER, 0);
//We create our transform feedback object. We then bind it and
//tell it to store its output into outputVBO.
feedbackObject = glGenTransformFeedbacks();
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, feedbackObject);
//binds outputVBO on start of GL_TRANSFORM_FEEDBACK_BUFFER, wich is feedbackObject
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, outputVBO);
//freeBuffer:
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
//We also create a query object. This object will be used to
//query how many points that were stored in the output VBO.
queryObject = glGenQueries();
glUseProgram(shaderProgram);
最后处理几何着色器中的点并尝试绘制它们...:
glEnable(GL_RASTERIZER_DISCARD);
{
//redundant?:
glUseProgram(shaderProgram);
//bind the ffedback object:
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, feedbackObject);
//actually start "rendering" (without rendering...processing):
glBeginTransformFeedback(GL_TRIANGLES);
{
//Bind and update the inputDataVBO:
glBindBuffer(GL_ARRAY_BUFFER, inputVBO);
glBufferData(GL_ARRAY_BUFFER, inputData, GL_STREAM_DRAW);
//enable shaderInputAttributes:
enableShaderInputAttributesForTF();
glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queryObject);
glDrawArrays(GL_TRIANGLES, 0, 5000);
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
System.out.println("Points drawn: " + glGetQueryObjecti(queryObject, GL_QUERY_RESULT));
//cleanup:
disableShaderInputAttributesForTF();
//free Buffer:
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glEndTransformFeedback();
}
//free program:
glUseProgram(0);
glDisable(GL_RASTERIZER_DISCARD);
渲染:
glBindBuffer(GL_ARRAY_BUFFER, outputVBO);
//If enabled, the vertex array is enabled for writing and used during rendering when glDrawArrays is called:
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 12 * sizeOfFloat, 0 * sizeOfFloat);
//??:
// glVertexPointer(3, GL_FLOAT, 12 * sizeOfFloat, 3 * sizeOfFloat);
// glVertexPointer(3, GL_FLOAT, 12 * sizeOfFloat, 6 * sizeOfFloat);
// glVertexPointer(2, GL_FLOAT, 12 * sizeOfFloat, 9 * sizeOfFloat);
// glVertexPointer(1, GL_FLOAT, 12 * sizeOfFloat, 11 * sizeOfFloat);
//actually Draw the transform Feedback:
glDrawTransformFeedback(GL_TRIANGLES, feedbackObject);
//Clean up...
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
我的顶点着色器很简单:
#version 330
in vec3 position;
in vec3 normal;
in vec3 color;
in vec2 texCoords;
in float length;
out geoValue{
vec3 pos;
vec3 normal;
vec3 color;
vec2 texCoords;
float length;
} vs_out;
void main()
{
vs_out.pos = position;
vs_out.normal = normal;
vs_out.color = color;
vs_out.texCoords = texCoords;
vs_out.length = length;
}
和我的geometryShader:
#version 330 core
layout (triangles) in;
layout (triangle_strip, max_vertices = 32) out;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
in geoValue{
vec3 pos;
vec3 normal;
vec3 color;
vec3 texCoords;
float length;
} gs_in[];
out DataBlock{
vec3 pos;
vec3 normal;
vec3 color;
vec3 texCoords;
float length;
} outValue;
out vec3 outPosition;
out vec3 outNormal;
out vec3 outColor;
out vec2 outTextureCoordinates;
out float outLength;
void passColorAndTexture(){
outValue.color = gs_in[0].color;
outValue.texCoords = gs_in[0].texCoords;
}
void constructTreeTrunk(vec4 position)
{
vec4 v0 = proj*(view*(model*(position+ vec4(-1, 0, -1, 0))));//uhl
vec4 v1 = proj*(view*(model*(position+ vec4(1, 0, -1, 0))));//uv
vec4 v2 = proj*(view*(model*(position+ vec4(0, 0, 1, 0))));//uhr
vec4 v3 = proj*(view*(model*(position+ vec4(-1, 2, -1, 0)*0.8)));//ohl
vec4 v4 = proj*(view*(model*(position+ vec4(1, 2, -1, 0)*0.8)));//ov
vec4 v5 = proj*(view*(model*(position+ vec4(0, 2, 1, 0)*0.8)));//ohr
vec4 v6 = proj*(view*(model*(position+ vec4(0, 4, 0, 0)*0.6)));//tip
//Bottom Pane
gl_Position = v0;
EmitVertex();
gl_Position = v1;
EmitVertex();
gl_Position = v2;
EmitVertex();
EndPrimitive();
//Top Pane
gl_Position = v3;
EmitVertex();
gl_Position = v4;
EmitVertex();
gl_Position = v5;
EmitVertex();
EndPrimitive();
//frontleft Pane1
gl_Position = v0;
EmitVertex();
gl_Position = v1;
EmitVertex();
gl_Position = v4;
EmitVertex();
EndPrimitive();
//frontleft Pane2
gl_Position = v0;
EmitVertex();
gl_Position = v4;
EmitVertex();
gl_Position = v3;
EmitVertex();
EndPrimitive();
//frontright Pane1
gl_Position = v1;
EmitVertex();
gl_Position = v2;
EmitVertex();
gl_Position = v4;
EmitVertex();
EndPrimitive();
//frontright Pane2
gl_Position = v4;
EmitVertex();
gl_Position = v2;
EmitVertex();
gl_Position = v5;
EmitVertex();
EndPrimitive();
//back Pane1
gl_Position = v0;
EmitVertex();
gl_Position = v2;
EmitVertex();
gl_Position = v5;
EmitVertex();
EndPrimitive();
//back Pane2
gl_Position = v5;
EmitVertex();
gl_Position = v3;
EmitVertex();
gl_Position = v0;
EmitVertex();
EndPrimitive();
//tip vl
gl_Position = v3;
EmitVertex();
gl_Position = v4;
EmitVertex();
gl_Position = v6;
EmitVertex();
EndPrimitive();
//tip vr
gl_Position = v4;
EmitVertex();
gl_Position = v5;
EmitVertex();
gl_Position = v6;
EmitVertex();
EndPrimitive();
//tip h
gl_Position = v3;
EmitVertex();
gl_Position = v5;
EmitVertex();
gl_Position = v6;
EmitVertex();
EndPrimitive();
}
void constructNewTetraeder(){
}
void main() {
passColorAndTexture();
constructTreeTrunk(gl_in[0].gl_Position);
constructNewTetraeder();
}
当前我还没有激活TF,但是留下了顶点生成,因此您可以看到我的需求。
我认为要激活TF,必须在136行和495行中注释,并在494行中注释掉。不幸的是,这里没有任何反应。
激活TF就足够了。着色器仍然需要调整。那应该是一个小问题。我只需要递归地生成几何。