我编写了一个类来导入.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);
第一种方法。这就是glDrawElemnt给我的。
2:
for(int i=0;i<trianglesNumber;i++)
{
glBegin(GL_TRIANGLES);
glNormal3f();glVertex3f();
glNormal3f();glVertex3f();
glNormal3f();glVertex3f();
glEnd();
}
第二种方法
答案 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;
}
感谢您的帮助.....................................