First attempt at non-deprecated code

Started by
31 comments, last by BackwardSpy 13 years, 4 months ago
Hey everyone; first post here :)

Basically, I want to start writing my OpenGL code the "proper" way, i.e. not using deprecated functions.

Here's what I've come up with so far for drawing a green triangle to the screen. I've come up with this by means of the scant online resources for GL 3.3+ and the OpenGL superbible.

Sorry for the massive chunk of code, but any part of it could be relevant, so I figured it's probably safest just to post the entire thing.

#include <iostream>#include <SFML/Window.hpp>#define GLEW_STATIC#include <GL/glew.h>#include "math3d.h"int main(){	const int W = 800;	const int H = 600;	sf::Window window(sf::VideoMode(W, H), "Non-deprecated OpenGL", sf::Style::Close);	bool keys[sf::Key::Count];	glewInit();	// Triangle vertex data	GLfloat triangle[] = {		-1.0f, -1.0f, -5.0f,		1.0f, -1.0f, -5.0f,		0.0f, 1.0f, -5.0f };	GLfloat colour[] = { 0.5f, 1.0f, 0.0f };	// Create a buffer to hold the data	GLuint triangleBuffer;	glGenBuffers(1, &triangleBuffer);	// Hint that we'll be buffering a vertex array...	glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer);	// And finally put the data into the buffer	glBufferData(GL_ARRAY_BUFFER, sizeof(triangleBuffer), &triangleBuffer, GL_STATIC_DRAW);	// Initialise OpenGL stuff	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);	// Set up some basic shaders	const GLchar *vertShaderCode =		"#version 140\n"		"uniform mat4 mvpMatrix;\n"		"in vec4 vertex;\n"		"in vec3 inColour;\n"		"out vec3 outColour;\n"		"void main()\n"		"{\n"		"gl_Position = mvpMatrix * vertex;\n"		"}\n";	const GLchar *fragShaderCode =		"#version 140\n"		"in vec3 inColour;\n"		"out vec3 outColour;\n"		"void main()\n"		"{\n"		"outColour = inColour;\n"		"}\n";	// Create some new shaders	GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);	GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);	// Put the code into them	glShaderSource(vertShader, 1, &vertShaderCode, NULL);	glShaderSource(fragShader, 1, &fragShaderCode, NULL);	// Compile them	glCompileShader(vertShader);	glCompileShader(fragShader);	GLint status;	glGetShaderiv(vertShader, GL_COMPILE_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to load vertex shader" << std::endl;		GLint logLength = 0;		glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetShaderInfoLog(vertShader, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	glGetShaderiv(fragShader, GL_COMPILE_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to load fragment shader" << std::endl;		GLint logLength = 0;		glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetShaderInfoLog(fragShader, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	// Link them into a program to use in rendering	GLuint shaderProgram = glCreateProgram();	glAttachShader(shaderProgram, vertShader);	glAttachShader(shaderProgram, fragShader);	glLinkProgram(shaderProgram);	glUseProgram(shaderProgram);	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to link shader program" << std::endl;		GLint logLength = 0;		glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetProgramInfoLog(shaderProgram, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	// Get the location of the mvp matrix in the vertex shader	GLint mvpmLocation = glGetUniformLocation(shaderProgram, "mvpMatrix");	// And also get the location of the colour and vertex attributes	GLint colourLocation = glGetAttribLocation(shaderProgram, "inColour");	GLint vertexLocation = glGetAttribLocation(shaderProgram, "vertex");	// Construct a projection matrix	M3DMatrix44f projectionMatrix;	m3dMakePerspectiveMatrix(projectionMatrix, 35.0f, W / H, 0.0f, 100.0f);	// And a modelview matrix	M3DMatrix44f modelviewMatrix;	m3dLoadIdentity44(modelviewMatrix);		// And combine them into a modelview-projection matrix!	M3DMatrix44f mvpMatrix;	m3dMatrixMultiply44(mvpMatrix, projectionMatrix, modelviewMatrix);	while(window.IsOpened())	{		sf::Event e;		while(window.GetEvent(e))		{			switch(e.Type)			{			case(sf::Event::Closed):				window.Close();				break;			case(sf::Event::KeyPressed):				if(e.Key.Code == sf::Key::Escape)					window.Close();				else					keys[e.Key.Code] = true;				break;			case(sf::Event::KeyReleased):				keys[e.Key.Code] = false;				break;			default:				break;			}		}		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Tell the shader about our modelview projection matrix...		glUniformMatrix4fv(mvpmLocation, 1, GL_FALSE, mvpMatrix);		// Give it our triangle's vertices and colour		glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer);		glVertexAttribPointer(vertexLocation, 9, GL_FLOAT, GL_FALSE, 0, triangle);		glVertexAttribPointer(colourLocation, 3, GL_FLOAT, GL_FALSE, 0, colour);		glUseProgram(shaderProgram);		// Finally, we can do some drawing!		glDrawArrays(GL_TRIANGLES, 0, 3);		window.Display();	}	// Remove our buffer objects	glDeleteBuffers(1, &triangleBuffer);}


