Transform Feedback

Dear GLers, I have about 8 hours OpenGL/CG experience, so I apologize in advance for any nonsense coming :wink:

My actual goal is to get information about primitives after they have run through transformation matrices. In principle, I want to identify lines etc. as they appear at the 2D-viewport, i.e. before the rasterizer has removed vertex identities. The whole procedure should be as unintrusive as possible as I want to transparently hook into 3rd party source code like the secondlife player.

It seems to me that the Transform Feedback extension comes close to meet these requirements (modulo that no clipping etc. has been performed when TF gets the data). Do you share this analysis? Are there alternatives, e.g. something that “labels” a 2D representation with the original primitives?

Aside from this fundamental question I also have practical problems. I have an Apple MP (late 2009) with Mac OS 10.6.2. GLView says “Renderer: NVIDIA GeForce 9400M OpenGL Engine
Vendor: NVIDIA Corporation
 Memory: 256 MB
Version: 2.1 NVIDIA-1.6.6
 Shading language version: 1.20”

I am currently playing with the following source code (original from http://cvit.iiit.ac.in, errors most probably introduced by me)


/////////////////////////////////////////////////////////////////
//
//	Simple Transform Feedback Example
//	Author: Shiben Bhattacharjee
//	shiben [at] research [dot] iiit [dot] ac [dot] in
//	http://cvit.iiit.ac.in/
//
/////////////////////////////////////////////////////////////////

#include<stdio.h>
#include<stdlib.h>
#include <iostream>

#ifdef _WIN32
#include<OpenGL/glee.h>
#else
#define GL_GLEXT_PROTOTYPES
#endif

#include<GLUT/glut.h>
#include<OpenGL/glu.h>
#include<OpenGL/gl.h>

GLuint tfvbo, pid, query;
int count=2;
float t=0;
void setupTFvbo(void)
{
	//position to be copied in the feedback buffer, 4 components, 3rd option is optional in position's case
	//generating the buffer, note that GL_TRANSFORM_FEEDBACK_BUFFER_NV is NOT a buffer type
	//record position attrib (no shaders, so cannot feedback varyings)
    const char* vars[] = { "gl_Position" };
	glUseProgram(pid);
	glTransformFeedbackVaryingsEXT(pid, 1,vars,GL_INTERLEAVED_ATTRIBS_EXT);
	glGenBuffersARB(1,&tfvbo);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB,tfvbo);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB,count*4*sizeof(float),0,GL_STATIC_DRAW_ARB);
    //const float init[] = {0.4f,0.4f,-0.3f,1.0f,-0.4f,-0.4f,-0.3f,1.0f};

    //int bufferSize;
    //glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &bufferSize);
    //std::cerr << "buffer size is " << bufferSize << std::endl;
	//bind the tfvbo to get the feedback

}

void 
init()
{
    pid = glCreateProgram();
    glLinkProgram (pid);
	glClearColor(0.0,0.0,0.0,0);
	glPointSize(4);
	setupTFvbo();

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1,1,-1,1,0.2,2);
	glMatrixMode(GL_MODELVIEW);
}

void 
display()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	glRotatef(t+=0.1,0,0,1);

//------display the normal rendered object at this viewport, with color red
	glColor3f(1,0,0);
	glViewport(0,0,512,512);

	//start transform feedback so that vertices get targetted to 'tfvbo'
	glBindBufferBaseEXT(GL_TRANSFORM_FEEDBACK_BUFFER_EXT,0,tfvbo);
	glBeginTransformFeedbackEXT(GL_POINTS);
	glutReportErrors();
    //glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT, query);
    //glEnable(GL_RASTERIZER_DISCARD_EXT);

	//render primitives and copy these positions to tranform feedback buffer
	glBegin( GL_POINTS );
		glVertex4f( -0.5, -0.5, -0.3, 1 );
		glVertex4f(  0.5,  0.5, -0.3, 1 );
	glEnd();
	//end transform feedback
    //glDisable(GL_RASTERIZER_DISCARD_EXT);
    //glEndQuery(query);
	glEndTransformFeedbackEXT();

    GLuint primitive_count = 4;
    //glGetQueryObjectuiv(query, GL_QUERY_RESULT, &primitive_count);
    std::cerr << "count is " << primitive_count << std::endl;

	float* buf = (float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB);
    std::cerr << "buf is " << std::hex << buf << std::endl;
    int i;
    for (i = 0; i < 4; ++i) {
        std::cerr << "data[" << i << "] is " << buf[i] << std::endl;
    }
	glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
//------display the transform feedback recorded data to this viewport
	glColor3f(0,1,0);

	//render the buffer which has recieved data from transform feedback
	//note that glRotate is still active, and it has already rotated once
	//means it will rotate twice the speed

	glEnableClientState(GL_VERTEX_ARRAY);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB,tfvbo);
	glVertexPointer(4,GL_FLOAT,0,(GLushort*)0+0);
	glDrawArrays(GL_POINTS,0,count);
	glDisableClientState(GL_VERTEX_ARRAY);

	glutSwapBuffers();
}

int main(int argc,char **argv)
{
	glutInit( &argc, argv );
	glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH );
	glutInitWindowSize(512,512);
	glutCreateWindow("Transform Feedback");
	glutDisplayFunc( display );
	glutIdleFunc( display );
	init();
	glutMainLoop();
	return 0;
}



What I get is an “Invalid Operation” at glBeginTransformFeedbackEXT (line 77).

The extension spec states that a possible cause could be that the varyings are not properly defined for the TF operation. This also seems likely to me as I had to replace a reference to glTransformFeedbackAttribsNV() in the original source code by glTransformFeedbackVaryingsEXT(), as I wasn’t able to find the former one in any header files. However, glTransformFeedbackVaryingsEXT() expects a program object and so I had to introduce all this machinery without being sure what it means nor if it’s correct.

Apart from the OpenGL error, when I start the program I see that the vertex array object is properly drawn, however the VBO is never filled with anything but the values chosen at init time.

Thanks in advance, Michael

Hi there! Download the latest glext.h, it has the definitions you need.

http://www.opengl.org/registry/api/glext.h

A quick search revealed that the function you’re after is defined.

Thank you for the answer.

Unfortunately, the problem seems to be more fundamental, as the GL_EXT_TRANSFORM_FEEDBACK extension, i.e. the one with glTransformFeedbackVaryingsEXT(), seems not to work for the fixed function pipeline, and Mac OS X 10.6.2 seems not to support GL_NV_TRANSFORM_FEEDBACK, i.e. the one with glTransformFeedbackAttribsNV(), (which works with the FFP).

So, I suppose I have to rewrite my test program to use a custom vertex shader?!