OpenGL 2D贴图texture与着色器Shader

OpenGL 2D贴图texture与着色器Shader

运行效果

利用GLSL操作shader着色器实现平移、纹理与顶点颜色的叠加处理:

利用GLSL操作shader着色器实现平移、旋转等操作:

定义纹理ID与绑定纹理

GLfloat vertices2[] = {
    // 坐标             // 颜色       // 纹理
    0.5f,  0.5f, 0.0f,  1.0f, 1.0f,  0.0f, 1.0f, 1.0f, // 右上 黄
    0.5f, -0.5f, 0.0f,  1.0f, 0.0f,  1.0f, 1.0f, 0.0f, // 右下 品
   -0.5f, -0.5f, 0.0f,  0.0f, 1.0f,  1.0f, 0.0f, 0.0f, // 左下 青
   -0.5f,  0.5f, 0.0f,  0.0f, 0.0f,  0.0f, 0.0f, 1.0f  // 左上 黑
};
GLuint indices[] = {
    0, 1, 3,    // 起始顶点:右上 -> 右下 -> 左上
    1, 2, 3     // 第二顶点:右下 -> 左下 -> 左上
};
GLuint texture;
glGenTextures(1, &texture); 			// 纹理ID
glBindTexture(GL_TEXTURE_2D, texture);	// 将纹理ID绑定到目标'GL_TEXTURE_2D'
// 纹理属性
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
// 为当前绑定的纹理对象设置环绕、过滤方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);       // 环绕方式x方向 重复
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);       // y 方向重复
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);   // 纹理缩小时的过滤方式 线性
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   // 纹理放大时的过滤方式 线性 or GL_NEAREST 相邻
// 载入纹理
IMG imageA;                                            // 定义 IMG 对象
loadImg(&imageA, "src/textures/ash_uvgrid01.jpg");     // 将纹理数据加载到 IMG 对象指针
if (imageA.data) 
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageA.width, imageA.height, 0, GL_RGB, GL_UNSIGNED_BYTE, imageA.data);
    glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
    std::cout << "Texture加载失败!" << std::endl;
}
// 释放纹理图像数据(已加载到GL_TEXTURE_2D目标了)
stbi_image_free(imageA.data);

主循环中渲染部分:

// 变换
glm::mat4 transform = glm::mat4(1.0f);
transform = move(transform, moveX, moveY);
transform = scale(transform, scaleX, scaleY);
ourShader.setMat4("transform", transform);

// 设置颜色与纹理贴图的叠加系数
ourShader.setFloat("coefficient", coefficient);

// 渲染容器
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

对应在主循环结束后的释放:

glDeleteBuffers(1, &texture);

纹理textures与着色器shader

片段着色器程序代码:

#version 330 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform float coefficient;		// 叠加系数

uniform sampler2D ourTexture;

void main()
{
    // FragColor = vec4(ourColor, 1.0f);
    // 纹理vec2 * 颜色vec4 * 系数float (纹理与顶点颜色混合) not texture mix texture
    FragColor = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0f) * coefficient;
    // 如果我们要将两个纹理混合可以:
    // FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
    // 20% - 80% (0.2 to 0.8)
}

顶点着色器代码:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord; // 顶点缓冲对象中描述纹理的顶点数据的position

out vec3 ourColor;
out vec2 TexCoord;

uniform mat4 transform;

void main()
{
    gl_Position = transform * vec4(aPos, 1.0f);
    ourColor = aColor;
    TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

在主循环中,对coefficient的设置,就是让片段着色器使用这个全局变量,而我们对鼠标滚轮事件回调后,通过滚动滚轮就可以实现着色器对纹理贴图和顶点颜色的属性进行叠加控制。

主循环中的设置:

// 设置颜色与纹理贴图的叠加系数
ourShader.setFloat("coefficient", coefficient);

鼠标滚轮事件回调函数处理滚轮滚动:

// 滚轮回调
void scrollCall(GLFWwindow* window, GLdouble xoffset, GLdouble yoffset)
{
    GLfloat inc = 0.1f;
    if (yoffset == 1)
    {
        coefficient += inc;
        if (coefficient > 10.0f)
        {
            coefficient = 10.0f;
        }
    }
    if (yoffset == -1)
    {
        coefficient -= inc;
        if (coefficient < 0.0f)
        {
            coefficient = 0.0f;
        }
    }
}

旋转

声明/定义:

glm::mat4 rotate(glm::mat4 &t, GLfloat a, GLfloat x, GLfloat y, GLfloat z);

x, y, z 为定义旋转的轴

// 旋转
glm::mat4 rotate(glm::mat4 &t, GLfloat a, GLfloat x, GLfloat y, GLfloat z)
{
    return glm::rotate(t, a, glm::vec3(x, y, z));
}

主循环中的旋转矩阵操作,以及shader操作:

// 变换
glm::mat4 transform = glm::mat4(1.0f);
transform = move(transform, moveX, moveY);
// transform = scale(transform, scaleX, scaleY);
transform = rotate(transform, (GLfloat)glfwGetTime(), 0.0f, 0.0f, 0.1f);
ourShader.setMat4("transform", transform);

// 设置颜色与纹理贴图的叠加系数
ourShader.setFloat("coefficient", coefficient);

完整代码:

你可能感兴趣的:(OpenGL)