以前随便找点代码,改吧改吧就能跑,今天算是入门学习了一下。 顶点着色器、几何着色器、片段着色器。又酷又通透 ——
相关代码
https://www.uni-marburg.de/en/fb12/research-groups/grafikmultimedia/lectures/graphics
https://www.mathematik.uni-marburg.de/~thormae/lectures/graphics1/graphics_9_1_eng_web.html
OpenGL Step by Step - OpenGL Development
1988 年 5 月,Pixar 公布了第三版 RenderMan 规范,将“着色器”的使用推广到了我们目前所知的各大应用领域。
随着图形处理器的进步,OpenGL 和 Direct3D 等主要的图形软件库都开始支持着色器。 第一批支持着色器的 GPU 仅支持像素着色器,但随着开发者逐渐认识到着色器的强大,很快便出现了顶点着色器。 2000 年,第一款支持可编程像素着色器的显卡 Nvidia GeForce 3(NV20)问世。Direct3D 10 和 OpenGL 3.2 则引入了几何着色器。
https://ke.qq.com/course/package/25480?flowToken=1019441
https://learnopengl-cn.github.io/
几个完整得范例:https://github.com/hawkhai/openglcpp.git
matrices.modelView = glm::mat4(1.0);
glDrawElementsInstanced
。错误 LNK2019 无法解析的外部符号 __imp__vsnprintf,该符号在函数 __glfwInputError 中被引用 LearnOpenGL E:\kSource\LearnOpenGLk\LearnOpenGL\glfw3.lib(init.obj) 1
原因:问题是 glfw 静态 libs 是用与您正在使用的版本不同的 visual studio 版本构建的。
你也可以添加一个额外的库到你的链接器输入,即 legacy_stdio_definitions.lib。进入“属性”>“链接器”>“输入”。在其他依赖项中添加上面提到的库。https://zgserver.com/parsing-6.html
Khronos 组织在 GDC 2015 大会上发布了 Vulkan API。关于 Vulkan 的细节,类似于 AMD Mantle 和微软 DirectX 12,Vulkan 是一个底层 3D 图形 API,允许开发者获得硬件底层控制能力,同时减少性能开销,Vulkan 为开发人员提供通常留给驱动程序的控制能力,如线程管理,内存管理和错误检查等等功能。
Standard, Portable Intermediate Representation - V (SPIR-V) OpenGL 4.6 的最大变化就是 支持 SPIR-V,一种用于 GPU 通用计算和图形学的中间语言,Khronos 开发设计,最初是为 OpenCL 规范准备的,和下一代图形标准 Vulkan 差不多同时提出,也在不断发展完善。
struct UboInstanceData {
// Model matrix for each instance
glm::mat4 model;
// Color for each instance
// vec4 is used due to memory alignment
// GPU aligns at 16 bytes
glm::vec4 color;
};
glGenBuffers(1, &UBOInst);
glBindBuffer(GL_UNIFORM_BUFFER, UBOInst);
glBufferData(GL_UNIFORM_BUFFER, uboInstance.size() * sizeof(UboInstanceData), uboInstance.data(), GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBuffer(GL_UNIFORM_BUFFER, UBO);
GLvoid* p = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY);
memcpy(p, &uboVS, sizeof(uboVS));
glUnmapBuffer(GL_UNIFORM_BUFFER);
struct GlobalMatricesData {
// Global matrices
struct MatricesData {
glm::mat4 projection;
glm::mat4 view;
} matrices;
// Seperate data for each instance
} uboVS;
// Uniform buffer object
glGenBuffers(1, &UBO);
glBindBuffer(GL_UNIFORM_BUFFER, UBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(uboVS), &uboVS, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBuffer(GL_UNIFORM_BUFFER, UBOInst);
GLvoid* p = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY);
memcpy(p, uboInstance.data(), uboSize);
glUnmapBuffer(GL_UNIFORM_BUFFER);
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (location = 0) in vec3 inPos;
layout (location = 1) in vec3 inNormal;
layout (location = 3) in vec3 inColor;
struct Instance
{
mat4 model;
vec4 color;
};
layout (binding = 0) uniform UBO
{
mat4 projection;
mat4 view;
} ubo;
layout (binding = 1) uniform UBOInst
{
Instance instance[343];
} uboinstance;
layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec3 outColor;
layout (location = 2) out vec3 outEyePos;
layout (location = 3) out vec3 outLightVec;
void main()
{
outNormal = inNormal;
outColor = inColor;
outColor = uboinstance.instance[gl_InstanceID].color.rgb;
mat4 modelView = ubo.view * uboinstance.instance[gl_InstanceID].model;
gl_Position = ubo.projection * modelView * vec4(inPos.xyz, 1.0);
outEyePos = (gl_Position).xyz;
vec4 lightPos = vec4(0.0, 0.0, 0.0, 1.0) * modelView;
outLightVec = normalize(lightPos.xyz - outEyePos);
}
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (location = 0) in vec3 inNormal;
layout (location = 1) in vec3 inColor;
layout (location = 2) in vec3 inEyePos;
layout (location = 3) in vec3 inLightVec;
layout (location = 0) out vec4 outFragColor;
void main()
{
vec3 N = normalize(inNormal);
vec3 L = normalize(vec3(1.0));
vec3 Eye = normalize(-inEyePos);
vec3 Reflected = normalize(reflect(-inLightVec, inNormal));
vec4 IAmbient = vec4(vec3(0.1), 1.0);
vec4 IDiffuse = vec4(1.0) * max(dot(inNormal, inLightVec), 0.0);
float specular = 0.75;
vec4 ISpecular = vec4(0.5, 0.5, 0.5, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 4.0) * specular;
outFragColor = vec4((IAmbient + IDiffuse) * vec4(inColor, 1.0) + ISpecular);
}
状态机上下文软件环境
状态机:当前绘制状态、光照设置、纹理设置、材质设置。
GLFW 窗口
生成窗口,支持 OpenGL 上下文。
GLAD
用户画图。
顶点数组对象 VAO 顶点缓冲对象 VBO
输入:3D 坐标;输出:2D 像素。
FragmentShader 片段着色器
VertexShader 顶点着色器
索引缓冲对象 EBO
其中在渲染的时候有多重的组合方式:
VBO / VAO / EBO
建议使用顶点缓冲区,但是是否索引可以参考他们的优劣:
glDrawArrays
传输或指定的数据是最终的真实数据,在绘制时效能更好glDrawElements
指定的是真实数据的调用索引,在内存 / 显存占用上更节省GLSL 数据传输
VBO 中存放多种属性
一个 VAO 对应多个 VBO
// Default VAO needed for OpenGL 3.3+ core profiles
void setVertexEnv() {
float vertices[] = {
-0.5f, -0.5f, 0.0f, // left, down
0.5f, -0.5f, 0.0f, // right, down
-0.5f, 0.5f, 0.0f, // left, top
};
float colors[] = {
1, 0, 0, // left, down
0, 1, 0, // right, down
0, 0, 1, // left, top
};
unsigned int VAO; // VAO: vertex array object
unsigned int VBO[2]; // VBO: vertex buffer object
glGenVertexArrays(1, &VAO);
glGenBuffers(2, VBO);
// 绑定当前上下文
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
}
shader 类封装
加载显示纹理
纹理过滤
纹理单元
齐次坐标
线性代数基础:三维里沿着 x 轴旋转
线性代数基础:变换
glm
缩放旋转位移顺序问题
坐标系统
坐标系实例
立方体
摄像机
LookAt
摄像机 WASD 空指
摄像机旋转缩放
代码整理 Camera 封装
// i 表示 32 位整形
// f 表示 32 位浮点型
// ub 表示 8 位无符号 byte
// ui 表示 32 位无符号整形
// v 表示接受相应的指针类型
void setInt(int value) glUniform1i(value);
void setBool(bool value) glUniform1i((int)value);
void setFloat(float value) glUniform1f(value);
void setVec2(glm::vec2 &value) glUniform2fv(1, &value[0]);
void setVec3(glm::vec3 &value) glUniform3fv(1, &value[0]);
void setVec4(glm::vec4 &value) glUniform4fv(1, &value[0]);
void setVec2(float x, float y) glUniform2f(x, y);
void setVec3(float x, float y, float z) glUniform3f(x, y, z);
void setVec4(float x, float y, float z, float w) glUniform4f(x, y, z, w);
void setMat2(glm::mat2 &mat) glUniformMatrix2fv(1, &mat[0][0]);
void setMat3(glm::mat3 &mat) glUniformMatrix3fv(1, &mat[0][0]);
void setMat4(glm::mat4 &mat) glUniformMatrix4fv(1, &mat[0][0]);