OpenGL - OBJ中的顶点法线

时间:2015-08-06 08:22:20

标签: c++ opengl opengl-es shader wavefront

我想知道如何使用顶点法线来实现闪电效果?目前我所拥有的是我可以将顶点和纹理坐标发送到着色器并使用它们但是使用法线,我不知道如何在着色器程序中使用它们。以下是我到目前为止的情况。

    // vertex shader
    layout(location = 0) in vec4 vert;
    layout(location = 1) in vec4 color;
    layout(location = 2) in vec2 texcoord;
    uniform mat4 m_model;
    uniform mat4 m_view;
    uniform mat4 m_proj;
    void main() {
        gl_Position = m_proj * m_view * m_model * vert;
    }

    // fragment shader
    in vec2 fragtexcoord;
    out vec4 color;
    uniform sampler2D textureunit;
    void main(void) {
        color = texture(textureunit, fragtexcoord);
    }

修改 以下是我的着色器。

顶点着色器

    layout(location = 0) in vec4 vert;
    layout(location = 1) in vec4 color;
    layout(location = 2) in vec2 texcoord;
    layout(location = 3) in vec4 normal;
    out vec4 LightIntensity;
    uniform vec4 LightPosition;
    uniform vec4 Kd; 
    uniform vec4 Ld;
    uniform mat4 m_model;
    uniform mat4 m_view;
    uniform mat4 m_proj;
    void main() {
        gl_Position = m_proj * m_view * m_model * vert;

        mat4 normalmatrix = transpose(inverse(m_view));

        vec4 tnorm = normalize(normalmatrix * normal);
        vec4 eyeCoords = m_model * vec4(vert);
        vec4 s = normalize(vec4(LightPosition - eyeCoords));

        LightIntensity = Ld * Kd * max(dot(s, tnorm), 0.0);
    }

片段着色器。

    in vec4 LightIntensity;
    out vec4 color;
    void main(void) {
        color = vec4(LightIntensity);
    }

目前获得没有阴影的黑色立方体。可能我在着色器中做错了,我不知道哪一个:(

更新:

顶点

    layout(location = 0) in vec4 vert;
    layout(location = 1) in vec4 color;
    layout(location = 2) in vec2 texcoord;
    layout(location = 3) in vec4 normal;
    out vec2 fragtexcoord;
    out vec4 fragnormal;
    uniform mat4 m_model;
    uniform mat4 m_view;
    uniform mat4 m_proj;
    void main() {
        gl_Position = m_proj * m_view * m_model * vert;
        fragtexcoord = texcoord;
        fragnormal = normal;
    }

片段

    in vec2 fragtexcoord;
    in vec4 fragnormal;
    out vec4 fragment_color;
    uniform sampler2D textureunit;
    void main(void) {
        vec4 lt_ambient = vec4(0.2, 0.2, 0.2, 1.0);
        vec4 lt_direct = vec4(0.8, 0.8, 0.8, 1.0);
        vec4 lt_direct_dir = vec4(1.5, 1.0, 1.0, 1.0);
        vec4 color = texture(textureunit, fragtexcoord);
        fragment_color = (lt_ambient + (lt_direct * dot(lt_direct_dir, -fragnormal))) * color;
    }

我不知道为lt_direct_dir放什么,这就是为什么它有这样的值:))

更新:以下是我的工作着色器

    // vertex shader
    layout(location = 0) in vec4 vert;
    layout(location = 1) in vec4 color;
    layout(location = 2) in vec2 texcoord;
    layout(location = 3) in vec4 normal;

    out vec4 fragposition;
    out vec4 fragcolor;
    out vec4 fragnormal;
    out vec2 fragtexcoord;

    uniform mat4 m_model;
    uniform mat4 m_view;
    uniform mat4 m_proj;
    uniform vec4 lightpos;
    void main() {
        gl_Position = m_proj * m_view * m_model * vert;
        mat4 m_normal = transpose(inverse(m_model));
        fragposition = m_model * vert;
        fragnormal = m_normal * normal;
        fragtexcoord = texcoord;
    }

    // fragment shader
    in vec4 fragposition;
    in vec4 fragnormal;
    in vec2 fragtexcoord;

    out vec4 fragment_color;

    uniform sampler2D textureunit;

    void main() {
        vec4 lt_pnt_pos = vec4(2.5, 2.5, 2.5, 1.0);
        vec4 lt_pnt_col = vec4(0.8, 0.8, 0.8, 1.0);
        vec4 lt_amb_col = vec4(0.2, 0.2, 0.2, 1.0);

        vec4 lt_dir = normalize(lt_pnt_pos - fragposition);
        float li = dot(fragnormal, lt_dir);
        if(li < 0.0) {
            li = 0.0;
        }
        vec4 color = texture(textureunit, fragtexcoord);
        fragment_color = color * (lt_amb_col + (lt_pnt_col * li));
    }

1 个答案:

答案 0 :(得分:7)

正常/凹凸地图

提供精细的细节而不增加几何的复杂性,这意味着以非常低的性能成本获得更多细节。普通/凹凸贴图可选粗糙。

正常着色(片段着色器)

Normal是垂直于fragment / face / primitive的向量,它有两个用途:

  1. 暗淡的表面照明

    让我们:

    • color - 每片段/面/原始颜色(用纹理调制)
    • normal - 每个片段/面/原始3D法线向量(指向网格外)
    • lt_ambient,lt_direct - 灯光颜色和力量
    • lt_direct_dir - 定向光线方向

    然后输出很简单:

    • fragment_color=(lt_ambient+(lt_direct*dot(lt_direct_dir,-normal))*color;

    这称为正常着色

    dot如果您想要使用展位边几何图形,则返回cos(angle between light and normal),然后使用fabs(dot(...))。总和的光色和强度矢量不应超过每通道1.0,否则钳位可能会导致颜色伪影。例如:

    • lt_ambient=(0.2,0.2,0.2)
    • lt_direct =(0.8,0.8,0.8)

    作为lt_direct_dir您可以使用(fragment_xyz-Sun.xyz)并规范化为单位矢量或使用相机视图方向。 你需要有点积的单位矢量,否则它将无法正常工作

  2. <强>反射

    如果您有任何环境贴图( cube_map ),则可以添加反射。您获得了片段(x,y,z)坐标和normal,因此您可以计算反射观察方向的方向,并添加指向结果fragment_color的纹素。

    还有更多的东西,如镜面高光和不同的光方程,但我认为你应该先从正常的阴影开始。如果你掌握了基础知识,那么了解更高级的东西就没有问题,只要记住背后的东西......

  3. [edit1]当你是菜鸟时,你显然需要完整的例子开始:

    所以这里用C ++完成GL + VAO / VBO + GLSL +着色器示例。当我使用Borland环境时,它是VCL表单应用程序,所以只需忽略VCL的东西,只提取你需要的东西。这就是它的样子:

    normal shading

    那个十字架是我的点光位置,用肉眼检查正确性,箭头(手绘)显示平均光线方向。

    <强> normal_shading.glsl_vert

    // Vertex
    #version 400 core
    layout(location = 0) in vec3 pos;
    layout(location = 2) in vec3 nor;
    layout(location = 3) in vec3 col;
    uniform mat4 m_model;   // model matrix
    uniform mat4 m_normal;  // model matrix with origin=(0,0,0)
    uniform mat4 m_view;    // inverse of camera matrix
    uniform mat4 m_proj;    // projection matrix
    out vec3 pixel_pos;     // fragment position [GCS]
    out vec3 pixel_col;     // fragment surface color
    out vec3 pixel_nor;     // fragment surface normal [GCS]
    void main()
        {
        pixel_col=col;
        pixel_pos=(m_model*vec4(pos,1)).xyz;
        pixel_nor=(m_normal*vec4(nor,1)).xyz;
        gl_Position=m_proj*m_view*m_model*vec4(pos,1);
        }
    

    <强> normal_shading.glsl_frag

    // Fragment
    #version 400 core
    uniform vec3 lt_pnt_pos;// point light source position [GCS]
    uniform vec3 lt_pnt_col;// point light source color&strength
    uniform vec3 lt_amb_col;// ambient light source color&strength
    in vec3 pixel_pos;      // fragment position [GCS]
    in vec3 pixel_col;      // fragment surface color
    in vec3 pixel_nor;      // fragment surface normal [GCS]
    out vec4 col;
    void main()
        {
        float li;
        vec3 c,lt_dir;
        lt_dir=normalize(lt_pnt_pos-pixel_pos); // vector from fragment to point light source in [GCS]
        li=dot(pixel_nor,lt_dir);
        if (li<0.0) li=0.0;
        c=pixel_col*(lt_amb_col+(lt_pnt_col*li));
        col=vec4(c,1.0);
        }
    

    <强> gl_simple.h

    //---------------------------------------------------------------------------
    //--- GL simple ver: 1.000 --------------------------------------------------
    //---------------------------------------------------------------------------
    #define GLEW_STATIC
    #include "glew.c"
    #include <gl\gl.h>
    #include <gl\glu.h>
    //---------------------------------------------------------------------------
    //--- OpenGL GL example -----------------------------------------------------
    //---------------------------------------------------------------------------
    int     xs,ys;      // screen size
    HDC     hdc=NULL;   // device context
    HGLRC   hrc=NULL;   // rendering context
    int  gl_inicialized=0;
    int  gl_init(HWND Handle);
    void gl_exit();
    void gl_draw();
    void gl_resize(int _xs,int _ys);
    //---------------------------------------------------------------------------
    //--- OpenGL GLSL example ---------------------------------------------------
    //---------------------------------------------------------------------------
    GLint prog_id=0,    // whole program
          vert_id=0,    // vertex shader
          frag_id=0;    // fragment shader
    char  glsl_log[4096];// compile/link GLSL log
    int   glsl_logs=0;
    void  glsl_init(char *vert,char *frag);     // create/compile/link GLSL program
    void  glsl_exit();
    //---------------------------------------------------------------------------
    //--- OpenGL VAO example ----------------------------------------------------
    //---------------------------------------------------------------------------
    #pragma pack(1)
    //#define vao_indices
    GLuint vbo[4]={-1,-1,-1,-1};
    GLuint vao[4]={-1,-1,-1,-1};
    const GLfloat vao_pos[]=
        {
    //  x    y    z     //ix
        -1.0,+1.0,-1.0, //0
        +1.0,+1.0,-1.0, //1
        +1.0,-1.0,-1.0, //2
        -1.0,-1.0,-1.0, //3
    
        -1.0,-1.0,+1.0, //4
        +1.0,-1.0,+1.0, //5
        +1.0,+1.0,+1.0, //6
        -1.0,+1.0,+1.0, //7
    
        #ifndef vao_indices
        -1.0,-1.0,-1.0, //3
        +1.0,-1.0,-1.0, //2
        +1.0,-1.0,+1.0, //5
        -1.0,-1.0,+1.0, //4
    
        +1.0,-1.0,-1.0, //2
        +1.0,+1.0,-1.0, //1
        +1.0,+1.0,+1.0, //6
        +1.0,-1.0,+1.0, //5
    
        +1.0,+1.0,-1.0, //1
        -1.0,+1.0,-1.0, //0
        -1.0,+1.0,+1.0, //7
        +1.0,+1.0,+1.0, //6
    
        -1.0,+1.0,-1.0, //0
        -1.0,-1.0,-1.0, //3
        -1.0,-1.0,+1.0, //4
        -1.0,+1.0,+1.0, //7
        #endif
        };
    
    const GLfloat vao_col[]=
        {
    //  r   g   b    //ix
        0.0,0.0,0.0, //0
        1.0,0.0,0.0, //1
        1.0,1.0,0.0, //2
        0.0,1.0,0.0, //3
        0.0,0.0,1.0, //4
        1.0,0.0,1.0, //5
        1.0,1.0,1.0, //6
        0.0,1.0,1.0, //7
    
        #ifndef vao_indices
        0.0,0.0,0.0, //0
        1.0,0.0,0.0, //1
        1.0,0.0,1.0, //5
        0.0,0.0,1.0, //4
    
        1.0,0.0,0.0, //1
        1.0,1.0,0.0, //2
        1.0,1.0,1.0, //6
        1.0,0.0,1.0, //5
    
        1.0,1.0,0.0, //2
        0.0,1.0,0.0, //3
        0.0,1.0,1.0, //7
        1.0,1.0,1.0, //6
    
        0.0,1.0,0.0, //3
        0.0,0.0,0.0, //0
        0.0,0.0,1.0, //4
        0.0,1.0,1.0, //7
        #endif
        };
    
    #ifndef vao_indices
    const GLfloat vao_nor[]=
        {
    //   nx   ny   nz   //ix
         0.0, 0.0,-1.0, //0
         0.0, 0.0,-1.0, //1
         0.0, 0.0,-1.0, //2
         0.0, 0.0,-1.0, //3
    
         0.0, 0.0,+1.0, //4
         0.0, 0.0,+1.0, //5
         0.0, 0.0,+1.0, //6
         0.0, 0.0,+1.0, //7
    
         0.0,-1.0, 0.0, //0
         0.0,-1.0, 0.0, //1
         0.0,-1.0, 0.0, //5
         0.0,-1.0, 0.0, //4
    
        +1.0, 0.0, 0.0, //1
        +1.0, 0.0, 0.0, //2
        +1.0, 0.0, 0.0, //6
        +1.0, 0.0, 0.0, //5
    
         0.0,+1.0, 0.0, //2
         0.0,+1.0, 0.0, //3
         0.0,+1.0, 0.0, //7
         0.0,+1.0, 0.0, //6
    
        -1.0, 0.0, 0.0, //3
        -1.0, 0.0, 0.0, //0
        -1.0, 0.0, 0.0, //4
        -1.0, 0.0, 0.0, //7
        };
    #endif
    
    #ifdef vao_indices
    const GLuint vao_ix[]=
        {
        0,1,2,3,
        4,5,6,7,
        3,2,5,4,
        2,1,6,5,
        1,0,7,6,
        0,3,4,7,
        };
    #endif
    
    #pragma pack()
    void vao_init();
    void vao_exit();
    void vao_draw();
    //---------------------------------------------------------------------------
    //--- bodies: ---------------------------------------------------------------
    //---------------------------------------------------------------------------
    int gl_init(HWND Handle)
        {
        if (gl_inicialized) return 1;
        hdc = GetDC(Handle);            // get device context
        PIXELFORMATDESCRIPTOR pfd;
        ZeroMemory( &pfd, sizeof( pfd ) );      // set the pixel format for the DC
        pfd.nSize = sizeof( pfd );
        pfd.nVersion = 1;
        pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
        pfd.iPixelType = PFD_TYPE_RGBA;
        pfd.cColorBits = 24;
        pfd.cDepthBits = 24;
        pfd.iLayerType = PFD_MAIN_PLANE;
        SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd);
        hrc = wglCreateContext(hdc);            // create current rendering context
        if(hrc == NULL)
                {
                ShowMessage("Could not initialize OpenGL Rendering context !!!");
                gl_inicialized=0;
                return 0;
                }
        if(wglMakeCurrent(hdc, hrc) == false)
                {
                ShowMessage("Could not make current OpenGL Rendering context !!!");
                wglDeleteContext(hrc);          // destroy rendering context
                gl_inicialized=0;
                return 0;
                }
        gl_resize(1,1);
        glEnable(GL_DEPTH_TEST);                // Zbuf
        glDisable(GL_CULL_FACE);                // vynechavaj odvratene steny
        glDisable(GL_TEXTURE_2D);               // pouzivaj textury, farbu pouzivaj z textury
        glDisable(GL_BLEND);                    // priehladnost
        glShadeModel(GL_SMOOTH);                // gourard shading
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);   // background color
        gl_inicialized=1;
        glewInit();
        return 1;
        }
    //---------------------------------------------------------------------------
    void gl_exit()
        {
        if (!gl_inicialized) return;
        wglMakeCurrent(NULL, NULL);     // release current rendering context
        wglDeleteContext(hrc);          // destroy rendering context
        gl_inicialized=0;
        }
    //---------------------------------------------------------------------------
    void gl_resize(int _xs,int _ys)
        {
        xs=_xs;
        ys=_ys;
        if (xs<=0) xs = 1;                  // Prevent a divide by zero
        if (ys<=0) ys = 1;
        if (!gl_inicialized) return;
        glViewport(0,0,xs,ys);              // Set Viewport to window dimensions
        glMatrixMode(GL_PROJECTION);        // operacie s projekcnou maticou
        glLoadIdentity();                   // jednotkova matica projekcie
        gluPerspective(30,float(xs)/float(ys),0.1,100.0); // matica=perspektiva,120 stupnov premieta z viewsize do 0.1
        glMatrixMode(GL_TEXTURE);           // operacie s texturovou maticou
        glLoadIdentity();                   // jednotkova matica textury
        glMatrixMode(GL_MODELVIEW);         // operacie s modelovou maticou
        glLoadIdentity();                   // jednotkova matica modelu (objektu)
        }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    void glsl_init(char *vert,char *frag)
        {
        const int _size=1024;
        GLint status,siz=0,i;
        const char * VS = vert;
        const char * FS = frag;
        glsl_logs=0;
        if (prog_id<=0) prog_id=glCreateProgram();
    
        if (vert_id<=0) vert_id=glCreateShader(GL_VERTEX_SHADER); else glDetachShader(prog_id,vert_id);
        if (vert)
            {
            glShaderSource(vert_id, 1, &VS,NULL);
            glCompileShader(vert_id);
            glAttachShader(prog_id,vert_id);
            glGetShaderiv(vert_id,GL_COMPILE_STATUS,&status);
            const char t[]="[Vertex]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
            glGetShaderInfoLog(vert_id,_size,&siz,glsl_log+glsl_logs);
            glsl_logs+=siz;
            }
        if (frag_id<=0) frag_id=glCreateShader(GL_FRAGMENT_SHADER); else glDetachShader(prog_id,frag_id);
        if (frag)
            {
            glShaderSource(frag_id, 1, &FS,NULL);
            glCompileShader(frag_id);
            glAttachShader(prog_id,frag_id);
            glGetShaderiv(frag_id,GL_COMPILE_STATUS,&status);
            const char t[]="[Fragment]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
            glGetShaderInfoLog(frag_id,_size,&siz,glsl_log+glsl_logs);
            glsl_logs+=siz;
            }
        glLinkProgram(prog_id);
        glGetProgramiv(prog_id,GL_LINK_STATUS,&status);
        const char t[]="[Program]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
        glGetProgramInfoLog(prog_id,_size,&siz,glsl_log+glsl_logs);
        glsl_logs+=siz;
    
        glReleaseShaderCompiler();
        glsl_log[glsl_logs]=0;
        }
    //------------------------------------------------------------------------------
    void glsl_exit()
        {
        glUseProgram(0);
        if (vert_id>0) { glDetachShader(prog_id,vert_id); glDeleteShader(vert_id); }
        if (frag_id>0) { glDetachShader(prog_id,frag_id); glDeleteShader(frag_id); }
        if (prog_id>0) {                                  glDeleteShader(prog_id); }
        glsl_log[0]=0;
        }
    //---------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    void vao_init()
        {
        GLuint i;
        glGenVertexArrays(4,vao);
        glGenBuffers(4,vbo);
        glBindVertexArray(vao[0]);
        i=0; // vertex
        glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
        glBufferData(GL_ARRAY_BUFFER,sizeof(vao_pos),vao_pos,GL_STATIC_DRAW);
        glEnableVertexAttribArray(i);
        glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
        i=1; // indices
        #ifdef vao_indices
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo[i]);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(vao_ix),vao_ix,GL_STATIC_DRAW);
        glEnableVertexAttribArray(i);
        glVertexAttribIPointer(i,4,GL_UNSIGNED_INT,0,0);
        #endif
        i=2; // normal
        #ifndef vao_indices
        glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
        glBufferData(GL_ARRAY_BUFFER,sizeof(vao_nor),vao_nor,GL_STATIC_DRAW);
        glEnableVertexAttribArray(i);
        glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
        #endif
        i=3; // color
        glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
        glBufferData(GL_ARRAY_BUFFER,sizeof(vao_col),vao_col,GL_STATIC_DRAW);
        glEnableVertexAttribArray(i);
        glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
    
        glBindVertexArray(0);
        glBindBuffer(GL_ARRAY_BUFFER,0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(2);
        glDisableVertexAttribArray(3);
        }
    //---------------------------------------------------------------------------
    void vao_exit()
        {
        glDeleteVertexArrays(4,vao);
        glDeleteBuffers(4,vbo);
        }
    //---------------------------------------------------------------------------
    void vao_draw()
        {
        glBindVertexArray(vao[0]);
        #ifndef vao_indices
        glDrawArrays(GL_QUADS,0,sizeof(vao_pos)/sizeof(vao_pos[0]));                    // QUADS ... no indices
        #endif
        #ifdef vao_indices
        glDrawElements(GL_QUADS,sizeof(vao_ix)/sizeof(vao_ix[0]),GL_UNSIGNED_INT,0);    // indices (choose just one line not both !!!)
        #endif
        glBindVertexArray(0);
        }
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    

    VCL App主要来源:

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #pragma hdrstop
    #include "Unit1.h"
    #include "gl_simple.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    GLfloat lt_pnt_pos[3]={+2.5,+2.5,+2.5};
    GLfloat lt_pnt_col[3]={0.8,0.8,0.8};
    GLfloat lt_amb_col[3]={0.2,0.2,0.2};
    //---------------------------------------------------------------------------
    void gl_draw()
        {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        // load values into shader
        GLint i,id;
        GLfloat m[16];
        glUseProgram(prog_id);
        id=glGetUniformLocation(prog_id,"lt_pnt_pos"); glUniform3fv(id,1,lt_pnt_pos);
        id=glGetUniformLocation(prog_id,"lt_pnt_col"); glUniform3fv(id,1,lt_pnt_col);
        id=glGetUniformLocation(prog_id,"lt_amb_col"); glUniform3fv(id,1,lt_amb_col);
        glGetFloatv(GL_MODELVIEW_MATRIX,m);
        id=glGetUniformLocation(prog_id,"m_model"   ); glUniformMatrix4fv(id,1,GL_FALSE,m);
        m[12]=0.0; m[13]=0.0; m[14]=0.0;
        id=glGetUniformLocation(prog_id,"m_normal"  ); glUniformMatrix4fv(id,1,GL_FALSE,m);
        for (i=0;i<16;i++) m[i]=0.0; m[0]=1.0; m[5]=1.0; m[10]=1.0; m[15]=1.0;
        id=glGetUniformLocation(prog_id,"m_view"    ); glUniformMatrix4fv(id,1,GL_FALSE,m);
        glGetFloatv(GL_PROJECTION_MATRIX,m);
        id=glGetUniformLocation(prog_id,"m_proj"    ); glUniformMatrix4fv(id,1,GL_FALSE,m);
        // draw VAO cube
        vao_draw();
        // turn of shader
        glUseProgram(0);
        // rotate the cube to see animation
        glMatrixMode(GL_MODELVIEW);
        glRotatef(1.0,0.0,1.0,0.0);
        glRotatef(1.0,1.0,0.0,0.0);
    
        // render point light source in [GCS]
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glLoadIdentity();
        GLfloat x,y,z,d=0.25;
        x=lt_pnt_pos[0];
        y=lt_pnt_pos[1];
        z=lt_pnt_pos[2];
        glBegin(GL_LINES);
        glColor3fv(lt_pnt_col);
        glVertex3f(x-d,y,z);
        glVertex3f(x+d,y,z);
        glVertex3f(x,y-d,z);
        glVertex3f(x,y+d,z);
        glVertex3f(x,y,z-d);
        glVertex3f(x,y,z+d);
        glEnd();
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
    
        glFlush();
        SwapBuffers(hdc);
        }
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
        {
        gl_init(Handle);
    
        int hnd,siz; char vertex[4096],fragment[4096];
        hnd=FileOpen("normal_shading.glsl_vert",fmOpenRead); siz=FileSeek(hnd,0,2); FileSeek(hnd,0,0); FileRead(hnd,vertex  ,siz); vertex  [siz]=0; FileClose(hnd);
        hnd=FileOpen("normal_shading.glsl_frag",fmOpenRead); siz=FileSeek(hnd,0,2); FileSeek(hnd,0,0); FileRead(hnd,fragment,siz); fragment[siz]=0; FileClose(hnd);
        glsl_init(vertex,fragment);
        hnd=FileCreate("GLSL.txt"); FileWrite(hnd,glsl_log,glsl_logs); FileClose(hnd);
    
        vao_init();
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormDestroy(TObject *Sender)
        {
        gl_exit();
        glsl_exit();
        vao_exit();
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormResize(TObject *Sender)
        {
        gl_resize(ClientWidth,ClientHeight);
        glMatrixMode(GL_PROJECTION);
        glTranslatef(0,0,-15.0);
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormPaint(TObject *Sender)
        {
        gl_draw();
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
        {
        gl_draw();
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled)
        {
        GLfloat dz=2.0;
        if (WheelDelta<0) dz=-dz;
        glMatrixMode(GL_PROJECTION);
        glTranslatef(0,0,dz);
        gl_draw();
        }
    //---------------------------------------------------------------------------
    

    不要忘记将布局更改为您的布局,仅在已经有效的情况下添加纹理和内容,并始终检查GLSL.txt(编译/链接日志)文件以查看是否所有内容都应该如此。

    此外,您还需要 GLEW ,请参阅