Java lwjgl 围绕其中心旋转模型
Java lwjgl rotating a model around its center
我一直在制作一个轻量级的项目 java 图形库,我在其中加载了一个模型并用每个三角形的颜色渲染它。我的下一步是围绕其中心旋转模型。通过阅读文章和源代码,我对我需要做什么有一个大致的了解,但我并不完全理解 glTranslatef() 方法。以我的理解你想要
glPushMatrix()
glTranslatef(0,0,0);
glRotatef(旋转值);
glTranslatef(原始坐标);
渲染模型
然后是 glPopMatrix();
我的主要问题是我在我的 glVertex() 方法调用中手动进行数学运算而不是翻译它们,我相信这使得从 0,0,0 返回到原始点的翻译变得困难。感谢您的时间和帮助。
package render;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import static org.lwjgl.opengl.GL11.glTranslatef;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11.glNormal3f;
import static org.lwjgl.opengl.GL11.glVertex3f;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.lwjgl.util.vector.Vector3f;
import models.Faces;
import models.Material;
import models.Model;
import models.OBJLoader;
public class OBJRender {
Material material = new Material();
private int count;
Model m = null;
Vector3f rgb = null;
Vector3f v1 = new Vector3f();
Vector3f v2 = new Vector3f();
Vector3f v3 = new Vector3f();
public void load_model(String model_name){ //loads model data
try{
m = OBJLoader.loadModel(new File("res/obj/"+model_name+".obj"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void model_render(Vector3f coords, Vector3f degrees){
count = 0; //count of triangle for coloring
model_rotate(coords, degrees); //coords is the obj coords degrees is rotation coords
glBegin(GL_TRIANGLES);
for (Faces face : m.faces) {
String mat = OBJLoader.getMaterialList().get(count);
rgb = material.getMaterial(mat);
glColor3f(rgb.x, rgb.y, rgb.z);
Vector3f n1 = m.normals.get((int) face.normals.x - 1);
v1 = m.vertices.get((int) face.Vertex.x - 1);
Vector3f n2 = m.normals.get((int) face.normals.y - 1);
v2 = m.vertices.get((int) face.Vertex.y - 1);
Vector3f n3 = m.normals.get((int) face.normals.z - 1);
v3 = m.vertices.get((int) face.Vertex.z - 1);
glNormal3f(n1.x, n1.y, n1.z);
glVertex3f(coords.x-v1.x, coords.y+v1.y+80, coords.z-v1.z);
glNormal3f(n2.x, n2.y, n2.z);
glVertex3f(coords.x-v2.x, coords.y+v2.y+80, coords.z-v2.z);
glNormal3f(n3.x, n3.y, n3.z);
glVertex3f(coords.x-v3.x, coords.y+v3.y+80, coords.z-v3.z);
count++;
}
glClearColor(rgb.x,rgb.y,rgb.z,0);
glEnd();
glPopMatrix();
}
public void model_rotate(Vector3f coords, Vector3f degrees){
glPushMatrix();
glTranslatef(-0, -0, -0);
glRotatef(degrees.y,0,1,0);
}
}
虽然还不完全清楚实际问题是什么(除了"What do I have to change so that the code does what I want"),尝试回答:
当您从 OBJ 文件加载对象时,您通常 不会 修改顶点坐标。您只需在从文件中读取它们时使用它们。当您想要将对象作为一个整体进行变换时,您可以使用 OpenGL 矩阵运算 - 在这种情况下,只有 glTranslate
和 glRotate
.
为了围绕其中心旋转物体,您首先必须知道这个中心。有疑问的,可以从顶点或者物体的边界框来计算。
然后,为了围绕其中心旋转对象,您必须
- 移动对象,使用
glTranslate
,使对象的中心位于原点
- 旋转对象,使用
glRotate
- 使用
glTranslate
将对象移回原来的位置
请注意,这些操作应用于对象的顺序与它们在源代码中出现的顺序相反。所以调用顺序将是
glTranslatef( center.x, center.y, center.z);
glRotatef(rotationAngleDeg,0,0,1);
glTranslatef(-center.x, -center.y, -center.z);
这里是一个MCVE,它使用一个由4个顶点组成的简单矩形作为对象,并绕其中心旋转。您可以看到,在 glVertex
调用中,它只是按原样使用顶点(在您的例子中,它们将从 OBJ 文件中读取)。整个转换是在 GL_MODELVIEW
矩阵上完成的,使用上面提到的命令。
import static org.lwjgl.opengl.GL11.*;
import java.awt.Canvas;
import javax.swing.JFrame;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.vector.Vector3f;
public class RotateAboutCenter
{
public static void main(String[] args)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(500,500);
f.setLocationRelativeTo(null);
Canvas canvas = new Canvas();
f.add(canvas);
try
{
Display.setParent(canvas);
f.setVisible(true);
Display.create();
}
catch (LWJGLException e)
{
e.printStackTrace();
}
while (!Display.isCloseRequested())
{
draw();
Display.update();
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
rotationAngleDeg += 1.0f;
}
Display.destroy();
}
private static float rotationAngleDeg = 0;
// The vertices of the model
private static Vector3f v0 = new Vector3f(10,10,0);
private static Vector3f v1 = new Vector3f(20,10,0);
private static Vector3f v2 = new Vector3f(20,20,0);
private static Vector3f v3 = new Vector3f(10,20,0);
// The center of the model
private static Vector3f center = new Vector3f(15,15,0);
private static void draw()
{
// Basic setup of view etc.
int w = Display.getWidth();
int h = Display.getHeight();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective(45, (float) w / (float) h, 0.1f, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLU.gluLookAt(0,0,70,0,0,0,0,1,0);
glPushMatrix();
// ===================================================================
// Now, do the model transform. Remember that this has to
// be read "backwards":
// THIRD STEP: Move the model back so that its center is
// again at its original position
glTranslatef(center.x, center.y, center.z);
// SECOND STEP: Rotate the model about the origin (which now
// is the center of the model)
glRotatef(rotationAngleDeg,0,0,1);
// FIRST STEP: Translate the model so that its center is at the origin
glTranslatef(-center.x, -center.y, -center.z);
// ===================================================================
// Draw the object, with its original coordinates. All the
// transforms are now contained in the MODELVIEW matrix.
glBegin(GL_TRIANGLES);
glColor3f(1,0,0);
glVertex3f(v0.x, v0.y, v0.z);
glVertex3f(v1.x, v1.y, v1.z);
glVertex3f(v3.x, v3.y, v3.z);
glVertex3f(v1.x, v1.y, v1.z);
glVertex3f(v2.x, v2.y, v2.z);
glVertex3f(v3.x, v3.y, v3.z);
glEnd();
glPopMatrix();
}
}
我一直在制作一个轻量级的项目 java 图形库,我在其中加载了一个模型并用每个三角形的颜色渲染它。我的下一步是围绕其中心旋转模型。通过阅读文章和源代码,我对我需要做什么有一个大致的了解,但我并不完全理解 glTranslatef() 方法。以我的理解你想要
glPushMatrix()
glTranslatef(0,0,0);
glRotatef(旋转值);
glTranslatef(原始坐标);
渲染模型
然后是 glPopMatrix();
我的主要问题是我在我的 glVertex() 方法调用中手动进行数学运算而不是翻译它们,我相信这使得从 0,0,0 返回到原始点的翻译变得困难。感谢您的时间和帮助。
package render;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import static org.lwjgl.opengl.GL11.glTranslatef;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11.glNormal3f;
import static org.lwjgl.opengl.GL11.glVertex3f;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.lwjgl.util.vector.Vector3f;
import models.Faces;
import models.Material;
import models.Model;
import models.OBJLoader;
public class OBJRender {
Material material = new Material();
private int count;
Model m = null;
Vector3f rgb = null;
Vector3f v1 = new Vector3f();
Vector3f v2 = new Vector3f();
Vector3f v3 = new Vector3f();
public void load_model(String model_name){ //loads model data
try{
m = OBJLoader.loadModel(new File("res/obj/"+model_name+".obj"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void model_render(Vector3f coords, Vector3f degrees){
count = 0; //count of triangle for coloring
model_rotate(coords, degrees); //coords is the obj coords degrees is rotation coords
glBegin(GL_TRIANGLES);
for (Faces face : m.faces) {
String mat = OBJLoader.getMaterialList().get(count);
rgb = material.getMaterial(mat);
glColor3f(rgb.x, rgb.y, rgb.z);
Vector3f n1 = m.normals.get((int) face.normals.x - 1);
v1 = m.vertices.get((int) face.Vertex.x - 1);
Vector3f n2 = m.normals.get((int) face.normals.y - 1);
v2 = m.vertices.get((int) face.Vertex.y - 1);
Vector3f n3 = m.normals.get((int) face.normals.z - 1);
v3 = m.vertices.get((int) face.Vertex.z - 1);
glNormal3f(n1.x, n1.y, n1.z);
glVertex3f(coords.x-v1.x, coords.y+v1.y+80, coords.z-v1.z);
glNormal3f(n2.x, n2.y, n2.z);
glVertex3f(coords.x-v2.x, coords.y+v2.y+80, coords.z-v2.z);
glNormal3f(n3.x, n3.y, n3.z);
glVertex3f(coords.x-v3.x, coords.y+v3.y+80, coords.z-v3.z);
count++;
}
glClearColor(rgb.x,rgb.y,rgb.z,0);
glEnd();
glPopMatrix();
}
public void model_rotate(Vector3f coords, Vector3f degrees){
glPushMatrix();
glTranslatef(-0, -0, -0);
glRotatef(degrees.y,0,1,0);
}
}
虽然还不完全清楚实际问题是什么(除了"What do I have to change so that the code does what I want"),尝试回答:
当您从 OBJ 文件加载对象时,您通常 不会 修改顶点坐标。您只需在从文件中读取它们时使用它们。当您想要将对象作为一个整体进行变换时,您可以使用 OpenGL 矩阵运算 - 在这种情况下,只有 glTranslate
和 glRotate
.
为了围绕其中心旋转物体,您首先必须知道这个中心。有疑问的,可以从顶点或者物体的边界框来计算。
然后,为了围绕其中心旋转对象,您必须
- 移动对象,使用
glTranslate
,使对象的中心位于原点 - 旋转对象,使用
glRotate
- 使用
glTranslate
将对象移回原来的位置
请注意,这些操作应用于对象的顺序与它们在源代码中出现的顺序相反。所以调用顺序将是
glTranslatef( center.x, center.y, center.z);
glRotatef(rotationAngleDeg,0,0,1);
glTranslatef(-center.x, -center.y, -center.z);
这里是一个MCVE,它使用一个由4个顶点组成的简单矩形作为对象,并绕其中心旋转。您可以看到,在 glVertex
调用中,它只是按原样使用顶点(在您的例子中,它们将从 OBJ 文件中读取)。整个转换是在 GL_MODELVIEW
矩阵上完成的,使用上面提到的命令。
import static org.lwjgl.opengl.GL11.*;
import java.awt.Canvas;
import javax.swing.JFrame;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.vector.Vector3f;
public class RotateAboutCenter
{
public static void main(String[] args)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(500,500);
f.setLocationRelativeTo(null);
Canvas canvas = new Canvas();
f.add(canvas);
try
{
Display.setParent(canvas);
f.setVisible(true);
Display.create();
}
catch (LWJGLException e)
{
e.printStackTrace();
}
while (!Display.isCloseRequested())
{
draw();
Display.update();
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
rotationAngleDeg += 1.0f;
}
Display.destroy();
}
private static float rotationAngleDeg = 0;
// The vertices of the model
private static Vector3f v0 = new Vector3f(10,10,0);
private static Vector3f v1 = new Vector3f(20,10,0);
private static Vector3f v2 = new Vector3f(20,20,0);
private static Vector3f v3 = new Vector3f(10,20,0);
// The center of the model
private static Vector3f center = new Vector3f(15,15,0);
private static void draw()
{
// Basic setup of view etc.
int w = Display.getWidth();
int h = Display.getHeight();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective(45, (float) w / (float) h, 0.1f, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLU.gluLookAt(0,0,70,0,0,0,0,1,0);
glPushMatrix();
// ===================================================================
// Now, do the model transform. Remember that this has to
// be read "backwards":
// THIRD STEP: Move the model back so that its center is
// again at its original position
glTranslatef(center.x, center.y, center.z);
// SECOND STEP: Rotate the model about the origin (which now
// is the center of the model)
glRotatef(rotationAngleDeg,0,0,1);
// FIRST STEP: Translate the model so that its center is at the origin
glTranslatef(-center.x, -center.y, -center.z);
// ===================================================================
// Draw the object, with its original coordinates. All the
// transforms are now contained in the MODELVIEW matrix.
glBegin(GL_TRIANGLES);
glColor3f(1,0,0);
glVertex3f(v0.x, v0.y, v0.z);
glVertex3f(v1.x, v1.y, v1.z);
glVertex3f(v3.x, v3.y, v3.z);
glVertex3f(v1.x, v1.y, v1.z);
glVertex3f(v2.x, v2.y, v2.z);
glVertex3f(v3.x, v3.y, v3.z);
glEnd();
glPopMatrix();
}
}