Read access violation on draw calls even though GLEW is initialized properly - c++

I am using GLEW and GLFW and I am repeatedly getting this error :
Exception thrown at 0x0819FF06 in GLTest.exe: 0xC0000005: Access violation reading location 0x00000000.
I pretty sure that I have correctly initialized GLEW (which seems to be whats wrong when most people get this error).
bool Game_Window::CreateWindow()
{
if (glfwInit() != true)
return false;
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
m_window = glfwCreateWindow(m_width, m_height, m_title, NULL, NULL);
glfwMakeContextCurrent(m_window);
glewExperimental = true;
if (glewInit() != GLEW_OK)
return false;
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
std::cout << glGetString(GL_VERSION) << std::endl;
return true;
}
Here is the code I'm using to draw it:
#include "Game_Window.h"
#include "Shader.h"
float verticies[] =
{
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.0f,0.5f,0.0f,
};
GLuint indecies[] =
{
0,1,2,
};
int main()
{
Game_Window window("Window", 1600, 900);
if (window.CreateWindow())
{
Shader shader("basic.vert", "basic.frag");
shader.CreateShader();
shader.Use();
GLuint VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(VBO, sizeof(verticies), verticies, GL_STATIC_DRAW);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indecies), indecies, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
(void*)0);
glEnableVertexAttribArray(0);
while (window.ShouldStayOpen())
{
window.Update();
window.clear();
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
window.swapBuffers();
}
}
return 0;
}
I am quite confused by this error as it seems also occurs on random glfw functions (but im not sure as I can't get it to happen consistently). I don't get any error untill I add:
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);

The 1st parameter of glBufferData has to be the target enumeration constant (e.g. GL_ARRAY_BUFFER), not the named buffer object.
Change your code like this to solve the issue:
glBufferData(
GL_ARRAY_BUFFER, // GL_ARRAY_BUFFER instead of VBO
sizeof(verticies), verticies, GL_STATIC_DRAW);
Note, if you would check for OpenGL errors (glGetError), then you would get an GL_INVALID_ENUM error in this case.

Related

OpenGL glGenBuffers with error message: EXC_BAD_ACCESS (code=1, address=0x0) [duplicate]

This is my code:
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
const int IMAGE_SIZE = 32;
GLFWwindow* window;
GLuint vao;
GLuint vbo;
int initWindow() {
// Initialize GLFW
if (!glfwInit()) {
cerr << "Error: Failed to initialize GLFW." << endl;
return 1;
}
// Set up GLFW window hints for OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Create window
window = glfwCreateWindow(IMAGE_SIZE * 20, IMAGE_SIZE * 20 + 60, "PBM Image", NULL, NULL);
if (!window) {
cerr << "Error: Failed to create GLFW window." << endl;
glfwTerminate();
return 1;
}
// Create context
glfwMakeContextCurrent(window);
// Set color and blendmode
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Create and bind VAO and VBO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao); // Here is the spot where I get the exception
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
return 0;
}
void renderImage(vector<unsigned char> vertices) {
// Update VBO data
glBufferData(GL_ARRAY_BUFFER, vertices.size(), vertices.data(), GL_STATIC_DRAW);
// Set vertex attribute pointers
glVertexAttribPointer(0, 3, GL_UNSIGNED_BYTE, GL_FALSE, 3 * sizeof(unsigned char), (void*)0);
glEnableVertexAttribArray(0);
// Unbind VBO and VAO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// Set up projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, IMAGE_SIZE, 0.0, IMAGE_SIZE, 0.0, 1.0);
// Clear screen
glClear(GL_COLOR_BUFFER_BIT);
// Bind VAO
glBindVertexArray(vao);
// Draw points
glDrawArrays(GL_POINTS, 0, vertices.size() / 3);
// Unbind VAO
glBindVertexArray(0);
// Swap buffers
glfwSwapBuffers(window);
}
int main() {
if (initWindow()) return 1;
// Here comes the code that generates vector<unsigned char> vertices
renderImage(vertices);
getchar();
// Delete VAO and VBO
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
// Terminate GLFW
glfwTerminate();
return 0;
}
It uses glew to setup opengl and glfw for window handling. After initializing the window it generates vector<unsigned char> vertices which renderImage takes in. Afterwards it removes VAO, VBO and terminates GLFW. But it won't even come to that point because it throws the following exception at glBindVertexArray(vao);:
Exception thrown at 0x0000000000000000 in generator.exe: 0xC0000005: Access violation executing location 0x0000000000000000.
Here are my lib and include settings and folders:
VC++ Directories
Input
Lib Folder
Lib x64 Folder
Include GL
Include GLFW
glew needs to be initialized (see Initializing GLEW). If glew is not initialized, the OpenGL API function pointers are not set. Call glewInit() right after glfwMakeContextCurrent(window):
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
return 1;

