LWJGL - 旋转和移动 = 问题
LWJGL - Rotation and movement = problems
长话短说,我正在制作一个 LWJGL 引擎,并且正在绘制一个基本的 QUAD。当我绘制这个 QUAD 并使用键盘侦听器时,它移动得很完美,up/down/left/right。
然而,当我平移和旋转时,它也绕着它的中心点旋转就好了,同时使用它们,然后你就有问题了。旋转开始偏离轴心,每次移动时,都会围绕其他地方的一个奇怪点旋转。
我怎样才能移动 QUAD(不是相对于旋转)以及旋转它?
编辑 1
我发现这个 QUAD 的一个主要问题是,当我旋转它时,我的整个屏幕(包括文本)都在旋转...
我目前的成绩:
运动前
移动后(希望你注意到它是绕着圆圈移动的,而不是我向左移动时只向左移动。)
代码:
(显示设置)
try {
Display.setDisplayMode(new DisplayMode(width, height));
Display.setVSyncEnabled(vsync);
Display.create();
open = true;
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
// Sets (0, 0) to the top left corner.
GL11.glOrtho(0, this.width, this.height, 0, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
} catch (LWJGLException e) {
e.printStackTrace();
}
(键盘监听器)
public void userLogic() {
if (keyboard.isKeyDown(Keyboard.KEY_A)) {
rect.setLocation(rect.x - 1, rect.y, rect.width, rect.height);
rect.setRotation(-1);
} else if (keyboard.isKeyDown(Keyboard.KEY_D)) {
rect.setLocation(rect.x + 1, rect.y, rect.width, rect.height);
rect.setRotation(1);
} if (keyboard.isKeyDown(Keyboard.KEY_W)) {
rect.setLocation(rect.x, rect.y - 1, rect.width, rect.height);
} else if (keyboard.isKeyDown(Keyboard.KEY_S)) {
rect.setLocation(rect.x, rect.y + 1, rect.width, rect.height);
}
}
(Movement/Rotation逻辑)
public void setRotation(float degrees) {
// TODO: Fix whatever the hell the problem is here.
GL11.glTranslatef(x + (width / 2), y/* + (height / 2)*/, 0);
GL11.glRotatef(degrees, 0f, 0f, 1f);
GL11.glTranslatef(-(x + (width / 2)), -(y/* + (height / 2)*/), 0);
}
public void setLocation(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
(绘制 QUAD,(与渲染过程的其余部分分离))
public void render() {
switch(type) {
case IMAGE:
// Not ready yet.
break;
case TRIANGLE:
// Not ready yet.
break;
case RECTANGLE:
GL11.glColor3f(colour.red, colour.green, colour.blue);
// X, Y, WIDTH, HEIGHT are the QUADS coords, not the displays or anything else's.
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(x, y);
GL11.glVertex2f(x + width, y);
GL11.glVertex2f(x + width, y + height);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
break;
}
}
任何帮助将不胜感激,如果您要投反对票,请给出一个理由,以便我改进这个问题,或者更好的是,发表评论。
这里的问题是您在 setRotation
函数中调用 OpenGL 的平移和旋转函数的顺序。调用顺序必须是Translation(如果有)->Rotation(如果有)->Scaling。您不能更改此调用顺序或以任何方式混淆它们。否则您将得不到想要的结果。这是因为 OpenGL 内部处理这些命令的方式。
将您的 SetRotation
函数更改为
public void setRotation(float degrees) {
// TODO: Fix whatever the hell the problem is here.
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glTranslatef(x , y , 0);
GL11.glRotatef(degrees, 0f, 0f, 1f);
}
您会注意到,如果添加行
GL11.glTranslatef(x , y, 0);
在
下面
GL11.glRotatef(degrees, 0f, 0f, 1f);
,结果会完全不同。这意味着顺序很重要。
userLogic()
函数也存在一些问题。在这种情况下,您需要创建一个全局变量来存储旋转,然后将其传递给setRotation()
float rotValue = 0;
public void userLogic() {
if (keyboard.isKeyDown(Keyboard.KEY_A)) {
rect.setLocation(rect.x - 1, rect.y, rect.width, rect.height);
rotValue-=.1f;
rotValue=rotValue<0?rotValue+360:rotValue;
rect.setRotation(rotValue);
} else if (keyboard.isKeyDown(Keyboard.KEY_D)) {
rect.setLocation(rect.x + 1, rect.y, rect.width, rect.height);
rotValue+=.1f;
rotValue=rotValue>=360?rotValue-360:rotValue;
rect.setRotation(rotValue);
} if (keyboard.isKeyDown(Keyboard.KEY_W)) {
rect.setLocation(rect.x, rect.y - 1, rect.width, rect.height);
} else if (keyboard.isKeyDown(Keyboard.KEY_S)) {
rect.setLocation(rect.x, rect.y + 1, rect.width, rect.height);
}
}
最后在 render()
函数中,传入以 (0,0) 为中心的顶点。 glTranslatef 将负责翻译。
case RECTANGLE:
GL11.glColor3f(colour.red, colour.green, colour.blue);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(-width/2, -height/2);
GL11.glVertex2f(width/2, -height/2);
GL11.glVertex2f(width/2, height/2);
GL11.glVertex2f(-width/2, height/2);
GL11.glEnd();
GL11.glMatrixMode(GL11.GL_MODELVIEW); //resetting the rotation
GL11.glLoadIdentity(); //and translation so that other
//objects are unaffected
break;
这是我制作的一个简单的 lwjgl 项目,用于展示四边形和三角形的平移和旋转
https://gist.github.com/Coditivity/0eedc86447a509f6b5ef
长话短说,我正在制作一个 LWJGL 引擎,并且正在绘制一个基本的 QUAD。当我绘制这个 QUAD 并使用键盘侦听器时,它移动得很完美,up/down/left/right。
然而,当我平移和旋转时,它也绕着它的中心点旋转就好了,同时使用它们,然后你就有问题了。旋转开始偏离轴心,每次移动时,都会围绕其他地方的一个奇怪点旋转。
我怎样才能移动 QUAD(不是相对于旋转)以及旋转它?
编辑 1
我发现这个 QUAD 的一个主要问题是,当我旋转它时,我的整个屏幕(包括文本)都在旋转...
我目前的成绩:
运动前
移动后(希望你注意到它是绕着圆圈移动的,而不是我向左移动时只向左移动。)
代码:
(显示设置)
try {
Display.setDisplayMode(new DisplayMode(width, height));
Display.setVSyncEnabled(vsync);
Display.create();
open = true;
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
// Sets (0, 0) to the top left corner.
GL11.glOrtho(0, this.width, this.height, 0, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
} catch (LWJGLException e) {
e.printStackTrace();
}
(键盘监听器)
public void userLogic() {
if (keyboard.isKeyDown(Keyboard.KEY_A)) {
rect.setLocation(rect.x - 1, rect.y, rect.width, rect.height);
rect.setRotation(-1);
} else if (keyboard.isKeyDown(Keyboard.KEY_D)) {
rect.setLocation(rect.x + 1, rect.y, rect.width, rect.height);
rect.setRotation(1);
} if (keyboard.isKeyDown(Keyboard.KEY_W)) {
rect.setLocation(rect.x, rect.y - 1, rect.width, rect.height);
} else if (keyboard.isKeyDown(Keyboard.KEY_S)) {
rect.setLocation(rect.x, rect.y + 1, rect.width, rect.height);
}
}
(Movement/Rotation逻辑)
public void setRotation(float degrees) {
// TODO: Fix whatever the hell the problem is here.
GL11.glTranslatef(x + (width / 2), y/* + (height / 2)*/, 0);
GL11.glRotatef(degrees, 0f, 0f, 1f);
GL11.glTranslatef(-(x + (width / 2)), -(y/* + (height / 2)*/), 0);
}
public void setLocation(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
(绘制 QUAD,(与渲染过程的其余部分分离))
public void render() {
switch(type) {
case IMAGE:
// Not ready yet.
break;
case TRIANGLE:
// Not ready yet.
break;
case RECTANGLE:
GL11.glColor3f(colour.red, colour.green, colour.blue);
// X, Y, WIDTH, HEIGHT are the QUADS coords, not the displays or anything else's.
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(x, y);
GL11.glVertex2f(x + width, y);
GL11.glVertex2f(x + width, y + height);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
break;
}
}
任何帮助将不胜感激,如果您要投反对票,请给出一个理由,以便我改进这个问题,或者更好的是,发表评论。
这里的问题是您在 setRotation
函数中调用 OpenGL 的平移和旋转函数的顺序。调用顺序必须是Translation(如果有)->Rotation(如果有)->Scaling。您不能更改此调用顺序或以任何方式混淆它们。否则您将得不到想要的结果。这是因为 OpenGL 内部处理这些命令的方式。
将您的 SetRotation
函数更改为
public void setRotation(float degrees) {
// TODO: Fix whatever the hell the problem is here.
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glTranslatef(x , y , 0);
GL11.glRotatef(degrees, 0f, 0f, 1f);
}
您会注意到,如果添加行
GL11.glTranslatef(x , y, 0);
在
下面GL11.glRotatef(degrees, 0f, 0f, 1f);
,结果会完全不同。这意味着顺序很重要。
userLogic()
函数也存在一些问题。在这种情况下,您需要创建一个全局变量来存储旋转,然后将其传递给setRotation()
float rotValue = 0;
public void userLogic() {
if (keyboard.isKeyDown(Keyboard.KEY_A)) {
rect.setLocation(rect.x - 1, rect.y, rect.width, rect.height);
rotValue-=.1f;
rotValue=rotValue<0?rotValue+360:rotValue;
rect.setRotation(rotValue);
} else if (keyboard.isKeyDown(Keyboard.KEY_D)) {
rect.setLocation(rect.x + 1, rect.y, rect.width, rect.height);
rotValue+=.1f;
rotValue=rotValue>=360?rotValue-360:rotValue;
rect.setRotation(rotValue);
} if (keyboard.isKeyDown(Keyboard.KEY_W)) {
rect.setLocation(rect.x, rect.y - 1, rect.width, rect.height);
} else if (keyboard.isKeyDown(Keyboard.KEY_S)) {
rect.setLocation(rect.x, rect.y + 1, rect.width, rect.height);
}
}
最后在 render()
函数中,传入以 (0,0) 为中心的顶点。 glTranslatef 将负责翻译。
case RECTANGLE:
GL11.glColor3f(colour.red, colour.green, colour.blue);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(-width/2, -height/2);
GL11.glVertex2f(width/2, -height/2);
GL11.glVertex2f(width/2, height/2);
GL11.glVertex2f(-width/2, height/2);
GL11.glEnd();
GL11.glMatrixMode(GL11.GL_MODELVIEW); //resetting the rotation
GL11.glLoadIdentity(); //and translation so that other
//objects are unaffected
break;
这是我制作的一个简单的 lwjgl 项目,用于展示四边形和三角形的平移和旋转 https://gist.github.com/Coditivity/0eedc86447a509f6b5ef