gpt4 book ai didi

c++ - 转动相机后,形状倾斜 OpenGL

转载 作者:行者123 更新时间:2023-11-30 04:45:48 27 4
gpt4 key购买 nike

在Y轴和X轴上的相机旋转以及随后的移动之后,是一个奇怪的相机沿Z轴的旋转。
例如,这里是正常状态All ok

但我在舞台上随意移动,全都扭曲了Curvature

我不知道该怎么做以及如何解决这个问题,我希望得到你的帮助。
我看到这个问题,它对我没有帮助,因为我什至不使用glm , 不要标记为重复。

代码:

#include <iostream>
#include <chrono>
#include <GL/glut.h>
#include "Camera.h"

using namespace std;

constexpr auto FPS_RATE = 120;
int windowHeight = 600, windowWidth = 600, windowDepth = 600;
float angle = 0, speedRatio = 0.25;
struct MyPoint3f
{
float x;
float y;
float z;
};
MyPoint3f lastMousePos = { };
bool mouseButtonWasPressed = false;
float mouseSensitivity = 0.1;
float camMoveSpeed = 3;
float camPitchAngle = 0, camYawAngle = 0;
Camera cam;

void init();
void displayFunction();
void idleFunction();
void reshapeFunction(int, int);
void keyboardFunction(unsigned char, int, int);
void specialKeysFunction(int, int, int);
void mouseFunc(int, int, int, int);
void motionFunction(int, int);
double getTime();

double getTime()
{
using Duration = std::chrono::duration<double>;
return std::chrono::duration_cast<Duration>(
std::chrono::high_resolution_clock::now().time_since_epoch()
).count();
}

const double frame_delay = 1.0 / FPS_RATE;
double last_render = 0;

void init()
{
glutDisplayFunc(displayFunction);
glutIdleFunc(idleFunction);
glutReshapeFunc(reshapeFunction);
glutKeyboardFunc(keyboardFunction);
glutMouseFunc(mouseFunc);
glutMotionFunc(motionFunction);
glViewport(0, 0, windowWidth, windowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-windowWidth / 2, windowWidth / 2, -windowHeight / 2, windowHeight / 2, -windowDepth / 2, windowDepth / 2);
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
cam.setShape(45, (double)windowWidth / windowHeight, 0.1, 1000);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
cam.set(Point3(0, 0, 350), Point3(0, 0, 349), Vector3(0, 1, 0));
}

void displayFunction()
{
angle += speedRatio;
if (angle >= 360 || angle <= -360) angle = 0;
if (camPitchAngle <= -360) camPitchAngle = 0;
if (camPitchAngle >= 360) camPitchAngle = 0;
if (camYawAngle <= -360) camYawAngle = 0;
if (camYawAngle >= 360) camYawAngle = 0;
cout << camPitchAngle << " " << camYawAngle << endl;
cam.pitch(-(camPitchAngle *= mouseSensitivity));
cam.yaw(-(camYawAngle *= mouseSensitivity));
camPitchAngle = 0; camYawAngle = 0;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

glPushMatrix();

glRotatef(angle, 1, 0, 0);
glRotatef(angle, 0, 1, 0);

glColor3f(0, 1, 0);
glutWireCube(150.0);

glBegin(GL_LINES);
glColor3f(1, 0, 0);
for (int i = 0; i <= 75; i += 5)
{
glVertex3i(i, 0, 0);
glVertex3i(-i, 0, 0);
glVertex3i(0, i, 0);
glVertex3i(0, -i, 0);
glVertex3i(0, 0, i);
glVertex3i(0, 0, -i);
}
glEnd();
glPopMatrix();

//RSHIFT and CTRL
if (GetAsyncKeyState(VK_LSHIFT))
{
cam.slide(0, 1.0 * camMoveSpeed, 0);
}
if (GetAsyncKeyState(VK_LCONTROL))
{
cam.slide(0, -1.0 * camMoveSpeed, 0);
}

glutSwapBuffers();
}

void idleFunction()
{
const double current_time = getTime();
if ((current_time - last_render) > frame_delay)
{
last_render = current_time;
glutPostRedisplay();
}
}

void reshapeFunction(int w, int h)
{

}

