Learning GLSL -- 001

来源:互联网 发布:淘宝网酒类 编辑:程序博客网 时间:2024/06/06 05:31

GLSL学习记录,环境:ubuntu12.04 + glut

编译命令: g++ -o 01_demo 01_demo.cpp -lGL -lGLU -lglut -lGLEW

------------------------------------------------------------- Code line -------------------------------------------------------------------shader.h

#ifndef __SHADER_H__
#define __SHADER_H__

#include <stdio.h>
#include <GL/glew.h>
#include <GL/glut.h>

#define MYLOG(x, y...) printf("[%s][%s][%04d]: "x"\n", __FILE__, __FUNCTION__, __LINE__, ##y)
#define printOpenGLError() printOglError(__FILE__, __LINE__)
int printOglError(char *file, int line)
{
    GLenum glErr;
    int retCode = 0;
    
    glErr = glGetError();
    while (glErr != GL_NO_ERROR)
    {
        MYLOG("glError in file %s @line %d: %s.", file, line, gluErrorString(glErr));
        retCode = 1;
        glErr = glGetError();
    }
    return retCode;
}


void printInfoLog(GLhandleARB obj)
{
    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;

    glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength);
    if (infologLength > 0)
    {
        infoLog = (char *)malloc(infologLength);
        glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
        MYLOG("%s.",infoLog);
        free(infoLog);
    }
}

char *stringFileRead(const char *fn)
{
    MYLOG("stringFileRead file[%s]", fn);
    FILE *fp;
    char *content = NULL;
    int count=0;
    if (fn != NULL) {
        fp = fopen(fn, "rt");
        if (fp != NULL) {
            fseek(fp, 0, SEEK_END);
            count = ftell(fp);
            rewind(fp);
            if (count > 0) {
                content = (char *)malloc(sizeof(char) * (count+1));
                count = fread(content,sizeof(char),count,fp);
                content[count] = '\0';
            }
            fclose(fp);                            
        }
    }
    return content;
}

GLhandleARB buildShader(const GLchar **code, GLenum shaderType)
{
    GLhandleARB handle = glCreateShaderObjectARB(shaderType);
    glShaderSourceARB(handle, 1, code, NULL);
    glCompileShaderARB(handle);
    printInfoLog(handle);
    return handle;
}

GLhandleARB buildShaderProgram(GLhandleARB v, GLhandleARB f)
{
    GLhandleARB pro = glCreateProgramObjectARB();
    glAttachObjectARB(pro, v);
    glAttachObjectARB(pro, f);
    glLinkProgramARB(pro);
    printInfoLog(pro);
    return pro;
}

void setShaders(const char *vert, const char *frag, GLhandleARB &pro)
{
    char *vs = NULL, *fs = NULL;
    GLhandleARB v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
    GLhandleARB f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);

    vs = stringFileRead(vert);
    fs = stringFileRead(frag);

    //printf("test.vert=[%s]\n", vs);
    //printf("test.frag=[%s]\n", fs);

    const char *vv = vs;
    const char *ff = fs;

    glShaderSourceARB(v, 1, &vv, NULL);
    glShaderSourceARB(f, 1, &ff, NULL);

    free(vs);
    free(fs);
    
    glCompileShaderARB(v);
    glCompileShaderARB(f);

    printInfoLog(v);
    printInfoLog(f);

    pro = glCreateProgramObjectARB();

    glAttachObjectARB(pro, v);
    glAttachObjectARB(pro, f);

    glLinkProgramARB(pro);
    printInfoLog(v);
    printInfoLog(f);
    printInfoLog(pro);

    //glUseProgramObjectARB(pro);
    //glUniform3fARB(glGetUniformLocationARB(pro, "LightPosition"), 100.0f, 100.0f, 100.0f);
    //glUniform1iARB(glGetUniformLocationARB(pro, "tex01"), 0);
    //glUniform1iARB(glGetUniformLocationARB(pro, "tex02"), 1);
}

#endif /* __SHADER_H__ */

------------------------------------------------------------- Code line -------------------------------------------------------------------01_demo.cpp

#include "shader.h"

GLfloat ambient[4] = {0.0, 0.0, 1.0, 1.0};
GLfloat lightcolor[4] = {1.0, 1.0, 1.0, 1.0};
GLfloat eyeposition[3] = {0.0, 10.0, 30.0};
GLfloat Ns = 5;
GLfloat attenuation = 0.1;
GLfloat objectSize = 15.0;
GLuint program;
GLuint vShader, fShader;

void myInit()
{
    glewInit();
    glClearColor(0.0 , 0.0 , 0.0 , 1.0); glEnable(GL_DEPTH_TEST);

    const GLchar *vShaderSource = stringFileRead("01_demo.vert");
    const GLchar *fShaderSource = stringFileRead("01_demo.frag");
    vShader = buildShader(&vShaderSource, GL_VERTEX_SHADER);
    fShader = buildShader(&fShaderSource, GL_FRAGMENT_SHADER);
    program = buildShaderProgram(vShader, fShader);

    //setShaders("01_demo.vert", "01_demo.frag", program);
}

void myReshape(int w , int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90, 1, 0.1, 1000.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(eyeposition[0], eyeposition[1], eyeposition[2], 0.0 , 0.0 , 0.0 , 0.0 , 1.0 , 0.0);
}

void myDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1.0 , 1.0 , 1.0);

    glUseProgram(program);
    glUniform3f(glGetUniformLocation(program , "lightposition"), 30.0, 30.0, 30.0);
    glUniform3f(glGetUniformLocation(program , "eyeposition"), eyeposition[0], eyeposition[1], eyeposition[2]);
    glUniform4f(glGetUniformLocation(program , "ambient"), ambient[0] , ambient[1] , ambient[2] , ambient[3]);
    glUniform4f(glGetUniformLocation(program , "lightcolor"), lightcolor[0] , lightcolor[1] , lightcolor[2] , lightcolor[3]);
    glUniform1f(glGetUniformLocation(program , "Ns"), Ns);
    glUniform1f(glGetUniformLocation(program , "attenuation") , attenuation);

    glutSolidTeapot(objectSize);
    glutSwapBuffers();
}

int main(int argc , char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowPosition(100 , 100);
    glutInitWindowSize(600 , 600);
    glutCreateWindow(argv[0]);
    myInit();
    glutReshapeFunc(myReshape);
    glutDisplayFunc(myDisplay);
    glutIdleFunc(myDisplay);
    glutMainLoop();
    return 0;
}

------------------------------------------------------------- Code line -------------------------------------------------------------------01_demo.vert

uniform vec3 lightposition;
uniform vec3 eyeposition;
uniform vec4 ambient;
uniform vec4 lightcolor;
uniform float Ns;
uniform float attenuation;
varying vec4 color;

void main()
{
    vec3 ECPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
    vec3 N = normalize(gl_NormalMatrix * gl_Normal);
    vec3 L = normalize(lightposition - ECPosition);
    vec3 V = normalize(eyeposition - ECPosition);
    vec3 H = normalize(V + L);
    vec4 diffuse = lightcolor * max(dot(N , L), 0.0);
    vec4 specular = lightcolor * pow(max(dot(N , H) , 0.0) , Ns) * attenuation;
    color = vec4(clamp((diffuse + specular), 0.0, 1.0));
    color = color + ambient;
    gl_Position = ftransform();
}

------------------------------------------------------------- Code line -------------------------------------------------------------------01_demo.frag

varying vec4 color;
void main()
{
    gl_FragColor = color;
}



0 0