LearnOpenGL(一) 渐变三角形

花一天的时间初探了OpenGL。最终的目标是完全理解OpenGL操作GPU的原理,以及shader编程的熟练运用。并最终做出一个3d物品的的视角,以及光照等的高级效果。

// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h> 
#include <iostream>
#include <string>
using namespace std;

int main()
{
	glewExperimental = GL_TRUE;
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
	glfwWindowHint(GLFW_CENTER_CURSOR, GL_TRUE);

	GLFWmonitor* currMonitor = glfwGetPrimaryMonitor();
	const GLFWvidmode *mode = glfwGetVideoMode(currMonitor);
	GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "LearnOpenGL2",nullptr, nullptr);
	glfwMakeContextCurrent(window);
	glewInit();
	int width;
	int height;
	glfwGetFramebufferSize(window, &width, &height);
	std::cout << width << std::endl;
	std::cout << height << std::endl;
// 	GLFWwindow* window2 = glfwCreateWindow(mode->width, mode->height, "LearnOpenGL2", nullptr, nullptr);
// 	glfwMakeContextCurrent(window2);
	if (window == nullptr)
	{
		//cout << "Failed to create GLFW window" << endl;
		glfwTerminate();
		return -1;
	}

	const GLubyte* name = glGetString(GL_VENDOR); //返回负责当前OpenGL实现厂商的名字
	const GLubyte* biaoshifu = glGetString(GL_RENDERER); //返回一个渲染器标识符,通常是个硬件平台
	const GLubyte* OpenGLVersion = glGetString(GL_VERSION); //返回当前OpenGL实现的版本号
	const GLubyte* gluVersion = glGetString(GLU_VERSION); //返回当前GLU工具库版本

	printf("OpenGL实现厂商的名字:%s\n", name);
	printf("渲染器标识符:%s\n", biaoshifu);
	printf("OpenGL实现的版本号:%s\n", OpenGLVersion);

	int x = 100;
	int y = 200;
	//窗口大小发生改变时的回调
	glfwSetWindowSizeCallback(window, (GLFWwindowsizefun)[](GLFWwindow* window, int width, int height) { std::cout << width << std::endl;
	std::cout << height << std::endl;
	});
	//设置关闭回调
	glfwSetKeyCallback(window, [](GLFWwindow * window,int key,int scancode, int action, int mode) {
		if (key == 299 && action == GLFW_PRESS) {
			glfwSetWindowShouldClose(window, GL_TRUE);
			}
	});
	std::cout << mode->blueBits << std::endl;
	std::cout << mode->greenBits << std::endl;
	std::cout << mode->redBits << std::endl;



//-----------------------------------------------------------------------顶点着色器

	GLuint vertexShader; //创建顶点着色器对象变量
	//顶点着色器源代码
	static const char *vertextShaderSrc =
		"#version 330\n"
		"layout (location = 0) in vec3 position;\n"
		"layout (location = 1) in vec3 vertex_colour;\n"
		"out vec3 colour;\n"
		"void main()\n"
		"{\n"
		"colour = vertex_colour;\n"
		"gl_Position = vec4(position.x,position.y,position.z,1.0);\n"
		"}\n";
	vertexShader = glCreateShader(GL_VERTEX_SHADER);//创建并返回一个shader对象
	glShaderSource(vertexShader,1,&vertextShaderSrc,NULL );//传入顶点着色器源代码与对象
	glCompileShader(vertexShader);

	//获取编译状态
	GLint success;
	GLchar  infoLog[512];
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
	if (!success) {
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		cout << "顶点着色器编译错误:" << infoLog << endl;
	}  
	else {
		cout << "顶点着色器编译成功" << endl;
	}
//------------------------------------------------------------------end

