Search code examples
javaopenglgraphicslwjgl

lwjgl 3 engine does not show anything


Im coding a Game with lwjgl3. I initially used lwjgl 2. but of major chanllenges, i switched to lwjgl3.

I walked through a couple tutorials and put together a gameloop with a window class and tried to implement the code i already had.

I had to change multiple things, had challenges like the slick util textureloader, but now im stuck:

Basically what i see is the Window, but nothing is displayed on it. My Engine is fairly big by now, but i will try to implement the important methods. When you need more, i can post more.

I will post the Shaderfiles for entity and skybox (what im trying to display currently) too

And all i see is a Window with nothing displayed

MAIN CLASS

     package main;

import static org.lwjgl.glfw.GLFW.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL;

import entities.Camera;
import entities.Light;
import entities.Player;
import graphics.Window;
import graphics.models.RawModel;
import graphics.models.TexturedModel;
import graphics.renderEngine.Loader;
import graphics.renderEngine.MasterRenderer;
import graphics.renderEngine.OBJLoader;
import graphics.textures.ModelTexture;
import toolbox.Vector3f;


public class Main 
{

    private GLFWErrorCallback errorCallback = GLFWErrorCallback.createPrint(System.err);

    private Window window;
    private MasterRenderer renderer;
    private Loader loader;

    private int Width;
    private int Height;
    private boolean running = false;
    private double delta;

    List<Light> lights = new ArrayList<Light>();
    Camera camera = null;
    private Player player;
    public Main()
    {


        init();

    }

    private void input()
    {
        glfwPollEvents();
        if(window.shouldClose()) stop();
    }

    private void update()
    {
        renderer.setHeight(Height);
        renderer.setWidth(Width);
        renderer.setDelta(delta);
    }

    private  void render()
    {
        renderer.processEntity(player);
        renderer.render(lights, camera);
        window.render();
    }

    private void run()
    {

        long lastTime = System.nanoTime();
        long currentTime = lastTime;
        long diff = 0;

        long timer = System.currentTimeMillis();

        double ns = 1000000000 / 60.0;
        delta = 0.0;

        double dfps = 1000000000 / 60.0;
        double d = 0.0;

        int fps = 0;
        int ups = 0;

        while(running)
        {
            currentTime = System.nanoTime();
            diff = currentTime - lastTime;
            delta += (diff)/ ns;
            d += diff/dfps;
            lastTime = currentTime;
            while(delta >= 1.0)
            {
                input();
                update();
                ups++;
                delta--;
            }

            if(d >- 1.0)
            {
                render();
                fps++;
                d = 0.0;
            }

            if(System.currentTimeMillis() > timer + 1000)
            {
                window.setTitle("Junker.5 | ups: "+ups+"| fps: "+fps+"");
                ups = 0;
                fps = 0;
                timer += 1000;
            }
        }

        cleanUp();
    }



    public void start()
    {
        if(running) return;
        running = true;
        run();
    }

    public void stop()
    {
        if(!running) return;
        running = false;
    }


    private void init()
    {

        Width = 1280;
        Height = 720;
        glfwSetErrorCallback(errorCallback);
        glfwInit();



        window = new Window(Width, Height, "Junker.5");
        GL.createCapabilities();

        loader = new Loader();
        renderer = new MasterRenderer(loader);
        renderer.setHeight(Height);
        renderer.setWidth(Width);
        renderer.setDelta(delta);


        RawModel playerShip = OBJLoader.loadObjModel("Puddle Jumper", loader);
        TexturedModel playership = new TexturedModel(playerShip, ModelTexture.loadTexture("white"));

        player = new Player(playership, new Vector3f(0, 0, -50),0,0,0,1);

        lights.add(new Light(new Vector3f(0,1000,-5000), new Vector3f(0f,0.4f,5f)));
        lights.add(new Light(new Vector3f(0,0,-10), new Vector3f(1,0,1), new Vector3f(1, 0.01f, 0.002f)));

        try 
        {
            camera = new Camera(player);
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }

    private void cleanUp()
    {
        window.hide();
        //guiRenderer.cleanUp();
        renderer.cleanUp();
        loader.cleanUp();
        window.dispose();
    }


    public static void main(String[] args) 
    {

        Main main = new Main();
        main.start();

    }

    public int getWidth()
    {
        return window.getWidth();
    }

    public int getheight()
    {
        return window.getHeight();
    }

    public double getDelta()
    {
        return delta;
    }

}

MASTER RENDERER CLASS

