OpenGL evaluator only partially burns

I tried to create a small wave generator in OpenGL with C ++ using an evaluator.

enter image description here

However, I was not very lucky, as my evaluator only partially lights up.

Why is this happening?

Below I include the complete source code for completeness, you will probably only need to look for init() , display() and the constants at the top of the file.

 #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 eo 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 ea 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; } 
+4
source share
1 answer

You say that OpenGL evaluators don't need normals to install. This is partly true. You do not need to set normals if you include automatically generated normals for evaluators by calling:

 glEnable(GL_AUTO_NORMAL); 

Just enable GL_NORMALIZE will not.

But you can, of course, also specify your own normals by providing breakpoints for GL_MAP2_NORMAL in the same way as for GL_MAP2_VERTEX_3 .

And the answer would not be complete without mentioning that OpenGL evaluators are very outdated and most likely implemented in softare driver. So just flip your own Bezier evaluation code (which is not very difficult) and create a simple grid grid drawn as GL_TRIANGLES will undoubtedly be a better idea.

+2
source

Source: https://habr.com/ru/post/1381816/


All Articles