texture buffer object without shader - c++

all tutorials online are written in opengl 3+ with intesive use of shader.
I was wondering, can I create a texture buffer object and show the texture without using shader? In very old opengl uber deprecate api calls you can write gltexcoord, I just tried this way only to see if my loader was OK, and it's alright.
Using TBO I'm encountering some problems..
Let's suppose I'm creating a quad, then after loading the image (named txtr), I will store coordinates in a vector
terrainTBO.push_back(1);
terrainTBO.push_back(1);
terrainTBO.push_back(0);
terrainTBO.push_back(1);
terrainTBO.push_back(1);
terrainTBO.push_back(0);
terrainTBO.push_back(0);
terrainTBO.push_back(0);
then, in initializing process of terrain I'm doing
(obviously I'm not writing here about vertices and indices)
glBindBuffer(GL_ARRAY_BUFFER, *texture_buffer);
glBufferData(GL_ARRAY_BUFFER, vectorSizeOf(*texture_indices), &(*texture_indices)[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
In drawing part:
glEnable(GL_TEXTURE_2D);
glhBindTexture(txtr);
glBindBuffer(GL_ARRAY_BUFFER, *vboId);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, *tboId);
glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *iboId);
glDrawElements(GL_TRIANGLES, (*indices).size(), GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisable(GL_TEXTURE_2D);
The quad is created correctly, but no texture is shown into.. How can I achieve my texture? Is shader mandatory in these cases?

Related

Only last VAO is drawn

I want to create a VAO for every 3D Object in my program.
I create two VAO's:
//in some method 1
glGenVertexArrays(1, &vao1);
//in some method 2
glGenVertexArrays(1, &vao2);
then for earch VAO I create 2 VBO's:
glBindVertexArray(vao1);
glGenBuffers(2, vbos1);
glBindVertexArray(0);
//and the same for vao2, vbos2
then I send the data to the gpu:
glBindVertexArray(vao1);
glBindBuffer(GL_ARRAY_BUFFER, vbos1[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions1), positions1, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbos1[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices1), indices1, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
//and the same for vao2, vbos2, indices2
Then I do the same thing for vao2.
Now only vao2 is drawn.
If I switch the
glGenVertexArrays(1, &vao2);
glGenVertexArrays(1, &vao1);
Then only the vao1 is drawn.
I draw the vaos via:
glBindVertexArray(vao1);
glDrawElements(GL_TRIANGLES, indices1, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
//in another method
glBindVertexArray(vao2);
glDrawElements(GL_TRIANGLES, indices2, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
It makes no difference in which order I draw them, send the data to the gpu or initialize the buffers.
Why is that so?
Right: the order of creating VAOs makes no difference.
Among other things, a VAO stores the buffer binding. You don't need to bind a buffer each time you draw or update data. Just bind the VAO.
If the whole data fits in GPU memory you can update data only once, likely at buffer+VAO creation and binding. If not, then binding the VAO also makes the buffer "associated" in that VAO ready for receiving data.

Binding a Non-Zero Texture Crashes Program With VBO's

So I wanted to implement a simple VBO to see if it was worth switching from display lists for static objects in my scene. So far, I don't think Im doing it anytime soon. So heres my problem: I can render vertices fine, but as soon as I throw in texture coordinates, it crashes. So I do a bit of experimenting and its because I'm binding a texture to the thing. I have NEVER heard of this as being a problem. Literally the exact same code, using display lists works. Here is my code:
//create a vertex buffer object for the particles to use
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//create the data, this is really sloppy
float QuadVertextData[] = {0,0,0,1,0,0,1,1,0,0,1,0};
float QuadTextureData[] = {0,1,1,1,1,0,0,0};
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3, &QuadVertextData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//generate another buffer for the texcoords
glGenBuffers(1, &VBOT);
glBindBuffer(GL_ARRAY_BUFFER, VBOT);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*2, &QuadTextureData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
and rendering:
glUseProgram(shader);
glBindTexture(GL_TEXTURE_2D, texture);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBOT);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
I really have no idea why this is happening, Doing a texture without a shader crashes it, binding a shader without a texture crashes it. Any help or advice?
In a core opengl profile, you need to use VAOs in order to work with calls such as glDrawArrays and glDrawElements. A VAO (vertex array object) is a list of binding points for VBOs that encapsulates information such as data format and number of components for each VBO that is bound to it. In code it looks something like this.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3, &QuadVertextData, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glGenBuffers(1, &vbot);
glBindBuffer(GL_ARRAY_BUFFER, vbot);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*2, &QuadTextureData, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glBindVertexArray(0);
The 0 and 1 (the first argument to glVertexAttribPointer) specifies the generic vertex attribute index in your shader. The 2 and 3 (the second argument) specify the number of components. Your input should be defined like this in the shader in order to work with this VAO:
layout(location=0) in vec3 position;
layout(location=1) in vec2 textureCoordinates;
Before drawing anything, you just have to use the shader program, bind your texture and bind the VAO:
glUseProgram(shader);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(vao);
glDrawArrays(GL_QUADS, 0, 4);
Don't forget to set the texture location of the sampler2D uniform in the shader.
If you want to learn more about switching to the OpenGL core profile, I recommand the tutorials from http://www.opengl-tutorial.org/

glDrawArrays Crashes When Using Texture Coordinates

So I've implemented a really quick VBO just to see if its worth switching from display lists. I've ran into a bit of trouble though when I try to put in texture coordinates. It crashes with EXC_BAD_ACCESS with glDrawArrays. Im pretty sure its the way Im rendering the VBO's, specifically in the order that Im doing it, but I've tried just about everything and haven't been able to get it to work properly. Here is my code:
//create a vertex buffer object for the particles to use
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//create the data, this is really sloppy
float QuadVertextData[] = {0,0,0,1,0,0,1,1,0,0,1,0};
float QuadTextureData[] = {0,1,1,1,1,0,0,0};
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3, &QuadVertextData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//generate another buffer for the texcoords
glGenBuffers(1, &VBOT);
glBindBuffer(GL_ARRAY_BUFFER, VBOT);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*2, &QuadTextureData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
The rendering code:
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBOT);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
From what I've seen on the internet, Im not doing anything wrong.

C++/OpenGL - VAO Problems

After learning about VBOs, a friend told me to try using VAOs for linking cube indices with the vertices. I followed about every tutorial I could find with no avail. It looks like the buffers are binding correctly and everything works up until I try to draw them.
This is how I generate the VAO -
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glGenBuffers(1, &cubeIndex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeIndex);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(GLuint), cubeIndices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, sizeof(GLuint)*3, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(1);
glGenBuffers(1, &cubeVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 21 * sizeof(GLfloat), cubeVertPoints, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*3, 0);
glBindVertexArray(0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Rendering -
glEnableClientState(GL_VERTEX_ARRAY);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, size);//Runtime exception here if anything larger that '2' is provided?
glBindVertexArray(0);
Your code does not make sense. You never bind anything to GL_ARRAY_BUFFER, so your glVertexAttribPointer() calls will point to invalid VBOs - explaining the crash when you try to draw that thing.
I'm not sure what you're trying to do here. It looks like cubeIndex is supposed to be the element array for indexed rendering. But you seem to try to use the indices as vertex attributes. But you should use that as GL_EMEMENT_ARRAY_BUFFER (as you already do) in conjunction with glDrawElements() (what you don't do). Your cubeVBO should be a GL_ARRAY_BUFFER, and you should use that as a vertex attribute.
The sizes of your array also seem strange. 36 Uints do make sense as index buffer when drawing a cube with 6 sides and 2 triangles each. But 21 floats for the vertex data with 3 components per vector are just 7 vertices - strange for a cube.
Please have a look at the Vertex Specification and Vertex Rendering pages in the OpenGL wiki, or look into some tutorials - the code you posted so far makes me think that you didn't grasp the underlying concepts.

Opengles mixing VBO and non VBO renders gives EXC_BAD_ACCESS

Hey guys. Im trying to render two methods shown below. RenderA() is using VBOs and RenderB() isnt. Im getting an EXC_BAD_ACCESS error when it reaches glDrawArrays() in RenderB().
RenderB() works fine though if i dont create and use any VBOs, ie when i comment out CreateVBOs() and RenderA().
So does this mean once you start using VBOs, all renderings must use VBOs?
Or what am I doing wrong here?
Render() {
CreateVBOs(); //glGenBuffers,glBindBuffer,glBufferData etc
RenderA();
RenderB();
}
RenderA(){
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo->indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vbo->vertexBuffer);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0);
glColorPointer(4, GL_FLOAT, sizeof(Vertex), colorOffset);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDrawElements(GL_TRIANGLES,vbo->indexCount, GL_UNSIGNED_SHORT, bodyOffset);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
RenderB(){
static GLfloat vertices[] = {1.0,1.0,1.0,2.0,1.0,1.0};
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_POINTS, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);
}
Edit(Solved)
Figured it out. Apparently you have to make sure you unbind the buffer if it was binded before in order to render without vbo.
My CreateVBOs() function binded but did not unbind the buffer so thats what created bad access when RenderB() was trying to use glDrawArrays. Unbinding the buffer is just binding it to 0 like so:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Try binding GL_ELEMENT_ARRAY_BUFFER and GL_ARRAY_BUFFER to zero before doing your non-VBO draw calls.
Add the following lines of code to the end of your VBO draw calls (RenderA):
glBindBuffer(GL_ElEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);