PDA

View Full Version : No Display(list) without glu-primitive. Why?



Luanah
07-27-2009, 01:47 AM
Hello there!

I'm working on a 3D Viewer with openGL and Qt. It already works. I did not write the basic view and camera system myself, i just proceed the code of some other developers.
So I'm not very familiar with how it works in detail, but i can find out if necessary.
All spinning and rotation of the view works (in some terms).
Lets assume everything is allright.
Now my Problem:

I load a Mesh file from a .obj. I generate a Display list.

There ist a "draw()" function that is called every time the view changes.

ignoring all redundant code i do the following:




preDraw();// initialize GL as common

void SViewer3d::draw(){
if ( mesh && _bDrawMeshobject ) {

glPushAttrib( GL_ALL_ATTRIB_BITS );
glEnable( GL_LIGHTING );

mesh->callMeshDisplayList();

glDisable( GL_LIGHTING );
glEnable( GL_COLOR_MATERIAL );
glPopAttrib();

}
}



The Point is: this does not work without a glu-Object.
glIsList(gliMeshDisplayList) is 'FALSE' and all the spinning and rotation and zooming stuff does nothing. But my Mesh ist displayed static and once.

now i add:

if ( _bDrawMeshobject) {
static GLUquadric *quadric = gluNewQuadric();
gluSphere( quadric, 0.025, 10, 10 );
}

to my draw() Method, and everything works fine. The Sphere could be any GLU-Object. It also works with all the others.

I know that maybe the error is hidden deeper in the other routines, but before i spent more hours and hours searching (and i already did) i thougt i ask you. Seems like a typical problem that a noob like me is faced.

I would be very thankful for every piece of information that you can offer me. Even if you have a little clue. Right now i have no idea...

_NK47
07-27-2009, 03:58 AM
show code from mesh->callMeshDisplayList();
also, how do you create display lists?

Luanah
07-27-2009, 05:05 AM
I have a special SMesh Class where all Mesh things are done. See code below.
Maybe its important to say, that the error occurs even if a simple drawing function is called. For example:

glBegin( GL_POINTS );
glVertex3f(30.0 ,30.0 ,30.0 );
glEnd;

When i do more complex things it is like all my commands have a kind of delay. If draw a cloud of points and then triangled Mesh, only points of the Mesh are drawn.
Flip both events: there are wrong Triangles in the point-cloud.
Same with the view of my worldaxis-system (some cones and cylinder glu) they are 'glues' so they make the view work, but if points are drawn before then the first glu of the first arrow is point-drawn. The rest is ok.
Is there something in the glu-Objects that influences the Buffer-Bits?

sorry if this gets a little annoying. I know its hard to say something if you dont see the code. Thank you for your paitence.

__________________________________________________ ____


void SMesh::genMeshDisplayList(){

gliMeshDisplayList = glGenLists(1);

glNewList(gliMeshDisplayList, GL_COMPILE);

for(int i=0; i<=_matNameList.size()-1;i++){

QMap <QString, SMaterial*>::Iterator it = matmap.find(_matNameList[i]);

if (it==matmap.end()){};
SMaterial *material = it.value();

V::Vector3 spec = material->getSpecular();
V::Vector3 amb = material->getAmbient();
V::Vector3 diff = material->getDiffuse();
double shin = material->getShininess();
double illu = material->getIllumination();
double trsp = material->getTransparency();

int cur = _materialFaceList.at(i);//anzahl faces vorm Material
int nex = _materialFaceList.at(i+1);




for(int j=cur; j <= nex-1 ;j++){

GLfloat mat_specular[] = {spec[0], spec[1], spec[2], trsp};
GLfloat mat_ambient[] = {amb[0], amb[1], amb[2], trsp};
GLfloat mat_diffuse[] = {diff[0], diff[1], diff[2], trsp};
GLfloat mat_shininess[] = {shin};
GLfloat mat_illumination[] = {illu};
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
//Fläche holen
V::Vector3 face = _iVertexFacelist.at(j);
V::Vector3 nor = _iNormalsFacelist.at(j);

//Punkte zur Fläche holen
V::Vector3 vert1 = _dVertexlist.at(face[0]-1);
V::Vector3 vert2 = _dVertexlist.at(face[1]-1);
V::Vector3 vert3 = _dVertexlist.at(face[2]-1);

//Normale zu den Punkten holen
V::Vector3 nor1 = _dVertexNormals.at(nor[0]-1);
V::Vector3 nor2 = _dVertexNormals.at(nor[1]-1);
V::Vector3 nor3 = _dVertexNormals.at(nor[2]-1);

//Fläche zeichnen
glBegin(GL_TRIANGLES);
glNormal3f(nor1[0],nor1[1],nor1[2]);
glVertex3d(vert1[0],vert1[1],vert1[2]);
glNormal3f(nor2[0],nor2[1],nor2[2]);
glVertex3d(vert2[0],vert2[1],vert2[2]);
glNormal3f(nor3[0],nor3[1],nor3[2]);
glVertex3d(vert3[0],vert3[1],vert3[2]);
glEnd;
}

}//endfor Material
glEndList();




}



void SMesh::callMeshDisplayList(){

if (glIsList(gliMeshDisplayList)==GL_TRUE){
glCallList(gliMeshDisplayList);
}
else {
TP::info(QString("Keine Mesh Displayliste"));
}
}

