I create the vertex array, i create the shaders, compile and link them, but when i use drawarrays nothing happens.
No geometry is drawn on screen while i should see a red triangle.
No error in the command line no problem at all but the triangle won't appear.
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
using namespace std;
static GLuint compileShader(const string& source,GLuint type);
static int createShader(const string& vertexShader, const string& fragment);
int main(void){
// I INITIALISE GLFW TO HAVE THE LATEST VERSION OF THE SHADER VERSION
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//I CREATE THE WINDOW
GLFWwindow* window = glfwCreateWindow(800,600,"Dio suino",NULL,NULL);
glfwMakeContextCurrent(window);
glewExperimental= GL_TRUE;
//I INITIALISE GLEW
if(glewInit()!=GLEW_OK){
fprintf(stderr,"ERROR");
exit(1);
}
//I SPECIFY THE VERTEX DATA
float bufferData[6]={
0.5,-0.5,
-0.5,-0.5,
0.0,0.5
};
GLuint bufferId;
// I CREATE THE BUFFER, BIND IT AND SPECIFY ALL THE INFO NEEDED
glGenBuffers(1,&bufferId);
glBindBuffer(GL_ARRAY_BUFFER,bufferId);
glBufferData(GL_ARRAY_BUFFER,6*sizeof(float),bufferData,GL_STATIC_DRAW);
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,2*sizeof(float),0);
glEnableVertexAttribArray(0);
// I CREATE THE VERTEX AND FRAGMENT SHADERS
string vs,fs;
vs =
"#version 330 core \n"
"in vec4 position;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = position;\n"
"}\n";
fs =
"#version 330 core \n"
"out vec4 color;\n"
"\n"
"void main()\n"
"{\n"
" color = vec4(1.0,0.0,0.0,1.0);\n"
"}\n";
//I USE THE PROGRAM
int shaderProgram = createShader(vs,fs);
glUseProgram(shaderProgram);
glBindBuffer(GL_ARRAY_BUFFER,0);
// WINDOW LOOP: CLEAR COLOR, SWAP BUFFER ECC
while(!glfwWindowShouldClose(window)){
glClearColor(0,60,80,0);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES,0,3);
glfwSwapBuffers(window);
glfwPollEvents();
}
cout<< glGetString(GL_VERSION)<<endl;
return 0;
}
//CREATES THE SHADER PROGRAM WITH ALL THE SHADERS LINKED
static int createShader(const string& vertexShader, const string& fragment)
{
GLuint program = glCreateProgram();
GLuint vs = compileShader(vertexShader,GL_VERTEX_SHADER);
GLuint fs = compileShader(fragment,GL_FRAGMENT_SHADER);
glAttachShader(program,vs);
glAttachShader(program,fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
//COMPILES THE SHADER
static GLuint compileShader(const string& source,GLuint type)
{
GLuint id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id,1,&src,nullptr);
glCompileShader(id);
int debug;
glGetShaderiv(id,GL_COMPILE_STATUS,&debug);
if(debug == GL_FALSE){
int length;
glGetShaderiv(id,GL_INFO_LOG_LENGTH,&length);
char message[length];
glGetShaderInfoLog(id,length,&length,message);
fprintf(stderr,"Something went wrong in the shader of type %i: %s",type,message);
glDeleteShader(id);
}
return id;
}
Now these are the libraries that i have included.
The makefile:
CC = clang++
MAIN = main.cpp
LIB = -lglew -lglfw
FWORK = -framework OpenGl
NAME = -o dio -std=c++11
all:
${CC} ${MAIN} ${LIB} ${FWORK} ${NAME}
What am i doing wrong?
When you use a core profile OpenGL Context, then you have to create an named Vertex Array Object, because the default VAO (0) is not valid. The VAO states the specification of the vertex arrays.
You can switch to a compatibility profile context, to solve the issue, if it is supported by your hardware and driver (probably not on macOSX):
https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_Array_Object:
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
But, I recommend to create a Vertex Array Object, before the specification of the generic vertex array data. The VAO has to be bound, when glVertexAttribPointer
and glEnableVertexAttribArray
are called, because this instruction change the state vector of the VAO:
GLuint bufferId;
glGenBuffers(1,&bufferId);
glBindBuffer(GL_ARRAY_BUFFER,bufferId);
glBufferData(GL_ARRAY_BUFFER,6*sizeof(float),bufferData,GL_STATIC_DRAW);
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,2*sizeof(float),0);
glEnableVertexAttribArray(0);