如何在 OpenGL 中更新"forward"运动
How to update the "forward" movement in OpenGL
我的OpenGL应用程序有问题,您可以在这张gif图中清楚地看到。基本上,我想沿着光标指向的方向移动,但这并没有发生,相反,"向前"的方向保持不变。
例如,如果我转过180°并按"w"向前走,我会向后走。我之所以说走路,是因为我试图复制第一人称相机,就像在FPS游戏中一样。
在这里你可以看到我迄今为止写的代码:
#include <GLglew.h>
#include <GLfreeglut.h>
#include <iostream>
#include <cstdlib>
#include "imageLoader.h"
using namespace std;
float _angleY = 0.0f;
float _angleX = 0.0f;
bool about_y = true;
float oldMouseX;
float oldMouseY;
int valid = 0;
float posX = 0.0;
float posZ = 0.0;
// actual vector representing the camera's direction
float lx = 0.0f, lz = -1.0f;
// XZ position of the camera
float x = 0.0f, z = 5.0f;
// the key states. These variables will be zero
// when no key is being presses
float deltaAngle = 0.0f;
float deltaMove = 0;
int xOrigin = -1;
// angle of rotation for the camera direction
float angle = 0.0f;
void mouseMove(int x, int y) {
// this will only be true when the left button is down
if (xOrigin >= 0) {
// update deltaAngle
deltaAngle = (x - xOrigin) * 0.001f;
// update camera's direction
lx = sin(angle + deltaAngle)*2;
lz = -cos(angle + deltaAngle)*2;
}
}
void mouseButton(int button, int state, int x, int y) {
// only start motion if the left button is pressed
if (button == GLUT_LEFT_BUTTON) {
// when the button is released
if (state == GLUT_UP) {
angle += deltaAngle;
xOrigin = -1;
}
else {// state = GLUT_DOWN
xOrigin = x;
}
}
}
void handleKeys(unsigned char key, int x, int y){
switch (key)
{
case 'w':
posZ+=4;
cout << "FORWARDn";
break;
case 's':
posZ-=4;
cout << "BACKn";
break;
case 'd':
posX-=4;
cout << "RIGHTn";
break;
case 'a':
posX+=4;
cout << "LEFTn";
break;
case 27:
exit(0);
break;
}
}
//initializes 3d rendering
void initRendering(){
glEnable(GL_DEPTH_TEST); //permits one object to show up behind another one
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING); //enables the lighting function
glEnable(GL_LIGHT0); //enables light num. 1
glEnable(GL_LIGHT1); //enables light num. 2
glEnable(GL_NORMALIZE);
Image* image = loadBMP("bricks.bmp");
_textureId = loadTexture(image);
delete image;
}
//handles the resize of the window
void handleResize(int w, int h){
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, double(w) / double(h), 1.0, 800.0);
}
void computePos(float deltaMove) {
x += deltaMove * lx * 0.1f;
z += deltaMove * lz * 0.1f;
}
//draws the 3D sccene
void drawScene(){
cout << "ANGLE: "<<angle<<"n";
if (deltaMove){
computePos(deltaMove);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set the camera
gluLookAt(x, 1.0f, z,
x + lx, 1.0f, z + lz,
0.0f, 1.0f, 0.0f);
glTranslatef(posX, 0.0f, posZ);
//HERE WE ADD THE AMBIENT LIGHT
GLfloat ambientColor[] = { 0.3f, 0.3f, 0.3f, 1.0f }; //the first 3 floats represent the //RGB intensity of the light
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);
//HERE WE ADD THE POSITIONED LIGHT (WHITE INTENSE)
GLfloat lightColor0[] = { 0.5f, 0.5f, 0.5f, 1.0f }; //LIGHT0 color
GLfloat lightPos0[] = { 4.0f, 0.0f, 8.0f, 1.0f }; //LIGHT0 position is (4,0,8)
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0); //sets color/intensity of the light
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightPos0); //sets position of the light
//HERE WE ADD THE DIRECTIONAL LIGHT (RED)
GLfloat lightColor1[] = { 0.5f, 0.2f, 0.2f, 1.0f }; //LIGHT1 color
GLfloat lightPos1[] = { -1.0f, 0.5f, 0.5f, 0.0f }; //LIGHT1 is coming from (-1,0.5,0.5)
//NOTE: we just have to put the 4th
//parameter to 0.0f to make it directional
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1); //sets color/intensity of the light
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightPos1); //sets position of the light
glColor3f(1.0f, 1.0f, 0.0f); //we set the cube color
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//HERE WE DEFINE COORDINATES FOR THE CUBE
glBegin(GL_QUADS);
//Front
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-40.5f, -40.0f, 40.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(40.5f, -40.0f, 40.5f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(40.5f, 40.0f, 40.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-40.5f, 40.0f, 40.5f);
//Right
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(40.5f, -40.0f, -80.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(40.5f, 40.0f, -80.5f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(40.5f, 40.0f, 40.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(40.5f, -40.0f, 40.5f);
//Back
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-40.5f, -40.0f, -80.5f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-40.5f, 40.0f, -80.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(40.5f, 40.0f, -80.5f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(40.5f, -40.0f, -80.5f);
//Left
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-40.5f, -40.0f, -80.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-40.5f, -40.0f, 40.5f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-40.5f, 40.0f, 40.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-40.5f, 40.0f, -80.5f);
glEnd();
glutSwapBuffers();
}
//main loop of the program
void update(int value){
glutPostRedisplay();
glutTimerFunc(25, update, 0);
}
您应该创建direction
的向量。每次移动鼠标时,都应该根据角度对其进行重新评估。方向矢量应该是单位圆上的矢量。
假设你有方向向量direction = (0.4X, 0.6Z)
(例如,数字可以是不真实的,但让它是真实的),那么为了向前移动,你应该把它乘以velocity = 4
的标量,所以向量velocity = (1.6X, 2.4Z)
。意思是posX += 1.6, posZ += 2.4;
如果需要向右旋转,将其旋转90度并乘以速度标量。
若要旋转方向矢量,可以使用函数的sin
和cos
,因为它是单位圆上的位置。
要向后和向左移动,可以使用负速度。
相关文章:
- 完美前进使用 std::forward vs RefRefCast
- 粒子系统:所有粒子都朝同一方向运动
- 你如何理解"std: :forward is just syntactic sugar"?这是真的吗?
- "std::forward"和"std::move"真的不生成代码吗?
- 在C++中使用 std::forward 的多个参数
- 如何使用 std::forward 精确地评估参数包的扩展?
- 如何组合许多连续的图像来模拟逼真的运动模糊?
- 太空入侵者 – 2D 矢量运动算法
- 普通的右值引用和 std::forward 返回的引用有什么区别?
- 在虚幻引擎中使用运动控制器组件,C++而不是蓝图
- OpenCV的卡尔曼滤波器过渡矩阵如何处理时间(如t和t^2)进行运动预测?
- 怎么可能写 f( *this, std::forward<Args>(args)... ) 而 f 只用 F f 声明;
- 如何通过通用引用或std::forward将这三个c++模板函数合并为一个
- C++模块(MSVC)中的visual Forward声明
- 如何使用OpenCV作为运动检测器(而不是寻找视频输出)
- 一维阵列的运动检测(神经网络或其他选项?
- 使用带有 PIR 传感器的米利斯检测连续运动
- 自 C++11 年以来对 std::forward 实施的理解
- 在 GTKMM 中捕捉鼠标运动
- 如何在 OpenGL 中更新"forward"运动