Draw Alternate vertices in OpenGL VBO - opengl

I am learning how to manipulate and draw vbo objects between OpenCL and OpenGL.
I have an array of float4 vertices in a VBO to describe lines which I am rendering using:
glBindBufferARB(GL_ARRAY_BUFFER_ARB, rbo);
glVertexPointer(3, GL_FLOAT, sizeof( float4 ), 0);
glColor4f(1, 0, 1, 0.4);
glPointSize(1);
glDrawArrays(GL_LINES, 0, db_rays);
etc...
But I would like to only render each other (i.e. alternate) vertices in the array as points (so GL_POINTS). Is there a smart way to tell openGL to do this?
I have tried
glVertexPointer(3, GL_FLOAT, sizeof( float4 )*2, 0);
But this doesn't seem to draw anything?
S

Related

openGL, C++, how do I make an imported OBJ object move?

I am currently using this: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading/
All I've done so far is replace the model, changed up the camera so that it is isometric, and made the cursor show up again. So nothing major.
My new model shows up perfectly along with its textures. I was wondering how I can make it so that by pressing W, A, S, & D, I can move my model around?
I'm planning on making a very simple "game" where I just move my model around, and collide with other objects scattered around the map.
Any help is appreciated! Thanks everyone!
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(programID);
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture);
// Set our "myTextureSampler" sampler to user Texture Unit 0
glUniform1i(TextureID, 0);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(
1, // attribute
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, vertices.size() );
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
the MVP matricies encode the translation, rotation and scaling of the model. It is the product of the Projection * View * Modelmatrix. If you apply the translation the the Modelmatrix and recalculate mvp, then you should see the object moving.

OpenGL Draw only some indexes from vertex array

how can I only draw selected indices from vertex array in OpenGL?
For instance, I am drawing my vertices like points, with some variable m_pointCloud containing my point cloud vertices (points):
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glPointSize(m_pointSize * point_scale);
glColorPointer(4, GL_UNSIGNED_BYTE,
static_cast<GLsizei>(sizeof(DensePoint)), &((*m_pointCloud)[0].r));
// glNormalPointer(GL_FLOAT,
// static_cast<GLsizei>(sizeof(DensePoint)), &((*m_pointCloud)[0].n_x));
glVertexPointer(3, GL_FLOAT,
static_cast<GLsizei>(sizeof(DensePoint)), &((*m_pointCloud)[0].x));
glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(m_pointCloud->size()) - 1);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
But I have some std::vector<size_t> indices containing the indices from m_pointCloud that I want to draw. How is this done?
Instead of glDrawArrays, use glDrawElements.
For example:
std::vector<GLuint> indices;
// populate vertices
glDrawElements(GL_POINTS, indices.size(), GL_UNSIGNED_INT, reinterpret_cast<void*>(indices.data()));
Note also that you cannot use size_t as an index type as OpenGL only allows 8, 16 and 32-bit indices.

OpenGL and GL_Blend with glDrawElements

Solved by adding glDepthFunc(GL_ALWAYS);
I'm trying to blend two textures on a heightfield with glDrawElements. Normalpointer and vertexpointer data are the same but the TexCoordPointer are different for the two textures. No matter which BlendFunc I try there's always only one of the textures visible although large parts of texture_two are transparent. Does glDrawElements work with gl_blend or am I doing it wrong?
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
glDepthFunc(GL_ALWAYS);
glNormalPointer(GL_FLOAT, 0, normals);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texture_ind_one);
glBindTexture(GL_TEXTURE_2D, texture_one);
glDrawElements(GL_TRIANGLES, indicies_num, GL_UNSIGNED_INT, indices);
glNormalPointer(GL_FLOAT, 0, normals);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texture_ind_two);
glBindTexture(GL_TEXTURE_2D, texture_two);
glDrawElements(GL_TRIANGLES, indicies_num, GL_UNSIGNED_INT, indices);
Thank you very much!
You need to set an appropriate depth function via glDepthFunc using something that has "equals" in it (probably GL_LEQUAL), since you are drawing twice at the same depth.
You can also consider blending the textures yourself inside a fragment shader.

OpenGL VBO drawing with multitexturing issue

I'm currently using a VBO to draw a series of cubes in OpenGL using a GLSL shader that performs multitexturing (with 5 textures). It works fine if I don't pass the textures in. But if I try to use texturing at all, the whole screen is only drawn white (presumably the last clear color). If I pass the textures in using immediate mode (without the VBO) then it's also fine there. I can't tell why there's a problem.
Code:
// create vertex/normal/color/texcoord VBO
glGenBuffersARB(1, &vboId);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vert_buf)+sizeof(norm_buf)+sizeof(col_buf)+sizeof(tex_buf), 0, GL_STREAM_DRAW);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(vert_buf), vert_buf);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vert_buf), sizeof(norm_buf), norm_buf);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vert_buf)+sizeof(norm_buf), sizeof(col_buf), col_buf);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vert_buf)+sizeof(norm_buf)+sizeof(col_buf), sizeof(tex_buf), tex_buf);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
// create geometry indices VBO
glGenBuffersARB(1, &vboId2);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vboId2);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(index_buf), index_buf, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
// bind vertex/normal/color/texcoord VBO
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
// enable vertex arrays
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
// specify vertex and index arrays with their offsets
glVertexPointer(3, GL_FLOAT, 0, 0);
glNormalPointer(GL_FLOAT, 0, (void*)sizeof(vert_buf));
glColorPointer(3, GL_FLOAT, 0, (void*)(sizeof(vert_buf)+sizeof(norm_buf)));
// bind geometry indices VBO
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vboId2);
glIndexPointer(GL_UNSIGNED_INT, 0, 0);
// set the texture units
GLvoid* start = (void*)(sizeof(vert_buf)+sizeof(norm_buf)+sizeof(col_buf));
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[0].tex_id); // same as GL_TEXTURE1
glTexCoordPointer(2, GL_FLOAT, 0, start);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[1].tex_id); // same as GL_TEXTURE2
glTexCoordPointer(2, GL_FLOAT, 0, start);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[2].tex_id); // same as GL_TEXTURE3
glTexCoordPointer(2, GL_FLOAT, 0, start);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + noiseTexID); // same as GL_TEXTURE4
glTexCoordPointer(2, GL_FLOAT, 0, start);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + lutTexID); // same as GL_TEXTURE5
glTexCoordPointer(2, GL_FLOAT, 0, start);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// draw VBOs
glDrawElements(GL_TRIANGLES, 36*ROWS*COLS, GL_UNSIGNED_INT, 0);
// disable arrays
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
// disable texture arrays
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[0].tex_id);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[1].tex_id);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[2].tex_id);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + noiseTexID);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + lutTexID);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// unbind VBOs
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
Note: the creation of the VBOs is called during the initial setup phase. The drawing happens in a drawing GLUT routine.
Try resetting your texture level back to 0:
glClientActiveTexture(GL_TEXTURE0);
It's not uncommon for weirdness to happen when the active texture level isn't reset (say if you're using FBOs, etc).
It might also be helpful to set your clear colour to something other than black/white/transparent to see if the screen is being drawn with the clear colour or if you're somehow seeing a texel stretched or something else.

How do you handle multiple textures in an OpenGL indexed buffer array for use with a data-shader?

I'm attempting to implement this paper. I've have most of it down, but the part about sending arbitrary, non-geometric data to the shader for use in determining and displaying geometric edges is causing me problems. I've managed to successfully send most of my data just fine using what I know of VBOs. However, I need to send a large amount of data, which necessitates the use of multiple texture coordinates.
I've already implemented several variations of what I believe to be the correct way of setting up multiple sets of texture coordinates, and followed the instructions of many forum posters. No solutions work thus far.
For context, the program is sending 4 nearly identical copies of a set of 4 vertices, 2 normal vectors, a float, and an integer (stored as a float) for each unique edge in the model. I've laid out the data like this:
v0 is stored in gl_Vertex (vec3)
v1 is stored in gl_Color (vec3)
v2 is stored in gl_MultiTexCoord0 (vec3)
v3 is stored in gl_MultiTexCoord1 (vec3)
n0 is stored in gl_Normal (vec3)
n1 is stored in gl_SecondaryColor (vec3)
r and i are stored in gl_MultiTexCoord2 (vec2)
The only difference between the 4 copies is the i value, which helps determine how to organize the vertices if and when a drawable edge is found.
As you can see, I need at least 3 texture coordinates. I was able to get the first one working (gl_MultiTexCoord0) just fine, but any following texture coordinates, though on the graphics card, appear to have uncontrollable behavior, sometimes working, but usually not.
My rendering function used to look like this:
void Mesh::RenderLineEdgesGPU()
{
// Enable client state
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Turn on edge shader
edgeProgram.Activate();
// Link buffers
// v0
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[0]);
glVertexPointer(3, GL_FLOAT, 0, 0);
// v1
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[1]);
glColorPointer(3, GL_FLOAT, 0, 0);
// v2
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[2]);
glTexCoordPointer(3, GL_FLOAT, 0, 0);
// v3
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[3]);
glTexCoordPointer(3, GL_FLOAT, 0, 0);
// n0
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[4]);
glNormalPointer(GL_FLOAT, 0, 0);
// n1
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[5]);
glSecondaryColorPointer(3, GL_FLOAT, 0, 0);
// r and i
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[6]);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
// Indicies
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, edgeMeshHandles[7]);
// Draw
glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);
// Turn off edge shader
edgeProgram.Deactivate();
// Disable client state
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
This was my original one. It definitely works for v0, v1, and v2. It appears to work for "r and i", but that could be an illusion. I don't have the ability to test n0 or n1 yet. v3 definitely DOES NOT work. As you can see, I'm drawing them as points, which tells me if they are there or not (via the shader). v0, v1, and v2 are all there. Attempting to do the same for v3 yields either a single point at the origin or nothing at all.
After looking at suggestions online, here's my new setup:
void Mesh::RenderLineEdgesGPU()
{
// Enable client state
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
// Turn on edge shader
edgeProgram.Activate();
// Link buffers
// v0
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[0]);
glVertexPointer(3, GL_FLOAT, 0, 0);
// v1
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[1]);
glColorPointer(3, GL_FLOAT, 0, 0);
// v2
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[2]);
glTexCoordPointer(3, GL_FLOAT, 0, 0);
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// v3
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[3]);
glTexCoordPointer(3, GL_FLOAT, 0, 0);
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// n0
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[4]);
glNormalPointer(GL_FLOAT, 0, 0);
// n1
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[5]);
glSecondaryColorPointer(3, GL_FLOAT, 0, 0);
// r and i
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[6]);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
// Indicies
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, edgeMeshHandles[7]);
// Draw
glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);
// Turn off edge shader
edgeProgram.Deactivate();
// Disable client state
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
}
Notice how I've done the glEnableClientState / glDisableClientState calls around the actual "loading" of each texture coordinate list. I also use glActiveTextureARB and glEnable(GL_TEXTURE_2D). While I think I might understand why glActiveTextureARB is needed here, the other one baffles me. According to the GLSL Common Mistakes page, you're not supposed to use glEnable(GL_TEXTURE_2D) when you make your own shaders, since the use of shaders ignores this call anyway.
So that's it. I've gotten this far without being able to find any tutorials specifically addressing how to send non-texture coordinate data in texture coordinates. Perhaps if someone knows a tutorial on that, my problem would be alleviated. Thanks for your time!
glClientActiveTextureARB changes which specific texture coordinate unit following calls to glEnableClientState(GL_TEX_COORD_ARRAY) and glTexCoordPointer will alter.
glActiveTextureARB affects glEnable(GL_TEXTURE_2D), which, as you mentioned, you don't need for shaders.
If you look at your code closely, picking only those 5 calls (and their equivalent Disable), here is what you have:
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexCoordPointer(3, GL_FLOAT, 0, 0);
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glTexCoordPointer(3, GL_FLOAT, 0, 0);
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);
Ok, we already said that glActiveTextureARB and glEnable are not useful (by the way, you enable/disable GL_TEXTURE_2D without any draw in between, that's not useful), so remove them:
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(3, GL_FLOAT, 0, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(3, GL_FLOAT, 0, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);
What stands out now ? 2 issues:
You Disable your client state before ever executing Draw
You don't set the Enable bit for TEXTURE2
What should you write ? Something along those lines: (Beware, you'll need to add the BindBuffer calls back to each Pointer call):
// texture coord 0
glClientActiveTextureARB(GL_TEXTURE0_ARB); // program texcoord unit 0
glEnableClientState(GL_TEXTURE_COORD_ARRAY); // enable array data to shader
glTexCoordPointer(3, GL_FLOAT, 0, 0); // say what data
// texture coord 1
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(3, GL_FLOAT, 0, 0);
// texture coord 2
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);
// done with those texcoord units, turn them off
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
Some more comments on BindBuffer: glBindBufferARB(GL_ARRAY_BUFFER_ARB,...) does not get affected by the glClientActiveTextureARB, but it does affect the next glTexCoordPointer call. In essence, think of glClientActiveTextureARB and glBindBufferARB as providing extra arguments to glTexCoordPointer.
Last thing, you probably want to group some of those VBOs in less buffers. Something for another question maybe ? (Hint, the 2 arguments to glTexCoordPointer don't have to be 0)