4
\$\begingroup\$

Introduction

Hello I will start out by explaining my setup, showing samples as I go along explaining the situation.


I'm using these tools:

  • OpenGL 3.3
  • GLSL 330
  • C++

Problem

The problem is when I render the wavefront obj 3d model it gives a very weird visual glitch the model was supposed to be a square but instead its a triangluated mess with parts of the vertexes pointing in a stretched direction in massive amounts towards the bottom left side of the frustum....

Explanation:

I'm using std::vectors to store my wavefront .obj model data using sscanf to get the floating point values into the structure members x,y,z and store them into the Points structure variable p;

int index = IndexAssigner(1, 1);
ifstream file (list[index].c_str() );
points.push_back(Point());
Point p;
int face[4]; 

while (!file.eof() ) {
    char  modelbuffer[10000];
    file.getline(modelbuffer, 10000);
    switch(modelbuffer[0]) {
        case 'v' :
        sscanf(modelbuffer, "v %f %f %f",  &p.x, &p.y, &p.z);
        points.push_back(p);
        break;
        case 'f':
        sscanf(modelbuffer, "f %d %d %d %d", face, face+1, face+2,  face+3 );
        faces.push_back(face[0]);
        faces.push_back(face[1]);
        faces.push_back(face[2]);
        faces.push_back(face[3]);
    }      
    //Turn on FileReader aka "RENDER CODE"
    FileReader = true;   
}

then I render the Points vector using the .data() member of std::vectors to the frustum.

Other declarations:

int numfloats = 4;
float* point=reinterpret_cast<float*>(&points[0]);
int num_bytes=numfloats*sizeof(float);

Vector declarations:

struct Point {float x,  y , z; };
std::vector<int>faces;
std::vector<Point>points;

Render code:

glGenBuffers(1, &vertexbuffer);
glGenTextures(1, &ModelTexture);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBindTexture(GL_TEXTURE_3D, ModelTexture);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA,  ModelSurface->w, ModelSurface->h, 0, GL_BGR, GL_UNSIGNED_BYTE, ModelSurface->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points.data(), GL_STATIC_DRAW);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE,num_bytes ,points.data());
glEnableVertexAttribArray(3);

//Translation Process
GLfloat TranslationMatrix[] = {
        1.0, 0.0, 0.0, 0.0, 
        0.0, 1.0, 0.0, 0.0, 
        0.0, 0.0, 1.0, 1.0,
        0.0, 0.0, 0.0, 1.0
      };

//Send Translation Matrix up to the vertex shader
glUniformMatrix4fv(translation, 1, TRUE, TranslationMatrix);

glDrawElements( GL_QUADS, faces.size(), GL_UNSIGNED_INT,  faces.data());

I tried looking at what was causing this and went through every function every parameter ,etc looked at the man pages.

Then found out that it could be my glVertexAttribPointer.

Here are the man pages for glVertexAttribPointer

http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml

The last 2 parameters is my problem

How do I write those 2 last parameters do I try putting the data from Points into it?.

glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE,num_bytes ,points.data());

How does it work with vectors?

Is it fast?*

if you can not be bothered too look at the man pages here is the scripts coming from the man pages directly.

Stride

Specifies the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in the array. The initial value is 0.

Pointer

Specifies a pointer to the first component of the first generic vertex attribute in the array. The initial value is 0.

If you want my full source -> http://ideone.com/fPfkg

Thanks Again if you do read this.

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

The parameters in your case should both be 0, because you don't have stride (your Point structure is packed) and because your data starts at the beginning of the vertex buffer.

However, there is another problem: sizeof(points) will not return the size of the data, only the size of the base vector class: you need to use your num_bytes instead.

But your computation of num_bytes uses the size of float, not Point. This is a more correct way to compute it:

num_bytes = points.size() * sizeof(points[0]);

And you are mixing GL_TEXTURE_3D and GL_TEXTURE_2D.

Also your "render" code should be split. There is initialisation code, and per-frame code.

This is initialisation code; it needs only be done once:

glGenTextures(1, &ModelTexture);
glBindTexture(GL_TEXTURE_2D, ModelTexture);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA,  ModelSurface->w, ModelSurface->h,
             0, GL_BGR, GL_UNSIGNED_BYTE, ModelSurface->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, num_bytes, points.data(), GL_STATIC_DRAW);

And this is code that needs to be run each frame:

glBindTexture(GL_TEXTURE_2D, ModelTexture);

glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0);

Hope this helps you fix your code a bit.

\$\endgroup\$
1
\$\begingroup\$

Also, Wavefront .OBJ format specifies that the index of the first vertex is 1. In OpenGL, it is assumed to be 0. So you might want to decrement each int of your faces vector to get correct indices in your array buffer.

faces.push_back(face[0] - 1);
faces.push_back(face[1] - 1);
faces.push_back(face[2] - 1);
faces.push_back(face[3] - 1);
\$\endgroup\$
6
  • \$\begingroup\$ thank you :D for the help that did help but I still have that stretchy vertex problem when I should have a 3d square :) \$\endgroup\$ Apr 11, 2012 at 14:56
  • \$\begingroup\$ any ideas why this may not be working ? :) \$\endgroup\$ Apr 11, 2012 at 15:28
  • \$\begingroup\$ Did you fix everything Sam pointed out? especially numfloats = 4; which is wrong, since your Point structure only contains 3 floats (so has a size of 3 * sizeof(float)). But num_bytes is not needed anyway, as explained by Sam. You still have a triangulated mess, or just a streched square? \$\endgroup\$
    – Benlitz
    Apr 11, 2012 at 16:17
  • \$\begingroup\$ yes but here is my code ideone.com/gwS7W and here is a picture i.imgur.com/vHByK.png \$\endgroup\$ Apr 11, 2012 at 17:04
  • \$\begingroup\$ :) hopefully that gives you some more insight in helping me thank you btw \$\endgroup\$ Apr 11, 2012 at 17:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .