OpenGL学习笔记(二)第一个三角形

话不多说直接上代码!

#include<iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include<GLFW/glfw3.h>

using namespace std;
void glfwInput(GLFWwindow* window);
const char* vertexShaderSource = 
"#version 330 core                     \n"
"layout(location = 0) in vec3 aPos;								  \n"
"void main(){	gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);}\n";
const char* fragmentShaderSource =
"#version 330 core								   \n"
"out vec4 FragColor;							   \n"
"void main()									   \n"
"{FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);}	   \n";

float vertices[] = {
	-0.5f, -0.5f, 0.0f,
	 0.5f, -0.5f, 0.0f,
	 0.0f,  0.5f, 0.0f
};


// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;

// The MAIN function, from here we start the application and run the game loop
int main(int argc, char* argv[])
{
	// Init GLFW
	glfwInit();
	// Set all the required options for GLFW
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

	// Create a GLFWwindow object that we can use for GLFW's functions
	GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
	glfwMakeContextCurrent(window);



	// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
	glewExperimental = GL_TRUE;
	// Initialize GLEW to setup the OpenGL Function pointers
	glewInit();

	// Define the viewport dimensions
	glViewport(0, 0, WIDTH, HEIGHT);

	GLuint VBO, VAO;//声明顶点缓冲,声明顶点数组用于管理顶点数据
	glGenVertexArrays(1, &VAO);//创建顶点数组,返回一个独一无二的整数,标识数组
	glGenBuffers(1, &VBO);//创建顶点缓冲,返回一个独一无二的整数,标识缓冲区

	glBindVertexArray(VAO);//绑定顶点数组
	glBindBuffer(GL_ARRAY_BUFFER, VBO);//绑定顶点缓冲
  //指定顶点数组的数据源为vertices,第四个参数代表显卡如何管理给定的数据,GL_STATIC_DRWA代表几乎不会改变
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	// 指定顶点属性的解析方式。即,如何从顶点缓冲获取相应的顶点属性和相应的颜色属性。或者说,顶点着色器中如何知道去哪个顶点属性分量重着色呢
   //对每一个顶点而言,属性有2种,一是位置属性,而是颜色属性,因此每六个浮点数决定了一个顶点的位置和颜色

    //顶点着色器中使用layout(location = 0)定义了position顶点属性的位置值(Location),因此第一个参数,代表属性分量的索引
    //参数二:顶点位置属性的维度,参数三:属性向量的数据类型,参数四:是否标准化;参数五,顶点位置属性的总字节长度,参数六:在缓冲数组中的偏移量,即起始位置
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(0);//启用属性0,因为默认是禁用的

	GLuint vertexShader, fragmentShader;//ID
	vertexShader = glCreateShader(GL_VERTEX_SHADER);//创建一个verterxShader
	glShaderSource(vertexShader,1,&vertexShaderSource,NULL);//获取到shader的源代码资源
	glCompileShader(vertexShader);//编译shader源代码
	fragmentShader=  glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);

	GLuint shaderProgram;
	shaderProgram = glCreateProgram();//创建shader渲染程序
	glAttachShader(shaderProgram,vertexShader);//附加vertexShader到渲染程序上
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);//链接上当前渲染程序


  //顶点数组对象(Vertex Array Object, VAO)的好处就是,当配置顶点属性指针时,你只需要将上面的代码调用执行一次,之后再绘制物体的时候只需要绑定相应的VAO就行了。如下文循环中的绑定再解绑
	glBindVertexArray(0); // 解绑 VAO
	// Game loop
	while (!glfwWindowShouldClose(window))
	{
	// 检查事件,调用相应的回调函数,如下文的glfwInput函数
		glfwInput(window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//渲染颜色到后台缓冲
		glClear(GL_COLOR_BUFFER_BIT);//清除前台缓冲


		glBindVertexArray(VAO);//每次循环都调用,绑定函数绑定VAO
		glUseProgram(shaderProgram);//使用渲染程序

		glDrawArrays(GL_TRIANGLES, 0, 3);//开始绘制三角形从0起始,画三组数值
		glBindVertexArray(0);//解绑

		// 切换屏幕缓冲区
		glfwSwapBuffers(window);
		glfwPollEvents();
	}
	// 清理资源
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glfwTerminate();//终止glfw
	return 0;
}

// Is called whenever a key is pressed/released via GLFW
void glfwInput(GLFWwindow* window)
{
	if (glfwGetKey(window,GLFW_KEY_ESCAPE)== GLFW_PRESS)
		glfwSetWindowShouldClose(window, GL_TRUE);
}

输出结果如下:

在这里插入图片描述
然后我们来画一个四边形。
由于OpenGL只能绘制三角形,所以如果要绘制四边形我们就得给出六个点,这样就很麻烦,于是我们便需要用到一个名叫EBO的东西,进行一下转换。
先修改一下顶点数组,并增加一个索引数组

float vertices[] = {
	-0.5f, -0.5f, 0.0f,
	 0.5f, -0.5f, 0.0f,
	 0.0f,  0.5f, 0.0f,
	 0.8f,  0.5f, 0.0f
};
GLuint indices[] = { 0,1,3,1,2,3 };

然后声明一下EBO并使用

   GLuint EBO;
	glGenBuffers(1, &EBO);//创建一个缓冲区
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);//绑定一个元素缓冲区
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//定义缓冲区中的数据,既对顶点数组的索引
	while (!glfwWindowShouldClose(window))
	{	
		glfwInput(window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		glBindVertexArray(VAO);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);//绑定EBO
		glUseProgram(shaderProgram);
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//绘制三角形,根据索引数组绘制6个顶点,索引数组类型为GL_UNSIGNED_INT,偏移值为0
		//glDrawArrays(GL_TRIANGLES, 0, 3);//开始绘制三角形从0起始,画三组数值
		//glBindVertexArray(0);//解绑
		glfwSwapBuffers(window);
		glfwPollEvents();
	}

后面与前面的不变。
然后就是看看效果图吧!
在这里插入图片描述
如果程序编译成功,却提示0xC0000005: 执行位置 0x00000000 时发生访问冲突。
就是少了下面两句

	glewExperimental = GL_TRUE;
	glewInit();

傅老师神笔镇楼:在这里插入图片描述
借鉴自:
https://www.cnblogs.com/nazhizq/p/6582375.html
https://www.bilibili.com/video/av24353839/?p=8
https://learnopengl.com/Getting-started/Hello-Triangle

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值