Getting an exception after executing "glBindVertexArray(vao);"

This is my code:
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
const int IMAGE_SIZE = 32;
GLFWwindow* window;
GLuint vao;
GLuint vbo;
int initWindow() {
// Initialize GLFW
if (!glfwInit()) {
cerr << "Error: Failed to initialize GLFW." << endl;
return 1;
}
// Set up GLFW window hints for OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Create window
window = glfwCreateWindow(IMAGE_SIZE * 20, IMAGE_SIZE * 20 + 60, "PBM Image", NULL, NULL);
if (!window) {
cerr << "Error: Failed to create GLFW window." << endl;
glfwTerminate();
return 1;
}
// Create context
glfwMakeContextCurrent(window);
// Set color and blendmode
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Create and bind VAO and VBO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao); // Here is the spot where I get the exception
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
return 0;
}
void renderImage(vector<unsigned char> vertices) {
// Update VBO data
glBufferData(GL_ARRAY_BUFFER, vertices.size(), vertices.data(), GL_STATIC_DRAW);
// Set vertex attribute pointers
glVertexAttribPointer(0, 3, GL_UNSIGNED_BYTE, GL_FALSE, 3 * sizeof(unsigned char), (void*)0);
glEnableVertexAttribArray(0);
// Unbind VBO and VAO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// Set up projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, IMAGE_SIZE, 0.0, IMAGE_SIZE, 0.0, 1.0);
// Clear screen
glClear(GL_COLOR_BUFFER_BIT);
// Bind VAO
glBindVertexArray(vao);
// Draw points
glDrawArrays(GL_POINTS, 0, vertices.size() / 3);
// Unbind VAO
glBindVertexArray(0);
// Swap buffers
glfwSwapBuffers(window);
}
int main() {
if (initWindow()) return 1;
// Here comes the code that generates vector<unsigned char> vertices
renderImage(vertices);
getchar();
// Delete VAO and VBO
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
// Terminate GLFW
glfwTerminate();
return 0;
}
It uses glew to setup opengl and glfw for window handling. After initializing the window it generates vector<unsigned char> vertices which renderImage takes in. Afterwards it removes VAO, VBO and terminates GLFW. But it won't even come to that point because it throws the following exception at glBindVertexArray(vao);:
Exception thrown at 0x0000000000000000 in generator.exe: 0xC0000005: Access violation executing location 0x0000000000000000.
Here are my lib and include settings and folders:
VC++ Directories
Input
Lib Folder
Lib x64 Folder
Include GL
Include GLFW
glew needs to be initialized (see Initializing GLEW). If glew is not initialized, the OpenGL API function pointers are not set. Call glewInit() right after glfwMakeContextCurrent(window):
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
return 1;

Trouble loading and drawing a .obj model using Assimp and OpenGL

After performing the basics of OpenGL (creating a window, making a 2D triangle, shaders, etc.) I decided to start trying to load simple .obj models. The most recommended library was Assimp so I followed some tutorials and modified my project to load models. But unfortunately, the models were displayed very strangely. I created the following code to show this:
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
struct Vertex
{
glm::vec3 position;
glm::vec3 normal;
};
struct Mesh
{
//The vertex array object, vertex buffer object and element buffer object
GLuint VAO;
GLuint VBO;
GLuint EBO;
//Vectors for the vertices and indices to put in the buffers
std::vector<Vertex> vertices;
std::vector<GLuint> indices;
//Constructor
Mesh(const std::vector<Vertex>& vertices, const std::vector<GLuint>& indices)
{
this->vertices = vertices;
this->indices = indices;
//Generate the VAO
glGenVertexArrays(1, &VAO);
//Generate the buffer objects
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
//Bind the VAO
glBindVertexArray(VAO);
//Bind the VBO and set the vertices
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), &vertices.at(0), GL_STATIC_DRAW);
//Enable the first attribute pointer
glEnableVertexAttribArray(0);
//Set the attribute pointer The stride is meant to be 'sizeof(Vertex)', but it doesn't work at all that way
// \/
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
//Enable the second attribute pointer
glEnableVertexAttribArray(1);
//Set the attribute pointer ditto
// \/
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*) offsetof(Vertex, normal));
//Bind the EBO and set the indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(), &indices.at(0), GL_STATIC_DRAW);
//Report any errors
GLenum error = glGetError();
if (error != GL_NO_ERROR)
{
std::cerr << "Error while creating mesh!" << std::endl;
}
glBindVertexArray(0);
}
void draw()
{
//Bind the VAO
glBindVertexArray(VAO);
//Bind the ELement Buffer Object
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
//Draw the mesh
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
//Unbind the VAO
glBindVertexArray(0);
}
};
int main()
{
//Intialize GLFW (no error checking for brevity)
glfwInit();
//Set the OpenGL version to 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//Create a new window
GLFWwindow* window = glfwCreateWindow(800, 600, "Model Testing", NULL, NULL);
glfwMakeContextCurrent(window);
//Initialize glew (no checking again)
glewInit();
glViewport(0, 0, 800, 600);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
//Load the model
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile("mymodel.obj", aiProcess_Triangulate | aiProcess_GenNormals);
//Check for errors
if ((!scene) || (scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE) || (!scene->mRootNode))
{
std::cerr << "Error loading mymodel.obj: " << std::string(importer.GetErrorString()) << std::endl;
//Return fail
return -1;
}
//A vector to store the meshes
std::vector<std::unique_ptr<Mesh> > meshes;
//Iterate over the meshes
for (unsigned int i = 0; i < scene->mNumMeshes; ++i)
{
//Get the mesh
aiMesh* mesh = scene->mMeshes[i];
//Create vectors for the vertices and indices
std::vector<Vertex> vertices;
std::vector<GLuint> indices;
//Iterate over the vertices of the mesh
for (unsigned int j = 0; j < mesh->mNumVertices; ++j)
{
//Create a vertex to store the mesh's vertices temporarily
Vertex tempVertex;
//Set the positions
tempVertex.position.x = mesh->mVertices[j].x;
tempVertex.position.y = mesh->mVertices[j].y;
tempVertex.position.z = mesh->mVertices[j].z;
//Set the normals
tempVertex.normal.x = mesh->mNormals[j].x;
tempVertex.normal.y = mesh->mNormals[j].y;
tempVertex.normal.z = mesh->mNormals[j].z;
//Add the vertex to the vertices vector
vertices.push_back(tempVertex);
}
//Iterate over the faces of the mesh
for (unsigned int j = 0; j < mesh->mNumFaces; ++j)
{
//Get the face
aiFace face = mesh->mFaces[j];
//Add the indices of the face to the vector
for (unsigned int k = 0; k < face.mNumIndices; ++k) {indices.push_back(face.mIndices[k]);}
}
//Create a new mesh and add it to the vector
meshes.push_back(std::unique_ptr<Mesh>(new Mesh(std::move(vertices), std::move(indices))));
}
//While the window shouldn't be closed
while (!glfwWindowShouldClose(window))
{
//Clear the buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Draw all the meshes
for (auto& mesh : meshes) {mesh.get()->draw();}
//Swap the buffers
glfwSwapBuffers(window);
}
//Close the window now that it's not needed anymore
glfwDestroyWindow(window);
return 0;
}
When the program loads this teapot my screen looks like this:
And from further away at another angle (using a more complex program than the one above):
In case it's useful, I'm running Ubuntu 16.04 with an Nvidia GTX 750 Ti, driver version 361.45
The stride should be sizeof(Vertex). If it doesn't work with that stride then something else is wrong!
Try moving the binding of the ebo to right after the vbo in the mesh constructor like this:
//Bind the VBO and set the vertices
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), &vertices.at(0), GL_STATIC_DRAW);
//Bind the EBO and set the indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(), &indices.at(0), GL_STATIC_DRAW);
Thats the way they have it on the mesh page you linked. I have had a similar problem with a different loader. Your indices are are not being loaded correctly so some verticies are positioned correctly while others are not.
My experience with OpenGL is pathetic so I can be mistaken. I see that your vertices are made as: x,y,z,nx,ny,nz where xyz is vertex coords and nxnynz is normal coords. Therefore stride is 6*sizeof(float).
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*) 3*sizeof(float);
just look at second answer here: Opengl Vertex attribute stride to learn more about stride calculation
if this doesn't help check if indices where formed correctly
and small advice: work with cubes not with teapots (just made cube in blender or write it yourself in notepad)

Can't get netbeans to link GLEW properly

I am running a basic openGL program that compiles and runs fine in command prompt with the command
g++ gltest.cpp -std=c++11 -lglew32s -lglfw3 -lgdi32 -lopengl32 -o gltest.exe
but when I try to use it in netbeans it gives me a bunch of "undefined reference to `_imp____glewCreateShader'" errors. All references to glew functions.
I have the needed libraries put in the linker options
here is the code:
// g++ gldrop.cpp -std=c++11 -lglew32s -lglfw3 -lgdi32 -lopengl32 -o gldrop.exe
#define GLEW_STATIC
#include <iostream>
#include "gl\glew.h"
#include "gl\glfw3.h"
#include "shaderM.cpp"
#include "glm\glm\gtc\matrix_transform.hpp"
#include "glm\glm\glm.hpp"
#include "data.cpp"
GLFWwindow* window;
int main(int argv, char** argc)
{
//initialize GLFW
if (!glfwInit())
{
std::cout << "Failed to initialize GLFW \n";
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//create GLFW window
window = glfwCreateWindow(640, 480, "GL", NULL, NULL);
glfwMakeContextCurrent(window);
glewExperimental = true;
//initialize GLEW
if(glewInit() != GLEW_OK)
{
std::cout << "failed to initialize glew";
return -1;
}
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
//background
glClearColor(0.4f, 0.3f, 0.7f, 0.0f);
//depth test
glEnable(GL_DEPTH_TEST);
//takes fragments closer to the camera
glDepthFunc(GL_LESS);
//Vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//Vertex buffer
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
//color buffer
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
//create shaders and attach them to a program object
GLuint program = rigShadersToProgram();
GLuint matrixID = glGetUniformLocation(program, "MVP");
//projection matrix 45 degree FoV, 4:3 ratio, display range 0.1 - 100
glm::mat4 projection = glm::perspective(70.0f, 4.0f/3.0f, 0.1f, 100.0f);
//camera matrix
glm::mat4 view = glm::lookAt(
glm::vec3(4,3,-3), //camera is at (4,3,-3)
glm::vec3(0,0, 0), //looks at origin
glm::vec3(0,1, 0) //head is up
);
//model matrix identity matrix
glm::mat4 model = glm::mat4(1.0f);
//model-view-projection
glm::mat4 MVP = projection * view * model;
while (!glfwWindowShouldClose(window))
{
//clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//use the compiled shaders
glUseProgram(program);
//send transformation matrix to currently bound shader
glUniformMatrix4fv(matrixID, 1, GL_FALSE, &MVP[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, //index
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
0 //array buffer offset
);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
1, //index
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
0 //array buffer offset
);
//draw triangle
glDrawArrays(GL_TRIANGLES, 0, 12*3); //start # vertex 0, 3 verticies
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &colorbuffer);
glDeleteProgram(program);
glDeleteVertexArrays(1, &vao);
glfwTerminate();
return 0;
}
Not sure why it won't recognize the libraries.
Where did you download glew32?
maybe you downloaded the Visual C version if not you could've unpacked the wrong version (64 bit).
Another thing I've heard (try this first)
I've had issues with glew32s on mingw and for some reason it doesn't work, use regular glew32. It should still work with the preprocessor and compiles statically without any issue.

How to use VBOs without VAOs with OpenGL core profile?

I'm having trouble using vertex buffer objects without using a vertex array object.
My understanding was that VAOs are just encapsulating the state around VBOs. But shouldn't the VBOs be usable without a VAO?
Here's a mini-example. With use_vao=true this works correctly (renders orange rect). With use_vao=false this renders nothing and generates a GL_INVALID_OPERATION error upon glDrawElements.
// make sure the modern opengl headers are included before any others
#include <OpenGL/gl3.h>
#define __gl_h_
#include <GLUT/glut.h>
#include <string>
#include <cassert>
// For rendering a full-viewport quad, set tex-coord from position
std::string tex_v_shader = R"(
#version 330 core
in vec3 position;
void main()
{
gl_Position = vec4(position,1.);
}
)";
// Render directly from color or depth texture
std::string tex_f_shader = R"(
#version 330 core
out vec4 color;
void main()
{
color = vec4(0.8,0.4,0.0,0.75);
}
)";
// shader id, vertex array object
GLuint tex_p_id;
int w=1440,h=480;
const GLfloat V[] = {-0.5,-0.5,0,0.5,-0.5,0,0.5,0.5,0,-0.5,0.5,0};
const GLuint F[] ={0,1,2, 0,2,3};
int main(int argc, char * argv[])
{
// Init glut and create window + OpenGL context
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_3_2_CORE_PROFILE|GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(w,h);
glutCreateWindow("test");
// Compile shaders
const auto & compile = [](const char * src,const GLenum type)->GLuint
{
GLuint s = glCreateShader(type);
glShaderSource(s, 1, &src, NULL);
glCompileShader(s);
return s;
};
tex_p_id = glCreateProgram();
glAttachShader(tex_p_id,compile(tex_v_shader.c_str(), GL_VERTEX_SHADER));
glAttachShader(tex_p_id,compile(tex_f_shader.c_str(), GL_FRAGMENT_SHADER));
glLinkProgram(tex_p_id);
glutDisplayFunc(
[]()
{
glViewport(0,0,w,h);
glUseProgram(tex_p_id);
glClearColor(0.0,0.4,0.7,0.);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const bool use_vao = true;
GLuint VAO;
if(use_vao)
{
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
}
GLuint VBO, EBO;
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(V), V, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(F), F, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
if(use_vao)
{
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
assert(glGetError() == GL_NO_ERROR);
glDrawElements(GL_TRIANGLES,sizeof(F)/sizeof(GLuint),GL_UNSIGNED_INT, 0);
assert(glGetError() == GL_NO_ERROR);
glutSwapBuffers();
}
);
glutReshapeFunc( [](int w,int h){::h=h, ::w=w;});
glutMainLoop();
}
On my machine glGetString(GL_VERSION) produces 4.1 INTEL-10.6.20.
Using VAOs is required in the core profile. From the OpenGL 3.3 spec, page 342, in the section E.2.2 "Removed Features":
The default vertex array object (the name zero) is also deprecated.
This means that you can't set up vertex attributes without creating and binding your own VAO.
No with a core 3.3+ profile you need a VAO to render.
You can however just create and bind a VAO and forget about it (keep it bound).
Besides that glEnableVertexAttribArray(0); must still be called even when using compatibility profile and not using a VAO.
A few other remarks is that you regenerate all buffers and VAOs every frame but don't clean it up. You should do that once during initialization and then rebind when drawing:
if(!use_vao){
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
}
else
{
glBindVertexArray(VAO);
}