LWJGL即使我可以制作其他制服也无法制作制服

时间:2017-09-20 23:25:24

标签: java opengl lwjgl

我一直在关注LWJGLGameDev关于在https://lwjglgamedev.gitbooks.io/3d-game-development-with-lwjgl/content/找到的LWJGL的教程。我正在使用它的源代码,并且我的项目设置与他们的相同。一切似乎很好,直到我试图在第8章中运行教程中的代码,当渲染器尝试创建modelViewMatrix制服时,它会抛出一个异常,它找不到统一的modelViewMatrix。我是LWJGL和openGL的新手,所以我不完全了解发生了什么。先感谢您。以下是相关代码:

public class Renderer {

/**
 * Field of View in Radians
 */
private static final float FOV = (float) Math.toRadians(60.0f);

private static final float Z_NEAR = 0.01f;

private static final float Z_FAR = 1000.f;

private final Transformation transformation;

private ShaderProgram shaderProgram;

public Renderer() {
    transformation = new Transformation();
}

public void init(Window window) throws Exception {
    // Create shader
    shaderProgram = new ShaderProgram();
    shaderProgram.createVertexShader(Utils.loadResource("/shaders/vertex.vs"));
    shaderProgram.createFragmentShader(Utils.loadResource("/shaders/fragment.fs"));
    shaderProgram.link();

    // Create uniforms for modelView and projection matrices and texture
    shaderProgram.createUniform("projectionMatrix");
    shaderProgram.createUniform("texture_sampler");
    shaderProgram.createUniform("modelViewMatrix");
}

public void clear() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

public void render(Window window, Camera camera, GameItem[] gameItems) {
    clear();

    if ( window.isResized() ) {
        glViewport(0, 0, window.getWidth(), window.getHeight());
        window.setResized(false);
    }

    shaderProgram.bind();

    // Update projection Matrix
    Matrix4f projectionMatrix = transformation.getProjectionMatrix(FOV, window.getWidth(), window.getHeight(), Z_NEAR, Z_FAR);
    shaderProgram.setUniform("projectionMatrix", projectionMatrix);

    // Update view Matrix
    Matrix4f viewMatrix = transformation.getViewMatrix(camera);

    shaderProgram.setUniform("texture_sampler", 0);
    // Render each gameItem
    for(GameItem gameItem : gameItems) {
        // Set model view matrix for this item
        Matrix4f modelViewMatrix = transformation.getModelViewMatrix(gameItem, viewMatrix);
        shaderProgram.setUniform("modelViewMatrix", modelViewMatrix);
        // Render the mes for this game item
        gameItem.getMesh().render();
    }

    shaderProgram.unbind();
}

public void cleanup() {
    if (shaderProgram != null) {
        shaderProgram.cleanup();
    }
}
}

ShaderProgram:

public class ShaderProgram {

private final int programId;

private int vertexShaderId;

private int fragmentShaderId;

private final Map<String, Integer> uniforms;

public ShaderProgram() throws Exception {
    programId = glCreateProgram();
    if (programId == 0) {
        throw new Exception("Could not create Shader");
    }
    uniforms = new HashMap<>();
}

public void createUniform(String uniformName) throws Exception {
    int uniformLocation = glGetUniformLocation(programId, uniformName);
    if (uniformLocation < 0) {
        throw new Exception("Could not find uniform:" + uniformName);
    }
    uniforms.put(uniformName, uniformLocation);
}

public void setUniform(String uniformName, Matrix4f value) {
    try (MemoryStack stack = MemoryStack.stackPush()) {
        // Dump the matrix into a float buffer
        FloatBuffer fb = stack.mallocFloat(16);
        value.get(fb);
        glUniformMatrix4fv(uniforms.get(uniformName), false, fb);
    }
}

public void setUniform(String uniformName, int value) {
    glUniform1i(uniforms.get(uniformName), value);
}

public void createVertexShader(String shaderCode) throws Exception {
    vertexShaderId = createShader(shaderCode, GL_VERTEX_SHADER);
}

public void createFragmentShader(String shaderCode) throws Exception {
    fragmentShaderId = createShader(shaderCode, GL_FRAGMENT_SHADER);
}

protected int createShader(String shaderCode, int shaderType) throws Exception {
    int shaderId = glCreateShader(shaderType);
    if (shaderId == 0) {
        throw new Exception("Error creating shader. Type: " + shaderType);
    }

    glShaderSource(shaderId, shaderCode);
    glCompileShader(shaderId);

    if (glGetShaderi(shaderId, GL_COMPILE_STATUS) == 0) {
        throw new Exception("Error compiling Shader code: " + glGetShaderInfoLog(shaderId, 1024));
    }

    glAttachShader(programId, shaderId);

    return shaderId;
}

public void link() throws Exception {
    glLinkProgram(programId);
    if (glGetProgrami(programId, GL_LINK_STATUS) == 0) {
        throw new Exception("Error linking Shader code: " + glGetProgramInfoLog(programId, 1024));
    }

    if (vertexShaderId != 0) {
        glDetachShader(programId, vertexShaderId);
    }
    if (fragmentShaderId != 0) {
        glDetachShader(programId, fragmentShaderId);
    }

    glValidateProgram(programId);
    if (glGetProgrami(programId, GL_VALIDATE_STATUS) == 0) {
        System.err.println("Warning validating Shader code: " + glGetProgramInfoLog(programId, 1024));
    }
}

public void bind() {
    glUseProgram(programId);
}

public void unbind() {
    glUseProgram(0);
}

public void cleanup() {
    unbind();
    if (programId != 0) {
        glDeleteProgram(programId);
    }
}
}

