
GL.Normal3 () not working when the parameters are integers
Posted Wednesday, 16 February, 2011 - 12:59 by migueltk inHi, ...
I have prepared a small program that demonstrates this. In the picture on the left when the parameters are integers and right when the parameters are floats.
Why does this happen?
using System; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; using OpenTK.Input; namespace LightingTest { public class LightingGameWindow : GameWindow { bool floatNormals = false; string titleBase = "LightingTest (Help: The key 'N' switching the parameter type of normal)"; public LightingGameWindow() : base(800, 600, new GraphicsMode(32, 16, 8, 0)) { Title = titleBase + " [Normals as integers]"; this.VSync = OpenTK.VSyncMode.Off; Keyboard.KeyDown += new EventHandler<KeyboardKeyEventArgs>(Keyboard_KeyDown); } void Keyboard_KeyDown(object sender, KeyboardKeyEventArgs e) { if(e.Key == Key.N) { floatNormals = !floatNormals; if(floatNormals) Title = titleBase + " [Normals as floats]"; else Title = titleBase + " [Normals as integers]"; } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); float[] mat_specular = { 1.0f, 1.0f, 1.0f, 1.0f }; float[] mat_shininess = { 50.0f }; float[] light_position = { 1.0f, 1.0f, 1.0f, 0.0f }; float[] light_ambient = { 0.5f, 0.5f, 0.5f, 1.0f }; GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); GL.ShadeModel(ShadingModel.Smooth); GL.Material(MaterialFace.Front, MaterialParameter.Specular, mat_specular); GL.Material(MaterialFace.Front, MaterialParameter.Shininess, mat_shininess); GL.Light(LightName.Light0, LightParameter.Position, light_position); GL.Light(LightName.Light0, LightParameter.Ambient, light_ambient); GL.Light(LightName.Light0, LightParameter.Diffuse, mat_specular); GL.Enable(EnableCap.Lighting); GL.Enable(EnableCap.Light0); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.ColorMaterial); GL.Enable(EnableCap.CullFace); } protected override void OnResize(EventArgs e) { base.OnResize(e); GL.Viewport(0, 0, Width, Height); GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); if (Width <= Height) { GL.Ortho(-1.5, 1.5, -1.5 * (double)Height / (double)Width, 1.5 * (double)Height / (double)Width, -10.0, 10.0); } else { GL.Ortho(-1.5 * (double)Width / (double)Height, 1.5 * (double)Width / (double)Height, -1.5, 1.5, -10.0, 10.0); } GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); } protected override void OnRenderFrame(FrameEventArgs e) { base.OnRenderFrame(e); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.PushMatrix(); { GL.Rotate(10, 1, 0, 0); GL.Rotate(10, 0, 1, 0); GL.Color3(0.0, 0.5, 1.0); GL.Begin(BeginMode.Quads); { // front face if(floatNormals) GL.Normal3(0, 0, 1.0f); else GL.Normal3(0, 0, 1); GL.Vertex3(-0.5, -0.5, 0.5); GL.Vertex3(0.5, -0.5, 0.5); GL.Vertex3(0.5, 0.5, 0.5); GL.Vertex3(-0.5, 0.5, 0.5); // back face if(floatNormals) GL.Normal3(0, 0, -1.0f); else GL.Normal3(0, 0, -1); GL.Vertex3(-0.5, -0.5, -0.5); GL.Vertex3(-0.5, 0.5, -0.5); GL.Vertex3(0.5, 0.5, -0.5); GL.Vertex3(0.5, -0.5, -0.5); // top face if(floatNormals) GL.Normal3(0, 1.0f, 0); else GL.Normal3(0, 1, 0); GL.Vertex3(-0.5, 0.5, -0.5); GL.Vertex3(-0.5, 0.5, 0.5); GL.Vertex3(0.5, 0.5, 0.5); GL.Vertex3(0.5, 0.5, -0.5); // bottom face if(floatNormals) GL.Normal3(0, -1.0f, 0); else GL.Normal3(0, -1, 0); GL.Vertex3(-0.5, -0.5, -0.5); GL.Vertex3(0.5, -0.5, -0.5); GL.Vertex3(0.5, -0.5, 0.5); GL.Vertex3(-0.5, -0.5, 0.5); // right face if(floatNormals) GL.Normal3(1.0f, 0, 0); else GL.Normal3(1, 0, 0); GL.Vertex3(0.5, -0.5, -0.5); GL.Vertex3(0.5, 0.5, -0.5); GL.Vertex3(0.5, 0.5, 0.5); GL.Vertex3(0.5, -0.5, 0.5); // left face if(floatNormals) GL.Normal3(-1.0f, 0, 0); else GL.Normal3(-1, 0, 0); GL.Vertex3(-0.5, -0.5, -0.5); GL.Vertex3(-0.5, -0.5, 0.5); GL.Vertex3(-0.5, 0.5, 0.5); GL.Vertex3(-0.5, 0.5, -0.5); } GL.End(); } GL.PopMatrix(); GL.Flush(); SwapBuffers(); } [STAThread] public static void Main(string[] args) { try { using (LightingGameWindow p = new LightingGameWindow()) { p.Run(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } } }


Comments
Re: GL.Normal3 () not working when the parameters are ...
The integer version is rescaled to [-1.0, 1.0] linearly. For instance:
corresponds to:
which is about -0.0000000004.6.
Re: GL.Normal3 () not working when the parameters are ...
Why is re-scaled? I understand that the right thing is not rescaled. The problem has been to adapt a code in java to csharp, using lwjgl, I understand that to maintain maximum compatibility with other wrappers right thing is not rescaled.
Regards, ...
Re: GL.Normal3 () not working when the parameters are ...
'Rescale' was a wrong choice of words. 'Map' is the correct term. This is done by the driver, not OpenTK:
The current normal is set to the given coordinates whenever glNormal is issued. Byte, short, or integer arguments are converted to floating-point format with a linear mapping that maps the most positive representable integer value to 1.0 and the most negative representable integer value to -1.0 .
http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml
OpenTK doesn't modify your parameters in any way. It passes them down to the drivers directly (with the sole exception of strings, which must be converted to ascii).
Re: GL.Normal3 () not working when the parameters are ...
Probably the java-based wrapper has no integer overload for this function and thus converts the integer parameter to float, thus (wrongly) calling a different function than OpenTK which chooses the intended function according to the parameter type.