栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

【LearnOpenGL学习笔记】——02.三角形绘制

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【LearnOpenGL学习笔记】——02.三角形绘制

文章目录
    • 1.渲染管线了解
    • 2.绘制过程
    • 3.顶点缓冲对象
    • 4.索引缓冲对象
    • 5.代码展示
    • 6.运行结果
    • 7.练习(矩形绘制)
    • 8.关于7的异常解决

1.渲染管线了解

【Unity Shader 入门精要学习笔记】—— 01.渲染管线

2.绘制过程

(1)数据的输入与管理

①顶点输入(涉及3D到2D坐标变换)
②顶点缓冲对象的创建与类型绑定
③顶点数据的复制(复制到创建的缓冲中)

(2)对数据的处理(顶点着色器、片元着色器)
顶点着色器

①GLSL源码编写
②顶点着色器对象的创建与源码附着
③编译检测

片元着色器过程类似

(3)着色器程序编写

①创建着色器程序对象
②添加并链接各个着色器对象
③编译检测
④着色器程序对象激活
⑤删除着色器对象

(4)顶点属性链接

3.顶点缓冲对象

顶点数组对象(Vertex Array Object, VAO)可以像顶点缓冲对象那样被绑定,任何随后的顶点属性调用都会储存在这个VAO中。这样的好处就是,当配置顶点属性指针时,你只需要将那些调用执行一次,之后再绘制物体的时候只需要绑定相应的VAO就行了。这使在不同顶点数据和属性配置之间切换变得非常简单,只需要绑定不同的VAO就行了。刚刚设置的所有状态都将存储在VAO中

4.索引缓冲对象

原文链接

5.代码展示
#include 
#include 
#include 

//三角形绘制

//Callback Function:窗口大小被调整时调用
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
//输入判定,用于窗口绘制,输入ESC后退出窗口绘制
void processInput(GLFWwindow* window);


//settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

//GLSL(OpenGL Shader Language)
const char* vertexShaderSource = "#version 330 coren" //OpenGL版本与模式设置
"layout (location = 0) in vec3 aPos;n" //定义顶点属性的位置值
"void main()n"
"{n"
"    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);n" //点位置设置,没有进行点的变换
"}";

const char* fragmentShaderSource = "#version 330 coren"
"out vec4 FragColor;n"
"void main()n"
"{n"
"   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);n"
"}n";


int main() {
	// glfw:initialize and configure
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

	// glfw:window creation
	GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL02", NULL, NULL);
	if (window == NULL) {
		std::cout << "Failed to created GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	//注册callback函数
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	// glad: load all OpenGL function pointers
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}





	//shader program
	// ----------------------------
	//vertex shader
	unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);//顶点着色器对象创建
	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);//GLSL设置
	glCompileShader(vertexShader);//
	//编译检测
	int success;
	char infolog[512];
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);//success存储编译结果
	if (!success) {
		glGetShaderInfoLog(vertexShader, 512, NULL, infolog);
		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILEDn" << infolog << std::endl;
	}
	// fragment shader
	unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);
	//编译检测
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragmentShader, 512, NULL, infolog);
		std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILEDn" << infolog << std::endl;
	}
	//着色器链接
	unsigned int shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);
	//编译检测
	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
	if (!success) {
		glGetProgramInfoLog(shaderProgram, 512, NULL, infolog);
		std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILEDn" << infolog << std::endl;
	}
	//delete shader
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);




	//顶点属性链接
	float vertices[] = {
	-0.5f, -0.5f, 0.0f, // left  
	 0.5f, -0.5f, 0.0f, // right 
	 0.0f,  0.5f, 0.0f  // top   
	};
	unsigned int VBO, VAO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	//绑定顶点数组对象
	glBindVertexArray(VAO);
	//绑定顶点缓冲对象
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	//顶点数据的复制,第三个参数有三个可选
	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, 0);
	glBindVertexArray(0);




	// render loop
	while (!glfwWindowShouldClose(window)) {
		//input
		processInput(window);

		//渲染指令
		//.....
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		//绘制三角形
		glUseProgram(shaderProgram);
		glBindVertexArray(VAO);
		//glDrawArrays()使用当前激活的着色器,之前定义的顶点属性配置,和VBO的顶点数据(通过VAO间接绑定)来绘制图元。
		glDrawArrays(GL_TRIANGLES, 0, 3);

		//交换颜色缓冲 用于绘制
		glfwSwapBuffers(window);
		//检查是否触发事件,并调用对应回调函数
		glfwPollEvents();
	}

	//Delete
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glDeleteProgram(shaderProgram);

	//release resource 
	glfwTerminate();
	return 0;
}

//
void processInput(GLFWwindow* window) {
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);
}

//
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
	glViewport(0, 0, width, height);
}
6.运行结果

7.练习(矩形绘制)

(1)绘制两个三角形,在LearnOpenGL02的基础上,增加一组顶点,并且设置其使用的VAO、VBO,和之前一样传入数据后,在render loop绘制三角形



运行结果:

但是结束绘制窗口后报了异常:Run-Time Check Failure #2 - Stack around the variable ‘VAO2’ was corrupted. 堆栈损坏(寄,搞不懂,似乎是只能用索引做),这里放一个可能的解决方案

8.关于7的异常解决

不需要多个VBO、VAO,只需要在顶点属性数组里面增加第二个三角形的坐标,在绘制的时候增加绘制的点数即可

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/901908.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号