Sign in to follow this  
therealremi

OpenGL varying color per vertex based on vertex normal in Cg/HLSL

Recommended Posts

therealremi    110
I was just trying to achieve color varying per vertex based on vertex normals for testing purposes. However I only get solid color per whole mesh (and I know the normals are ok cause I drew them using OpenGL lines). Maybe someone can take a look? struct vertex_input { float4 position : POSITION; float3 normal : NORMAL; }; struct vertex_output { float4 position : POSITION; float4 color : COLOR; }; vertex_output vertex_program(vertex_input IN, uniform float4x4 model_view_proj, { vertex_output OUT; OUT.position = mul(model_view_proj, float4(position, 1.0f)); float3 normal = normalize(IN.normal); normal = 0.5f + 0.5f*normal; OUT.color = float4(normal, 1.0f); return OUT; }

Share this post


Link to post
Share on other sites
iNsAn1tY    476
It looks like there's an error in your program, it isn't being compiled properly, and OpenGL is using the default pipeline instead of your program. There's a comma ',' after model_view_proj instead of a left parenthesis ')'. Are you checking for compilation errors? I assume you're using Cg, so you need to check the value returned from cgGetError after you create and compile your vertex program. If it returns anything other than CG_NO_ERROR, then you can use cgGetErrorString and cgGetLastListing to get detailed information about what failed, and where.

A very simple way of testing for your current problem would be to call glColor with a known colour like red before you render. If the model is all red instead of all white (which is the default OpenGL colour), you know that OpenGL is using the default pipeline instead of your program.

Share this post


Link to post
Share on other sites
therealremi    110
no, no, it does compile properly, I check that in Cg, this coma was added by mistake when I edited the post. The model takes bluish color but it is uniform on the whole model and it should vary per vertex since the normals are very varied.


[Edited by - therealremi on March 4, 2007 7:07:23 AM]

Share this post


Link to post
Share on other sites
Todo    451
This is just a guess, but if the model has a uniform blueish colour, then it looks to me like your normals are defined (or being transformed) in local space, or local to each face. Are you sure you didn't transform them into world space before you drew them?

To clarify a bit: you could think your normals are correct, when they are not, because of a flawed transformation somewhere.

Share this post


Link to post
Share on other sites
therealremi    110
hmm, I'm not a math guy but they are computed directly from face vertices (taking the cross product of two face vectors) and so they should be in the same coordinate space as the vertices.
So the shader looks ok? Is it just the normals that can be wrong? (although I was able to draw them as lines in OpenGL and they looked right)

Share this post


Link to post
Share on other sites
iNsAn1tY    476
Quote:
Original post by therealremi
no, no, it does compile properly, I check that in Cg, this coma was added by mistake when I edited the post. The model takes bluish color but it is uniform on the whole model and it should vary per vertex since the normals are very varied.

Ah, if it's a typo, then the program's not the problem.

Quote:
Original post by therealremi
hmm, I'm not a math guy but they are computed directly from face vertices (taking the cross product of two face vectors) and so they should be in the same coordinate space as the vertices.
So the shader looks ok? Is it just the normals that can be wrong? (although I was able to draw them as lines in OpenGL and they looked right)

Your program works fine in RenderMonkey (tested on a sphere object, the sphere is coloured as you'd expect)...so I guess it has to be your normals.

Are you submitting them to OpenGL properly?

Share this post


Link to post
Share on other sites
therealremi    110
thanks for checking iNsAn1tY.

Here's what I do in OpenGL:
glVertexPointer(3, GL_FLOAT, 0, geometry_coordinates);
glNormalPointer(GL_FLOAT, 0, normal_coordinates);
glIndexPointer(GL_INT, 0, indices);
glDrawElements(GL_TRIANGLES, indices_count, GL_UNSIGNED_INT, indices);

And as I said, I did this to draw normals:
glLineWidth(3.0f);
glBegin(GL_LINES);
for (unsigned int j=0; j<geometry_coordinates_count/3; j++)//for every vertex
{
glVertex3f(geometry_coordinates[j*3 + 0], geometry_coordinates[j*3 + 1], geometry_coordinates[j*3 + 2]); //line start
float x = geometry_coordinates[j*3 + 0] + 0.7f * normal_coordinates[j*3 + 0];
float y = geometry_coordinates[j*3 + 1] + 0.7f * normal_coordinates[j*3 + 1];
float z = geometry_coordinates[j*3 + 2] + 0.7f * normal_coordinates[j*3 + 2];
glVertex3f(x, y, z); //line end
}
glEnd();

Share this post


Link to post
Share on other sites
Todo    451
I don't really see an error (logical or otherwise) there either, and since iNsAn1tY tested it in RenderMonkey, I guess the problem lies somewhere else. Could you please try it in ATI's RenderMonkey or something similar yourself? I can't really think of anything else, except for the fact that you have to enable the throughput of vertex attributes, or in this case:

glEnableClientState( GL_NORMAL_ARRAY );


But I suspect you already know this...

Share this post


Link to post
Share on other sites
iNsAn1tY    476
Quote:
Original post by Todo
[Code snippet]

I see a suspect function call in your code: the one to glIndexPointer. Try removing that and any call you have to glEnableClientState( GL_INDEX_ARRAY ). "Index" here doesn't have anything to do with an index array, it refers to color indexes (not sure what they are, never used 'em; could be a relic of an earlier OpenGL version). This could be messing up your rendering.

Quote:
Original post by Todo
..except for the fact that you have to enable the throughput of vertex attributes, or in this case:
glEnableClientState( GL_NORMAL_ARRAY );
But I suspect you already know this...

