ifndef                  _GLSL_ASM
_GLSL_ASM               equ     1

; ------------------------------------------------------
; Structure
SHADER_ARG              struct
Arg1                    real4   ?
Arg2                    real4   ?
Arg3                    real4   ?
Arg4                    real4   ?
SHADER_ARG              ends

; ------------------------------------------------------
; Includes
                        include Extensions.asm
                        include Files.asm

; ------------------------------------------------------
; Variables
glCreateShaderObjectARB PFNGLCREATESHADEROBJECTARBPROC 0
glShaderSourceARB       PFNGLSHADERSOURCEARBPROC 0
glCompileShaderARB      PFNGLCOMPILESHADERARBPROC 0
glCreateProgramObjectARB PFNGLCREATEPROGRAMOBJECTARBPROC 0
glAttachObjectARB       PFNGLATTACHOBJECTARBPROC 0
glLinkProgramARB        PFNGLLINKPROGRAMARBPROC 0
glUseProgramObjectARB   PFNGLUSEPROGRAMOBJECTARBPROC 0
glGetInfoLogARB         PFNGLGETINFOLOGARBPROC 0
glDeleteObjectARB       PFNGLDELETEOBJECTARBPROC 0
glGetObjectParameterivARB PFNGLGETOBJECTPARAMETERIVARBPROC 0
glGetUniformLocationARB PFNGLGETUNIFORMLOCATIONARBPROC 0
glUniform1fvARB         PFNGLUNIFORM1FVPROC 0
glUniform2fvARB         PFNGLUNIFORM2FVPROC 0
glUniform3fvARB         PFNGLUNIFORM3FVPROC 0
glUniform4fvARB         PFNGLUNIFORM4FVPROC 0
glUniform1ivARB         PFNGLUNIFORM1IVPROC 0
glUniform2ivARB         PFNGLUNIFORM2IVPROC 0
glUniform3ivARB         PFNGLUNIFORM3IVPROC 0
glUniform4ivARB         PFNGLUNIFORM4IVPROC 0
glUniformMatrix2fvARB   PFNGLUNIFORMMATRIX2FVPROC 0
glUniformMatrix3fvARB   PFNGLUNIFORMMATRIX3FVPROC 0
glUniformMatrix4fvARB   PFNGLUNIFORMMATRIX4FVPROC 0

_Object_Err_Format      db      "%s:",13,10,"%s", 0

                        .data?

_Object_Err_Msg_Len     dd      ?
_Object_Err_Msg         db      2048 dup (?)
_Object_Err_String      db      2048 dup (?)
_Object_Name            db      MAX_PATH dup (?)

                        .code

; ------------------------------------------------------
; Name: Init_GLSL_Context
; Desc: Obtain GLSL compiler procedures
Init_GLSL_Context       proc
                        invoke  wglGetProcAddress, CSTR("glCreateShaderObjectARB")
                        mov     glCreateShaderObjectARB, eax
                        invoke  wglGetProcAddress, CSTR("glShaderSourceARB")
                        mov     glShaderSourceARB, eax
                        invoke  wglGetProcAddress, CSTR("glCompileShaderARB")
                        mov     glCompileShaderARB, eax
                        invoke  wglGetProcAddress, CSTR("glCreateProgramObjectARB")
                        mov     glCreateProgramObjectARB, eax
                        invoke  wglGetProcAddress, CSTR("glAttachObjectARB")
                        mov     glAttachObjectARB, eax
                        invoke  wglGetProcAddress, CSTR("glLinkProgramARB")
                        mov     glLinkProgramARB, eax
                        invoke  wglGetProcAddress, CSTR("glUseProgramObjectARB")
                        mov     glUseProgramObjectARB, eax
                        invoke  wglGetProcAddress, CSTR("glGetInfoLogARB")
                        mov     glGetInfoLogARB, eax
                        invoke  wglGetProcAddress, CSTR("glDeleteObjectARB")
                        mov     glDeleteObjectARB, eax
                        invoke  wglGetProcAddress, CSTR("glGetObjectParameterivARB")
                        mov     glGetObjectParameterivARB, eax
                        invoke  wglGetProcAddress, CSTR("glGetUniformLocationARB")
                        mov     glGetUniformLocationARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniform1fvARB")
                        mov     glUniform1fvARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniform2fvARB")
                        mov     glUniform2fvARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniform3fvARB")
                        mov     glUniform3fvARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniform4fvARB")
                        mov     glUniform4fvARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniform1ivARB")
                        mov     glUniform1ivARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniform2ivARB")
                        mov     glUniform2ivARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniform3ivARB")
                        mov     glUniform3ivARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniform4ivARB")
                        mov     glUniform4ivARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniformMatrix2fvARB")
                        mov     glUniformMatrix2fvARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniformMatrix3fvARB")
                        mov     glUniformMatrix3fvARB, eax
                        invoke  wglGetProcAddress, CSTR("glUniformMatrix4fvARB")
                        mov     glUniformMatrix4fvARB, eax

                        .if     glCreateShaderObjectARB != NULL && glShaderSourceARB != NULL && glCompileShaderARB != NULL && \
                                glCreateProgramObjectARB != NULL && glAttachObjectARB != NULL && glLinkProgramARB != NULL && \
                                glUseProgramObjectARB != NULL && glGetInfoLogARB != NULL && glDeleteObjectARB != NULL && \
                                glGetObjectParameterivARB != NULL && glGetUniformLocationARB != NULL
                                mov     eax, TRUE
                                ret
                        .endif
                        mov     eax, FALSE
                        ret
Init_GLSL_Context       endp

; ------------------------------------------------------
; Name: Destroy_GLSL_Object
; Desc: Delete a container or a shader object from memory
Destroy_GLSL_Object     proc    GLSLObjectID:dword
                        .if     GLSLObjectID != NULL
                                invoke  glDeleteObjectARB, GLSLObjectID
                        .endif
                        ret
Destroy_GLSL_Object     endp

; ------------------------------------------------------
; Name: Create_GLSL_Object
; Desc: Create a GLSL shaders container
Create_GLSL_Object      proc
                        invoke  glCreateProgramObjectARB
                        ret
Create_GLSL_Object      endp

; ------------------------------------------------------
; Name: Link_GLSL_Object
; Desc: Link all shaders in a container
Link_GLSL_Object        proc    GLSLObjectID:dword
                        local   Error_Status:dword

                        invoke  glLinkProgramARB, GLSLObjectID
                        mov     eax, TRUE
                        .if     Error_Status == GL_FALSE
                                xor     eax, eax
                        .endif
                        ret
Link_GLSL_Object        endp

; ------------------------------------------------------
; Name: Get_GLSL_Error
; Desc: Report GLSL compiler errors
Get_GLSL_Error          proc    uses ebx GLSLObjectID:dword
                        invoke  glGetInfoLogARB, GLSLObjectID, 2048, addr _Object_Err_Msg_Len, addr _Object_Err_Msg
                        lea     eax, [_Object_Err_Msg]
                        mov     ebx, eax
                        invoke  lstrlen, eax
                        .if     eax == 0
                                push    offset _Object_Name
                                push    CSTR("Can't open GLSL file: %s")
                                push    offset _Object_Err_String
                                invoke  sprintf
                                add     esp, 3 * 4
                                mov     eax, offset _Object_Err_String
                        .else
                                push    ebx
                                push    offset _Object_Name
                                push    offset _Object_Err_Format
                                push    offset _Object_Err_String
                                invoke  sprintf
                                add     esp, 4 * 4
                                mov     eax, offset _Object_Err_String
                        .endif
                        ret
Get_GLSL_Error          endp

; ------------------------------------------------------
; Name: Load_GLSL_Pixel_Shader
; Desc: Attach a GLSL fragment shader to a GLSL program
Load_GLSL_Pixel_Shader  proc    uses ebx GLSLObjectID:dword, ShaderFileName:dword, ShaderID:dword
                        local   Shader_Len:dword
                        local   Shader_Mem:dword
                        local   Error_Status:dword

                        mov     ebx, [ShaderID]
                        invoke  glCreateShaderObjectARB, GL_FRAGMENT_SHADER_ARB
                        .if     eax != 0
                                mov     [ebx], eax
                                invoke  Load_File, ShaderFileName, addr Shader_Len
                                mov     Shader_Mem, eax
                                .if     eax == NULL
                                        invoke  Destroy_GLSL_Object, dword ptr [ebx]
                                        xor     eax, eax
                                        ret
                                .endif
                                invoke  glShaderSourceARB, dword ptr [ebx], 1, addr Shader_Mem, NULL
                                invoke  Free_File, Shader_Mem
                                invoke  glCompileShaderARB, dword ptr [ebx]
                                invoke  glGetObjectParameterivARB, dword ptr [ebx], GL_OBJECT_COMPILE_STATUS_ARB, addr Error_Status
                                push    ShaderFileName
                                push    CSTR("%s")
                                push    offset _Object_Name
                                invoke  sprintf
                                add     esp, 3 * 4
                                .if     Error_Status == GL_FALSE
                                        xor     eax, eax
                                        ret
                                .else
                                        invoke  glAttachObjectARB, GLSLObjectID, dword ptr [ebx]
                                        mov     eax, TRUE
                                .endif
                        .endif
                        ret
Load_GLSL_Pixel_Shader  endp

; ------------------------------------------------------
; Name: Load_GLSL_Vertex_Shader
; Desc: Attach a GLSL vertex shader to a GLSL program
Load_GLSL_Vertex_Shader proc    uses ebx GLSLObjectID:dword, ShaderFileName:dword, ShaderID:dword
                        local   Shader_Len:dword
                        local   Shader_Mem:dword
                        local   Error_Status:dword

                        mov     ebx, [ShaderID]
                        invoke  glCreateShaderObjectARB, GL_VERTEX_SHADER_ARB
                        .if     eax != 0
                                mov     [ebx], eax
                                invoke  Load_File, ShaderFileName, addr Shader_Len
                                mov     Shader_Mem, eax
                                .if     eax == NULL
                                        invoke  Destroy_GLSL_Object, dword ptr [ebx]
                                        xor     eax, eax
                                        ret
                                .endif
                                invoke  glShaderSourceARB, dword ptr [ebx], 1, addr Shader_Mem, NULL
                                invoke  Free_File, Shader_Mem
                                invoke  glCompileShaderARB, dword ptr [ebx]
                                invoke  glGetObjectParameterivARB, dword ptr [ebx], GL_OBJECT_COMPILE_STATUS_ARB, addr Error_Status
                                push    ShaderFileName
                                push    CSTR("%s")
                                push    offset _Object_Name
                                invoke  sprintf
                                add     esp, 3 * 4
                                .if     Error_Status == GL_FALSE
                                        xor     eax, eax
                                        ret
                                .else
                                        invoke  glAttachObjectARB, GLSLObjectID, dword ptr [ebx]
                                        mov     eax, TRUE
                                .endif
                        .endif
                        ret
Load_GLSL_Vertex_Shader endp

; ------------------------------------------------------
; Name: Enable_GLSL_Object
; Desc: Enable rendering with a given container
Enable_GLSL_Object      proc    GLSLObjectID:dword
                        invoke  glUseProgramObjectARB, GLSLObjectID
                        ret
Enable_GLSL_Object      endp

; ------------------------------------------------------
; Name: Disable_GLSL_Object
; Desc: Return to the fixed opengl pipeline functions
Disable_GLSL_Object     proc
                        invoke  glUseProgramObjectARB, NULL
                        ret
Disable_GLSL_Object     endp

; ------------------------------------------------------
; Name: Set_GLSL_Float_Var_x
; Desc: Set floating points uniform variables
Set_GLSL_Float_Var_1    proc    ShaderID:dword, VarName:dword, Count:dword, VarValue:ptr real4
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniform1fvARB, eax, Count, VarValue
                        ret
Set_GLSL_Float_Var_1    endp

Set_GLSL_Float_Var_2    proc    ShaderID:dword, VarName:dword, Count:dword, VarValue:ptr real4
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniform2fvARB, eax, Count, VarValue
                        ret
Set_GLSL_Float_Var_2    endp

Set_GLSL_Float_Var_3    proc    ShaderID:dword, VarName:dword, Count:dword, VarValue:ptr real4
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniform3fvARB, eax, Count, VarValue
                        ret
Set_GLSL_Float_Var_3    endp

Set_GLSL_Float_Var_4    proc    ShaderID:dword, VarName:dword, Count:dword, VarValue:ptr real4
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniform4fvARB, eax, Count, VarValue
                        ret
Set_GLSL_Float_Var_4    endp

; ------------------------------------------------------
; Name: Set_GLSL_Int_Var_x
; Desc: Set integers uniform variables
Set_GLSL_Int_Var_1      proc    ShaderID:dword, VarName:dword, Count:dword, VarValue:ptr dword
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniform1ivARB, eax, Count, VarValue
                        ret
Set_GLSL_Int_Var_1      endp

Set_GLSL_Int_Var_2      proc    ShaderID:dword, VarName:dword, Count:dword, VarValue:ptr dword
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniform2ivARB, eax, Count, VarValue
                        ret
Set_GLSL_Int_Var_2      endp

Set_GLSL_Int_Var_3      proc    ShaderID:dword, VarName:dword, Count:dword, VarValue:ptr dword
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniform3ivARB, eax, Count, VarValue
                        ret
Set_GLSL_Int_Var_3      endp

Set_GLSL_Int_Var_4      proc    ShaderID:dword, VarName:dword, Count:dword, VarValue:ptr dword
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniform4ivARB, eax, Count, VarValue
                        ret
Set_GLSL_Int_Var_4      endp

; ------------------------------------------------------
; Name: Set_GLSL_Matrix_Var_x
; Desc: Set matrices uniform variables
Set_GLSL_Matrix_Var_2   proc    ShaderID:dword, VarName:dword, Count:dword, Transpose:dword, VarValue:ptr real4
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniformMatrix2fvARB, eax, Count, Transpose, VarValue
                        ret
Set_GLSL_Matrix_Var_2   endp

Set_GLSL_Matrix_Var_3   proc    ShaderID:dword, VarName:dword, Count:dword, Transpose:dword, VarValue:ptr real4
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniformMatrix3fvARB, eax, Count, Transpose, VarValue
                        ret
Set_GLSL_Matrix_Var_3   endp

Set_GLSL_Matrix_Var_4   proc    ShaderID:dword, VarName:dword, Count:dword, Transpose:dword, VarValue:ptr real4
                        invoke  glGetUniformLocationARB, ShaderID, VarName
                        invoke  glUniformMatrix4fvARB, eax, Count, Transpose, VarValue
                        ret
Set_GLSL_Matrix_Var_4   endp

endif
