glNormalPointer似乎不正确

时间:2013-06-26 11:24:22

标签: c++ opengl glut

我编写了一个类来导入.obj模型。但法线似乎不正确。 所以我试着在我的代码中找到了很多天的错误。但是我没有找到任何错误。 然后我将“glDrawElement()”更改为以下代码。

for(int i=0;i<trianglesNumber;i++)
{
glBegin(GL_TRIANGLES);
glNormal3f();glVertex3f();
glNormal3f();glVertex3f();
glNormal3f();glVertex3f();
glEnd();
}

那么法线是正确的。

我想知道如何解决这个问题。但是当导入较大的模型时,第二种方法的FPS太低。如果你帮我解决这个问题,我会非常感激。

以下是两种方法的代码和结果。

1:

void init()
{
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glTexCoordPointer(3,GL_DOUBLE,0,textures);
    glNormalPointer(GL_DOUBLE,0,normals);
    glVertexPointer(3,GL_DOUBLE,0,vertex);
}

然后glDrawElements(GL_TRIANGLES,faces*3,GL_UNSIGNED_INT,vertexIndex);

1st method.This what glDrawElemnt gave me.

第一种方法。这就是glDrawElemnt给我的。

2:

for(int i=0;i<trianglesNumber;i++)
{
glBegin(GL_TRIANGLES);
glNormal3f();glVertex3f();
glNormal3f();glVertex3f();
glNormal3f();glVertex3f();
glEnd();
}

2nd method

第二种方法

1 个答案:

答案 0 :(得分:0)

这个页面向我展示了一种方法。 http://www.opengl.org/wiki/VBO_-_just_examples

我的代码如下。

#include"gl\glew.h"
#include"obj-catcher.h"
#include"gl\glut.h"

#define ushort unsigned int
#define BUFFER_OFFSET(i) ((char *)NULL + (i))

Catch  A("models\\ballALL.obj");
int xRot=0;
int Size=1;
GLfloat lightPos[]={0.0f,0.0f,500.0f,10};
GLfloat specular[]={1.0f,1.0f,1.0f,1.0f};
GLfloat specref[]={1.0f,1.0f,1.0f,1.0f};
GLfloat ambientLight[]={1.0f,1.0f,0.0f,1.0f};
GLfloat spotDir[]={0.0f,0.0f,-1.0f};

GLuint VertexVBOID,IndexVBOID;

struct MyVertex
{
    float x, y, z;
    Normal vn;
    float s0, t0 , w0;
}*pvertex;
unsigned int *index;
int something()
{
    glEnable(GL_LIGHTING);
    glClearColor(0.0f,0.0f,0.0f,1.0f);
    glShadeModel(GL_SMOOTH);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientLight);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,ambientLight);
    glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
    glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,60.0f);
    glEnable(GL_LIGHT0);
    return 0;
}
int SetupRC()
{
    glEnable(GL_DEPTH_TEST);
    glClearDepth(1);
    pvertex=new MyVertex [A.get_f()*3];
    index=new unsigned int [A.get_f()*3];
    for(int i=0;i<A.get_f()*3;i++)
    {
        index[i]=i;
        pvertex[i].x=A.get_vertex()[A.get_vi()[i]*3];pvertex[i].y=A.get_vertex()[A.get_vi()[i]*3+1];pvertex[i].z=A.get_vertex()[A.get_vi()[i]*3+2];
        pvertex[i].s0=A.get_texture()[A.get_ui()[i]*3+0];pvertex[i].t0=A.get_texture()[A.get_ui()[i]*3+1];pvertex[i].w0=A.get_texture()[A.get_ui()[i]*3+2];
        pvertex[i].vn=A.get_normal()[A.get_vni()[i]];
    }
    glGenBuffers(1, &VertexVBOID);//注意这句在原文章里是错的。原文章的网址在本文最下方
    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*3*A.get_f(), &pvertex[0].x, GL_STATIC_DRAW);
    glGenBuffers(1, &IndexVBOID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(ushort)*3*A.get_f(), index, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
    glEnableVertexAttribArray(0);                                                                                           //We like submitting vertices on stream 0 for no special reason
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));     //VBO顶点数据在内存中的起始位置
    glEnableVertexAttribArray(1);                                                                                           //我们把法线在编号为1的流中提交,没什么特别的原因
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(12));//法线在内存中的起始位置,偏移量为12字节
    glEnableVertexAttribArray(2);                                                                                           //我们把纹理在编号为2的流中提交,没什么特别的原因
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(24));//纹理在内存中的起始位置,偏移量为24字节
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glNormalPointer(GL_FLOAT,sizeof(MyVertex),BUFFER_OFFSET(12));   
    glTexCoordPointer(3,GL_FLOAT,sizeof(MyVertex),BUFFER_OFFSET(12));
    if(index) {delete [] index;index=NULL;}
    if(pvertex){delete [] pvertex;pvertex=NULL;}
    something();
    return 0;
}
void renderscene()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glColor3f(1.0,1.0,1.0);
    glPushMatrix();
        glRotatef(xRot++,0.0f,1.0f,0.0f);
            glDrawElements(GL_TRIANGLES,A.get_f()*3, GL_UNSIGNED_INT, BUFFER_OFFSET(0));
    glPopMatrix();
    glutSwapBuffers();
}
void TimerFunction(int value)
{
    glutPostRedisplay();
    glutTimerFunc(33,TimerFunction,1);
}
void windowchange(int w,int h)
{
    float fAspect;
    if(h==0)
        h=1;
    glViewport(0,0,w,h);
    fAspect=(GLfloat)w/(GLfloat)h;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1*Size,Size,-1*Size,Size,-1*Size,Size);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
int main(int argc,char *argv[])
{
    glutInit( &argc , argv );
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
    glutInitWindowSize(300,300);
    glutCreateWindow("obj-catcher,example(for OpenGL)");
    glutReshapeFunc(windowchange);
    glutDisplayFunc(renderscene);
    glutTimerFunc(1,TimerFunction,1);
    glewInit();
    SetupRC();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glutMainLoop();
    if(index) {delete [] index;index=NULL;}
    if(pvertex){delete [] pvertex;pvertex=NULL;}
    return 0;
}

enter image description here

感谢您的帮助.....................................