LearnOpengl_first

在这里插入图片描述
顶点数组对象:Vertex Array Object,VAO
顶点缓冲对象:Vertex Buffer Object,VBO
索引缓冲对象:Index Buffer Object,IBO

顶点着色器:转换坐标。
图元装配:将顶点装配成指定图元的形状,例如三角形、线段。
几何着色器:产生新的顶点,构造出新的图元。
光栅化:把图元映射为最终屏幕上相应的像素,生成供片段着色器使用的Fragment。
片段着色器:计算一个像素的最终颜色。
测试与混合:深度、模板、Alpha测试|混合。

标准化设备坐标(Normallized Device Coordinates,NDC)

顶点属性配置
一个顶点有如下几个属性:位置坐标,颜色,法线,切线,uv坐标。

顶点缓冲对象:

unsigned int VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//把用户定义的数据复制到当前绑定缓冲的函数

顶点着色器

#version 330 core
layout (location = 0) in vec3 aPos;//layout(location=0)定义了我们使用哪个顶点属性(位置、颜色、uv、法线、切线)
void main()
{
	gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}

编译着色器

unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
//检测shader是否编译成功
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if(!success)
{
	glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
	std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}

片段着色器

#version 330 core
out vec4 FragColor;
void main()
{
	FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
//编译片元着色器
unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);

//着色器程序对象

unsigned int shaderProgram;
shaderProgram = glCreateProgram();//创建一个着色器程序对象
glAttachShader(shaderProgram, vertexShader);//将之前编译的着色器附加到程序对象上
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);//将多个附加在程序对象上的shader链接
//检测链接着色器程序是否失败
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if(!success)
{
	glGetProgramInfoLog(vertexShader, 512, NULL, infoLog);
	std::cout << "ERROR::SHADER::VERTEX::LINK_FAILED\n" << infoLog << std::endl;
}
//激活着色器程序对象
glUseProgram(shaderProgram);
//在把着色器链接到程序对象以后,删除着色器对象
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

链接顶点属性

//我们使用一个顶点缓冲对象将顶点数据初始化到缓冲中
//建立了一个顶点着色器和一个片段着色器
//并告诉opengl该如何解释顶点数据
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
//第一个参数:指定我们要配置哪个顶点属性(位置、颜色、uv、法线、切线)
//第二个参数:顶点属性的大小,例如位置有三个分量
//第三个参数:数据类型
//第四个参数:数据是否被标准化
//第五个参数:步长(字节数)
//第六个参数:表示位置数据在缓冲中起始位置的偏移量

使用顶点数据绘制

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSource(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//设置顶点属性指针
glVertexAttibPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
//启用顶点属性
glEnableVertexAttribArray(0);

glUseProgram(shaderProgram);

顶点数组对象

unsigned int VAO;
glGenVertexArrays(1, &VAO);

//1.绑定VAO
glBindVertexArray(VAO);
//2.把顶点数组复制到缓冲中
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//3.设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//4.绘制物体
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
someOpenGLFunctionThatDrawsOurTriangle();
glDrawArrays(GL_TRIANGLES, 0, 3);
//将要绘制的图元类型
//顶点数组的起始索引
//将要绘制的顶点总数

索引缓冲对象

float vertices[] = {
    0.5f, 0.5f, 0.0f,   // 右上角
    0.5f, -0.5f, 0.0f,  // 右下角
    -0.5f, -0.5f, 0.0f, // 左下角
    -0.5f, 0.5f, 0.0f   // 左上角
};

unsigned int indices[] = { // 注意索引从0开始! 
    0, 1, 3, // 第一个三角形
    1, 2, 3  // 第二个三角形
};

unsigned int EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

在这里插入图片描述

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)//使用线框模式绘制
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)//使用填充模式绘制
tuple_find_first 是一个用于在 tuple 中查找第一个满足条件的元素的函数模板。它接受一个可调用对象作为参数,返回 tuple 中第一个满足该可调用对象的元素。如果没有找到符合条件的元素,则抛出 std::out_of_range 异常。 以下是 tuple_find_first 的函数模板定义: ``` template <typename Tuple, typename Predicate> decltype(auto) tuple_find_first(Tuple&& t, Predicate&& pred); ``` 其中,Tuple 是一个 std::tuple 类型的参数,表示要查找的元组;Predicate 是一个可调用对象类型的参数,表示查找条件。该函数模板返回符合条件的元素的引用(如果存在),否则抛出异常。 例如,以下代码展示了如何使用 tuple_find_first 函数查找元组中第一个奇数元素: ``` #include <iostream> #include <tuple> #include <stdexcept> template <typename Tuple, typename Predicate> decltype(auto) tuple_find_first(Tuple&& t, Predicate&& pred) { const std::size_t N = std::tuple_size<std::decay_t<Tuple>>::value; for (std::size_t i = 0; i < N; ++i) { if (pred(std::get<i>(std::forward<Tuple>(t)))) { return std::get<i>(std::forward<Tuple>(t)); } } throw std::out_of_range("No matching element found"); } int main() { auto t = std::make_tuple(2, 4, 3, 6, 8, 9); try { auto x = tuple_find_first(t, [](auto&& x) { return x % 2 != 0; }); std::cout << "Found first odd element: " << x << std::endl; } catch (const std::out_of_range& e) { std::cout << "No odd element found" << std::endl; } return 0; } ``` 输出结果为:Found first odd element: 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值