• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Jens Eckervogt
      Hello guys, 
       
      Please tell me! 
      How do I know? Why does wavefront not show for me?
      I already checked I have non errors yet.
      using OpenTK; using System; using System.Collections.Generic; using System.IO; namespace Tutorial_08.net.sourceskyboxer { public class WaveFrontLoader { private static List<Vector3> vertices; private static List<Vector2> textures; private static List<Vector3> normals; private static List<int> indices; private static float[] verticesArray; private static float[] normalsArray; private static float[] texturesArray; private static int[] indicesArray; private static string[] lines; public static RawModel LoadObjModel(string filename, Loader loader) { if (!File.Exists("Contents/" + filename + ".obj")) { throw new FileNotFoundException("Error: wavefront file doesn't exist path: " + filename + ".png"); } vertices = new List<Vector3>(); textures = new List<Vector2>(); normals = new List<Vector3>(); indices = new List<int>(); lines = File.ReadAllLines("Contents/" + filename + ".obj"); try { foreach (string line in lines) { if (line == "" || line.StartsWith("#")) continue; string[] token = line.Split(' '); switch(token[0]) { case ("o"): string o = token[1]; break; case "v": Vector3 vertex = new Vector3(float.Parse(token[1]), float.Parse(token[2]), float.Parse(token[3])); vertices.Add(vertex); break; case "vn": Vector3 normal = new Vector3(float.Parse(token[1]), float.Parse(token[2]), float.Parse(token[3])); normals.Add(normal); break; case "vt": Vector2 texture = new Vector2(float.Parse(token[1]), float.Parse(token[2])); textures.Add(texture); break; case "f": texturesArray = new float[vertices.Count * 2]; normalsArray = new float[vertices.Count * 3]; verticesArray = new float[vertices.Count * 3]; indicesArray = new int[indices.Count]; int vertexPointer = 0; foreach (Vector3 vex in vertices) { verticesArray[vertexPointer++] = vex.X; verticesArray[vertexPointer++] = vex.Y; verticesArray[vertexPointer++] = vex.Z; } for (int i = 0; i < indices.Count; i++) { indicesArray[i] = indices[i]; } break; } } } catch (FileNotFoundException f) { throw new FileNotFoundException($"OBJ file not found: {f.FileName}", f); } catch (ArgumentException ae) { throw new ArgumentException("OBJ file is damaged", ae); } return loader.loadToVAO(verticesArray, texturesArray, indicesArray); } } } And It have tried other method but it can't show for me.  I am mad now. Because any OpenTK developers won't help me.
      Please help me how do I fix.

      And my download (mega.nz) should it is original but I tried no success...
      - Add blend source and png file here I have tried tried,.....  
       
      PS: Why is our community not active? I wait very longer. Stop to lie me!
      Thanks !
    • By codelyoko373
      I wasn't sure if this would be the right place for a topic like this so sorry if it isn't.
      I'm currently working on a project for Uni using FreeGLUT to make a simple solar system simulation. I've got to the point where I've implemented all the planets and have used a Scene Graph to link them all together. The issue I'm having with now though is basically the planets and moons orbit correctly at their own orbit speeds.
      I'm not really experienced with using matrices for stuff like this so It's likely why I can't figure out how exactly to get it working. This is where I'm applying the transformation matrices, as well as pushing and popping them. This is within the Render function that every planet including the sun and moons will have and run.
      if (tag != "Sun") { glRotatef(orbitAngle, orbitRotation.X, orbitRotation.Y, orbitRotation.Z); } glPushMatrix(); glTranslatef(position.X, position.Y, position.Z); glRotatef(rotationAngle, rotation.X, rotation.Y, rotation.Z); glScalef(scale.X, scale.Y, scale.Z); glDrawElements(GL_TRIANGLES, mesh->indiceCount, GL_UNSIGNED_SHORT, mesh->indices); if (tag != "Sun") { glPopMatrix(); } The "If(tag != "Sun")" parts are my attempts are getting the planets to orbit correctly though it likely isn't the way I'm meant to be doing it. So I was wondering if someone would be able to help me? As I really don't have an idea on what I would do to get it working. Using the if statement is truthfully the closest I've got to it working but there are still weird effects like the planets orbiting faster then they should depending on the number of planets actually be updated/rendered.
    • By Jens Eckervogt
      Hello everyone, 
      I have problem with texture
      using System; using OpenTK; using OpenTK.Input; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL4; using System.Drawing; using System.Reflection; namespace Tutorial_05 { class Game : GameWindow { private static int WIDTH = 1200; private static int HEIGHT = 720; private static KeyboardState keyState; private int vaoID; private int vboID; private int iboID; private Vector3[] vertices = { new Vector3(-0.5f, 0.5f, 0.0f), // V0 new Vector3(-0.5f, -0.5f, 0.0f), // V1 new Vector3(0.5f, -0.5f, 0.0f), // V2 new Vector3(0.5f, 0.5f, 0.0f) // V3 }; private Vector2[] texcoords = { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) }; private int[] indices = { 0, 1, 3, 3, 1, 2 }; private string vertsrc = @"#version 450 core in vec3 position; in vec2 textureCoords; out vec2 pass_textureCoords; void main(void) { gl_Position = vec4(position, 1.0); pass_textureCoords = textureCoords; }"; private string fragsrc = @"#version 450 core in vec2 pass_textureCoords; out vec4 out_color; uniform sampler2D textureSampler; void main(void) { out_color = texture(textureSampler, pass_textureCoords); }"; private int programID; private int vertexShaderID; private int fragmentShaderID; private int textureID; private Bitmap texsrc; public Game() : base(WIDTH, HEIGHT, GraphicsMode.Default, "Tutorial 05 - Texturing", GameWindowFlags.Default, DisplayDevice.Default, 4, 5, GraphicsContextFlags.Default) { } protected override void OnLoad(EventArgs e) { base.OnLoad(e); CursorVisible = true; GL.GenVertexArrays(1, out vaoID); GL.BindVertexArray(vaoID); GL.GenBuffers(1, out vboID); GL.BindBuffer(BufferTarget.ArrayBuffer, vboID); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * Vector3.SizeInBytes), vertices, BufferUsageHint.StaticDraw); GL.GenBuffers(1, out iboID); GL.BindBuffer(BufferTarget.ElementArrayBuffer, iboID); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(int)), indices, BufferUsageHint.StaticDraw); vertexShaderID = GL.CreateShader(ShaderType.VertexShader); GL.ShaderSource(vertexShaderID, vertsrc); GL.CompileShader(vertexShaderID); fragmentShaderID = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(fragmentShaderID, fragsrc); GL.CompileShader(fragmentShaderID); programID = GL.CreateProgram(); GL.AttachShader(programID, vertexShaderID); GL.AttachShader(programID, fragmentShaderID); GL.LinkProgram(programID); // Loading texture from embedded resource texsrc = new Bitmap(Assembly.GetEntryAssembly().GetManifestResourceStream("Tutorial_05.example.png")); textureID = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, textureID); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texsrc.Width, texsrc.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); System.Drawing.Imaging.BitmapData bitmap_data = texsrc.LockBits(new Rectangle(0, 0, texsrc.Width, texsrc.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texsrc.Width, texsrc.Height, PixelFormat.Bgra, PixelType.UnsignedByte, bitmap_data.Scan0); texsrc.UnlockBits(bitmap_data); GL.Enable(EnableCap.Texture2D); GL.BufferData(BufferTarget.TextureBuffer, (IntPtr)(texcoords.Length * Vector2.SizeInBytes), texcoords, BufferUsageHint.StaticDraw); GL.BindAttribLocation(programID, 0, "position"); GL.BindAttribLocation(programID, 1, "textureCoords"); } protected override void OnResize(EventArgs e) { base.OnResize(e); GL.Viewport(0, 0, ClientRectangle.Width, ClientRectangle.Height); } protected override void OnUpdateFrame(FrameEventArgs e) { base.OnUpdateFrame(e); keyState = Keyboard.GetState(); if (keyState.IsKeyDown(Key.Escape)) { Exit(); } } protected override void OnRenderFrame(FrameEventArgs e) { base.OnRenderFrame(e); // Prepare for background GL.Clear(ClearBufferMask.ColorBufferBit); GL.ClearColor(Color4.Red); // Draw traingles GL.EnableVertexAttribArray(0); GL.EnableVertexAttribArray(1); GL.BindVertexArray(vaoID); GL.UseProgram(programID); GL.BindBuffer(BufferTarget.ArrayBuffer, vboID); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, IntPtr.Zero); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture3D, textureID); GL.BindBuffer(BufferTarget.ElementArrayBuffer, iboID); GL.DrawElements(BeginMode.Triangles, indices.Length, DrawElementsType.UnsignedInt, 0); GL.DisableVertexAttribArray(0); GL.DisableVertexAttribArray(1); SwapBuffers(); } protected override void OnClosed(EventArgs e) { base.OnClosed(e); GL.DeleteVertexArray(vaoID); GL.DeleteBuffer(vboID); } } } I can not remember where do I add GL.Uniform2();
    • By Jens Eckervogt
      Hello everyone
      For @80bserver8 nice job - I have found Google search. How did you port from Javascript WebGL to C# OpenTK.?
      I have been searched Google but it shows f***ing Unity 3D. I really want know how do I understand I want start with OpenTK But I want know where is porting of Javascript and C#?
       
      Thanks!
    • By mike44
      Hi
      I draw in a OpenGL framebuffer. All is fine but it eats FPS (frames per second), hence I wonder if I could execute the framebuffer drawing only every 5-10th loop or so?
      Many thanks
       
  • Advertisement
  • Advertisement
Sign in to follow this  

OpenGL Normal buffer troubles again... Strange... Any advice?

This topic is 3234 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, everyone. I am trying to render out a simple GL_FLAT cube using a vertex buffer as shown here: The cube I'm trying to render. The vertices I'm using are in the following array, which is fine (and it renders fine):
GLfloat vertices[24] =  {0.5,  0.5,  0.5,
                        -0.5,  0.5,  0.5,
                        -0.5, -0.5,  0.5,
                         0.5, -0.5,  0.5, 
                         0.5, -0.5, -0.5,
                         0.5,  0.5, -0.5,
                        -0.5,  0.5, -0.5,
                        -0.5, -0.5, -0.5};

The index array, which is also fine, is as follows:
GLubyte indices[24] =  {0,1,2,3,   // 24 indices
			0,3,4,5,
			0,5,6,1,
			1,6,7,2,
			7,4,3,2,
			4,7,6,5};

The normals array is being calculated automatically (for each face here, not each vertex, since the model is faceted, not smooth). It also seems to be fine:
normals 0x0012fcbc float [18] [0] 0.00000000 float [1] 0.00000000 float [2] 1.0000000 float [3] 1.0000000 float [4] 0.00000000 float [5] 0.00000000 float [6] 0.00000000 float [7] 1.0000000 float [8] 0.00000000 float [9] -1.0000000 float [10] 0.00000000 float [11] 0.00000000 float [12] 0.00000000 float [13] -1.0000000 float [14] 0.00000000 float [15] 0.00000000 float [16] 0.00000000 float [17] -1.0000000 float
And here is the code I have for the actual rendering:
//...
glTranslatef(0.0f, 0.0f, -3.0f);
glRotatef(45.0f, 0.0f, 1.0f, 0.0f);
// bind vertex and index buffers
g_VBE.glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertBuffer);
g_VBE.glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indBuffer);
glEnableClientState(GL_VERTEX_ARRAY);		// activate vertex coords array
    glVertexPointer(3, GL_FLOAT, 0, 0);		// last param is offset, not ptr

    // bind the normals buffer
    g_VBE.glBindBufferARB(GL_ARRAY_BUFFER_ARB, normBuffer);
    glEnableClientState(GL_NORMAL_ARRAY);
    glNormalPointer(GL_FLOAT, 0, 0); 

    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, 0);
  glDisableClientState(GL_NORMAL_ARRAY); // deactivate normals array
