簡體   English   中英

為什么我的紋理被渲染為黑色?

[英]Why is my texture being rendered black?

我正在使用LWJGL 3編寫OpenGL應用程序。我能夠很好地渲染純色,但是一旦嘗試引入紋理采樣器,我所看到的只是黑色。

純色與紋理采樣

具體來說, 片段着色器中texture(texUnit,DataIn.texCoord)返回的值始終為vec4(0,0,0,1)

我什至嘗試用所有255手動填充傳遞給glTexImage2D的緩沖區,但得到的結果相同。 在這一點上,我完全陷入了困境!

初始化:

private void initGL() {

    // Enable depth buffer
    GL11.glEnable(GL11.GL_DEPTH_TEST);

    // Set background colour
    GL11.glClearColor(0.2f, 0.2f, 0.4f, 0.0f);

    // Set viewport to the whole window
    GL11.glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

    // Enable alpha blending (transparency)
    GL11.glEnable(GL11.GL_BLEND);
    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

    // Enable back-face culling
    GL11.glEnable(GL11.GL_CULL_FACE);
    GL11.glCullFace(GL11.GL_BACK);

    // Use linear filtering for texture scaling
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
            GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
            GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);

    // Clamp texture co-ordinates between 0 and 1
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
            GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
            GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);

    int errorCode = GL11.glGetError();
    if (errorCode != GL11.GL_NO_ERROR) {
        throw new RuntimeException(
                "OpenGL error " + String.valueOf(errorCode)
                + " during initialisation");
    }
}

紋理加載:

    String filename = "terrain.png";

    // Read image into a ByteBuffer
    IntBuffer w = BufferUtils.createIntBuffer(1);
    IntBuffer h = BufferUtils.createIntBuffer(1);
    IntBuffer comp = BufferUtils.createIntBuffer(1);
    ByteBuffer texelData = 
            STBImage.stbi_load(GFX_DIR + filename, w, h, comp, 4);
    if (texelData == null) {
        throw new RuntimeException("Error loading " + filename + ": " +
                STBImage.stbi_failure_reason());
    }
    int width = w.get();
    int height = h.get();

    // Generate texture ID
    terrainTexId = GL11.glGenTextures();
    // Pass our texture to the shader
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, terrainTexId);
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height,
            0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, texelData);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); // Deselect

    int errorCode = GL11.glGetError();
    if (errorCode != GL11.GL_NO_ERROR) {
        throw new RuntimeException(
                "OpenGL error " + String.valueOf(errorCode)
                + " loading texture: " + filename);
    }

渲染:

    // Clear the screen and depth buffer
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

    // Use our shader program
    GL20.glUseProgram(Shaders.programId);

    // Set the projection matrix
    FloatBuffer fb = BufferUtils.createFloatBuffer(16);
    projection.setPerspective(
            camera.getFovY(),
            window.getAspectRatio(), 
            Camera.Z_NEAR,
            Camera.Z_FAR);
    GL20.glUniformMatrix4fv(
            Shaders.projectionLoc, false, projection.get(fb));

    // Set the model-view matrix.
    modelView.setLookAt(
            camera.getPos(),
            camera.getTarget(),
            camera.getUpVector());
    GL20.glUniformMatrix4fv(Shaders.modelViewLoc, false, modelView.get(fb));

    // Bind our texture to texture unit 0
    GL13.glActiveTexture(GL13.GL_TEXTURE0 + 0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, terrainTexId);
    // Tell the shader to sample from texture unit 0.
    // This is the default anyway.
    GL20.glUniform1i(Shaders.texUnitLoc, 0);

    // Pass the lighting information to the shader
    fb = BufferUtils.createFloatBuffer(3);
    GL20.glUniform3fv(Shaders.lightAmbientColourLoc,
            lighting.getAmbientColour().get(fb));
    GL20.glUniform1f(Shaders.lightAmbientIntensityLoc,
            lighting.getAmbientIntensity());
    GL20.glUniform3fv(Shaders.lightDiffuseColourLoc,
            lighting.getDiffuseColour().get(fb));
    GL20.glUniform3fv(Shaders.lightDiffuseAngleLoc,
            lighting.getDiffuseVector().get(fb));
    GL20.glUniform1f(Shaders.lightDiffuseIntensityLoc,
            lighting.getDiffuseIntensity());

    // Bind to the VAO that has all the information about the vertices
    GL30.glBindVertexArray(terrainSection.getVaoId());
    GL20.glEnableVertexAttribArray(Shaders.PARAM_VERTEX);
    GL20.glEnableVertexAttribArray(Shaders.PARAM_VERTEX_NORMAL);
    GL20.glEnableVertexAttribArray(Shaders.PARAM_MATERIAL_AMBIENT_COLOUR);
    GL20.glEnableVertexAttribArray(Shaders.PARAM_MATERIAL_DIFFUSE_COLOUR);
    GL20.glEnableVertexAttribArray(Shaders.PARAM_TEXTURE_COORDS);

    // Draw the vertices
    GL11.glDrawArrays(
            GL11.GL_TRIANGLES, 0, TerrainSection.NUM_VERTICES_FOR_BUFFERS);

    // Put everything back to default (deselect)
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
    GL20.glDisableVertexAttribArray(Shaders.PARAM_VERTEX);
    GL20.glDisableVertexAttribArray(Shaders.PARAM_VERTEX_NORMAL);
    GL20.glDisableVertexAttribArray(Shaders.PARAM_MATERIAL_AMBIENT_COLOUR);
    GL20.glDisableVertexAttribArray(Shaders.PARAM_MATERIAL_DIFFUSE_COLOUR);
    GL30.glBindVertexArray(0);
    GL20.glUseProgram(0);

