I recently created an OBJ loader, it works perfectly fine at the moment, which is without any VBO buffer objects. I am currently in the process of changing over to using VBO with my program and it crashes( doesn't respond) every time I try to run it.
My obj loader consists of drawing the normals and verts, it has the indicies aswell.
I am new to openGL and I somewhat have an idea of how VBO works.
This is it when I have made an attempt to add buffers to my program.
This is it without
This is my code that is currently crashing
#define GLEW_STATIC
#include <GL/glew.h
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
int main(int argc,char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow("Object Loader!");
setUpArrays();
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glGenBuffers(1, &vbo);
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(normals), normals, GL_STATIC_DRAW);
GLfloat posLight0[] = {0.0f, 0.0f, -1.0f, 0.0f};
GLfloat lightColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, posLight0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
glutDisplayFunc(Draw);
glutSpecialFunc(specialKeys);
glutReshapeFunc(reshape);
glutTimerFunc(25,update,0);
glutMainLoop();
return 0;
}
This is my draw function
void Draw(void)
{
glPushMatrix();
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef( rotate_x, 1.0, 0.0, 0.0 );
glRotatef( rotate_y, 0.0, 1.0, 0.0 );
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT,0, vertices);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, normals);
glColor3f(0.5f, 0.0f, 0.8f);
glDrawElements(GL_TRIANGLES, amountOfFaces, GL_UNSIGNED_INT, faces);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glFlush();
glutSwapBuffers();
glPopMatrix();
}
These are the only two functions that I have changed,
I've defined the unsigned int vbo and vbo2 outside.
The problem (and cause of the crash) is that your glVertexPointer should have 0 as the offset because it is relative tot the beginning of the bound buffer. (0 is a special case that treats program memory as one big buffer)
glGenBuffers(1, &vbo);
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(normals), normals, GL_STATIC_DRAW);
That is another problem; the 4th line glBindBuffer fully overrides the previous call to glBindBuffer. Or more generally; only the last glBindBuffer call is used so you never actually use vbo.
Also how are vertices and normals declared? if they are just pointers then you should replace sizeof with sizeof(*vertices)*3*amountOfFaces
Your code sample indicates that you're trying to use GLEW, but you haven't called glewInit after glutCreateWindow. You can't use OpenGL extension functions without loading their addresses first - that's exactly what GLEW do, if you don't want to mess with it manually (most likely you don't).
Your code appears to be wrong even after that, but it probably wouldn't crash. Can't say without full code of course, but
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
Don't making sense - bind one buffer, then immediately another - why is that?
Related
I'm trying to draw two triangles using separate VAOs and VBOs but while execution I see only one triangle being rendered. Below is my code snippet. I'm not sure where I'm messing up.
I'm using glfw and glew.
.....
//initialization and creating shader program
.....
GLfloat vertices[] = {
-0.9f, -0.5f, 0.0f, // Left
-0.0f, -0.5f, 0.0f, // Right
-0.45f, 0.5f, 0.0f, // Top
};
GLfloat vertices2[] = {
0.0f, -0.5f, 0.0f, // Left
0.9f, -0.5f, 0.0f, // Right
0.45f, 0.5f, 0.0f // Top
};
GLuint VBO1, VAO1, EBO;
glGenVertexArrays(1, &VAO1);
glGenBuffers(1, &VBO1);
glGenBuffers(1, &EBO);
GLuint VBO2, VAO2;
glGenBuffers(1, &VAO2);
glGenBuffers(1, &VBO2);
glBindVertexArray(VAO1);
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)nullptr);
glEnableVertexAttribArray(0);
//glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindVertexArray(VAO1);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)nullptr);
glEnableVertexAttribArray(0);
//glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(ShaderProgramID);
glBindVertexArray(VAO1);
glDrawArrays(GL_TRIANGLES, 0, 3);
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//glBindVertexArray(0);
glBindVertexArray(VAO2);
glDrawArrays(GL_TRIANGLES, 0, 3);
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//glBindVertexArray(0);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO1);
glDeleteVertexArrays(1, &VAO2);
glDeleteBuffers(1, &VBO1);
glDeleteBuffers(1, &VBO2);
glfwTerminate();
...
Although if I create VAOs and VBOs as array like below and change the code above code accordingly I see both the triangles. I'm unable to understand why is it so?
GLuint VAO[2], VBO[2];
GLuint VBO2, VAO2;
glGenBuffers(1, &VAO2);
...
glBindVertexArray(VAO2);
You've initialized VAO2 as a buffer, not a VAO.
First question so sorry if somethings out of place.
Below is a code snippet that works just fine.
Init function
ShaderLoader shaderloader;
Program = shaderloader.LoadShaders("VertexShader.vs", "FragmentShader.fs");
glGenVertexArrays(1, &VertexArrayObject);
glBindVertexArray(VertexArrayObject);
glGenBuffers(1, &VertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexBufferData) *
vertexBufferData.size(), &vertexBufferData.front(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
Render function
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 1.0);
glUseProgram(Program);
glBindVertexArray(VertexArrayObject);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glutSwapBuffers();
This all works fine within my main.cpp but when i put this into a class it gives me an access violation error. My class container holds its own VertexArrayObject and VertexBuffer so I am assuming that should be enough information to draw a simple triangle as it draws fine when it is not in a class. My end goal here is to create two objects so if I'm going about this completely wrong please point me in the right direction!
Code in the sprite class:
void Mesh::init(std::vector<GLfloat> vertexBufferData)
{
glGenVertexArrays(1, &VertexArrayObject);
glBindVertexArray(VertexArrayObject);
glGenBuffers(1, &VertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexBufferData) *
vertexBufferData.size(), &vertexBufferData.front(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
}
void Mesh::Draw()
{
glBindVertexArray(VertexArrayObject);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
How I'm using the class in the main.cpp:
Mesh object1;
void init()
{
ShaderLoader shaderloader;
Program = shaderloader.LoadShaders("VertexShader.vs", "FragmentShader.fs");
object1.init(vertexBufferData);
}
void Render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 1.0);
glUseProgram(Program);
object1.Draw();
glutSwapBuffers();
}
And the exception thrown is: 0x5253F00A
Access Violation reading location
Your Mesh class (opposed to the code at the top) writes twice to the same variable. Was that a simple typo?
glGenVertexArrays(1, &VertexArrayObject);
glBindVertexArray(VertexArrayObject);
glGenBuffers(1, &VertexArrayObject);
^^^^^^^^^^^^^^^^^
Hi so i have been basically pulling my hair out trying to understand this OpenGL confusion
i have tried to find answers in books, in tutorials , and even experimenting around with it
SO basically i have a opengl program that draws the first time my two triangles, however when i try to redraw the first triangle again it doesnt seem to be working
i dont know what information i am missing , but its no t making any sense
as far as i understand once the VAO and VBO have been created and bounded and buffered to memory, and vertex attrib pointers set and enabled that once i bind the vao object that i want to draw as many times as i like, i just have to do that
after initialization which works for me, the problem is that once i rebind another vao object it doesnt seem to draw it
my code is quiet long , i can paste it here if you like, but i think that the drawing part of the code would be sufficient
here it is
GLfloat vec[] = {0.0f, 0.0f,
1.0f, -1.0f,
-1.0f, -1.0f};
GLfloat vec2[] = {0.0f, 1.0f,
1.0f, 0.0f,
-1.0f, 0.0f};
//next step is to upload data to graphics memory
//generating a buffer from openGL
GLuint vbo;
GLuint vbo2 ;
GLuint vao;
GLuint vao2;
glGenBuffers(1, &vbo);
glGenBuffers(1, &vbo2);
glGenVertexArrays(1, &vao);
glGenVertexArrays(1, &vao2);
//to upload the actual data must make the object active by binding it to a target
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//upload the data of active object to memory
glBufferData(GL_ARRAY_BUFFER, sizeof(vec), vec, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec2), vec2, GL_STATIC_DRAW);
//bind and draw
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays (GL_TRIANGLES, 0, 3);
glXSwapBuffers ( dpy, glxWin );
sleep(3);
glClear(GL_COLOR_BUFFER_BIT);
//rendering second triangle
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBindVertexArray(vao2);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays (GL_TRIANGLES, 0, 3);
glXSwapBuffers ( dpy, glxWin );
sleep(3);
//rendering the first triangle again------where the problem lies!!!
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays (GL_TRIANGLES, 0, 3);
glXSwapBuffers ( dpy, glxWin );
sleep(3);
You'll also need to clear the depth buffer glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
If you follow a tutorial then you will probably have enabled depth testing in the openGL setup boilerplate it provided. This is because more people will want to use the depth buffer than not.
you can also not call glEnable(GL_DEPTH_TEST); during setup.
I've created a simple opengl program on Windows 7 using WIN api.
I've setup the window by following the tutorial on MSDN win api website.
The window works perfectly, even with input logging it does not leak any memory and works alright stays at 1.7 MB of ram.
With opengl context it takes 11MB.
If i want to draw something like Rectangle it begins to leak by 200 kb.
(The rectangle draws perfectly fine....)
It starts at 14.5 MB and grows up to 50MB and continues.
There are no 'new' keywords in the whole program, it is very simple program. Only create window. Than while loop in which the rendering is done...
Here is the main.
int main()
{
Window wind(800,600);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
while(!wind.isCloseRequested())
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
Vector3f Vertices[3];
Vertices[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Vertices[1] = Vector3f(1.0f, -1.0f, 0.0f);
Vertices[2] = Vector3f(0.0f, 1.0f, 0.0f);
GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
wind.update();
Sleep(16);
}
wind.Destroy();
return 0;
}
glGenBuffers(1, &VBO);
make memory leak. You need create buffer one time and using it or destroy buffer every time with glDeleteBuffers
By the way, before using any OpenGL function I recommended read docs. Many OpenGL function allocate some internal buffers in memory or resources in GPU and need call delete/destroy.
I'm just using the opengl SDL template with Xcode, and everything runs fine. I removed the Atlantis code, and changed the main extension to .mm, then added some testing code to drawGL. Drawing a simple triangle (using immediate mode) at this point inside drawGL gives me a white triangle, but when I add the code to draw using a vertex buffer object, i just get a black window.
Here is my VBO drawing code:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity();
GLuint buffer;
float vertices[] = {
0.0f, 1.0f, 0.0f,
-1.0f,-1.0f, 0.0f,
1.0f,-1.0f, 0.0f
};
// VBO doesn't work :(
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 9, vertices, GL_STATIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
Your glVertexPointer() call looks suspect for VBO usage. I think you need a BUFFER_OFFSET construct instead of the vertices pointer.