本文介绍了新手的问题是在OpenGL程序中使用lib3ds.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好!

我目前在我的opengl程序中使用lib3ds绘制模型.

从3ds文件中读取顶点后,它会在屏幕上显示一个车辆模型,但是当我将光分配到表面时,我发现有一些片段显示不正确.

在较近的表面上出现了一些较远的像素(事实上,我启用了深度缓冲功能),我无法弄清代码出了什么问题.

附上我的代码:

Hi there!

I am currently using lib3ds draw models in my opengl program.

After drawing vertex reading from the 3ds file, it appears a vehicle model on screen, but while I assign the light onto the surface I found there is some fragment displayed incorrectly.

Some far pixel appeared on the nearer surface (matter fact I enabled the depth buffer facility) that I can`t figure what`s wrong with the code.

Attached is my code:

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <lib3ds.h>
#include <iostream>
typedef float Lib3dsVector[3];
typedef float Lib3dsTexel[2];
using namespace std;
Lib3dsFile* model;
Lib3dsMesh** mesh;
Lib3dsCamera** camera;
Lib3dsFace* face;
Lib3dsLight** light;
Lib3dsMaterial** material;
GLuint vertexVBO,normalVBO,textureVBO;
unsigned long total_face;
void lightup()
{
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CCW);
    float gambient[]={0.2,0.2,0.2,1.0};
    float lightpos[]={1.0,1.0,1.0,0.0};
    float lambient[]={1.0,1.0,1.0,1.0};
    float ldiffuse[]={0.8,0.8,0.8,1.0};
    float lspecular[]={0.3,0.3,0.3,1.0};
    glLightfv(GL_LIGHT0,GL_DIFFUSE,ldiffuse);
    glLightfv(GL_LIGHT0,GL_AMBIENT,lambient);
    glLightfv(GL_LIGHT0,GL_SPECULAR,lspecular);
    glLightfv(GL_LIGHT0,GL_POSITION,lightpos);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,gambient);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
}
void getfaces()
{
    total_face=0;
    for(long meshcount=0;meshcount<model->nmeshes;meshcount++)
        total_face+=mesh[meshcount]->nfaces;
}
void display()
{
    glEnable(GL_DEPTH_TEST);
    glClearDepth(1.0);
    glDepthFunc(GL_LEQUAL);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BITS);
    glLoadIdentity();
    gluLookAt(camera[0]->position[0]+1000,camera[0]->position[1],camera[0]->position[2],camera[0]->target[0],camera[0]->target[1],camera[0]->target[2],0.0,0.0,1.0);
    glColor3f(1.0,0.0,0.0);
    glPushMatrix();
    lightup();
    glScalef(0.5,0.5,0.5);
    glTranslatef(0.0,0.0,-1000.0);
    long meshcount;
    for(meshcount=0;meshcount<model->nmeshes;meshcount++)
    {
        face=mesh[meshcount]->faces;
        for(long i=0;i<mesh[meshcount]->nfaces;i++)
        {
            glMaterialfv(GL_FRONT,GL_DIFFUSE,material[face[i].material]->diffuse);
            glMaterialfv(GL_FRONT,GL_AMBIENT,material[face[i].material]->ambient);
            glMaterialfv(GL_FRONT,GL_SPECULAR,material[face[i].material]->specular);
            glBegin(GL_TRIANGLES);
            glVertex3fv(mesh[meshcount]->vertices[face[i].index[0]]);
            glVertex3fv(mesh[meshcount]->vertices[face[i].index[1]]);
            glVertex3fv(mesh[meshcount]->vertices[face[i].index[2]]);
            glEnd();
        }
    }
    glPopMatrix();
/*
    glPushMatrix();
    glTranslatef(0.0,0.0,-2000.0);
    glColor3f(1.0,1.0,1.0);
    glBegin(GL_QUADS);
    glVertex3f(-10000.0f,-10000.0f,0.0f);
    glVertex3f(10000.0f,-10000.0f,0.0f);
    glVertex3f(10000.0f,10000.0f,0.0f);
    glVertex3f(-10000.0f,10000.0f,0.0f);
    glEnd();
    glPopMatrix();
*/
    glutSwapBuffers();
}
void keypress(unsigned char key,int x,int y)
{
    switch(key)
    {
    case 27:
        exit(0);
        break;
    }
}
void reshape(int w,int h)
{
    if(h==0) h=1;
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0,w/h,0.0,1000.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
int main(int argc,char* argv[])
{
    glutInit(&argc,argv);
    model=lib3ds_file_open("vehicle.3DS");
    if(model==NULL) cout<<"Error"<<endl; else cout<<model->nmaterials<<endl;
    mesh=model->meshes;
    material=model->materials;
    camera=model->cameras;
    light=model->lights;
    cout<<"Light Num:"<<model->nlights<<endl;

    glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
    glutInitWindowSize(800,800);
    glutInitWindowPosition(100,100);
    glutCreateWindow("VC 2008 Glut");
    //glutFullScreen();
    glShadeModel(GL_FLAT);
    glutKeyboardFunc(keypress);
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}





Thank you for reading, any answer would be appreciated.

推荐答案


for(meshcount=0;meshcount<model->nmeshes;meshcount++)
{
    face=mesh[meshcount]->faces;
    Lib3dsVector* vertex_normal=new Lib3dsVector[mesh[meshcount]->nfaces*3];
    lib3ds_mesh_calculate_vertex_normals(mesh[meshcount],vertex_normal);
    for(long i=0;i<mesh[meshcount]->nfaces;i++)
    {
        glMaterialfv(GL_FRONT,GL_DIFFUSE,material[face[i].material]->diffuse);
        glMaterialfv(GL_FRONT,GL_AMBIENT,material[face[i].material]->ambient);
        glMaterialfv(GL_FRONT,GL_SPECULAR,material[face[i].material]->specular);
        glBegin(GL_TRIANGLES);
        glNormal3fv(vertex_normal[i*3]);
        glVertex3fv(mesh[meshcount]->vertices[face[i].index[0]]);
        glNormal3fv(vertex_normal[i*3+1]);
        glVertex3fv(mesh[meshcount]->vertices[face[i].index[1]]);
        glNormal3fv(vertex_normal[i*3+2]);
        glVertex3fv(mesh[meshcount]->vertices[face[i].index[2]]);
        glEnd();
    }
}


这是我修改后的源代码.因为您可以看到lib3ds_mesh_calculate_vertex_normals用于顶点,而lib3ds_mesh_calculate_face_normals用于脸.


here is my modified source code.as u can see lib3ds_mesh_calculate_vertex_normals for vertex and lib3ds_mesh_calculate_face_normals for face.


这篇关于新手的问题是在OpenGL程序中使用lib3ds.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 20:30