Switching from Fixed-Function to GLSL - Help

Hi guys,

I am currently trying to switch our rendering from fixed-function to shaders and can’t seem to get anything to draw to screen. I know the shaders load and compile properly as I have the correct checks in place. Below is the code I think is relevant just to get something basic to render:

void OGL_Core_Renderer::initGL(){
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT);
	
	// Spit out system graphics information.
	cout << "	- OpenGL System Info -" << endl;
	
	driverName((char*)glGetString(GL_RENDERER));
	
	cout << "	Vendor: " << glGetString(GL_VENDOR) << endl;
	cout << "	Renderer: " << driverName() << endl;
	cout << "	Driver Version: " << glGetString(GL_VERSION) << endl;
	cout << "	GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl;
	
//	if(!checkExtensions())
//		throw Exception(0, "Graphics Requirements Not Met", "Your graphics driver does not meet the minimum requirements.");
	
	glGenVertexArrays(1, &mVertexArray);
	getError();
	glBindVertexArray(mVertexArray);
	getError();
	
	glGenBuffers(1, &mVertexBufferObject);
	getError();
	glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferObject);
	getError();
	glBufferData(GL_ARRAY_BUFFER, 2 * sizeof(DEFAULT_VERTEX_COORDS), DEFAULT_VERTEX_COORDS, GL_STATIC_DRAW);
	getError();
	
	glGenBuffers(1, &mTextureBufferObject);
	getError();
	glBindBuffer(GL_ARRAY_BUFFER, mTextureBufferObject);
	getError();
	glBufferData(GL_ARRAY_BUFFER, 2 * sizeof(DEFAULT_TEXTURE_COORDS), DEFAULT_TEXTURE_COORDS, GL_STATIC_DRAW);
	getError();
}
void OGL_Core_Renderer::drawVertexArray(GLuint textureId, bool defaultTextureCoords){
	clearScreen(0, 0, 0);
	
	/* We're going to create a simple diamond made from lines */
    const GLfloat vert[4][2] = {
		{  0.0,  1.0  }, /* Top point */
		{  1.0,  0.0  }, /* Right point */
		{  0.0, -1.0  }, /* Bottom point */
		{ -1.0,  0.0  } }; /* Left point */
	
	glUseProgram(mShaderManager->getShaderProgram());
	getError();
	
	glBindVertexArray(mVertexArray);
	
	glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferObject);
	getError();
	glBufferData(GL_ARRAY_BUFFER, 4 * 2 * sizeof(vert), vert, GL_STATIC_DRAW);
	getError();
	glEnableVertexAttribArray(mVertexArray);
	getError();
	
	glVertexAttribPointer(mVertexArray, 2, GL_FLOAT, GL_FALSE, 0, 0);
	getError();
	
	glDrawArrays(GL_LINES, 0, 2);
	getError();
	glDisableVertexAttribArray(mVertexArray);
	getError();
}

And the shaders:

Vert:

#version 150

in vec4 position;


void main()
{
    gl_Position = vec4(1.0, 1.0, 0.0, 0.0) + position;
}

Frag:

#version 150

out vec3 fragColor;


void main()
{
    fragColor = vec3(0,0,1);
}

I can’t for the life of me figure out what step I have missed or done improperly. I have no errors or crashing at all even in my OGL Profiler. Does anything standout to you guys?

There are a number of problems that you’re facing. But first, you’ll want to set up the vertex array object completely in initGL(), including the glVertexAttribPointer() and glEnableVertexAttribArray() calls. The Vertex Array Object (VAO) stores all that state. Next, you’ll want to remove all the glBufferData() and glVertexAttribPointer() calls from the draw() method because the single glBindVertexArray() call will setup all the state that you assigned to it in initGL(). So, in draw(), all you will need to do is bind the shader, bind the VAO, draw, then unbind the VAO and shader.

Next, the specific issues:

  • glEnableVertexAttribArray() takes an index from 0 to GL_MAX_VERTEX_ATTRIBS-1, not the vertex buffer object id. In the draw method, use glEnableVertexAttribArray(0). The same goes for glVertexAttribPointer() – the first parameter takes the attribute index, not the vertex buffer object ID.
  • if you’re using a vec2 position array, declare it as ‘in vec2 position’ in the shader. Then pad it to vec4 in the vertex shader: gl_Position = vec4( position, 0,1);
  • I’m not sure why you’re adding (1,1,0,0) to your position in the vertex shader. The values in your passed vertex array are correct for the midpoints of the window edges.
  • GL_LINES draws (v0, v1) as a line, then (v2, v3) as another line. What you want is GL_LINE_LOOP for this example (v0, v1, v2, v3, v0).

Also, you may want to avoid calling your texture coordinate array a ‘texture buffer object’ as that has a specific meaning in OpenGL (see the GL_ARB_texture_buffer_object extension or the GL3.2 core specification). Hope that helps!

That does seem to help, thank you! In order to update the vertex positions in the shader I would have to call glBufferData() again at some point right? At least that was my understanding of its function.

How would you guys recommend I send new vertex data to the GPU? It doesn’t seem to work if I just use glBufferData(). I haven’t been able to find anything online to clear this bit of confusion up for me.

Any guidance would be appreciated.