【由浅入深OpenGL】一:Visual Studio下搭建OpenGL开发环境

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuyizhou95/article/details/80170079

万事开头难!

理论与实践结合才能产生价值,很多人学习OpengGL碰到的第一件事情就是配置环境

首先需要下载GLFW 与GLEW包,建议都下载32位的

http://www.glfw.org/

http://glew.sourceforge.net/


1.首先打开Visual Studio创建项目工程,现在很多时候如果我们选择创建控制台程序就会生成stdafx.文件等比较不必要的东西,所以我们直接创建一个空项目

2.创建完毕后,源文件中新建main.cpp文件,这时候我们就可以比较干净的书写代码了


3.接下来就是比较重要的环境配置GLFW与GLEW的配置环节,其实不管动态还是静态的链接目的都是一个将GLFW与GLEW的include库文件与lib库文件引入到Visual Studio的环境中

    右击项目,点击属性,弹出项目属性配置窗口,在VC++目录下,首先看一下个人计算机装配Visual Studio时引入的默认的include 与lib库文件的路径,两种方式

  (1)将GLFW与GLEW的include 与lib库文件中的内容复制到visual studio指定目录下,

    比如我这里分别是

     H:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\include

     H:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\lib\x86

  


   (2)在弹出的目录文件窗口中,新增GLFW与GLEW的include 与lib库文件路径,点击包含目录中的空白块右上方的新增按钮,引入GLFW与GLEW的include 与lib库路径。

            比如我这里是

    C:\Users\admin\Desktop\Opengl环境搭建\glew-2.1.0\include

    C:\Users\admin\Desktop\Opengl环境搭建\glfw-3.2.1.bin.WIN32\include

    C:\Users\admin\Desktop\Opengl环境搭建\glfw-3.2.1.bin.WIN32\lib-vc2015

    C:\Users\admin\Desktop\Opengl环境搭建\glew-2.1.0\lib\Release\Win32

(1)(2)两种方式都可以完成GLFW与GLEW的include与lib库引入,任意一种即可

然后在连接器\输入\附加依赖项下新增

opengl32.lib
glfw3.lib
glew32s.lib

至此为止,已经配置完毕,现在可以试验一下正确性了,粘贴下面一段代码运行即可,

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

using namespace std;

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);


const GLchar* vertexShaderSource =
"#version 330 core\n\
layout(location = 0) in vec3 position;\n\
layout(location = 1) in vec3 color;\n\
out vec3 ourColor;\n\
void main()\n\
{\n\
	gl_Position = vec4(position, 1.0f);\n\
	ourColor = color;\n\
}\n\0";
const GLchar* fragmentShaderSource =
"#version 330 core\n						\
	in vec3 ourColor;\n\
	out vec4 color;\n							\
	void main()\n								\
	{\n											\
	color = vec4(ourColor, 1.0f);\n		\
	}\n\0";

int main()
{
	//GLFW
	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_FALSE);

	//创建窗口
	GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
	if (window == nullptr)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	//GLEW
	glewExperimental = GL_TRUE;
	if (glewInit() != GLEW_OK)
	{
		std::cout << "Failed to initialize GLEW" << std::endl;
		return -1;
	}

	//顶点着色器
	GLuint vertexShader;
	vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
	glCompileShader(vertexShader);
	GLint success;
	GLchar 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;
	}
	//片元着色器
	GLuint fragmentShader;
	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);

	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::FRAGEMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
	}

	//创建着色器程序
	GLuint shaderProgram;
	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::PROGRAM::LINK_FAILED\n" << infoLog << std::endl;
	}
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);

	//事件响应
	glfwSetKeyCallback(window, key_callback);


	GLfloat vertices[] = {
		// 顶点              //颜色
		0.5f, -0.5f, 0.0f,   1.0f, 0.0f, 0.0f,  
		-0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,  
		0.0f,  0.5f, 0.0f,   0.0f, 0.0f, 1.0f  
	};

	//创建顶点缓冲区对象
	GLuint VBO;
	glGenBuffers(1, &VBO);

	//创建顶点数组对象
	GLuint VAO;
	glGenVertexArrays(1, &VAO);


	// 1.t绑定顶点数据
	glBindVertexArray(VAO);
	// 2.绑定顶点缓冲区对象
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	//将顶点数据传入缓冲区对象中(&传入缓冲区数据的类型&数据量大小以字节为单位&传入的数据&显卡管理传入数据的方式)
	/*
	*	GL_STATIC_DRAW: 这些数据基本上不会改变或者极少情况下会被改变。
		GL_DYNAMIC_DRAW: 这些数据可能会经常被改变。
		GL_STREAM_DRAW: 这些数据在每次绘制的时候都会被改变。
	*/
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//
	// 3.告知管线顶点数据的解析方式
	/*
	该属性在着色器程序中的属性索引。location 0
	该属性的分量个数(1-4)
	分量的数据类型
	是否规格化
	stride两个连续该属性之间的间隔
	该属性第一个分量距离数据起点的偏移量
	*/
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
	//启用顶点属性数据0
	glEnableVertexAttribArray(0);
	//告知管线颜色数据的解析方式
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
	glEnableVertexAttribArray(1);//启用属性1.
	//4. Unbind the VAO解除VAO绑定
	glBindVertexArray(0);
	glDisableVertexAttribArray(0);

	while (!glfwWindowShouldClose(window))
	{
		//事件处理
		glfwPollEvents();

		//清屏背景
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		//渲染程序对象
		glUseProgram(shaderProgram);

		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glBindVertexArray(0);

		//交换前后缓存
		glfwSwapBuffers(window);
		glFlush();
	}
	glfwTerminate();
	cout << "Success!" << endl;
	system("pause");
	return 0;
}

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
	// When a user presses the escape key, we set the WindowShouldClose property to true, 
	// closing the application
	if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
		glfwSetWindowShouldClose(window, GL_TRUE);
}

猜你喜欢

转载自blog.csdn.net/liuyizhou95/article/details/80170079