I've fiddled around with it for a while now, and I'm clueless what the problem is. The shaders are compiling and linking fine, so I don't think it's those.

Thanks in advance :)
Advertisement
The main problem is that when you put the data into the buffer, you mistake the second argument to be an OpenGL object while it's a size in bytes of your data.
The third argument is actually the data itself.

So
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleBuffer), &triangleBuffer, GL_STATIC_DRAW);

should be
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * sizeof(triangles), triangles, GL_STATIC_DRAW); // or does sizeof(static array) return bytes? don't remember


Aside from that, you use one color while using three vertices. This means that when the shaders process the second and third vertices, they get undefined (or does it default to something?) values for the color value.
Duplicate the color two more times to solve this.
You need to be calling glGetError() in your code, there are lots of problems that you could be hitting and have no idea unless you check for it.

Your shaders are not really right, I think you might have missed a few lines.
const GLchar *vertShaderCode =		"#version 140\n"		"uniform mat4 mvpMatrix;\n"		"in vec4 vertex;\n"		"in vec3 inColour;\n"		"out vec3 outColour;\n"		"void main()\n"		"{\n"		"gl_Position = mvpMatrix * vertex;\n"		"}\n";	const GLchar *fragShaderCode =		"#version 140\n"		"in vec3 inColour;\n"		"out vec3 outColour;\n"		"void main()\n"		"{\n"		"outColour = inColour;\n"		"}\n";


You have variables inColour and outColour in your vertex shader, but you do not use them. If you want outColour = inColour, then you need to specify this in the vertex shader. Again, you're referencing inColour in the fragment shader, which is not correct to do. The inputs to the fragment shader must be outputs from the vertex shader, not from your vbo data.

Finally you're assigning outColour in the fragment shader, but OpenGL doesn't know what to do with this.

How it it supposed to know that outColour is what you actually want the color of the pixel to be? When you're writing pixels you've got two choices:

1) Use the (deprecated) built in variable gl_FragColor, i.e.:
gl_FragColor = outColour

2) Tell opengl that outColour is supposed to be the pixel color with glBindFragDataLocation, eg:

glBindFragDataLocationEXT(shaderProgram,0,"outColour");

You call this right before glLinkProgram.

Your shaders should look more like this:
#version 140uniform mat4 mvpMatrix;in vec4 vertex;in vec3 inColour;out vec3 outVertexColour;void main(){gl_Position = mvpMatrix * vertex;outVertexColour = inColour;}//FRAGMENT#version 140in vec3 outVertexColour;main() {gl_FragColor = outVertexColour;//or define your own output variable}


[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
Also you've got a potential problem in your code. Your main loop looks like this

while(1) {
...
glUniformMatrix(...);

glUseProgram(...);

...
}

It's not causing a problem in your case because you never turn off your shader (so it's always on), but it's incorrect to call these in this order. You need the shader to be bound when you set the uniforms, and you're calling glUniformMatrix before enabling your shader.

You get away with it in this case because you've only got one shader, but if you were using a second shader later this would fail, because the wrong shader would be bound when you're uploading your uniform.

Just something to be aware of/ watch out for.
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
When creating the projection matrix, you are dividing W by H, but they are both integers, so the result will not be what you want.
My iOS 3D action/hacking game: http://itunes.apple....73873?ls=1&mt=8
Blog
Thank you all for your extremely helpful replies, I'll get to work fixing all of these problems right away!

Edit:
Ok, I think I've implemented all of the above suggestions
There's still nothing drawing on the screen though

#include <iostream>#include <SFML/Window.hpp>#define GLEW_STATIC#include <GL/glew.h>#include "math3d.h"int main(){	const int W = 800;	const int H = 600;	sf::Window window(sf::VideoMode(W, H), "Non-deprecated OpenGL", sf::Style::Close);	bool keys[sf::Key::Count];	glewInit();	// Triangle vertex data	GLfloat triangle[] = {		-1.0f, -1.0f, -5.0f,		1.0f, -1.0f, -5.0f,		0.0f, 1.0f, -5.0f };	GLfloat colour[] = {		0.5f, 1.0f, 0.0f,		0.5f, 1.0f, 0.0f,		0.5f, 1.0f, 0.0f,	};	// Create a buffer to hold the data	GLuint triangleBuffer;	glGenBuffers(1, &triangleBuffer);	// Hint that we'll be buffering a vertex array...	glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer);	// And finally put the data into the buffer	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * sizeof(triangle), &triangle, GL_STATIC_DRAW);	// Initialise OpenGL stuff	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);	// Set up some basic shaders	const GLchar *vertShaderCode =		"#version 140\n"		"uniform mat4 mvpMatrix;\n"		"in vec4 vertex;\n"		"in vec3 inColour;\n"		"out vec3 fColour;\n"		"void main()\n"		"{\n"		"gl_Position = mvpMatrix * vertex;\n"		"fColour = inColour;\n"		"}\n";	const GLchar *fragShaderCode =		"#version 140\n"		"in vec3 fColour;\n"		"void main()\n"		"{\n"		"gl_FragColor = vec4(fColour, 0);\n"		"}\n";	// Create some new shaders	GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);	GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);	// Put the code into them	glShaderSource(vertShader, 1, &vertShaderCode, NULL);	glShaderSource(fragShader, 1, &fragShaderCode, NULL);	// Compile them	glCompileShader(vertShader);	glCompileShader(fragShader);	GLint status;	glGetShaderiv(vertShader, GL_COMPILE_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to load vertex shader" << std::endl;		GLint logLength = 0;		glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetShaderInfoLog(vertShader, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	glGetShaderiv(fragShader, GL_COMPILE_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to load fragment shader" << std::endl;		GLint logLength = 0;		glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetShaderInfoLog(fragShader, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	// Link them into a program to use in rendering	GLuint shaderProgram = glCreateProgram();	glAttachShader(shaderProgram, vertShader);	glAttachShader(shaderProgram, fragShader);	glLinkProgram(shaderProgram);	glUseProgram(shaderProgram);	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to link shader program" << std::endl;		GLint logLength = 0;		glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetProgramInfoLog(shaderProgram, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	// Get the location of the mvp matrix in the vertex shader	GLint mvpmLocation = glGetUniformLocation(shaderProgram, "mvpMatrix");	// And also get the location of the colour and vertex attributes	GLint colourLocation = glGetAttribLocation(shaderProgram, "inColour");	GLint vertexLocation = glGetAttribLocation(shaderProgram, "vertex");	// Construct a projection matrix	M3DMatrix44f projectionMatrix;	m3dMakePerspectiveMatrix(projectionMatrix, 35.0f, static_cast<float>(W / H), 0.0f, 100.0f);	// And a modelview matrix	M3DMatrix44f modelviewMatrix;	m3dLoadIdentity44(modelviewMatrix);		// And combine them into a modelview-projection matrix!	M3DMatrix44f mvpMatrix;	m3dMatrixMultiply44(mvpMatrix, projectionMatrix, modelviewMatrix);	while(window.IsOpened())	{		sf::Event e;		while(window.GetEvent(e))		{			switch(e.Type)			{			case(sf::Event::Closed):				window.Close();				break;			case(sf::Event::KeyPressed):				if(e.Key.Code == sf::Key::Escape)					window.Close();				else					keys[e.Key.Code] = true;				break;			case(sf::Event::KeyReleased):				keys[e.Key.Code] = false;				break;			default:				break;			}		}		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Enable the shader program (not required in this case, but it's safe enough to do it anyway		glUseProgram(shaderProgram);		// Tell the shader about our modelview projection matrix...		glUniformMatrix4fv(mvpmLocation, 1, GL_FALSE, mvpMatrix);		// Give it our triangle's vertices and colour		glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer);		glVertexAttribPointer(vertexLocation, 9, GL_FLOAT, GL_FALSE, 0, triangle);		glVertexAttribPointer(colourLocation, 3, GL_FLOAT, GL_FALSE, 0, colour);		// Finally, we can do some drawing!		glDrawArrays(GL_TRIANGLES, 0, 3);		window.Display();	}	// Remove our buffer objects	glDeleteBuffers(1, &triangleBuffer);}


I'm going to fiddle with glGetError now, as was suggested earlier, to see if I can figure it out.

[Edited by - BackwardSpy on December 19, 2010 5:50:28 AM]
Ok, I made a LogErrors function that simply displays any error flags that are set.

I got an invalid value error, pointing to my glVertexAttribPointer for the vertex's location

I fixed that, still nothing drawing.

#include <iostream>#include <SFML/Window.hpp>#define GLEW_STATIC#include <GL/glew.h>#include "math3d.h"void LogErrors(){	GLenum err;	while((err = glGetError()) != GL_NO_ERROR)	{		switch(err)		{		case(GL_INVALID_ENUM):			std::cerr << "GL_INVALID_ENUM" << std::endl;			break;		case(GL_INVALID_VALUE):			std::cerr << "GL_INVALID_VALUE" << std::endl;			break;		case(GL_INVALID_OPERATION):			std::cerr << "GL_INVALID_OPERATION" << std::endl;			break;		case(GL_STACK_OVERFLOW):			std::cerr << "GL_STACK_OVERFLOW" << std::endl;			break;		case(GL_STACK_UNDERFLOW):			std::cerr << "GL_STACK_UNDERFLOW" << std::endl;			break;		case(GL_OUT_OF_MEMORY):			std::cerr << "GL_OUT_OF_MEMORY" << std::endl;			break;		case(GL_TABLE_TOO_LARGE):			std::cerr << "GL_TABLE_TOO_LARGE" << std::endl;			break;		}	}}int main(){	const int W = 800;	const int H = 600;	sf::Window window(sf::VideoMode(W, H), "Non-deprecated OpenGL", sf::Style::Close);	bool keys[sf::Key::Count];	glewInit();	// Triangle vertex data	GLfloat triangle[] = {		-1.0f, -1.0f, -5.0f,		1.0f, -1.0f, -5.0f,		0.0f, 1.0f, -5.0f };	GLfloat colour[] = {		0.5f, 1.0f, 0.0f,		0.5f, 1.0f, 0.0f,		0.5f, 1.0f, 0.0f,	};	// Create a buffer to hold the data	GLuint triangleBuffer;	glGenBuffers(1, &triangleBuffer);	// Hint that we'll be buffering a vertex array...	glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer);	// And finally put the data into the buffer	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * sizeof(triangle), &triangle, GL_STATIC_DRAW);	// Initialise OpenGL stuff	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);	// Set up some basic shaders	const GLchar *vertShaderCode =		"#version 140\n"		"uniform mat4 mvpMatrix;\n"		"in vec4 vertex;\n"		"in vec3 inColour;\n"		"out vec3 fColour;\n"		"void main()\n"		"{\n"		"gl_Position = mvpMatrix * vertex;\n"		"fColour = inColour;\n"		"}\n";	const GLchar *fragShaderCode =		"#version 140\n"		"in vec3 fColour;\n"		"void main()\n"		"{\n"		"gl_FragColor = vec4(fColour, 0.0);\n"		"}\n";	// Create some new shaders	GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);	GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);	// Put the code into them	glShaderSource(vertShader, 1, &vertShaderCode, NULL);	glShaderSource(fragShader, 1, &fragShaderCode, NULL);	// Compile them	glCompileShader(vertShader);	glCompileShader(fragShader);	GLint status;	glGetShaderiv(vertShader, GL_COMPILE_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to load vertex shader" << std::endl;		GLint logLength = 0;		glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetShaderInfoLog(vertShader, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	glGetShaderiv(fragShader, GL_COMPILE_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to load fragment shader" << std::endl;		GLint logLength = 0;		glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetShaderInfoLog(fragShader, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	// Link them into a program to use in rendering	GLuint shaderProgram = glCreateProgram();	glAttachShader(shaderProgram, vertShader);	glAttachShader(shaderProgram, fragShader);	glLinkProgram(shaderProgram);	glUseProgram(shaderProgram);	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to link shader program" << std::endl;		GLint logLength = 0;		glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetProgramInfoLog(shaderProgram, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	// Get the location of the mvp matrix in the vertex shader	GLint mvpmLocation = glGetUniformLocation(shaderProgram, "mvpMatrix");	// And also get the location of the colour and vertex attributes	GLint colourLocation = glGetAttribLocation(shaderProgram, "inColour");	GLint vertexLocation = glGetAttribLocation(shaderProgram, "vertex");	// Construct a projection matrix	M3DMatrix44f projectionMatrix;	m3dMakePerspectiveMatrix(projectionMatrix, 35.0f, static_cast<float>(W / H), 0.0f, 100.0f);	// And a modelview matrix	M3DMatrix44f modelviewMatrix;	m3dLoadIdentity44(modelviewMatrix);		// And combine them into a modelview-projection matrix!	M3DMatrix44f mvpMatrix;	m3dMatrixMultiply44(mvpMatrix, projectionMatrix, modelviewMatrix);	while(window.IsOpened())	{		sf::Event e;		while(window.GetEvent(e))		{			switch(e.Type)			{			case(sf::Event::Closed):				window.Close();				break;			case(sf::Event::KeyPressed):				if(e.Key.Code == sf::Key::Escape)					window.Close();				else					keys[e.Key.Code] = true;				break;			case(sf::Event::KeyReleased):				keys[e.Key.Code] = false;				break;			default:				break;			}		}		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Enable the shader program (not required in this case, but it's safe enough to do it anyway		glUseProgram(shaderProgram);		// Tell the shader about our modelview projection matrix...		glUniformMatrix4fv(mvpmLocation, 1, GL_FALSE, mvpMatrix);		// Give it our triangle's vertices and colour		glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer);		glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, triangle);		glVertexAttribPointer(colourLocation, 3, GL_FLOAT, GL_FALSE, 0, colour);		// Finally, we can do some drawing!		glDrawArrays(GL_TRIANGLES, 0, 3);		window.Display();		LogErrors();	}	// Remove our buffer objects	glDeleteBuffers(1, &triangleBuffer);}
This line:
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * sizeof(triangle), &triangle, GL_STATIC_DRAW);

is wrong.
You must pass size of data in bytes as second argument. Your size is sizeof(triangle). Also third argument is wrong. You must pass there pointer to data:

glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);



Also
static_cast<float>(W / H)

will perform division in integer domain, and only then will cast the resulting integer to float. What you want is division in flat domain:
static_cast<float>(W) / static_cast<float>(H)


When you have VBO bound (also in "old" deprecated GL context) glVertexAttribPointer function as last argument expects offset in bytes from the beggining of buffer. Not the full pointer value.

So yor call for triangle vertex locations should look like:
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);


As for color values - you haven't uploaded them to VBO (either same, which is recommended, if values won't change or to different one.

Also call LogErrors() function after each OpenGL call. And examine only first place where error happens, not only after full frame.
Ok, I've decided to just remove colour from the equation for now: I'll just give it the vertices and use a hard coded value for the colour

#include <iostream>#include <SFML/Window.hpp>#define GLEW_STATIC#include <GL/glew.h>#include "math3d.h"void LogErrors(){	GLenum err;	while((err = glGetError()) != GL_NO_ERROR)	{		switch(err)		{		case(GL_INVALID_ENUM):			std::cerr << "GL_INVALID_ENUM" << std::endl;			break;		case(GL_INVALID_VALUE):			std::cerr << "GL_INVALID_VALUE" << std::endl;			break;		case(GL_INVALID_OPERATION):			std::cerr << "GL_INVALID_OPERATION" << std::endl;			break;		case(GL_STACK_OVERFLOW):			std::cerr << "GL_STACK_OVERFLOW" << std::endl;			break;		case(GL_STACK_UNDERFLOW):			std::cerr << "GL_STACK_UNDERFLOW" << std::endl;			break;		case(GL_OUT_OF_MEMORY):			std::cerr << "GL_OUT_OF_MEMORY" << std::endl;			break;		case(GL_TABLE_TOO_LARGE):			std::cerr << "GL_TABLE_TOO_LARGE" << std::endl;			break;		}	}}int main(){	const float W = 800.0f;	const float H = 600.0f;	sf::Window window(sf::VideoMode(W, H), "Non-deprecated OpenGL", sf::Style::Close);	bool keys[sf::Key::Count];	glewInit();	// Triangle vertex data	GLfloat triangle[] = {		-1.0f, -1.0f, -5.0f,	// Vertices		1.0f, -1.0f, -5.0f,		0.0f, 1.0f, -5.0f };	// Create a buffer to hold the data	GLuint triangleBuffer;	glGenBuffers(1, &triangleBuffer);	// Hint that we'll be buffering a vertex array...	glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer);	// And finally put the data into the buffer	glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);	// Initialise OpenGL stuff	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);	// Set up some basic shaders	const GLchar *vertShaderCode =		"#version 140\n"		"uniform mat4 mvpMatrix;\n"		"in vec4 vertex;\n"		"void main()\n"		"{\n"		"gl_Position = mvpMatrix * vertex;\n"		"}\n";	const GLchar *fragShaderCode =		"#version 140\n"		"void main()\n"		"{\n"		"gl_FragColor = vec4(0.5, 1.0, 0.0, 0.0);\n"		"}\n";	// Create some new shaders	GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);	GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);	// Put the code into them	glShaderSource(vertShader, 1, &vertShaderCode, NULL);	glShaderSource(fragShader, 1, &fragShaderCode, NULL);	// Compile them	glCompileShader(vertShader);	glCompileShader(fragShader);	GLint status;	glGetShaderiv(vertShader, GL_COMPILE_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to load vertex shader" << std::endl;		GLint logLength = 0;		glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetShaderInfoLog(vertShader, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	glGetShaderiv(fragShader, GL_COMPILE_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to load fragment shader" << std::endl;		GLint logLength = 0;		glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetShaderInfoLog(fragShader, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	// Link them into a program to use in rendering	GLuint shaderProgram = glCreateProgram();	glAttachShader(shaderProgram, vertShader);	glAttachShader(shaderProgram, fragShader);	glLinkProgram(shaderProgram);	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);	if(status == GL_FALSE)	{		std::cerr << "Failed to link shader program" << std::endl;		GLint logLength = 0;		glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &logLength);		GLchar *log = new GLchar[logLength];		glGetProgramInfoLog(shaderProgram, logLength, &status, log);		std::cerr << log << std::endl;		delete[] log;	}	// Get the location of the mvp matrix in the vertex shader	GLint mvpmLocation = glGetUniformLocation(shaderProgram, "mvpMatrix");	// And also get the location of the colour and vertex attributes	GLint vertexLocation = glGetAttribLocation(shaderProgram, "vertex");	// Construct a projection matrix	M3DMatrix44f projectionMatrix;	m3dMakePerspectiveMatrix(projectionMatrix, 35.0f, W / H, 0.0f, 100.0f);	// And a modelview matrix	M3DMatrix44f modelviewMatrix;	m3dLoadIdentity44(modelviewMatrix);		// And combine them into a modelview-projection matrix!	M3DMatrix44f mvpMatrix;	m3dMatrixMultiply44(mvpMatrix, projectionMatrix, modelviewMatrix);	while(window.IsOpened())	{		sf::Event e;		while(window.GetEvent(e))		{			switch(e.Type)			{			case(sf::Event::Closed):				window.Close();				break;			case(sf::Event::KeyPressed):				if(e.Key.Code == sf::Key::Escape)					window.Close();				else					keys[e.Key.Code] = true;				break;			case(sf::Event::KeyReleased):				keys[e.Key.Code] = false;				break;			default:				break;			}		}		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Enable the shader program (not required in this case, but it's safe enough to do it anyway		glUseProgram(shaderProgram);		// Tell the shader about our modelview projection matrix...		glUniformMatrix4fv(mvpmLocation, 1, GL_FALSE, mvpMatrix);		// Give it our triangle's vertices		glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer);		glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);		// Finally, we can do some drawing!		glDrawArrays(GL_TRIANGLES, 0, 3);		window.Display();	}	// Remove our buffer objects	glDeleteBuffers(1, &triangleBuffer);}


I've fixed the things you mentioned (I think), still nothing onscreen
I don't thinkg zMin for m3dMakePerspectiveMatrix can have value 0. Try something small - 0.1f

Or better - try without any transformation matrix. Put gl_Position = vertex; in your vertex shader. Just draw triangle with these coordinates - (0,1,0),(-1,-1,0),(1,-1,0)

And what about LogErrors() function now? Does it show errors somewhere?

This topic is closed to new replies.

Advertisement