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 |