So I'm swapping from one program to another, and I can't figure out why but GL_QUADS will no longer display with the same code. To try and figure out why old code was not working, I made this new, simple code and it STILL does not work.
The setup:
vector <vec3f> squarepoints;
vec3f temper(-0.5f, 0.5f, 0.5f);
squarepoints.push_back(temper);
temper.x += 1.0f;
squarepoints.push_back(temper);
temper.y -= 1.0f;
squarepoints.push_back(temper);
temper.x -= 1.0f;
squarepoints.push_back(temper);
vector <unsigned int> squareindex;
squareindex.push_back(0);
squareindex.push_back(1);
squareindex.push_back(2);
//squareindex.push_back(0);
//squareindex.push_back(2);
squareindex.push_back(3);
GLuint VAOO;
GLuint IBOO;
GLuint VBOO;
glGenVertexArrays(1, &VAOO);
glBindVertexArray(VAOO);
glGenBuffers(1, &VBOO);
glBindBuffer(GL_ARRAY_BUFFER, VBOO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec3f) * squarepoints.size(), &squarepoints[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT,GL_FALSE, 0, 0);
glGenBuffers(1, &IBOO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * squareindex.size(), &squareindex[0], GL_STATIC_DRAW);
glBindVertexArray(0);
The drawing:
glBindVertexArray(VAOO);
glDrawElements(GL_QUADS, squareindex.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
This displays nothing. Now if I add in the two commented lines in the setup to make it 6 points and change it to GL_TRIANGLES in the drawing, it all displays perfectly. I am not sure where the fault is lying here, but I've been trying to fix my model loading and other features so long that I'm sure I'm just overlooking something super obvious at this point.
GL_QUADS have been removed from core OpenGL 3.1 and above.
Related
So I'm swapping from one program to another, and I can't figure out why but GL_QUADS will no longer display with the same code. To try and figure out why old code was not working, I made this new, simple code and it STILL does not work.
The setup:
vector <vec3f> squarepoints;
vec3f temper(-0.5f, 0.5f, 0.5f);
squarepoints.push_back(temper);
temper.x += 1.0f;
squarepoints.push_back(temper);
temper.y -= 1.0f;
squarepoints.push_back(temper);
temper.x -= 1.0f;
squarepoints.push_back(temper);
vector <unsigned int> squareindex;
squareindex.push_back(0);
squareindex.push_back(1);
squareindex.push_back(2);
//squareindex.push_back(0);
//squareindex.push_back(2);
squareindex.push_back(3);
GLuint VAOO;
GLuint IBOO;
GLuint VBOO;
glGenVertexArrays(1, &VAOO);
glBindVertexArray(VAOO);
glGenBuffers(1, &VBOO);
glBindBuffer(GL_ARRAY_BUFFER, VBOO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec3f) * squarepoints.size(), &squarepoints[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT,GL_FALSE, 0, 0);
glGenBuffers(1, &IBOO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * squareindex.size(), &squareindex[0], GL_STATIC_DRAW);
glBindVertexArray(0);
The drawing:
glBindVertexArray(VAOO);
glDrawElements(GL_QUADS, squareindex.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
This displays nothing. Now if I add in the two commented lines in the setup to make it 6 points and change it to GL_TRIANGLES in the drawing, it all displays perfectly. I am not sure where the fault is lying here, but I've been trying to fix my model loading and other features so long that I'm sure I'm just overlooking something super obvious at this point.
GL_QUADS have been removed from core OpenGL 3.1 and above.
I have been working with VBOs in OpenGL, and I apparently don't understand what I'm even doing wrong here. I want to display a VBO with text in it that is updated each frame. The goal this time is for a FPS counter, but other applications are definitely viable.
Down to the actual code: I can get it to work just fine if I set up the VBOs in my initialization function and then draw it in the rendering function. If I try and edit it in the draw function, however, nothing displays. While debugging I have found that all of the vectors containing the data are exactly correct (I even updated the VBO with the same text and the vectors were indeed identical), so the issue must be with my handling of VBOs, and not the data inside of them.
Here is the initialization/rendering commands:
glGenBuffers(1, &pntvbo);
glBindBuffer(GL_ARRAY_BUFFER, pntvbo);
glBufferData(GL_ARRAY_BUFFER, newpoints.size() * sizeof(vec3f), &newpoints[0], GL_STREAM_DRAW);
glGenBuffers(1, &indvbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indvbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, newindex.size() * sizeof(unsigned int), &newindex[0], GL_STREAM_DRAW);
I also tried this, but with no success:
glBindBuffer(GL_ARRAY_BUFFER, pntvbo);
glBufferData(GL_ARRAY_BUFFER, newpoints.size() * sizeof(vec3f), NULL, GL_STREAM_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, newpoints.size() * sizeof(vec3f), &newpoints[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indvbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, newindex.size() * sizeof(unsigned int), NULL, GL_STREAM_DRAW);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0, newindex.size() * sizeof(unsigned int), &newindex[0]);
And the draw command itself:
glClientActiveTexture(GL_TEXTURE5);
glEnable(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, &newtexts[0]);
glBindBuffer(GL_ARRAY_BUFFER, pntvbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indvbo);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,sizeof(vec3f),0);
glDrawElements(GL_TRIANGLES, newindex.size() , GL_UNSIGNED_INT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
I'm sure I'm doing SOMETHING wrong here, but I just can't figure out for the life of me as to what it is. As I said, everything works out fine if I only initialize or edit the VBO in the initialization function of my program, but once those same functions are put into the rendering function nothing displays. Any help would be greatly appreciated.
I generated model (Suzie) in blender and exported it to .obj file with normals. During loading mode to my app i noticed that numbers of vertices and normals are diffrent (2012 and 1967).
I try to implement simple cell shading. The problem is in passing normals to shader. For storing vertex data i use vectors from glm.
std::vector<unsigned int> face_indices;
std::vector<unsigned int> normal_indices;
std::vector<glm::vec3> geometry;
std::vector<glm::vec3> normals;
Result i've got so far
Buffers Layout
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, geometry.size() * sizeof(glm::vec3), &geometry[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, NormalVBOID);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_DYNAMIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VIndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, face_indices.size() * sizeof(unsigned int), &face_indices[0], GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Rendering fragment
glBindVertexArray(VAO);
glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS);
glDrawElements(GL_QUADS, face_indices.size(), GL_UNSIGNED_INT, (void*)0);
glBindVertexArray(0);
The reason that had such wierd problem was that some normals were used more than once to preserve disk space so i had to rearrange them in a proper order. So the solution is pretty trival.
geometry.clear();
normals.clear();
geometry.resize(vv.size());
normals.resize(vv.size());
for (unsigned int i = 0; i < face_indices.size(); i++)
{
int vi = face_indices[i];
int ni = normal_indices[i];
glm::vec3 v = vv [vi];
glm::vec3 n = vn [ni];
geometry[vi] = v ;
normals[vi] = n ;
indices.push_back(vi);
}
You should also keep in mind that using the smooth modifier in Blender before export will in some cases help ensure that you have 1 normal per vertex (you may or may not need to also set per-vert normal view instead of face-normal view...can't rem so you'll have to test). This is because by default, blender uses per-face normals. The smooth modifier ("w" hotkey menu)
will switch it to per-vertex norms. Then when you export, you export verts and norms as usual, and the number should match. It doesn't always, but this has worked for me in the past.
This could possibly mean less unnecessary juggling of your data during import.
I've been trying to convert some of my code to modern OpenGL. I've gotten it to the point where I don't get any OpenGL errors, but nothing shows up when I try to draw an object. Here's my code (minus context creation, and error checking):
//Compile shaders and create/link program
//I very highly doubt the problem's here (all my tests say it worked fine),
//so I'm leaving this out for now, but I'll dig it out of my classes if
//there's no obvious problem with the VBO code.
//Create VAO, VBO
unsigned vaoId, vboId;
int positionAttributeLocation;
float vertices[] = {...vertex data here...};
unsigned indices[] = {...index data here...};
positionAttributeLocation = glGetAttribLocation(programId, "position");
glGenVertexArrays(1, &vaoId);
glGenBuffers(1, &vboId);
glBindVertexArray(vaoId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, null);
glEnableVertexAttribArray(positionAttributeLocation);
//Create index buffer
unsigned indexId;
glGenBuffers(1, &indexId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glUseProgram(programId);
glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(unsigned int), GL_UNSIGNED_INT, null);
Not quite SSCCE, but I think that's all the code that could possibly be causing an issue and it's pretty much self-contained.
Try glUseProgram() before your glGetAttribLocation()/glEnableVertexAttribArray() calls.
I figured it out. With some of my refactoring, I forgot to set my width and height variables properly, creating a 0 by 0 viewport. Oops...
Your problem more than likely lies with your cg program and modelview space.
Add cgGLSetStateMatrixParameter(modelViewMatrix, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); to your program just before gldrawarrays, and in your cg file add OUT.HPos = mul(ModelViewProj, IN.position);.
Also add modelViewMatrix as a cgparameter in you initcg section.
I worked this out from the basic opengl samples in the cgtoolkit, and my render function is very similar to yours and now works after having the same problem.
I decided to import Wavefront .OBJ format to a test-scene that I'm working on. I get the model (vertices) to be in the right place and it displays fine. When I then apply a texture a lot of things looks distorted. I checked my Maya scene (there it looks good), and the object has many more uv-coordinates than vertex positions (this is what makes the scene looks weird in OpenGL, is my guess).
How would I go about loading a scene like that. Do I need to duplicate vertices and how do I store it in the vertex-buffer object?
You are right that you have to duplicate the vertices.
In addition to that you have to sort them in draw order, meaning that you have to order the vertices with the same offsets as the texture coordinates and normals.
basically you'll need this kind of structure:
float *verts = {v1_x,v1_y,v1_z,v1_w,v2_x,v2_y,v2_z,v2_w,...};
float *normals = {n1_x,n1_y,n1_z,n2_x,n2_y,n2_z,...};
float *texcoords = {t1_u,t1_v,t1_w,t2_u,t2_v,t2_w,...};
This however would mean that you have at least 108bytes per Triangle.
3(vert,norm,tex)
*3(xyz/uvw)
*3(points in tri)
*4(bytes in a float))
-----------------------
= 108
You can significantly reduce that number by only duplicating the vertices that actually are duplicate (have identical texture coordinate,vertices and normals meaning: smoothed normals and no UV borders) and using an Index Buffer Object to set the draw order.
I faced the same problem recently in a small project and I just split the models along the hard-edges and UV-Shell borders therefore creating only the necessary duplicate Vertices. Then I used the glm.h and glm.cpp from Nate Robins and copied/sorted the normals and texture coordinates in the same order as the vertices.
Then setup the VBO and IBO:
//this is for Data that does not change dynamically
//GL_DYNAMIC_DRAW and others are available
GLuint mDrawMode = GL_STATIC_DRAW;
//////////////////////////////////////////////////////////
//Setup the VBO
//////////////////////////////////////////////////////////
GLuint mId;
glGenBuffers(1, &mId);
glBindBuffer(GL_ARRAY_BUFFER, mId);
glBufferData(GL_ARRAY_BUFFER,
mMaxNumberOfVertices * (mVertexBlockSize + mNormalBlockSize + mColorBlockSize + mTexCoordBlockSize),
0,
mDrawMode);
glBufferSubData(GL_ARRAY_BUFFER, mVertexOffset, numberOfVertsToStore * mVertexBlockSize, vertices);
glBufferSubData(GL_ARRAY_BUFFER, mNormalOffset, numberOfVertsToStore * mNormalBlockSize, normals);
glBufferSubData(GL_ARRAY_BUFFER, mColorOffset, numberOfVertsToStore * mColorBlockSize, colors);
glBufferSubData(GL_ARRAY_BUFFER, mTexCoordOffset, numberOfVertsToStore * mTexCoordBlockSize, texCoords);
//////////////////////////////////////////////////////////
//Setup the IBO
//////////////////////////////////////////////////////////
GLuint IBOId;
glGenBuffers(1, &IBOId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mMaxNumberOfIndices * sizeof(GLuint), 0, mDrawMode);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, numberOfIndicesToStore * sizeof(GLuint), indices);
//////////////////////////////////////////////////////////
//This is how to draw the object
//////////////////////////////////////////////////////////
glBindBuffer(GL_ARRAY_BUFFER, mId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOId);
//Enables and Disables are only necessary each draw
//when they change between objects
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(mVertexComponents, GL_FLOAT, 0, (void*)mVertexOffset);
if(mNormalBlockSize){
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, (void*)mNormalOffset);
}
if(mColorBlockSize){
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(mColorComponents, GL_FLOAT, 0, (void*)mColorOffset);
}
if(mTexCoordBlockSize){
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(mTexCoordComponents, GL_FLOAT, 0, (void*)mTexCoordOffset);
}
glDrawRangeElements(primMode,
idFirstVertex,
idLastVertex,
idLastVertex - idFirstVertex + 1,
mAttachedIndexBuffer->getDataType(),
0);
if(mTexCoordBlockSize)
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if(mColorBlockSize)
glDisableClientState(GL_COLOR_ARRAY);
if(mNormalBlockSize)
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);