如何启用两个对象的不同 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;
}
渲染结果:
我想创建两个具有不同光照位置的对象。但是即使我设置了不同的位置参数,第二个物体(金色球体)的光线位置始终与第一个物体(银色球体)相同。
我已经一个接一个地启用了两个光源。但是第二个总是和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;
}
渲染结果: