Thread: [Plib-users] Trouble making simple colored triangle
Brought to you by:
sjbaker
From: Ben D. <be...@wa...> - 2000-10-13 03:46:51
|
I'm in the process of porting my whole 3d project over to PLIB/SSG, and mostly it's great, but i'm having a lot of trouble trying to build some simple geometry with SSG. As an example, consider a plain green triangle. You might think that the following code would work: sgVec4 color; sgVec3 pos; ssgSimpleState *state = new ssgSimpleState(); sgSetVec4(color, 0.0f, 1.0f, 0.0f, 1.0f); state->setMaterial(GL_DIFFUSE, color); ssgVertexArray *vertices = new ssgVertexArray(3); ssgNormalArray *normals = new ssgNormalArray(3); ssgVtxTable *pVtx = new ssgVtxTable(GL_TRIANGLES, vertices, normals, NULL, NULL); for (int i = 0; i < 3; i++) { double a = i * PI2f / 3.0f; sgSetVec3(pos, cos(a), sin(a), 0); vertices->add(pos); sgSetVec3(pos, 0, 0, 1); normals->add(pos); } pVtx->setState(state); But, this makes a triangle which is white, not green. Stepping into the SSG code, i discovered that in the function ssgVtxTable::draw_geometry(), there is the line: if ( num_colours == 0 ) glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ) ; This forces all primitives to white if they don't have a color per vertex! I worked around this problem by making and using a subclass of ssgVtxTable with a draw_geometry that doesn't make this assumption. The triangle was still white, so i found the next problem. In ssgSimpleState::apply(), it uses glMaterialfv to set the diffuse color. However, GL is in "Color Material" mode by default, so the glMaterialfv calls have no effect, making the shape default white. I tried to solve this problem by adding a statement to the triangle code: state->disable(GL_COLOR_MATERIAL); But, another problem (bug?) in ssgSimpleState::apply() prevents this from working. The Enable/Disable state code, required to disable "Color Material", is called *after* the glMaterialfv code, but OGL requires the glMaterialfv call to come after! So, i tried to work around this by changing the order in ssgSimpleState.cxx. That worked, so i finally got a green triangle. Surely there is some way to do simple colored geometry without all the hacking i had to do? Please help, i would really love to be able to use SSG. Thanks, Ben Discoe http://vterrain.org/ |
From: Steve B. <sjb...@ai...> - 2000-10-13 14:11:28
|
Ben Discoe wrote: > But, this makes a triangle which is white, not green. Stepping into the SSG > code, i discovered that in the function ssgVtxTable::draw_geometry(), there > is the line: > if ( num_colours == 0 ) glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ) ; That's a very carefully considered decision - don't mess with it! OK - there is a common misconception about ssgState's: **** THERE IS NO "DEFAULT" VALUE FOR ANY FIELD OF AN SSGSTATE **** The 'default' is that if you don't set some attribute of the state, SSG won't set it - and you'll get whatever garbage happens to be set up in OpenGL at the time. You *MUST* set precisely those state elements that you need and pay attention to NOT setting the ones you truly don't care about. This has THREE very important benefits: 1) Speed. Since there are many aspects to OpenGL state, if I had to set them all up before drawing every Leaf node, we would be there all night doing pre-triangle setup. Hence, you only set what you care about and I don't waste time setting up parameters you care nothing about. 2) Some applications want to set a particular state globally. By leaving that state out of all of your primitives, you can set that state yourself in the application and SSG won't mess with it. 3) Future enhancements. If there is some aspect of OpenGL state that SSG doesn't manage (there are quite a few) - and so the application sets it up, then if ssgState had a default for everthing, we would not be able to extend the coverage of ssgState in the future without breaking existing programs. With the default being "don't change anything", we could (hypothetically) decide to implement (say) bump mapping in ssgState without destroying programs that already set that up outside of SSG. Of these, speed is by far the most important. > This forces all primitives to white if they don't have a color per vertex! No - it sets them to white if you didn't give the LEAF node a colour. That's a very rare circumstance in practice. (Notice the comments earlier about there not being defaults applied to *STATE* structures not *LEAF* structures.) > I worked around this problem by making and using a subclass of ssgVtxTable > with a draw_geometry that doesn't make this assumption. The triangle was > still white, so i found the next problem. Nah - that was wrong. > In ssgSimpleState::apply(), it uses glMaterialfv to set the diffuse color. > However, GL is in "Color Material" mode by default, so the glMaterialfv > calls have no effect, making the shape default white. It's unwise to rely on OpenGL's default state. Many implementations get that wrong. No - it's simply that you didn't enable or disable GL_COLOR_MATERIAL explicitly and you didn't set the glColorMaterial setting to (say) GL_AMBIENT_AND_DIFFUSE in the ssgStates that needed that. > I tried to solve this problem by adding a statement to the triangle code: > state->disable(GL_COLOR_MATERIAL); OK - that's going to mean that the polygon colour is entirely determined by the glMaterial - but *ONLY* if GL_LIGHTING is enabled. > But, another problem (bug?) in ssgSimpleState::apply() prevents this from > working. The Enable/Disable state code, required to disable "Color > Material", is called *after* the glMaterialfv code, but OGL requires the > glMaterialfv call to come after! That's *REALLY* unclear in the OpenGL spec. Many of the experts (including two members of the ARB) have disagreed on this point. Mesa *used* to behave as you have described it - but the latest versions do not. It's a mess! > So, i tried to work around this by changing the order in ssgSimpleState.cxx. > > That worked, so i finally got a green triangle. What OpenGL implementation do you have - and what PLIB are you using? > Surely there is some way to do simple colored geometry without all the > hacking i had to do? Yes - 99% of people put the colour in the leaf node and enable GL_COLOR_MATERIAL. This is presumed to be faster than changing the colour with glMaterial (the OpenGL RedBook says that somewhere) - and you can change the colour with vertex arrays, etc. It's *possible* that you have found a bug in the state apply code - but I'm not convinced that it isn't an error in your OpenGL - or something else screwed up. Can you mail me a short example program so that I can investigate more carefully? > Please help, i would really love to be able to use SSG. Sure - I'm always anxious to help people with interesting applications. -- Steve Baker HomeEmail: <sjb...@ai...> WorkEmail: <sj...@li...> HomePage : http://web2.airmail.net/sjbaker1 Projects : http://plib.sourceforge.net http://tuxaqfh.sourceforge.net http://tuxkart.sourceforge.net http://prettypoly.sourceforge.net |
From: Ben D. <be...@wa...> - 2000-10-13 17:48:55
Attachments:
Green.cxx
|
Hi Steve, thanks for the quick response! > > if ( num_colours == 0 ) glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ) ; > > This forces all primitives to white if they don't have a color per vertex! > > No - it sets them to white if you didn't give the LEAF node a colour. That's > a very rare circumstance in practice. I don't understand. The num_colors field comes from this: int num_colours = getNumColours () ; which is the number of colors in the vertex color table. I would presume in general that more than one primitive will share the same vertex table, so color information will come from the state, not the per-vertex colors. Or are you saying that it is customary to make a ssgColourArray with a single element in it, for each differently-colored primitive?? > > In ssgSimpleState::apply(), it uses glMaterialfv to set the diffuse color. > > However, GL is in "Color Material" mode by default, so the glMaterialfv > > calls have no effect, making the shape default white. > > It's unwise to rely on OpenGL's default state. Many implementations get > that wrong. OK, i can set the state's state explicitly - but which is correct? Is disabling GL_COLOR_MATERIAL required to get any ssgSimpleState-colored objects? > No - it's simply that you didn't enable or disable GL_COLOR_MATERIAL explicitly > and you didn't set the glColorMaterial setting to (say) GL_AMBIENT_AND_DIFFUSE > in the ssgStates that needed that. I've tried that, and the triangle is still white, not green. > > I tried to solve this problem by adding a statement to the triangle code: > > state->disable(GL_COLOR_MATERIAL); > > OK - that's going to mean that the polygon colour is entirely determined by > the glMaterial - but *ONLY* if GL_LIGHTING is enabled. I've tried that, and the triangle is still white, not green. > What OpenGL implementation do you have - and what PLIB are you using? I'm using a NVidia Quadro under Win2k, presumably OGL1.2. I've been using PLIB 1.2.0, but i looked at the latest 1.3.1 as well, and it didn't appear to have changed in the core functionality i'm using. > Yes - 99% of people put the colour in the leaf node and enable > GL_COLOR_MATERIAL. Does this mean i can't use ssgSimpleState? Using vertex colors ("in the leaf node") means that the ssgSimpleState values are ignored, since they are ignored by OpenGL when *not* using GL_COLOR_MATERIAL. Wouldn't that also mean that i can't set additional properties like Emission? You can't specify that with a ssgColourArray, so do 99% of people not care about any state besides diffuse? > Can you mail me a short example program so that I can investigate more carefully? I've attached a small example, which is basically the "tux" example with tux replaced by a "green" triangle, which appears white. Thanks! Ben |
From: Ben D. <be...@wa...> - 2000-10-13 20:40:17
|
I spent more time trying to debug the problem, and have more information. The reason that SSG seemed to be causing trouble is that inside ssgInit, it enables GL_COLOR_MATERIAL. What i discovered is that even if i disable GL_COLOR_MATERIAL afterwards, geometry is still rendered incorrectly! Instead of calling SSG, i tried simply calling: glEnable(GL_COLOR_MATERIAL); glDisable(GL_COLOR_MATERIAL); and was able to duplicate the white-object problem, thus it's not SSG's fault. The question remains why merely enabling and disabling this state messes up rendering. Perhaps it's a driver bug, but the Quadro is a pretty common card. Anyone have an idea? Thanks, Ben |
From: Steve B. <sjb...@ai...> - 2000-10-13 23:25:10
|
Ben Discoe wrote: > glEnable(GL_COLOR_MATERIAL); > glDisable(GL_COLOR_MATERIAL); > > and was able to duplicate the white-object problem, thus it's not SSG's > fault. I was aware of a bug like this in Mesa - which (IIRC) was recently fixed. > The question remains why merely enabling and disabling this state messes up > rendering. Perhaps it's a driver bug, but the Quadro is a pretty common > card. Anyone have an idea? (The Quadro? That's just the 'professional' version of the GeForce - right?) Are you using Linux or Windoze? If Linux, are you using the nVidia drivers or the Utah-GLX drivers? I'm not having any problems of this kind with the GeForce - and in fact the way we found the original Mesa bug was when I got my GeForce cards and all the peculiar lighting problems 'went away'. (BTW: The Quadro is a ripoff - it's an identical chip/board to the GeForce, with the exception of a single resistor value. If you know how to solder small surface-mount parts, you can convert a GeForce card into a Quadro!) -- Steve Baker HomeEmail: <sjb...@ai...> WorkEmail: <sj...@li...> HomePage : http://web2.airmail.net/sjbaker1 Projects : http://plib.sourceforge.net http://tuxaqfh.sourceforge.net http://tuxkart.sourceforge.net http://prettypoly.sourceforge.net |
From: Ben D. <be...@wa...> - 2000-10-14 17:36:23
|
> > glEnable(GL_COLOR_MATERIAL); > > glDisable(GL_COLOR_MATERIAL); > > > > and was able to duplicate the white-object problem, thus it's not SSG's > > fault. > > I was aware of a bug like this in Mesa - which (IIRC) was recently fixed. So far i've tried: Quadro with 0522 drivers Quadro with 0631 (latest) drivers GeForce DDR with 0631 drivers ... all under Win2k, and all of them exhibit the same problem! Could someone please try that small 'green triangle' example in my last email, does it work on anyone's system? > (BTW: The Quadro is a ripoff - it's an identical chip/board to the GeForce, > with the exception of a single resistor value. If you know how to solder > small surface-mount parts, you can convert a GeForce card into a Quadro!) The way i heard it, the Quadro was a ripoff because it was identical hardware, shipped with a different driver which enabled fast line-draw (because CAD people use wireframe so much). Anyhow, back at the time that card was purchased, it was also the only way to get a 64MB NVidia card. I'm really tearing my hair out here over making simple coloured geometry. Steve, i beg of you to please help me with my previous email, the one with the stuff about sgSimpleState/ssgVertexColourArray. Desperate thanks in advance, Ben |
From: Steve B. <sjb...@ai...> - 2000-10-14 19:35:45
|
Ben Discoe wrote: > > (BTW: The Quadro is a ripoff - it's an identical chip/board to the > GeForce, > > with the exception of a single resistor value. If you know how to solder > > small surface-mount parts, you can convert a GeForce card into a Quadro!) > > The way i heard it, the Quadro was a ripoff because it was identical > hardware, shipped with a different driver which enabled fast line-draw > (because CAD people use wireframe so much). Nearly. In fact, the driver is identical - but either it or the nVidia GeForce/Quadro chip reads the value of a resistor that's connected across two pins of the chip - depending on the value, it either does LINE-SMOOTH lines using the hardware - or in a software routine that must have been deliberately crippled because it's AMAZINGLY slow. One of my programs runs at 500Hz plus with non-smoothed lines (about 1000 polygons in wireframe mode) - and takes nearly a minute per frame (on a 750MHz PC) with line-smoothing turned on. When Mesa is run in software-only mode, it does the same image at about 10Hz. Hence either those nVidia programmers are really bad at their job - or it's deliberately crippled. > Anyhow, back at the time that > card was purchased, it was also the only way to get a 64MB NVidia card. Not any more. There are 64Mb GeForce-2's in Fry's at $280 right now. > I'm really tearing my hair out here over making simple coloured geometry. > Steve, i beg of you to please help me with my previous email, the one with > the stuff about sgSimpleState/ssgVertexColourArray. I'm *really* busy right now - I'll try to find some time...no promises though. You said that you could get this to happen with simple GL-level commands - shouldn't you just take out all of the PLIB code and mail your example to one of the OpenGL mailing lists (and possibly to the nVidia developers) ?? -- Steve Baker HomeEmail: <sjb...@ai...> WorkEmail: <sj...@li...> HomePage : http://web2.airmail.net/sjbaker1 Projects : http://plib.sourceforge.net http://tuxaqfh.sourceforge.net http://tuxkart.sourceforge.net http://prettypoly.sourceforge.net |
From: Ben D. <be...@wa...> - 2000-10-17 01:28:23
|
From: "Steve Baker" <sjb...@ai...> > > > I'm really tearing my hair out here over making simple coloured geometry. > > Steve, i beg of you to please help me with my previous email, the one with > > the stuff about ssgSimpleState/ssgVertexColourArray. > > You said that you could get this to happen with simple GL-level commands - shouldn't > you just take out all of the PLIB code and mail your example to one of the OpenGL > mailing lists (and possibly to the nVidia developers) ?? There is more than one problem. Here are two of them: 1. Using enable-disable of GL_COLOR_MATERIAL does not properly disable the state. I confirmed this using just OpenGL calls, on multiple NVidia cards and drivers. I also found a workaround, which consists of calling glColorMaterial(GL_FRONT, GL_DIFFUSE) *before* calling glEnable(GL_COLOR_MATERIAL ) for the first time. No logical reason why this should make it work, but it does. 2. I haven't found a way to use ssgSimpleState/ssgVtxTable to make simple colored geometry. That's the current killer, if there's no solution then i'll have to abandon PLIB/SSG. Thanks, Ben |
From: Steve B. <sjb...@ai...> - 2000-10-17 03:55:51
|
Ben Discoe wrote: > There is more than one problem. Here are two of them: > > 1. Using enable-disable of GL_COLOR_MATERIAL does not properly disable the > state. I confirmed this using just OpenGL calls, on multiple NVidia cards > and drivers. I also found a workaround, which consists of calling > glColorMaterial(GL_FRONT, GL_DIFFUSE) *before* calling > glEnable(GL_COLOR_MATERIAL ) for the first time. No logical reason why this > should make it work, but it does. Make that the first line of your code after ssgInit() and you are done then! > 2. I haven't found a way to use ssgSimpleState/ssgVtxTable to make simple > colored geometry. That's the current killer, if there's no solution then > i'll have to abandon PLIB/SSG. Well, it can certainly be done - I'm still pretty confused as to your precise problem - but SSG doesn't really do anything different than the underlying OpenGL calls. -- Steve Baker HomeEmail: <sjb...@ai...> WorkEmail: <sj...@li...> HomePage : http://web2.airmail.net/sjbaker1 Projects : http://plib.sourceforge.net http://tuxaqfh.sourceforge.net http://tuxkart.sourceforge.net http://prettypoly.sourceforge.net |
From: Ben D. <be...@wa...> - 2000-10-17 21:06:18
|
> > 1. Using enable-disable of GL_COLOR_MATERIAL does not properly disable the > > state... I also found a workaround, which consists of calling > > glColorMaterial(GL_FRONT, GL_DIFFUSE) *before* calling > > glEnable(GL_COLOR_MATERIAL ) for the first time. > > Make that the first line of your code after ssgInit() and you are done then! That's the first line *before*, not after. ssgInit enables the state, so the glColorMaterial call is required before that in order for subsequent disables to work (with NVidia cards/drivers). > > 2. I haven't found a way to use ssgSimpleState/ssgVtxTable to make simple > > colored geometry. That's the current killer, if there's no solution then > > i'll have to abandon PLIB/SSG. > > Well, it can certainly be done I've spent a lot of time trying, even tried fixing the SSG code, read ever word of the documentation, then wrote the mailing list found that nobody here has known either. > I'm still pretty confused as to your precise problem When you get some time to run that test program, and if the triangle is white, you can see them problem clearly on your own machine: SSG apparently doesn't let you give objects a non-white material without using per-vertex color. I've used a lot of 3D APIs over the years, and this is first time i've ever seen a limitation like this. -Ben |