2011-11-17 73 views
4

我想用C++在OpenGL中使用评估器制作一个小波发生器。OpenGL评估器只能部分点亮

enter image description here

不过,我已经没有多少运气,因为我的评估只得到部分点亮。

为什么会出现这种情况?

为了完整起见,下面我包含了完整的源代码,你可能只需要看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,0,0,0, 
          0,1,0,0, 
          0,0,1,0, 
          0,0,0,1 }; 

float obj_pos[] = { 0.0, 0.0, 0.0 }; 
float obj_pan[] = { 0.0, 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, 5.0, 0.0}; 
float light0_ambient[] = {0.0, 0.0, 0.0, 1.0}; 
float light0_diffuse[] = {0.6, 0.6, 0.6, 1.0}; 
float light0_specular[] = {1.0, 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, 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, 0.2, 1.0}; 
GLfloat position[] = {0.0, 0.0, 2.0, 1.0}; 
GLfloat mat_diffuse[] = {0.6, 0.6, 0.6, 1.0}; 
GLfloat mat_specular[] = {1.0, 1.0, 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, 1.0,0.0,0.0); 
    glRotated(-45.0, 0.0,1.0,0.0); 

    glMultMatrixf(view_rotate); 

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


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


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


    glColor3f(0.0,0.0,1.0); 
    glPushMatrix(); 

    gluCylinder(glQ, axis_radius_begin, axis_radius_end, 
        axis_lenght, axis_nslices, 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,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, 0, 1 , 3, uSize, 0, 1, uSize * 3, vSize, &grid[0][0][0]); 
    glEvalMesh2(GL_FILL, 0, gridSize, 0, 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, ty, tw, th); 
    xy_aspect = (float)tw/(float)th; 

    glutPostRedisplay(); 

} 


void keyboard(unsigned char key, int x, 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,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, GL_DIFFUSE, light0_diffuse); 
    glLightfv(GL_LIGHT0, GL_SPECULAR, 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, GL_POSITION, light0_position); 


    glEnable(GL_LIGHTING); 
    glEnable(GL_LIGHT0); 

    glEnable(GL_NORMALIZE); 

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


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

void do_nothing(int key, int x, 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; 
} 
+2

您是否计算过并设置了法线(代码太长,无法读取) – Shahbaz

+0

评估者不需要设置法线。 –

+0

只是一个小问题,但OpenGL评估者自OpenGL 3.0以来已弃用,因此它可能是一个驱动程序错误。尝试运行[demo](http://www.opengl.org/resources/code/samples/mjktips/grid/index.html)程序并查看它是否有效。另外,您可能想考虑使用另一种使用顶点着色器的方法。 – bernie

回答

2

你说OpenGL评估器不需要法线设置。这只是部分正确。你不仅不需要设置法线,如果你通过调用启用评估自动生成法线:

glEnable(GL_AUTO_NORMAL); 

只是使GL_NORMALIZE不会去做。

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

如果没有提到OpenGL评估者被高度弃用并且很可能在驱动程序的softare中实现,答案将不会完整。所以只需要滚动你自己的Bezier评估代码(这不是非常困难),并生成一个简单的网格,如GL_TRIANGLES,肯定是一个更好的主意。

+0

这没有用。照明仍然和我的问题一样。不过,绘制“GL_POLYGONS”网格产生了预期的结果。 –

+0

@FranciscoP。因此,考虑到没有人真正使用评估人员,这可能是一个驱动因素问题。顺便说一句,不要诚实地画出GL_POLYGONS。 –

+0

示例(http://www.opengl.org/resources/code/samples/mjktips/grid/index.html)正常工作。这是困扰我的东西。 –