glDisableClientState(GL_VERTEX_ARRAY);  // deactivate vertex array
//...

I have a light set up at 0.0f, 0.0f, 1.0f, 1.0f and it seems to be working fine. It is right behind the camera, and since the cube is right in front, it should be dead on. However, here is what I'm seeing (this is the cube turned to 45 degree angle): The cube I'm rendering. As you can see, the two sides aren't lit equally bright, which means either the normals or something about the way I'm using them is messed up. If I try to do a 360-degree turnaround, the faces are not lit the same, and the lighting changes from face to face in a weird way. Any suggestions?

Share this post


Link to post
Share on other sites
Advertisement
Is the light directional or point? (or spot?)
If the cube is not 45° rotated, then that's how it's supposed to look.

I'm not into OpenGL (D3D guy here), but check the normals are being transformed (rotated as well), and that the light position isn't being transformed.

Quote:

If I try to do a 360-degree turnaround, (...) and the lighting changes from face to face in a weird way.


That could be either the flat shading artifact, or specular lighting turned on

Cheerio
Dark Sylinc

Share this post


Link to post
Share on other sites
It seems that you position your light in the wrong space(camera vs world space). A position of (0,0,1) would be behind your camera only if your light position is given in camera space. If your position is given in world space it will be most likely transformed by your MV matrix (translate->rotation) too, which will result in your light being in front of your cube and would only light one side of it.

