Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import org.joml.*;
- import org.lwjgl.glfw.GLFW;
- import org.lwjgl.glfw.GLFWErrorCallback;
- import org.lwjgl.glfw.GLFWVidMode;
- import org.lwjgl.opengl.*;
- import org.lwjgl.stb.STBImage;
- import org.lwjgl.system.MemoryStack;
- import org.lwjgl.system.MemoryUtil;
- import java.io.BufferedWriter;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.io.InputStream;
- import java.lang.Math;
- import java.nio.ByteBuffer;
- import java.nio.FloatBuffer;
- import java.nio.IntBuffer;
- import java.nio.charset.StandardCharsets;
- import java.nio.file.Files;
- import java.nio.file.Paths;
- import java.util.*;
- import static org.lwjgl.glfw.GLFW.*;
- import static org.lwjgl.opengl.GL.*;
- import static org.lwjgl.opengl.GL11.*;
- class Run {
- public static void main(String[] args) throws Exception {
- Client.init();
- }
- }
- class Client {
- private static Display display;
- private static Server server = new Server();
- public static void init() throws Exception {
- display = new Display();
- if (Vars.singleplayer) {
- server = new Server();
- }
- while (!glfwWindowShouldClose(display.getWindow())) {
- display.update();
- }
- display.cleanup();
- }
- public static Display getDisplay() {
- return display;
- }
- public static Server getServer() {
- return server;
- }
- public static class Vars {
- public static boolean singleplayer = true, vSync = false;
- }
- }
- class Display {
- private final float FOV = (float) Math.toRadians(60), Z_NEAR = 0.01f, Z_FAR = 1000f;
- private final String title = "Project Negative";
- private static long window;
- private boolean fullscreen = false, inWindow = true;
- private int width = 1280, height = 800, cullMethod = -1;
- private Matrix4f projectionMatrix = new Matrix4f();
- private Shader shader;
- private Vector4f backgroundColor;
- public Display() throws Exception {
- windowInit();
- renderInit();
- }
- public void windowInit() {
- GLFWErrorCallback.createPrint(System.err).set();
- if (!glfwInit()) {
- throw new IllegalStateException("Unable to initialize GLFW");
- }
- glfwDefaultWindowHints();
- glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
- glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
- if (fullscreen) {
- glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
- }
- window = glfwCreateWindow(width, height, title, MemoryUtil.NULL, MemoryUtil.NULL);
- if (window == MemoryUtil.NULL) {
- throw new RuntimeException("Failed to create GLFW window");
- }
- glfwSetFramebufferSizeCallback(window, (window, width, height) -> {
- this.width = width;
- this.height = height;
- });
- glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
- if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
- glfwSetWindowShouldClose(window, true);
- }
- if (key == GLFW_KEY_R && action == GLFW_PRESS) {
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
- inWindow = false;
- }
- if (key == GLFW_KEY_G && action == GLFW_PRESS) {
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- inWindow = true;
- }
- });
- if (fullscreen) {
- glfwMaximizeWindow(window);
- } else {
- GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
- glfwSetWindowPos(window, (vidMode.width() - width) / 2, (vidMode.height() - height) / 2);
- }
- glfwMakeContextCurrent(window);
- if (Client.Vars.vSync) {
- glfwSwapInterval(1);
- }
- glfwShowWindow(window);
- createCapabilities();
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_STENCIL_TEST);
- if (cullMethod != -1) {
- glEnable(GL_CULL_FACE);
- glCullFace(cullMethod);
- }
- }
- public void renderInit() throws Exception {
- shader = new Shader();
- shader.createVertexShader(FileUtils.loadResource("/shaders/vertex.vs"));
- shader.createFragmentShader(FileUtils.loadResource("/shaders/fragment.fs"));
- shader.link();
- shader.createUniform("textureSampler");
- shader.createUniform("transformationMatrix");
- shader.createUniform("projectionMatrix");
- shader.createUniform("viewMatrix");
- shader.createUniform("ambientLight");
- shader.createMaterialUniform("material");
- shader.createUniform("specularPower");
- shader.createDirectionalLightUniform("directionalLight");
- shader.createPointLightListUniform("pointLights", 5);
- shader.createSpotLightListUniform("spotLights", 5);
- }
- public long getWindow() {
- return window;
- }
- public void update() {
- glfwSwapBuffers(window);
- glfwPollEvents();
- }
- public void cleanup() {
- glfwDestroyWindow(window);
- }
- public boolean isKeyPressed(int keycode) {
- return org.lwjgl.glfw.GLFW.glfwGetKey(window, keycode) == GLFW.GLFW_PRESS;
- }
- public boolean isInWindow() {
- return inWindow;
- }
- public Matrix4f updateProjectionMatrix() {
- float aspectRatio = (float) width / height;
- return projectionMatrix.setPerspective(FOV, aspectRatio, Z_NEAR, Z_FAR);
- }
- }
- class Render {
- private final Display display;
- private Shader shader;
- private final Map<Model, List<Entity>> entities = new HashMap<>();
- public Render() {
- display = Client.getDisplay();
- }
- public void init() throws Exception {
- shader = new Shader();
- shader.createVertexShader(FileUtils.loadResource("/shaders/vertex.vs"));
- shader.createFragmentShader(FileUtils.loadResource("/shaders/fragment.fs"));
- shader.link();
- shader.createUniform("textureSampler");
- shader.createUniform("transformationMatrix");
- shader.createUniform("projectionMatrix");
- shader.createUniform("viewMatrix");
- shader.createUniform("ambientLight");
- shader.createMaterialUniform("material");
- shader.createUniform("specularPower");
- shader.createDirectionalLightUniform("directionalLight");
- shader.createPointLightListUniform("pointLights", 5);
- shader.createSpotLightListUniform("spotLights", 5);
- }
- public void bind(Model model) {
- GL30.glBindVertexArray(model.getId());
- GL20.glEnableVertexAttribArray(0);
- GL20.glEnableVertexAttribArray(1);
- GL20.glEnableVertexAttribArray(2);
- shader.setUniform("material", model.getMaterial());
- GL13.glActiveTexture(GL13.GL_TEXTURE0);
- GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexture().id());
- }
- public void unbind() {
- GL20.glDisableVertexAttribArray(0);
- GL20.glDisableVertexAttribArray(1);
- GL20.glDisableVertexAttribArray(2);
- GL30.glBindVertexArray(0);
- }
- public void prepare(Entity entity, Camera camera) {
- shader.setUniform("textureSampler", 0);
- shader.setUniform("transformationMatrix", TransformationUtils.createTransformationMatrix(entity));
- shader.setUniform("viewMatrix", TransformationUtils.getViewMatrix(camera));
- }
- public void renderLights(Camera camera, DirectionalLight directionalLight, PointLight[] pointLights, SpotLight[] spotLights) {
- shader.setUniform("ambientLight", Client.getServer().ambientLight);
- shader.setUniform("specularPower", Client.getServer().specularPower);
- int numLights = spotLights != null ? spotLights.length : 0;
- for (int i = 0; i < numLights; i++) {
- shader.setUniform("spotLights", spotLights[i], i);
- }
- numLights = pointLights != null ? pointLights.length : 0;
- for (int i = 0; i < numLights; i++) {
- shader.setUniform("pointLights", pointLights[i], i);
- }
- shader.setUniform("directionalLight", directionalLight);
- }
- public void render(Camera camera, DirectionalLight directionalLight, PointLight[] pointLights, SpotLight[] spotLights) {
- clear();
- shader.bind();
- shader.setUniform("projectionMatrix", display.updateProjectionMatrix());
- renderLights(camera, directionalLight, pointLights, spotLights);
- for (Model model : entities.keySet()) {
- bind(model);
- List<Entity> entityList = entities.get(model);
- for (Entity entity : entityList) {
- prepare(entity, camera);
- GL11.glDrawElements(GL11.GL_TRIANGLES, entity.model().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
- }
- unbind();
- }
- entities.clear();
- shader.unbind();
- }
- public void processEntity(Entity entity) {
- List<Entity> entityList = entities.get(entity.model());
- if (entityList != null) {
- entityList.add(entity);
- } else {
- List<Entity> newEntityList = new ArrayList<>();
- newEntityList.add(entity);
- entities.put(entity.model(), newEntityList);
- }
- }
- public void clear() {
- GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
- }
- public void cleanup() {
- shader.cleanup();
- }
- }
- class Shader {
- private final int programID;
- private int vertexShaderID, fragmentShaderID;
- private final Map<String, Integer> uniforms;
- public Shader() throws Exception {
- programID = GL20.glCreateProgram();
- if (programID == 0) {
- throw new Exception("Could not create shader");
- }
- uniforms = new HashMap<>();
- }
- public void createUniform(String uniformName) throws Exception {
- int uniformLocation = GL20.glGetUniformLocation(programID, uniformName);
- if (uniformLocation < 0) {
- throw new Exception("Could not find uniform " + uniformName);
- }
- uniforms.put(uniformName, uniformLocation);
- }
- public void createDirectionalLightUniform(String uniformName) throws Exception {
- createUniform(uniformName + ".color");
- createUniform(uniformName + ".direction");
- createUniform(uniformName + ".intensity");
- }
- public void createMaterialUniform(String uniformName) throws Exception {
- createUniform(uniformName + ".ambient");
- createUniform(uniformName + ".diffuse");
- createUniform(uniformName + ".specular");
- createUniform(uniformName + ".hasTexture");
- createUniform(uniformName + ".reflectance");
- }
- public void createPointLightUniform(String uniformName) throws Exception {
- createUniform(uniformName + ".color");
- createUniform(uniformName + ".position");
- createUniform(uniformName + ".intensity");
- createUniform(uniformName + ".constant");
- createUniform(uniformName + ".linear");
- createUniform(uniformName + ".exponent");
- }
- public void createPointLightListUniform(String uniformName, int size) throws Exception {
- for (int i = 0; i < size; i++) {
- createPointLightUniform(uniformName + "[" + i + "]");
- }
- }
- public void createSpotLightListUniform(String uniformName, int size) throws Exception {
- for (int i = 0; i < size; i++) {
- createSpotLightUniform(uniformName + "[" + i + "]");
- }
- }
- public void createSpotLightUniform(String uniformName) throws Exception {
- createPointLightUniform(uniformName + ".pl");
- createUniform(uniformName + ".conedir");
- createUniform(uniformName + ".cutoff");
- }
- public void setUniform(String uniformName, boolean value) {
- float res = 0;
- if (value) {
- res = 1;
- }
- GL20.glUniform1f(uniforms.get(uniformName), res);
- }
- public void setUniform(String uniformName, Matrix4f value) {
- try (MemoryStack stack = MemoryStack.stackPush()) {
- GL20.glUniformMatrix4fv(uniforms.get(uniformName), false, value.get(stack.mallocFloat(16)));
- }
- }
- public void setUniform(String uniformName, Vector4f value) {
- GL20.glUniform4f(uniforms.get(uniformName), value.x, value.y, value.z, value.w);
- }
- public void setUniform(String uniformName, Vector3f value) {
- GL20.glUniform3f(uniforms.get(uniformName), value.x, value.y, value.z);
- }
- public void setUniform(String uniformName, int value) {
- GL20.glUniform1i(uniforms.get(uniformName), value);
- }
- public void setUniform(String uniformName, float value) {
- GL20.glUniform1f(uniforms.get(uniformName), value);
- }
- public void setUniform(String uniformName, Material material) {
- setUniform(uniformName + ".ambient", material.getAmbientColor());
- setUniform(uniformName + ".diffuse", material.getDiffuseColor());
- setUniform(uniformName + ".specular", material.getSpecularColor());
- setUniform(uniformName + ".hasTexture", material.hasTexture() ? 1 : 0);
- setUniform(uniformName + ".reflectance", material.getReflectance());
- }
- public void setUniform(String uniformName, DirectionalLight directionalLight) {
- setUniform(uniformName + ".color", directionalLight.getColor());
- setUniform(uniformName + ".direction", directionalLight.getDirection());
- setUniform(uniformName + ".intensity", directionalLight.getIntensity());
- }
- public void setUniform(String uniformName, PointLight pointLight) {
- setUniform(uniformName + ".color", pointLight.getColor());
- setUniform(uniformName + ".position", pointLight.getPosition());
- setUniform(uniformName + ".intensity", pointLight.getIntensity());
- setUniform(uniformName + ".constant", pointLight.getConstant());
- setUniform(uniformName + ".linear", pointLight.getLinear());
- setUniform(uniformName + ".exponent", pointLight.getExponent());
- }
- public void setUniform(String uniformName, SpotLight spotLight) {
- setUniform(uniformName + ".pl", spotLight.getPointLight());
- setUniform(uniformName + ".conedir", spotLight.getConeDirection());
- setUniform(uniformName + ".cutoff", spotLight.getCutoff());
- }
- public void setUniform(String uniformName, PointLight[] pointLights) {
- int numLights = pointLights != null ? pointLights.length : 0;
- for (int i = 0; i < numLights; i++) {
- setUniform(uniformName, pointLights[i], i);
- }
- }
- public void setUniform(String uniformName, PointLight pointLight, int pos) {
- setUniform(uniformName + "[" + pos + "]", pointLight);
- }
- public void setUniform(String uniformName, SpotLight[] spotLights) {
- int numLights = spotLights != null ? spotLights.length : 0;
- for (int i = 0; i < numLights; i++) {
- setUniform(uniformName, spotLights[i], i);
- }
- }
- public void setUniform(String uniformName, SpotLight spotLight, int pos) {
- setUniform(uniformName + "[" + pos + "]", spotLight);
- }
- public void createVertexShader(String shaderCode) throws Exception {
- vertexShaderID = createShader(shaderCode, GL20.GL_VERTEX_SHADER);
- }
- public void createFragmentShader(String shaderCode) throws Exception {
- fragmentShaderID = createShader(shaderCode, GL20.GL_FRAGMENT_SHADER);
- }
- public int createShader(String shaderCode, int shaderType) throws Exception {
- int shaderId = GL20.glCreateShader(shaderType);
- if (shaderId == 0) {
- throw new Exception("Error creating shader of type " + shaderType);
- }
- GL20.glShaderSource(shaderId, shaderCode);
- GL20.glCompileShader(shaderId);
- if (GL20.glGetShaderi(shaderId, GL20.GL_COMPILE_STATUS) == 0) {
- throw new Exception("Error compiling shader code of type " + shaderType + " Info: " + GL20.glGetShaderInfoLog(shaderId, 1024));
- }
- GL20.glAttachShader(programID, shaderId);
- return shaderId;
- }
- public void link() throws Exception {
- GL20.glLinkProgram(programID);
- //if (GL20.glGetShaderi(programID, GL20.GL_LINK_STATUS) == 0) {
- // throw new Exception("Error linking shader code Info: " + GL20.glGetProgramInfoLog(programID, 1024));
- //}
- // Program worked fine without this, may cause issues in the future.
- if (vertexShaderID != 0) {
- GL20.glDetachShader(programID, vertexShaderID);
- }
- if (fragmentShaderID != 0) {
- GL20.glDetachShader(programID, fragmentShaderID);
- }
- GL20.glValidateProgram(programID);
- if (GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS) == 0) {
- throw new Exception("Unable to validate shader code " + GL20.glGetProgramInfoLog(programID, 1024));
- }
- }
- public void bind() {
- GL20.glUseProgram(programID);
- }
- public void unbind() {
- GL20.glUseProgram(programID);
- }
- public void cleanup() {
- unbind();
- if (programID != 0) {
- GL20.glDeleteProgram(programID);
- }
- }
- }
- record Entity(Model model, Vector3f pos, Vector3f rotation, float scale, Map<String, Object> data) {
- public void incPos(float x, float y, float z) {
- this.pos.x += x;
- this.pos.y += y;
- this.pos.z += z;
- }
- public void setPos(float x, float y, float z) {
- this.pos.x = x;
- this.pos.y = y;
- this.pos.z = z;
- }
- public void incRotation(float x, float y, float z) {
- this.rotation.x += x;
- this.rotation.y += y;
- this.rotation.z += z;
- }
- public void setRotation(float x, float y, float z) {
- this.rotation.x += x;
- this.rotation.y += y;
- this.rotation.z += z;
- }
- }
- class Material {
- private Vector4f ambientColor, diffuseColor, specularColor;
- private float reflectance;
- private Texture texture;
- public Material() {
- this.ambientColor = Client.getServer().defaultColor;
- this.diffuseColor = Client.getServer().defaultColor;
- this.specularColor = Client.getServer().defaultColor;
- this.reflectance = 0;
- this.texture = null;
- }
- public Material(Vector4f color, float reflectance) {
- this(color, color, color, reflectance, null);
- }
- public Material(Vector4f color, float reflectance, Texture texture) {
- this(color, color, color, reflectance, texture);
- }
- public Material(Texture texture) {
- this(Client.getServer().defaultColor, Client.getServer().defaultColor, Client.getServer().defaultColor, 0, texture);
- }
- public Material(Vector4f ambientColor, Vector4f diffuseColor, Vector4f specularColor, float reflectance, Texture texture) {
- this.ambientColor = ambientColor;
- this.diffuseColor = diffuseColor;
- this.specularColor = specularColor;
- this.reflectance = reflectance;
- this.texture = texture;
- }
- public Vector4f getAmbientColor() {
- return ambientColor;
- }
- public void setAmbientColor(Vector4f ambientColor) {
- this.ambientColor = ambientColor;
- }
- public Vector4f getDiffuseColor() {
- return diffuseColor;
- }
- public void setDiffuseColor(Vector4f diffuseColor) {
- this.diffuseColor = diffuseColor;
- }
- public Vector4f getSpecularColor() {
- return specularColor;
- }
- public void setSpecularColor(Vector4f specularColor) {
- this.specularColor = specularColor;
- }
- public float getReflectance() {
- return reflectance;
- }
- public void setReflectance(float reflectance) {
- this.reflectance = reflectance;
- }
- public Texture getTexture() {
- return texture;
- }
- public void setTexture(Texture texture) {
- this.texture = texture;
- }
- public boolean hasTexture() {
- return texture != null;
- }
- }
- record Texture(int id) {}
- class Model {
- private final int id;
- private final int vertexCount;
- private Material material;
- private float[] vertices, texCoords, normals;
- private int[] indices;
- private List<Vector3f> boundingBox;
- public Model(int id, int vertexCount) {
- this.id = id;
- this.vertexCount = vertexCount;
- this.material = new Material();
- }
- public Model(int id, int vertexCount, Texture texture) {
- this.id = id;
- this.vertexCount = vertexCount;
- this.material = new Material(texture);
- }
- public Model(Model model, Texture texture) {
- this.id = model.getId();
- this.vertexCount = model.getVertexCount();
- this.material = model.getMaterial();
- this.material.setTexture(texture);
- }
- public Model(float[] vertices, float[] texCoords, float[] normals, int[] indices, List<Vector3f> boundingBox) {
- ObjectLoader loader = new ObjectLoader();
- this.vertices = vertices;
- this.texCoords = texCoords;
- this.normals = normals;
- this.indices = indices;
- this.boundingBox = boundingBox;
- this.id = loader.createVAO();
- loader.storeIndiciesBuffer(indices);
- loader.storeDataInAttributes(0, 3, vertices);
- loader.storeDataInAttributes(1, 2, texCoords);
- loader.storeDataInAttributes(2, 3, normals);
- loader.unbind();
- this.vertexCount = indices.length;
- this.material = new Material();
- }
- public Model(Model model) {
- ObjectLoader loader = new ObjectLoader();
- this.vertices = model.vertices;
- this.texCoords = model.texCoords;
- this.normals = model.normals;
- this.indices = model.indices;
- this.id = loader.createVAO();
- loader.storeIndiciesBuffer(indices);
- loader.storeDataInAttributes(0, 3, vertices);
- loader.storeDataInAttributes(1, 2, texCoords);
- loader.storeDataInAttributes(2, 3, normals);
- loader.unbind();
- this.vertexCount = indices.length;
- this.material = new Material();
- }
- public int getId() {
- return id;
- }
- public int getVertexCount() {
- return vertexCount;
- }
- public Material getMaterial() {
- return material;
- }
- public void setMaterial(Material material) {
- this.material = material;
- }
- public Texture getTexture() {
- return material.getTexture();
- }
- public void setTexture(Texture texture) {
- material.setTexture(texture);
- }
- public void setTexture(Texture texture, float reflectance) {
- this.material.setTexture(texture);
- this.material.setReflectance(reflectance);
- }
- public float[] getVertices() {
- return vertices;
- }
- public void setVertices(float[] vertices) {
- this.vertices = vertices;
- }
- public float[] getTexCoords() {
- return texCoords;
- }
- public void setTexCoords(float[] texCoords) {
- this.texCoords = texCoords;
- }
- public float[] getNormals() {
- return normals;
- }
- public void setNormals(float[] normals) {
- this.normals = normals;
- }
- public int[] getIndices() {
- return indices;
- }
- public void setIndices(int[] indices) {
- this.indices = indices;
- }
- public List<Vector3f> getBoundingBox() {
- return boundingBox;
- }
- }
- class ObjectLoader {
- private final List<Integer> vaos = new ArrayList<>();
- private final List<Integer> vbos = new ArrayList<>();
- private final List<Integer> textures = new ArrayList<>();
- /*
- public Model loadModel(String filename) throws IOException {
- List<Vector3f> vertices = new ArrayList<>();
- List<Vector2f> textureCoords = new ArrayList<>();
- List<Integer> indices = new ArrayList<>();
- List<String> lines = Utils.readAllLines(filename);
- for (String line : lines) {
- String[] parts = line.split(" ");
- if (parts[0].equals("v")) {
- float[] vertex = new float[3];
- vertex[0] = Float.parseFloat(parts[1]);
- vertex[1] = Float.parseFloat(parts[2]);
- vertex[2] = Float.parseFloat(parts[3]);
- vertices.add(vertex);
- } else if (parts[0].equals("tC")) {
- float[] texCoord = new float[2];
- texCoord[0] = Float.parseFloat(parts[1]);
- texCoord[1] = Float.parseFloat(parts[2]);
- textureCoords.add(texCoord);
- } else if (parts[0].equals("i")) {
- int[] index = new int[6];
- index[0] = Integer.parseInt(parts[1]);
- index[1] = Integer.parseInt(parts[2]);
- index[2] = Integer.parseInt(parts[3]);
- index[3] = Integer.parseInt(parts[4]);
- index[4] = Integer.parseInt(parts[5]);
- index[5] = Integer.parseInt(parts[6]);
- indices.add(index);
- }
- }
- return loadModel(vertices, textureCoords, new float[]{vertices.size() * 3}, indices);
- }
- */
- public Model loadOBJModel(String filename) throws IOException {
- List<String> lines = FileUtils.readAllLines(filename);
- List<Vector3f> verticies = new ArrayList<>();
- List<Vector3f> normals = new ArrayList<>();
- List<Vector2f> textures = new ArrayList<>();
- List<Vector3i> faces = new ArrayList<>();
- for (String line : lines) {
- String[] tokens = line.split("\\s+");
- switch (tokens[0]) {
- case "v":
- Vector3f verticiesVec = new Vector3f(
- Float.parseFloat(tokens[1]),
- Float.parseFloat(tokens[2]),
- Float.parseFloat(tokens[3])
- );
- verticies.add(verticiesVec);
- break;
- case "vt":
- Vector2f textureVec = new Vector2f(
- Float.parseFloat(tokens[1]),
- Float.parseFloat(tokens[2])
- );
- textures.add(textureVec);
- break;
- case "vn":
- Vector3f normalsVec = new Vector3f(
- Float.parseFloat(tokens[1]),
- Float.parseFloat(tokens[2]),
- Float.parseFloat(tokens[3])
- );
- normals.add(normalsVec);
- break;
- case "f":
- processFace(tokens[1], faces);
- processFace(tokens[2], faces);
- processFace(tokens[3], faces);
- break;
- default:
- break;
- }
- }
- List<Integer> indices = new ArrayList<>();
- float[] verticiesArr = new float[verticies.size() * 3];
- int i = 0;
- for (Vector3f pos : verticies) {
- verticiesArr[i * 3] = pos.x;
- verticiesArr[i * 3 + 1] = pos.y;
- verticiesArr[i * 3 + 2] = pos.z;
- i++;
- }
- float[] texCoordArr = new float[verticies.size() * 2];
- float[] normalArr = new float[verticies.size() * 3];
- for (Vector3i face : faces) {
- processVertex(face.x, face.y, face.z, textures, normals, indices, texCoordArr, normalArr);
- }
- int[] indicesArr = indices.stream().mapToInt((Integer v) -> v).toArray();
- return new Model(verticiesArr, texCoordArr, normalArr, indicesArr, new ArrayList<>());
- }
- private static void processVertex(int pos, int texCoord, int normal, List<Vector2f> texCoordList, List<Vector3f> normalList, List<Integer> indicesList, float[] texCoordArr, float[] normalArr) {
- indicesList.add(pos);
- if (texCoord >= 0) {
- Vector2f texCoordVec = texCoordList.get(texCoord);
- texCoordArr[pos * 2] = texCoordVec.x;
- texCoordArr[pos * 2 + 1] = 1 - texCoordVec.y;
- }
- if (normal >= 0) {
- Vector3f normalVec = normalList.get(normal);
- normalArr[pos * 3] = normalVec.x;
- normalArr[pos * 3 + 1] = normalVec.y;
- normalArr[pos * 3 + 2] = normalVec.z;
- }
- }
- private static void processFace(String token, List<Vector3i> faces) {
- String[] lineToken = token.split("/");
- int length = lineToken.length;
- int pos = -1, coords = -1, normal = -1;
- pos = Integer.parseInt(lineToken[0]) - 1;
- if (length > 1 && !lineToken[1].isEmpty()) {
- coords = Integer.parseInt(lineToken[1]) - 1;
- }
- if (length > 2 && !lineToken[2].isEmpty()) {
- normal = Integer.parseInt(lineToken[2]) - 1;
- }
- Vector3i facesVec = new Vector3i(pos, coords, normal);
- faces.add(facesVec);
- }
- /*
- public Model loadModel(float[] vertices, float[] texCoords, float[] normals, int[] indices) {
- int id = createVAO();
- storeIndiciesBuffer(indices);
- storeDataInAttributes(0, 3, vertices);
- storeDataInAttributes(1, 2, texCoords);
- storeDataInAttributes(2, 3, normals);
- unbind();
- return new Model(id, indices.length);
- }
- */
- public int loadTexture(String filename) throws Exception {
- int width, height;
- ByteBuffer buffer;
- try (MemoryStack stack = MemoryStack.stackPush()) {
- IntBuffer w = stack.mallocInt(1);
- IntBuffer h = stack.mallocInt(1);
- IntBuffer c = stack.mallocInt(1);
- buffer = STBImage.stbi_load(filename, w, h, c, 4);
- if (buffer == null) {
- throw new Exception("Image file " + filename + " not loaded " + STBImage.stbi_failure_reason());
- }
- width = w.get();
- height = h.get();
- }
- int id = GL11.glGenTextures();
- textures.add(id);
- GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
- GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
- GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
- GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
- STBImage.stbi_image_free(buffer);
- return id;
- }
- public int createVAO() {
- int id = GL30.glGenVertexArrays();
- vaos.add(id);
- GL30.glBindVertexArray(id);
- return id;
- }
- public void storeIndiciesBuffer(int[] indices) {
- int vbo = GL15.glGenBuffers();
- vbos.add(vbo);
- GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vbo);
- IntBuffer buffer = FileUtils.storeDataInIntBuffer(indices);
- GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
- }
- public void storeDataInAttributes(int attribNo, int vertexCount, float[] data) {
- int vbo = GL15.glGenBuffers();
- vbos.add(vbo);
- GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
- FloatBuffer buffer = FileUtils.storeDataInFloatBuffer(data);
- GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
- GL20.glVertexAttribPointer(attribNo, vertexCount, GL11.GL_FLOAT, false, 0, 0);
- GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
- }
- public void unbind() {
- GL30.glBindVertexArray(0);
- }
- public void cleanup() {
- for (int vao : vaos) {
- GL30.glDeleteVertexArrays(vao);
- }
- for (int vbo : vbos) {
- GL30.glDeleteBuffers(vbo);
- }
- for (int texture : textures) {
- GL11.glDeleteTextures(texture);
- }
- }
- }
- class Camera {
- private final Vector3f position;
- private final Vector3f rotation;
- public Camera() {
- position = new Vector3f(0, 0, 0);
- rotation = new Vector3f(0, 0, 0);
- }
- public Camera(Vector3f position, Vector3f rotation) {
- this.position = position;
- this.rotation = rotation;
- }
- public void movePosition(float x, float y, float z) {
- if (z != 0) {
- position.x += (float) Math.sin(Math.toRadians(rotation.y)) * -1.0f * z;
- position.z += (float) Math.cos(Math.toRadians(rotation.y)) * z;
- }
- if (x != 0) {
- position.x += (float) Math.sin(Math.toRadians(rotation.y - 90)) * -1.0f * x;
- position.z += (float) Math.cos(Math.toRadians(rotation.y - 90)) * x;
- }
- position.y += y;
- }
- public void setPosition(float x, float y, float z) {
- this.position.x = x;
- this.position.y = y;
- this.position.z = z;
- }
- public void moveRotation(float x, float y, float z) {
- this.rotation.x += x;
- this.rotation.y += y;
- this.rotation.z += z;
- }
- public void setRotation(float x, float y, float z) {
- this.rotation.x = x;
- this.rotation.y = y;
- this.rotation.z = z;
- }
- public Vector3f getPosition() {
- return position;
- }
- public Vector3f getRotation() {
- return rotation;
- }
- }
- class MouseInput {
- private final Vector2d previousPos, currentPos;
- private final Vector2f displVec;
- private boolean inWindow = false, leftButtonPress = false, rightButtonPress = false;
- public MouseInput() {
- previousPos = new Vector2d(-1, -1);
- currentPos = new Vector2d(0, 0);
- displVec = new Vector2f();
- }
- public void init() {
- glfwSetInputMode(Client.getDisplay().getWindow(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- GLFW.glfwSetCursorPosCallback(Client.getDisplay().getWindow(), (window, xpos, ypos) -> {
- currentPos.x = xpos;
- currentPos.y = ypos;
- });
- GLFW.glfwSetCursorEnterCallback(Client.getDisplay().getWindow(), (window, entered) -> {
- inWindow = entered;
- });
- GLFW.glfwSetMouseButtonCallback(Client.getDisplay().getWindow(), (window, button, action, mods) -> {
- leftButtonPress = button == GLFW.GLFW_MOUSE_BUTTON_1 && action == GLFW.GLFW_PRESS;
- rightButtonPress = button == GLFW.GLFW_MOUSE_BUTTON_2 && action == GLFW.GLFW_PRESS;
- });
- }
- public void input() {
- if (Client.getDisplay().isInWindow()) {
- displVec.x = 0;
- displVec.y = 0;
- double x = currentPos.x - previousPos.x;
- double y = currentPos.y - previousPos.y;
- boolean rotateX = x != 0;
- boolean rotateY = x != 0;
- if (rotateX) {
- displVec.y = (float) -x;
- }
- if (rotateY) {
- displVec.x = (float) y;
- }
- previousPos.x = currentPos.x;
- previousPos.y = currentPos.y;
- }
- }
- public Vector2f getDisplVec() {
- return displVec;
- }
- public boolean isLeftButtonPress() {
- return leftButtonPress;
- }
- public boolean isRightButtonPress() {
- return rightButtonPress;
- }
- public void cleanup() {
- glfwSetInputMode(Client.getDisplay().getWindow(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
- }
- }
- class DirectionalLight {
- private Vector3f color, direction;
- private float intensity;
- public DirectionalLight(Vector3f color, Vector3f direction, float intensity) {
- this.color = color;
- this.direction = direction;
- this.intensity = intensity;
- }
- public Vector3f getColor() {
- return color;
- }
- public void setColor(Vector3f color) {
- this.color = color;
- }
- public Vector3f getDirection() {
- return direction;
- }
- public void setDirection(Vector3f direction) {
- this.direction = direction;
- }
- public float getIntensity() {
- return intensity;
- }
- public void setIntensity(float intensity) {
- this.intensity = intensity;
- }
- }
- class PointLight {
- private Vector3f color, position;
- private float intensity, constant, linear, exponent;
- public PointLight(Vector3f color, Vector3f position, float intensity, float constant, float linear, float exponent) {
- this.color = color;
- this.position = position;
- this.intensity = intensity;
- this.constant = constant;
- this.linear = linear;
- this.exponent = exponent;
- }
- public PointLight(Vector3f color, Vector3f position, float intensity) {
- this(color, position, intensity, 1, 0, 0);
- }
- public Vector3f getColor() {
- return color;
- }
- public void setColor(Vector3f color) {
- this.color = color;
- }
- public Vector3f getPosition() {
- return position;
- }
- public void setPosition(Vector3f position) {
- this.position = position;
- }
- public float getIntensity() {
- return intensity;
- }
- public void setIntensity(float intensity) {
- this.intensity = intensity;
- }
- public float getConstant() {
- return constant;
- }
- public void setConstant(float constant) {
- this.constant = constant;
- }
- public float getLinear() {
- return linear;
- }
- public void setLinear(float linear) {
- this.linear = linear;
- }
- public float getExponent() {
- return exponent;
- }
- public void setExponent(float exponent) {
- this.exponent = exponent;
- }
- }
- class SpotLight {
- private PointLight pointLight;
- private Vector3f coneDirection;
- private float cutoff;
- public SpotLight(PointLight pointLight, Vector3f coneDirection, float cutoff) {
- this.pointLight = pointLight;
- this.coneDirection = coneDirection;
- this.cutoff = cutoff;
- }
- public SpotLight(SpotLight spotLight) {
- this.pointLight = spotLight.getPointLight();
- this.coneDirection = spotLight.getConeDirection();
- setCutoff(spotLight.getCutoff());
- }
- public PointLight getPointLight() {
- return pointLight;
- }
- public void setPointLight(PointLight pointLight) {
- this.pointLight = pointLight;
- }
- public Vector3f getConeDirection() {
- return coneDirection;
- }
- public void setConeDirection(Vector3f coneDirection) {
- this.coneDirection = coneDirection;
- }
- public float getCutoff() {
- return cutoff;
- }
- public void setCutoff(float cutoff) {
- this.cutoff = cutoff;
- }
- }
- class FileUtils {
- public static FloatBuffer storeDataInFloatBuffer(float[] data) {
- FloatBuffer buffer = MemoryUtil.memAllocFloat(data.length);
- buffer.put(data).flip();
- return buffer;
- }
- public static IntBuffer storeDataInIntBuffer(int[] data) {
- IntBuffer buffer = MemoryUtil.memAllocInt(data.length);
- buffer.put(data).flip();
- return buffer;
- }
- public static String loadResource(String filename) throws Exception {
- String result;
- try (InputStream in = Run.class.getResourceAsStream(filename); Scanner scanner = new Scanner(in, StandardCharsets.UTF_8)) {
- result = scanner.useDelimiter("\\A").next();
- }
- return result;
- }
- public static List<String> readAllLines(String filename) throws IOException {
- return Files.readAllLines(Paths.get(filename));
- }
- public static void writeToFile(String filename, List<String> data) {
- try (BufferedWriter bw = new BufferedWriter(new FileWriter(filename))) {
- for (String line : data) {
- bw.write(line);
- bw.newLine();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void newLine(String filename) throws IOException {
- writeToFile(filename, new ArrayList<>() {{
- addAll(readAllLines(filename));
- add("|");
- }});
- }
- }
- class TransformationUtils {
- public static Matrix4f createTransformationMatrix(Entity entity) {
- Matrix4f matrix = new Matrix4f();
- matrix.identity().translate(entity.pos()).
- rotateX((float) Math.toRadians(entity.rotation().x)).
- rotateY((float) Math.toRadians(entity.rotation().y)).
- rotateZ((float) Math.toRadians(entity.rotation().z)).
- scale(entity.scale());
- return matrix;
- }
- public static Matrix4f getViewMatrix(Camera camera) {
- Vector3f pos = camera.getPosition();
- Vector3f rot = camera.getRotation();
- Matrix4f matrix = new Matrix4f();
- matrix.identity();
- matrix
- .rotate((float) Math.toRadians(rot.x), new Vector3f(1, 0, 0))
- .rotate((float) Math.toRadians(rot.y), new Vector3f(0, 1, 0))
- .rotate((float) Math.toRadians(rot.z), new Vector3f(0, 0, 1));
- matrix.translate(-pos.x, -pos.y, -pos.z);
- return matrix;
- }
- }
- class Server {
- public Vector3f ambientLight = new Vector3f(0.3f, 0.3f, 0.3f);
- public Vector4f defaultColor = new Vector4f(1.0f, 1.0f, 1.0f, 1.0f);
- public Map<String, Model> models = new HashMap<>(){{
- put("cube", new Model(
- new float[]{
- -0.5f, 0.5f, 0.5f,
- -0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
- -0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- -0.5f, -0.5f, 0.5f,
- -0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- -0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f
- },
- new float[]{
- 0.0f, 0.0f,
- 0.0f, 0.5f,
- 0.5f, 0.5f,
- 0.5f, 0.0f,
- 0.0f, 0.0f,
- 0.5f, 0.0f,
- 0.0f, 0.5f,
- 0.5f, 0.5f,
- 0.0f, 0.5f,
- 0.5f, 0.5f,
- 0.0f, 1.0f,
- 0.5f, 1.0f,
- 0.0f, 0.0f,
- 0.0f, 0.5f,
- 0.5f, 0.0f,
- 0.5f, 0.5f,
- 0.5f, 0.0f,
- 1.0f, 0.0f,
- 0.5f, 0.5f,
- 1.0f, 0.5f
- },
- new float[]{
- 72
- },
- new int[]{
- 0, 1, 3, 3, 1, 2,
- 8, 10, 11, 9, 8, 11,
- 12, 13, 7, 5, 12, 7,
- 14, 15, 6, 4, 14, 6,
- 16, 18, 19, 17, 16, 19,
- 4, 6, 7, 5, 4, 7
- }, new ArrayList<>(){{
- add(new Vector3f(0.5f, 0.5f, 0.5f));
- add(new Vector3f(-0.5f, -0.5f, -0.5f));
- }}));
- }};
- public World world = new World("test", new Box(new Vector3f(3, 3, 3), new Vector3f(-3, -3, -3)));
- public List<Entity> blocks = world.getEntities();
- public float specularPower = 10f;
- }
- class World {
- private String name;
- private List<Entity> entities = new ArrayList<>();
- public World(String name, Box box) {
- this.name = name;
- for (float x = 0; x < box.a().x() - box.b().x(); x++) {
- for (float y = 0; x < box.a().y() - box.b().y(); y++) {
- for (float z = 0; z < box.a().z() - box.b().z(); z++) {
- final int type;
- float posY = Math.max(box.a().y(), box.b().y());
- float negY = Math.min(box.a().y(), box.b().y());
- Vector3f pos = new Vector3f(x, y, z);
- if (y == posY) {
- type = 0;
- } else if (y < posY) {
- type = 1;
- } else if (y >= negY) {
- type = 2;
- } else {
- type = 0;
- }
- entities.add(new Entity(Client.getServer().models.get("cube"), new Vector3f(x, y, z), new Vector3f(0, 0, 0), 1f, new HashMap<>(){{put("type", type);}}));
- }
- }
- }
- }
- public List<Entity> getEntities() {
- return entities;
- }
- }
- record Box(Vector3f a, Vector3f b) {}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement