带着色器的OpenGL LWJGL3仅提供黑屏

时间:2017-08-05 08:56:53

标签: java opengl shader lwjgl slick2d

我有一个NetBeans项目(请参阅下面的zip文件链接),我试图从我的Visual Studio项目(C#)转换。 我正在使用LWJGL和JOML(对于Matrix类)的库,但无论我放置对象的哪个位置,它们都不会在屏幕上呈现。

这是init方法:

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

    // Configure GLFW
    glfwDefaultWindowHints(); // optional, the current window hints are already the default
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable

    // Create the window
    window = glfwCreateWindow(800, 600, "Hello World!", NULL, NULL);
    if (window == NULL) {
        throw new RuntimeException("Failed to create the GLFW window");
    }

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

    });

    int width = 0;
    int height = 0;
    // Get the thread stack and push a new frame
    try (MemoryStack stack = stackPush()) {
        IntBuffer pWidth = stack.mallocInt(1); // int*
        IntBuffer pHeight = stack.mallocInt(1); // int*

        // Get the window size passed to glfwCreateWindow
        glfwGetWindowSize(window, pWidth, pHeight);

        // Get the resolution of the primary monitor
        GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
        width = pWidth.get(0);
        height = pHeight.get(0);

        // Center the window
        glfwSetWindowPos(
                window,
                (vidmode.width() - pWidth.get(0)) / 2,
                (vidmode.height() - pHeight.get(0)) / 2
        );
    } // the stack frame is popped automatically

    // Make the OpenGL context current
    glfwMakeContextCurrent(window);
    // Enable v-sync
    glfwSwapInterval(1);
    GLCapabilities caps = GL.createCapabilities();
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glEnable(GL11.GL_CULL_FACE);
    GL11.glCullFace(GL11.GL_BACK);

    initRenderPrograms();
    float ratio = (float)width / height;
    mViewMatrix = new Matrix4f();
    mViewMatrix = mViewMatrix.lookAt(mCameraX, mCameraY, mCameraZ, mTargetX, mTargetY, mTargetZ,0,1,0 );
    mProjectionMatrix = new Matrix4f();
    mProjectionMatrix = mProjectionMatrix.frustum(-ratio, ratio, -1f, 1f, 1.0f, 1000f);
    World.prepare(this);

    // Make the window visible
    glfwShowWindow(window);
}

...和渲染循环:

private void loop() {
    // Set the clear color
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    // Run the rendering loop until the user has attempted to close
    // the window or has pressed the ESCAPE key.
    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
        for (Cube c : World.getGeometryObjects()) {
            c.draw(mViewMatrix, mProjectionMatrix);
        }
        glfwSwapBuffers(window); // swap the color buffers
        // Poll for window events. The key callback above will only be
        // invoked during this call.
        glfwPollEvents();
    }
}

...和多维数据集实例的render方法:

public void draw(Matrix4f pViewMatrix, Matrix4f pProjectionMatrix) {
    //System.out.println("program id: " + mRenderer.getProgramId());
    GL20.glUseProgram(mRenderer.getProgramId());
    int error = GL11.glGetError();
    //System.out.println("Program: " + error);

    Matrix4f modelMatrix = new Matrix4f();
    modelMatrix.translate(new Vector3f(mXLL, mYLL, mZLL));

    // Calculate mvp and mv matrix from translation matrix and view/projection matrix
    Matrix4f mvMatrix = new Matrix4f();
    //pViewMatrix.mul(modelMatrix, mvMatrix);
    modelMatrix.mul(pViewMatrix, mvMatrix);

    Matrix4f mvpMatrix = new Matrix4f();
    //pProjectionMatrix.mul(mvMatrix, mvpMatrix);
    mvMatrix.mul(pProjectionMatrix, mvpMatrix);

    // Generate normal matrix by first inverting, then transposing the model matrix:
    Matrix4f normalMatrixTemp = new Matrix4f();
    mvMatrix.invert(normalMatrixTemp);
    Matrix4f normalMatrix = new Matrix4f();
    normalMatrixTemp.transpose(normalMatrix);

    // Pass through the light's position in world space (if there is any light):
    if (World.getLightObjects().size() > 0 && World.getLightObjects().get(0) != null && mRenderer.getUniformHandleLightPos() != -1) {
        LightPoint currentLight = World.getLightObjects().get(0);
        GL20.glUniform3f(mRenderer.getUniformHandleLightPos(), currentLight.getPosition().x, currentLight.getPosition().y, currentLight.getPosition().z);
        error = GL11.glGetError();
        //System.out.println("Lighting: " + error);
    }

    // Apply vertex data:
    if (mRenderer.getAttributeHandlePosition() != -1) {
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, mRenderer.getBufferHandlePosition());
        //GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, getVertexBuffer(), GL15.GL_STATIC_DRAW); //Send up the data and specify usage hint.
        GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);
        GL20.glVertexAttribPointer(mRenderer.getAttributeHandlePosition(), 3, GL11.GL_FLOAT, false, 0, 0);
        GL20.glEnableVertexAttribArray(mRenderer.getAttributeHandlePosition());

        error = GL11.glGetError();
        //System.out.println("Position: " + error);
    }

    // Apply color data:
    if (mRenderer.getAttributeHandleColor() != -1) {
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, mRenderer.getBufferHandleColor());
        //GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, getColorBuffer(), GL15.GL_STATIC_DRAW); //Send up the data and specify usage hint.
        GL11.glColorPointer(3, GL11.GL_FLOAT, 0, 0);
        GL20.glVertexAttribPointer(mRenderer.getAttributeHandleColor(), 3, GL11.GL_FLOAT, true, 0, 0);
        GL20.glEnableVertexAttribArray(mRenderer.getAttributeHandleColor());

        error = GL11.glGetError();
        //System.out.println("Color: " + error);
    }

    // Apply normal data:
    if (mRenderer.getAttributeHandleNormals() != -1) {
        //GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, mRenderer.getBufferHandleNormals());
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, getNormalBuffer(), GL15.GL_STATIC_DRAW); //Send up the data and specify usage hint.
        GL11.glColorPointer(3, GL11.GL_FLOAT, 0, 0);
        GL20.glVertexAttribPointer(mRenderer.getAttributeHandleNormals(), 3, GL11.GL_FLOAT, true, 0, 0);
        GL20.glEnableVertexAttribArray(mRenderer.getAttributeHandleNormals());

        error = GL11.glGetError();
        //System.out.println("Normals: " + error);
    }

    // Apply the texture:
    if (mRenderer.getAttributeHandleTexture() != -1) {
        GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); // Texture0 might (later) be used for depth map (dynamic shadows)

        GL11.glBindTexture(GL11.GL_TEXTURE_2D, mTextureHandle);

        GL20.glUniform1i(mRenderer.getUniformHandleTexture(), 1); // "1" because the active texture is texture unit 1

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, mRenderer.getBufferHandleTexture());
        //GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, getTextureBuffer(), GL15.GL_STATIC_DRAW);
        GL20.glVertexAttribPointer(mRenderer.getAttributeHandleTexture(), 2, GL11.GL_FLOAT, true, 0, 0);
        GL20.glEnableVertexAttribArray(mRenderer.getAttributeHandleTexture());

        error = GL11.glGetError();
        //System.out.println("Texture: " + error);
    }

    // Pass mvp matrix as uniform to the shader:
    FloatBuffer bufferMVP = BufferUtils.createFloatBuffer(16);
    GL20.glUniformMatrix4fv(mRenderer.getUniformHandleMVP(), true, mvpMatrix.get(bufferMVP));
    error = GL11.glGetError();
    //System.out.println("MVP: " + error);

    // Pass model matrix as uniform to the shader (for lighting):
    if (mRenderer.getUniformHandleModelMatrix() != -1) {
        FloatBuffer bufferM = BufferUtils.createFloatBuffer(16);
        modelMatrix.get(bufferM);
        GL20.glUniformMatrix4fv(mRenderer.getUniformHandleModelMatrix(), false, bufferM);
        error = GL11.glGetError();
        //System.out.println("ModelMatrix: " + error);
    }

    // Pass normal matrix as uniform to the shader:
    if (mRenderer.getUniformHandleNormalMatrix() != -1){
        FloatBuffer bufferNormals = BufferUtils.createFloatBuffer(16);
        normalMatrix.get(bufferNormals);
        GL20.glUniformMatrix4fv(mRenderer.getUniformHandleNormalMatrix(), false, bufferNormals);
        error = GL11.glGetError();
        //System.out.println("NormalMatrix: " + error);
    }

    // Finally draw the primitives:
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, mVertexCount);
    error = GL11.glGetError();
    //System.out.println("DrawArrays: " + error);

    // Release all buffers for this object:
    GL20.glDisableVertexAttribArray(mRenderer.getAttributeHandlePosition());
    GL20.glDisableVertexAttribArray(mRenderer.getAttributeHandleColor());
    GL20.glDisableVertexAttribArray(mRenderer.getAttributeHandleTexture());
    GL20.glDisableVertexAttribArray(mRenderer.getAttributeHandleNormals());
    error = GL11.glGetError();
    //System.out.println("DisableArrays: " + error);
}

