复制代码
import java.io.*;
import java.nio.file.*;
import java.util.*;
public class OBJLoader {
public static class Vertex {
public float x, y, z; // Position
public float u, v; // Texture coordinates
public float nx, ny, nz; // Normal
public Vertex(float x, float y, float z, float u, float v, float nx, float ny, float nz) {
this.x = x;
this.y = y;
this.z = z;
this.u = u;
this.v = v;
this.nx = nx;
this.ny = ny;
this.nz = nz;
}
}
public static class Model {
public List<Vertex> vertices = new ArrayList<>();
public List<Integer> indices = new ArrayList<>();
}
public static Model loadModel(String filePath) throws IOException {
List<float[]> positions = new ArrayList<>();
List<float[]> texCoords = new ArrayList<>();
List<float[]> normals = new ArrayList<>();
Model model = new Model();
List<String> lines = Files.readAllLines(Paths.get(filePath));
for (String line : lines) {
String[] tokens = line.split("\\s+");
switch (tokens[0]) {
case "v":
positions.add(new float[]{
Float.parseFloat(tokens[1]),
Float.parseFloat(tokens[2]),
Float.parseFloat(tokens[3])});
break;
case "vt":
texCoords.add(new float[]{
Float.parseFloat(tokens[1]),
Float.parseFloat(tokens[2])});
break;
case "vn":
normals.add(new float[]{
Float.parseFloat(tokens[1]),
Float.parseFloat(tokens[2]),
Float.parseFloat(tokens[3])});
break;
case "f":
for (int i = 1; i <= 3; i++) { // Assuming triangles
String[] parts = tokens[i].split("/");
int posIndex = Integer.parseInt(parts[0]) - 1;
int texIndex = Integer.parseInt(parts[1]) - 1;
int normIndex = Integer.parseInt(parts[2]) - 1;
float[] pos = positions.get(posIndex);
float[] tex = texCoords.get(texIndex);
float[] norm = normals.get(normIndex);
Vertex vertex = new Vertex(pos[0], pos[1], pos[2], tex[0], tex[1], norm[0], norm[1], norm[2]);
model.vertices.add(vertex);
model.indices.add(model.vertices.size() - 1);
}
break;
}
}
return model;
}
}
复制代码
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.GLU;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
import java.io.File;
import java.io.IOException;
import java.nio.FloatBuffer;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL30.*;
public class Main_test_simple_scene {
// 窗口大小
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
// 阴影贴图的大小
private static final int SHADOW_WIDTH = 1024;
private static final int SHADOW_HEIGHT = 1024;
// 帧缓冲对象和纹理对象
private int fbo;
private int shadowMapTexture;
// 光源位置
private float[] lightPosition = {0.0f, 10.0f, 0.0f, 1.0f};
Texture earthTexture;
public void start() throws Exception {
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// Load texture data using your preferred library
earthTexture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("Project1/Assignment3/res/earthspace.png"));
initGL();
while (!Display.isCloseRequested()) {
renderScene();
Display.update();
Display.sync(60);
}
Display.destroy();
}
private void initGL() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective(45.0f, (float) WIDTH / HEIGHT, 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLight(GL_LIGHT0, GL_POSITION, asFloatBuffer(new float[]{0.0f, 10.0f, 0.0f, 1.0f}));
}
static int xRot = 0;
private void renderScene() {
xRot++;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
GLU.gluLookAt(0.0f, 10.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
// 设置物体颜色
glColor3f(1.0f, 1.0f, 0.0f);
// 绘制球体
glPushMatrix();
glTranslatef(0.0f, 4.0f, 0.0f);
// Sphere sp = new Sphere();
// sp.draw(1.0f, 32, 32);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_CULL_FACE); // 启用剔除
glCullFace(GL_BACK); // 剔除背面
// draw obj sphere exported from blender
// 然后创建缓冲区并使用这些数据进行渲染
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, earthTexture.getTextureID());
try {
glRotatef(xRot, 0, 1, 0);
// glRotatef(30, 0, 0, 1);
OBJLoader.Model model = OBJLoader.loadModel("C:\\Users\\adsfa\\Documents\\blender_textures\\earth.obj");
glEnable(GL_TEXTURE_2D); // 如果模型使用纹理
glBegin(GL_TRIANGLES); // 开始绘制三角形
for (int index : model.indices) {
OBJLoader.Vertex v = model.vertices.get(index);
glTexCoord2f(v.u, 1.f-v.v); // 纹理坐标
glNormal3f(v.nx, v.ny, v.nz); // 法线
glVertex3f(v.x, v.y, v.z); // 顶点坐标
}
glEnd(); // 结束绘制
} catch (IOException e) {
e.printStackTrace();
}
glPopMatrix();
// // 绘制地面
glBegin(GL_QUADS);
// glScalef(100, 1, 100);
glNormal3f(0, 1, 1);
glVertex3f(-5.0f, 0.0f, -5.0f);
glVertex3f(-5.0f, 0.0f, 5.0f);
glVertex3f(5.0f, 0.0f, 5.0f);
glVertex3f(5.0f, 0.0f, -5.0f);
glEnd();
}
private FloatBuffer asFloatBuffer(float[] values) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(values.length);
buffer.put(values);
buffer.flip();
return buffer;
}
public static void main(String[] args) {
Main_test_simple_scene example = new Main_test_simple_scene();
try {
example.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}