; ------------------------------------------------------
; Render To Texture
; 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

PBUFFER_WIDTH           equ     512

; ------------------------------------------------------
; Includes
                        include ..\Common_Src\FrameWork.asm
                        include ..\Common_Src\Bmp.asm
                        include ..\Common_Src\Textures.asm
                        include ..\Common_Src\PBuffers.asm

; ------------------------------------------------------
; Fucntions
Draw_Cube               proto

; ------------------------------------------------------
; Variables
RotX                    real4   0.0
RotXSpeed               real4   40.0
RotY                    real4   0.0
RotYSpeed               real4   30.0
RotZ                    real4   0.0
RotZSpeed               real4   20.0
Texture1                BMP     <>
Texture1_Id             dd      0

Back_Buffer             PBUFFER <>

; ------------------------------------------------------
; 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

                        invoke  Init_Textures_Context

                        ; Create the pixel buffer
                        invoke  Init_PBuffer_Context
                        .if     eax == FALSE
                                invoke  Set_Error_Msg, CSTR("Pixels buffers aren't supported on this hardware.")
                                mov     eax, FALSE
                                ret
                        .endif

                        invoke  Init_PBuffer, addr Back_Buffer, PBUFFER_WIDTH, SCREEN_BPP, 24, 0
                        .if     eax == FALSE
                                invoke  Set_Error_Msg, CSTR("Can't create pixel buffer")
                                mov     eax, FALSE
                                ret
                        .endif

                        ; Init the context of the pbuffer
                        invoke  Select_Render, Back_Buffer.hDC, Back_Buffer.hRC
                        invoke  Reshape_Context, PBUFFER_WIDTH, PBUFFER_WIDTH
                        invoke  glClearDepth, CDBL(1.0)
                        invoke  glHint, GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
                        invoke  glClearColor, CFLT(0.2), CFLT(0.3), CFLT(0.4), CFLT(1.0)
                        invoke  glEnable, GL_NORMALIZE
                        invoke  glEnable, GL_CULL_FACE

                        ; Since it will be used in the context of the pbuffer we need to create this texture
                        ; within that rendering context
                        invoke  Load_BMP, CSTR("..\..\Media\masm32.bmp"), addr Texture1, -1
                        .if     eax == FALSE
                                invoke  Set_Error_Msg, CSTR("Can't load texture file")
                                mov     eax, FALSE
                                ret
                        .endif
                        invoke  Create_2D_Texture, Texture1.Datas, Texture1._Width, TRUE, GL_RGBA, GL_RGBA
                        mov     Texture1_Id, eax
                        .if     eax == FALSE
                                invoke  Set_Error_Msg, CSTR("Can't create texture")
                                mov     eax, FALSE
                                ret
                        .endif
                        
                        ; Restore to the window's context
                        invoke  Select_Render, g_window.hDC, g_window.hRC

                        mov     eax, TRUE
                        ret
Initialize              endp

; ------------------------------------------------------
; Name: Deinitialize()
; Desc: Free allocated resources
Deinitialize            proc
                        invoke  Destroy_PBuffer, addr Back_Buffer
                        invoke  Destroy_Texture, Texture1_Id
                        invoke  Unload_BMP, addr Texture1
                        ret
