; ------------------------------------------------------
; Simple Vertex Shader
; Copyright (c) 2005-2016, Franck Charlet
; All rights reserved.
; ------------------------------------------------------
; buildblock RELEASE
;       CAPT %5\Release.bat
; buildblockend
; buildblock DEBUG
;       CAPT %5\Debug.bat
; buildblockend

; ------------------------------------------------------
; Constants
SCREEN_WIDTH            equ     800
SCREEN_HEIGHT           equ     600
SCREEN_BPP              equ     32

; ------------------------------------------------------
; Includes
                        include ..\Common_Src\FrameWork.asm
                        include ..\Common_Src\Shaders.asm

; ------------------------------------------------------
; Variables
RotXSpeed               real4   20.0
RotX                    real4   0.0
RotY                    real4   -90.0
RotZ                    real4   0.0
Pos_Z                   real4   0.0

pmodel                  LPGLMmaterial 0
Array                   GLMArray <>

VShader_Id              dd      0

Light_Position          real4   -2.0, 2.0, -2.0, 1.0
Light_Diffuse           real4   1.0, 1.0, 1.0, 1.0
Light_Ambient           real4   0.1, 0.3, 0.4, 1.0

Mat_Specular            real4   1.0, 1.0, 1.0, 1.0

Wave_Pos                real4   0.0
Wave_Speed              real4   14.0

VShader_Args            SHADER_ARG <0.0, 0.0, 0.0, 0.0>

; ------------------------------------------------------
; Name: Initialize()
; Desc: Perform the various initializations
Initialize              proc

                        invoke  glClearDepth, CDBL(1.0)
                        invoke  glHint, GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
                        invoke  glClearColor, 0, 0, 0, CFLT(1.0)
                        invoke  glEnable, GL_NORMALIZE
                        invoke  glEnable, GL_CULL_FACE

                        ; Init the context (needs shader 2.0)
                        invoke  Init_Shaders_Context
                        .if     eax == FALSE
                                invoke  Set_Error_Msg, CSTR("This gfxcard doesn't handle ARB programs")
                                mov     eax, FALSE
                                ret
                        .endif

                        ; Load & assemble the shader
                        invoke  Load_Vertex_Shader, CSTR("..\..\Media\simple.vsh"), addr VShader_Id
                        .if     eax == FALSE
                                invoke  Get_Shader_Error
                                invoke  Set_Error_Msg, eax
                                mov     eax, FALSE
                                ret
                        .endif                  

                        ; Load the object
                        invoke  glmReadOBJ, CSTR("..\..\Media\fish.obj")
                        mov     pmodel, eax
                        .if     eax == FALSE
                                invoke  Set_Error_Msg, CSTR("Can't load model file")
                                mov     eax, FALSE
                                ret
                        .endif
                        
                        ; Prepare it for rendering
                        invoke  glmUnitize, pmodel
                        invoke  glmFacetNormals, pmodel
                        invoke  glmVertexNormals, pmodel, CFLT(90.0)
                        invoke  glmCreateVertexArray, pmodel, GLM_SMOOTH or GLM_MATERIAL, addr Array

                        mov     eax, TRUE
                        ret
Initialize              endp

; ------------------------------------------------------
; Name: Deinitialize()
; Desc: Free allocated resources
Deinitialize            proc
                        invoke  glmDestroyVertexArray, addr Array
                        invoke  glmDelete, pmodel
                        invoke  Destroy_Shader, VShader_Id
                        ret
Deinitialize            endp

; ------------------------------------------------------
; Name: Update()
; Desc: Update the scene
Update                  proc    FrameRate:real4

                        ; Update scene here
                        fld     RotXSpeed
                        fchs
                        fmul    FrameRate
                        fadd    RotX
                        fstp    RotX

                        fld     Wave_Speed
                        fmul    FrameRate
                        fadd    Wave_Pos
                        fstp    Wave_Pos

                        fld     Wave_Pos
                        fsin
                        fstp    VShader_Args.Arg1
                
                        invoke  DInput_Get_Key, DIK_ESCAPE
                        test    eax, eax
                        jz      Esc_Pressed
                        invoke  Terminate_Application
Esc_Pressed:            ret
Update                  endp

; ------------------------------------------------------
; Name: Draw()
; Desc: Draw the scene
Draw                    proc
                        invoke  glClear, GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT

                        invoke  glEnable, GL_DEPTH_TEST

                        ; Draw scene here
                        invoke  glLightfv, GL_LIGHT0, GL_DIFFUSE, addr Light_Diffuse
                        invoke  glLightfv, GL_LIGHT0, GL_AMBIENT, addr Light_Ambient
                        invoke  glLightfv, GL_LIGHT0, GL_POSITION, addr Light_Position
                        invoke  glMaterialf, GL_FRONT, GL_SHININESS, CFLT(110.0)
                        ;invoke glLightfv, GL_LIGHT0, GL_SPECULAR, addr Mat_Specular

                        ; USe this shader to render the geometry
                        invoke  Enable_Vertex_Shader, VShader_Id
                        ; Update it's parameters
                        ; (arguments are sent by group of 4 floating points)
                        invoke  Set_Vertex_Shader_Param, 0, addr VShader_Args

                        ; Draw scene here
                        invoke  glPushMatrix
                                invoke  glTranslatef, CFLT(0.0), CFLT(0.0), CFLT(-3.0)
                                invoke  glRotatef, CFLT(20.0), CFLT(1.0), CFLT(0.0), CFLT(0.0)
                                invoke  glTranslatef, CFLT(0.0), CFLT(0.2), Pos_Z
                                invoke  glRotatef, RotX, CFLT(0.0), CFLT(1.0), CFLT(0.0)
                                invoke  glRotatef, RotY, CFLT(1.0), CFLT(0.0), CFLT(0.0)
                                invoke  glRotatef, RotZ, CFLT(0.0), CFLT(0.0), CFLT(1.0)

                                ; ------------------

                                invoke  glTranslatef, CFLT(-1.0), CFLT(0.0), CFLT(0.0)

                                ; ------------------

                                invoke  glTranslatef, CFLT(2.0), CFLT(0.0), CFLT(0.0)

                                lea     esi, Array
                                invoke  glEnable, GL_COLOR_MATERIAL
                                invoke  glEnable, GL_VERTEX_ARRAY
                                invoke  glEnable, GL_NORMAL_ARRAY
                                invoke  glEnable, GL_COLOR_ARRAY

                                invoke  glVertexPointer, 3, GL_FLOAT, 0, [esi + GLMArray.Triangles]
                                invoke  glColorPointer, 3, GL_FLOAT, 0, [esi + GLMArray.Colors]
                                invoke  glNormalPointer, GL_FLOAT, 0, [esi + GLMArray.Normals]
                                invoke  glDrawArrays, GL_TRIANGLES, 0, [esi + GLMArray.Nbr_Triangles]

                                invoke  glDisable, GL_COLOR_ARRAY
                                invoke  glDisable, GL_NORMAL_ARRAY
                                invoke  glDisable, GL_VERTEX_ARRAY
                                invoke  glDisable, GL_COLOR_MATERIAL

                        invoke  glPopMatrix

                        ; Stop rendering with the shader
                        invoke  Disable_Vertex_Shader

                        ret
Draw                    endp

end start
