I got the problem that the first vertex is always drawn at (0,0,0) no matter where I want it to be (all other positions are correct). I think it is a mistake in my 'init' function.
Here are the positions I use:
positions.push_back( glm::vec3(-0.5f , -0.5f , 0.0f ) );
positions.push_back( glm::vec3( 0.0f , 0.5f , 0.0f ) );
positions.push_back( glm::vec3( 0.5f , -0.5f , 0.0f ) );
My 'init' function:
// generate buffers
glGenVertexArrays(1, &this->VAO);
glGenBuffers(1, &this->VBO);
glGenBuffers(1, &this->EBO);
glBindVertexArray(this->VAO);
// fill buffers with data
glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * this->positions.size(), &this->positions[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * this->indices.size(), &this->indices[0], GL_STATIC_DRAW);
// linking vertex attributes
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
// unbind (only) VAO
glBindVertexArray(0);
And my 'render' function (just to render the VAO, no shaders):
glBindVertexArray(this->VAO);
glDrawElements(GL_TRIANGLES, this->numElements, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
I also tried to adjust the 'stride' and 'pointer' values in the 'glVertexAttribPointer' function but it just didn't work.
Ok thanks to Anton Angelov I found the mistake... The indices of the mesh need to start from 0 (not from 1)! Thanks again for your comments
Related
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.
I'm learning OpenGL and I'm trying to implement some particles in my application.
To do so, I followed some courses.
But when I try to render my particles, nothing happen, it doesn't even enter the shader (I tried to put some infinite loop in it and nothing happened). I tried a lot of thing, maybe there is something I did not understand..
I created a class Particle, with a constructor, an update and a draw method, I followed every step of the course, and adapted it to my class (the course is doing everything in the main loop).
My particles class got some private members:
private:
size_t maxSize_;
std::vector<float> quadData_;
unsigned int dataVbo_;
std::vector<float> posData_;
unsigned int posVbo_;
std::vector<float> colorData_;
unsigned int colorVbo_;
std::list<Particle> allParticles_;
and here is the initialization of Particles:
Particles::Particles(size_t maxSize)
: maxSize_(maxSize), quadData_({-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f})
{
posData_.resize(maxSize_*4);
colorData_.resize(maxSize_*4);
glGenBuffers(1, &dataVbo_);
glBindBuffer(GL_ARRAY_BUFFER, dataVbo_);
glBufferData(GL_ARRAY_BUFFER, quadData_.size() * sizeof(float), quadData_.data(), GL_STATIC_DRAW);
// The VBO containing the positions and sizes of the particles
glGenBuffers(1, &posVbo_);
glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
// Initialize with empty (NULL) buffer : it will be updated later, each frame.
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);
// The VBO containing the colors of the particles
glGenBuffers(1, &colorVbo_);
glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
// Initialize with empty (NULL) buffer : it will be updated later, each frame.
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);
}
and the draw:
void Particles::draw(){
size_t count(posData_.size());
glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW); // Buffer orphaning, a common way to improve streaming perf. See above link for details.
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), posData_.data());
glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW); // Buffer orphaning, a common way to improve streaming perf. See above link for details.
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float) * 4, colorData_.data());
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, dataVbo_);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// 2nd attribute buffer : positions of particles' centers
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// 3rd attribute buffer : particles' colors
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glVertexAttribDivisor(0, 0); // particles vertices : always reuse the same 4 vertices -> 0
glVertexAttribDivisor(1, 1); // positions : one per quad (its center) -> 1
glVertexAttribDivisor(2, 1); // color : one per quad -> 1
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
}
And in my main loop I'm doing this:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
myParticules.update(elapsedTime);
glDisable(GL_DEPTH_TEST);
glUseProgram(_particleShad);
myParticles.draw();
I'm also sending some uniform vec and mat, but nothing important.
In my shader I only try to do this:
Vertex :
gl_Position = vec4(squareVertices.xyz, 1);
//squareVertices contain the vertices of my square for my particles
Fragment :
color = vec4(1, 1, 1, 1);
I don't find anything wrong, I really need some help, I'm totally lost.
You must create a VAO (Vertex Array Object):
class Particles {
private:
// add:
GLuint vao;
...
Initialization:
Particles::Particles(size_t maxSize)
: maxSize_(maxSize), quadData_({-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f})
{
posData_.resize(maxSize_*4);
colorData_.resize(maxSize_*4);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &dataVbo_);
glBindBuffer(GL_ARRAY_BUFFER, dataVbo_);
glBufferData(GL_ARRAY_BUFFER, quadData_.size() * sizeof(float), quadData_.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// The VBO containing the positions and sizes of the particles
glGenBuffers(1, &posVbo_);
glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
// Initialize with empty (NULL) buffer : it will be updated later, each frame.
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// The VBO containing the colors of the particles
glGenBuffers(1, &colorVbo_);
glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
// Initialize with empty (NULL) buffer : it will be updated later, each frame.
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glVertexAttribDivisor(0, 0); // particles vertices : always reuse the same 4 vertices -> 0
glVertexAttribDivisor(1, 1); // positions : one per quad (its center) -> 1
glVertexAttribDivisor(2, 1); // color : one per quad -> 1
}
Drawing code:
void Particles::draw(){
size_t count(posData_.size());
glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), posData_.data());
glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float) * 4, colorData_.data());
glBindVertexArray(vao);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
}
Notice how you don't need to update your VAO state during the draw() call, only during the initialization.
I'm a newbie to OpenGL and I'm trying draw two triangles using two VAOs and only one VBO. Even if after some research, I came to have a better understanding of VAO, VBO and how the needed glew functions work, I have no clue why my program displays only one triangle instead of two. Can somebody help?
...
GLfloat points[] = {
0.5f, 0.5f, 0.0f, //First Triangle
-0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.0f, 0.0f, //Second Triangle
-1.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f
};
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLuint vao1;
glGenVertexArrays(1, &vao1);
glBindVertexArray(vao1);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
GLuint vao2;
glGenVertexArrays(1, &vao2);
glBindVertexArray(vao2);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL + 9);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
...
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader_program);
glBindVertexArray(vao1);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindVertexArray(vao2);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
glfwPollEvents();
glfwSwapBuffers(window);
}
...
The last parameter for this function call is incorrect:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL + 9);
You're telling it to add 9 bytes, but your points are floats
Try this:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL + 9 * sizeof(float));
I know in 2.0- openGL we can draw a line simply like this.
glBegin(GL_LINES);
glVertex3f(20.0f,150.0f,0.0f);
glVertex3f(220.0f,150.0f,0.0f);
glVertex3f(200.0f,160.0f,0.0f);
glVertex3f(200.0f,160.0f,0.0f);
glEnd();
but how to do similar thing in modern openGL(3.0+)
I have read Drawing round points using modern OpenGL but the answer is not about certain point,since I want to draw polygon with points have certain coordinates,it's not quite helpful.
I use this code,but it shows nothing except a blue background.what do I missed?
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
static const GLfloat g_vertex_buffer_data[] = {
20.0f, 150.0f, 0.0f, 1.0f,
220.0f, 150.0f, 0.0f, 1.0f,
200.0f, 160.0f, 0.0f, 1.0f
};
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);
do{
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT );
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
4, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_LINES, 0, 2); // 3 indices starting at 0 -> 1 triangle
glDisableVertexAttribArray(0);
// Swap buffers
glfwSwapBuffers(window);
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
1) You have to define an array of vertices, that contain the points of your polygon lines. Like in your example:
GLfloat vertices[] =
{
20.0f, 150.0f, 0.0f, 1.0f,
220.0f, 150.0f, 0.0f, 1.0f,
200.0f, 160.0f, 0.0f, 1.0f
};
2) You have to define and bind a Vertex Buffer Object (VBO) to be able to pass your vertices to the vertex shader. Like this:
// This is the identifier for your vertex buffer
GLuint vbo;
// This creates our identifier and puts it in vbo
glGenBuffers(1, &vbo);
// This binds our vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// This hands the vertices into the vbo and to the rendering pipeline
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
3) Now we are ready to draw. Doing this:
// "Enable a port" to the shader pipeline
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// pass information about how vertex array is composed
glVertexAttribPointer(0, // same as in glEnableVertexAttribArray(0)
4, // # of coordinates that build a vertex
GL_FLOAT, // data type
GL_FALSE, // normalized?
0, // stride
(void*)0);// vbo offset
glDrawArrays(GL_LINES, 0, 2);
glDisableVertexAttribArray(0);
Step 1) and 2) can be done before rendering as initialization. Step 3) is done in your rendering loop. Also you'll need a vertex shader and a fragment shader to visualize the line with color.
If you don't know anything about these things and like to start with OpenGL 3, I'd suggest to start over with a tutorial like this:
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-1-opening-a-window/
my problem is not properly drawing simple plane;
I dont know why i get once error at begining : Invalid Operation 1282.
Can someone check that?
My variables :
GLfloat *tab for verticies plane
int *tab2 for indecies
this is my init funcion:
// kolor tła - zawartość bufora koloru
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
// wczytanie shaderów i przygotowanie obsługi programu
program=LoadShaders("shader.vert","shader.frag" );
//Vertexy
//VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
//Verticies;
glGenBuffers(1, &Verticies);
glBindBuffer(GL_ARRAY_BUFFER, Verticies);
glBufferData( GL_ARRAY_BUFFER,foo*sizeof(GLfloat), tab, GL_STATIC_DRAW );
unsigned int m_ciezarkow[]={0,1,0};
//Indicies
glGenBuffers(1,&Indeksy);
glBindBuffer(GL_ARRAY_BUFFER,Indeksy);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*size, tab2, GL_STATIC_DRAW);
glUseProgram( program );
pos_cam=glGetUniformLocation( program, "camera" );
pos_color=glGetUniformLocation( program, "_color" );
glUseProgram(0);
This is my draw function:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
//my camera
glUniformMatrix4fv(pos_cam,1,GL_FALSE,&cam.matrix()[0][0]);
//Verticies
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, Verticies);
glVertexAttribPointer( 0, 3 , GL_FLOAT, GL_FALSE, 0, (void*)0 );
//Masa
//glEnableVertexAttribArray(1);
//glBindBuffer(GL_ARRAY_BUFFER, Masa);
//glVertexAttribPointer( 0, 3 , GL_FLOAT, GL_FALSE, 0, (void*)0 );
//Indicies
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,Indeksy);
glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_INT,(void*)0);
glUseProgram( 0 );
glDisableVertexAttribArray(0);`
There is a mistake here:
//Indicies
glGenBuffers(1,&Indeksy);
glBindBuffer(GL_ARRAY_BUFFER,Indeksy);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*size, tab2, GL_STATIC_DRAW);
You bind Indeksy as GL_ARRAY_BUFFER, but it should be GL_ELEMENT_ARRAY_BUFFER. With your code, there is probably 0 bound as index buffer, and the glBufferData for that target will fail with GL_INVALID_OPERATION.