_NK47
07-27-2009, 06:02 AM
first thing to do is to check after glEndList or glBegin/glEnd for glGetError(). you should check for gl errors every frame in DEBUG mode. no doubt you have some errors related to that. what error is raised after certain function can be obtained from the function specs like this one: http://www.opengl.org/sdk/docs/man/xhtml/glNewList.xml, see the Errors section.

Luanah
07-27-2009, 06:27 AM
I tryed:

...
glEndList();
TP::info(QString("GL Error %1") .arg(glGetError()));

Output:GL Error 0

same for the routine that draws the point-cloud from the Mesh:

________________________________________
void SMesh::drawSMeshCloud(){
int iCalls = _dVertexlist.size()-1; //_iVertexFacelist.size();
for(int i2=0; i2 <= iCalls ;i2++){
GLfloat mat_specular[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_ambient[] = {0.2, 0.2, 0.2, 1.0};
GLfloat mat_diffuse[] = {0.8, 0.8, 0.8, 1.0};
GLfloat mat_shininess[] = {50.0};
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glEnable(GL_NORMALIZE);

//Punkte zur Fläche holen
V::Vector3 vert = _dVertexlist.at(i2);

//Fläche zeichnen
glPointSize(4.00);
glBegin(GL_POINTS);
glVertex3f(vert[0],vert[1],vert[2]);
glEnd;
TP::info(QString("GL Error %1") .arg(glGetError()));


}//endfor*/
};

___________________________________________

see, here is no display list used to draw. And I checked each and every Begin() and End() Block to open and close proper.
I know ist senseless to draw points with material ;-)

Luanah
07-27-2009, 06:36 AM
Is there some crap in my preDraw function?


void SViewer3d::preDraw(){



glEnable(GL_DEPTH_TEST);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
camera()->loadProjectionMatrix();//glLoadIdentity happens here
camera()->loadModelViewMatrix();
glShadeModel(GL_SMOOTH);
//Light
GLfloat light_position0[] = {-300, -300, -300, 1.0};
GLfloat red_light[] = {1.0, 0.0, 0.0, 1.0};
glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
glLightfv(GL_LIGHT0, GL_SPECULAR, red_light);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//second Light
GLfloat light_position1[] = {400, 400, 400, 1.00};
GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat light_ambient[] = {0.1, 0, 0.2, 1.0};
GLfloat light_diffuse[] = {0.7, 0.7, 0.7, 1.0};
glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, white_light);
glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
glEnable(GL_LIGHT1);
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
renderText( 5,15,"R: Rotate");
renderText( 5,30,"Z: Zoom");
renderText( 5,45,"P: Pan");
glEnable( GL_COLOR_MATERIAL );

}

_NK47
07-28-2009, 01:52 AM
im am bit lost. again, what you do for it to work properly and when exactly does it not work? sounds like a context problem. does glGetString(GL_VENDOR) return a valid string pointer in your draw method?

Luanah
07-29-2009, 02:02 AM
Hey _NK47 Thanks for your reply.

We worked at a customer yesterday, so i could'nt answer faster.
I'm a bit lost too.
The glGetString(GL_VENDOR) called in draw() returns "ATI Technologies Inc"

And once again the my problem:
My view has an error if i do not draw a glu-primitive.
If i draw a primitive my mesh is diplayed correct and moves as it should do.
But there are Problems when i draw a sequence of Things.
If i call "glBegin(GL_POINTS)... glEnd" and after that draw a glu-primitive or a mesh only the points of the primitive are drawn. But the next primitive drawn will look correct.
There is a kind of "delay" in everything.

Luanah
07-29-2009, 02:18 AM
My next idea, is to check if there is more than one thread or instance of the widget running. Seems absurd to me, but i'm running out of ideas. A freind said 'maybe there is an error on your graphic board'. Seems absurd too, but i am stones throw away from testing it.
Are there possibilitys to force GL commands to be executed immidiately, or anyway things that interrupt the rendering-pipeline?

Luanah
07-29-2009, 04:19 AM
No, no, NOOOOOOO please tell me, this is not true!!!

There is a main difference in glEnd; and glEnd();

:-( the first is total rubbish and the second ... oh man...

Why didn't my compiler tell me? This had to be a syntax error!

Still strange things happen when i dont use the glu's but i'm optimistic to find the answers ind the camera Methods.

I'm glad ist not one big error. Computers are great. They do only what you tell them. When do i start to rely on this? :-)

Big big thanks so far for your help.

Dark Photon
07-29-2009, 05:26 AM
There is a main difference in glEnd; and glEnd();

:-( the first is total rubbish and the second ... oh man...

Why didn't my compiler tell me? This had to be a syntax error
Actually no. The first isn't an error in the C/C++ languages, though it isn't what you want. It's just a function (void glEnd()), which used as a value, evaluates as a function pointer. Values are valid on their own in C/C++.

However, if you flip compiler warnings on -- i.e. tell it to Warn on all "weird code" permutations it knows about (almost always developer goofs) -- e.g. add -Wall to the command line with gcc -- then you'll get something like this:

tst.cxx:5: warning: statement is a reference, not call, to function 'glEnd'
tst.cxx:5: warning: statement has no effect

I'd highly recommend gcc folks compile with -Wall -Werror, which says "look for weird stuff" and "treat this stuff as a hard compiler error, not just a warning".

If you're not using gcc, find out what the equivalent is with your compiler. If you can't make your compiler generate warnings for this, then ditch it and get a real compiler.