Quicktest: Put your light at (1,0,1) or (-1,0,1), this should shade the visible faces equally if I'm right with my assumption.

--
Ashaman


Share this post


Link to post
Share on other sites
I wish that were true [bawling], but I've already tested for it...
When I set the light to -1,0,1 or 1,0,1 the picture doesn't change (the sides are lit uneven, pretty much the same). The light positioning isn't included in the glPush/glPopMatrix block with the cube rendering, so the cube is translated & rotated separate from the rest of the scene.

Quote:
Is the light directional or point? (or spot?)

By default in OpenGL it is of point/omni type.

Also, when the cube is rotating a full 360, I'm getting this one side lit brightly, and the side opposite to it also becomes lit brightly when it becomes illuminated, but the two other sides stay dim... Which is weird[attention]

Here, see for yourself:
Executable

As a testament, here is the cube at some point in the rotation looked at from the top/front view with the gluLookAt function:
Cube from top/front.

As you can see, not only are the side faces sporadically lit, but the top face is also lit, which shouldn't be happening.

I also changed my code now a bit (I thought I had some problems with the offset of the buffers in memory or, perhaps, was specifying the buffer to be overwritten or something like that):

/* offset is defined as (char *)pointer - (char *)NULL in OpenGL,
so we do the reverse to convert offset to pointer.*/

