gpt4 book ai didi

android - OpenGL 3.0 ES 中的错误纹理渲染

转载 作者:行者123 更新时间:2023-11-30 03:26:35 24 4
gpt4 key购买 nike

我正在尝试在 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;
}

fragment 着色器:

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

但是当我在 Android 上运行这段代码时,纹理没有正确放置。

Error using the texture

原始纹理是这样的:

Original texture

我做错了什么?

最佳答案

在您的着色器代码中,您没有任何颜色属性。您只有顶点位置和纹理坐标:

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 的属性索引连续为 0、1、2。这取决于硬件和 OpenGL 驱动程序。因此,您应该使用 glGetAttribLocation 来获取属性索引。
此外,您必须使用着色器代码中的所有属性。未使用的属性变为非 Activity 状态。这意味着它不会添加到资源中,也不会获得任何属性索引。


参见 OpenGL ES 2 Specifications - 2.10.4 Shader Variables - p. 32 :

A generic attribute variable is considered active if it is determined by the compiler and linker that the attribute may be accessed when the shader is executed. Attribute variables that are declared in a vertex shader but never used are not considered active. In cases where the compiler and linker cannot make a conclusive determination, an attribute will be considered active.

.....

To determine the set of active vertex attributes used by a program, and to determine their types, use the command:

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

.....

After a program object has been linked successfully, the bindings of attribute variable names to indices can be queried. The command

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

关于android - OpenGL 3.0 ES 中的错误纹理渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48217175/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com