    package graphics.renderEngine;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.lwjgl.opengl.GL11;


import entities.Camera;
import entities.Entity;
import entities.Light;
import entities.Player;
import graphics.models.RawModel;
import graphics.models.TexturedModel;
import graphics.shaders.StaticShader;
import graphics.shaders.TerrainShader;
import graphics.skybox.SkyboxRenderer;
import graphics.terrains.Terrain;
import graphics.textures.ModelTexture;
import toolbox.Matrix4f;
import toolbox.Vector3f;

public class MasterRenderer 
{
    private static final float FOV = 70;
    private static final float NEAR_PLANE = 0.01f;
    private static final float FAR_PLANE = 1000;

    public int Width;
    public double delta;
    public int Height;

    private Matrix4f projectionMatrix;

    private StaticShader shader = new StaticShader();
    private TerrainRenderer terrainRenderer;
    private TerrainShader terrainShader = new TerrainShader();

    private EntityRenderer renderer;

    private Map<TexturedModel, List<Entity>> entities = new HashMap<TexturedModel, List<Entity>>();
    private List<Terrain> terrains = new ArrayList<Terrain>();

    private SkyboxRenderer skyboxRenderer ;

    public MasterRenderer(Loader loader)
    {
        enableCulling();

        createProjectionMatrix();
        renderer = new EntityRenderer(shader, projectionMatrix);
        terrainRenderer = new TerrainRenderer(terrainShader, projectionMatrix);
        skyboxRenderer = new SkyboxRenderer(loader, projectionMatrix);


    }

    public static void enableCulling()
    {
        GL11.glEnable(GL11.GL_CULL_FACE);
        GL11.glCullFace(GL11.GL_BACK);
    }

    public static void disableCullig()
    {
        GL11.glDisable(GL11.GL_CULL_FACE);
    }

    public void render(List<Light> lights, Camera camera)
    {
        prepare();
        shader.start();
        shader.loadLights(lights);
        shader.loadViewMatrix(camera);
        renderer.render(entities);
        shader.stop();
        terrainShader.start();
        terrainShader.loadLights(lights);
        terrainShader.loadViewMatrix(camera);
        terrainRenderer.render(terrains);
        terrainShader.stop();
        skyboxRenderer.render(camera);
        terrains.clear();
        entities.clear();
    }

    public void processTerrain(Terrain terrain)
    {
        terrains.add(terrain);
    }

    public void processEntity(Entity entity)
    {
        TexturedModel entityModel = entity.getModel();
        List<Entity> batch = entities.get(entityModel);
        if(batch != null)
        {
            batch.add(entity);
        }
        else
        {
            List<Entity> newBatch = new ArrayList<Entity>();
            newBatch.add(entity);
            entities.put(entityModel, newBatch);
        }
    }

    private void createProjectionMatrix()
    {
        float aspectRatio = (float) Width / (float) Height;
        float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))) * aspectRatio);
        float x_scale = y_scale / aspectRatio;
        float frustum_length = FAR_PLANE - NEAR_PLANE;

        projectionMatrix = new Matrix4f();
        projectionMatrix.m00 = x_scale;
        projectionMatrix.m11 = y_scale;
        projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length);
        projectionMatrix.m23 = -1;
        projectionMatrix.m32 = -((2 * FAR_PLANE + NEAR_PLANE) / frustum_length);
        projectionMatrix.m33 = 0;   
    }

    public void prepare()
    {
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glClearColor(0.03f, 0f, 0.0f, 1);
    }

    public void cleanUp()
    {
        shader.cleanUp();
        terrainShader.cleanUp();
    }

    public void setWidth(int width) 
    {
        Width = width;
    }

    public void setHeight(int height) 
    {
        Height = height;
    }

    public void setDelta(double delta) 
    {
        this.delta = delta;
    }
}

STATIC SHADER CLASS

 package graphics.shaders;

import java.util.List;

import entities.Camera;
import entities.Light;
import toolbox.Maths;
import toolbox.Matrix4f;
import toolbox.Vector3f;



public class StaticShader extends ShaderProgram
{

    public static final String VERTEX_FILE = "./Ressources/Shaders/VertexShader.shd";
    public static final String FRAGMENT_FILE = "./Ressources/Shaders/FragmentShader.shd";
    public static final int MAX_LIGHTS = 4;

    private int location_transformationMatrix;
    private int location_projectionMatrix;
    private int location_viewMatrix;
    private int location_lightPosition[];
    private int location_lightColour[];
    private int location_attenuation[];
    private int location_shineDamper;
    private int location_reflectivity;
    private int location_useFakeLighting;

    public StaticShader() 
    {
        super(VERTEX_FILE, FRAGMENT_FILE);
    }

    @Override
    protected void bindAttributes() 
    {
        super.bindAttribute(0, "position");
        super.bindAttribute(1, "textureCoords");
        super.bindAttribute(2, "normal");
    }

    protected void getAllUniformLocations()
    {
        location_transformationMatrix = super.getUniformLocation("transformationMatrix");
        location_projectionMatrix = super.getUniformLocation("projectionMatrix");
        location_viewMatrix = super.getUniformLocation("viewMatrix");
        location_shineDamper = super.getUniformLocation("shineDamper");
        location_reflectivity = super.getUniformLocation("reflectivity");
        location_useFakeLighting = super.getUniformLocation("useFakeLighting");


        location_lightPosition = new int[MAX_LIGHTS];
        location_attenuation = new int[MAX_LIGHTS];
        location_lightColour = new int[MAX_LIGHTS];
        for(int i = 0;i<MAX_LIGHTS;i++)
        {
            location_lightPosition[i] = super.getUniformLocation("lightPosition["+i+"]");
            location_lightColour[i] = super.getUniformLocation("lightColour["+i+"]");   
            location_attenuation[i] = super.getUniformLocation("attenuation["+i+"]");   
        }
    }

    public void loadFakeLightingVariable(boolean useFake)
    {
        super.loadBoolean(location_useFakeLighting, useFake);
    }

    public void loadShineVariables(float damper, float reflectivity)
    {
        super.LoadFloat(location_shineDamper, damper);
        super.LoadFloat(location_reflectivity, reflectivity);
    }

    public void loadTreansformationMatrix(Matrix4f matrix)
    {
        super.loadMatrix(location_transformationMatrix, matrix);
    }

    public void loadLights(List<Light> lights)
    {
        for(int i = 0;i<MAX_LIGHTS;i++)
        {
            if(i<lights.size())
            {
                super.LoadVector(location_lightPosition[i], lights.get(i).getPosition());
                super.LoadVector(location_lightColour[i], lights.get(i).getColour());
                super.LoadVector(location_attenuation[i], lights.get(i).getAttenuation());
            }
            else
            {
                super.LoadVector(location_lightPosition[i], new Vector3f(0,0,0));
                super.LoadVector(location_lightColour[i], new Vector3f(0,0,0));
                super.LoadVector(location_attenuation[i], new Vector3f(1,0,0));
            }
        }
    }

    public void loadViewMatrix(Camera camera)
    {
        Matrix4f viewMatrix = Maths.createViewMatrix(camera);
        super.loadMatrix(location_viewMatrix, viewMatrix);
    }

    public void loadProjectionMatrix(Matrix4f projection)
    {
        super.loadMatrix(location_projectionMatrix, projection);
    }

}

SHADERFILES:

FRAGMENT SHADER

#version 400 core

in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector[4];
in vec3 toCameraVector;

out vec4 out_Color;

uniform sampler2D textureSampler;
uniform vec3 lightColour[4];
uniform float shineDamper;
uniform float reflectivity;
uniform vec3 attenuation[4];

