[英]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;
}
但是,不能保證aPos
, aColor
和aTexCoord
的屬性索引分別為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);
}
但是有兩件事我不明白:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.