转型:

public class Transformation {

private final Matrix4f projectionMatrix;

private final Matrix4f modelViewMatrix;

private final Matrix4f viewMatrix;

public Transformation() {
    projectionMatrix = new Matrix4f();
    modelViewMatrix = new Matrix4f();
    viewMatrix = new Matrix4f();
}

public final Matrix4f getProjectionMatrix(float fov, float width, float height, float zNear, float zFar) {
    float aspectRatio = width / height;
    projectionMatrix.identity();
    projectionMatrix.perspective(fov, aspectRatio, zNear, zFar);
    return projectionMatrix;
}

public Matrix4f getViewMatrix(Camera camera) {
    Vector3f cameraPos = camera.getPosition();
    Vector3f rotation = camera.getRotation();

    viewMatrix.identity();
    // First do the rotation so camera rotates over its position
    viewMatrix.rotate((float)Math.toRadians(rotation.x), new Vector3f(1, 0, 0))
            .rotate((float)Math.toRadians(rotation.y), new Vector3f(0, 1, 0));
    // Then do the translation
    viewMatrix.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z);
    return viewMatrix;
}

public Matrix4f getModelViewMatrix(GameItem gameItem, Matrix4f viewMatrix) {
    Vector3f rotation = gameItem.getRotation();
    modelViewMatrix.identity().translate(gameItem.getPosition()).
            rotateX((float)Math.toRadians(-rotation.x)).
            rotateY((float)Math.toRadians(-rotation.y)).
            rotateZ((float)Math.toRadians(-rotation.z)).
            scale(gameItem.getScale());
    Matrix4f viewCurr = new Matrix4f(viewMatrix);
    return viewCurr.mul(modelViewMatrix);
}
}

的Utils:

public class Utils {

public static String loadResource(String fileName) throws Exception {
    String result;
    try (InputStream in = Utils.class.getClass().getResourceAsStream(fileName);
         Scanner scanner = new Scanner(in, "UTF-8")) {
        result = scanner.useDelimiter("\\A").next();
    }
    return result;
}

}

GameItem:

公共类GameItem {     私人最终网格网;

private final Vector3f position;

private float scale;

private final Vector3f rotation;

public GameItem(Mesh mesh)
{
    this.mesh=mesh;
    position=new Vector3f(0,0,0);
    scale=1;
    rotation=new Vector3f(0,0,0);
}

public Vector3f getPosition()
{
    return position;
}

public void setPosition(float x, float y, float z)
{
    this.position.x=x;
    this.position.y=y;
    this.position.z=z;
}

public float getScale()
{
    return scale;
}

public void setScale(float scale)
{
    this.scale=scale;
}

public Vector3f getRotation()
{
    return rotation;
}

public void setRotation(float x, float y, float z) {
    this.rotation.x = x;
    this.rotation.y = y;
    this.rotation.z = z;
}

public Mesh getMesh() {
    return mesh;
}
}

目数:

