使用OpenGL绘制随机点/星星?

时间:2018-08-15 03:19:45

标签: c++ c opengl glut

我试图绘制一些随机点作为窗口中的星星, 但分数没有显示。但是其他对象显示正确。

我的源代码:

#include<windows.h>
#include <GL\glut.h>
#include <math.h>      // For math routines (such as sqrt & trig).
GLfloat xRotated, yRotated, zRotated;
GLdouble  radius=3;

GLfloat qaBlack[] = {0.0, 0.0, 0.0, 1.0}; //Black Color
GLfloat qaGreen[] = {0.0, 1.0, 0.0, 1.0}; //Green Color
GLfloat qaWhite[] = {1.0, 1.0, 1.0, 1.0}; //White Color
GLfloat qaRed[] = {1.0, 0.0, 0.0, 1.0}; //Red Color

// Set lighting intensity and color

GLfloat qaSpecularLight[]    = {1.0, 1.0, 1.0, 1.0};
GLfloat emitLight[] = {0.9, 0.9, 0.9, 0.9};
GLfloat Noemit[] = {0.0, 0.0, 0.0, 1.0};

// Light source position

GLfloat qaLightPosition[] = {1, 1, 1, 1};

void display(void);
void reshape(int x, int y);

void idleFunc(void)
{
    if ( zRotated > 360.0 ) {
        zRotated -= 360.0*floor(zRotated/360.0);   // Don't allow overflow
      }

    if ( yRotated > 360.0 ) {
        yRotated -= 360.0*floor(yRotated/360.0);   // Don't allow overflow
      }
    zRotated += 0.05;
    yRotated +=0.01;

    display();
}

void initLighting()
{

    // Enable lighting
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    glLightfv(GL_LIGHT0, GL_SPECULAR, qaSpecularLight);

}




void display(void){






    glMatrixMode(GL_MODELVIEW);
    // clear the drawing buffer.
     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    // clear the identity matrix.
    glLoadIdentity();



    glTranslatef(0.0,0.0,-40.0);

    glPushMatrix();

    glutSolidSphere(radius,25,25);

    glPopMatrix();



    glPopMatrix();


    glPushMatrix();

    glRotatef(yRotated,0.0,2.0,0.0);
    glTranslatef(5.0,0.0,0.0);

    // Set the light position
    glLightfv(GL_LIGHT0, GL_POSITION, qaLightPosition);
    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emitLight);   // Make sphere glow (emissive)
    glutSolidSphere(radius/6,25,25);
    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Noemit);

    glPopMatrix();

    glTranslatef(0.0,0.0,0.0);


    glPushMatrix();

    glColor3f(1.0, 1.0, 1.0);
    glPointSize(3);
    for(int i=1;i<100;i++){
         int x = rand()%640 ;
       int  y = rand()%480;
        glBegin(GL_POINTS);
        glVertex2i (x,y);
    glEnd();
    }

    glPopMatrix();

    glLoadIdentity();

    glColor3f(1.0, 1.0, 1.0);
    glPointSize(3);
    for(int i=1;i<100;i++){
int          x = rand()%640 ;
    int     y = rand()%480;
        glBegin(GL_POINTS);
        glVertex2i (x,y);
    glEnd();
    }


    glFlush(); //FOR RENDERING
    glutSwapBuffers();
}

void reshape(int x, int y){
    if(y == 0 || x == 0) return;
    glMatrixMode(GL_PROJECTION);

    gluPerspective(20.0,(GLdouble)x/(GLdouble)y,0.6,40.0);
    glMatrixMode(GL_MODELVIEW);
    glViewport(0,0,x,y);  //Use the whole window for rendering
}


int main (int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutInitWindowSize(1000,600);
    glutCreateWindow("Project_KD");
    initLighting();

    xRotated = yRotated = zRotated = 0.0;

    glutIdleFunc(idleFunc);
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}

1 个答案:

答案 0 :(得分:6)

