2017-04-08 53 views
-1

我有一個問題,弄清楚我最簡單的着色器是怎麼回事。這裏是我的頂點着色器:OpenGL4着色器(#version 410)意外的行爲

#version 410 core 

in vec3 position; 
in vec2 textureCoords; 
out vec2 color; 

void main(void) 
{ 

    gl_Position = vec4(position.x, position.y, position.z, 1.0); 
    color = vec2(1.0,0.5); 
} 

而片段着色器:

#version 410 core 

in vec2 color; 
out vec4 out_color; 

void main(void) 
{ 
    out_color = vec4(0.0, 1.0, 0.0, 1.0); 
} 

注意,顏色可變正從VS傳遞出FS並沒有真正做任何事情。這些着色器給我預期的結果是下面的圖片:

Render from the original shaders above

現在,如果我僅僅是從VS使用顏色變量傳遞textureCoords的FS沒有任何改變它改變了FS我的形象在右邊。因此,修改後的VS(和唯一的修改着色器)是:

#version 410 core 

in vec3 position; 
in vec2 textureCoords; 
out vec2 color; 

void main(void) 
{ 
    gl_Position = vec4(position.x, position.y, position.z, 1.0); 
    color = textureCoords; 
} 

這給了意想不到以下渲染(三角形轉移到右上角):

After the modification to the VS

我不明白爲什麼這是因爲我甚至沒有在FS中使用顏色變量。

這是怎麼發生的?我只是想把vec2傳給FS!我在這裏沒有看到什麼?

下面是一些額外的信息: GL信息: 支持GL版本:4.1 NVIDIA - 34年10月16日355.10.05.35f05 支持陰影郎鹹平:4.10

完整的代碼在這裏: complete code 切入點是測試的.cpp

這裏是我當前的頂點數組:

GLfloat PossibleVertices[] = { 
    // Left bottom triangle 
    0.0f, 0.5f, 0.0f, // v0 
    -0.5f, -0.5f, 0.0f, // v1 
    0.5f, -0.5f, 0.0f 
}; 

GLuint Indices[] = { 
    0, 1, 2 
}; 

GLfloat TextureCoords[] = 
{ 
    0.5f, 1.0f, // v0 
    0.0f, 0.0f, // v1 
    1.0f, 0.0f 
}; 

// Load data to VAO 
LoadToVAO(PossibleVertices, 9, Indices, 3, TextureCoords, 6); 

... 

LoadToVAO 
(
    GLfloat Positions[], GLuint PosArrySize, 
    GLuint Indices[], GLuint IndArrySize, 
    GLfloat TexCoords[], GLuint TCArrySize 
) 
{ 
    GLuint VaoID = CreateVAO(); 
    BindIndicesBufferVBO(Indices, IndArrySize); // Buffer Index - optimization 
    StoreDataInAttrList(0, 3, Positions, PosArrySize); 
    StoreDataInAttrList(1, 2, TexCoords, TCArrySize); 
    UnbindVAO(); 
    CGCore::RawModel* ret = new CGCore::RawModel(VaoID, IndArrySize); 
    return ret; 
} 

這裏是FUNC要求實際存儲數據到VAO。所謂的兩個頂點數組:

void CGCore::Loader::StoreDataInAttrList(GLuint AttrNumber, GLuint AttrSize, GLfloat Data[], GLuint DataSize) 
{ 
    GLuint VboID; 
    glGenBuffers(1,&VboID); 
    VBOContainer.push_back(VboID); 
    glBindBuffer(GL_ARRAY_BUFFER, VboID); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*DataSize, Data, GL_STATIC_DRAW); 
    glVertexAttribPointer(AttrNumber, AttrSize, GL_FLOAT, GL_FALSE, 0, (void*) 0); // write to VAO 
    glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind current VBO 
} 

這裏是ATTR綁定代碼:

void BindAttributes() 
{ 
    BindAttribute(0, "position"); 
    BindAttribute(1, "textureCoords"); 
} 

// and also ... 

void BindAttribute(int Attrib, const GLchar* VarName) 
{ 
    glBindAttribLocation(ProgramID, Attrib, VarName); 
} 

最後渲染代碼:

void CGCore::Renderer::Render(CGCore::TexturedModel* TexturedModelObj) 
{ 
    CGCore::RawModel* Model = TexturedModelObj->GetModel(); 
    glBindVertexArray(Model->GetVaoID()); 
    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 
    glActiveTexture(GL_TEXTURE0); 
    glDrawElements(GL_TRIANGLES, Model->GetVertexCount(), GL_UNSIGNED_INT, (void*) 0); 
    glBindTexture(GL_TEXTURE_2D, TexturedModelObj->GetTexture()->GetTextureID()); 
    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 
    glBindVertexArray(0); 
} 

很抱歉的長期職位。感謝名單!

+1

請顯示圖紙代碼。我的猜測是你搞砸了數據或屬性指針。 – BDL

+0

我編輯github鏈接到繪圖代碼。但是,如果vec2沒有以任何方式被使用,那麼如何將vec2賦值給out vec2 shift頂點?爲什麼downvote它是一個合法的q? –

+1

例如,可能存在屬性位置的問題。如果你在VS中不使用'textureCoords',那麼它是不活動的,並且會被優化掉。現在,當您使用它時,它將處於活動狀態並將獲得指定位置。如果你沒有在你的代碼中正確處理這些位置,你可以畫一些其他的東西。 – BDL

回答

-1

經過試驗,經歷了大量的OpenGL文檔等,我終於解決了我的問題。與一些評論相反,問題在於頂點着色器。即變量的聲明。在VS下面的變化給我的預期輸出:

#version 410 core 
layout (location = 0) in vec3 position; 
layout (location = 1) in vec2 textureCoords; 

out vec2 TexCoord; 

void main() 
{ 
    gl_Position = vec4(position, 1.0f); 
    TexCoord = textureCoords; 
} 

所以我在做什麼是明確指定的位置在VOA PARAMS PARAMS中聲明的時候。我想它與頂點着色器(v4.10)的版本有關,但我不確定。在任何情況下,通過聲明類似var 佈局(位置= X)來指定attr位置var_name

+0

您正在得出錯誤的結論。 @ BDL的評論是重點。事實上,通過使用另一種方式來指定這些位置,可以解決錯誤地使用'glBindAttribLocation'這一事實並不意味着使用'glBindAttribLocation'是錯誤的,或者GLSL 4.10在這方面的行爲不同。 – derhass