如何启用两个对象的不同 GL_POSITION

How to enable different GL_POSITION of two objects

我想创建两个具有不同光照位置的对象。但是即使我设置了不同的位置参数,第二个物体(金色球体)的光线位置始终与第一个物体(银色球体)相同。

我已经一个接一个地启用了两个光源。但是第二个总是和first/above一个一样。

    // light from top right
    GLfloat light_position_top_right[] = { 1.0, 1.0, 1.0, 0.0 };
    // light from bottom left
    GLfloat light_position_bottom_left[] = { -1.0, -1.0, 1.0, 0.0 };

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLightfv(GL_LIGHT0, GL_POSITION, light_position_top_right);
    glLightfv(GL_LIGHT1, GL_POSITION, light_position_bottom_left);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHT1);
    glEnable(GL_DEPTH_TEST);

您可以在 gist 中找到完整的代码。

我希望第二个对象从左下角开始有光照位置。但它从右上角显示为第一个对象。

你的灯光位置的第四个坐标必须是 1.0 而不是 0.0,否则由于投影变换的工作原理,灯光将表现得好像它们在指定方向上无限远。

第四个坐标0.0

第四个坐标1.0:

至于为什么有两个高光而不是一个,你忘了为你的灯设置正确的 glLight* 设置。默认情况下,GL_LIGHT0 以白色漫反射和镜面反射颜色开始,但所有其他灯光默认情况下具有黑色漫反射和镜面反射颜色。


编辑:

如果您希望单独的球体使用单独的灯光,您需要在 init() 期间初始化灯光。但是,与其 glEnable 立即点亮灯光,不如执行以下操作:

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

    glPushMatrix();
    glTranslatef(1.0, 0.0, -1.0);
    glEnable(GL_LIGHT0);
    drawGraySphere();
    glutSolidSphere(0.5, 50, 50);
    glDisable(GL_LIGHT0);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.75, -0.8, 0.0);
    glEnable(GL_LIGHT1);
    drawGoldSphere();
    glutSolidSphere(0.5, 50, 50);
    glDisable(GL_LIGHT1);
    glPopMatrix();

    glFlush();
}

或者,您可以选择仅使用单个光源,并在渲染每个球体之前使用每个帧 glLight* 更改其参数。如果您计划拥有一堆对象,每个对象都有自己的光,这是更好的选择。

这是您的代码,已修改为执行您希望它执行的操作:

#include<windows.h>
#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

void drawGoldSphere() {
    GLfloat mat_specular[] = { 0.628281, 0.555802, 0.366065, 1.0 };
    GLfloat mat_shininess[] = { 51.2 };
    GLfloat mat_ambient[] = { 0.24725, 0.1995, 0.0745, 1.0 };
    GLfloat mat_diffuse[] = { 0.75164, 0.60648, 0.22648, 1.0 };
    //Material Properties
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
}

void drawGraySphere() {
    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat mat_shininess[] = { 50.0 };
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
}

void init(void)
{
    // light from middle left
    //GLfloat light_position[] = { 0.0, 0.0, 0.0, 1.0 };
    // light from top right
    GLfloat light_position_top_right[] = { 1.0, 1.0, 1.0, 0.0 };
    // light from bottom left
    GLfloat light_position_bottom_left[] = { -1.0, -1.0, 1.0, 0.0 };
    // light from bottom left
    //GLfloat light_position[] = { -0.1, -0.1, -0.1, 0.0 };
    // light from middle top
    //GLfloat light_position[] = { 0.0, 1.0, 0.0, 0.0 };
    // light from middle right
    //GLfloat light_position[] = { 1.0, 0.0, 0.0, 0.0 };
    // light from middle middle
    //GLfloat light_position[] = { 0.0, 0.0, 1.0, 0.0 };
    // light from middle bottom
    //GLfloat light_position[] = { 0.0, -1.0, 1.0, 0.0 };


    GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
    GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat high_shininess[] = { 100.0 };

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position_top_right);

    glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT1, GL_POSITION, light_position_bottom_left);

    glEnable(GL_LIGHTING);
    glEnable(GL_DEPTH_TEST);
}

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

    glPushMatrix();
    glTranslatef(1.0, 0.0, -1.0);
    glEnable(GL_LIGHT0);
    drawGraySphere();
    glutSolidSphere(0.5, 50, 50);
    glDisable(GL_LIGHT0);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.75, -0.8, 0.0);
    glEnable(GL_LIGHT1);
    drawGoldSphere();
    glutSolidSphere(0.5, 50, 50);
    glDisable(GL_LIGHT1);
    glPopMatrix();

    glFlush();
}
void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
    glOrtho(-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
    1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
    else
    glOrtho(-1.5*(GLfloat)w/(GLfloat)h,
    1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}

渲染结果: