Having trouble with drawing a triangle. (Solved)

Hey everyone! I had taken a break from learning OpenGL for a few months and have been trying to get back into it in the last few days. I was looking over some of my old code and was finding that I didn’t exactly remember how everything works so I decided I’d try to come up with some basic stuff to see if I can jog my memory. I wrote this little program below which should just draw a triangle on the screen, however I’m not getting anything. I’ve looked it over and over and can’t find my error. I know it’s in poor taste to just dump a bunch of code and ask for help but I’m clueless where my problem is. If anyone is willing to offer an extra set of eyes I’d be very thankful!

import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.GLU;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;

public class BasicGLTest {

	private final float[] vertCoords = {-0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f};
	
	private final int[] indicies = {0, 1, 2};
	
	private final String vertexSource = "#version 330\n" +
								  "in vec3 position;\n" +
								  "void main() {\n" +
								  "gl_Position = vec4(position, 1);\n" +
								  "}";
	
	private final String fragmentSource = "#version 330\n" + 
									"void main() {\n" +
									"gl_FragColor = vec4(1, 0, 0, 1);\n" +
									"}";
	
	
	public void go() {
		
		try {
			Display.setDisplayMode(new DisplayMode(800, 600));
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			System.exit(1);
		}
		
		// Make the Shader
		
		int program = glCreateProgram();
		int vertexShader = glCreateShader(GL_VERTEX_SHADER);
		int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
		
		glShaderSource(vertexShader, vertexSource);
		glCompileShader(vertexShader);
		
		if(glGetShaderi(vertexShader, GL_COMPILE_STATUS) == GL_FALSE) {
			System.err.println(glGetShaderInfoLog(vertexShader, 512));
		}
		
		glShaderSource(fragmentShader, fragmentSource);
		glCompileShader(fragmentShader);
		
		if(glGetShaderi(fragmentShader, GL_COMPILE_STATUS) == GL_FALSE) {
			System.err.println(glGetShaderInfoLog(fragmentShader, 512));
		}
		
		glAttachShader(program, vertexShader);
		glAttachShader(program, fragmentShader);
		glLinkProgram(program);
		
		if(glGetProgrami(program, GL_LINK_STATUS) == GL_FALSE) {
			System.err.println(glGetProgramInfoLog(program, 512));
		}
		
		glValidateProgram(program);
		
		if(glGetProgrami(program, GL_VALIDATE_STATUS) == GL_FALSE) {
			System.err.println(glGetProgramInfoLog(program, 512));
		}
		
		glDetachShader(program, vertexShader);
		glDetachShader(program, fragmentShader);

		// Set up buffers
		
		int vbo = glGenBuffers();
		int ibo = glGenBuffers();
		
		FloatBuffer bf = BufferUtils.createFloatBuffer(vertCoords.length);
		bf.put(vertCoords);
		bf.flip();
		glBindBuffer(GL_ARRAY_BUFFER, vbo);
		glBufferData(GL_ARRAY_BUFFER, bf, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		
		IntBuffer bi = BufferUtils.createIntBuffer(indicies.length);
		bi.put(indicies);
		bi.flip();
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, bi, GL_STATIC_DRAW);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		
		
		
		while(!Display.isCloseRequested()) {
			
			//draw
			
			glClearColor(0.0f, 0.5f, 1.0f, 1.0f); // light blue clear color
			glClear(GL_COLOR_BUFFER_BIT);
			
			glUseProgram(program);
			
			glBindBuffer(GL_ARRAY_BUFFER, vbo);
			
			int positionLocation = glGetAttribLocation(program, "position");
			glEnableVertexAttribArray(positionLocation);
			glVertexAttribPointer(positionLocation, 3, GL_FLOAT, false, 0, 0);
			
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
			glDrawElements(GL_POINTS, 3, GL_UNSIGNED_BYTE, 0);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
			
			glDisableVertexAttribArray(positionLocation);
			
			glBindBuffer(GL_ARRAY_BUFFER, 0);
			
			glUseProgram(0);
			
			//update Display			
			
			Display.setTitle(GLU.gluErrorString(glGetError()));
			
			Display.update();
			
			Display.sync(60);
		}
		
		glDeleteProgram(program);
		Display.destroy();
		
	}
	
	public static void main(String[] args) {
		new BasicGLTest().go();
	}
	
}

Thank you very much! I’m sure it’s something simple that I just can’t see.

I added in this code to see if the buffers were working ok:


		FloatBuffer bf2 = BufferUtils.createFloatBuffer(vertCoords.length);
		
		glBindBuffer(GL_ARRAY_BUFFER, vbo);
		glGetBufferSubData(GL_ARRAY_BUFFER, 0, bf2);
		
		for(int i = 0; i < bf2.limit(); i++) {
			System.out.print("" + bf2.get() + ", ");
		}
		
		System.out.println();
		
		/////
		
		IntBuffer bi2 = BufferUtils.createIntBuffer(indicies.length);
		
		glBindBuffer(GL_ARRAY_BUFFER, vbo);
		glGetBufferSubData(GL_ARRAY_BUFFER, 0, bi2);
		
		for(int i = 0; i < bi2.limit(); i++) {
			System.out.print("" + bi2.get() + ", ");
		}

When I run this I get the following output:


-0.5, -0.5, 0.0, -0.5, 0.5, 0.0, 0.5, -0.5, 0.0, 
-1090519040, -1090519040, 0,

So the problem I think is with the indexArray data not being formatted correctly. It works as expected when I draw with glDrawArrays(). I’ll keep trying to figure this out and post if I find the problem. If anyone has any input I’d appreciate it!!! ;D

Okay ignore part of the post with the strange output, I realized I had a copy-and-paste error (which should be obvious to you guys of course). But I’t still getting the weird behavior where it’s working with glDrawArrays() but not glDrawElements().

Try removing this code:

glDetachShader(program, vertexShader);
glDetachShader(program, fragmentShader);

Why are you detaching the shaders from the program after everything is setup correctly?

I was following the advice from this post:

From what I can see there is no change in behavior whether or not those lines are present.

Well, they will affect your program eventually, so you should remove those lines.

Thanks, I will do so. I’ve finally figured out the problem as well. It seemed that the issue was with passing GL_UNSIGNED_BYTE in glDrawElements instead of GL_UNSIGNED_INT.

To those who are confused as to why we do not detach shaders to save memory:

Source: http://stackoverflow.com/questions/9113154/proper-way-to-delete-glsl-shader

Thanks for this info! I was pretty confused about this actually.