今又研究了下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编译的工程,包括库的源码都在.