GLSL要点记录

来源:互联网 发布:宏观数据 编辑:程序博客网 时间:2024/05/01 16:14
  1. 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);
  1. 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);
  1. 获取shader中uniform对象在程序中的引用:必须在加载了shader程序之后才能获取
    //加载着色器程序    GLuint program = LoadShaders("vertexshader4.vert", "fragmentshader4.frag");    //获取Uniform属性    GLuint uniformPMV = glGetUniformLocation(program, "pmvmat");
  1. 获取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
  1. 调用绘图指令:
//画三角形,指定开始的下标和需要用到的顶点个数glDrawArrays(GL_TRIANGLES, 0, 3 * 12);
  1. 在绘图结束后,需要删除申请的VAO,VBO,Program对象:
    //记得删除VAO对象,buffer对象,和着色器程序对象       glDeleteBuffers(1, &vertexBuffer);    glDeleteBuffers(1, &colorBuffer);    glDeleteProgram(program);    glDeleteVertexArrays(1, &vertexArrayID);
  1. 着色器程序加载流程:
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;}
  1. 简单顶点着色器程序示例:
//指定版本#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;  }
  1. 利用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;}
  1. 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
原创粉丝点击