void keyboardFunction(unsigned char key, int w, int h)
{
switch (key)
{
case '+': case '=':
speedRatio += 0.125;
break;
case '-': case '_':
speedRatio -= 0.125;
break;
case 'A': case 'a':
cam.slide(-1.0 * camMoveSpeed, 0, 0);
break;
case 'D': case 'd':
cam.slide(1.0 * camMoveSpeed, 0, 0);
break;
case 'W': case 'w':
cam.slide(0, 0, -1.0 * camMoveSpeed);
break;
case 'S': case 's':
cam.slide(0, 0, 1.0 * camMoveSpeed);
break;
case 'Z': case 'z':
cam.yaw(-1);
break;
case 'X': case 'x':
cam.yaw(1);
break;
case 27:
angle = 0;
speedRatio = 0;
cam.set(Point3(0, 0, 350), Point3(0, 0, 349), Vector3(0, 1, 0));
break;
default:
cout << key << endl;
break;
}
}

void specialKeysFunction(int key, int x, int y)
{
cout << key << endl;
}

void mouseFunc(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
mouseButtonWasPressed = true;
lastMousePos.x = x;
lastMousePos.y = y;
}
}

void motionFunction(int mousePosX, int mousePosY)
{
if (mousePosX >= 0 && mousePosX < windowWidth && mousePosY >= 0 && mousePosY < windowHeight)
{
if (mouseButtonWasPressed)
{
camPitchAngle += -mousePosY + lastMousePos.y;
camYawAngle += mousePosX - lastMousePos.x;
lastMousePos.x = mousePosX;
lastMousePos.y = mousePosY;
}
}
}

int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition((GetSystemMetrics(SM_CXSCREEN) - windowWidth) / 2, (GetSystemMetrics(SM_CYSCREEN) - windowHeight) / 2);
glutCreateWindow("Window");
init();
glutMainLoop();
return 0;
}

Camera.h Camera.cpp

最佳答案

当你做的时候

glRotatef(angle, 1, 0, 0);
glRotatef(angle, 0, 1, 0);

然后模型绕y轴旋转然后旋转后的模型绕x轴旋转,因为glRotatef设置一个旋转矩阵并将其与当前矩阵相乘。
因为模型在绕 x 轴旋转之前绕 y 轴旋转,所以( View 空间)y 轴保持在 View 空间的 yz 平面。

如果你想保持 x 轴在 View 空间的 xz 平面内,你必须先绕 x 轴旋转:

glRotatef(angle, 0, 1, 0);
glRotatef(angle, 1, 0, 0);


当您将 pich()yaw() 应用于相机对象时,会出现同样的问题。如果您切换它(先是 yaw(),然后是 pitch()),那么这不会解决问题,因为俯仰和偏航会随着每次鼠标移动而递增应用( pich(), yaw(), pich(), yaw(), pich() , 偏航() ...)。所以在 pitch() 之后总是有一个 yaw() 并且模型会倾斜。

要解决此问题,您必须总结 camPitchAnglecamYawAngle。考虑鼠标强度:

void motionFunction(int mousePosX, int mousePosY)
{
if (mousePosX >= 0 && mousePosX < windowWidth && mousePosY >= 0 && mousePosY < windowHeight)
{
if (mouseButtonWasPressed)
{
camPitchAngle += (-mousePosY + lastMousePos.y) * mouseSensitivity;
camYawAngle += (mousePosX - lastMousePos.x) * mouseSensitivity;
lastMousePos.x = mousePosX;
lastMousePos.y = mousePosY;
}
}
}

displayFunction 中复制相机对象 (cam/curr_cam) 并应用 camPitchAnglecamYawAngle 到拷贝。使用拷贝设置 View 和投影矩阵:

void displayFunction()
{
// [...]

// cam.pitch(-(camPitchAngle *= mouseSensitivity)); <--- delete
// cam.yaw(-(camYawAngle *= mouseSensitivity)); <--- delete

// [...]

Camera curr_cam = cam;
curr_cam.yaw( -camYawAngle );
curr_cam.pitch( -camPitchAngle );

// [...]

if (GetAsyncKeyState(VK_LSHIFT))
{
curr_cam.slide(0, 1.0 * camMoveSpeed, 0);
}
if (GetAsyncKeyState(VK_LCONTROL))
{
curr_cam.slide(0, -1.0 * camMoveSpeed, 0);
}

// [...]
}

当然你要分别设置camYawAngle = 0 camPitchAngle = 0;z, xESC 被按下。

关于c++ - 转动相机后,形状倾斜 OpenGL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57071832/

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