OpenGL | Learn From Basic Examples - BasicShader

Basic Knowledge

1.1 OpenGL is a specification (API) or a library?

1.2 OpenGL pipeline

  • 图片来源网络,侵删。
    在这里插入图片描述

1.3 What’s the difference between glfw, glew and glut

  • [glut]: OpenGL utility toolkit for OpenGL to put the platform-dependent details (e.g. creating windows and responding to mouse events) under one hood.

GLUT是一个实用工具库, 用于创建窗口和相应鼠标事件等。

  • glfw: glfw is the latest library for creating OpenGL context, opening a window and managing input after glut and freeglut.

与glut类似,glut是比较早期的工具。

  • glew: GPU manufacturers provide their own exclusive functions, OpenGL extension wrangle will automatic identify advanced extension functions supported by specific graphics cards.

GPU的厂商(如Nvidia,AMD)会提供他们独有的高级扩展函数,GLEW会自动搜索这些函数以供用户使用。

Development Environment

1.1 Visual Studio

  • Additional include directories.

附加包含目录, C/C++ -> 常规 -> 附加包含目录。

  • Additional library directories.

附加库目录,链接器 -> 常规 -> 附加库目录。

  • Additional dependencies. (e.g. opengl32.lib\glew32s.lib\glfw3.lib)

添加依赖项,链接器 -> 输入 -> 添加依赖项。

  • Preprocessor Definitions.

若采用静态链接库,则需要定义GLEW_STATIC。 C/C++ -> 预处理器 ->预处理器定义。

1.2 OpenGL dependency libraries (e.g. glfw etc.)

Resource

Example 1 - Create a Window

1.1 Source Code

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


int main(void)
{
	GLFWwindow* window;

	/* Initialize the library */
	if (!glfwInit())
		return -1;

	/* Create a windowed mode window and its OpenGL context */
	window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
	if (!window)
	{
		glfwTerminate();
		return -1;
	}

	/* Make the window's context current */
	glfwMakeContextCurrent(window);

	// glewInit必须在context之后
	GLenum err = glewInit();
	if (GLEW_OK == err) {
		std::cout << "Glew init successful!" << std::endl;
		std::cout << glGetString(GL_VERSION) << std::endl;
	}
	else {
		std::cout << "Glew init failed!" << std::endl;
		return -1;
	}

	/* Loop until the user closes the window */
	while (!glfwWindowShouldClose(window))
	{
		/* Render here */
		glClear(GL_COLOR_BUFFER_BIT);

		/* Swap front and back buffers */
		glfwSwapBuffers(window);

		/* Poll for and process events */
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}

1.2 Notes

  • glewInit must be after make context.

glew.h要在glfw3.h之前,glewInit要在glfwMakeContext之后。

1.3 Display

在这里插入图片描述

Example 2 - Draw a Triangle (legacy mode)

1.1 Source Code

	/* Loop until the user closes the window */
	while (!glfwWindowShouldClose(window))
	{
		/* Render here */
		glClear(GL_COLOR_BUFFER_BIT);

		glBegin(GL_TRIANGLES);
		glVertex2d(0.0f, 1.0f);
		glVertex2d(0.5f, 0.0f);
		glVertex2d(-0.5f, 0.0f);
		glEnd();

		/* Swap front and back buffers */
		glfwSwapBuffers(window);

		/* Poll for and process events */
		glfwPollEvents();
	}

1.2 Notes

  • The coordinate system of OpenGL is from -1 to 1.

OpenGl的坐标系是从-1到1的。

1.3 Display

在这里插入图片描述

Example 3 - Draw a Triangle (buffer mode)

1.1 Source Code

	// 顶点信息
	float positions[8] = {
		0.0f, 1.0f,
		0.5f, 0.0f,
       -0.5f, 0.0f,
	    0.0f, 1.0f
	};
	// 缓存id
	GLenum bufferId;
	// 申请缓存
	glGenBuffers(1, &bufferId);
	// 选择当前缓存
	glBindBuffer(GL_ARRAY_BUFFER, bufferId);
	// 缓存中的数据赋值
	glBufferData(GL_ARRAY_BUFFER, sizeof(positions), &positions, GL_STATIC_DRAW);
	// 启用(状态机的)顶点属性
	glEnableVertexAttribArray(0);
	// 设置顶点的布局,第一个参数为属性索引,对应glEnableVertexAttribArray(0)
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

	/* Loop until the user closes the window */
	while (!glfwWindowShouldClose(window))
	{
		/* Render here */
		glClear(GL_COLOR_BUFFER_BIT);

		// 绘制缓存数据,最后一个参数为总共几个顶点
		glDrawArrays(GL_LINE_STRIP, 0, 4);

		/* Swap front and back buffers */
		glfwSwapBuffers(window);

		/* Poll for and process events */
		glfwPollEvents();
	}

1.2 Notes

  • OpenGL can be seen as a state machine, don’t forget enable the vertex attribute.

OpenGL可以看成是一个状态机,别忘了要启用顶点属性,不然画不出来。

1.3 Display

在这里插入图片描述

Example 4 - Color the Triangle Using Vertex Shader & Fragment Shader

1.1 About Shader(着色器)

1.1.1 Vertex Shader(顶点着色器)

  • If there are 3 vertices, then the vertex shader will be called three times.

有几个顶点,则顶点着色器就会被调用几次,如三角形三个顶点会调用三次顶点着色器。

1.1.2 Fragment Shader(片元着色器)

  • Fragment shader decides which color that pixel is supposed to be, and it may be called thousands of times.

片元着色器(也叫像素着色器)决定每个像素的颜色,所以可能被调用上千次。

1.2 About Rasterization(光栅化)

  • The points, lines and surfaces description of vectors become the description of pixels.

矢量的点线面描述变成像素的描述。图片来源

在这里插入图片描述

1.3 Source Code

1.3.1 File Structure

在这里插入图片描述

1.3.2 Shader Code

在这里插入图片描述

1.3.3 ShaderLoader Code

  • read source file (读取着色器文件)
  • compile shaders (编译着色器)
    • glCreateShader
    • glShaderSource
    • glCompileShader
  • link to program. (链接着色器到程序)
    • glCreateProgram
    • glAttachShader
    • glLinkProgram
    • glValidateProgram

1.3.4 Application Code

	/*载入着色器*/
	std::map<std::string, unsigned int> shaderMap;
	shaderMap["resources/shaders/BasicVertexShader.shader"] = GL_VERTEX_SHADER;
	shaderMap["resources/shaders/BasicFragmentShader.shader"] = GL_FRAGMENT_SHADER;

	ShaderLoader shaderLoader;
	unsigned int shaderProgram = shaderLoader.createProgram(shaderMap);
	// 启用着色器
	glUseProgram(shaderProgram);

	/* Loop until the user closes the window */
	while (!glfwWindowShouldClose(window))
	{
		/* Render here */
		glClear(GL_COLOR_BUFFER_BIT);

		// 绘制缓存数据,最后一个参数为总共几个顶点
		glDrawArrays(GL_TRIANGLES, 0, 3);

		/* Swap front and back buffers */
		glfwSwapBuffers(window);

		/* Poll for and process events */
		glfwPollEvents();
	}

	// 删除着色器对象
	glDeleteProgram(shaderProgram);

1.4 GitHub

1.5 Display

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值