2017-09-20 11 views
-4

LWJGLのLWJGLGameDevのチュートリアルは、https://lwjglgamedev.gitbooks.io/3d-game-development-with-lwjgl/content/にあります。私はそのソースコードを使用しており、私のプロジェクトを自分たちのものと同じ方法で設定しています。レンダラーがmodelViewMatrixユニフォームを作成しようとしたときに、ユニフォームmodelViewMatrixを見つけることができないという例外がスローされたときに、第8章のチュートリアルのコードを実行しようとするまでは、すべてうまくいっていました。私はLWJGLとopenGLの初心者ですので、何が起こっているのか十分に理解していません。前もって感謝します。LWJGL他のユニフォームを作成することはできますが、ユニフォームを作成できません

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の:

パブリッククラス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(); 
} 

}

+0

どこで 'createUniform'を呼び出しますか?また、そのユニフォームが使用されているシェーダをポストします。 – Ripi2

答えて

-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; 
} 
関連する問題