
[Solved] Black screen troubles
Posted Sunday, 16 October, 2011 - 14:16 by patrickm inHello All,
I'm having some trouble with Index Buffer Objects. My code worked fine when I was just using a Vertex Buffer Object and doing ordered draw, but now I'm trying to add an IBO to that, I just get a black screen. My code is below, I would appreciate someone taking a quick glance at it, it's probably something very simple that I've overlooked. Thank you for your time.
Patrick
Main.cs
using System; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; using OpenTK.Audio; using OpenTK.Audio.OpenAL; using OpenTK.Input; namespace opentk30test { class Game : GameWindow { public mesh m1; public shader s; public Matrix4 world; public Game() : base(800, 600, GraphicsMode.Default, "OpenTK Quick Start Sample") { VSync = VSyncMode.On; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); Console.WriteLine(GL.GetString(StringName.Version)); GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.VertexArray); GL.Enable(EnableCap.IndexArray); s = new shader("vertexShader.glsl", "fragmentShader.glsl"); Console.WriteLine (s.fragmentShaderMessage); Console.WriteLine (s.vertexShaderMessage); s.use (); Vector3[] vertices; vertices = new Vector3[3]; vertices[0].X=0.0f; vertices[0].Y=1.0f; vertices[0].Z=0.0f; vertices[1].X=0.0f; vertices[1].Y=-1.0f; vertices[1].Z=0.0f; vertices[2].X=-1.0f; vertices[2].Y=-1.0f; vertices[2].Z=0.0f; uint[] indices = {0,1,2}; m1=new mesh(vertices, indices); world = Matrix4.Scale(0.5f) * Matrix4.CreateRotationZ(0.0f) * Matrix4.CreateTranslation(new Vector3(0.0f, 0.0f, -10.0f)); } protected override void OnResize(EventArgs e) { base.OnResize(e); GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height); Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, Width / (float)Height, 1.0f, 64.0f); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref projection); } protected override void OnUpdateFrame(FrameEventArgs e) { base.OnUpdateFrame(e); if (Keyboard[Key.Escape]) Exit(); ErrorCode ec = GL.GetError(); if (ec != 0) { throw new System.Exception(ec.ToString()); } } protected override void OnRenderFrame(FrameEventArgs e) { base.OnRenderFrame(e); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref modelview); s.setUniformMatrix4f("gWorld", world); m1.draw(); SwapBuffers(); } [STAThread] static void Main() { using (Game game = new Game()) { game.Run(30.0); } } } }
Mesh.cs
using System; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; namespace opentk30test { public class mesh { public Vector3[] _vertices; public uint[] _indices; public uint _vbo; public uint _ibo; public mesh (Vector3[] vertices, uint[] indices) { _vertices = new Vector3[vertices.Length]; Array.Copy(vertices, _vertices, vertices.Length); _indices = new uint[indices.Length]; Array.Copy(indices, _indices, indices.Length); GL.GenBuffers(1, out _vbo); GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo); GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(Vector3.SizeInBytes * _vertices.Length), _vertices, BufferUsageHint.StaticDraw); GL.GenBuffers(1, out _ibo); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _ibo); GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(sizeof(uint) * _indices.Length), _indices, BufferUsageHint.StaticDraw); } public void draw() { GL.EnableVertexAttribArray(0); GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo); GL.VertexAttribPointer(0,3,VertexAttribPointerType.Float, false, 0, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _ibo); GL.DrawElements(BeginMode.Triangles, _indices.Length, DrawElementsType.UnsignedInt, 0); GL.DisableVertexAttribArray(0); } } }
Shader.cs
using System; using System.Collections.Generic; using System.IO; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; namespace opentk30test { public class shader { public int vertexShader; public string vertexShaderMessage; public int fragmentShader; public string fragmentShaderMessage; public int program; public shader(string vertexShaderSource, string fragmentshaderSource) { vertexShader = GL.CreateShader(ShaderType.VertexShader); fragmentShader = GL.CreateShader(ShaderType.FragmentShader); program = GL.CreateProgram(); using (StreamReader sr = new StreamReader(vertexShaderSource)) { GL.ShaderSource(vertexShader, sr.ReadToEnd()); } using (StreamReader sr = new StreamReader(fragmentshaderSource)) { GL.ShaderSource(fragmentShader, sr.ReadToEnd()); } GL.CompileShader (vertexShader); GL.CompileShader (fragmentShader); GL.AttachShader (program, vertexShader); GL.AttachShader (program, fragmentShader); GL.LinkProgram (program); GL.ValidateProgram (program); vertexShaderMessage = GL.GetShaderInfoLog (vertexShader); fragmentShaderMessage = GL.GetShaderInfoLog (fragmentShader); } public void setUniformVar1f(string name, float setVar) { int temp = GL.GetUniformLocation(program, name); GL.Uniform1(temp, setVar); } public void setUniformMatrix4f(string name, Matrix4 setVar) { int temp = GL.GetUniformLocation(program, name); GL.UniformMatrix4(temp, false, ref setVar); } public void use() { GL.UseProgram (program); } } }
fragmentShader.glsl
#version 330 in vec4 Color; out vec4 FragColor; void main() { FragColor = Color; }
vertexShader.glsl
#version 330 layout (location = 0) in vec3 Position; uniform mat4 gWorld; out vec4 Color; void main() { gl_Position = gWorld * vec4(Position, 1.0); Color = vec4(clamp(Position, 0.0, 1.0), 1.0); }


