Author Topic: GLFW HelloWorld NASM MinGW GCC (Example code)  (Read 5396 times)

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
GLFW HelloWorld NASM MinGW GCC (Example code)
« on: October 10, 2013, 01:10:42 PM »
Hello!

GLFW is an Open Source, multi-platform library for creating windows with OpenGL.

; ############################################################
; This is: GLFW HelloWorld NASM MinGW GCC
; Author: J.K. Encryptor256
; Date: October 10, 2013
; ############################################################
; Description:
; This program set's up GLFW window,
; Loads bitmap image "helloworld.bmp" via custom load function,
; Displays that image on screen via OpenGL.
; ############################################################
; Program code is organized into three sections:
; 1. At this section, i setup bitmap image structure offsets.
; 2. At this section, i define NASM macros. They are pretty easy.
; 3. At this section, is all the code.
; ############################################################
; How to compile:
; In the way i did, in two simple steps as follows:
; 1. NASM: "nasm.exe helloworld.asm -f win32 -o helloworld.o".
;
; 2. GCC: This is a bit larger, folded in two lines, you have to make in one, if compile. :D
;
; "gcc.exe helloworld.o -o helloworld.exe
;         -L"C:/MinGW/lib" -L"K:/win32/glfw" -lglfw3 -lgdi32  -lopengl32  -mwindows".
;
; MinGW library files are here: "C:/MinGW/lib"
; GLFW library files are here: "K:/win32/glfw" there are files "glfw3.dll,glfw3dll.a,libglfw3.a"
; ############################################################
; Using:
; NASM: The Netwide Assembler.(http://nasm.us/).
; GLFW: Multi-platform library for creating windows with OpenGL.(http://www.glfw.org/).
; GCC: GNU Compiler Collection.(http://gcc.gnu.org/).
; MinGW: Minimalist GNU for Windows.(http://www.mingw.org/).
; ############################################################
; I consulted this site, to get an idea,
; on how images are thrown on the sreen via OpenGL. (http://lazyfoo.net)
; OpenGL and Bitmap Structure description i found on MSDN.
; ############################################################

Using GLFW functions:

Code: [Select]
1. glfwInit.
2. glfwTerminate.
3. glfwSetErrorCallback.
4. glfwCreateWindow.
5. glfwMakeContextCurrent.
6. glfwWindowShouldClose.
7. glfwSwapBuffers.
8. glfwPollEvents.
9. glfwSetWindowSizeCallback.
10. glfwGetFramebufferSize.

Using OpenGL functions:

Code: [Select]
1. glClear.
2. glClearColor.
3. glViewport.
4. glMatrixMode.
5. glLoadIdentity.
6. glOrtho.
7. glBegin.
8. glColor3f.
9. glVertex2f.
10. glEnd.
11. glEnable.
12. glDisable.
13. glTexCoord2f.
14. glBindTexture.
15. glTexImage2D.3
16. glGenTextures.
17. glTexParameteri.
18. glDeleteTextures.
19. glGetError.

.Full demonstration:

Full source code and runtime demonstration you can view at youtube.

Named: "GLFW HelloWorld NASM MinGW GCC"

Link: http://youtu.be/yu5M0RsbfQw

.Attachment:

There is an attacment file "GLFW HelloWorld NASM MinGW GCC.zip" of this post, which includes:
1. Main compile file, full source, named: "helloworld.asm".
2. BMP image file, that is loaded and displayed at runtime, named: "helloworld.bmp".
3. Screen shot, there you can see the result of all this, named: "screenshot.bmp".

! There is a post limitation, so i will post other parts, these three sections, here, after.

And that's it!

Encryptor256!

Encryptor256's Investigation \ Research Department.

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: GLFW HelloWorld NASM MinGW GCC (Example code)
« Reply #1 on: October 10, 2013, 01:12:54 PM »
This is section 1, the content of the main compile file, code was organized into three sections.

Code: [Select]
; ############################################################
; ############################################################
; 1. Section: BITMAP IMAGE STRUCTURE OFFSETS
; ############################################################
; ############################################################

        ; The BITMAPFILEHEADER structure contains information about the type,
        ; size, and layout of a file that contains a device-independent bitmap (DIB).

        ; Define offsets
        BITMAPFILEHEADER.bfType equ 0
        BITMAPFILEHEADER.bfSize equ 0+2
        BITMAPFILEHEADER.bfReserved1 equ 0+2+4
        BITMAPFILEHEADER.bfReserved2 equ 0+2+4+2
        BITMAPFILEHEADER.bfOffBits equ 0+2+4+2+2
        BITMAPFILEHEADER_SIZE equ 0+2+4+2+2+4

        ; The BITMAPINFOHEADER structure contains information about the dimensions
        ; and color format of a device-independent bitmap (DIB).

        ; Define offsets
        BITMAPINFOHEADER.biSize equ 0
        BITMAPINFOHEADER.biWidth equ 0+4
        BITMAPINFOHEADER.biHeight equ 0+4+4
        BITMAPINFOHEADER.biPlanes equ 0+4+4+4
        BITMAPINFOHEADER.biBitCount equ 0+4+4+4+2
        BITMAPINFOHEADER.biCompression equ 0+4+4+4+2+2
        BITMAPINFOHEADER.biSizeImage equ 0+4+4+4+2+2+4
        BITMAPINFOHEADER.biXPelsPerMeter equ 0+4+4+4+2+2+4+4
        BITMAPINFOHEADER.biYPelsPerMeter equ 0+4+4+4+2+2+4+4+4
        BITMAPINFOHEADER.biClrUsed equ 0+4+4+4+2+2+4+4+4+4
        BITMAPINFOHEADER.biClrImportant equ 0+4+4+4+2+2+4+4+4+4+4
        BITMAPINFOHEADER_SIZE equ 0+4+4+4+2+2+4+4+4+4+4+4

This is section 2, the content of the main compile file, code was organized into three sections.

Code: [Select]
; ############################################################
; ############################################################
; 2. Section: A BUNCH OF NASM MACROS
; ############################################################
; ############################################################

%macro cextern 1
        extern _%1
        %ifndef %1
                %define %1 _%1
        %endif
%endmacro
%macro cglobal 1
        global _%1
        %ifndef %1
                %define %1 _%1
        %endif
%endmacro
%macro cexternList 1-*
        %rep %0
                cextern %1
                %rotate 1
        %endrep
%endmacro
%macro invoke_cdecl 1-*
        %assign max %0-1
        %if %0 > 0
                %rotate max
                %rep max
                        push dword %1
                        %rotate -1
                %endrep
        %endif
        call %1
        add esp,dword max * 4
%endmacro
%macro invoke_stdcall 1-*
        %assign max %0-1
        %if %0 > 0
                %rotate max
                %rep max
                        push dword %1
                        %rotate -1
                %endrep
        %endif
        call %1
%endmacro
%macro invoke_error 3
        cmp eax,dword %2
        %1 %3
%endmacro
%macro invoke_returns_at 1
        mov dword %1, eax
%endmacro
%macro define_gl_func 2
        extern _%1@%2
        %define %1 _%1@%2
%endmacro
%macro float32.push 1
        fld dword [%1]
%endmacro
%macro float32.pushi 1
        fild dword [%1]
%endmacro
%macro float32.pushv 1
        sub esp,dword 4
        mov dword [esp],__float32__(%1)
        float32.push esp
        add esp,dword 4
%endmacro
%macro float32.pushvi 1
        sub esp,dword 4
        mov dword [esp],%1
        float32.pushi esp
        add esp,dword 4
%endmacro
%macro float32.pop 1
        fstp dword [%1]
%endmacro
%macro float64.pop 1
        fstp qword [%1]
%endmacro
%macro float32.pops 0
        sub esp,dword 4
        float32.pop esp
%endmacro
%macro float64.pops 0
        sub esp,dword 8
        float64.pop esp
%endmacro
%macro float32.args32 1-*
        %rotate -1
        %rep %0
                float32.pushv %1
                float32.pops
                %rotate -1
        %endrep
%endmacro
%macro float32.args32i 1-*
        %rotate -1
        %rep %0
                float32.pushvi %1
                float32.pops
                %rotate -1
        %endrep
%endmacro
%macro float32.args64 1-*
        %rotate -1
        %rep %0
                float32.pushv %1
                float64.pops
                %rotate -1
        %endrep
%endmacro
%macro float32.args64i 1-*
        %rotate -1
        %rep %0
                float32.pushvi %1
                float64.pops
                %rotate -1
        %endrep
%endmacro
Encryptor256's Investigation \ Research Department.

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: GLFW HelloWorld NASM MinGW GCC (Example code)
« Reply #2 on: October 10, 2013, 01:15:37 PM »
This is section 3, the content of the main compile file, code was organized into three sections.

Code: [Select]
; ############################################################
; ############################################################
; 3. Section: MAIN CORE IN NASM
; ############################################################
; ############################################################

; Tell compiler what kind'a cpu type
cpu 386

; Tell compiler to generate 32bit code
bits 32

        ; # Define GLFW functions and constants:
        ; ----------------------------------------------------
        cexternList glfwInit, \
                        glfwTerminate, \
                        glfwSetErrorCallback, \
                        glfwCreateWindow, \
                        glfwMakeContextCurrent, \
                        glfwWindowShouldClose, \
                        glfwSwapBuffers, \
                        glfwPollEvents, \
                        glfwSetWindowSizeCallback, \
                        glfwGetFramebufferSize

        ; # Define C functions and constants
        ; ----------------------------------------------------
        cexternList atexit, \
                        printf, \
                        fopen, \
                        fread, \
                        fclose, \
                        malloc, \
                        free, \
                        fseek

        cglobal main

        SEEK_CUR equ 1

        ; # Define OpenGL functions and constants
        ; ----------------------------------------------------

                ; GL externs (These functions are imported from library)
                define_gl_func glClear,4
                define_gl_func glClearColor,16
                define_gl_func glViewport,16
                define_gl_func glMatrixMode,4
                define_gl_func glLoadIdentity,0
                define_gl_func glOrtho,48
                define_gl_func glBegin,4
                define_gl_func glColor3f,12
                define_gl_func glVertex2f,8
                define_gl_func glEnd,0
                define_gl_func glEnable,4
                define_gl_func glDisable,4
                define_gl_func glTexCoord2f,8
                define_gl_func glBindTexture,8
                define_gl_func glTexImage2D,36
                define_gl_func glGenTextures,8
                define_gl_func glTexParameteri,12
                define_gl_func glDeleteTextures,8
                define_gl_func glGetError,0

                ; GL error constants
                GL_NO_ERROR equ 0
                GL_INVALID_ENUM equ 0x0500
                GL_INVALID_VALUE equ 0x0501
                GL_INVALID_OPERATION equ 0x0502
                GL_STACK_OVERFLOW equ 0x0503
                GL_STACK_UNDERFLOW equ 0x0504
                GL_OUT_OF_MEMORY equ 0x0505

                ; GL graphical constants
                GL_COLOR_BUFFER_BIT equ 0x00004000

                GL_TRUE equ 1
                GL_FALSE equ 0
                GL_MODELVIEW equ 0x1700
                GL_PROJECTION equ 0x1701
                GL_TRIANGLES equ 0x0004
                GL_TEXTURE_2D equ 0x0DE1
                GL_QUADS equ 0x0007
                GL_RGB equ 0x1907
                GL_UNSIGNED_BYTE equ 0x1401
                GL_TEXTURE_MAG_FILTER equ 0x2800
                GL_TEXTURE_MIN_FILTER equ 0x2801
                GL_LINEAR equ 0x2601
                GL_BGR_EXT equ 0x80E0

; -------------------------------------------------------------------------------------
section .data use32 ; 32bit Data segment
; -------------------------------------------------------------------------------------

        ; Strings:
        ; -------------------------------------------------------------------------------

                txt_bmp_info: db 10,"Bitmap '%s' info (Width: %d, Height: %d,"
                                     db "Compression: %d, BitCount: %d, DataSize: %d).",0

                txt_window_text: db "Hello world with GLFW, NASM and Encryptor256",0
                txt_esp: db 10,"Stack check: %d is equal? %d",0
                txt_bmpname: db "helloworld.bmp",0
                txt_error: db 10,"~ Error: %s",0
                txt_file_access_rb: db "rb",0

        ; Strings: glGetError:
        ; -------------------------------------------------------------------------------

                txt_glGetError: db 10,"glGetError: 0x%X, %s.",0
                txt_glErrorN: db "GL_NO_ERROR",0
                txt_glError0: db "GL_INVALID_ENUM",0
                txt_glError1: db "GL_INVALID_VALUE",0
                txt_glError2: db "GL_INVALID_OPERATION",0
                txt_glError3: db "GL_STACK_OVERFLOW",0
                txt_glError4: db "GL_STACK_UNDERFLOW",0
                txt_glError5: db "GL_OUT_OF_MEMORY",0
       
                ; Determine OpenGL error type by this jump table
                glError_types: dd txt_glError0,txt_glError1,txt_glError2
                                      dd txt_glError3,txt_glError4,txt_glError5

        ; Memory items:
        ; -------------------------------------------------------------------------------

        hWindow: dd 0
        bitmapW: dd 0
        bitmapH: dd 0
        hBitmapData: dd 0
        textureID: dd 0
       
        ; One for the debug purposes
        espBK: dd 0


; -------------------------------------------------------------------------------------
section .text use32 ; 32bit Code segment
; -------------------------------------------------------------------------------------

main:       
        push ebp
        mov ebp,esp

        ; Save stack pointer, if error occurs, then compare, maybe stack error.
        mov dword [espBK],esp

        ; glfwSetErrorCallback: (GLFW)
        ; -------------------------------------------------------------------------------
        ; This function sets the error callback.
        ; -------------------------------------------------------------------------------

                invoke_cdecl glfwSetErrorCallback,GLFWErrorCallbackFunction

        ; glfwInit:  (GLFW)
        ; -------------------------------------------------------------------------------
        ; This function initializes the GLFW library.
        ; -------------------------------------------------------------------------------

                invoke_cdecl glfwInit
                invoke_error je,GL_FALSE,main.quitError

        ; glfwTerminate: (GLFW)
        ; -------------------------------------------------------------------------------
        ; This function destroys all remaining windows,
        ; frees any allocated resources and sets the library to an uninitialized state.
        ; -------------------------------------------------------------------------------

                invoke_cdecl atexit,glfwTerminate
       

        ; glfwCreateWindow: (GLFW)
        ; -------------------------------------------------------------------------------
        ; This function creates a window and its associated context.
        ; -------------------------------------------------------------------------------

                invoke_cdecl glfwCreateWindow,1024,512,txt_window_text,0,0
                invoke_error je,0,main.quitError
                invoke_returns_at [hWindow]

        ; glfwSetWindowSizeCallback: (GLFW)
        ; -------------------------------------------------------------------------------
        ; This function sets the size callback of the specified window,
        ; which is called when the window is resized.
        ; -------------------------------------------------------------------------------

                invoke_cdecl glfwSetWindowSizeCallback,[hWindow],GLFWWindowSizeCallback

        ; glfwMakeContextCurrent: (GLFW)
        ; -------------------------------------------------------------------------------
        ; TThis function makes the context of the specified window current on the calling thread
        ; -------------------------------------------------------------------------------

                invoke_cdecl glfwMakeContextCurrent,[hWindow]

        ; * This early GL setup...

        ; glViewport: (OpenGL)
        ; -------------------------------------------------------------------------------
        ; The glViewport function sets the viewport.
        ; -------------------------------------------------------------------------------

                invoke_stdcall glViewport,0,0,1024,512

        ; glMatrixMode: (OpenGL)
        ; -------------------------------------------------------------------------------
        ; The glMatrixMode function specifies which matrix is the current matrix.
        ; -------------------------------------------------------------------------------

                invoke_stdcall glMatrixMode,GL_PROJECTION

        ; glLoadIdentity: (OpenGL)
        ; -------------------------------------------------------------------------------
        ; The glLoadIdentity function replaces the current matrix with the identity matrix.
        ; -------------------------------------------------------------------------------

                invoke_stdcall glLoadIdentity

        ; glOrtho: (OpenGL)
        ; -------------------------------------------------------------------------------
        ; The glOrtho function multiplies the current matrix by an orthographic matrix.
        ; -------------------------------------------------------------------------------

                float32.args64i 0,1024,512,0,0,1
                invoke_stdcall glOrtho

        ; glMatrixMode: (OpenGL)
        ; -------------------------------------------------------------------------------
        ; The glMatrixMode function specifies which matrix is the current matrix.
        ; -------------------------------------------------------------------------------

                invoke_stdcall glMatrixMode,GL_MODELVIEW

        ; glLoadIdentity: (OpenGL)
        ; -------------------------------------------------------------------------------
        ; The glLoadIdentity function replaces the current matrix with the identity matrix.
        ; -------------------------------------------------------------------------------

                invoke_stdcall glLoadIdentity

        ; * This is where image loading and image setup begins...

        ; LoadBmpFile: (Custom)
        ; -------------------------------------------------------------------------------
        ; Load bitmap image and obtain data.
        ; -------------------------------------------------------------------------------

                invoke_stdcall LoadBmpFile, \
                                        txt_bmpname, \
                                        txt_file_access_rb, \
                                        bitmapW,bitmapH, hBitmapData
                invoke_error jne,0,main.quitError

        ; glGenTextures: (OpenGL)
        ; -------------------------------------------------------------------------------
        ; The glGenTextures function generates texture names.
        ; -------------------------------------------------------------------------------

                invoke_stdcall glGenTextures,1,textureID
                invoke_error je,0,main.quitError

        ; glBindTexture: (OpenGL)
        ; -------------------------------------------------------------------------------
        ; The glBindTexture function enables the creation
        ; of a named texture that is bound to a texture target.
        ; -------------------------------------------------------------------------------

                invoke_stdcall glBindTexture,GL_TEXTURE_2D,[textureID]

        ; glTexImage2D: (OpenGL)
        ; -------------------------------------------------------------------------------
        ; The glTexImage2D function specifies a two-dimensional texture image.
        ; -------------------------------------------------------------------------------

                invoke_stdcall glTexImage2D,GL_TEXTURE_2D,0, \
                                        GL_RGB,[bitmapW],[bitmapH],0, \
                                        GL_BGR_EXT,GL_UNSIGNED_BYTE,[hBitmapData]

        ; glTexParameteri: (OpenGL)
        ; -------------------------------------------------------------------------------
        ; Sets texture parameters.
        ; -------------------------------------------------------------------------------
                invoke_stdcall glTexParameteri,GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR
                invoke_stdcall glTexParameteri,GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR

        ; glBindTexture: (OpenGL)
        ; -------------------------------------------------------------------------------

                invoke_stdcall glBindTexture,GL_TEXTURE_2D,0

        ; Enter main loop:
        ; -------------------------------------------------------------------------------

        main.messageLoop:


                ; glClearColor: (OpenGL)
                ; -------------------------------------------------------------------------------
                ; The glClearColor function specifies clear values for the color buffers.
                ; -------------------------------------------------------------------------------

                float32.args32 0.84765625,0.875,0.9375,0.0
                invoke_stdcall glClearColor

                ; glClear: (OpenGL)
                ; -------------------------------------------------------------------------------
                ; The glClear function clears buffers to preset values.
                ; -------------------------------------------------------------------------------

                invoke_stdcall glClear,GL_COLOR_BUFFER_BIT
       
                ; Display image: BEGIN
                ; -------------------------------------------------------------------------------

                        float32.args32 1.0,1.0,1.0
                        invoke_stdcall glColor3f
                        invoke_stdcall glEnable,GL_TEXTURE_2D
                        invoke_stdcall glBindTexture,GL_TEXTURE_2D,[textureID]
                        invoke_stdcall glBegin,GL_QUADS

                                ; Get window size
                                sub esp,dword 4
                                mov edx,esp
                                sub esp,dword 4
                                mov eax,esp
                                invoke_cdecl glfwGetFramebufferSize,[hWindow],eax,edx
                                pop dword eax ; W
                                pop dword edx ; H

                                ; Push arguments
                                float32.args32i 0,edx ; 8. Arguments for glVertex2f
                                float32.args32i 0,1 ; 7. Arguments for glTexCoord2f
                                float32.args32i eax,edx ; 6. Arguments for glVertex2f
                                float32.args32i 1,1 ; 5. Arguments for glTexCoord2f
                                float32.args32i eax,0 ; 4. Arguments for glVertex2f
                                float32.args32i 1,0 ; 3. Arguments for glTexCoord2f
                                float32.args32i 0,0 ; 2. Arguments for glVertex2f
                                float32.args32i 0,0 ; 1. Arguments for glTexCoord2f

                                ; Call functions, set texture and vertex coordinates
                                invoke_stdcall glTexCoord2f ; 1.
                                invoke_stdcall glVertex2f ; 2.
                                invoke_stdcall glTexCoord2f ; 3.
                                invoke_stdcall glVertex2f ; 4.
                                invoke_stdcall glTexCoord2f ; 5.
                                invoke_stdcall glVertex2f ; 6.
                                invoke_stdcall glTexCoord2f ; 7.
                                invoke_stdcall glVertex2f ; 8.

                        invoke_stdcall glEnd
                        invoke_stdcall glDisable,GL_TEXTURE_2D

                ; Display image: END
                ; -------------------------------------------------------------------------------
               
                ; glfwWindowShouldClose: (GLFW)
                ; -------------------------------------------------------------------------
                ; This function returns the value of the close flag of the specified window.
                ; -------------------------------------------------------------------------

                        invoke_cdecl glfwWindowShouldClose,[hWindow]
                        invoke_error jg,0,main.quitLoop
               
                ; glfwSwapBuffers: (GLFW)
                ; -------------------------------------------------------------------------
                ; This function swaps the front and back buffers of the specified window.
                ; -------------------------------------------------------------------------

                        invoke_cdecl glfwSwapBuffers,[hWindow]
               
                ; glfwPollEvents: (GLFW)
                ; -------------------------------------------------------------------------
                ; This function processes only those events that
                ; have already been received and then returns immediately.
                ; -------------------------------------------------------------------------

                        invoke_cdecl glfwPollEvents

                jmp main.messageLoop
        main.quitLoop:


        ; free: (C)
        ; -------------------------------------------------------------------------
        ; C function, release bitmap data, that were allocated by Load bitmap function
        ; -------------------------------------------------------------------------

                invoke_cdecl free,[hBitmapData]
               
        ; glDeleteTextures: (OpenGL)
        ; -------------------------------------------------------------------------
        ; The glDeleteTextures function deletes named textures.
        ; -------------------------------------------------------------------------

                invoke_stdcall glDeleteTextures,1,textureID

        ; Quit normal:
        ; -------------------------------------------------------------------------------
        mov eax,dword 0
        pop ebp
        ret

        ; Quit error:
        ; -------------------------------------------------------------------------------
        main.quitError:

        ; Check, print stack error:
        mov eax,esp
        mov edx,esp
        mov edx,dword [espBK]
        invoke_cdecl printf,txt_esp,edx,eax

        ; Check stack error:
        call printGLError
        mov eax,dword -1
        pop ebp
        ret

Encryptor256's Investigation \ Research Department.

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: GLFW HelloWorld NASM MinGW GCC (Example code)
« Reply #3 on: October 10, 2013, 01:17:00 PM »
This is section 3, the content of the main compile file, code was organized into three sections.

This is rest of the section 3: "Procedures".

Code: [Select]
; ############################################################
; ############################################################
; PROCEDURES
; ############################################################
; ############################################################

; -------------------------------------------------------------------------------------
GLFWErrorCallbackFunction: ; This procedure is called when GLFW finds an error
; -------------------------------------------------------------------------------------
        push ebp
        mov ebp,esp
        ; -------------------------------
        %define ebp_error_code ebp+8
        %define ebp_error_text ebp+12
        ; -------------------------------
        ; Display error message
        invoke_cdecl printf,txt_error,[ebp_error_text]
        pop ebp
        ret

; -------------------------------------------------------------------------------------
GLFWWindowSizeCallback: ; This procedure is called when GLFW resizes window
; -------------------------------------------------------------------------------------
        push ebp
        mov ebp,esp
        ; -------------------------------
        %define ebp_wnd_handle ebp+8
        %define ebp_width ebp+12
        %define ebp_height ebp+16
        ; -------------------------------
       
        ; Reset opengl...

        invoke_stdcall glViewport,0,0,[ebp_width],[ebp_height]

        invoke_stdcall glMatrixMode,GL_PROJECTION
        invoke_stdcall glLoadIdentity

        mov eax,dword [ebp_width]
        mov edx,dword [ebp_height]
        float32.args64i 0,eax,edx,0,0,1
        invoke_stdcall glOrtho

        invoke_stdcall glMatrixMode,GL_MODELVIEW
        invoke_stdcall glLoadIdentity
       
        pop ebp
        ret

; -------------------------------------------------------------------------------------
LoadBmpFile:
; Loads uncompressed RGB image, bits per pixel: 24
; Code description:
; 1. Open File.
; 2. Allocate structure of BITMAPFILEHEADER.
; 3. Allocate structure of BITMAPINFOHEADER.
; 4. Read both structures from file.
; 5. Collect data, print bitmap info, format specified in "txt_bmp_info".
; 6. Allocate bitmap data, the data for all bitmap image pixels.
; 7. Read bitmap data into allocated buffer address.
; 8. Set output w and h pointer params.
; 9. Right now loaded image is upside down, so flip image vertically.
; 10. Quit
; -------------------------------------------------------------------------------------
        push ebp
        mov ebp,esp
        ; -------------------------------
        %define ebp_name ebp+8
        %define ebp_access ebp+12
        %define ebp_w_ptr ebp+16
        %define ebp_h_ptr ebp+20
        %define ebp_data_ptr ebp+24
        ; -------------------------------
        %define ebp_handle ebp-4
        %define ebp_w ebp-8
        %define ebp_h ebp-12
        %define ebp_hBMFileHeader ebp-16
        %define ebp_hBMInfoHeader ebp-20
        %define ebp_hData ebp-24
        %define ebp_hDataLen ebp-28
        ; -------------------------------------------------------------------------------
        sub esp,dword 28
        ; 1. -------------------------------------------------------------------------------
        invoke_cdecl fopen,[ebp_name],[ebp_access]
        invoke_error je,0,LoadBmpFile.quitError
        invoke_returns_at [ebp_handle]
        ; 2. -------------------------------------------------------------------------------
        invoke_cdecl malloc,BITMAPFILEHEADER_SIZE
        invoke_error je,0,LoadBmpFile.quitError
        invoke_returns_at [ebp_hBMFileHeader]
        ; 3. -------------------------------------------------------------------------------
        invoke_cdecl malloc,BITMAPINFOHEADER_SIZE
        invoke_error je,0,LoadBmpFile.quitError
        invoke_returns_at [ebp_hBMInfoHeader]
        ; 4. -------------------------------------------------------------------------------
        invoke_cdecl fread,[ebp_hBMFileHeader],1,BITMAPFILEHEADER_SIZE,[ebp_handle]
        invoke_cdecl fread,[ebp_hBMInfoHeader],1,BITMAPINFOHEADER_SIZE,[ebp_handle]
        ; -------------------------------------------------------------------------------
        ; 5. Print info:
        ; -------------------------------------------------------------------------------
        ; -
        ; Calculate size w*h:
        mov eax,dword [ebp_hBMInfoHeader]
        mov ebx,dword [eax+BITMAPINFOHEADER.biWidth]
        mov eax,dword [eax+BITMAPINFOHEADER.biHeight]
        mov dword [ebp_w],ebx
        mov dword [ebp_h],eax
        mov edx,dword 0
        mul ebx
        ; -
        ; Calculate size w*h*3:
        mov ebx,eax
        mov eax,3
        mov edx,dword 0
        mul ebx
        mov ecx,eax
        push ecx ; Save data size
        ; -
        ; Get bit count word:
        mov eax,dword [ebp_hBMInfoHeader]
        mov edx,dword 0
        mov dx,word [eax+BITMAPINFOHEADER.biBitCount]
        ; Display:
        invoke_cdecl printf, \
                                txt_bmp_info, \
                                [ebp_name], \
                                [eax+BITMAPINFOHEADER.biWidth], \
                                [eax+BITMAPINFOHEADER.biHeight], \
                                [eax+BITMAPINFOHEADER.biCompression], \
                                edx, \
                                ecx
        ; 6. -------------------------------------------------------------------------------
        ; Allocate memory
        pop edx
        push edx
        mov dword [ebp_hDataLen],edx
        invoke_cdecl malloc,edx
        invoke_error je,0,LoadBmpFile.quitError
        invoke_returns_at [ebp_hData]
        mov edx,dword [ebp_data_ptr]
        invoke_returns_at [edx]
        ; 7. -------------------------------------------------------------------------------
        pop edx
        invoke_cdecl fread,[ebp_hData],1,edx,[ebp_handle] ; Read data
        ; 8. -------------------------------------------------------------------------------
        mov edx,dword [ebp_w]
        mov eax,dword [ebp_w_ptr]
        mov dword [eax],edx
        mov edx,dword [ebp_h]
        mov eax,dword [ebp_h_ptr]
        mov dword [eax],edx
        ; 9. -------------------------------------------------------------------------------
        ; Flip output memory vertically:

                ; Get row size in bytes: w * 3
                mov eax,dword [ebp_w]
                mov edx,dword 0
                mov ebx,dword 3
                mul ebx
               
                ;Setup addresses
                mov esi,dword [ebp_hData] ; Setup address on start
                mov edi,dword [ebp_hData] ; Setup address on end
                add edi,dword [ebp_hDataLen] ; Setup address on end
                sub edi,eax ; edi - row size (eax)

                ;Save row size, source and dst addresses
                push esi ;Stack +1 (1)
                push edi ;Stack +2 (2)
                push eax ;Stack +3 (3)

                ; Get column size in bytes: h / 2
                mov eax,dword [ebp_h]
                mov edx,dword 0
                mov ebx,dword 2
                div ebx
                mov ecx,eax

                LoadBmpFile.Reverser:
                        ; ----------------
                        pop eax ;Stack -1 (2)
                        push eax ;Stack +1 (3)
                        ; ----------------
                        push ecx ;Stack +1 (4)
                        ; ----------------
                        mov ecx,eax
                        ; ----------------

                        LoadBmpFile.Reverser.loopRow:

                                ; Swap bytes esi, edi
                                mov al,byte [esi]
                                mov ah,byte [edi]
                                mov byte [edi],al
                                mov byte [esi],ah

                                ; Inc addresses
                                add esi,dword 1
                                add edi,dword 1

                                ; Dec loop counter
                                sub ecx,dword 1
                                cmp ecx,dword 0
                                jg LoadBmpFile.Reverser.loopRow

                        ; ----------------
                        pop ecx ;Stack -1 (3)
                        ; ----------------
                        pop eax ;Stack -1 (2)
                        pop edi ;Stack -1 (1)
                        pop esi ;Stack -1 (0)
                        ; ----------------
                        add esi,eax ; esi + row size (eax)
                        sub edi,eax ; edi - row size (eax)
                        ; ----------------
                        push esi ;Stack +1 (1)
                        push edi ;Stack +1 (2)
                        push eax ;Stack +1 (3)
                        ; ----------------
                        sub ecx,dword 1
                        cmp ecx,dword 0
                        jg LoadBmpFile.Reverser

                pop eax ;Stack -1 (2)
                pop edi ;Stack -1 (1)
                pop esi ;Stack -1 (0)

        ; 10. -------------------------------------------------------------------------------
        ; Quit Normal:
        ; -------------------------------------------------------------------------------
        invoke_cdecl free,[ebp_hBMFileHeader]
        invoke_cdecl free,[ebp_hBMInfoHeader]
        invoke_cdecl fclose,[ebp_handle]
        ; -------------------------------------------------------------------------------
        add esp,dword 28
        ; -------------------------------------------------------------------------------
        mov eax,dword 0
        pop ebp
        ret 4*5

        ; Quit error:
        ; -------------------------------------------------------------------------------
        LoadBmpFile.quitError:
        ; -------------------------------------------------------------------------------
        add esp,dword 28
        ; -------------------------------------------------------------------------------
        mov eax,dword -1
        pop ebp
        ret 4*5

; -------------------------------------------------------------------------------------
printGLError: ; This procedure prints OpenGL error
; -------------------------------------------------------------------------------------
        push ebp
        mov ebp,esp
        pushad
        invoke_stdcall glGetError
        cmp eax,dword 0
        jne printGLError.continue
        ;----------------------------------
        invoke_cdecl printf,txt_glGetError,0,txt_glErrorN
        ;----------------------------------
        popad
        pop ebp
        ret
        ;----------------------------------
        printGLError.continue:
        push eax
        sub eax,dword 0x0500
        mov edx,dword 0
        mov ebx,dword 4
        mul ebx
        add eax,dword glError_types
        pop edx
        invoke_cdecl printf,txt_glGetError,edx,[eax]
        popad
        pop ebp
        ret

; ---
; END ---
; ---

And that's it!

Byte!

Encryptor256!
Encryptor256's Investigation \ Research Department.