纹理

OpenGL 中的函数

数据流向:

pixels → Texture Object → 绑到某个 Unit 的 GL_TEXTURE_2D → sampler 保存单元编号

调用顺序:

glActiveTexture → glBindTexture → glTexImage2D → glUseProgram → glGetUniformLocation → glUniform1i

glUniform1i 写的是单元编号。

一些问题

上下文
  Texture Unit          glActiveTexture 选中
    GL_TEXTURE_2D       glBindTexture
      Texture Object    glGenTextures
  Buffer Target         glBindBuffer
    Buffer Object       glGenBuffers
  VAO                   glBindVertexArray
    VAO Object          glGenVertexArrays
  FBO                   glBindFramebuffer
    Attachment
      Texture / Renderbuffer
  Program               glUseProgram
    glCreateShader → 编译 → glCreateProgram → attach → link

FBO 附件和纹理单元是两条绑定。

C++ 代码

program 已链接,vao 已绑好索引缓冲,pixels 是解码后的紧密 RGBA8。

// ===========================
// 1. 创建 Texture Object
// ===========================

GLuint texture;
glGenTextures(1, &texture);


// ===========================
// 2. 选择 Texture Unit 0
// ===========================

glActiveTexture(GL_TEXTURE0);


// ===========================
// 3. 把 Texture Object
//    绑定到 Unit 0
// ===========================

glBindTexture(GL_TEXTURE_2D, texture);


// ===========================
// 4. 上传图片
// ===========================

glTexImage2D(
    GL_TEXTURE_2D,
    0,
    GL_RGBA,
    width,
    height,
    0,
    GL_RGBA,
    GL_UNSIGNED_BYTE,
    pixels
);

// 只上传了 level 0,缩小过滤设为 GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);


// ===========================
// 5. Shader 中的 sampler
//    指向 Unit 0
// ===========================

glUseProgram(program);

GLint texLocation =
    glGetUniformLocation(program, "tex");

glUniform1i(texLocation, 0);


// ===========================
// 6. 绘制
// ===========================

glBindVertexArray(vao);

glDrawElements(
    GL_TRIANGLES,
    6,
    GL_UNSIGNED_INT,
    nullptr
);

shader 代码

uv 由顶点着色器传入,一般在 [0, 1]。

#version 330 core

in vec2 uv;
out vec4 FragColor;

uniform sampler2D tex;

void main()
{
    FragColor = texture(tex, uv);
}