如何在opengl中使用聚光灯

时间:2016-05-27 14:33:40

标签: opengl lighting

我正在尝试学习如何在OpenGL中使用聚光灯。我希望从标记为(lighpos)的点(并显示为灰点)照射到3D空间中以(可能)为中心的GLUT茶壶的一侧点亮(火炬)光。我附上了一个例子,我试图这样做,但我无法将光线集中在茶壶上。基于我试图使用的参数,我期待几乎触摸光焦点。

有人可以指出我错过了什么/我做错了吗。

由于

斯图尔特

#include <windows.h>
#include <GL/glut.h>
#include <stdio.h>

GLfloat lighpos[] = { -300., 200., 250., 1.0 }; // Location of light
GLfloat possph[] = { -50., 350., 150. }; // Position of teapot
GLfloat ligdir[] = { 250., 150., -100. }; // Direction from light to teapot

void init(void) {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_DEPTH_TEST);

    glLightfv(GL_LIGHT0, GL_POSITION, lighpos);
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, ligdir);
    glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 10.0);

    GLfloat ambientLight0[] = { 0.25, 0.25, 0.25, 1.0 };
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight0);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight0);

    GLfloat diffuseLight0[] = { 1.0, 1.0, 1.0, 1.0 };
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight0);

    GLfloat specularLight0[] = { 1.0, 1.0, 1.0, 1.0 };
    glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight0);

    glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 128.0f);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
}

void drawAxis() {
    glBegin(GL_LINES);
    glColor3f(1.0, 0.0, 0.0);  glVertex3f(-500., 0.0, 0.0);  glVertex3f(500., 0.0, 0.0);
    glColor3f(0.0, 1.0, 0.0);  glVertex3f(0.0, -500., 0.0);  glVertex3f(0.0, 500., 0.0);
    glColor3f(0.0, 0.0, 1.0);  glVertex3f(0.0, 0.0, -500.);  glVertex3f(0.0, 0.0, 500.);
    glEnd();
}

void display(void) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
    drawAxis();
    glPushMatrix();
    glPointSize(10);
    glColor3f(1.0, 1.0, 1.0);
    glBegin(GL_POINTS);
    glVertex3d(lighpos[0], lighpos[1], lighpos[2]);
    glEnd();
    glPopMatrix();

    glColor3f(1., 0., 0.); 
    glPushMatrix();
    glTranslated(possph[0], possph[1], possph[2]);
    glutSolidTeapot(100.);
    glPopMatrix();
    glutSwapBuffers();
}

void reshape(int w, int h) {
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.0, 1.0, -1.0, 1.0, 4, 3000.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(1500.0, 1500.0, 1500.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}


int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);   
    glutInitWindowPosition(0.0, 0.0);   
    glutInitWindowSize(800, 800);     
    glutCreateWindow("spotlight"); 
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);               
    glutMainLoop();
    return 0;
}

1 个答案:

答案 0 :(得分:0)

固定功能管道照明,这是您在代码中使用的,仅在顶点执行光照计算。如果您的聚光灯仅照亮几个或一个顶点,您将无法获得令人愉悦的聚光灯效果。一种可能的解决方案是高度优化模型的网格。更好,更有效和更优雅的解决方案是使用固定功能管道并实现照明片段着色器,以便为每个像素计算光照。