Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Tessellation with Transform Feedback

  1. #1
    Newbie Newbie
    Join Date
    May 2013
    Posts
    2

    Tessellation with Transform Feedback

    Right now I want to generate a mesh with a tessellation shader and have that go into a different program/vertex/tessellation shader...

    I got the mesh generating just fine with the tessellation shader, which outputs 'quads'. I'm having issues with the transform feedback aspect though so I can't even start the second pass yet...

    The initialization looks like:
    Code :
    	//Transform feedback output buffer
    	glGenBuffers(1, &TransformFeedbackBuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, TransformFeedbackBuffer);
    	glBufferData(GL_ARRAY_BUFFER, 4096*3*4, 0, GL_STATIC_DRAW);
    	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    	glBindBuffer(GL_ARRAY_BUFFER, 0);
     
    	//transform feedback object
    	glGenTransformFeedbacks(1, &TransformFeedbackObject);
    	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TransformFeedbackObject);	
    	glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TransformFeedbackBuffer);
    	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);

    And in the render loop:

    Code :
    		// enable / disable wireframe
    		glPolygonMode( GL_FRONT_AND_BACK, wireframe ? GL_LINE : GL_FILL);printGLError();
     
    		glEnable(GL_RASTERIZER_DISCARD);printGLError(); 
    		//set up the program
    		glUseProgram(program);printGLError();
     
    		glBindBufferBase( GL_UNIFORM_BUFFER , 1, ubo);printGLError();
    		glBufferData(GL_UNIFORM_BUFFER, sizeof(TessellationParams), &tessellationParameters, GL_STREAM_DRAW);printGLError();
     
    		GLint numfeedbackwritten;
     
    		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TransformFeedbackObject);printGLError();
    		glBeginTransformFeedback(GL_TRIANGLES);printGLError();
    		{
    			glBindBuffer(GL_ARRAY_BUFFER, vbo);
    			glEnableVertexAttribArray(0);
    			glPatchParameteri( GL_PATCH_VERTICES, 1);
     
    			//draw a single patch
    			GLuint queryObject;
    			glGenQueries(1, &queryObject);printGLError();
     
    			glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queryObject);printGLError();
    				glDrawArrays( GL_PATCHES, 0, 1);printGLError();
    			glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);printGLError();
     
     
    			glGetQueryObjectiv(queryObject, GL_QUERY_RESULT, &numfeedbackwritten);
    			printf("Tris drawn to feedback buffer: %d\n", numfeedbackwritten);
     
    			glDisableVertexAttribArray(0);
    			glBindBuffer(GL_ARRAY_BUFFER, 0);
    		}
    		glEndTransformFeedback();printGLError();
    		glDisable(GL_RASTERIZER_DISCARD);printGLError();

    The printGLError() says Invalid Operation on the glDrawArrays call... Also, I'm not sure how to render it to the screen afterwards. I think this is right?

    Code :
    		glUseProgram(0);
    		glBindBuffer(GL_ARRAY_BUFFER, TransformFeedbackBuffer);printGLError();
    		glEnableVertexAttribArray(0);
     
    		GLuint queryObject2;
    		glGenQueries(1, &queryObject2);printGLError();
     
    		glBeginQuery(GL_PRIMITIVES_GENERATED, queryObject2);
    			glDrawArrays( GL_TRIANGLES, 0, numfeedbackwritten);printGLError();
    		glEndQuery(GL_PRIMITIVES_GENERATED);
     
    		glGetQueryObjectiv(queryObject2, GL_QUERY_RESULT, &numfeedbackwritten);
    		printf("Tris drawn to display: %d\n", numfeedbackwritten);

    But it's hard to tell since I'm getting no tris being drawn in either case. I think glDrawTransformFeedback should work too...

    Is this setup even possible? The feedback says it only works on points, lines and tris, and the tess shader I want to have it as a quad input (but triangle output).

  2. #2
    Newbie Newbie
    Join Date
    May 2013
    Posts
    2
    So after messing around with this a lot, I managed to get it working. There was a ton wrong, highlighted in bold below (I don't know how to bold things that are in CODE tags). I ended up using a second set of passthrough shaders because it was easier to set what I wanted. Basically I was missing vertexAttribPointer calls that I thought were bound to the buffer before.

    Initialization is modified:
    //Transform feedback output buffer
    glGenBuffers(1, &TransformFeedbackBuffer);
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, TransformFeedbackBuffer);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 100000*4*4, 0, GL_STATIC_DRAW);
    glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TransformFeedbackBuffer, 0, 100000*4*4);
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
    Render is modified:
    //first pass, render vertices to transform feedback buffer
    glEnable(GL_RASTERIZER_DISCARD);
    glUseProgram(program);

    glBindBufferBase( GL_UNIFORM_BUFFER , 1, ubo); //uniforms
    glBufferData(GL_UNIFORM_BUFFER, sizeof(TessellationParams), &tessellationParameters, GL_STREAM_DRAW);

    glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TransformFeedbackObject);
    glBeginTransformFeedback(GL_TRIANGLES);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glPatchParameteri( GL_PATCH_VERTICES, 1);
    glDrawArrays( GL_PATCHES, 0, 1);

    glDisableVertexAttribArray(0); //cleanup
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glEndTransformFeedback();
    glDisable(GL_RASTERIZER_DISCARD);
    glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);

    //second pass
    glUseProgram(program2);
    glBindBuffer(GL_ARRAY_BUFFER, TransformFeedbackBuffer);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glPatchParameteri(GL_PATCH_VERTICES, 3);
    glDrawTransformFeedback(GL_PATCHES, TransformFeedbackObject);

  3. #3
    Newbie Newbie
    Join Date
    Jun 2013
    Posts
    1
    Hi, I am working on tessellation with transform feedback these days too. But right now, I still can not get it working. In my code, I use tessellation shader to generate a sphere object from a single input vertex, this works fine. Then I want to obtain the vertices and normals of the sphere generated by the tessellation via transform feedback. Right now, all I get in the transform feedback buffer is the input vertex without tessellation. Do you have any idea, what is wrong? Thanks in advance. Sorry for my poor English. Here is my tessellation shader:
    vertex shader:
    Code :
    layout(location=0) in vec4 vertex;
    out vec4 vPosition;
    void main() {   
    	vPosition = vertex;
    }
    tessellation control shader:
    Code :
    #version 420
    #extension GL_ARB_tessellation_shader : enable
     
    layout( vertices=1) out;
    in vec4 vPosition[];
    out vec4 tcPosition[];
    uniform float innerTessFactor;
    uniform float outerTessFactor;
     
     
    void main() {
     
        tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];  
     
        gl_TessLevelOuter[0] = outerTessFactor;
        gl_TessLevelOuter[1] = outerTessFactor;
        gl_TessLevelOuter[2] = outerTessFactor;
        gl_TessLevelOuter[3] = outerTessFactor;
     
        gl_TessLevelInner[0] = innerTessFactor;
        gl_TessLevelInner[1] = innerTessFactor;
    }

    tessellation evaluation shader:
    Code :
    #version 420 compatibility
    #extension GL_ARB_tessellation_shader : enable
    #extension GL_ARB_shading_language_include : enable
     
    layout(quads,fractional_odd_spacing,ccw) in;
    uniform mat4 MVP;
    uniform mat4 ModelView;
    out vec3 normal;
    out vec3 vertex;
    out vec4 position;
    in vec4 tcPosition[];
     
    out gl_PerVertex {
        vec4  gl_Position;
    };
     
    void main() {
     
        position = tcPosition[0];
     
        position.y = cos(gl_TessCoord.x * 3.1415927);
        position.x = sin(gl_TessCoord.y * 3.1415927 * 2.0)*sin(gl_TessCoord.x * 3.1415927);
        position.z = cos(gl_TessCoord.y * 3.1415927 * 2.0)*sin(gl_TessCoord.x * 3.1415927);
        normal = normalize(position).xyz;
     
        gl_Position = MVP * position;
        normal = (ModelView * vec4(normal,0.0)).xyz;
        vertex = vec3(ModelView * position);
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •