OpenGL VAO,VBO,EBO accessviolation - opengl

I have following code for loading a model (here it's a triangle) and load it up into my resourcemanager:
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f, // Left
0.5f, -0.5f, 0.0f, // Right
0.0f, 0.5f, 0.0f // Top
};
GLuint indices[] = {
0, 1, 2
};
ModelGroup* newGroup = new ModelGroup;
GLuint VBO;
glGenVertexArrays(1, &newGroup->vao);
glGenBuffers(1, &VBO);
glGenBuffers(1, &newGroup->ebo);
glBindVertexArray(newGroup->vao);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newGroup->ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
newGroup->vbos.push_back(VBO);
vertexCount = 3;
indiciesCount = 3;
modelGroups.insert(std::pair<GLchar*, ModelGroup*>("default", newGroup));
and following code to render my triangle:
GLuint vao = model->getVAO();
GLuint count = model->getIndicesCount();
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
This code doesn't work and throws an accessviolation-error.
I don't know why ... but here is the thing
If i instead write the load-code into my resourcemanager, write the same triangle-load-code into the constructor of the renderer-class it works. What did i wrong?
PS: it also works if i use the loaded triangle from the resourcemanager and write the same load-code into the renderer-class-constructor ... that's weird
Edit: I think i found the bug ... some how the vbo-, vao-, eboIDs is only accessable in the resourcemanager and if i write the load-code into the constructor of the renderer he creates the same IDs (which shouldn't or not?)
Has that something to do with the opengl-context? And how can i fix that?
Edit2: It's the same opengl-context but the vao outside of the resourcemanager-class is not a vao(checked with glIsVertexArray). Here is more code about my resourcemanager and it's structs for more clarity (updated also the code above).
Edit3: Already made some mistakes (updated code)
Also i can't render the triangle in other classes and i checked IDs, etc.
All IDs are correct. The triangle is correctly created. But at anytime i try to access the vao outside of the loader-class it throws a violation-exception.
Its drive me crazy ... i don't know what to do
Edit4: Yaay ... i got it to work, it was just a little fail on pointers but now it works :)
class Model {
public:
struct ModelGroup {
GLuint vao;
GLuint ebo;
std::vector<GLuint> vbos;
};
private:
GLuint vertexCount;
GLuint indiciesCount;
std::map<GLchar*, ModelGroup*> modelGroups;
public:
// all the getters ...
};

Related

How do I change buffer data with std::vector?

So my idea is to add more data to the buffer.
My first idea was to use std::vector so I have a non fixed array, that I can add data to.
In the generation of the data:
void initData()
{
std::vector<float> vertices;
std::array<float, 12> verts = {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f
};
for(int i = 0; i < verts.size(); i++)
vertices.push_back(verts[i]);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices), &vertices[0], GL_DYBAMIC_DRAW);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
}
this works just fine!
but then when I want to add more data:
void render()
{
std::vector<float> newVertices;
// Generates new vertices with more data, like I did in the initData()
// for-loop adding it to the new vector (newVertices)
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, newVertices.size() * sizeof(newVertices), &newVertices[0]);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLE, 0, 6 * theAmountIveGeneratedBefore);
}
that's the part that I can't seem to get to work...
what am I doing wrong??
EDIT: As pointed out in the comments, you can NOT add more data to a buffer using glBufferSubData(). So this answer only points out the mistake in calculating the size of the passed data.
sizeof(newVertices) doesn't give you what you need. The std::vector is a class and is more complicated than a simple array. Also, you don't need its whole size, actually. What you need is actually just the size of a float, since you are multiplying it by the number of elements. So just:
newVertices.size() * sizeof(float)
or
newVertices.size() * sizeof(newVertices[0])

C++ OpenGL, drawing shapes is returning an error

I am trying to draw shapes onto my application. I have added #include <glad/glad.h> into my code.
I set my vertex array, vertex buffer & index buffer as unsigned ints in my header file.
In my application.h file I added this:
unsigned int m_FCvertexArray; // Textured Phong VAO
unsigned int m_FCvertexBuffer;// Textured Phong VBO
unsigned int m_FCindexBuffer; // Index buffer for texture Phong cube
In my application.cpp in my constructor I added this:
Application::Application()
{
//------------- OPENGL VALUES -----------//
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// Enabling backface culling to ensure triangle vertices are correct ordered (CCW)
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
////--------DRAW VERTICES---------//
float FCvertices[3 * 3] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
glGenVertexArrays(1, &m_FCvertexArray);
glBindVertexArray(m_FCvertexArray);
glCreateBuffers(1, &m_FCvertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_FCvertexBuffer);
//
//
glBufferData(GL_ARRAY_BUFFER, sizeof(FCvertices), FCvertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(sizeof(float) * 3));
////--------DRAW INDICES---------//
glCreateBuffers(1, &m_FCindexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_FCindexBuffer);
unsigned int indices[3] = {0, 1, 2};
glBufferData(GL_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
}
in my void Application::run() I added:
glUseProgram(m_FCprogram);
glBindVertexArray(m_FCvertexArray);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
now the problem is when I run the code, it gives me the error mentioned on the title:
Exception thrown at 0x000000005D78F420 (nvoglv64.dll) in Sandbox.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
I've been trying ways to fix this but it seems not to work. and if i comment out glDrawElements, the code runs and works but no shapes are drawn (obvious).
When you create the index buffer, you need to use GL_ELEMENT_ARRAY_BUFFER instead of GL_ARRAY_BUFFER.

Drawing multiple triangles with different VAOs and VBOs

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.

glDrawArray not drawing the second time

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.

How to bind multiple IBOs from one VBO in OpenGL

I am trying to render two different triangles with IBOs. I stored the six vertices in one VBO and tried to access them through two separate IBOs. The problem is the first IBO renders but the second doesn't. The createVertices and createIndices are called at initialization.
void createVertices()
{
//Vertex Data
GLfloat v[] = { 0.95f, 0.75f, 0.0f, 1.0f,
0.75f, -0.75f, 0.0f, 1.0f,
0.0f, -0.75f, 0.0f, 1.0f, // END OF TRIANGLE 1
-0.75, 0.75f, 0.5f, 1.0f,
-0.75, -0.75f, 0.5f, 1.0f,
0.0f, -0.75f, 0.5f, 1.0f }; // END OF TRIANGLE 2
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
//////////
void createIndices()
{
GLushort i[] = { 0,1,2};
glGenBuffers(2, IBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(i), i, GL_STATIC_DRAW);
size = (sizeof(i)/sizeof(GLushort)); // USED IN DRAWELEMENTS
GLushort w[] = { 3,4,5};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(w), w, GL_STATIC_DRAW);
size2 = (sizeof(i)/sizeof(GLushort)); // USED IN DRAWELEMENTS
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
/////////
void Render()
{
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader.SProgram);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0,4, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO[0]);
glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_SHORT,(GLvoid*)IBO[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO[1]);
glDrawElements(GL_TRIANGLES,size2,GL_UNSIGNED_SHORT,(GLvoid*)IBO[1]);
glUseProgram(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
This doesn't make sense:
glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_SHORT,(GLvoid*)IBO[0]);
^^^^^^^^^^^^^^
The parameter to glDrawElements with an IBO bound is an offset into the buffer just as it is with gl…Pointer and VBOs. You probably just want this
glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_SHORT,(GLvoid*)0);
for both your IBOs and just bind the IBO itself with
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO[…]);