Comments
Re: Black screen troubles
- Maybe you're aware of this one already: Shader object's lifetime is incorrect. But this won't cause problems here.
- You don't need the lines "Array.Copy" because an array is actually a reference type.
- on the line with:
GL.VertexAttribPointer(0,3,VertexAttribPointerType.Float, false, 0, 0);
you set the stride to 0, but it should be size of Vector3 in bytes,
GL.VertexAttribPointer(0,3,VertexAttribPointerType.Float, false, 12, 0);
Re: Black screen troubles
Hey, thanks for taking a look. To respond to your points:
1. Not sure what you mean by this, can you clarify? I'm new to this and want to be as correct as possible.
2. I was running into an issue while making 2 meshes with the same array of vertices, I determined that it was because it was passing the array by reference, so the solution was to actually explicitly make a copy of the array.
3. Not sure how this got changed... I changed it to Vector3.SizeInBytes. This does not fix the issue though.
Any other ideas?
Re: Black screen troubles
1. Actually, I though 's' was a local variable but it looks like it's a member variable, so it's correct.
2. You should be able to use the same array on multiple models unless the vertex data is different.
Your modelview isn't used in the vertex shader.
I'm not sure. But I think you should either use
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
or pass the view and projection matrix as uniforms
gl_Position = projection_matrix * modelview_matrix * vec4(in_position, 1);
other stuff you could try is changing the clear colour to something other than black, maybe you can already see something.
or disable vertex culling.
If you really can't find the solution you could upload your project as a .rar so people on here can just run it and test there changes.
Re: Black screen troubles
I changed the copy statements back to regular assignment, the trouble was that I was using the same array to instantiate 2 meshes, just changing the array, so it caused an issue. Hindsight being 20/20 I should have just used 2 separate arrays.
I'm not using a projection matrix just yet actually. I'm running through this set of tutorials: http://ogldev.atspace.co.uk/index.html and I'm on tutorial 10. This code should just display a triangle whose vertices are the top center of the screen, and the 2 bottom corners.
I've zipped and uploaded my project to my personal server: Link
Re: Black screen troubles
hey just set the world matrix to identity and you'll see the triangle :)
Re: Black screen troubles
Thank you! I knew it had to be something simple like that. It seems the default far clip plane is 1.0f for some reason. At least, that's what it looks like. If I set the translation piece of my world matrix to 0,0,0 and make one of the Z elements of one of the vertices in my triangle 2.0f, then the triangle gets cut off halfway.
In any case thank you very much for the help, It is much appreciated.
Patrick