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

时间:2011-10-16 16:48:27

标签: 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();
}

1 个答案:

答案 0 :(得分:5)

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


编辑回复评论

Tesselation的

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

+---------------------+
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
+---------------------+

+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+

每片段照明

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

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