Dear GLers, I have about 8 hours OpenGL/CG experience, so I apologize in advance for any nonsense coming
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