頂點着色器:

#version 330

uniform mat4 projection;
uniform mat4 modelView;
uniform vec3 lightAmbientColour;
uniform float lightAmbientIntensity;
uniform vec3 lightDiffuseAngle;
uniform vec3 lightDiffuseColour;
uniform float lightDiffuseIntensity;

layout(location = 0) in vec3 vertex;
layout(location = 1) in vec3 vertexNormal;
layout(location = 2) in vec3 materialAmbientColour;
layout(location = 3) in vec3 materialDiffuseColour;
layout(location = 4) in vec2 texCoord;

out Data {
    vec4 colour;
    vec2 texCoord;
} DataOut;

void main(void) {
    gl_Position = projection * modelView * vec4(vertex, 1.0);

    vec3 ambientComponent = lightAmbientIntensity * 
            (lightAmbientColour * materialAmbientColour);
    ambientComponent = clamp(ambientComponent, 0.0, 1.0);

    // The dot product gives us a measure of how "aligned" 2 vectors are,
    // between 0 and 1. If the light direction and the vertex normal are
    // well-aligned, the vertex should appear more brightly-lit.
    float dotProduct = dot(lightDiffuseAngle, vertexNormal);
    if (dotProduct < 0){
        dotProduct = 0;
    }
    vec3 diffuseComponent = lightDiffuseIntensity * dotProduct * 
            (lightDiffuseColour * materialDiffuseColour);
    diffuseComponent = clamp(diffuseComponent, 0.0, 1.0);

    vec3 colourResult = max(diffuseComponent, ambientComponent);
    DataOut.colour = vec4(colourResult, 1.0);
    DataOut.texCoord = texCoord;
}

片段着色器:

#version 330

uniform sampler2D texUnit;

in Data {
    vec4 colour;
    vec2 texCoord;
} DataIn;

out vec4 fragColour;

void main() {

    if (DataIn.colour.w == 0.0){
        // Discard transparent fragments, so they don't affect the depth buffer
        discard;
    }

    vec4 texColour = texture(texUnit, DataIn.texCoord);
    fragColour = DataIn.colour * texColour;
}

你應該:

  • 暫時避免融合
  • glTexParameteri移至紋理加載/初始化中,因為它是紋理的一部分。 或使用采樣器
  • 調用glActiveTextureglBindTexture紋理加載
  • 檢查Shaders.texUnitLoc != -1
  • 在渲染中避免:
    • 綁定/解除綁定vao並添加glVertexAttribPointer
    • 調用glEnableVertexAttribArrayglBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); 因為那些是vao的一部分
  • GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); 當綁定vao時,將導致綁定的vao中的ebo / ibo解除綁定
  • 如果您不使用任何索引( glDrawArrays ),則無需取消綁定任何ebo / ibo
  • 由於調用了所有這些enableVertexAttribArray ,因此還應該調用glDisableVertexAttribArray(Shaders.PARAM_TEXTURE_COORDS);
  • 在着色器中定義相同的語義,例如:

    • #define VERTEX 0
    • #define VERTEX_NORMAL 1
    • #define MATERIAL_AMBIENT_COLOUR 2
    • #define MATERIAL_DIFFUSE_COLOUR 3
    • #define TEXTURE_COORDS 4

    並將它們相應地分配到各個location

  • 檢查紋理坐標
  • 暫時避免丟棄
  • fragColour = texColour寫上純色的fragColour = texColour

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM