天空盒是全黑的

Skybox is completely black

我正在按照 Youtube 上的 ThinMatrix 指南尝试为我的引擎创建一个天空盒。但是,我的天空盒变黑了。我已经尝试了人们在评论中提出的所有不同建议和常见错误,我终其一生都无法弄清楚它有什么问题。

我也没有收到任何错误:/

下面是相关类中的相关方法。如果需要,我可以提供更多代码。

Loader.java

 public int loadCubeMap(String[] cubeMapTextures) { 
        int textureID = GL11.glGenTextures(); 

        GL13.glActiveTexture(GL13.GL_TEXTURE0); 
        GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, textureID); 

        for (int i = 0; i < cubeMapTextures.length; i++) { 
          TextureData data = decodeTexture("res/skybox/" + cubeMapTextures[i] + ".png"); 

          GL11.glTexImage2D(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL11.GL_RGBA, data.getWidth(), data.getHeight(), 
              0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, data.getBuffer()); 
        } 

        GL11.glTexParameteri(GL13.GL_PROXY_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); 
        GL11.glTexParameteri(GL13.GL_PROXY_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); 
        GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); 
        GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); 

        textures.add(textureID); 
        return textureID; 
      } 

      private TextureData decodeTexture(String fileName) { 
        int width = 0; 
        int height = 0; 
        ByteBuffer buffer = null; 

        try { 
          FileInputStream in = new FileInputStream(fileName); 
          PNGDecoder decoder = new PNGDecoder(in); 

          width = decoder.getWidth(); 
          height = decoder.getHeight(); 
          buffer = ByteBuffer.allocateDirect(4 * width * height); 
          decoder.decode(buffer, width * 4, Format.RGBA); 

          buffer.flip(); 
          in.close(); 
        } catch (Exception e) { 
          e.printStackTrace(); 
          System.err.println("Failed loading:  " + fileName); 
          System.exit(-1); 
        } 

        return new TextureData(height, width, buffer); 
      } 

SkyboxRenderer.java

private static final float SIZE = 500f;
private static final float[] VERTICES = {        
    -SIZE,  SIZE, -SIZE,
    -SIZE, -SIZE, -SIZE,
    SIZE, -SIZE, -SIZE,
     SIZE, -SIZE, -SIZE,
     SIZE,  SIZE, -SIZE,
    -SIZE,  SIZE, -SIZE,

    -SIZE, -SIZE,  SIZE,
    -SIZE, -SIZE, -SIZE,
    -SIZE,  SIZE, -SIZE,
    -SIZE,  SIZE, -SIZE,
    -SIZE,  SIZE,  SIZE,
    -SIZE, -SIZE,  SIZE,

     SIZE, -SIZE, -SIZE,
     SIZE, -SIZE,  SIZE,
     SIZE,  SIZE,  SIZE,
     SIZE,  SIZE,  SIZE,
     SIZE,  SIZE, -SIZE,
     SIZE, -SIZE, -SIZE,

    -SIZE, -SIZE,  SIZE,
    -SIZE,  SIZE,  SIZE,
     SIZE,  SIZE,  SIZE,
     SIZE,  SIZE,  SIZE,
     SIZE, -SIZE,  SIZE,
    -SIZE, -SIZE,  SIZE,

    -SIZE,  SIZE, -SIZE,
     SIZE,  SIZE, -SIZE,
     SIZE,  SIZE,  SIZE,
     SIZE,  SIZE,  SIZE,
    -SIZE,  SIZE,  SIZE,
    -SIZE,  SIZE, -SIZE,

    -SIZE, -SIZE, -SIZE,
    -SIZE, -SIZE,  SIZE,
     SIZE, -SIZE, -SIZE,
     SIZE, -SIZE, -SIZE,
    -SIZE, -SIZE,  SIZE,
     SIZE, -SIZE,  SIZE
};

private static String[] textureFiles = {"stormydays_rt", "stormydays_lf", "stormydays_up", "stormydays_dn", "stormydays_bk", "stormydays_ft"};

private RawModel cube;
private int textureID;
private SkyboxShader shader;

public SkyBoxRenderer(Loader loader, Matrix4f projectionMatrix) {
    cube = loader.loadToVAO(VERTICES, 3);
    textureID = loader.loadCubeMap(textureFiles);
    shader = new SkyboxShader();
    shader.start();
    shader.loadProjectionMatrix(projectionMatrix);
    shader.stop();
}

public void render(Camera camera) {
    shader.start();
    shader.loadViewMatrix(camera);

    GL30.glBindVertexArray(cube.getVaoID());
    GL20.glEnableVertexAttribArray(0);
    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, textureID);
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, cube.getVertexCount());
    GL20.glDisableVertexAttribArray(0);
    GL30.glBindVertexArray(0);

    shader.stop();
}

SkyboxShader.java

 private static final String VERTEX_FILE = "src/shaders/skyboxVertexShader.txt"; 
  private static final String FRAGMENT_FILE = "src/shaders/skyboxFragmentShader.txt"; 

  private int location_projectionMatrix; 
  private int location_viewMatrix; 

  public SkyboxShader() { 
      super(VERTEX_FILE, FRAGMENT_FILE); 
  } 

  public void loadProjectionMatrix(Matrix4f matrix){ 
      super.loadMatrix(location_projectionMatrix, matrix); 
  } 

  public void loadViewMatrix(Camera camera){ 
      Matrix4f matrix = Maths.createViewMatrix(camera); 
      super.loadMatrix(location_viewMatrix, matrix); 
  } 

  @Override 
  protected void getAllUniformLocations() { 
      location_projectionMatrix = super.getUniformLocation("projectionMatrix"); 
      location_viewMatrix = super.getUniformLocation("viewMatrix"); 
  } 

  @Override 
  protected void bindAttributes() { 
      super.bindAttribute(0, "position"); 
  } 

这是我的 GLSL 代码 天空盒顶点着色器

#version 400

in vec3 position;
out vec3 textureCoords;

uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;

void main(void){

    gl_Position = projectionMatrix * viewMatrix * vec4(position, 1.0); 
    textureCoords = position;

}

天空盒片段着色器

#version 400

in vec3 textureCoords;
out vec4 out_Color;

uniform samplerCube cubeMap;

void main(void){
    out_Color = texture(cubeMap, textureCoords);
}

这可能是因为纹理不完整。 要完成立方体贴图纹理,您必须将 GL_TEXTURE_WRAP_R 设置为 glTexParameteri,因为立方体是 3D 的。 此外,您使用的是 GL_PROXY_TEXTURE_CUBE_MAP 而不是 GL_TEXTURE_CUBE_MAP,这不起作用,因为代理纹理不是 a valid parameter.

所以只需替换:

GL11.glTexParameteri(GL13.GL_PROXY_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); 
GL11.glTexParameteri(GL13.GL_PROXY_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); 
GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); 
GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); 

有:

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

如果这没有帮助,请确认所有纹理都具有相同的大小。

PS:用import static GL##.*;,那么可以写methodName()代替GL##.methodName() (##换成数字)