GLSL要点记录
来源:互联网 发布:宏观数据 编辑:程序博客网 时间:2024/05/01 16:14
- GLEW的使用:初始化glew之前,需要先设置glewExperimental参数,以访问核心类,否则有可能造成使用glGenVertexArrays()时有内存访问冲突。
glewExperimental = true; // Needed for core profile, 造成内存访问冲突 if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); return -1; }
2.VertexArrayObject的使用:先声明引用ID,然后生成VAO引用,接着绑定该VAO为当前对象
GLuint vertexArrayID; glGenVertexArrays(1, &vertexArrayID); glBindVertexArray(vertexArrayID);
- VertexBufferObject的使用:先声明ID,然后生成VBO引用,接着绑定该VBO类型,指定该VBO的对应数组数据指针和大小,这四步必须写在一起:
//设置顶点缓存对象VBO GLuint vertexBuffer; //顶点缓存标示 glGenBuffers(1, &vertexBuffer); //生成缓存标示符 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); //绑定缓存标识为数组缓存 //将数据和缓存绑定,使缓存指向数据数组 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_array_buffer_data), vertex_array_buffer_data, GL_STATIC_DRAW);
- 获取shader中uniform对象在程序中的引用:必须在加载了shader程序之后才能获取
//加载着色器程序 GLuint program = LoadShaders("vertexshader4.vert", "fragmentshader4.frag"); //获取Uniform属性 GLuint uniformPMV = glGetUniformLocation(program, "pmvmat");
- 获取shader中的属性与VBO对象的对应关系:先获取属性在shader中的位置Location,激活该属性,指定绑定的VBO对象,最后指定buffer中元素的解释规则。在调用完成后需要禁用该属性:glDisableVertexAttribArray(0); //禁用0号属性
glEnableVertexAttribArray(0); //使当前绑定的VertexArrayObject的某个属性可用glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); //必须重新绑定,以此和0号位置绑定glVertexAttribPointer(0, //指定要修改的顶点属性的索引值 3, //属性组件的个数,必须是1,2,3或4 GL_FLOAT, //组件的类型 GL_FALSE, //是否Normolized? 0, //tride指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0); (void*)0); //array buffer offset
- 调用绘图指令:
//画三角形,指定开始的下标和需要用到的顶点个数glDrawArrays(GL_TRIANGLES, 0, 3 * 12);
- 在绘图结束后,需要删除申请的VAO,VBO,Program对象:
//记得删除VAO对象,buffer对象,和着色器程序对象 glDeleteBuffers(1, &vertexBuffer); glDeleteBuffers(1, &colorBuffer); glDeleteProgram(program); glDeleteVertexArrays(1, &vertexArrayID);
- 着色器程序加载流程:
GLuint LoadShaders(const char* vertexshaderfile, const char* fragmentshaderfile) { //设置顶点着色器和片元着色器的ID GLuint vertexshaderID = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentshaderID = glCreateShader(GL_FRAGMENT_SHADER); //从shader的文件中读入shader的源代码 std::string vertexShaderSource; std::ifstream vertexShaderStream(vertexshaderfile, std::ios::in); if (vertexShaderStream.is_open()) { std::string Line; while (getline(vertexShaderStream, Line)) { vertexShaderSource += "\n" + Line; } vertexShaderStream.close(); } else { printf("Can't load the source of the vertexshader\n"); getchar(); return -1; } //从文件加载片元着色器代码 string fragmentShaderSource; ifstream fragmentShaderStream(fragmentshaderfile, std::ios::in); if (fragmentShaderStream.is_open()) { string Line; while (getline(fragmentShaderStream, Line)) { fragmentShaderSource += "\n" + Line; } fragmentShaderStream.close(); } else { printf("无法加载片元着色器代码\n"); getchar(); return -1; } GLint Result = GL_FALSE; //编译链接结果 GLint LogLength; //编译链接的Log长度 //编译顶点着色器程序 printf("编译着色器程序:%s\n", vertexshaderfile); char const * vertexSourcePoint = vertexShaderSource.c_str(); glShaderSource(vertexshaderID, 1, &vertexSourcePoint, NULL); glCompileShader(vertexshaderID); //编译程序 //检查编译结果 glGetShaderiv(vertexshaderID, GL_COMPILE_STATUS, &Result); //获取编译结果 glGetShaderiv(vertexshaderID, GL_INFO_LOG_LENGTH, &LogLength); //获取LOG长度 //编译不成功 if (!Result) { printf("着色器程序:[%s]编译失败\n", vertexshaderfile); char* logMsg = new char[LogLength]; glGetShaderInfoLog(vertexshaderID, LogLength, NULL, logMsg); printf("%s\n", logMsg); delete[] logMsg; return -1; } //编译片元着色器 printf("编译片元着色器\n"); const char* fragmentSourcePointer = fragmentShaderSource.c_str(); //源代码 glShaderSource(fragmentshaderID, 1, &fragmentSourcePointer, NULL); //绑定源码 glCompileShader(fragmentshaderID); glGetShaderiv(fragmentshaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(fragmentshaderID, GL_INFO_LOG_LENGTH, &LogLength); //检查编译结果 if (!Result) { printf("着色器程序:[%s]编译失败\n", fragmentshaderfile); char* logMsg = new char[LogLength]; glGetShaderInfoLog(fragmentshaderID, LogLength, NULL, logMsg); printf("%s\n", logMsg); delete[] logMsg; return -1; } //链接程序 GLuint programID = glCreateProgram(); glAttachShader(programID, vertexshaderID); //给程序附着着色器程序 glAttachShader(programID, fragmentshaderID); //链接开始 printf("链接程序\n"); glLinkProgram(programID); //检查链接结果 glGetProgramiv(programID, GL_LINK_STATUS, &Result); glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &LogLength); if (!Result) { printf("着色器程序链接失败\n"); char* logMsg = new char[LogLength]; glGetProgramInfoLog(programID, LogLength, NULL, logMsg); printf("%s\n", logMsg); delete[] logMsg; return -1; } //删除着色器 glDeleteShader(vertexshaderID); glDeleteShader(fragmentshaderID); return programID;}
- 简单顶点着色器程序示例:
//指定版本#version 330 core//指定输入参数类型,属性的位置索引,用于://glEnableVertexAttribArray(0); //使当前绑定的VertexArrayObject的某个属性可用layout(location=0) in vec3 position;layout(location=1) in vec3 color;//指定uniform属性uniform mat4 pmvmat;//指定输出参数的类型out vec3 fragcolor;void main() { vec4 vpos = vec4(position, 1.0f); gl_Position = pmvmat * vpos; //gl_Position内置的属性 fragcolor = color;}
10.简单片元着色器程序示例:
#version 330 corein vec3 fragcolor;out vec3 color;void main() { color = fragcolor; }
- 利用glfw窗口管理库函数和glew扩展库的开发初始化流程和MainLoop的模板:
// Include standard headers#include <stdio.h>#include <stdlib.h>// Include GLEW#include <GL/glew.h>// Include GLFW#include <glfw3.h>GLFWwindow* window;// Include GLM#include <glm/glm.hpp>using namespace glm;int main( void ){ // Initialise GLFW if( !glfwInit() ) { fprintf( stderr, "Failed to initialize GLFW\n" ); return -1; } glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Open a window and create its OpenGL context window = glfwCreateWindow( 1024, 768, "Tutorial 01", NULL, NULL); if( window == NULL ){ fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" ); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // Initialize GLEW if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); return -1; } // Ensure we can capture the escape key being pressed below glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); // Dark blue background glClearColor(0.0f, 0.0f, 0.4f, 0.0f); do{ // Draw nothing, see you in tutorial 2 ! // Swap buffers glfwSwapBuffers(window); glfwPollEvents(); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 ); // Close OpenGL window and terminate GLFW glfwTerminate(); return 0;}
- GL常用的清除函数:
//清空各种缓存,只有四个Buffer值可用,用其他值将导致程序错误 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Dark blue background glClearColor(0.0f, 0.0f, 0.4f, 0.0f); //设置屏幕背景色
0 0
- GLSL要点记录
- glsl 内置函数(仅记录用)
- GLSL学习第一课笔记记录
- GLSL记录(1)-实时旋转的三角形
- GLSL(2)记录-使用uniform block
- div+css 要点记录
- 记录一些要点
- CSDN讲座要点记录
- java 要点记录
- 面向对象要点记录
- android面试要点记录
- MySQL必知必会,要点记录
- Apache 配置文件要点记录
- C++ Java要点记录
- C++ Java要点记录
- C++ Java要点记录
- Java学习要点记录
- Android学习要点记录
- printf输出颜色
- HTTP405
- 求一个字符串中连续出现的次数最多的子串
- C#高级编程六十二天----LINQ标准的查询操作符
- TortoiseSVN搭建本地版本库及简单操作使用
- GLSL要点记录
- Hibernate 悲观锁与乐观锁
- poj 2528 线段树+离散化+有颜色的区间覆盖
- Android 常用 adb 命令总结
- 【STL源码剖析】序列式容器
- 文章标题
- 数据结构基础 算法复杂度分析(一) 概念篇
- 消息队列创建以及使用示例
- nyoj 891 找点【贪心】