Deinitialize            endp

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

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

                        fld     RotYSpeed
                        fmul    FrameRate
                        fadd    RotY
                        fstp    RotY

                        fld     RotZSpeed
                        fmul    FrameRate
                        fadd    RotZ
                        fstp    RotZ

                        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

                        ; Render the scene in the pbuffer
                        invoke  Select_Render, Back_Buffer.hDC, Back_Buffer.hRC
                        invoke  glClear, GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT

                        ; Create a cube with the picture on each face as usual
                        invoke  glEnable, GL_TEXTURE_2D
                        invoke  glBindTexture, GL_TEXTURE_2D, Texture1_Id
                        invoke  glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
                        invoke  glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
                        invoke  glPushMatrix
                                invoke  glTranslatef, CFLT(0.0), CFLT(0.0), CFLT(-4.0)
                                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  Draw_Cube
                        invoke  glPopMatrix
                        invoke  glDisable, GL_TEXTURE_2D

                        ; Final rendering in the window
                        invoke  Select_Render, g_window.hDC, g_window.hRC
                        invoke  glClear, GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT

                        ; Bind the pbuffer instead of simply using glBindTexture with a texture id
                        invoke  glEnable, GL_TEXTURE_2D
                        invoke  Bind_PBuffer, addr Back_Buffer
                        invoke  glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
                        invoke  glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
                        invoke  glPushMatrix
                                invoke  glTranslatef, CFLT(0.0), CFLT(0.0), CFLT(-4.0)
                                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  glColor3f, CFLT(1.0), CFLT(1.0), CFLT(1.0)
                                invoke  Draw_Cube
                        invoke  glPopMatrix
                        invoke  glDisable, GL_TEXTURE_2D
                        ; We need to release it once done
                        invoke  Unbind_PBuffer, addr Back_Buffer

                        ret
Draw                    endp

; ------------------------------------------------------
; Name: Draw_Cube()
; Desc: Draw a cube with texture coordinates
Draw_Cube               proc
                        invoke  glBegin, GL_QUADS
                                invoke  glColor3f, CFLT(1.0), CFLT(1.0), CFLT(1.0)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(-1.0), CFLT(-1.0), CFLT(1.0)
                                invoke  glTexCoord2f, CFLT(1.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(-1.0), CFLT(1.0)
                                invoke  glTexCoord2f, CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(1.0), CFLT(1.0)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(-1.0),  CFLT(1.0), CFLT(1.0)

                                invoke  glTexCoord2f, CFLT(1.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(-1.0), CFLT(-1.0), CFLT(-1.0)
                                invoke  glTexCoord2f, CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(-1.0),  CFLT(1.0), CFLT(-1.0)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(1.0),  CFLT(1.0), CFLT(-1.0)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(-1.0), CFLT(-1.0)

                                invoke  glColor3f, CFLT(0.5), CFLT(0.5), CFLT(0.5)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(-1.0),  CFLT(1.0), CFLT(-1.0)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(-1.0),  CFLT(1.0), CFLT(1.0)
                                invoke  glTexCoord2f, CFLT(1.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(1.0),  CFLT(1.0), CFLT(1.0)
                                invoke  glTexCoord2f, CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(1.0),  CFLT(1.0), CFLT(-1.0)

                                invoke  glTexCoord2f, CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(-1.0), CFLT(-1.0), CFLT(-1.0f)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(-1.0), CFLT(-1.0f)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(-1.0), CFLT(1.0f)
                                invoke  glTexCoord2f, CFLT(1.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(-1.0), CFLT(-1.0), CFLT(1.0f)

                                invoke  glColor3f, CFLT(0.7), CFLT(0.7), CFLT(0.7)
                                invoke  glTexCoord2f, CFLT(1.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(-1.0), CFLT(-1.0)
                                invoke  glTexCoord2f, CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(1.0), CFLT(-1.0)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(1.0), CFLT(1.0)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(1.0), CFLT(-1.0), CFLT(1.0)

                                invoke  glTexCoord2f, CFLT(0.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(-1.0), CFLT(-1.0), CFLT(-1.0)
                                invoke  glTexCoord2f, CFLT(1.0), CFLT(0.0)
                                invoke  glVertex3f, CFLT(-1.0), CFLT(-1.0), CFLT(1.0)
                                invoke  glTexCoord2f, CFLT(1.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(-1.0), CFLT(1.0), CFLT(1.0)
                                invoke  glTexCoord2f, CFLT(0.0), CFLT(1.0)
                                invoke  glVertex3f, CFLT(-1.0), CFLT(1.0), CFLT(-1.0)
                        invoke  glEnd
                        ret
Draw_Cube               endp

end start
