卐 2-第一个OpenGL程序

Posted itzyjr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了卐 2-第一个OpenGL程序相关的知识,希望对你有一定的参考价值。

OpenGL渲染管线简图


圆角矩形框代表不可编程阶段,直角矩形框代表可编程阶段。

第一个OpenGL程序
#include "sb7.h"
class my_application : public sb7::application {
public:
	void render(double currentTime) {
		static const GLfloat red[] = {1.0f, 0.0f, 0.0f, 1.0f};
		glClearBufferv(GL_COLOR, 0, red);
	}
};
DECLARE_MAIN(my_application);


所有的OpenGL函数都以“gl”开头,后缀“fv”意味着它消费(consume)一个浮点(floating-point【f】)向量(vector【v】)。

void glClearBufferfv(GLenum buffer, GLint drawBuffer, const GLfloat* value);
此函数告诉OpenGL用第三个参数的值去清理第一个参数对应的缓冲,这里是GL_COLOR,这里即是用红色去清除颜色缓冲。
第二个参数drawBuffer是从0开始的索引,这里因为我们只用到一个缓冲,所以值为0。
编译并链接GLSL代码
GLuint compile_shaders(void) {
	GLuint vertex_shader;
	GLuint fragment_shader;
	GLuint program;
	// Source code for vertex shader
	static const GLchar * vertex_shader_source[] = {
		"#version 450 core \\n"
		" \\n"
		"void main(void) \\n"
		"{ \\n"
		" gl_Position = vec4(0.0, 0.0, 0.5, 1.0); \\n"
		"} \\n"
	};
	// Source code for fragment shader
	static const GLchar * fragment_shader_source[] = {
		"#version 450 core \\n"
		" \\n"
		"out vec4 color; \\n"
		" \\n"
		"void main(void) \\n"
		"{ \\n"
		" color = vec4(0.0, 0.8, 1.0, 1.0); \\n"
		"} \\n"
	};
	// Create and compile vertex shader
	vertex_shader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
	glCompileShader(vertex_shader);
	// Create and compile fragment shader
	fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragment_shader, 1, fragment_shader_source, NULL);
	glCompileShader(fragment_shader);
	// Create program, attach shaders to it, and link it
	program = glCreateProgram();
	glAttachShader(program, vertex_shader);
	glAttachShader(program, fragment_shader);
	glLinkProgram(program);
	
	// Delete the shaders as the program has them now
	// 删除着色器对象,因为程序现在已拥有它们,不再单独需要了
	glDeleteShader(vertex_shader);
	glDeleteShader(fragment_shader);
	return program;
}
• glCreateShader() 创建一个空的着色器对象,准备接收源代码并编译。
• glShaderSource() 将着色器源代码交给着色器对象。
• glCompileShader() 编译着色器对象所包含的源代码。
• glCreateProgram() 创建一个可以关联着色器对象的程序对象。
• glAttachShader() 关联一个着色器对象到一个程序对象。
• glLinkProgram() 链接所有关联到程序对象上的着色器对象。
• glDeleteShader() 删除一个着色器对象。一旦一个着色器对象链接到了程序对象,这个程序对象就包含了二进制代码,这时着色器对象不再被需要。
创建并绑定VAO

我们在绘制任何东西之前,最后一件必须得做的事是创建一个vertex array object(VAO),它表示OpenGL管线的【顶点获取阶段(Vertex Fetch)】的对象,用于向顶点着色器提供输入。
调用glCreateVertexArrays(); 创建顶点数组;调用glBindVertexArray(); 将创建的顶点数组绑定到我们的上下文。

函数原型如下:

void glCreateVertexArrays(GLsizei n, GLuint* arrays);
void glBindVertexArray(GLuint array);
class my_application : public sb7::application {
public:
	// <snip>
	void startup() {
		rendering_program = compile_shaders();
		glCreateVertexArrays(1, &vertex_array_object);
		glBindVertexArray(vertex_array_object);
	}
	void shutdown() {
		glDeleteProgram(rendering_program);// 程序结束,删除之
		glDeleteVertexArrays(1, &vertex_array_object);// 在starup中创建的VAO,相对应地在shutdown中删除VAO
	}
private:
	GLuint rendering_program;
	GLuint vertex_array_object;
};
绘制一个点
void render(double currentTime) {
	const GLfloat color[] = { (float)sin(currentTime)*0.5f + 0.5f,
							  (float)cos(currentTime)*0.5f + 0.5f,
							  0.0f, 1.0f };
	glClearBufferfv(GL_COLOR, 0, color);

	glUseProgram(rendering_program);
	glDrawArrays(GL_POINTS, 0, 1);
}

glUseProgram()函数告诉OpenGL使用我们的程序对象(此为rendering_program)进行渲染。

void glDrawArrays(GLenum mode, GLint first, GLsizei count);
mode - 告诉OpenGL我们要去渲染什么样类型的图元。此处我们画单个点,所以用GL_POINTS
first - 起始点索引。此处为0
count - 要渲染的顶点数目。此处为1

我们可以调用glPointSize(GLfloat size)函数去画size个像素大小的点,例如glPointSize(40.0f),这样更利于察看。

绘制一个三角形(GLSL中硬编码顶点数据,注意与C++编码异同)

顶点着色器的一个内置输入变量gl_VertexID,它是此时正在处理的顶点的索引。它从glDrawArrays()函数的第二个参数的值开始计数,每处理一个顶点,计数加一。

我们可以基于gl_VertexID来为不同的点指定不同的位置,如下:

#version 450 core
void main() {
	const vec4 vertices[3] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0),
									 vec4(-0.25, -0.25, 0.5, 1.0),
									 vec4(0.25, 0.25, 0.5, 1.0));
	gl_Position = vertices[gl_VertexID];
}
void render(double currentTime) {
	const GLfloat color[] = {0.0f, 0.2f, 0.0f, 1.0f};
	glClearBufferfv(GL_COLOR, 0, color);
	glUseProgram(rendering_program);
	glDrawArrays(GL_TRIANGLES, 0, 3);
}

Summary

In this chapter, you have been briefly introduced to the sb7 application framework,compiled a shader, cleared the window, and drawn points and triangles. You have seen how to change the size of points using the glPointSize() function and have seen your first drawing command—glDrawArrays().

以上是关于卐 2-第一个OpenGL程序的主要内容,如果未能解决你的问题,请参考以下文章

✠OpenGL-2-图像管线

✠OpenGL-2-图像管线

OpenGL第一个立方体渲染不起作用

opengl着色器程序中的重复顶点

片段着色器中未使用纹理数据 - OpenGL

OpenGL片段着色器不照亮场景