public class Mesh {

private final int vaoId;

private final List<Integer> vboIdList;

private final int vertexCount;

private final Texture texture;

public Mesh(float[] positions, float[] textCoords, int[] indices, Texture texture) {
    FloatBuffer posBuffer = null;
    FloatBuffer textCoordsBuffer = null;
    IntBuffer indicesBuffer = null;
    try {
        this.texture = texture;
        vertexCount = indices.length;
        vboIdList = new ArrayList();

        vaoId = glGenVertexArrays();
        glBindVertexArray(vaoId);

        // Position VBO
        int vboId = glGenBuffers();
        vboIdList.add(vboId);
        posBuffer = MemoryUtil.memAllocFloat(positions.length);
        posBuffer.put(positions).flip();
        glBindBuffer(GL_ARRAY_BUFFER, vboId);
        glBufferData(GL_ARRAY_BUFFER, posBuffer, GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

        // Texture coordinates VBO
        vboId = glGenBuffers();
        vboIdList.add(vboId);
        textCoordsBuffer = MemoryUtil.memAllocFloat(textCoords.length);
        textCoordsBuffer.put(textCoords).flip();
        glBindBuffer(GL_ARRAY_BUFFER, vboId);
        glBufferData(GL_ARRAY_BUFFER, textCoordsBuffer, GL_STATIC_DRAW);
        glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);

        // Index VBO
        vboId = glGenBuffers();
        vboIdList.add(vboId);
        indicesBuffer = MemoryUtil.memAllocInt(indices.length);
        indicesBuffer.put(indices).flip();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboId);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    } finally {
        if (posBuffer != null) {
            MemoryUtil.memFree(posBuffer);
        }
        if (textCoordsBuffer != null) {
            MemoryUtil.memFree(textCoordsBuffer);
        }
        if (indicesBuffer != null) {
            MemoryUtil.memFree(indicesBuffer);
        }
    }
}

public int getVaoId() {
    return vaoId;
}

public int getVertexCount() {
    return vertexCount;
}

public void render() {
    // Activate firs texture bank
    glActiveTexture(GL_TEXTURE0);
    // Bind the texture
    glBindTexture(GL_TEXTURE_2D, texture.getId());

    // Draw the mesh
    glBindVertexArray(getVaoId());
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    glDrawElements(GL_TRIANGLES, getVertexCount(), GL_UNSIGNED_INT, 0);

    // Restore state
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glBindVertexArray(0);
}

public void cleanUp() {
    glDisableVertexAttribArray(0);

    // Delete the VBOs
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    for (int vboId : vboIdList) {
        glDeleteBuffers(vboId);
    }

    // Delete the texture
    texture.cleanup();

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

窗口:

public class Window {

private final String title;

private int width;

private int height;

private long windowHandle;

private boolean resized;

private boolean vSync;

public Window(String title, int width, int height, boolean vSync) {
    this.title = title;
    this.width = width;
    this.height = height;
    this.vSync = vSync;
    this.resized = false;
}

public void init() {
    // Setup an error callback. The default implementation
    // will print the error message in System.err.
    GLFWErrorCallback.createPrint(System.err).set();

    // Initialize GLFW. Most GLFW functions will not work before doing this.
    if (!glfwInit()) {
        throw new IllegalStateException("Unable to initialize GLFW");
    }

    glfwDefaultWindowHints(); // optional, the current window hints are already the default
    glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // the window will stay hidden after creation
    glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // the window will be resizable
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

    // Create the window
    windowHandle = glfwCreateWindow(width, height, title, NULL, NULL);
    if (windowHandle == NULL) {
        throw new RuntimeException("Failed to create the GLFW window");
    }

    // Setup resize callback
    glfwSetFramebufferSizeCallback(windowHandle, (window, width, height) -> {
        this.width = width;
        this.height = height;
        this.setResized(true);
    });

    // Setup a key callback. It will be called every time a key is pressed, repeated or released.
    glfwSetKeyCallback(windowHandle, (window, key, scancode, action, mods) -> {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
            glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
        }
    });

    // Get the resolution of the primary monitor
    GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    // Center our window
    glfwSetWindowPos(
            windowHandle,
            (vidmode.width() - width) / 2,
            (vidmode.height() - height) / 2
    );

    // Make the OpenGL context current
    glfwMakeContextCurrent(windowHandle);

    if (isvSync()) {
        // Enable v-sync
        glfwSwapInterval(1);
    }

    // Make the window visible
    glfwShowWindow(windowHandle);

    GL.createCapabilities();

    // Set the clear color
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glEnable(GL_DEPTH_TEST);
}

public long getWindowHandle() {
    return windowHandle;
}

public void setClearColor(float r, float g, float b, float alpha) {
    glClearColor(r, g, b, alpha);
}

public boolean isKeyPressed(int keyCode) {
    return glfwGetKey(windowHandle, keyCode) == GLFW_PRESS;
}

public boolean windowShouldClose() {
    return glfwWindowShouldClose(windowHandle);
}

public String getTitle() {
    return title;
}

public int getWidth() {
    return width;
}

public int getHeight() {
    return height;
}

public boolean isResized() {
    return resized;
}

public void setResized(boolean resized) {
    this.resized = resized;
}

public boolean isvSync() {
    return vSync;
}

public void setvSync(boolean vSync) {
    this.vSync = vSync;
}

public void update() {
    glfwSwapBuffers(windowHandle);
    glfwPollEvents();
}

}

1 个答案:

答案 0 :(得分:-1)

没关系,问题是vertex.vs文件必须指定统一:

#version 330

layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoord;

out vec2 outTexCoord;

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

void main()
{
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    outTexCoord = texCoord;
}