未设置 LWJGL OpenGL 制服

LWJGL OpenGL Uniforms aren't being set

现在我正在进行渲染对象的简单步骤。我正在关注 gitbook here,虽然我有几乎相同的设置,但我在屏幕上什么也看不到。

我试过:

但是一旦我使用制服,除了清晰的颜色外,屏幕上什么也看不到。 任何有关如何让这些古怪的制服工作的帮助将不胜感激。谢谢!

我的申请代码Window class:

package flaff.gameengine.internal;

import flaff.gameengine.*;

import java.util.List;

import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import static org.lwjgl.opengl.GL30.*;

public class ApplicationWindow
{
    private int width;
    private int height;
    private String title;
    private boolean resized;
    private long window;

    public ApplicationWindow(int width, int height, String title)
    {
        this.width = width;
        this.height = height;
        this.title = title;
    }

    public void start()
    {
        if (!GLFW.glfwInit())
        {
            System.err.println("Error: Couldn't initialize GLFW");
            System.exit(-1);
        }
        this.window = GLFW.glfwCreateWindow(this.width, this.height, this.title, 0, 0);
        if (window == 0)
        {
            System.err.println("Error: Window couldn't be created");
            System.exit(-1);
        }
        GLFW.glfwMakeContextCurrent(this.window);
        GL.createCapabilities();
        GLFW.glfwSetFramebufferSizeCallback(this.window, (unusedW, width, height) ->
        {
            this.width = width;
            this.height = height;
            this.resized = true;
        });
        glClearColor(0.1921569f, 0.3019608f, 0.4745098f, 0f);
        GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
        // centers the window
        GLFW.glfwSetWindowPos(this.window, (videoMode.width() - this.width) / 2, (videoMode.height() - this.height) / 2);
        // show the video
        GLFW.glfwShowWindow(this.window);
        glEnable(GL_DEPTH_TEST);
    }

    public void render()
    {
        if (this.resized)
        {
            glViewport(0, 0, width, height);
            glMatrixMode(GL_MODELVIEW);
            this.resized = false;
        }

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        List<Renderer> rendererList = GObject.findObjectsOfType(Renderer.class);
        for (int index = 0; index < rendererList.size(); index++)
            rendererList.get(index).render();
    }

    public boolean isClosed()
    {
        return GLFW.glfwWindowShouldClose(this.window);
    }

    public void nextFrame()
    {
        // non-relevant code
        GLFW.glfwPollEvents();

        // more non-relevant code

        // render loop
        this.render();

        // more non-relevant code

        GLFW.glfwSwapBuffers(this.window);
    }
}

我的实例代码Class:

package flaff.gameengine;

import java.util.List;
import flaff.gameengine.internal.*;
import flaff.gameengine.renderers.MeshRenderer;

public class Instance
{
    private ApplicationWindow window;

    private Instance(int width, int height, String title)
    {
        this.window = new ApplicationWindow(width, height, title);
    }
    public ApplicationWindow getWindow()
    {
        return this.window;
    }
    public void run()
    {
        this.window.start();
        Shader shader = Shader.getDefault();
        shader.createUniform("projectionMatrix");
        MeshRenderer renderer = new MeshRenderer();
        renderer.setShader(shader);
        Mesh mesh = new Mesh(new float[] {
            0.0f,  0.5f, 0f,
            -0.5f, -0.5f, 0f,
            0.5f, -0.5f, 0f
        });
        renderer.setMesh(mesh);
        while (!this.window.isClosed())
        {
            this.window.nextFrame();
        }
        // non-relevant code
    }

    // entry point
    public static void main(String[] args)
    {
        new Instance(800, 600, "Test").run();
    }
}

网格渲染器:

package flaff.gameengine.renderers;

import flaff.gameengine.Application;
import flaff.gameengine.Mesh;
import flaff.utils.geometry.Mathg;
import flaff.utils.geometry.matrix.Matrix4x4f;

public class MeshRenderer extends Renderer
{
    private Mesh mesh;
    private Matrix4x4f perspectiveMatrix;
    
    public MeshRenderer() 
    {
        super();
    }
    
    public void setMesh(Mesh value)
    {
        this.mesh = value;
    }
    
    @Override
    public void render()
    {
        float aspectRatio = (float)Application.getWidth() / Application.getHeight();
        float fov = Mathg.DEG2RAD * 90F;
        float zNear = 0.001F;
        float zFar = 1000F;
        
        if (this.perspectiveMatrix == null)
            this.perspectiveMatrix = Matrix4x4f.createPerspectiveFieldOfView(aspectRatio, fov, zNear, zFar);
        
        shader.bind();
        
        shader.setUniform("projectionMatrix", this.perspectiveMatrix);
        
        glBindVertexArray(mesh.getVaoId());
        glEnableVertexAttribArray(0);
        
        glDrawArrays(GL_TRIANGLES, 0, mesh.getVertexCount());

        // Restore state
        glDisableVertexAttribArray(0);
        glBindVertexArray(0);
        
        shader.unbind();
    }
}

渲染器Class:

package flaff.gameengine.renderers;

import flaff.gameengine.Behaviour;
import flaff.gameengine.SerializeField;
import flaff.gameengine.internal.Shader;

public abstract class Renderer extends Behaviour
{
    @SerializeField
    protected Shader shader;
    
    public Renderer()
    {
        super();
    }
    
    public void setShader(Shader shader)
    {
        this.shader = shader;
    }
    
    public abstract void render();
}

着色器Class:

package flaff.gameengine.internal;

import static org.lwjgl.opengl.GL30.*;

import java.nio.FloatBuffer;
import java.util.HashMap;
import java.util.Map;

import org.lwjgl.system.MemoryStack;