很多清醒

  • 未匹配的glPushMatrix()/ glPopMatrix()调用的实例;避免矩阵堆栈上溢/下溢;我喜欢使用额外的范围来直观地指示矩阵堆栈嵌套。
  • 您的点图假设一个正投影,而您只设置了一个透视图。
  • 在尝试绘制点时,您启用了照明功能,导致除左下角以外的所有地方都有非常暗的点。
  • 您的点绘制循环由于某种原因被复制;如果您想将星星加倍,请调整for循环的最终值,而不是复制粘贴循环。
  • 您应该在空闲回调中使用glutPostRedisplay(),而不是直接调用display()
  • 每次通过display()设置投影/模型视图矩阵,而不是在调整大小回调中进行设置;有助于减少神秘的矩阵错误。默认的大小调整回调为您调用glViewport(),因此您不必担心这样做。
  • 您是在3D球面之后绘制点(“星”?);我认为这样做的目的是在它们之前绘制它们,以便它们位于“下面”。
  • 邪恶的代码格式混搭;建议使用类似clang-format之类的内容以保持检查状态。
  • 如果您在Windows上使用FreeGLUT(应该是,这实际上是剩下的唯一维护的GLUT实现),则不需要#include <Windows.h>
  • 建议使用计时器回调而不是空闲回调来更新模拟/动画。如果没有vsync,空闲回调通常会被令人难以置信调用。通过计时器回调,您可以模拟vsync系统将为您提供的甚至约16毫秒的帧。

一起:

screen capture

#include <GL/glut.h>
#include <cmath>

GLfloat xRotated, yRotated, zRotated;
GLdouble radius = 3;

void timer( int value )
{
    if( zRotated > 360.0 )
    {
        zRotated -= 360.0 * floor( zRotated / 360.0 ); // Don't allow overflow
    }

    if( yRotated > 360.0 )
    {
        yRotated -= 360.0 * floor( yRotated / 360.0 ); // Don't allow overflow
    }

    zRotated += 5.0;
    yRotated += 1.0;

    glutTimerFunc( 16, timer, 0 );
    glutPostRedisplay();
}

void display()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glDepthMask( GL_FALSE );
    glDisable( GL_DEPTH_TEST );
    glDisable( GL_LIGHTING );

    // 2D rendering
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( 0, 640, 0, 480, -1, 1 );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glPushMatrix();
    {
        glColor3f( 1.0, 1.0, 1.0 );
        glPointSize( 3 );
        glBegin( GL_POINTS );
        for( int i = 1; i < 100; i++ )
        {
            int x = rand() % 640;
            int y = rand() % 480;
            glVertex2i( x, y );
        }
        glEnd();
    }
    glPopMatrix();


    glDepthMask( GL_TRUE );
    glEnable( GL_DEPTH_TEST );

    // Enable lighting
    glEnable( GL_LIGHTING );
    glEnable( GL_LIGHT0 );
    GLfloat qaSpecularLight[] = {1.0, 1.0, 1.0, 1.0};
    glLightfv( GL_LIGHT0, GL_SPECULAR, qaSpecularLight );

    // 3D rendering
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    gluPerspective( 20.0, w / h, 0.1, 80.0 );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( 0.0, 0.0, -40.0 );

    glPushMatrix();
    {
        glutSolidSphere( radius, 25, 25 );
    }
    glPopMatrix();

    glPushMatrix();
    {
        glRotatef( yRotated, 0.0, 2.0, 0.0 );
        glTranslatef( 5.0, 0.0, 0.0 );
        GLfloat qaLightPosition[] = {1, 1, 1, 1};
        glLightfv( GL_LIGHT0, GL_POSITION, qaLightPosition );
        GLfloat emitLight[] = {0.9, 0.9, 0.9, 0.9};
        glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, emitLight ); // Make sphere glow (emissive)
        glutSolidSphere( radius / 6, 25, 25 );
        GLfloat Noemit[] = {0.0, 0.0, 0.0, 1.0};
        glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, Noemit );
    }
    glPopMatrix();

    glutSwapBuffers();
}

int main( int argc, char** argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutInitWindowSize( 1000, 600 );
    glutCreateWindow( "Project_KD" );

    xRotated = yRotated = zRotated = 0.0;

    glutDisplayFunc( display );
    glutTimerFunc( 0, timer, 0 );
    glutMainLoop();
    return 0;
}