Heh, I had a really nice one like this a few months ago. I forgot one little call to enable texturing, and it caused huge problems [grin]

Share this post


Link to post
Share on other sites
therealremi    110
iNsAn1tY, Todo, your response has been great. I'm ashamed to admit that;) but I did forget to include
glEnableClientState( GL_NORMAL_ARRAY );
and now it seems to work.

iNsAn1tY, are you sure with that?:
Quote:

I see a suspect function call in your code: the one to glIndexPointer. Try removing that and any call you have to glEnableClientState( GL_INDEX_ARRAY ). "Index" here doesn't have anything to do with an index array, it refers to color indexes

Share this post


Link to post
Share on other sites
Todo    451
Yeah, he's right. Colour indices point into a colour palette, which is the ancestor of todays true colour (24-bits and up) output. I should've spotted that. You can omit that call, it's faulty and you provide a pointer to your indices in the call below it anyway.

Share this post


Link to post
Share on other sites
iNsAn1tY    476
Quote:
Original post by therealremi
iNsAn1tY, Todo, your response has been great. I'm ashamed to admit that;) but I did forget to include
glEnableClientState( GL_NORMAL_ARRAY );
and now it seems to work.

Ah, happens all the time [smile] Glad it's sorted.

Quote:
Original post by Todo
Yeah, he's right. Colour indices point into a colour palette, which is the ancestor of todays true colour (24-bits and up) output. I should've spotted that. You can omit that call, it's faulty and you provide a pointer to your indices in the call below it anyway.

So that what it does...I thought it might have something to do with palettes. I remember when you had to do that, 256 colours way back with DirectDraw [grin]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Similar Content

    • By pseudomarvin
      I assumed that if a shader is computationally expensive then the execution is just slower. But running the following GLSL FS instead just crashes
      void main() { float x = 0; float y = 0; int sum = 0; for (float x = 0; x < 10; x += 0.00005) { for (float y = 0; y < 10; y += 0.00005) { sum++; } } fragColor = vec4(1, 1, 1 , 1.0); } with unhandled exception in nvoglv32.dll. Are there any hard limits on the number of steps/time that a shader can take before it is shut down? I was thinking about implementing some time intensive computation in shaders where it would take on the order of seconds to compute a frame, is that possible? Thanks.
    • By Arulbabu Donbosco
      There are studios selling applications which is just copying any 3Dgraphic content and regenerating into another new window. especially for CAVE Virtual reality experience. so that the user opens REvite or CAD or any other 3D applications and opens a model. then when the user selects the rendered window the VR application copies the 3D model information from the OpenGL window. 
      I got the clue that the VR application replaces the windows opengl32.dll file. how this is possible ... how can we copy the 3d content from the current OpenGL window.
      anyone, please help me .. how to go further... to create an application like VR CAVE. 
       
      Thanks
    • By cebugdev
      hi all,

      i am trying to build an OpenGL 2D GUI system, (yeah yeah, i know i should not be re inventing the wheel, but this is for educational and some other purpose only),
      i have built GUI system before using 2D systems such as that of HTML/JS canvas, but in 2D system, i can directly match a mouse coordinates to the actual graphic coordinates with additional computation for screen size/ratio/scale ofcourse.
      now i want to port it to OpenGL, i know that to render a 2D object in OpenGL we specify coordiantes in Clip space or use the orthographic projection, now heres what i need help about.
      1. what is the right way of rendering the GUI? is it thru drawing in clip space or switching to ortho projection?
      2. from screen coordinates (top left is 0,0 nd bottom right is width height), how can i map the mouse coordinates to OpenGL 2D so that mouse events such as button click works? In consideration ofcourse to the current screen/size dimension.
      3. when let say if the screen size/dimension is different, how to handle this? in my previous javascript 2D engine using canvas, i just have my working coordinates and then just perform the bitblk or copying my working canvas to screen canvas and scale the mouse coordinates from there, in OpenGL how to work on a multiple screen sizes (more like an OpenGL ES question).
      lastly, if you guys know any books, resources, links or tutorials that handle or discuss this, i found one with marekknows opengl game engine website but its not free,
      Just let me know. Did not have any luck finding resource in google for writing our own OpenGL GUI framework.
      IF there are no any available online, just let me know, what things do i need to look into for OpenGL and i will study them one by one to make it work.
      thank you, and looking forward to positive replies.
    • By fllwr0491
      I have a few beginner questions about tesselation that I really have no clue.
      The opengl wiki doesn't seem to talk anything about the details.
       
      What is the relationship between TCS layout out and TES layout in?
      How does the tesselator know how control points are organized?
          e.g. If TES input requests triangles, but TCS can output N vertices.
             What happens in this case?
      In this article,
      http://www.informit.com/articles/article.aspx?p=2120983
      the isoline example TCS out=4, but TES in=isoline.
      And gl_TessCoord is only a single one.
      So which ones are the control points?
      How are tesselator building primitives?
    • By Orella
      I've been developing a 2D Engine using SFML + ImGui.
      Here you can see an image
      The editor is rendered using ImGui and the scene window is a sf::RenderTexture where I draw the GameObjects and then is converted to ImGui::Image to render it in the editor.
      Now I need to create a 3D Engine during this year in my Bachelor Degree but using SDL2 + ImGui and I want to recreate what I did with the 2D Engine. 
      I've managed to render the editor like I did in the 2D Engine using this example that comes with ImGui. 
      3D Editor preview
      But I don't know how to create an equivalent of sf::RenderTexture in SDL2, so I can draw the 3D scene there and convert it to ImGui::Image to show it in the editor.
      If you can provide code will be better. And if you want me to provide any specific code tell me.
      Thanks!
  • Popular Now