gpt4 book ai didi

c++ - 使聚光灯静止

转载 作者:太空宇宙 更新时间:2023-11-04 11:43:26 25 4
gpt4 key购买 nike

我正在尝试在我的简单 OpenGL 场景中实现纯固定聚光灯,它不随相机移动。它应该始终突出显示我放置茶壶的场景中心(0,0,0 的坐标)。这是一个简化的代码:

#include <windows.h>
#define GLUT_DISABLE_ATEXIT_HACK
#include <gl/glut.h>
#include <gl/glu.h>
#include <gl/gl.h>
#include <math.h>
#include <iostream>

const int windowWidth = 640;
const int windowHeight = 480;

float alpha=0.0, alphaDelta=0.0, ratio, beta=0.0, betaDelta=0.0;
float x=0.0, y=1.75, z=5.0;
float lx=0.0, ly=0.0, lz=-1.0;
int moveDelta = 0;
float lastMouseX=windowWidth*0.5, lastMouseY=windowHeight*0.5;

void reshape(int w, int h){
//...
}

// handles angle changes
void orientMe(float horizontalAngle, float verticalAngle) {
lx = sin(horizontalAngle);
if(beta > -1.5 && beta < 1.5)
ly = sin(verticalAngle);
lz = -cos(horizontalAngle);
glLoadIdentity();
gluLookAt(x, y, z,
x + lx, y + ly, z + lz,
0.0, 1.0, 0.0);
}

// handles x,y,z coords changes
void flatMovement(int i) {
x = x + i*(lx)*0.1;
z = z + i*(lz)*0.1;
glLoadIdentity();
gluLookAt(x, y, z,
x + lx, y + ly, z + lz,
0.0, 1.0, 0.0);
}

void display() {
// orient observer
if(moveDelta)
flatMovement(moveDelta);

if(alphaDelta || betaDelta) {
alpha += alphaDelta;
alphaDelta = 0;

beta += betaDelta;
betaDelta = 0;

orientMe(alpha, beta);
}

glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3f(0,1,0);
glBegin(GL_QUADS);
glNormal3d(0,1,0);
glVertex3f(-100.0, 0.0, -100.0);
glVertex3f(-100.0, 0.0, 100.0);
glVertex3f(100.0, 0.0, 100.0);
glVertex3f(100.0, 0.0, -100.0);
glEnd();

glColor3f(1,0,0);
glutSolidTeapot(1);

glutSwapBuffers();
}

void pressSpecialKey(int key, int x, int y) {
//...
}

void releaseSpecialKey(int key, int x, int y) {
//...
}

static void idle(void)
{
glutPostRedisplay();
}

void mouseMove(int x, int y) {
//...
}

void setupLights() {
GLfloat spotDirection[] = {0.0f, -1.0f, 0.0f, 1.0f};
GLfloat spotPosition[] = {0.0f, 4.0f, 0.0f, 1.0f};

glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 40);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDirection);
glLightfv(GL_LIGHT0, GL_POSITION, spotPosition);

glEnable(GL_LIGHT0);
}

int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(windowWidth,windowHeight);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

glutCreateWindow("Spotlight");

glutSpecialFunc(pressSpecialKey);
glutSpecialUpFunc(releaseSpecialKey);
glutPassiveMotionFunc(mouseMove);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);

setupLights();

glutMainLoop();

return EXIT_SUCCESS;
}

不幸的是,聚光灯似乎随着相机的变化而变化,我不知道上面的代码有什么问题。


编辑

感谢@genpfault 发布的内容,我已经解决了问题。

答案是在main()函数中只留下glEnable(GL_LIGHT0),将其余负责光照的代码移到最后display() 函数(就在调用 glutSwapBuffers() 之前。

所以最终的简化代码如下所示:

#include <windows.h>
#define GLUT_DISABLE_ATEXIT_HACK
#include <gl/glut.h>
#include <gl/glu.h>
#include <gl/gl.h>
#include <math.h>
#include <iostream>

const int windowWidth = 640;
const int windowHeight = 480;

float alpha=0.0, alphaDelta=0.0, ratio, beta=0.0, betaDelta=0.0;
float x=0.0, y=1.75, z=5.0;
float lx=0.0, ly=0.0, lz=-1.0;
int moveDelta = 0;
float lastMouseX=windowWidth*0.5, lastMouseY=windowHeight*0.5;

void reshape(int w, int h){
//...
}

// handles angle changes
void orientMe(float horizontalAngle, float verticalAngle) {
//...
}

// handles x,y,z coords changes
void flatMovement(int i) {
//...
}

void setupLights() {
//THE CONTENTS SLIGHTLY CHANGED HERE
GLfloat spotPosition[] = {2.0f, 4.0f, 0.0f, 1.0f};
GLfloat spotDirection[] = {0.0f, -1.0f, 0.0f, 1.0f};

glLightfv(GL_LIGHT0, GL_POSITION, spotPos
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 40);ition);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDirection);
}

void display() {
// orient observer
if(moveDelta)
flatMovement(moveDelta);

if(alphaDelta || betaDelta) {
alpha += alphaDelta;
alphaDelta = 0;

beta += betaDelta;
betaDelta = 0;

orientMe(alpha, beta);
}

glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3f(0,1,0);
glBegin(GL_QUADS);
glNormal3d(0,1,0);
glVertex3f(-100.0, 0.0, -100.0);
glVertex3f(-100.0, 0.0, 100.0);
glVertex3f(100.0, 0.0, 100.0);
glVertex3f(100.0, 0.0, -100.0);
glEnd();

glColor3f(1,0,0);
glutSolidTeapot(1);

setupLights(); // PUT THE LIGHTING SETUP AT THE END OF DISPLAY()

glutSwapBuffers();
}

void pressSpecialKey(int key, int x, int y) {
//...
}

void releaseSpecialKey(int key, int x, int y) {
//...
}

static void idle(void)
{
glutPostRedisplay();
}

void mouseMove(int x, int y) {
//...
}

int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(windowWidth,windowHeight);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

glutCreateWindow("Spotlight");

glutSpecialFunc(pressSpecialKey);
glutSpecialUpFunc(releaseSpecialKey);
glutPassiveMotionFunc(mouseMove);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);

glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);

glEnable(GL_LIGHT0); // IN THE MAIN, LEAVE ONLY THE ENABLING CALL

glutMainLoop();

return EXIT_SUCCESS;
}

最佳答案

在设置相机变换后设置光照位置:

void display() 
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// orient observer
if(moveDelta)
flatMovement(moveDelta);

if(alphaDelta || betaDelta)
{
alpha += alphaDelta;
alphaDelta = 0;

beta += betaDelta;
betaDelta = 0;

orientMe(alpha, beta);
}

setupLights();

glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3f(0,1,0);
glBegin(GL_QUADS);
glNormal3d(0,1,0);
glVertex3f(-100.0, 0.0, -100.0);
glVertex3f(-100.0, 0.0, 100.0);
glVertex3f(100.0, 0.0, 100.0);
glVertex3f(100.0, 0.0, -100.0);
glEnd();

glColor3f(1,0,0);
glutSolidTeapot(1);

glutSwapBuffers();
}

参见 here .您现有的代码遵循“将光源与您的视点一起移动”调用序列。

关于c++ - 使聚光灯静止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20547604/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com