I’m trying to write a C++ application that will be render VAO and shaders.
That’s my algorithm:
- GLUT initialization
- GLEW initialization
- Shaders loading
- Shaders attaching
- Program linking
- Attribute’s and uniform’s location getting
- Buffers generating
- Data buffering
- Main loop (
display()
callback) - Buffers and program deleting
This algorithm is correct? Anyway, application doesn’t render anything. Where is my mistake?
My code is here (glew and freeglut required):
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <iostream>
#include <exception>
using namespace std;
/************************** SERVICE CLASSES AND FUNCTIONS ******************/
class ProgramException : public exception {
private:
const char *message;
const exception *cause;
public:
ProgramException(const char *message) : message(message), cause(nullptr) { }
ProgramException(const char *message, const exception *cause) : message(message), cause(cause) { }
virtual const char *what() const throw() { return message; }
const exception *why() const throw() { return cause; }
};
void checkOpenGLError() {
GLenum errCode;
if ((errCode = glGetError()) != GL_NO_ERROR) {
string error = "OpenGl error: ";
error.append((char *) gluErrorString(errCode));
throw new ProgramException(error.c_str());
}
}
void shaderLog(unsigned int shader, string shaderType) {
int infoLogLen = 0;
int charsWritten = 0;
char *infoLog;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
if (infoLogLen > 1) {
infoLog = new char[infoLogLen];
glGetShaderInfoLog(shader, infoLogLen, &charsWritten, infoLog);
shaderType.append(" -> ");
shaderType.append(infoLog);
cerr << shaderType << endl;
delete[] infoLog;
}
}
/************************* SHADER SOURCES **************************/
const char *vShaderSrc =
"#version 330
"
"attribute vec3 in_Position;
"
"void main() {
"
" gl_Position = vec4(in_Position, 1.0);
"
"}
";
const char *fShaderSrc =
"#version 330
"
"uniform vec4 in_Color;
"
"void main() {
"
" gl_FragColor = in_Color;
"
"}
";
/************************ GL identificators *****************/
int idWindowHandle;
GLuint idProgram;
GLuint idVao;
GLuint idVbo[2]; // positions and colors
GLuint idEbo;
GLuint idVShader;
GLuint idFShader;
GLuint idAttributePosition;
GLuint idUniformColor;
/***************************** INPUT DATA ********************/
int vertexIndices[3] = {
0, 1, 2
};
long lengthVertexIndices = 3;
float vertexPositions[9] = {
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 1.0, 0.0
};
long lengthVertexPositions = 9;
float vertexColors[12] = {
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0
};
long lengthVertexColors = 12;
/******************************* CALLBACKS ***********************/
void reshape(int w, int h) {
glViewport(0, 0, w, h);
}
void idle() {
glutPostRedisplay();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(idVao);
glUseProgram(idProgram);
glDrawArrays(GL_TRIANGLES, 0, 3);
glUseProgram(0);
glBindVertexArray(0);
glutSwapBuffers();
}
/******************************** START OF MAIN *********************/
int main(int argc, char **argv ) {
/******************** GLUT INIT ********************/
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_ALPHA);
glutInitContextVersion(3, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitWindowSize(320, 240);
glutCreateWindow("Hello");
glutIdleFunc(idle);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
/******************** GLEW INIT ********************/
glewExperimental = GL_TRUE;
GLenum glew_status;
try {
/* glewInit() may be caused of OpenGL invalid enumerant error,
* but this is not critical*/
glew_status = glewInit();
checkOpenGLError();
} catch (ProgramException *ignored) { }
if (glew_status != GLEW_OK) {
/* GLEW is not initialized */
string error = "GLEW error: ";
error.append((char *) glewGetErrorString(glew_status));
throw new ProgramException(error.c_str());
}
/* Check for accessibility of OpenGL 3.3 */
if (!GLEW_VERSION_3_3) {
string error = "No support for OpenGL 3.3 found : ";
error.append((char *) glewGetErrorString(glew_status));
throw new ProgramException(error.c_str());
}
/***************************** LOAD SHADERS *************************/
/* Vertex shader */
idVShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(idVShader, 1, &vShaderSrc, NULL);
glCompileShader(idVShader);
shaderLog(idVShader, "VShader");
/* Fragment shader */
idFShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(idFShader, 1, &fShaderSrc, NULL);
glCompileShader(idFShader);
shaderLog(idFShader, "FShader");
/***************************** ATTACH SHADERS *************************/
idProgram = glCreateProgram();
glAttachShader(idProgram, idVShader);
glAttachShader(idProgram, idFShader);
checkOpenGLError();
/************************** LINK PROGRAM ******************************/
glLinkProgram(idProgram);
int link_ok;
glGetProgramiv(idProgram, GL_LINK_STATUS, &link_ok);
if (!link_ok) {
throw new ProgramException("Error attach shaders");
}
checkOpenGLError();
/************************** GET ATTRIBUTES AND UNIFORMS ***************/
const char *positionAttributeName = "in_Position";
idAttributePosition = (GLuint) glGetAttribLocation(idProgram, positionAttributeName);
if (idAttributePosition == -1) {
string error = "Could not bind attribute ";
error.append(positionAttributeName);
throw new ProgramException(error.c_str());
}
const char *colorAttributeName = "in_Color";
idUniformColor = (GLuint) glGetUniformLocation(idProgram, colorAttributeName);
if (idUniformColor == -1) {
string error = "Could not bind uniform ";
error.append(colorAttributeName);
throw new ProgramException(error.c_str());
}
checkOpenGLError();
/******************** GEN BUFFERS ****************/
glGenVertexArrays(1, &idVao);
glGenBuffers(2, idVbo);
glGenBuffers(1, &idEbo);
checkOpenGLError();
/********************** BUFFER DATA ******************/
glBindVertexArray(idVao);
/* Element array */
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idEbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, lengthVertexIndices * sizeof(int),
vertexIndices, GL_STATIC_DRAW);
checkOpenGLError();
/* Position array */
glBindBuffer(GL_ARRAY_BUFFER, idVbo[0]);
glBufferData(GL_ARRAY_BUFFER, lengthVertexPositions * sizeof(float),
vertexPositions, GL_STATIC_DRAW);
glVertexAttribPointer(idAttributePosition, 3,
GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(idAttributePosition);
checkOpenGLError();
/* Color array */
glBindBuffer(GL_ARRAY_BUFFER, idVbo[1]);
glBufferData(GL_ARRAY_BUFFER, lengthVertexColors * sizeof(float),
vertexColors, GL_STATIC_DRAW);
glVertexAttribPointer(idUniformColor, 4,
GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(idAttributePosition);
/*********************** MAIN LOOP ********************/
glutMainLoop();
/********************** DISABLE ***********************/
glDisableVertexAttribArray(idAttributePosition);
glDisableVertexAttribArray(idUniformColor);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(2, idVbo);
glUseProgram(0);
glDeleteProgram(idProgram);
checkOpenGLError();
}