opengl使用着色器简单示例

今又研究了下opengl着色器,直接用简单示例代码~

#include "../glew/GL/glew.h"
#include "../glfw/GLFW/glfw3.h"
#include <stdio.h>

// 按键-回调函数
void key_callback(GLFWwindow* window, int key, int scancode,
	int action, int mode);

//窗口大小
const GLuint g_width = 500, g_height = 500;

/// gl_Position 为内建变量,表示变换后点的空间位置。 顶点着色器从应用程序中获得原始的顶点位置数据,这些原始的顶点数据在顶点着色器中经过平移、旋转、缩放等数学变换后,生成新的顶点位置。新的顶点位置通过在顶点着色器中写入gl_Position传递到渲染管线的后继阶段继续处理。

// 顶点着色器用于读取顶点(坐标)数据,所以这个position参数是从外部数据源读取的,在main方法中将外部读取的顶点数据转化为四维坐标(x,y,z,w),并且赋值给全局变量:gl_Position。
const GLchar* g_vertexShaderSource = "#version 330 core\n"
	"layout (location = 0) in vec3 position;\n"
	"void main()\n"
	"{\n"
	"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
	"}\0";

// 片元着色器隐式地对所有的gl_Position中的坐标点进行着色并且将颜色输出。所以这个color参数是输出的,可能你也看到了,输出的颜色是个vec4,分别代表RGBA,最后一个1.0f表示alpha通道值为1.0f(浮点型)
const GLchar* g_fragmentShaderSource = "#version 330 core\n"
	"out vec4 color;\n"
	"void main()\n"
	"{\n"
	"color = vec4(1.0f, 0.5f, 0.5f, 1.0f);\n"
	"}\n\0";

int main()
{
	int ret = 0;

	// 初始化 GLFW
	ret = glfwInit();
	if(ret != GLFW_TRUE){
		return -1;
	}

	// 设置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);

	// 创建一个窗口对象
	GLFWwindow* window = glfwCreateWindow(g_width, g_height, "test1", nullptr, nullptr);
	glfwMakeContextCurrent(window);

	// 设置回调函数
	glfwSetKeyCallback(window, key_callback);

	glewExperimental = GL_TRUE;

	// 初始化 GLEW
	ret = glewInit();
	if(ret != GLEW_OK){
		return -1;
	}

	int width = 0, height = 0;
	glfwGetFramebufferSize(window, &width, &height);
	glViewport(0, 0, width, height);

	// 顶点着色器
	GLuint vertextShader = 0;
	vertextShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertextShader, 1, &g_vertexShaderSource, NULL);
	glCompileShader(vertextShader);

	// 用于判断一个着色器是否编译成功
	GLint retCompile = 0;
	GLchar infoLog[512] = {0};
	glGetShaderiv(vertextShader, GL_COMPILE_STATUS, &retCompile);
	if (retCompile == GL_FALSE){
		glGetShaderInfoLog(vertextShader, 512, NULL, infoLog);
		printf("vertex shader create fail : %s", infoLog);
		return -1;
	}

	// 片元着色器
	GLuint fragmentShader = 0;
	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &g_fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);

	// 用于判断一个着色器是否编译成功
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &retCompile);
	if (retCompile == GL_FALSE){
		glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
		printf("fragmaent shader create fail : %s", infoLog);
		return -1;
	}

	// 创建一个着色器程序对象,多个着色器最后链接的版本
	GLuint shaderProgram = 0;	// 用来渲染
	shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertextShader);	// 顶点着色器
	glAttachShader(shaderProgram, fragmentShader);	// 片元着色器
	glLinkProgram(shaderProgram);

	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &retCompile);
	if (retCompile == GL_FALSE){
		glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
		printf("shaderProgram link fail : %s", infoLog);
		return -1;
	}
	glDeleteShader(vertextShader);
	glDeleteShader(fragmentShader);

	// 创建顶点数据
	GLfloat vertices[] = {
		-0.3f, -0.3f, 0.0f,
		0.3f, -0.3f, 0.0f,
		0.0f, 0.3f, 0.0f
	};

	// vao顶点数组对象
	GLuint vao;
	glGenVertexArrays(1, &vao);

	// 绑定vao
	glBindVertexArray(vao);

	// 创建vbo顶点缓冲数据,并把数据赋值到内存中
	GLuint vbo;
	glGenBuffers(1, &vbo);

	// 复制顶点数据到缓冲中提供给OpenGL使用
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	// 设置顶点属性指针
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *)0);
	glEnableVertexAttribArray(0);

	// 解绑vbo
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	// 解绑vao
	glBindVertexArray(0);

	while (!glfwWindowShouldClose(window))
	{
		glfwPollEvents();

		// 释放颜色缓存
		glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		// 绘制物体-当打算渲染一个物体使用使用着色器程序
		glUseProgram(shaderProgram);	// 激活着色器程序
		glBindVertexArray(vao);

		// 绘制函数
		glDrawArrays(GL_TRIANGLES, 0, 3);
		//glDrawArrays(GL_LINE_LOOP, 0, 3);
		glBindVertexArray(0);

		glfwSwapBuffers(window);
	}

	glDeleteVertexArrays(1, &vao);
	glDeleteBuffers(1, &vbo);

	glfwTerminate();

	return 0;
}

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
	if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS){
		glfwSetWindowShouldClose(window, GL_TRUE);
	}
}

至于glew和glfw库,需要的可以点击下载https://download.csdn.net/download/a1173356881/12280097),我是使用VS2010编译的工程,包括库的源码都在.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值