#define BUFFER_OFFSET(i) ((i) + (char *)NULL)

...
//sets up the objects for rendering
void SetupScene()
{
//...

//generate normals
GenerateNormalArray(vertices, 24, indices, normals, GL_QUADS);

geometry = calloc(42,sizeof(GLfloat));
memcpy(geometry, vertices, 24*(sizeof(GLfloat)));
memcpy(&(geometry[24]), normals, 18 * sizeof(GLfloat));

g_VBE.glGenBuffersARB(2, &geomBuffer);
g_VBE.glBindBufferARB(GL_ARRAY_BUFFER_ARB, geomBuffer);
g_VBE.glBufferDataARB(GL_ARRAY_BUFFER_ARB, (42*sizeof(GLfloat)), geometry, GL_STREAM_DRAW_ARB);
free(geometry);

g_VBE.glGenBuffersARB(1, &indBuffer);
g_VBE.glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indBuffer);
g_VBE.glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(indices), indices, GL_STREAM_DRAW_ARB);
}
/*Renders one frame*/
void Render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluLookAt(0.0, 1.5, 0.0, 0.0, 0.0, -3.0, 0.0, 1.0, 0.0);
glPushMatrix();

glTranslatef(0.0f, 0.0f, -3.0f);
glRotatef(angle, 0.0f, 1.0f, 0.0f);

// bind vertex and index buffers
g_VBE.glBindBufferARB(GL_ARRAY_BUFFER_ARB, geomBuffer);
g_VBE.glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indBuffer);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)); // last param is offset, not ptr
glNormalPointer(GL_FLOAT, 0, BUFFER_OFFSET(24*sizeof(GLfloat))); // bind the normals buffer

glEnableClientState(GL_VERTEX_ARRAY); // activate vertex coords array
glEnableClientState(GL_NORMAL_ARRAY); // activate nomral coords array

// draw 6 quads using offset of index array
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, 0);

glDisableClientState(GL_VERTEX_ARRAY); // deactivate vertex array
glDisableClientState(GL_NORMAL_ARRAY); // deactivate normal array
glPopMatrix();