void main(void)
{
    vec3 unitNormal = normalize(surfaceNormal);
    vec3 unitVectorToCamera = normalize(toCameraVector);

    vec3 totalDiffuse = vec3(0.0);
    vec3 totalSpecular = vec3(0.0);

    for(int i=0;i<4;i++)
    {
    float distance = length(toLightVector[i]);
    float attFactor = attenuation[i].x + (attenuation[i].y * distance) + (attenuation[i].z * distance * distance);
        vec3 unitLightVector = normalize(toLightVector[i]);
        float nDot1 = dot(unitNormal, unitLightVector);
        float brightness = max(nDot1,0.0);
        vec3 lightDirection = -unitLightVector;
        vec3 reflectedLightDirection = reflect(lightDirection,unitNormal);
        float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
        specularFactor = max(specularFactor,0.0);
        float dampedFactor = pow(specularFactor,shineDamper);
        totalSpecular = totalSpecular + (dampedFactor * reflectivity * lightColour[i])/attFactor;
        totalDiffuse = totalDiffuse  + (brightness * lightColour[i])/attFactor;

    }

    totalDiffuse = max(totalDiffuse, 0.2);

    vec4 textureColour = texture(textureSampler, pass_textureCoords);
    if(textureColour.a<0.5)
    {
        discard;
    }

    out_Color = vec4(totalDiffuse,1.0) * texture(textureSampler, pass_textureCoords) + vec4(totalSpecular,1.0);
}

VERTEX SHADER

#version 400 core

in vec3 position;
in vec2 textureCoords;
in vec3 normal;


out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector[4];
out vec3 toCameraVector;

uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition[4];

uniform float useFakeLighting;

void main(void)
{
    vec4 worldPosition = transformationMatrix * vec4(position,1.0);
    gl_Position = projectionMatrix * viewMatrix * worldPosition;
    pass_textureCoords = textureCoords;

    vec3 actualNormal = normal;
    if(useFakeLighting > 0.5)
    {
        actualNormal = vec3(0.0,1.0,0.0);
    }

    surfaceNormal = (transformationMatrix * vec4(actualNormal,0.0)).xyz;
    for(int i=0;i<4;i++)
    {
        toLightVector[i] = lightPosition[i] - worldPosition.xyz;
    }
    toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;

}

I have absolutely no idea what im doing wrong. If anyone wants to really help me more personal on this problem, feel free to contact me too.

Thank you soo much!

EDIT:

Yes, the Clearcolor works, thats part of why i am confused. And before i worked ofer my lwjgl2 code to my new lwjgl3 code, the lwjgl3 window DID display simple graphics such as a 3d cube

Here is my window class

WINDOW

package graphics;

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;

import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.system.MemoryUtil;


public class Window 
{

    private long window;
    private int Width;
    private int Height;

    public Window(int width, int height, String title)
    {

        this.Width = width;
        this.Height = height;
        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_RESIZABLE, GL11.GL_FALSE);
        glfwWindowHint(GLFW_VISIBLE, GL11.GL_TRUE);
        //DECORATION
        glfwWindowHint(GLFW_DECORATED, GL11.GL_TRUE);
        glfwWindowHint(GLFW_FOCUSED, GL11.GL_TRUE);
        window = glfwCreateWindow(Width,Height,"Junker.5",NULL,NULL);

        GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());

        glfwSetWindowPos(
                window,
                 (vidmode.width() - width) / 2,
                (vidmode.height() - height) / 2
            ); 

        glfwMakeContextCurrent(window);
    }

    public void dispose()
    {
        glfwDestroyWindow(window);
    }

    public void hide()
    {
        glfwHideWindow(window);
    }

    public void render()
    {
        glfwSwapBuffers(window);
    }

    public void show()
    {
        glfwShowWindow(window);
    }

    public void setTitle(String title)
    {
        glfwSetWindowTitle(window, title);
    }

    public boolean shouldClose() 
    {
          if(!glfwWindowShouldClose(window)) 
          {
           return false;
          }
          else
          {
              return true;
          }
    }



    public int getWidth() 
    {
        return Width;
    }

    public void setWidth(int width) 
    {
        Width = width;
    }

    public int getHeight() 
    {
        return Height;
    }

    public void setHeight(int height) 
    {
        Height = height;
    }

    public void changecursor()
    {
        // Create the cursor object
        //long cursor = GLFW.glfwCreateCursor(imageBuffer, 0, 0);

        /*if (cursor == MemoryUtil.NULL)
            throw new RuntimeException("Error creating cursor");

        // Set the cursor on a window
        GLFW.glfwSetCursor(window, cursor);*/
    }

}

Solution

  • I did manage to fix the problem myself, atleast its displaying stuff now :)

    I just hardcoded the Width and height right now. The method of doing a setHeight() in the Main class must have angried the gods of my createProjectionMatrix() function. However, id would be awesome to know how to do this dynamic for future purposes