OpenGL - 用锥形聚光灯创建平面

ant*_*ngl 1 c opengl

我在创建一个矩形表面时遇到了麻烦,该表面上有一个锥形聚光灯.到目前为止,我已经尝试创建一个2D立方体表面(glutSolidCube())并用于GL_SPOT_XXX创建聚光灯.但是我不是出于什么原因,光线只是在整个表面散射而不是聚集成一个点.

所以这是我的代码到目前为止,你可以专注于init_light()display()函数.如果你需要:)其他功能供你参考

void rotateCamera()
{
    /* Rotate camera 2 degrees about selected axis */
    theta[axis] += dtheta;
    if (theta[axis] > 360.0 ) theta[axis] -= 360.0;
    glutPostRedisplay();
}

void computeCameraPosition() {
    GLdouble M[16];

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glTranslatef(centroid[0], centroid[1], centroid[2]);
    glRotatef(theta[0], 1.0, 0.0, 0.0);
    glRotatef(theta[1], 0.0, 1.0, 0.0);
    glRotatef(theta[2], 0.0, 0.0, 1.0);
    glTranslatef(-centroid[0], -centroid[1], -centroid[2]);
    glGetDoublev(GL_MODELVIEW_MATRIX, M);

    GLdouble newvec[16];

    glMultMatrixd(init_vec);
    glGetDoublev(GL_MODELVIEW_MATRIX, newvec);
    glPopMatrix();

    /* the 1st and 2nd columns are the eye position and new y-axis direction */
    memcpy(eye, newvec, sizeof(GLdouble)*4);
    memcpy(yaxis, newvec+4, sizeof(GLdouble)*4);
}

void init_light()
{
    GLfloat spot_direction[] = { 1.0, 1.0, 0.0 };
    glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction );
    glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, 2.0 );
    glLightf( GL_LIGHT0, GL_SPOT_CUTOFF, 45.0 );

    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL);
}


void display() {
    computeCameraPosition();
    glClearColor(0.9, 0.9, 0.9, 1.0);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(eye[0], eye[1], eye[2], 
          centroid[0], centroid[1], centroid[2], 
          yaxis[0], yaxis[1], yaxis[2]); 
    glutSolidCube(2.0);
    glFlush();
    glutSwapBuffers();
}

int main(int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(800, 800);
    glutInitWindowPosition (200, 100);
    glutCreateWindow("Scene Editor");
    init_light();
    glutDisplayFunc(display);
    glutMainLoop();
}
Run Code Online (Sandbox Code Playgroud)

dat*_*olf 5

标准固定功能OpenGL照明仅在顶点位置和在基元上插入的确定颜色进行评估.因此,要获得聚光效果,必须以高分辨率评估照明.您可以通过测试平面或使用每个片段光照的片段着色器来实现此目的.


编辑回答评论

镶嵌

Tesselation意味着将您的飞机细分为大量"补丁".像这样:

+---------------------+
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
+---------------------+
Run Code Online (Sandbox Code Playgroud)

+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
Run Code Online (Sandbox Code Playgroud)

每片段照明

每个片段照明意味着在每个光栅化片段处评估照明方程(片段通常是指像素).为此,使用片段着色器,即对图形处理器(GPU)的小程序加载,其针对光栅化基元(三角形,线,点)的每个片段/像素执行.

Lighthouse3D有一个关于它的教程:http://www.lighthouse3d.com/tutorials/glsl-tutorial/spot-light-per-pixel/我建议你在那里阅读完整的GLSL教程,以了解发生了什么.