首页 > 解决方案 > 未设置 LWJGL OpenGL 制服

问题描述

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

我试过了:

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

我的应用程序窗口类的代码:

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);
    }
}

我的实例类的代码:

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();
    }
}

渲染器类:

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();
}

着色器类:

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"
                + "}");
    }
}

网格类:

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);
    }
}

标签: javaopenglshaderlwjgl

解决方案


The geometry (triangle) is clipped by the near plane of the Perspective Projection. With Perspective Projection the viewing volume is a Frustum. Any geometries that are not in the viewing volume and not between the near and far planes are clipped.

Your geometry (triangle) is drawn at (z=0.0). The near pane is 0.001 and the dat plane is 1000. Therefor the geometry is clipped. Shift the geometry along the negative z-axis:

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

Note that the view space coordinate system is a right-handed system. The x-axis points to the right, the y-axis points upwards. Therefore, the z-axis points out of the viewport. To move the geometry between the near and far planes, you must move the geometry in the negative direction along the z-axis.
The projection matrix converts from the view space to the clip space. Clip space is a right-handed system. For the transformation from a left-handed system to a right-handed system, the projection matrix "flips" the z-axis.


推荐阅读