簡體   English   中英

OpenGL 3.0 ES中錯誤的紋理渲染

[英]Wrong texture rendering in OpenGL 3.0 ES

我試圖在Android中使用C ++渲染帶有紋理的簡單正方形,但是在使用紋理時遇到了一些麻煩。

這是准備OpenGL ES的代碼

// set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
float vertices[] = {
        // positions          // colors           // texture coords
        0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
        0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left
};
unsigned int indices[] = {
        0, 1, 3, // first triangle
        1, 2, 3  // second triangle
};

glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);

這里是頂點着色器:

attribute vec4 vertexPosition;
attribute vec2 vertexTexCoord;

varying vec2 texCoord;

void main()
{
   gl_Position = vec4(vertexPosition.x, vertexPosition.y, vertexPosition.z, 1.0);
   texCoord = vertexTexCoord;
}

和片段着色器:

precision mediump float;
uniform sampler2D texSampler2D;
varying vec2 texCoord;
void main()
{
    gl_FragColor = texture2D(texSampler2D, texCoord);
}

但是,當我在Android上運行此代碼時,紋理放置不正確。

使用紋理時出錯

原始紋理如下所示:

原始質感

我究竟做錯了什么?

在着色器代碼中,您沒有任何顏色屬性。 您只有頂點位置和紋理坐標:

attribute vec4 vertexPosition;
attribute vec2 vertexTexCoord;

但是在C ++代碼中,您定義並啟用了具有索引0、1和2的通用頂點屬性數組。尤其是紋理坐標與屬性索引2的關聯可能不起作用。

使用glGetAttribLocation獲取屬性的屬性索引(在glLinkProgram之后):

GLuint prog .....;   

GLint vert_loc = glGetAttribLocation(prog , "vertexPosition");
GLint texc_loc = glGetAttribLocation(prog , "texCoord");

然后像這樣更改代碼:

glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

// position attribute
glVertexAttribPointer(vert_loc, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(vert_loc);

// texture coord attribute
glVertexAttribPointer(texc_loc, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(texc_loc);


如果您使用具有頂點坐標,顏色屬性和紋理坐標的頂點着色器,則代碼可以工作:

attribute vec3 aPos;
attribute vec3 aColor;
attribute vec2 aTexCoord;

varying vec3 ourColor;
varying vec2 texCoord;

void main()
{
   gl_Position = vec4(aPos.xyz, 1.0);
   ourColor = aColor;
   texCoord = aTexCoord;
}

但是,不能保證aPosaColoraTexCoord的屬性索引分別為aPos 。這取決於硬件和OpenGL驅動程序。 因此,您應該使用glGetAttribLocation獲取屬性索引。
此外,您必須使用着色器代碼中的所有屬性。 未使用的屬性無效。 這意味着它不會添加到資源中,也不會獲得屬性索引。


請參見OpenGL ES 2規范-2.10.4着色器變量-p。 32

如果編譯器和鏈接器確定在執行着色器時可以訪問該屬性,則將其視為通用屬性變量。 在頂點着色器中聲明但從未使用過的屬性變量不被認為是活動的。 如果編譯器和鏈接器無法做出確定的確定,則將屬性視為活動的。

.....

要確定程序使用的活動頂點屬性集並確定其類型,請使用以下命令:

void GetActiveAttrib( uint program, uint index, sizei bufSize, sizei *length, int *size, enum *type, char *name );

.....

成功鏈接程序對象后,可以查詢屬性變量名稱與索引的綁定。 命令

int GetAttribLocation( uint program, const char *name );

着色器出現問題的地方。 我將着色器更改如下:

attribute vec3 aPos;
attribute vec3 aColor;
attribute vec2 aTexCoord;

varying vec3 ourColor;
varying vec2 texCoord;

void main()
{
   gl_Position = vec4(aPos.xyz, 1.0);
   ourColor = aColor;
   texCoord = aTexCoord;
}

和片段:

precision mediump float;

varying vec3 ourColor;
varying vec2 texCoord;

uniform sampler2D texSampler2D;

void main()
{
    gl_FragColor = texture2D(texSampler2D, texCoord);
}

但是有兩件事我不明白:

  1. 如果我刪除行ourColor = aColor; 從向量着色器我有同樣的問題,為什么?
  2. 現在的紋理是顛倒的,為什么呢? 截圖

暫無
暫無

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

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