gpt4 book ai didi

OpenGL gluLookAt() 未按预期工作

转载 作者:行者123 更新时间:2023-12-04 17:39:27 26 4
gpt4 key购买 nike

我在 OpenGL 的天空盒内制作过山车,并且没有太多关于它的功能或计算机图形的背景知识,这被证明是非常困难的。我使用 Catmull-Rom 样条插值绘制了一个过山车,并使用 glVertex3f 绘制了每个点。现在我想调用update()每 50 毫秒运行一次,以在轨道周围移动相机。 gluLookAt()正在产生奇怪的结果,或者从屏幕上删除轨道,产生黑屏等。我想我需要移动一些矩阵函数,但我不确定将每个矩阵放在哪里。到目前为止,这是我的代码:

int main(int argc, char** argc)
{
// ... load track, etc ...

// Init currpos, nextpos, iter, up
currpos = Vec3f(0, 0, 0);
nextpos = currpos;
iter = 0;
up = Vec3f(0, 1, 0);

deque<Vec3f> points;
Vec3f newpt;

// Loop through the points and interpolate
for (pointVectorIter pv = g_Track.points().begin(); pv != g_Track.points().end(); pv++)
{
Vec3f curr(*pv); // Initialize the current point and a new point (to be drawn)
points.push_back(curr); // Push the current point onto the stack
allpoints.push_back(curr); // Add current point to the total stack

if (points.size() == 4) // Check if there are 4 points in the stack, if so interpolate
{
for (float u = 0.0f; u < 1.0f; u += 0.01f)
{
newpt = interpolate(points[0], points[1], points[2], points[3], u);
glColor3f(1, 1, 1);
glVertex3f(newpt.x(), newpt.y(), newpt.z());

allpoints.push_back(newpt);
}

points.pop_front();
}
}

// glutInit, InitGL(), etc...
}

void InitGL(GLvoid)
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(100.0, (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, .0001, 999999);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
}

void display (void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(currpos.x(), currpos.y(), currpos.z(), nextpos.x(), nextpos.y(), nextpos.z(), up.x(), up.y(), up.z());

glPushMatrix();
glEnable(GL_TEXTURE_2D); // Enable texturing from now on

/* draw skybox, this was from previous assignment and renders correctly */

glPopMatrix();

// now draw rollercoaster ...

glPushMatrix();
glBegin(GL_LINE_STRIP);

deque<Vec3f> points;
Vec3f newpt;

for each (Vec3f pt in allpoints)
{
glColor3f(1, 1, 1);
glVertex3f(pt.x(), pt.y(), pt.z());
}

glutTimerFunc(50, update, 1);
glEnd();
glPopMatrix();

// Swap buffers, so one we just drew is displayed
glutSwapBuffers();
}

void update(int a)
{
if (iter < allpoints.size())
{
currpos = allpoints[iter];
nextpos = allpoints[iter + 1];

gaze = nextpos - currpos;
gaze.Normalize();

Vec3f::Cross3(binorm, gaze, up);
binorm.Normalize();

Vec3f::Cross3(up, binorm, gaze);
up.Normalize();

glutPostRedisplay();
}

iter++;
}

这个想法是我保持一个全局双端队列 allpoints包括样条的控制点和插值点。完成后,我调用 update()每 50 毫秒,沿 allpoints 中的每个点移动相机.在项目的早期版本中,我可以看到过山车被正确绘制。是 gluLookAt()这似乎并不像我想要的那样工作。使用上面的代码,程序开始时相机用过山车的一部分看着天空盒的一侧,然后当 update()被调用,过山车消失了,但相机没有移动。我一直在搞乱我将 OpenGL 矩阵函数放在哪里,并且取决于它们有时在哪里 update()也会导致黑屏。

最佳答案

除了没有glPopMatrix (user971377 已经发现),您调用 glLoadIdentity在您的绘图例程中,这当然会覆盖您对 update 中的模型 View 矩阵所做的任何更改方法(使用 gluLookAt )。

时刻牢记:gluLookAt , glOrtho , gluPerspective , glTranslate , glRotate ,并且所有其他矩阵和变换函数始终在当前选定的矩阵堆栈(由 glPush/PopMatrix 更改)的顶部元素(由 glMatrixMode 更改)上工作。他们总是乘以当前矩阵,而不是替换它。所以喜欢 gluPerspective ,您应该调用glLoadIdentity在调用 gluLookAt 之前.并且整个相机更改应该在渲染例程中完成,而不是更新例程。

而不是在 update 中进行任何 GL 转换您应该更改相机所依赖的变量并在 gluLookAt 中设置相机(模型 View 矩阵上的 display)方法。为了演示这些函数的标准用法,您的代码应类似于:

void display()
{
<general state setup (glClear, ...)>

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLookAt(camera); //view transformation (camera)

//object 1
glPushMatrix(); //save modelview
glTranslate/glRotate/glScale; //local model transformations
<draw object 1>
glPopMatrix();
...
//object n
glPushMatrix(); //save modelview
glTranslate/glRotate/glScale; //local model transformations
<draw object n>
glPopMatrix();

gluSwapBuffers();
}

void update()
{
camera = ...;
}

}

关于OpenGL gluLookAt() 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7729294/

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