Tutorial 09 - Interpolation

来源:互联网 发布:playclubsaber捏脸数据 编辑:程序博客网 时间:2024/04/28 05:22
#include <stdio.h>#include <string.h>#include <assert.h>#include <math.h>#include <GL/glew.h>#include <GL/freeglut.h>#include "math_3d.h"GLuint VBO;GLuint gWorldLocation;/*在管线之间传输的变量,都要被声明为out,out是一个shader保留关键字在片元shader中,定义输入颜色,该输入颜色是顶点属性插值后像素的颜色。我们用该插值颜色,做为片元shader最终的输出颜色。*/static const char *pVS = "                                                          \n\#version 330                                                                        \n\                                                                                    \n\layout (location = 0) in vec3 Position;                                             \n\                                                                                    \n\uniform mat4 gWorld;                                                                \n\                                                                                    \n\out vec4 Color;                                                                     \n\                                                                                    \n\void main()                                                                         \n\{                                                                                   \n\    gl_Position = gWorld * vec4(Position, 1.0);                                     \n\    Color = vec4(clamp(Position, 0.0, 1.0), 1.0);                                   \n\}";static const char *pFS = "                                                          \n\#version 330                                                                        \n\                                                                                    \n\in vec4 Color;                                                                      \n\                                                                                    \n\out vec4 FragColor;                                                                 \n\                                                                                    \n\void main()                                                                         \n\{                                                                                   \n\    FragColor = Color;                                                              \n\}";static void RenderSceneCB(){    glClear(GL_COLOR_BUFFER_BIT);    static float Scale = 0.0f;    Scale += 0.001f;    Matrix4f World;    World.m[0][0] = sinf(Scale) ; World.m[0][1] = 0.0f       ; World.m[0][2] = 0.0f;        World.m[0][3] = 0.0f;    World.m[1][0] = 0.0f        ; World.m[1][1] = sinf(Scale); World.m[1][2] = 0.0f;        World.m[1][3] = 0.0f;    World.m[2][0] = 0.0f;       ; World.m[2][1] = 0.0f;      ; World.m[2][2] = sinf(Scale); World.m[2][3] = 0.0f;    World.m[3][0] = 0.0f;       ; World.m[3][1] = 0.0f;      ; World.m[3][2] = 0.0f;        World.m[3][3] = 1.0f;    glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, &World.m[0][0]);    glEnableVertexAttribArray(0);    glBindBuffer(GL_ARRAY_BUFFER, VBO);    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);    glDrawArrays(GL_TRIANGLES, 0, 3);    glDisableVertexAttribArray(0);    glutSwapBuffers();}static void InitializeGlutCallbacks(){    glutDisplayFunc(RenderSceneCB);    glutIdleFunc(RenderSceneCB);}static void CreateVertexBuffer(){    Vector3f Vertices[3];    Vertices[0] = Vector3f(-1.0f, -1.0f, 0.0f);    Vertices[1] = Vector3f(1.0f, -1.0f, 0.0f);    Vertices[2] = Vector3f(0.0f, 1.0f, 0.0f);    glGenBuffers(1, &VBO);    glBindBuffer(GL_ARRAY_BUFFER, VBO);    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);}static void AddShader(GLuint ShaderProgram, const char *pShaderText, GLenum ShaderType){    GLuint ShaderObj = glCreateShader(ShaderType);    if (ShaderObj == 0)    {        fprintf(stderr, "Error creating shader type %d\n", ShaderType);        exit(0);    }    const GLchar *p[1];    p[0] = pShaderText;    GLint Lengths[1];    Lengths[0] = strlen(pShaderText);    glShaderSource(ShaderObj, 1, p, Lengths);    glCompileShader(ShaderObj);    GLint success;    glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success);    if (!success)    {        GLchar InfoLog[1024];        glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog);        fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog);        exit(1);    }    glAttachShader(ShaderProgram, ShaderObj);}static void CompileShaders(){    GLuint ShaderProgram = glCreateProgram();    if (ShaderProgram == 0)    {        fprintf(stderr, "Error creating shader program\n");        exit(1);    }    AddShader(ShaderProgram, pVS, GL_VERTEX_SHADER);    AddShader(ShaderProgram, pFS, GL_FRAGMENT_SHADER);    GLint Success = 0;    GLchar ErrorLog[1024] = { 0 };    glLinkProgram(ShaderProgram);    glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success);    if (Success == 0)    {        glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);        fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);        exit(1);    }    glValidateProgram(ShaderProgram);    glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success);    if (!Success)    {        glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);        fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);        exit(1);    }    glUseProgram(ShaderProgram);    /*通过查询shader程序对象,我们能够得到uniform变量的位置,该位置和该uniform变量在shader代码中的位置一致。    通常情况下,我们不能直接访问和更新uniform变量。在glsl compiler编译shader代码时候,它会给每个uniform变量    分配一个索引,在shader内部访问uniform变量都是通过这个索引来实现的,应用程序则是通过glGetUniformLocation    函数来访问相应的uniform变量,函数的参数为shader程序句柄以及uniform变量名字。函数调用成功,    则会返回索引值,失败的话返回-1,对返回值进行错误检测也非常重要,这样可以保证shader值被正确更新。    */    gWorldLocation = glGetUniformLocation(ShaderProgram, "gWorld");    assert(gWorldLocation != 0xFFFFFFFF);}int main(int argc, char **argv){    glutInit(&argc, argv);    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);    glutInitWindowSize(1024, 768);    glutInitWindowPosition(100, 100);    glutCreateWindow("Tutorial 09");    InitializeGlutCallbacks();    // Must be done after glut is initialized!    GLenum res = glewInit();    if (res != GLEW_OK)    {        fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));        return 1;    }    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    CreateVertexBuffer();    CompileShaders();    glutMainLoop();    return 0;}


原创粉丝点击