angle += 0.2;
if (angle >= 360.0f)
{
angle = 0.0f;
}
glLoadIdentity();
glFlush();

/* Bring back buffer to foreground
*/

SwapBuffers(g_hdc);
}





[Edited by - Megamorph on June 10, 2009 9:33:36 AM]

Share this post


Link to post
Share on other sites
try removing the
glTranslatef(0.0f, 0.0f, -3.0f);
glRotatef(45.0f, 0.0f, 1.0f, 0.0f);

i.e position the cube at 0,0,0 in identity space

Share this post


Link to post
Share on other sites
Quote:

try removing the
glTranslatef(0.0f, 0.0f, -3.0f);
glRotatef(45.0f, 0.0f, 1.0f, 0.0f);

i.e position the cube at 0,0,0 in identity space


I did now... Lighting is just as messed up as it was... And how was that supposed to help me, exactly? I think we've established that the light wasn't rotating with the cube, or at least that it wasn't the real problem.

I don't mean to be mean to people who are trying to help me, I think I just watched too much House M.D., so my sarcasm center is a bit overexcited. My frustration center is also overstimulated...

And is anyone going to be willing to look at the code rather than the pictures? I mean, I know it's such a pretty cube, but [disturbed]...

I read out from the VBO to debug (using the glMapBufferARB function) and I got the same result that I put in, meaning that the data that is loaded appears correct, unless I'm missing something.

Share this post


Link to post
Share on other sites
Quote:
And how was that supposed to help me, exactly?

always simplify the problem as much as possible

u have 18normals, yet 24verts

Share this post


Link to post
Share on other sites
Quote:
always simplify the problem as much as possible


I agree, that's why I started out with a cube. But changing coordinates of the whole object doesn't really help with the lighting / rendering issues...

Quote:
u have 18normals, yet 24verts


LOL, I was waiting for someone to bring that up... How ironic.

I have 8 verts (24 coords), which compose a cube with 6 faces. 6 quads need 6 normals, each normal is represented by 3 floats, 6 * 3 yeilds 18, hence the normals array contains 18 floats.

Correct me if I'm wrong here, but since we're going for a flat rendering, those should be face normals - not vertex normals. In this decision I was going off some earlier gamedev.net post about some other normals issue and the sugguestion therein, as well as tutorials, such as this one, which use old-style GLbegin/GLend blocks to render a cube with normals (scroll down).

Although that does arouse suspicion... How would I then render a smooth-shaded mesh (how does OpenGL know whether to expect vertex normals or face normals?)

Perhaps I'm wrong and all I need is to calculate 8 vertex normals instead. In this case, would a vertex normal then = (normals of all adjacent faces)/(number of all adjacent faces)?

Share this post


Link to post
Share on other sites
Since you want hard edges, each face of the cube is made of 4 unique verts, and no two faces share any verts. Remember that a vert is a unique combination of position+normal (and any other attributes you add in the future like uv, color, etc).

You only have one index buffer, and that indexes into an array of positions and normals with the same index. 6 indices per face * 6 faces = 36 indices. 4 verts per face * 6 faces = 24 verts.

That means your index array should be sized at 36 (assuming triangle list), and your position and normal array should have 24 entries (24 float3's = 72 floats). Yes, your positions and normals will be duplicated, but each of your verts will be unique.

An array of positions and an array of normals of different sizes doesn't make sense if you only have one index buffer.

Smooth edges share more verts, so you wouldn't need 24 unique verts to describe a cube, you could do it with 8.

Share this post


Link to post
Share on other sites
Well if you're doing Face normals, then surely you only need 6 normals, one for each face.

Also, as OpenGL is a state machine, normals can be per-Vertex or per-Face. Using Immediate mode as an example.

This will be Per-Face Normals

glNorma3f(0.0, 0.0, 1.0);
glBegin(GL_QUADS);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glEnd();

This will be Per-Vertex Normals

glBegin(GL_QUADS);
glNorma3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glNorma3f(0.0, 1.0, 1.0);
glVertex3f(0.0, 1.0, 0.0);
glNorma3f(1.0, 0.0, 1.0);
glVertex3f(1.0, 1.0, 0.0);
glNorma3f(1.0, 1.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glEnd();



The numbers are arbitrary, it's the function calls that are important in this example.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement