c – OpenGL评估程序仅部分亮起

我试图使用评估器在C语言中用OpenGL制作一个小型波形发生器.

但是,由于我的评估员只是部分点亮,所以运气不好.

为什么会这样?

下面我为了完整性而包含完整的源代码,你可能只需要查看init(),display()和文件顶部的常量.

#include <gl/glui.h>
#include <math.h>

const int DIMX = 500;
const int DIMY = 500;
const int INITIALPOS_X = 200;
const int INITIALPOS_Y = 200;


// Aspect ratio (calculated on the fly)
float xy_aspect;

// UI aux. matrices
float view_rotate[16] = { 1,1,1 };

float obj_pos[] = { 0.0,0.0,0.0 };
float obj_pan[] = { 0.0,0.0 };

// Referential axis
double axis_radius_begin =  0.2;
double axis_radius_end   =  0.0;
double axis_lenght       = 16.0;
int axis_nslices = 8;
int axis_nstacks = 1;

// Light 0 properties
float light0_position[]  = {5.0,5.0,0.0};
float light0_ambient[] =   {0.0,1.0};
float light0_diffuse[] =   {0.6,0.6,1.0};
float light0_specular[] =  {1.0,1.0,1.0};
float light0_kc = 0.0;
float light0_kl = 1.0;
float light0_kq = 0.0;
double light0x = 5.0;
double light0y = 5.0;
double light0z = 5.0;
double symb_light0_radius = 0.2;
int symb_light0_slices = 8;
int symb_light0_stacks =8;

// Ambient light source properties
float light_ambient[] = {0.5,0.5,1.0}; /* Set the background ambient lighting. */

// Windowing related variables
int main_window;
GLUquadric* glQ;
GLUI  *glui;

const unsigned int gridSize = 40;

float grid[gridSize][gridSize][3];

const int uSize = gridSize;
const int vSize = gridSize;

GLfloat ambient[] = {0.2,0.2,1.0};
GLfloat position[] = {0.0,2.0,1.0};
GLfloat mat_diffuse[] = {0.6,1.0};
GLfloat mat_specular[] = {1.0,1.0};
float mat_shininess[] = {50.0};


void display(void) {
    static float value = 0;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glFrustum( -xy_aspect*.04,xy_aspect*.04,-.04,.04,.1,50.0 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glTranslatef( obj_pos[0],obj_pos[1],-obj_pos[2]-25 );
    glTranslatef( obj_pan[0],obj_pan[1],obj_pan[2] );

    glRotated( 20.0,0.0 );
    glRotated(-45.0,0.0 );

    glMultMatrixf( view_rotate );

    glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);


    glColor3f(1.0,0.0);
    glPushMatrix();
    glRotated(90.0,0.0 );
    gluCylinder(glQ,axis_radius_begin,axis_radius_end,axis_lenght,axis_nslices,axis_nstacks);   
    glPopMatrix();


    glColor3f(0.0,0.0);
    glPushMatrix();
    glRotated(-90.0,1.0);
    glPushMatrix();

    gluCylinder(glQ,axis_nstacks);
    glPopMatrix();


    light0_position[0] = light0x;
    light0_position[1] = light0y;
    light0_position[2] = light0z;

    glLightfv(GL_LIGHT0,GL_POSITION,light0_position);

    glColor3f(1.0,0.0);
    gluQuadricOrientation( glQ,GLU_INSIDE);
    glPushMatrix();
        glTranslated(light0x,light0y,light0z);
        gluSphere(glQ,symb_light0_radius,symb_light0_slices,symb_light0_stacks);
    glPopMatrix();

    gluQuadricOrientation( glQ,GLU_OUTSIDE);

    gluQuadricDrawStyle(glQ,GLU_FILL);
    gluQuadricNormals(glQ,GLU_SMOOTH);
    gluQuadricOrientation(glQ,GLU_OUTSIDE);
    gluQuadricTexture(glQ,GL_FALSE);

    for (unsigned int y = 0; y < vSize; ++y) {
        for (unsigned int x = 0; x < uSize; ++x) {
            float xVal = 5*3.14/gridSize*x;
            float yVal = 5*3.14/gridSize*y;
            grid[y][x][0] = (float) x/gridSize*10.0;
            grid[y][x][1] = sin(xVal + value) + sin(yVal + value);
            grid[y][x][2] = (float) y/gridSize*10.0;
        }
    }

    glMap2f(GL_MAP2_VERTEX_3,3,uSize,uSize * 3,vSize,&grid[0][0][0]);
    glEvalMesh2(GL_FILL,gridSize,gridSize);

    value += 3.14/25;

    if (value > 3.14*2)
        value = 0;
    // swapping the buffers causes the rendering above to be shown
    glutSwapBuffers();
    glFlush();
}


/* Mouse handling */
void processMouse(int button,int state,int x,int y)
{
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {    
    }
    if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
    {   
    }

    glutPostRedisplay();

}

void processMouseMoved(int x,int y)
{

    // pedido de refrescamento da janela
    glutPostRedisplay();                

}

void processPassiveMouseMoved(int x,int y)
{

    // pedido de refrescamento da janela
    glutPostRedisplay();                
}

void reshape(int w,int h)
{
    int tx,ty,tw,th;

    GLUI_Master.get_viewport_area( &tx,&ty,&tw,&th );
    glViewport( tx,th );
    xy_aspect = (float)tw / (float)th;

    glutPostRedisplay();

}


void keyboard(unsigned char key,int y)
{
   switch (key) {
      case 27:      // tecla de escape termina o programa
         exit(0);
         break;
   }
}


void glut_idle( void )
{
  if ( glutGetWindow() != main_window ) 
    glutSetWindow(main_window);  

  glutPostRedisplay();

}

void init()
{
    glQ = gluNewQuadric();

    glFrontFace(GL_CCW);        // Front faces defined using a counterclockwise rotation
    glDepthFunc(GL_LEQUAL);     // Por defeito e GL_LESS
    glEnable(GL_DEPTH_TEST);    // Use a depth (z) buffer to draw only visible objects

    glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);

    // Face Culling para aumentar a velocidade
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);        // GL_FRONT,GL_BACK,GL_FRONT_AND_BACK


    // Define que modelo de iluminacao utilizar; consultar o manual de referencia
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,light_ambient);  // define luz ambiente
    glLightModelf (GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);
    glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER,1);

    // por defeito a cor de fundo e o preto
    // glClearColor(1.0,1.0);    // cor de fundo a branco


    // declaracoes para a fonte luz GL_LIGHT0
    glLightfv(GL_LIGHT0,GL_AMBIENT,light0_ambient);
    glLightfv(GL_LIGHT0,light0_diffuse);
    glLightfv(GL_LIGHT0,light0_specular);
    glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,light0_kc);
    glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,light0_kl);
    glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,light0_kq);

    // NOTA: a direccao e a posicao de GL_LIGHT0 estao na rotina display(),pelo
    //       que as isntrucoes seguntes nao sao necessarias
    //glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,90.0);
    //glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_direction);
    //glLightfv(GL_LIGHT0,light0_position);


    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    glEnable(GL_NORMALIZE); 

    glEnable(GL_MAP2_VERTEX_3);
    glMapGrid2f(gridSize,1.0);


    glShadeModel(GL_SMOOTH);
    glPolygonMode(GL_FRONT,GL_FILL);
    //glPolygonMode(GL_FRONT,GL_LINE);
}

void do_nothing(int key,int y) {}

int main(int argc,char* argv[])
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize (DIMX,DIMY);
    glutInitWindowPosition (INITIALPOS_X,INITIALPOS_Y);
    main_window = glutCreateWindow (argv[0]);

    glutDisplayFunc(display);
    GLUI_Master.set_glutReshapeFunc(reshape);
    GLUI_Master.set_glutKeyboardFunc (keyboard);
    GLUI_Master.set_glutMouseFunc(processMouse);      
    glutMotionFunc(processMouseMoved);
    glutPassiveMotionFunc(processPassiveMouseMoved);
    GLUI_Master.set_glutSpecialFunc( do_nothing );


    /*** Create the bottom subwindow ***/
    glui = GLUI_Master.create_glui_subwindow( main_window,GLUI_SUBWINDOW_BOTTOM );
    glui->set_main_gfx_window( main_window );

    GLUI_Rotation *view_rot = glui->add_rotation( "Rotation",view_rotate );
    view_rot->set_spin( 1.0 );

    glui->add_column( false );
    GLUI_Translation *trans_z = glui->add_translation( "Zoom",GLUI_TRANSLATION_Z,&obj_pos[2] );
    trans_z->set_speed( .1 );

    glui->add_column(false);
    GLUI_Translation *trans_pan = glui->add_translation("Pan",GLUI_TRANSLATION_XY,&obj_pan[0]);
    trans_pan->set_speed(.1);

    GLUI_Master.set_glutIdleFunc( glut_idle );

    init();

    glutMainLoop();

    return 0;
}

解决方法

你说OpenGL评估者不需要设置法线.这只是部分正确.如果通过调用以下方式为评估者启用自动生成的法线,则只需设置法线:

glEnable(GL_AUTO_NORMAL);

只是启用GL_NORMALIZE将不会这样做.

但是,您当然也可以通过为GL_MAP2_NORMAL提供控制点来指定自己的法线,方法与GL_MAP2_VERTEX_3相同.

如果没有提到OpenGL评估员被高度弃用并且最有可能被驱动程序软件实现,答案就不会完整.因此,只需滚动自己的Bezier评估代码(这不是很难)并生成一个绘制为GL_TRIANGLES的简单网格网格肯定会是一个更好的主意.

相关文章

一.C语言中的static关键字 在C语言中,static可以用来修饰局...
浅谈C/C++中的指针和数组(二) 前面已经讨论了指针...
浅谈C/C++中的指针和数组(一)指针是C/C++...
从两个例子分析C语言的声明 在读《C专家编程》一书的第三章时...
C语言文件操作解析(一)在讨论C语言文件操作之前,先了解一下...
C语言文件操作解析(三) 在前面已经讨论了文件打开操作,下面...