OpenGL Can't draw a triangle? No error either.

Started by
10 comments, last by Krankles 11 years, 2 months ago

Shader compilation and mesh drawing could look like this:


struct Shader
{
	GLuint vertSh, fragSh;
	GLuint program;
};

Shader CompileShader(const char* vertShCode, const char* fragShCode)
{
	Shader sh;
	
	// create and compile vertex shader
	sh.vertSh=glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(sh.vertSh, 1, &vertShCode, NULL);
	glCompileShader(sh.vertSh);
	
	// create and compile fragment shader
	fh.fragSh=glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(sh.fragSh, 1, &fragShCode, NULL);
	glCompileShader(sh.fragSh);
	
	// create, bind attribute locations and link program
	sh.program=glCreateProgram();
	glAttachShader(sh.program, sh.vertSh);
	glAttachShader(sh.program, sh.fragSh);
	
	/*
	 * Arguments are: program's handle, an index which will be used
	 * as an argument for glVertexAttribPointer and glEnableVertexAttribArray,
	 * and a name which identifies the attribute in the vertex shader.
	 */
	glBindAttribLocation(sh.program, 0, "inPosition");
	glBindAttribLocation(sh.program, 1, "inColour");
	// other attributes; they must be bound before calling glLinkProgram
	
	glLinkProgram(sh.program);
	
	return sh;
}

void DrawMesh(const Shader& sh, GLuint vbo, GLuint numVertices)
{
	glUseProgram(sh.program);
	
	glBindBuffer(GL_ARRAY_BUFFER);
	
	glEnableVertexAttribArray(0);	// index, 0 == "inPosition"
	glVertexAttribPointer(
			0,		// index, 0 == "inPosition"
			3,		// size
			false,	// normalised
			24,		// vertex' stride, 3*float for position, and 3*float for colour
			0		// offset in the vbo
		);
	
	glEnableVertexAttribArray(1);	// vertex colour
	glVertexAttribPointer(1, 3, false, 24, (void*)12);
	
	glDrawArrays(GL_TRIANGLES, 0, numVertices);
}

I've omitted checking for errors to simplify the code.

Simple vertex shader:


#version 120

// "attribute" instead of "in"
attribute vec3 inPosition;
attribute vec3 inColour;

// "varying" instead of "out"
varying vec3 colour;

void main()
{
	gl_Position=vec4(inPosition, 1);
	colour=inColour;
}

Simple fragment shader:


#version 120

// "varying" instead of "in"
varying vec3 colour;

void main()
{
	gl_FragData[0]=colour;
}

Also, what are the differences between glEnableVertexAttribArray and glEnableClientState, and glVertexAttribPointer and glVertexPointer?

glEnableClientState and glVertexPointer is for fixed function pipline, where vertex attributes were "hard coded" in OpenGL (though you can use them in old GLSL).

glEnableVertexAttribArray, glVertexAttribPointer, and glBindAttribLocation are for modern OpenGL. By using them ( you can specify custom name for each attribute.

The first method was abandoned in new versions of OpenGL, so I suggest using the second one (it is in OpenGL 2.0 core).

But how come using glEnableVertexAttribArray and glVertexAttribPointer
works on Windows but not Linux? And the tutorial even uses this code
without shaders and it still draws the triangle.

Aparently it depends on a specific driver. AFAIK this isn't bound to work. Just a hack to avoid thowing shaders at you from the beginnning.

Also, going a bit off-topic, but is the tutorial teaching fixed-function pipeline? Or is it programmable?

If it teaches shaders, then it teaches programmable pipeline.

Advertisement

Thank you all for the help. I got it working now :)

This topic is closed to new replies.

Advertisement