顶点和片段着色器:

attribute   vec3 aPosition;
attribute   vec3 aColor;
attribute   vec2 aTexture;
attribute   vec3 aNormal;

varying     vec4 vPosition;
varying     vec4 vColor;
varying     vec2 vTexture;
varying     vec3 vNormal;

uniform mat4 uMVP;
uniform mat4 uM;
uniform mat4 uNormalMatrix;

void main()
{
    // Pass through the vertex position in world space (for measuring lighting angle and intensity)
    vPosition = uM * vec4(aPosition, 1.0); 

    // Pass through object color adding an alpha of 1.0 (1.0 = visible, 0.0 = invisible)
    vColor = vec4(aColor, 1.0); 

    // Pass through texture coordinate
    vTexture = aTexture; 

    // Calculate normal vector in world space by multiplying normal matrix by normal vector
    vNormal = vec3(uNormalMatrix * vec4(aNormal, 0.0));

    // Calculate final vertex position on screen by multiplying the vertex 
    // coordinate by the model-view-projection matrix
    gl_Position = uMVP * vec4(aPosition, 1.0); 
}
varying vec4 vPosition;
varying vec4 vColor;
varying vec3 vNormal;
varying vec2 vTexture;

uniform sampler2D uTexture;
uniform vec3 uLightPos;

out vec4 gl_FragColor;

void main()
{
    //Calculate the lighting vector (direction from light to fragment)
    vec3 lightVec = normalize(uLightPos - vec3(vPosition));

    //Calculate the lighting vector distance
    float distance = length(uLightPos - vec3(vPosition));

    // Calculate the dot product of normal vector and light vector and take the distance into account
    float diffuseComponent = max(dot(vNormal, lightVec), 0.0) * (1.0 / (1.0 + (0.01 * distance * distance)));

    // Create ambient light (if needed), otherwise everything that is not hit by light would be pitch black:
    float ambientComponent = 1.0;

    // Calculate the final fragment color (including the object's texture)
    gl_FragColor = (diffuseComponent + ambientComponent) * vColor * texture2D(uTexture, vTexture);
}

我不知道错误可能在哪里。我认为它与Matrix类或我使用缓冲区的方式有关。似乎与C#中需要设置的方式有很大不同......

https://www.dropbox.com/s/gyr9pcm1ewtqy3l/JavaOpenGL.zip?dl=0(44MB)

如果有人看了我的项目并把我推向了正确的方向,那就太棒了。

提前致谢!

0 个答案:

没有答案