Advertisement
Guest User

(reddit) https://www.reddit.com/r/javahelp/comments/17azphj/stupid_error_with_lwjgl_333/

a guest
Oct 18th, 2023
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 45.42 KB | None | 0 0
  1. import org.joml.*;
  2. import org.lwjgl.glfw.GLFW;
  3. import org.lwjgl.glfw.GLFWErrorCallback;
  4. import org.lwjgl.glfw.GLFWVidMode;
  5. import org.lwjgl.opengl.*;
  6. import org.lwjgl.stb.STBImage;
  7. import org.lwjgl.system.MemoryStack;
  8. import org.lwjgl.system.MemoryUtil;
  9.  
  10. import java.io.BufferedWriter;
  11. import java.io.FileWriter;
  12. import java.io.IOException;
  13. import java.io.InputStream;
  14. import java.lang.Math;
  15. import java.nio.ByteBuffer;
  16. import java.nio.FloatBuffer;
  17. import java.nio.IntBuffer;
  18. import java.nio.charset.StandardCharsets;
  19. import java.nio.file.Files;
  20. import java.nio.file.Paths;
  21. import java.util.*;
  22.  
  23. import static org.lwjgl.glfw.GLFW.*;
  24. import static org.lwjgl.opengl.GL.*;
  25. import static org.lwjgl.opengl.GL11.*;
  26.  
  27. class Run {
  28.     public static void main(String[] args) throws Exception {
  29.         Client.init();
  30.     }
  31. }
  32.  
  33. class Client {
  34.     private static Display display;
  35.     private static Server server = new Server();
  36.  
  37.     public static void init() throws Exception {
  38.         display = new Display();
  39.  
  40.         if (Vars.singleplayer) {
  41.             server = new Server();
  42.         }
  43.  
  44.         while (!glfwWindowShouldClose(display.getWindow())) {
  45.             display.update();
  46.         }
  47.  
  48.         display.cleanup();
  49.     }
  50.  
  51.     public static Display getDisplay() {
  52.         return display;
  53.     }
  54.  
  55.     public static Server getServer() {
  56.         return server;
  57.     }
  58.  
  59.     public static class Vars {
  60.         public static boolean singleplayer = true, vSync = false;
  61.     }
  62. }
  63.  
  64. class Display {
  65.     private final float FOV = (float) Math.toRadians(60), Z_NEAR = 0.01f, Z_FAR = 1000f;
  66.     private final String title = "Project Negative";
  67.     private static long window;
  68.     private boolean fullscreen = false, inWindow = true;
  69.     private int width = 1280, height = 800, cullMethod = -1;
  70.     private Matrix4f projectionMatrix = new Matrix4f();
  71.     private Shader shader;
  72.     private Vector4f backgroundColor;
  73.  
  74.     public Display() throws Exception {
  75.         windowInit();
  76.         renderInit();
  77.     }
  78.  
  79.     public void windowInit() {
  80.         GLFWErrorCallback.createPrint(System.err).set();
  81.  
  82.         if (!glfwInit()) {
  83.             throw new IllegalStateException("Unable to initialize GLFW");
  84.         }
  85.  
  86.         glfwDefaultWindowHints();
  87.         glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
  88.         glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
  89.         glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  90.         glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  91.         glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  92.         glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  93.  
  94.         if (fullscreen) {
  95.             glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
  96.         }
  97.  
  98.         window = glfwCreateWindow(width, height, title, MemoryUtil.NULL, MemoryUtil.NULL);
  99.  
  100.         if (window == MemoryUtil.NULL) {
  101.             throw new RuntimeException("Failed to create GLFW window");
  102.         }
  103.  
  104.         glfwSetFramebufferSizeCallback(window, (window, width, height) -> {
  105.             this.width = width;
  106.             this.height = height;
  107.         });
  108.  
  109.         glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
  110.             if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
  111.                 glfwSetWindowShouldClose(window, true);
  112.             }
  113.  
  114.             if (key == GLFW_KEY_R && action == GLFW_PRESS) {
  115.                 glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
  116.                 inWindow = false;
  117.             }
  118.  
  119.             if (key == GLFW_KEY_G && action == GLFW_PRESS) {
  120.                 glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
  121.                 inWindow = true;
  122.             }
  123.         });
  124.  
  125.         if (fullscreen) {
  126.             glfwMaximizeWindow(window);
  127.         } else {
  128.             GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
  129.             glfwSetWindowPos(window, (vidMode.width() - width) / 2, (vidMode.height() - height) / 2);
  130.         }
  131.  
  132.         glfwMakeContextCurrent(window);
  133.  
  134.         if (Client.Vars.vSync) {
  135.             glfwSwapInterval(1);
  136.         }
  137.  
  138.         glfwShowWindow(window);
  139.         createCapabilities();
  140.  
  141.         glEnable(GL_DEPTH_TEST);
  142.         glEnable(GL_STENCIL_TEST);
  143.         if (cullMethod != -1) {
  144.             glEnable(GL_CULL_FACE);
  145.             glCullFace(cullMethod);
  146.         }
  147.     }
  148.  
  149.     public void renderInit() throws Exception {
  150.         shader = new Shader();
  151.         shader.createVertexShader(FileUtils.loadResource("/shaders/vertex.vs"));
  152.         shader.createFragmentShader(FileUtils.loadResource("/shaders/fragment.fs"));
  153.         shader.link();
  154.         shader.createUniform("textureSampler");
  155.         shader.createUniform("transformationMatrix");
  156.         shader.createUniform("projectionMatrix");
  157.         shader.createUniform("viewMatrix");
  158.         shader.createUniform("ambientLight");
  159.         shader.createMaterialUniform("material");
  160.         shader.createUniform("specularPower");
  161.         shader.createDirectionalLightUniform("directionalLight");
  162.         shader.createPointLightListUniform("pointLights", 5);
  163.         shader.createSpotLightListUniform("spotLights", 5);
  164.     }
  165.  
  166.     public long getWindow() {
  167.         return window;
  168.     }
  169.  
  170.     public void update() {
  171.         glfwSwapBuffers(window);
  172.         glfwPollEvents();
  173.     }
  174.  
  175.     public void cleanup() {
  176.         glfwDestroyWindow(window);
  177.     }
  178.  
  179.     public boolean isKeyPressed(int keycode) {
  180.         return org.lwjgl.glfw.GLFW.glfwGetKey(window, keycode) == GLFW.GLFW_PRESS;
  181.     }
  182.  
  183.     public boolean isInWindow() {
  184.         return inWindow;
  185.     }
  186.  
  187.     public Matrix4f updateProjectionMatrix() {
  188.         float aspectRatio = (float) width / height;
  189.         return projectionMatrix.setPerspective(FOV, aspectRatio, Z_NEAR, Z_FAR);
  190.     }
  191. }
  192.  
  193. class Render {
  194.     private final Display display;
  195.     private Shader shader;
  196.  
  197.     private final Map<Model, List<Entity>> entities = new HashMap<>();
  198.  
  199.     public Render() {
  200.         display = Client.getDisplay();
  201.     }
  202.  
  203.     public void init() throws Exception {
  204.         shader = new Shader();
  205.         shader.createVertexShader(FileUtils.loadResource("/shaders/vertex.vs"));
  206.         shader.createFragmentShader(FileUtils.loadResource("/shaders/fragment.fs"));
  207.         shader.link();
  208.         shader.createUniform("textureSampler");
  209.         shader.createUniform("transformationMatrix");
  210.         shader.createUniform("projectionMatrix");
  211.         shader.createUniform("viewMatrix");
  212.         shader.createUniform("ambientLight");
  213.         shader.createMaterialUniform("material");
  214.         shader.createUniform("specularPower");
  215.         shader.createDirectionalLightUniform("directionalLight");
  216.         shader.createPointLightListUniform("pointLights", 5);
  217.         shader.createSpotLightListUniform("spotLights", 5);
  218.     }
  219.  
  220.     public void bind(Model model) {
  221.         GL30.glBindVertexArray(model.getId());
  222.         GL20.glEnableVertexAttribArray(0);
  223.         GL20.glEnableVertexAttribArray(1);
  224.         GL20.glEnableVertexAttribArray(2);
  225.         shader.setUniform("material", model.getMaterial());
  226.         GL13.glActiveTexture(GL13.GL_TEXTURE0);
  227.         GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexture().id());
  228.     }
  229.  
  230.     public void unbind() {
  231.         GL20.glDisableVertexAttribArray(0);
  232.         GL20.glDisableVertexAttribArray(1);
  233.         GL20.glDisableVertexAttribArray(2);
  234.         GL30.glBindVertexArray(0);
  235.     }
  236.  
  237.     public void prepare(Entity entity, Camera camera) {
  238.         shader.setUniform("textureSampler", 0);
  239.         shader.setUniform("transformationMatrix", TransformationUtils.createTransformationMatrix(entity));
  240.         shader.setUniform("viewMatrix", TransformationUtils.getViewMatrix(camera));
  241.     }
  242.  
  243.     public void renderLights(Camera camera, DirectionalLight directionalLight, PointLight[] pointLights, SpotLight[] spotLights) {
  244.         shader.setUniform("ambientLight", Client.getServer().ambientLight);
  245.         shader.setUniform("specularPower", Client.getServer().specularPower);
  246.  
  247.         int numLights = spotLights != null ? spotLights.length : 0;
  248.  
  249.         for (int i = 0; i < numLights; i++) {
  250.             shader.setUniform("spotLights", spotLights[i], i);
  251.         }
  252.  
  253.         numLights = pointLights != null ? pointLights.length : 0;
  254.  
  255.         for (int i = 0; i < numLights; i++) {
  256.             shader.setUniform("pointLights", pointLights[i], i);
  257.         }
  258.  
  259.         shader.setUniform("directionalLight", directionalLight);
  260.     }
  261.  
  262.     public void render(Camera camera, DirectionalLight directionalLight, PointLight[] pointLights, SpotLight[] spotLights) {
  263.         clear();
  264.  
  265.         shader.bind();
  266.         shader.setUniform("projectionMatrix", display.updateProjectionMatrix());
  267.         renderLights(camera, directionalLight, pointLights, spotLights);
  268.  
  269.         for (Model model : entities.keySet()) {
  270.             bind(model);
  271.             List<Entity> entityList = entities.get(model);
  272.  
  273.             for (Entity entity : entityList) {
  274.                 prepare(entity, camera);
  275.                 GL11.glDrawElements(GL11.GL_TRIANGLES, entity.model().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
  276.             }
  277.  
  278.             unbind();
  279.         }
  280.  
  281.         entities.clear();
  282.         shader.unbind();
  283.     }
  284.  
  285.     public void processEntity(Entity entity) {
  286.         List<Entity> entityList = entities.get(entity.model());
  287.  
  288.         if (entityList != null) {
  289.             entityList.add(entity);
  290.         } else {
  291.             List<Entity> newEntityList = new ArrayList<>();
  292.             newEntityList.add(entity);
  293.             entities.put(entity.model(), newEntityList);
  294.         }
  295.     }
  296.  
  297.     public void clear() {
  298.         GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
  299.     }
  300.  
  301.     public void cleanup() {
  302.         shader.cleanup();
  303.     }
  304. }
  305.  
  306. class Shader {
  307.     private final int programID;
  308.     private int vertexShaderID, fragmentShaderID;
  309.     private final Map<String, Integer> uniforms;
  310.  
  311.     public Shader() throws Exception {
  312.         programID = GL20.glCreateProgram();
  313.         if (programID == 0) {
  314.             throw new Exception("Could not create shader");
  315.         }
  316.  
  317.         uniforms = new HashMap<>();
  318.     }
  319.  
  320.     public void createUniform(String uniformName) throws Exception {
  321.         int uniformLocation = GL20.glGetUniformLocation(programID, uniformName);
  322.  
  323.         if (uniformLocation < 0) {
  324.             throw new Exception("Could not find uniform " + uniformName);
  325.         }
  326.  
  327.         uniforms.put(uniformName, uniformLocation);
  328.     }
  329.  
  330.     public void createDirectionalLightUniform(String uniformName) throws Exception {
  331.         createUniform(uniformName + ".color");
  332.         createUniform(uniformName + ".direction");
  333.         createUniform(uniformName + ".intensity");
  334.     }
  335.  
  336.     public void createMaterialUniform(String uniformName) throws Exception {
  337.         createUniform(uniformName + ".ambient");
  338.         createUniform(uniformName + ".diffuse");
  339.         createUniform(uniformName + ".specular");
  340.         createUniform(uniformName + ".hasTexture");
  341.         createUniform(uniformName + ".reflectance");
  342.     }
  343.  
  344.     public void createPointLightUniform(String uniformName) throws Exception {
  345.         createUniform(uniformName + ".color");
  346.         createUniform(uniformName + ".position");
  347.         createUniform(uniformName + ".intensity");
  348.         createUniform(uniformName + ".constant");
  349.         createUniform(uniformName + ".linear");
  350.         createUniform(uniformName + ".exponent");
  351.     }
  352.  
  353.     public void createPointLightListUniform(String uniformName, int size) throws Exception {
  354.         for (int i = 0; i < size; i++) {
  355.             createPointLightUniform(uniformName + "[" + i + "]");
  356.         }
  357.     }
  358.  
  359.     public void createSpotLightListUniform(String uniformName, int size) throws Exception {
  360.         for (int i = 0; i < size; i++) {
  361.             createSpotLightUniform(uniformName + "[" + i + "]");
  362.         }
  363.     }
  364.  
  365.     public void createSpotLightUniform(String uniformName) throws Exception {
  366.         createPointLightUniform(uniformName + ".pl");
  367.         createUniform(uniformName + ".conedir");
  368.         createUniform(uniformName + ".cutoff");
  369.     }
  370.  
  371.     public void setUniform(String uniformName, boolean value) {
  372.         float res = 0;
  373.  
  374.         if (value) {
  375.             res = 1;
  376.         }
  377.  
  378.         GL20.glUniform1f(uniforms.get(uniformName), res);
  379.     }
  380.  
  381.     public void setUniform(String uniformName, Matrix4f value) {
  382.         try (MemoryStack stack = MemoryStack.stackPush()) {
  383.             GL20.glUniformMatrix4fv(uniforms.get(uniformName), false, value.get(stack.mallocFloat(16)));
  384.         }
  385.     }
  386.  
  387.     public void setUniform(String uniformName, Vector4f value) {
  388.         GL20.glUniform4f(uniforms.get(uniformName), value.x, value.y, value.z, value.w);
  389.     }
  390.  
  391.     public void setUniform(String uniformName, Vector3f value) {
  392.         GL20.glUniform3f(uniforms.get(uniformName), value.x, value.y, value.z);
  393.     }
  394.  
  395.     public void setUniform(String uniformName, int value) {
  396.         GL20.glUniform1i(uniforms.get(uniformName), value);
  397.     }
  398.  
  399.     public void setUniform(String uniformName, float value) {
  400.         GL20.glUniform1f(uniforms.get(uniformName), value);
  401.     }
  402.  
  403.     public void setUniform(String uniformName, Material material) {
  404.         setUniform(uniformName + ".ambient", material.getAmbientColor());
  405.         setUniform(uniformName + ".diffuse", material.getDiffuseColor());
  406.         setUniform(uniformName + ".specular", material.getSpecularColor());
  407.         setUniform(uniformName + ".hasTexture", material.hasTexture() ? 1 : 0);
  408.         setUniform(uniformName + ".reflectance", material.getReflectance());
  409.     }
  410.  
  411.     public void setUniform(String uniformName, DirectionalLight directionalLight) {
  412.         setUniform(uniformName + ".color", directionalLight.getColor());
  413.         setUniform(uniformName + ".direction", directionalLight.getDirection());
  414.         setUniform(uniformName + ".intensity", directionalLight.getIntensity());
  415.     }
  416.  
  417.     public void setUniform(String uniformName, PointLight pointLight) {
  418.         setUniform(uniformName + ".color", pointLight.getColor());
  419.         setUniform(uniformName + ".position", pointLight.getPosition());
  420.         setUniform(uniformName + ".intensity", pointLight.getIntensity());
  421.         setUniform(uniformName + ".constant", pointLight.getConstant());
  422.         setUniform(uniformName + ".linear", pointLight.getLinear());
  423.         setUniform(uniformName + ".exponent", pointLight.getExponent());
  424.     }
  425.  
  426.     public void setUniform(String uniformName, SpotLight spotLight) {
  427.         setUniform(uniformName + ".pl", spotLight.getPointLight());
  428.         setUniform(uniformName + ".conedir", spotLight.getConeDirection());
  429.         setUniform(uniformName + ".cutoff", spotLight.getCutoff());
  430.     }
  431.  
  432.     public void setUniform(String uniformName, PointLight[] pointLights) {
  433.         int numLights = pointLights != null ? pointLights.length : 0;
  434.  
  435.         for (int i = 0; i < numLights; i++) {
  436.             setUniform(uniformName, pointLights[i], i);
  437.         }
  438.     }
  439.  
  440.     public void setUniform(String uniformName, PointLight pointLight, int pos) {
  441.         setUniform(uniformName + "[" + pos + "]", pointLight);
  442.     }
  443.  
  444.     public void setUniform(String uniformName, SpotLight[] spotLights) {
  445.         int numLights = spotLights != null ? spotLights.length : 0;
  446.  
  447.         for (int i = 0; i < numLights; i++) {
  448.             setUniform(uniformName, spotLights[i], i);
  449.         }
  450.     }
  451.  
  452.     public void setUniform(String uniformName, SpotLight spotLight, int pos) {
  453.         setUniform(uniformName + "[" + pos + "]", spotLight);
  454.     }
  455.  
  456.     public void createVertexShader(String shaderCode) throws Exception {
  457.         vertexShaderID = createShader(shaderCode, GL20.GL_VERTEX_SHADER);
  458.     }
  459.  
  460.     public void createFragmentShader(String shaderCode) throws Exception {
  461.         fragmentShaderID = createShader(shaderCode, GL20.GL_FRAGMENT_SHADER);
  462.     }
  463.  
  464.     public int createShader(String shaderCode, int shaderType) throws Exception {
  465.         int shaderId = GL20.glCreateShader(shaderType);
  466.  
  467.         if (shaderId == 0) {
  468.             throw new Exception("Error creating shader of type " + shaderType);
  469.         }
  470.  
  471.         GL20.glShaderSource(shaderId, shaderCode);
  472.         GL20.glCompileShader(shaderId);
  473.  
  474.         if (GL20.glGetShaderi(shaderId, GL20.GL_COMPILE_STATUS) == 0) {
  475.             throw new Exception("Error compiling shader code of type " + shaderType + " Info: " + GL20.glGetShaderInfoLog(shaderId, 1024));
  476.         }
  477.  
  478.         GL20.glAttachShader(programID, shaderId);
  479.  
  480.         return shaderId;
  481.     }
  482.  
  483.     public void link() throws Exception {
  484.         GL20.glLinkProgram(programID);
  485.         //if (GL20.glGetShaderi(programID, GL20.GL_LINK_STATUS) == 0) {
  486.         //    throw new Exception("Error linking shader code Info: " + GL20.glGetProgramInfoLog(programID, 1024));
  487.         //}
  488.         // Program worked fine without this, may cause issues in the future.
  489.  
  490.         if (vertexShaderID != 0) {
  491.             GL20.glDetachShader(programID, vertexShaderID);
  492.         }
  493.  
  494.         if (fragmentShaderID != 0) {
  495.             GL20.glDetachShader(programID, fragmentShaderID);
  496.         }
  497.  
  498.         GL20.glValidateProgram(programID);
  499.  
  500.         if (GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS) == 0) {
  501.             throw new Exception("Unable to validate shader code " + GL20.glGetProgramInfoLog(programID, 1024));
  502.         }
  503.     }
  504.  
  505.     public void bind() {
  506.         GL20.glUseProgram(programID);
  507.     }
  508.  
  509.     public void unbind() {
  510.         GL20.glUseProgram(programID);
  511.     }
  512.  
  513.     public void cleanup() {
  514.         unbind();
  515.  
  516.         if (programID != 0) {
  517.             GL20.glDeleteProgram(programID);
  518.         }
  519.     }
  520. }
  521.  
  522. record Entity(Model model, Vector3f pos, Vector3f rotation, float scale, Map<String, Object> data) {
  523.     public void incPos(float x, float y, float z) {
  524.         this.pos.x += x;
  525.         this.pos.y += y;
  526.         this.pos.z += z;
  527.     }
  528.  
  529.     public void setPos(float x, float y, float z) {
  530.         this.pos.x = x;
  531.         this.pos.y = y;
  532.         this.pos.z = z;
  533.     }
  534.  
  535.     public void incRotation(float x, float y, float z) {
  536.         this.rotation.x += x;
  537.         this.rotation.y += y;
  538.         this.rotation.z += z;
  539.     }
  540.  
  541.     public void setRotation(float x, float y, float z) {
  542.         this.rotation.x += x;
  543.         this.rotation.y += y;
  544.         this.rotation.z += z;
  545.     }
  546. }
  547.  
  548. class Material {
  549.     private Vector4f ambientColor, diffuseColor, specularColor;
  550.     private float reflectance;
  551.     private Texture texture;
  552.  
  553.     public Material() {
  554.         this.ambientColor = Client.getServer().defaultColor;
  555.         this.diffuseColor = Client.getServer().defaultColor;
  556.         this.specularColor = Client.getServer().defaultColor;
  557.         this.reflectance = 0;
  558.         this.texture = null;
  559.     }
  560.  
  561.     public Material(Vector4f color, float reflectance) {
  562.         this(color, color, color, reflectance, null);
  563.     }
  564.  
  565.     public Material(Vector4f color, float reflectance, Texture texture) {
  566.         this(color, color, color, reflectance, texture);
  567.     }
  568.  
  569.     public Material(Texture texture) {
  570.         this(Client.getServer().defaultColor, Client.getServer().defaultColor, Client.getServer().defaultColor, 0, texture);
  571.     }
  572.  
  573.     public Material(Vector4f ambientColor, Vector4f diffuseColor, Vector4f specularColor, float reflectance, Texture texture) {
  574.         this.ambientColor = ambientColor;
  575.         this.diffuseColor = diffuseColor;
  576.         this.specularColor = specularColor;
  577.         this.reflectance = reflectance;
  578.         this.texture = texture;
  579.     }
  580.  
  581.     public Vector4f getAmbientColor() {
  582.         return ambientColor;
  583.     }
  584.  
  585.     public void setAmbientColor(Vector4f ambientColor) {
  586.         this.ambientColor = ambientColor;
  587.     }
  588.  
  589.     public Vector4f getDiffuseColor() {
  590.         return diffuseColor;
  591.     }
  592.  
  593.     public void setDiffuseColor(Vector4f diffuseColor) {
  594.         this.diffuseColor = diffuseColor;
  595.     }
  596.  
  597.     public Vector4f getSpecularColor() {
  598.         return specularColor;
  599.     }
  600.  
  601.     public void setSpecularColor(Vector4f specularColor) {
  602.         this.specularColor = specularColor;
  603.     }
  604.  
  605.     public float getReflectance() {
  606.         return reflectance;
  607.     }
  608.  
  609.     public void setReflectance(float reflectance) {
  610.         this.reflectance = reflectance;
  611.     }
  612.  
  613.     public Texture getTexture() {
  614.         return texture;
  615.     }
  616.  
  617.     public void setTexture(Texture texture) {
  618.         this.texture = texture;
  619.     }
  620.  
  621.     public boolean hasTexture() {
  622.         return texture != null;
  623.     }
  624. }
  625.  
  626. record Texture(int id) {}
  627.  
  628. class Model {
  629.     private final int id;
  630.     private final int vertexCount;
  631.     private Material material;
  632.     private float[] vertices, texCoords, normals;
  633.     private int[] indices;
  634.     private List<Vector3f> boundingBox;
  635.  
  636.     public Model(int id, int vertexCount) {
  637.         this.id = id;
  638.         this.vertexCount = vertexCount;
  639.         this.material = new Material();
  640.     }
  641.  
  642.     public Model(int id, int vertexCount, Texture texture) {
  643.         this.id = id;
  644.         this.vertexCount = vertexCount;
  645.         this.material = new Material(texture);
  646.     }
  647.  
  648.     public Model(Model model, Texture texture) {
  649.         this.id = model.getId();
  650.         this.vertexCount = model.getVertexCount();
  651.         this.material = model.getMaterial();
  652.         this.material.setTexture(texture);
  653.     }
  654.  
  655.     public Model(float[] vertices, float[] texCoords, float[] normals, int[] indices, List<Vector3f> boundingBox) {
  656.         ObjectLoader loader = new ObjectLoader();
  657.         this.vertices = vertices;
  658.         this.texCoords = texCoords;
  659.         this.normals = normals;
  660.         this.indices = indices;
  661.         this.boundingBox = boundingBox;
  662.         this.id = loader.createVAO();
  663.         loader.storeIndiciesBuffer(indices);
  664.         loader.storeDataInAttributes(0, 3, vertices);
  665.         loader.storeDataInAttributes(1, 2, texCoords);
  666.         loader.storeDataInAttributes(2, 3, normals);
  667.         loader.unbind();
  668.         this.vertexCount = indices.length;
  669.         this.material = new Material();
  670.     }
  671.  
  672.     public Model(Model model) {
  673.         ObjectLoader loader = new ObjectLoader();
  674.         this.vertices = model.vertices;
  675.         this.texCoords = model.texCoords;
  676.         this.normals = model.normals;
  677.         this.indices = model.indices;
  678.         this.id = loader.createVAO();
  679.         loader.storeIndiciesBuffer(indices);
  680.         loader.storeDataInAttributes(0, 3, vertices);
  681.         loader.storeDataInAttributes(1, 2, texCoords);
  682.         loader.storeDataInAttributes(2, 3, normals);
  683.         loader.unbind();
  684.         this.vertexCount = indices.length;
  685.         this.material = new Material();
  686.     }
  687.  
  688.     public int getId() {
  689.         return id;
  690.     }
  691.  
  692.     public int getVertexCount() {
  693.         return vertexCount;
  694.     }
  695.  
  696.     public Material getMaterial() {
  697.         return material;
  698.     }
  699.  
  700.     public void setMaterial(Material material) {
  701.         this.material = material;
  702.     }
  703.  
  704.     public Texture getTexture() {
  705.         return material.getTexture();
  706.     }
  707.  
  708.     public void setTexture(Texture texture) {
  709.         material.setTexture(texture);
  710.     }
  711.  
  712.     public void setTexture(Texture texture, float reflectance) {
  713.         this.material.setTexture(texture);
  714.         this.material.setReflectance(reflectance);
  715.     }
  716.  
  717.     public float[] getVertices() {
  718.         return vertices;
  719.     }
  720.  
  721.     public void setVertices(float[] vertices) {
  722.         this.vertices = vertices;
  723.     }
  724.  
  725.     public float[] getTexCoords() {
  726.         return texCoords;
  727.     }
  728.  
  729.     public void setTexCoords(float[] texCoords) {
  730.         this.texCoords = texCoords;
  731.     }
  732.  
  733.     public float[] getNormals() {
  734.         return normals;
  735.     }
  736.  
  737.     public void setNormals(float[] normals) {
  738.         this.normals = normals;
  739.     }
  740.  
  741.     public int[] getIndices() {
  742.         return indices;
  743.     }
  744.  
  745.     public void setIndices(int[] indices) {
  746.         this.indices = indices;
  747.     }
  748.  
  749.     public List<Vector3f> getBoundingBox() {
  750.         return boundingBox;
  751.     }
  752. }
  753.  
  754. class ObjectLoader {
  755.     private final List<Integer> vaos = new ArrayList<>();
  756.     private final List<Integer> vbos = new ArrayList<>();
  757.     private final List<Integer> textures = new ArrayList<>();
  758.  
  759.     /*
  760.     public Model loadModel(String filename) throws IOException {
  761.         List<Vector3f> vertices = new ArrayList<>();
  762.         List<Vector2f> textureCoords = new ArrayList<>();
  763.         List<Integer> indices = new ArrayList<>();
  764.  
  765.         List<String> lines = Utils.readAllLines(filename);
  766.  
  767.         for (String line : lines) {
  768.             String[] parts = line.split(" ");
  769.  
  770.             if (parts[0].equals("v")) {
  771.                 float[] vertex = new float[3];
  772.                 vertex[0] = Float.parseFloat(parts[1]);
  773.                 vertex[1] = Float.parseFloat(parts[2]);
  774.                 vertex[2] = Float.parseFloat(parts[3]);
  775.                 vertices.add(vertex);
  776.             } else if (parts[0].equals("tC")) {
  777.                 float[] texCoord = new float[2];
  778.                 texCoord[0] = Float.parseFloat(parts[1]);
  779.                 texCoord[1] = Float.parseFloat(parts[2]);
  780.                 textureCoords.add(texCoord);
  781.             } else if (parts[0].equals("i")) {
  782.                 int[] index = new int[6];
  783.                 index[0] = Integer.parseInt(parts[1]);
  784.                 index[1] = Integer.parseInt(parts[2]);
  785.                 index[2] = Integer.parseInt(parts[3]);
  786.                 index[3] = Integer.parseInt(parts[4]);
  787.                 index[4] = Integer.parseInt(parts[5]);
  788.                 index[5] = Integer.parseInt(parts[6]);
  789.                 indices.add(index);
  790.             }
  791.         }
  792.  
  793.         return loadModel(vertices, textureCoords, new float[]{vertices.size() * 3}, indices);
  794.     }
  795.     */
  796.  
  797.     public Model loadOBJModel(String filename) throws IOException {
  798.         List<String> lines = FileUtils.readAllLines(filename);
  799.         List<Vector3f> verticies = new ArrayList<>();
  800.         List<Vector3f> normals = new ArrayList<>();
  801.         List<Vector2f> textures = new ArrayList<>();
  802.         List<Vector3i> faces = new ArrayList<>();
  803.  
  804.         for (String line : lines) {
  805.             String[] tokens = line.split("\\s+");
  806.  
  807.             switch (tokens[0]) {
  808.                 case "v":
  809.                     Vector3f verticiesVec = new Vector3f(
  810.                             Float.parseFloat(tokens[1]),
  811.                             Float.parseFloat(tokens[2]),
  812.                             Float.parseFloat(tokens[3])
  813.                     );
  814.                     verticies.add(verticiesVec);
  815.                     break;
  816.                 case "vt":
  817.                     Vector2f textureVec = new Vector2f(
  818.                             Float.parseFloat(tokens[1]),
  819.                             Float.parseFloat(tokens[2])
  820.                     );
  821.                     textures.add(textureVec);
  822.                     break;
  823.                 case "vn":
  824.                     Vector3f normalsVec = new Vector3f(
  825.                             Float.parseFloat(tokens[1]),
  826.                             Float.parseFloat(tokens[2]),
  827.                             Float.parseFloat(tokens[3])
  828.                     );
  829.                     normals.add(normalsVec);
  830.                     break;
  831.                 case "f":
  832.                     processFace(tokens[1], faces);
  833.                     processFace(tokens[2], faces);
  834.                     processFace(tokens[3], faces);
  835.                     break;
  836.                 default:
  837.                     break;
  838.             }
  839.         }
  840.  
  841.         List<Integer> indices = new ArrayList<>();
  842.         float[] verticiesArr = new float[verticies.size() * 3];
  843.         int i = 0;
  844.  
  845.         for (Vector3f pos : verticies) {
  846.             verticiesArr[i * 3] = pos.x;
  847.             verticiesArr[i * 3 + 1] = pos.y;
  848.             verticiesArr[i * 3 + 2] = pos.z;
  849.             i++;
  850.         }
  851.  
  852.         float[] texCoordArr = new float[verticies.size() * 2];
  853.         float[] normalArr = new float[verticies.size() * 3];
  854.  
  855.         for (Vector3i face : faces) {
  856.             processVertex(face.x, face.y, face.z, textures, normals, indices, texCoordArr, normalArr);
  857.         }
  858.  
  859.         int[] indicesArr = indices.stream().mapToInt((Integer v) -> v).toArray();
  860.  
  861.         return new Model(verticiesArr, texCoordArr, normalArr, indicesArr, new ArrayList<>());
  862.     }
  863.  
  864.     private static void processVertex(int pos, int texCoord, int normal, List<Vector2f> texCoordList, List<Vector3f> normalList, List<Integer> indicesList, float[] texCoordArr, float[] normalArr) {
  865.         indicesList.add(pos);
  866.  
  867.         if (texCoord >= 0) {
  868.             Vector2f texCoordVec = texCoordList.get(texCoord);
  869.             texCoordArr[pos * 2] = texCoordVec.x;
  870.             texCoordArr[pos * 2 + 1] = 1 - texCoordVec.y;
  871.         }
  872.  
  873.         if (normal >= 0) {
  874.             Vector3f normalVec = normalList.get(normal);
  875.             normalArr[pos * 3] = normalVec.x;
  876.             normalArr[pos * 3 + 1] = normalVec.y;
  877.             normalArr[pos * 3 + 2] = normalVec.z;
  878.         }
  879.     }
  880.  
  881.     private static void processFace(String token, List<Vector3i> faces) {
  882.         String[] lineToken = token.split("/");
  883.         int length = lineToken.length;
  884.         int pos = -1, coords = -1, normal = -1;
  885.         pos = Integer.parseInt(lineToken[0]) - 1;
  886.  
  887.         if (length > 1 && !lineToken[1].isEmpty()) {
  888.             coords = Integer.parseInt(lineToken[1]) - 1;
  889.         }
  890.  
  891.         if (length > 2 && !lineToken[2].isEmpty()) {
  892.             normal = Integer.parseInt(lineToken[2]) - 1;
  893.         }
  894.  
  895.         Vector3i facesVec = new Vector3i(pos, coords, normal);
  896.         faces.add(facesVec);
  897.     }
  898.  
  899.     /*
  900.     public Model loadModel(float[] vertices, float[] texCoords, float[] normals, int[] indices) {
  901.         int id = createVAO();
  902.         storeIndiciesBuffer(indices);
  903.         storeDataInAttributes(0, 3, vertices);
  904.         storeDataInAttributes(1, 2, texCoords);
  905.         storeDataInAttributes(2, 3, normals);
  906.         unbind();
  907.         return new Model(id, indices.length);
  908.     }
  909.     */
  910.  
  911.     public int loadTexture(String filename) throws Exception {
  912.         int width, height;
  913.         ByteBuffer buffer;
  914.  
  915.         try (MemoryStack stack = MemoryStack.stackPush()) {
  916.             IntBuffer w = stack.mallocInt(1);
  917.             IntBuffer h = stack.mallocInt(1);
  918.             IntBuffer c = stack.mallocInt(1);
  919.  
  920.             buffer = STBImage.stbi_load(filename, w, h, c, 4);
  921.  
  922.             if (buffer == null) {
  923.                 throw new Exception("Image file " + filename + " not loaded " + STBImage.stbi_failure_reason());
  924.             }
  925.  
  926.             width = w.get();
  927.             height = h.get();
  928.         }
  929.  
  930.         int id = GL11.glGenTextures();
  931.         textures.add(id);
  932.         GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
  933.         GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
  934.         GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
  935.         GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
  936.         STBImage.stbi_image_free(buffer);
  937.         return id;
  938.     }
  939.  
  940.     public int createVAO() {
  941.         int id = GL30.glGenVertexArrays();
  942.         vaos.add(id);
  943.         GL30.glBindVertexArray(id);
  944.         return id;
  945.     }
  946.  
  947.     public void storeIndiciesBuffer(int[] indices) {
  948.         int vbo = GL15.glGenBuffers();
  949.         vbos.add(vbo);
  950.         GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vbo);
  951.         IntBuffer buffer = FileUtils.storeDataInIntBuffer(indices);
  952.         GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
  953.     }
  954.  
  955.     public void storeDataInAttributes(int attribNo, int vertexCount, float[] data) {
  956.         int vbo = GL15.glGenBuffers();
  957.         vbos.add(vbo);
  958.         GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
  959.         FloatBuffer buffer = FileUtils.storeDataInFloatBuffer(data);
  960.         GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
  961.         GL20.glVertexAttribPointer(attribNo, vertexCount, GL11.GL_FLOAT, false, 0, 0);
  962.         GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
  963.     }
  964.  
  965.     public void unbind() {
  966.         GL30.glBindVertexArray(0);
  967.     }
  968.  
  969.     public void cleanup() {
  970.         for (int vao : vaos) {
  971.             GL30.glDeleteVertexArrays(vao);
  972.         }
  973.  
  974.         for (int vbo : vbos) {
  975.             GL30.glDeleteBuffers(vbo);
  976.         }
  977.  
  978.         for (int texture : textures) {
  979.             GL11.glDeleteTextures(texture);
  980.         }
  981.     }
  982. }
  983.  
  984. class Camera {
  985.     private final Vector3f position;
  986.     private final Vector3f rotation;
  987.  
  988.     public Camera() {
  989.         position = new Vector3f(0, 0, 0);
  990.         rotation = new Vector3f(0, 0, 0);
  991.     }
  992.  
  993.     public Camera(Vector3f position, Vector3f rotation) {
  994.         this.position = position;
  995.         this.rotation = rotation;
  996.     }
  997.  
  998.     public void movePosition(float x, float y, float z) {
  999.         if (z != 0) {
  1000.             position.x += (float) Math.sin(Math.toRadians(rotation.y)) * -1.0f * z;
  1001.             position.z += (float) Math.cos(Math.toRadians(rotation.y)) * z;
  1002.         }
  1003.  
  1004.         if (x != 0) {
  1005.             position.x += (float) Math.sin(Math.toRadians(rotation.y - 90)) * -1.0f * x;
  1006.             position.z += (float) Math.cos(Math.toRadians(rotation.y - 90)) * x;
  1007.         }
  1008.  
  1009.         position.y += y;
  1010.     }
  1011.  
  1012.     public void setPosition(float x, float y, float z) {
  1013.         this.position.x = x;
  1014.         this.position.y = y;
  1015.         this.position.z = z;
  1016.     }
  1017.  
  1018.     public void moveRotation(float x, float y, float z) {
  1019.         this.rotation.x += x;
  1020.         this.rotation.y += y;
  1021.         this.rotation.z += z;
  1022.     }
  1023.  
  1024.     public void setRotation(float x, float y, float z) {
  1025.         this.rotation.x = x;
  1026.         this.rotation.y = y;
  1027.         this.rotation.z = z;
  1028.     }
  1029.  
  1030.     public Vector3f getPosition() {
  1031.         return position;
  1032.     }
  1033.  
  1034.     public Vector3f getRotation() {
  1035.         return rotation;
  1036.     }
  1037. }
  1038.  
  1039. class MouseInput {
  1040.     private final Vector2d previousPos, currentPos;
  1041.     private final Vector2f displVec;
  1042.     private boolean inWindow = false, leftButtonPress = false, rightButtonPress = false;
  1043.  
  1044.     public MouseInput() {
  1045.         previousPos = new Vector2d(-1, -1);
  1046.         currentPos = new Vector2d(0, 0);
  1047.         displVec = new Vector2f();
  1048.     }
  1049.  
  1050.     public void init() {
  1051.         glfwSetInputMode(Client.getDisplay().getWindow(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
  1052.  
  1053.         GLFW.glfwSetCursorPosCallback(Client.getDisplay().getWindow(), (window, xpos, ypos) -> {
  1054.             currentPos.x = xpos;
  1055.             currentPos.y = ypos;
  1056.         });
  1057.  
  1058.         GLFW.glfwSetCursorEnterCallback(Client.getDisplay().getWindow(), (window, entered) -> {
  1059.             inWindow = entered;
  1060.         });
  1061.  
  1062.         GLFW.glfwSetMouseButtonCallback(Client.getDisplay().getWindow(), (window, button, action, mods) -> {
  1063.             leftButtonPress = button == GLFW.GLFW_MOUSE_BUTTON_1 && action == GLFW.GLFW_PRESS;
  1064.             rightButtonPress = button == GLFW.GLFW_MOUSE_BUTTON_2 && action == GLFW.GLFW_PRESS;
  1065.         });
  1066.     }
  1067.  
  1068.     public void input() {
  1069.         if (Client.getDisplay().isInWindow()) {
  1070.             displVec.x = 0;
  1071.             displVec.y = 0;
  1072.  
  1073.             double x = currentPos.x - previousPos.x;
  1074.             double y = currentPos.y - previousPos.y;
  1075.             boolean rotateX = x != 0;
  1076.             boolean rotateY = x != 0;
  1077.  
  1078.             if (rotateX) {
  1079.                 displVec.y = (float) -x;
  1080.             }
  1081.  
  1082.             if (rotateY) {
  1083.                 displVec.x = (float) y;
  1084.             }
  1085.  
  1086.             previousPos.x = currentPos.x;
  1087.             previousPos.y = currentPos.y;
  1088.         }
  1089.     }
  1090.  
  1091.     public Vector2f getDisplVec() {
  1092.         return displVec;
  1093.     }
  1094.  
  1095.     public boolean isLeftButtonPress() {
  1096.         return leftButtonPress;
  1097.     }
  1098.  
  1099.     public boolean isRightButtonPress() {
  1100.         return rightButtonPress;
  1101.     }
  1102.  
  1103.     public void cleanup() {
  1104.         glfwSetInputMode(Client.getDisplay().getWindow(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
  1105.     }
  1106. }
  1107.  
  1108. class DirectionalLight {
  1109.     private Vector3f color, direction;
  1110.     private float intensity;
  1111.  
  1112.     public DirectionalLight(Vector3f color, Vector3f direction, float intensity) {
  1113.         this.color = color;
  1114.         this.direction = direction;
  1115.         this.intensity = intensity;
  1116.     }
  1117.  
  1118.     public Vector3f getColor() {
  1119.         return color;
  1120.     }
  1121.  
  1122.     public void setColor(Vector3f color) {
  1123.         this.color = color;
  1124.     }
  1125.  
  1126.     public Vector3f getDirection() {
  1127.         return direction;
  1128.     }
  1129.  
  1130.     public void setDirection(Vector3f direction) {
  1131.         this.direction = direction;
  1132.     }
  1133.  
  1134.     public float getIntensity() {
  1135.         return intensity;
  1136.     }
  1137.  
  1138.     public void setIntensity(float intensity) {
  1139.         this.intensity = intensity;
  1140.     }
  1141. }
  1142.  
  1143. class PointLight {
  1144.     private Vector3f color, position;
  1145.     private float intensity, constant, linear, exponent;
  1146.  
  1147.     public PointLight(Vector3f color, Vector3f position, float intensity, float constant, float linear, float exponent) {
  1148.         this.color = color;
  1149.         this.position = position;
  1150.         this.intensity = intensity;
  1151.         this.constant = constant;
  1152.         this.linear = linear;
  1153.         this.exponent = exponent;
  1154.     }
  1155.  
  1156.     public PointLight(Vector3f color, Vector3f position, float intensity) {
  1157.         this(color, position, intensity, 1, 0, 0);
  1158.     }
  1159.  
  1160.     public Vector3f getColor() {
  1161.         return color;
  1162.     }
  1163.  
  1164.     public void setColor(Vector3f color) {
  1165.         this.color = color;
  1166.     }
  1167.  
  1168.     public Vector3f getPosition() {
  1169.         return position;
  1170.     }
  1171.  
  1172.     public void setPosition(Vector3f position) {
  1173.         this.position = position;
  1174.     }
  1175.  
  1176.     public float getIntensity() {
  1177.         return intensity;
  1178.     }
  1179.  
  1180.     public void setIntensity(float intensity) {
  1181.         this.intensity = intensity;
  1182.     }
  1183.  
  1184.     public float getConstant() {
  1185.         return constant;
  1186.     }
  1187.  
  1188.     public void setConstant(float constant) {
  1189.         this.constant = constant;
  1190.     }
  1191.  
  1192.     public float getLinear() {
  1193.         return linear;
  1194.     }
  1195.  
  1196.     public void setLinear(float linear) {
  1197.         this.linear = linear;
  1198.     }
  1199.  
  1200.     public float getExponent() {
  1201.         return exponent;
  1202.     }
  1203.  
  1204.     public void setExponent(float exponent) {
  1205.         this.exponent = exponent;
  1206.     }
  1207. }
  1208.  
  1209. class SpotLight {
  1210.     private PointLight pointLight;
  1211.     private Vector3f coneDirection;
  1212.     private float cutoff;
  1213.  
  1214.     public SpotLight(PointLight pointLight, Vector3f coneDirection, float cutoff) {
  1215.         this.pointLight = pointLight;
  1216.         this.coneDirection = coneDirection;
  1217.         this.cutoff = cutoff;
  1218.     }
  1219.  
  1220.     public SpotLight(SpotLight spotLight) {
  1221.         this.pointLight = spotLight.getPointLight();
  1222.         this.coneDirection = spotLight.getConeDirection();
  1223.         setCutoff(spotLight.getCutoff());
  1224.     }
  1225.  
  1226.     public PointLight getPointLight() {
  1227.         return pointLight;
  1228.     }
  1229.  
  1230.     public void setPointLight(PointLight pointLight) {
  1231.         this.pointLight = pointLight;
  1232.     }
  1233.  
  1234.     public Vector3f getConeDirection() {
  1235.         return coneDirection;
  1236.     }
  1237.  
  1238.     public void setConeDirection(Vector3f coneDirection) {
  1239.         this.coneDirection = coneDirection;
  1240.     }
  1241.  
  1242.     public float getCutoff() {
  1243.         return cutoff;
  1244.     }
  1245.  
  1246.     public void setCutoff(float cutoff) {
  1247.         this.cutoff = cutoff;
  1248.     }
  1249. }
  1250.  
  1251. class FileUtils {
  1252.     public static FloatBuffer storeDataInFloatBuffer(float[] data) {
  1253.         FloatBuffer buffer = MemoryUtil.memAllocFloat(data.length);
  1254.         buffer.put(data).flip();
  1255.         return buffer;
  1256.     }
  1257.  
  1258.     public static IntBuffer storeDataInIntBuffer(int[] data) {
  1259.         IntBuffer buffer = MemoryUtil.memAllocInt(data.length);
  1260.         buffer.put(data).flip();
  1261.         return buffer;
  1262.     }
  1263.  
  1264.     public static String loadResource(String filename) throws Exception {
  1265.         String result;
  1266.  
  1267.         try (InputStream in = Run.class.getResourceAsStream(filename); Scanner scanner = new Scanner(in, StandardCharsets.UTF_8)) {
  1268.             result = scanner.useDelimiter("\\A").next();
  1269.         }
  1270.  
  1271.         return result;
  1272.     }
  1273.  
  1274.     public static List<String> readAllLines(String filename) throws IOException {
  1275.         return Files.readAllLines(Paths.get(filename));
  1276.     }
  1277.  
  1278.     public static void writeToFile(String filename, List<String> data) {
  1279.         try (BufferedWriter bw = new BufferedWriter(new FileWriter(filename))) {
  1280.             for (String line : data) {
  1281.                 bw.write(line);
  1282.                 bw.newLine();
  1283.             }
  1284.         } catch (IOException e) {
  1285.             e.printStackTrace();
  1286.         }
  1287.     }
  1288.  
  1289.     public static void newLine(String filename) throws IOException {
  1290.         writeToFile(filename, new ArrayList<>() {{
  1291.             addAll(readAllLines(filename));
  1292.             add("|");
  1293.         }});
  1294.     }
  1295. }
  1296.  
  1297. class TransformationUtils {
  1298.     public static Matrix4f createTransformationMatrix(Entity entity) {
  1299.         Matrix4f matrix = new Matrix4f();
  1300.         matrix.identity().translate(entity.pos()).
  1301.                 rotateX((float) Math.toRadians(entity.rotation().x)).
  1302.                 rotateY((float) Math.toRadians(entity.rotation().y)).
  1303.                 rotateZ((float) Math.toRadians(entity.rotation().z)).
  1304.                 scale(entity.scale());
  1305.         return matrix;
  1306.     }
  1307.  
  1308.     public static Matrix4f getViewMatrix(Camera camera) {
  1309.         Vector3f pos = camera.getPosition();
  1310.         Vector3f rot = camera.getRotation();
  1311.         Matrix4f matrix = new Matrix4f();
  1312.         matrix.identity();
  1313.         matrix
  1314.                 .rotate((float) Math.toRadians(rot.x), new Vector3f(1, 0, 0))
  1315.                 .rotate((float) Math.toRadians(rot.y), new Vector3f(0, 1, 0))
  1316.                 .rotate((float) Math.toRadians(rot.z), new Vector3f(0, 0, 1));
  1317.         matrix.translate(-pos.x, -pos.y, -pos.z);
  1318.         return matrix;
  1319.     }
  1320. }
  1321.  
  1322. class Server {
  1323.     public Vector3f ambientLight = new Vector3f(0.3f, 0.3f, 0.3f);
  1324.     public Vector4f defaultColor = new Vector4f(1.0f, 1.0f, 1.0f, 1.0f);
  1325.     public Map<String, Model> models = new HashMap<>(){{
  1326.         put("cube", new Model(
  1327.                 new float[]{
  1328.                         -0.5f, 0.5f, 0.5f,
  1329.                         -0.5f, -0.5f, 0.5f,
  1330.                         0.5f, -0.5f, 0.5f,
  1331.                         0.5f, 0.5f, 0.5f,
  1332.                         -0.5f, 0.5f, -0.5f,
  1333.                         0.5f, 0.5f, -0.5f,
  1334.                         -0.5f, -0.5f, -0.5f,
  1335.                         0.5f, -0.5f, -0.5f,
  1336.                         -0.5f, 0.5f, -0.5f,
  1337.                         0.5f, 0.5f, -0.5f,
  1338.                         -0.5f, 0.5f, 0.5f,
  1339.                         0.5f, 0.5f, 0.5f,
  1340.                         0.5f, 0.5f, 0.5f,
  1341.                         0.5f, -0.5f, 0.5f,
  1342.                         -0.5f, 0.5f, 0.5f,
  1343.                         -0.5f, -0.5f, 0.5f,
  1344.                         -0.5f, -0.5f, -0.5f,
  1345.                         0.5f, -0.5f, -0.5f,
  1346.                         -0.5f, -0.5f, 0.5f,
  1347.                         0.5f, -0.5f, 0.5f
  1348.                 },
  1349.                 new float[]{
  1350.                         0.0f, 0.0f,
  1351.                         0.0f, 0.5f,
  1352.                         0.5f, 0.5f,
  1353.                         0.5f, 0.0f,
  1354.                         0.0f, 0.0f,
  1355.                         0.5f, 0.0f,
  1356.                         0.0f, 0.5f,
  1357.                         0.5f, 0.5f,
  1358.                         0.0f, 0.5f,
  1359.                         0.5f, 0.5f,
  1360.                         0.0f, 1.0f,
  1361.                         0.5f, 1.0f,
  1362.                         0.0f, 0.0f,
  1363.                         0.0f, 0.5f,
  1364.                         0.5f, 0.0f,
  1365.                         0.5f, 0.5f,
  1366.                         0.5f, 0.0f,
  1367.                         1.0f, 0.0f,
  1368.                         0.5f, 0.5f,
  1369.                         1.0f, 0.5f
  1370.                 },
  1371.                 new float[]{
  1372.                         72
  1373.                 },
  1374.                 new int[]{
  1375.                         0, 1, 3, 3, 1, 2,
  1376.                         8, 10, 11, 9, 8, 11,
  1377.                         12, 13, 7, 5, 12, 7,
  1378.                         14, 15, 6, 4, 14, 6,
  1379.                         16, 18, 19, 17, 16, 19,
  1380.                         4, 6, 7, 5, 4, 7
  1381.                 }, new ArrayList<>(){{
  1382.             add(new Vector3f(0.5f, 0.5f, 0.5f));
  1383.             add(new Vector3f(-0.5f, -0.5f, -0.5f));
  1384.         }}));
  1385.     }};
  1386.     public World world = new World("test", new Box(new Vector3f(3, 3, 3), new Vector3f(-3, -3, -3)));
  1387.     public List<Entity> blocks = world.getEntities();
  1388.     public float specularPower = 10f;
  1389. }
  1390.  
  1391. class World {
  1392.     private String name;
  1393.     private List<Entity> entities = new ArrayList<>();
  1394.  
  1395.     public World(String name, Box box) {
  1396.         this.name = name;
  1397.  
  1398.         for (float x = 0; x < box.a().x() - box.b().x(); x++) {
  1399.             for (float y = 0; x < box.a().y() - box.b().y(); y++) {
  1400.                 for (float z = 0; z < box.a().z() - box.b().z(); z++) {
  1401.                     final int type;
  1402.                     float posY = Math.max(box.a().y(), box.b().y());
  1403.                     float negY = Math.min(box.a().y(), box.b().y());
  1404.                     Vector3f pos = new Vector3f(x, y, z);
  1405.  
  1406.                     if (y == posY) {
  1407.                         type = 0;
  1408.                     } else if (y < posY) {
  1409.                         type = 1;
  1410.                     } else if (y >= negY) {
  1411.                         type = 2;
  1412.                     } else {
  1413.                         type = 0;
  1414.                     }
  1415.  
  1416.                     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);}}));
  1417.                 }
  1418.             }
  1419.         }
  1420.     }
  1421.  
  1422.     public List<Entity> getEntities() {
  1423.         return entities;
  1424.     }
  1425. }
  1426.  
  1427. record Box(Vector3f a, Vector3f b) {}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement