OpenGl shader 初次上手

来源:互联网 发布:nginx ssi绝对路径 编辑:程序博客网 时间:2024/05/20 17:40

shader(着色器)分为顶点着色器和片元着色器,shader的源代码写在单独的文件中,后缀名不限,但一般为 .shader(VS可以识别点语法) ,然后在程序中读取着色器代码并通过gl库函数编译并链接,如果编译或链接失败可以在过程中读取log信息排错

遇上的坑有

  • 要在VS项目属性->链接器->输入的附加依赖项添加
    opengl32.lib
    glu32.lib
    glew32.lib
    glut32.lib
    glfw3.lib
    不清楚哪些是必须的= =,全加了总是好的
  • 把顶点着色器代码当片元着色器编译= =会报错:gl_Position undeclared identifier
  • GLSL是大小写敏感的, gl_Position不要写成gl_position
  • 着色器源代码记得在开头申明版本,例如 “#version 400”
  • 可以 cout glGetString (GL_SHADING_LANGUAGE_VERSION) 查看glsl版本
  • delete []s.source 删除结构体里面的char *时莫名报错,未解之谜
  • for反括号打错位置= =,链接好一个着色器就要 glAttachShader
  • 最好在编译和链接的输出错误语句里面加system(“pause”)或打断点,这样就能在出错时看到报错信息,不然窗口闪太快看不到= =,重定向输出到文件应该也行
  • 貌似并没有 glEnableClientState(GL_VERTEX_ARRAY); 也可以正常使用glDrawArrays
  • 使用glDrawArrays绑定的数组可以是2维也可以是1维,即
    { {-0.5,-0.5},{0.5,-0.5},{0,0.5} } 和 { -0.5,-0.5,0.5,-0.5,0,0.5 } 都行
    但是要注意绑定时候类型的参数要正确,参考百度glVertexAttribPointer()
  • 如果绑定的是GL_FLOAT那么你的数组就必须是float,如果是double的话会显示不出来
  • 用书上的FILE char*读源代码总是出错,就自己改了用string读了= =

附上编译链接着色器的代码(initShader.cpp):

#include "initShader.h"using namespace std;//读源代码string readShaderSource(const char *shaderFile) {    string shaderCode;    fstream input(shaderFile, std::ios::in);    if (input.is_open()) {        string line;        while (getline(input, line)) {        shaderCode += line + '\n';        }    input.close();    }    return shaderCode;}GLuint InitShader(const char *vShaderFile, const char *fShaderFile) {    struct Shader {        const char* filename;        GLenumtype;        GLchar*source;    } shaders[2] = {        { vShaderFile,GL_VERTEX_SHADER,NULL },        { fShaderFile,GL_FRAGMENT_SHADER,NULL }    };    GLuint program = glCreateProgram();    for (int i = 0; i < 2; i++) {//for语句开始        Shader& s = shaders[i];        string code = readShaderSource(s.filename);        s.source = (GLchar *)code.c_str();//各种类型转换心很累        if (shaders[i].source == NULL) {            cerr << "Failed to read" << s.filename << endl;            exit(EXIT_FAILURE);        }        GLuint shader = glCreateShader(s.type);        GLchar**temp = &s.source;        cout << temp[0];        glShaderSource(shader, 1, temp, NULL);        //编译        glCompileShader(shader);        GLint compiled;        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);        if (!compiled) {            cerr << s.filename << " failed to compile:" << endl;            GLint logSize;            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);            char *logMsg = new char[logSize];            glGetShaderInfoLog(shader, logSize, NULL, logMsg);            cerr << logMsg << endl;            delete[]logMsg;            exit(EXIT_FAILURE);       }       //delete[] s.source;       glAttachShader(program, shader);    }//for语句结束    //链接    glLinkProgram(program);    GLint linked;    glGetProgramiv(program, GL_LINK_STATUS, &linked);    if (!linked) {        cerr << "Shader program failed to link" << endl;        GLint logSize;        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize);        char *logMsg = new char[logSize];        glGetProgramInfoLog(program, logSize, NULL, logMsg);        cerr << logMsg << endl;        delete[]logMsg;        exit(EXIT_FAILURE);     }     glUseProgram(program);     return program;}
0 0
原创粉丝点击