import flaff.utils.geometry.matrix.Matrix4x4f;

public class Shader
{
    private final int programId;
    private int vertexShaderId;
    private int fragmentShaderId;
    private Map<String, Integer> uniforms;
    
    public Shader(String vertexShader, String fragmentShader)
    {
        this.uniforms = new HashMap<String, Integer>();
        
        this.programId = glCreateProgram();
        if (programId == 0)
            throw new RuntimeException("FML");
        
        this.vertexShaderId = this.createShader(vertexShader, GL_VERTEX_SHADER);
        this.fragmentShaderId = this.createShader(fragmentShader, GL_FRAGMENT_SHADER);
        
        this.link();
    }
    
    private int createShader(String shaderCode, int shaderType)
    {
        int shaderId = glCreateShader(shaderType);
        if (shaderId == 0)
            throw new RuntimeException("Error creating a shader. FML: " + shaderType);
        
        glShaderSource(shaderId, shaderCode);
        glCompileShader(shaderId);
        
        if (glGetShaderi(shaderId, GL_COMPILE_STATUS) == 0)
            throw new RuntimeException("Error compiling Shader code: " + glGetShaderInfoLog(shaderId, 1024));
        
        glAttachShader(this.programId, shaderId);
        
        return shaderId;
    }
    
    public void link()
    {
        glLinkProgram(this.programId);
        if (glGetProgrami(this.programId, GL_LINK_STATUS) == 0)
            throw new RuntimeException("Error linking Shader code: " + glGetProgramInfoLog(programId, 1024));
        
        if (this.vertexShaderId != 0)
            glDetachShader(this.programId, this.vertexShaderId);
        
        if (this.fragmentShaderId != 0)
            glDetachShader(programId, this.fragmentShaderId);
        
        glValidateProgram(this.programId);
        if (glGetProgrami(this.programId, GL_VALIDATE_STATUS) == 0)
            System.err.println("Warning validating Shader code: " + glGetProgramInfoLog(programId, 1024));
    }
    
    public void bind()
    {
        glUseProgram(this.programId);
    }
    
    public void unbind()
    {
        glUseProgram(0);
    }
    
    public void cleanup()
    {
        unbind();
        if (this.programId != 0)
            glDeleteProgram(this.programId);
    }
    
    public void createUniform(String uniformName)
    {
        int uniformLocation = glGetUniformLocation(this.programId, uniformName);
        if (uniformLocation < 0)
            throw new RuntimeException("Could not find uniform: " + uniformName);
        
        uniforms.put(uniformName, uniformLocation);
    }
    
    public void setUniform(String uniformName, Matrix4x4f matrix)
    {
        try (MemoryStack stack = MemoryStack.stackPush())
        {
            FloatBuffer fb = stack.mallocFloat(16);
            matrix.updateBuffer(fb);
            
            glUniformMatrix4fv(uniforms.get(uniformName), false, fb);
        }
    }
    
    public static Shader getDefault()
    {
        return new Shader(
                  "#version 330\n"
                + "\n"
                + "\n"
                + "layout (location=0) in vec3 position;\n"
                + "\n"
                + "uniform mat4 projectionMatrix;\n"
                + "\n"
                + "void main()\n"
                + "{\n"
                + "    gl_Position = projectionMatrix * vec4(position, 1.0);\n"
                + "}", 
    
                  "#version 330\n"
                + "\n"
                + "\n"
                + "out vec4 fragColor;\n"
                + "\n"
                + "void main()\n"
                + "{\n"
                + "    fragColor = vec4(0.5, 0.5, 0.5, 1.0);\n"
                + "}");
    }
}

网格Class:

package flaff.gameengine;

import java.nio.FloatBuffer;
import static org.lwjgl.opengl.GL30.*;
import org.lwjgl.system.MemoryUtil;

public class Mesh extends GObject
{
    private final int vaoId;

    private final int vboId;

    private final int vertexCount;

    public Mesh(float[] positions) //TODO: Implement indices
    {
        FloatBuffer verticesBuffer = null;
        verticesBuffer = MemoryUtil.memAllocFloat(positions.length);
        vertexCount = positions.length / 3;
        verticesBuffer.put(positions).flip();

        vaoId = glGenVertexArrays();
        glBindVertexArray(vaoId);

        vboId = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboId);
        glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);          
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
        MemoryUtil.memFree(verticesBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glBindVertexArray(0);
    }

    public int getVaoId() 
    {
        return vaoId;
    }

    public int getVertexCount() 
    {
        return vertexCount;
    }

    private void onDestroy() 
    {
        glDisableVertexAttribArray(0);

        // Delete the VBO
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glDeleteBuffers(vboId);

        // Delete the VAO
        glBindVertexArray(0);
        glDeleteVertexArrays(vaoId);
    }
}

几何体(三角形)被 Perspective Projection. With Perspective Projection the viewing volume is a Frustum 的近平面剪裁。任何不在观察体积内且不在近平面和远平面之间的几何图形都将被剪裁。

您的几何图形(三角形)绘制在 (z=0.0) 处。近窗格为 0.001,数据平面为 1000。因此几何图形被裁剪。沿负 z 轴移动几何:

Mesh mesh = new Mesh(new float[] {
     0.0f,  0.5f, -5.0f,
    -0.5f, -0.5f, -5.0f,
     0.5f, -0.5f, -5.0f
 });

注意视图space坐标系是右手系。 x 轴指向右侧,y 轴指向上方。因此,z 轴指向视口外。要在近平面和远平面之间移动几何体,必须沿 z 轴向负方向移动几何体。
投影矩阵从视图 space 转换为剪辑 space。 Clip space 是一个右手系统。对于从左手系统到右手系统的转换,投影矩阵“翻转”了 z 轴。