gpt4 book ai didi

c++ - 在 OpenGL 中将纹理传递给着色器

转载 作者:搜寻专家 更新时间:2023-10-31 01:40:16 25 4
gpt4 key购买 nike

我正在处理一些示例,我正在尝试将纹理传递给着色器。

要构建一个 VAO,我有这段代码:

void PlaneShaderProgram::BuildVAO()
{
// Generate and bind the vertex array object
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);

// Generate and bind the vertex buffer object
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), _coordinates, GL_STATIC_DRAW);

// Generate and bind the index buffer object
glGenBuffers(1, &_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), _indexes, GL_STATIC_DRAW);

// Generate and bind texture
_texture = LoadTexture("floor.bmp");

LoadAttributeVariables();

glBindVertexArray(0);
}

这是我加载着色器属性的方式:

void PlaneShaderProgram::LoadAttributeVariables()
{
GLuint VertexPosition_location = glGetAttribLocation(GetProgramID(), "vPosition");
glEnableVertexAttribArray(VertexPosition_location);

glVertexAttribPointer(VertexPosition_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
}

void PlaneShaderProgram::LoadUniformVariables()
{
// OpenGL Matrices
GLuint ModelViewProjection_location = glGetUniformLocation(GetProgramID(), "mvpMatrix");
glUniformMatrix4fv(ModelViewProjection_location, 1, GL_FALSE, glm::value_ptr(_ModelViewProjection));

// Floor texture
// glActiveTexture(GL_TEXTURE0);
// glBindTexture(GL_TEXTURE_2D, _texture);
// GLint Texture_location = glGetUniformLocation(GetProgramID(), "texture");
// glUniform1i(Texture_location, 0);
}

还有我的LoatTexture:

GLuint ProgramManager::LoadTexture(const char* imagepath)
{
unsigned char * data = LoadBMP(imagepath, &width, &height);

GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

return textureID;
}

最后,在 OpenGL 主循环中调用的我的绘制函数如下:

void PlaneShaderProgram::DrawPlane(const glm::mat4 &Projection, const glm::mat4 &ModelView)
{
_ModelViewProjection = Projection * ModelView;
_ModelView = ModelView;

Bind();

glBindVertexArray(_vao);
LoadUniformVariables();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);

UnBind();
}

我没有得到的是,即使我没有设置我的着色器使用的统一纹理(在代码中注释),平面仍然使用纹理绘制。这对我来说毫无意义。一旦着色器需要 sample2D,我认为这不应该工作并返回一些错误。

顶点着色器:

uniform mat4 mvpMatrix;
in vec4 vPosition;

smooth out vec2 uvCoord;

void main()
{
uvCoord = vPosition.xz;
gl_Position = mvpMatrix * vPosition;
}

片段着色器:

uniform sampler2D texture;
in vec2 uvCoord;

out vec4 fragColor;
void main()
{
fragColor.rgb = texture(texture, uvCoord).rgb;
};

我错过了什么吗?不知何故,我不明白为什么,但我真的很喜欢。

最佳答案

GLSL 中的采样器 数据类型引用纹理单元,而不是纹理对象。默认情况下,uniform 会被初始化为 0,所以如果你没有设置 sampler uniform,它们将从纹理单元 0(这也是默认单元)采样。在您的 ProgramManager::LoadTexture() 方法中,您绑定(bind)了新创建的纹理,很可能您仍在使用 GL_TEXTURE0 作为当前事件的纹理单元。你似乎永远不会取消绑定(bind)它,所以它在绘制调用时仍然是绑定(bind)的,着色器可以访问它。

关于c++ - 在 OpenGL 中将纹理传递给着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30014617/

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