LWJGL 使对象始终面朝上
LWJGL make object always face up
我需要让 3D 对象以相同的方式正面朝上,无论它们在相机中的位置如何。好像相机距离很远并且放大了。这就是我的意思(看看柱子和墙壁):http://youtu.be/Pn9fh93oV-c
这是我目前的情况:
package pack;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import java.util.Random;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.gluPerspective;
public class Main {
float viewx, viewy;
float angle;
public static void main(String[] args) {
Main main = new Main();
main.start();
}
private void start() {
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setTitle("Three Dee Demo");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
Display.destroy();
System.exit(1);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective((float) 30, 640f / 480f, 0.001f, 100);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glTranslatef(0, 0, -20);
while (!Display.isCloseRequested()) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
update();
render();
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
private void render() {
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor3f(1.0f,1.0f,0.0f);
GL11.glVertex3f( 1.0f, 1.0f,-1.0f);
GL11.glVertex3f(-1.0f, 1.0f,-1.0f);
GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
GL11.glVertex3f( 1.0f, 1.0f, 1.0f);
GL11.glColor3f(1.0f,0.5f,0.0f);
GL11.glVertex3f( 1.0f,-1.0f, 1.0f);
GL11.glVertex3f(-1.0f,-1.0f, 1.0f);
GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
GL11.glVertex3f( 1.0f,-1.0f,-1.0f);
GL11.glColor3f(1.0f,0.0f,0.0f);
GL11.glVertex3f( 1.0f, 1.0f, 1.0f);
GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
GL11.glVertex3f(-1.0f,-1.0f, 1.0f);
GL11.glVertex3f( 1.0f,-1.0f, 1.0f);
GL11.glColor3f(1.0f,1.0f,0.0f);
GL11.glVertex3f( 1.0f,-1.0f,-1.0f);
GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
GL11.glVertex3f(-1.0f, 1.0f,-1.0f);
GL11.glVertex3f( 1.0f, 1.0f,-1.0f);
GL11.glColor3f(0.0f,0.0f,1.0f);
GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
GL11.glVertex3f(-1.0f, 1.0f,-1.0f);
GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
GL11.glVertex3f(-1.0f,-1.0f, 1.0f);
GL11.glColor3f(1.0f,0.0f,1.0f);
GL11.glVertex3f( 1.0f, 1.0f,-1.0f);
GL11.glVertex3f( 1.0f, 1.0f, 1.0f);
GL11.glVertex3f( 1.0f,-1.0f, 1.0f);
GL11.glVertex3f( 1.0f,-1.0f,-1.0f);
GL11.glEnd();
}
private void update() {
if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
viewx -= 0.1f*(float)Math.sin(Math.toRadians(angle));
viewy -= 0.1f*(float)Math.cos(Math.toRadians(angle));
}
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
viewx += 0.1f*(float)Math.sin(Math.toRadians(angle));
viewy += 0.1f*(float)Math.cos(Math.toRadians(angle));
}
if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
viewx+= 0.1f*(float)Math.sin(Math.toRadians(angle-90));
viewy+=0.1f*(float)Math.cos(Math.toRadians(angle-90));
}
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
viewx+= 0.1f*(float)Math.sin(Math.toRadians(angle+90));
viewy+=0.1f*(float)Math.cos(Math.toRadians(angle+90));
}
if (Keyboard.isKeyDown(Keyboard.KEY_Q)) {
angle += 1;
}
if (Keyboard.isKeyDown(Keyboard.KEY_E)) {
angle -= 1;
}
glLoadIdentity();
glRotatef (angle, 0, 0, 1);
glTranslated(viewx, viewy, -20);
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor3f(1.0f,1.0f,0.0f);
GL11.glVertex3f( -viewx-0.2f, -viewy-0.2f,0);
GL11.glVertex3f(-viewx+0.2f, -viewy-0.2f, 0);
GL11.glVertex3f(-viewx+0.2f, -viewy+0.2f, 0);
GL11.glVertex3f( -viewx-0.2f, -viewy+0.2f, 0);
glEnd();
}
}
该游戏似乎使用了正交投影 - 请注意离相机越远的东西并没有变小。这就是为什么线条的方向不依赖于相机位置的原因。
这张图片的左半部分显示了用透视投影渲染的板条箱网格。右半部分显示了使用正交投影渲染的相同网格。
请注意,通过正交投影,所有板条箱看起来都一样,无论它们的位置如何,也无论它们与相机的距离如何 - 只有它们的方向很重要。
在 OpenGL fixed-function 管道中,您可以使用 glOrtho 设置正交投影。如果你使用的是可编程流水线,那么就看你的具体程序了;通常,您需要在 fo
中使用投影矩阵
我需要让 3D 对象以相同的方式正面朝上,无论它们在相机中的位置如何。好像相机距离很远并且放大了。这就是我的意思(看看柱子和墙壁):http://youtu.be/Pn9fh93oV-c
这是我目前的情况:
package pack;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import java.util.Random;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.gluPerspective;
public class Main {
float viewx, viewy;
float angle;
public static void main(String[] args) {
Main main = new Main();
main.start();
}
private void start() {
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setTitle("Three Dee Demo");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
Display.destroy();
System.exit(1);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective((float) 30, 640f / 480f, 0.001f, 100);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glTranslatef(0, 0, -20);
while (!Display.isCloseRequested()) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
update();
render();
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
private void render() {
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor3f(1.0f,1.0f,0.0f);
GL11.glVertex3f( 1.0f, 1.0f,-1.0f);
GL11.glVertex3f(-1.0f, 1.0f,-1.0f);
GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
GL11.glVertex3f( 1.0f, 1.0f, 1.0f);
GL11.glColor3f(1.0f,0.5f,0.0f);
GL11.glVertex3f( 1.0f,-1.0f, 1.0f);
GL11.glVertex3f(-1.0f,-1.0f, 1.0f);
GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
GL11.glVertex3f( 1.0f,-1.0f,-1.0f);
GL11.glColor3f(1.0f,0.0f,0.0f);
GL11.glVertex3f( 1.0f, 1.0f, 1.0f);
GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
GL11.glVertex3f(-1.0f,-1.0f, 1.0f);
GL11.glVertex3f( 1.0f,-1.0f, 1.0f);
GL11.glColor3f(1.0f,1.0f,0.0f);
GL11.glVertex3f( 1.0f,-1.0f,-1.0f);
GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
GL11.glVertex3f(-1.0f, 1.0f,-1.0f);
GL11.glVertex3f( 1.0f, 1.0f,-1.0f);
GL11.glColor3f(0.0f,0.0f,1.0f);
GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
GL11.glVertex3f(-1.0f, 1.0f,-1.0f);
GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
GL11.glVertex3f(-1.0f,-1.0f, 1.0f);
GL11.glColor3f(1.0f,0.0f,1.0f);
GL11.glVertex3f( 1.0f, 1.0f,-1.0f);
GL11.glVertex3f( 1.0f, 1.0f, 1.0f);
GL11.glVertex3f( 1.0f,-1.0f, 1.0f);
GL11.glVertex3f( 1.0f,-1.0f,-1.0f);
GL11.glEnd();
}
private void update() {
if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
viewx -= 0.1f*(float)Math.sin(Math.toRadians(angle));
viewy -= 0.1f*(float)Math.cos(Math.toRadians(angle));
}
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
viewx += 0.1f*(float)Math.sin(Math.toRadians(angle));
viewy += 0.1f*(float)Math.cos(Math.toRadians(angle));
}
if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
viewx+= 0.1f*(float)Math.sin(Math.toRadians(angle-90));
viewy+=0.1f*(float)Math.cos(Math.toRadians(angle-90));
}
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
viewx+= 0.1f*(float)Math.sin(Math.toRadians(angle+90));
viewy+=0.1f*(float)Math.cos(Math.toRadians(angle+90));
}
if (Keyboard.isKeyDown(Keyboard.KEY_Q)) {
angle += 1;
}
if (Keyboard.isKeyDown(Keyboard.KEY_E)) {
angle -= 1;
}
glLoadIdentity();
glRotatef (angle, 0, 0, 1);
glTranslated(viewx, viewy, -20);
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor3f(1.0f,1.0f,0.0f);
GL11.glVertex3f( -viewx-0.2f, -viewy-0.2f,0);
GL11.glVertex3f(-viewx+0.2f, -viewy-0.2f, 0);
GL11.glVertex3f(-viewx+0.2f, -viewy+0.2f, 0);
GL11.glVertex3f( -viewx-0.2f, -viewy+0.2f, 0);
glEnd();
}
}
该游戏似乎使用了正交投影 - 请注意离相机越远的东西并没有变小。这就是为什么线条的方向不依赖于相机位置的原因。
这张图片的左半部分显示了用透视投影渲染的板条箱网格。右半部分显示了使用正交投影渲染的相同网格。
请注意,通过正交投影,所有板条箱看起来都一样,无论它们的位置如何,也无论它们与相机的距离如何 - 只有它们的方向很重要。
在 OpenGL fixed-function 管道中,您可以使用 glOrtho 设置正交投影。如果你使用的是可编程流水线,那么就看你的具体程序了;通常,您需要在 fo
中使用投影矩阵