3

I've got this not-so-small-anymore tile-based game, which is my first real OpenGL project. I want to render every tile as a 3D object. So at first I created some objects, like a cube and a sphere, provided them with vertex normals and rendered them in immediate mode with flat shading. But since I've got like 10.000 objects per level, it was a bit slow. So I put my vertices and normals into VBOs.

That's where I encountered the first problem: Before using VBOs I just push()ed and pop()ed matrices for every object and used glTranslate / glRotate to place them in my scene. But when I did the same with VBOs, the lighting started to behave strangely. Instead of a fixed lighting position behind the camera, the light seemed to rotate with my objects. When moving around them 180 degrees I could see only a shadow.

So i did some research. I could not find any answer to my specific problem, but I read, that instead of using glTranslate/glRotate one should implement shaders and provide them with uniform matrices.

I thought "perhaps that could fix my problem too" and implemented a first small vertex shader program which only stretched my objects a bit, just to see if I could get a shader to work before focusing on the details.

void main(void)
{
    vec4 v = gl_Vertex;
    v.x = v.x * 0.5;
    v.y = v.y * 0.5;
    gl_Position = gl_ModelViewProjectionMatrix * v;
}

Well, my objects get stretched - but now OpenGLs flat shading is broken. I just get white shades. And I can't find any helpful information. So I got a few questions:

  • Can I only use one shader at a time, and when using my own shader, OpenGLs flat shading is turned off? So do I have to implement flat shading myself?

  • What about my vector normals? I read somewhere, that there is something like a normal-matrix. Perhaps I have to apply operations to my normals as well when modifying vertices?

genpfault
  • 51,148
  • 11
  • 85
  • 139
cargath
  • 832
  • 8
  • 18

1 Answers1

1

That your lighting gets messed up with matrix operations changes means, that your calls to glLightfv(..., GL_POSITION, ...) happen in the wrong context (not the OpenGL context, but state of matrices, etc.).

Well, my objects get stretched - but now OpenGLs flat shading is broken. I just get white shades

I think you mean Gourad shading (flat shading means something different). The thing is: If you're using a vertex shader you must do everthing the fixed function pipeline did. That includes the lighting calculation. Lighthouse3D has a nice tutorial http://www.lighthouse3d.com/tutorials/glsl-tutorial/lighting/ as does Nicol Bolas' http://arcsynthesis.org/gltut/Illumination/Illumination.html

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • I override Cocoas NSOpenGLView and put the glLightfv() into the [prepareOpenGL] method. That should be correct. Also, it did work in immediate mode, it broke since i switched to VBOs, so it DOES work where i put it, but not with VBOs. – cargath Dec 01 '11 at 13:35
  • @cargath: No. Lights must be positioned in the drawing function after the view has been set up, since light coordinates are multiplied with the modelview matrix. – datenwolf Dec 01 '11 at 13:38
  • Well, most people call it "flat shading". It's even called "flat shading" in OpenGL itself: glShadeModel(GL_FLAT); But i get what you mean, there is a shading method to really flatten all objects with the same name. I guess by everything the fixed function pipeline did you mean everything the FFP did at vertex transformation stage? – cargath Dec 01 '11 at 14:02
  • Thanks. All tutorials i could find put it in the prepareOpenGL method, so i guess i learned it wrong. But putting it in my drawing function did not help. – cargath Dec 01 '11 at 14:06
  • After some more experimentation i don't think the light rotates with my object anymore. I tried using a cube, and the lighting does change during the rotation, only it fades to dark and back to bright again and back to dark again and so on... strange. – cargath Dec 01 '11 at 14:10
  • Okay, i'm so sorry, turns out i'm just stupid: I accidentally turned on the TEX_COORD_ARRAY instead of the NORMAL_ARRAY, so lighting could not work correctly. Since you could help me with my other question, this is the correct answer. Thanks. – cargath Dec 01 '11 at 14:41
  • @cargath: Flat shading in OpenGL does not mean what you probably thing it means: Flat shading means, that only for the first vertex of a primitive the lighting calculation is performed and no lighting interpolation over the face happens. – datenwolf Dec 01 '11 at 18:29
  • That is exactly what i initially meant. – cargath Dec 04 '11 at 23:43