目录
第一个三角形与矩形(两个三角形)
普通着色和Shader类(代码及使用方法)
贴纹理(含全部代码以及stb_image.h的使用)
利用矩阵变换(缩放、旋转、位移),使用glm库
坐标系统,进入3D世界(深度测试)
本文只是给跟着我一起学OpenGL 的小白所写,仅是博主部分文章着色器代码的解读,不适合大神以及没有看之前文章的读者。
在文章中没有对着色器部分代码做解读,补充在这里。
main.cpp部分代码
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
顶点着色器部分代码
//点着色器
const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
#version 330 core 声明OpengGL版本,必不可少
layout (location = 0) in vec3 aPos; main中绑定的是0号,隔三个挖一次,所以location是等于0的,aPos是in变量,就读入了
gl_Position 是内建输出变量,把刚才得到的aPos加扩展的w变量赋值给gl_Position即可。
片段着色器部分代码
//片段着色器
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
FragColor 输出变量,给后续管线使用,前三个值对应RGB的三个值,后面默认1.0。0.0f代表0,1.0f代表255。
main.cpp中的代码
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(6);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3*sizeof(float)));
glEnableVertexAttribArray(7);
顶点着色器
#version 330 core
layout (location = 6) in vec3 aPos;
layout (location = 7) in vec3 aColor;
out vec4 vertexColor;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
vertexColor = vec4(aColor.x, aColor.y, aColor.z, 1.0);
}
layout (location = 6) in vec3 aPos; 顶点位置 main中使用的是6号,隔6个挖3个,因为顶点数组中还包含了颜色。
layout (location = 7) in vec3 aColor; 顶点颜色 main中使用的是7号,隔6个挖3个。
out vec4 vertexColor; 顶点颜色 输出向量,在片段着色器中就直接使用,不必写死在着色器中
#version 330 core
in vec4 vertexColor;
out vec4 FragColor;
void main()
{
FragColor = vertexColor;
}
in vec4 vertexColor; 顶点颜色 输入向量,是从顶点着色器输入的,直接给FragColor,这样颜色不必写死在着色器中
main.cpp中的代码
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(6);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(7);
glVertexAttribPointer(8, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(8);
//使用着色器
myShader->use();
glUniform1i(glGetUniformLocation(myShader->ID, "ourTexture"), 0); // 手动设置
myShader->setInt("ourFace", 3); // 或者使用着色器类设置
顶点着色器部分代码
#version 330 core
layout (location = 6) in vec3 aPos;
layout (location = 7) in vec3 aColor;
layout (location = 8) in vec2 aTexCoord;
out vec4 vertexColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
vertexColor = vec4(aColor.x, aColor.y, aColor.z, 1.0);
TexCoord = aTexCoord;
}
layout (location = 8) in vec2 aTexCoord; 纹理坐标 main函数中绑定的是6 7 8号,8号存的是纹理坐标,这次是隔8个挖一次。
out vec2 TexCoord; 纹理坐标 out型,输出到下一步
片段着色器部分代码
#version 330 core
out vec4 FragColor;
in vec4 vertexColor;
in vec2 TexCoord;
uniform sampler2D ourTexture;
uniform sampler2D ourFace;
void main()
{
//FragColor = vertexColor;
FragColor = mix(texture(ourTexture, TexCoord), texture(ourFace, TexCoord), 0.6)*vertexColor;
}
in vec2 TexCoord; 读入的纹理坐标
uniform sampler2D ourTexture; 二维纹理采样器 uniform变量在着色器外的main.cpp中也可使用
uniform sampler2D ourFace; 同理,第二张纹理对应的二维纹理采样器
GLSL内建的mix函数需要接受两个值作为参数,并对它们根据第三个参数进行线性插值。如果第三个值是0.0
,它会返回第一个输入;如果是1.0
,会返回第二个输入值。0.6
会返回40%
的第一个输入颜色和60%
的第二个输入颜色,即返回两个纹理的混合色。
main.cpp中的部分代码
unsigned int transformLoc = glGetUniformLocation(myShader->ID, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
顶点着色器部分代码
#version 330 core
layout (location = 6) in vec3 aPos;
layout (location = 7) in vec3 aColor;
layout (location = 8) in vec2 aTexCoord;
out vec4 vertexColor;
out vec2 TexCoord;
uniform mat4 transform;
void main()
{
gl_Position = transform * vec4(aPos.x, aPos.y, aPos.z, 1.0);
vertexColor = vec4(aColor.x, aColor.y, aColor.z, 1.0);
TexCoord = aTexCoord;
}
gl_Position = transform * vec4(aPos.x, aPos.y, aPos.z, 1.0); 利用矩阵乘法,改变顶点位置,这也是前面为什么补充w变量了。
main.cpp中的部分代码
unsigned int modelMatLoc = glGetUniformLocation(myShader->ID, "modelMat");
unsigned int viewMatLoc = glGetUniformLocation(myShader->ID, "viewMat");
unsigned int projMatLoc = glGetUniformLocation(myShader->ID, "projMat");
glUniformMatrix4fv(modelMatLoc, 1, GL_FALSE, glm::value_ptr(modelMat));
glUniformMatrix4fv(viewMatLoc, 1, GL_FALSE, glm::value_ptr(viewMat));
glUniformMatrix4fv(projMatLoc, 1, GL_FALSE, glm::value_ptr(projMat));
顶点着色器部分代码
#version 330 core
layout (location = 6) in vec3 aPos;
layout (location = 8) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;
void main()
{
gl_Position = projMat * viewMat * modelMat * vec4(aPos.x, aPos.y, aPos.z, 1.0);
TexCoord = aTexCoord;
}
gl_Position = projMat * viewMat * modelMat * vec4(aPos.x, aPos.y, aPos.z, 1.0); 乘了三个矩阵,实现更好的3d显示
更多OpenGL知识:现代OpenGL入门教程
有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。