2016-08-30 124 views
0

在學習OpenGL和我試圖繪製一個紅色三角形,但我的三角形保持黑色。我不能改變我的片段着色器的顏色

這是我的片段着色器的代碼:

#version 330 core 

out vec4 color; 

void main() 
{ 
    color = vec4(1,0,0,1); 
} 

我的着色器編譯沒有問題,我使用這個類使用着色器:

public class ShaderProgram 
{ 
    private final int programId; 

    private int vertexShaderId; 

    private int fragmentShaderId; 

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

    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. Code: " + shaderId); 
     } 

     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: " + glGetShaderInfoLog(programId, 1024)); 
     } 

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

    } 

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

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

    public void cleanup() { 
     unbind(); 
     if (programId != 0) { 
      if (vertexShaderId != 0) { 
       glDetachShader(programId, vertexShaderId); 
      } 
      if (fragmentShaderId != 0) { 
       glDetachShader(programId, fragmentShaderId); 
      } 
      glDeleteProgram(programId); 
     } 
    } 
} 

然後,這是我的遊戲類:

public class Game { 

    int vertexArrayID; 
    int vertexBufferID; 

    ShaderProgram fragmentShader; 
    ShaderProgram vertexShader; 

    float[] vertexData = 
     { 
      -1.0f, -1.0f, 0.0f, 
      1.0f, -1.0f, 0.0f, 
      0.0f, 1.0f, 0.0f, 
     }; 

    FloatBuffer vertexBuffer; 

    public Game() throws Exception { 
     vertexArrayID = glGenVertexArrays(); 
     glBindVertexArray(vertexArrayID); 

     vertexBufferID = glGenBuffers(); 
     glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID); 

     vertexBuffer = BufferUtils.createFloatBuffer(vertexData.length); 
     vertexBuffer.put(vertexData); 
     vertexBuffer.flip(); 

     glBufferData(GL_ARRAY_BUFFER, vertexBuffer,GL_STATIC_DRAW); 

     fragmentShader = new ShaderProgram(); 
     vertexShader = new ShaderProgram(); 

     fragmentShader.createFragmentShader(loadShader("fragmentShader.glsl")); 
     vertexShader.createVertexShader(loadShader("vertexShader.glsl")); 

     fragmentShader.link(); 
     vertexShader.link(); 
    } 

    public void update() 
    { 
     fragmentShader.bind(); 
     vertexShader.bind(); 

     glEnableVertexAttribArray(0); 
     glBindBuffer(GL_ARRAY_BUFFER,vertexBufferID); 
     glVertexAttribPointer(0,3,GL_FLOAT,false,0,0); 

     glDrawArrays(GL_TRIANGLES,0,3); 
     glDisableVertexAttribArray(0); 

     fragmentShader.unbind(); 
     vertexShader.unbind(); 
    } 

    private String loadShader(String input) { 
     String r = ""; 

     try { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(Game.class.getResourceAsStream("/shaders/" + input))); 
      String buffer = ""; 
      while ((buffer = reader.readLine()) != null) { 
       r += buffer + "\n"; 
      } 
      reader.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return r; 
    } 
} 

爲什麼我的三角形在此之後保持黑色?

+3

請提供一個合適的[mcve]。這還不足以正確診斷問題。特別是,看你的着色器/程序是如何被初始化和使用的,將會很有價值。既然你聲稱要學習OpenGL,你應該可以毫無問題地包含整個「主機」(即C++)代碼。 – Xirema

回答

6

看起來你誤解了OpenGL中的程序和着色器的使用。

Shader對象對應於OpenGL中的「着色器階段」,即頂點着色器或片段着色器或OpenGL圖形流水線中的其他可編程階段之一。

Program對象對應於着色器階段的組裝鏈,有時稱爲完整的「着色器」。

然而,在你的程序中,你似乎在做的是創建兩個程序,將頂點着色器附加到另一個上,並將片段着色器附加到另一個上,然後使用它們。據我所知,這不會導致OpenGL拋出一個錯誤(它只會使用基本的傳遞着色器,無論哪個階段丟失),但這也意味着只有其中一個階段在任何時候都會被激活,否定另一個。在你的情況,你update函數的代碼:

fragmentShader.bind(); 
vertexShader.bind(); 

是指僅使用頂點着色引擎,這就是爲什麼更改您的片段着色器是有沒有影響。

要修復此問題,請只創建一個ShaderProgram對象,並將Vertex和Fragment着色器源代碼連接到該對象,並分別調用create[X]Shader。鏈接一次,然後在update功能中,只需撥打use即可。該程序應該按照預期工作。

+0

謝謝你的解釋它的工作。 – JohnyBro

相關問題