//------------------------------------------------------------------片段着色器
	GLuint fragmentShader;
	static const char *fragmentShaderSrc =
		"#version 330\n"
		"in vec3 colour;\n"
		"out vec4 color;\n"
		"void main()\n"
		"{\n"
		"color = vec4(colour,1.0f);\n"
		"}\n";
	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSrc, NULL);
	glCompileShader(fragmentShader);
	GLint success2;
	GLchar infoLogs2[512];
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success2);
	if (!success2) {
		glGetShaderInfoLog(fragmentShader, 512, NULL, infoLogs2);
		cout << "片段着色器编译错误:" << infoLogs2 << endl;
	}
	else
	{
		cout << "片段着色器编译成功" << endl;
	}

	//-------------------------------------------------------------------end

	//-------------------------------------------------------------------着色器程序
	GLuint shaderProgram;
	shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);

	//着色器编译成功后就可以将顶点和片段着色器对象删除
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);
	GLint success3;
	GLchar infoLogs3[512];
	glGetProgramiv(shaderProgram, GL_COMPILE_STATUS, &success3);
	if (!success3) {
		glGetProgramInfoLog(shaderProgram,512,NULL,infoLogs3);
		cout << "着色器程序编译错误:" << infoLogs3 << endl;
	}
	else
	{
		cout << "着色器程序编译成功" << endl;
	}
	//-------------------------------------------------------------------end

	//--------------------------------------------------------------------链接顶点属性
	GLfloat  vertex[] = {
		-0.5f,-0.5f,0.0f,
		0.5f,-0.5f,0.0f,
		0.0f,0.5f,0.0f,
	};

	GLfloat  vertex2[] = {
		1.0f, 0.0f,  0.0f,
		0.0f, 1.0f,  0.0f,
		0.0f, 0.0f,  1.0f,
	};

	GLfloat colours[] = {
	  1.0f, 0.0f,  0.0f,
	  0.0f, 1.0f,  0.0f,
	  0.0f, 0.0f,  1.0f,
	};

	GLuint VAO;//顶点数组对象
	glGenVertexArrays(1,&VAO);
	glBindVertexArray(VAO);//后面的VBO操作会被记录到该顶点数组对象,后面能直接用

	GLuint VBO;
	glGenBuffers(1, &VBO);//创建顶点缓冲对象(空),创建显存空间
	glBindBuffer(GL_ARRAY_BUFFER, VBO);//缓冲对象绑定到缓冲区,一个缓冲区只能有一个缓冲对象, 不然后面写入缓冲区不知道写入哪个对象,但是一个缓冲对象可以绑定多个缓冲区
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);//往缓冲区中的对象写入数据c
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);//设置顶点属性指针,使用的是此时绑定到GL_ARRAY_BUFFER的VBO顶点缓冲对象
	glEnableVertexAttribArray(0);//启用顶点属性,参数是顶点属性的位置

	GLuint VBO2;
	glGenBuffers(1, &VBO2);
	glBindBuffer(GL_ARRAY_BUFFER, VBO2);
	glBufferData(GL_ARRAY_BUFFER, sizeof(colours), colours, GL_STATIC_DRAW);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(1);
	glBindVertexArray(0);

	GLuint VAO2;
	glGenVertexArrays(1,&VAO2);
	glBindVertexArray(VAO2);

	GLuint VBO3;
	glGenBuffers(1, &VBO3);
	glBindBuffer(GL_ARRAY_BUFFER, VBO3);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex2), vertex2, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(0);//启用顶点属性,参数是顶点属性的位置	glBindVertexArray(0);

	GLuint VBO4;
	glGenBuffers(1, &VBO4);
	glBindBuffer(GL_ARRAY_BUFFER, VBO4);
	glBufferData(GL_ARRAY_BUFFER,sizeof(colours), colours, GL_STATIC_DRAW);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(1);
	glBindVertexArray(0);


// 	glEnable(GL_CULL_FACE);//剔除脸
// 	glCullFace(GL_BACK);//剔除背面
// 	glFrontFace(GL_CW); // GL_CCW为逆时针方向
	//--------------------------------------------------------------------end

	while (!glfwWindowShouldClose(window))
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glUseProgram(shaderProgram);//使用之前编译好的着色器程序
		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glBindVertexArray(0);

		glBindVertexArray(VAO2);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glBindVertexArray(0);
		glfwPollEvents();
		glfwSwapBuffers(window);
	}
	glfwTerminate();
	return 0;
}

这是效果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值