Voici le debut d'un moteur 3D OPEN GL.
Il est tres basique et comporte des erreurs.
Je reviendrais le mettre a jours de temps a autre, mais pour etre franc, je n'ai pas beaucoup de temps en ce moment
Ce programme integre un gestion des FPS afin donner des ressources CPU a d'autres processus
Source / Exemple :
.586p
.MODEL FLAT,STDCALL
option casemap:none
include .\include\windows.inc
include .\Include\OpenGL\gl.def
include .\Include\OpenGL\glu.def
include .\Include\kernel32.inc
include .\Include\user32.inc
include .\Include\gdi32.inc
include .\Include\masm32.inc
include .\Include\WinExtra\winextra.def
include .\Include\fpu.inc
includelib .\Lib\OpenGL\opengl32.lib
includelib .\Lib\OpenGL\glu32.lib
includelib .\Lib\kernel32.lib
includelib .\Lib\user32.lib
includelib .\Lib\gdi32.lib
includelib .\Lib\masm32.lib
includelib .\Lib\fpu.lib
CreateGLWindow PROTO :DWORD,:DWORD,:DWORD,:DWORD,:BOOL
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
GLPrint PROTO :UINT, :UINT, :DWORD,:UINT
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
ReSizeGLScene PROTO :DWORD,:DWORD
ReadALine PROTO :DWORD,:DWORD
KillGLWindow PROTO
InitGL PROTO
DrawGLScene PROTO
LoadGLTexture PROTO
SetupWorld PROTO
BuildFont PROTO
KillFont PROTO
include macro.inc ; Macros
include variable.inc ; Variable d'environement
include user_var.inc ; Variable utilisateur
include timer.asm ; thread enfant de gestion des prioritées
include world.asm ; creation du monde 3D
.CODE
start:
INVOKE GetModuleHandle,0
MOV hInstance,eax
INVOKE WinMain,eax,0,0,0
INVOKE ExitProcess,eax
WinMain PROC hInst: HWND,
hPrevInst: UINT,
CmdLine: WPARAM,
CmdShow: LPARAM
LOCAL msg:MSG
; on defini le centre de l'ecran
mov eax,x_size
shr eax,2
mov cmx,eax
mov eax,y_size
shr eax,2
mov cmy,eax
INVOKE CreateGLWindow,ADDR our_title,x_size,y_size,bpp,fullscreen ; creation de la fenetre GL
.IF (!eax)
ret
.ENDIF
INVOKE CreateThread,0,4096,ADDR Timer,0,0,ADDR Id_Timer ; creation d'un thread enfants d'une taille initial de 4 Ko
invoke SetCursorPos,cmx,cmy ; on position le curseur au centre de l'ecran
mov eax,cmx ; on defini les coordonées de la souris a cet emplacement
mov ebx,cmy
mov mx,eax
mov my,ebx
MOV done,0
.WHILE (!done) ; boucle inifi tant que done <>0
invoke Sleep, 1 ; pour reduire l'utilisation CPU
inc Loop_Count
INVOKE PeekMessage,ADDR msg,0,0,0,PM_REMOVE ; controle de la file d'attente de message
.IF (eax)
.IF msg.message == WM_QUIT
MOV done,1
.ELSE
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.ENDIF
.ENDIF
.IF (Go_Draw) ; si c'est le moment d'afficher
INVOKE DrawGLScene ; on affiche la scene
.IF ((active) && (!eax)) || (keys[VK_ESCAPE])
MOV done,1
.ELSE
INVOKE SwapBuffers,hDC
.ENDIF
XOR eax,eax ; Go_Draw=0
MOV Go_Draw,eax
.ENDIF
.ENDW
INVOKE KillGLWindow ; on tue la fenetre GL
MOV eax,msg.wParam
RET
WinMain endp
WndProc PROC hWin: DWORD,
uMsg: DWORD,
wParam: DWORD,
lParam: DWORD
LOCAL ps: PAINTSTRUCT
.IF uMsg == WM_DESTROY
invoke PostQuitMessage,0 ; tuez l'application, envoyez un message de WM_QUIT
xor eax,eax
ret
.ELSEIF uMsg == WM_PAINT
invoke BeginPaint,hWin,ADDR ps ; prépare la fenêtre
.if eax == NULL
;INVOKE MessageBox,0,"aucun DC d'affichage n'est disponible",ADDR error_00,MB_OK or MB_ICONEXCLAMATION
xor eax,eax
ret
.endif
mov hDC,eax
invoke EndPaint,hWin, ADDR ps
xor eax,eax
ret
.ELSEIF uMsg == WM_CREATE
xor eax,eax
ret
.ELSEIF uMsg == WM_ACTIVATE
MOV eax,wParam
.IF (!eax)
MOV active,1
.ELSE
MOV active,0
.ENDIF
xor eax,eax
ret
.ELSEIF uMsg == WM_SYSCOMMAND
.IF (wParam == SC_SCREENSAVE) || (wParam == SC_MONITORPOWER)
XOR eax,eax
RET
.ENDIF
xor eax,eax
ret
.ELSEIF uMsg == WM_LBUTTONDOWN
xor eax,eax
ret
.ELSEIF uMsg == WM_LBUTTONUP
xor eax,eax
ret
.ELSEIF uMsg == WM_RBUTTONDOWN
xor eax,eax
ret
.ELSEIF uMsg == WM_RBUTTONUP
xor eax,eax
ret
.ELSEIF uMsg == WM_MBUTTONDOWN
xor eax,eax
ret
.ELSEIF uMsg == WM_MBUTTONUP
xor eax,eax
ret
.ELSEIF uMsg == WM_MOUSEMOVE ; si la souris a bouger
mov eax,lParam ; mx = LOWORD(lParam) horizontal position of cursor
mov ebx,eax ; my = HIWORD(lParam) vertical position of cursor
and eax,65535
shr ebx,16
mov ecx,eax
and ecx,32768
.if ecx != 0
sub eax,65536
.endif
mov ecx,ebx
and ecx,32768
.if ecx != 0
sub ebx,65536
.endif
mov mx,eax
mov my,ebx
xor eax,eax
ret
.ELSEIF uMsg == WM_MOUSEWHEEL
xor eax,eax
ret
.ELSEIF uMsg == WM_KEYDOWN ; si une touche est pressé
MOV eax,wParam ; on l'enregistre dans le tableau des touches
MOV keys[eax],1
xor eax,eax
ret
.ELSEIF uMsg == WM_KEYUP ; si une touche est relaché
MOV eax,wParam ; on la libere du tableau des touches
MOV keys[eax],0
xor eax,eax
ret
.ELSEIF uMsg == WM_SIZE ; si on redimention l'ecran
MOV eax,lParam
MOV ebx,eax
AND eax,0ffffh ; eax=width=LOWORD
SHR ebx,16 ; ebx=height=HIWORD
INVOKE ReSizeGLScene,eax,ebx ; on redimentionne la scene
xor eax,eax
ret
.ELSEIF uMsg == WM_CLOSE ; si on quitte l'application
INVOKE PostQuitMessage,0
XOR eax,eax
RET
.ENDIF
INVOKE DefWindowProc,hWin,uMsg,wParam,lParam
RET
WndProc endp
InitGL PROC
INVOKE LoadGLTexture ; Chargement des textures
.IF (!eax) ; si il y a eu une erreur
;INVOKE MessageBox,0,"Erreur au chargements des textures",ADDR error_00,MB_OK or MB_ICONEXCLAMATION
xor eax,eax
RET
.ENDIF
INVOKE BuildFont ; Construire la police
_glClearColor 0.0f,0.0f,0.0f,0.0f ; Definir la couleur de fond en noir
_glClearDepth 1.0f ; Installation du buffer de profondeur
INVOKE glDepthFunc,GL_LEQUAL ; Definir le type de profondeur
INVOKE glBlendFunc,GL_SRC_ALPHA,GL_ONE ; Definir le type BLEND
INVOKE glShadeModel,GL_SMOOTH ; Definir la nuance
INVOKE glEnable,GL_TEXTURE_2D ; Activer les textures
INVOKE SetupWorld ; Constuire les objets du monde
MOV eax,1
RET
InitGL endp
BuildFont PROC
LOCAL charx: REAL4,
chary: REAL4,
temp: UINT,
counter:UINT
.data
align 4
r4_000_0625 REAL4 00.0625f
r4_016_0 REAL4 16.0000f
r4_001_0 REAL4 01.0000f
r8_010_0 REAL8 10.0f
.code
INVOKE glGenLists,256 ; Créez 256 listes d'affichage
MOV base,eax
MOV counter,0
.WHILE (counter < 256)
MOV eax,counter ; charx = (temp2 mod 16)/16 chary = 1 - int(temp2/16)/16
XOR edx,edx
MOV ebx,16
DIV ebx
MOV temp,eax
FILD temp
FDIV r4_016_0
FSUBR r4_001_0
FSTP chary
MOV temp,edx
FILD temp
FDIV r4_016_0
FSTP charx
MOV eax,[counter]
ADD eax,base
INVOKE glNewList,eax,GL_COMPILE ; Demarre la creation de la liste
INVOKE glBegin,GL_QUADS ; Utiliser un carré pour chaque caractere
FLD chary ; coord. gauche inférieure de la texture
FSUB r4_000_0625
FSTP chary
INVOKE glTexCoord2f,charx,chary
INVOKE glVertex2i,0,0
FLD charx ; coord. droite inférieure de la texture
FADD r4_000_0625
FSTP charx
INVOKE glTexCoord2f,charx,chary
INVOKE glVertex2i,16,0
FLD chary ; coord. droite superieur de la texture
FADD r4_000_0625
FSTP chary
INVOKE glTexCoord2f,charx,chary
INVOKE glVertex2i,16,16
FLD charx ; coord. gauche superieur de la texture
FSUB r4_000_0625
FSTP charx
INVOKE glTexCoord2f,charx,chary
INVOKE glVertex2i,0,16
INVOKE glEnd
INVOKE glTranslated,(DWORD PTR [r8_010_0]),(DWORD PTR [r8_010_0+4]),(DWORD PTR [Zero]),(DWORD PTR [Zero]),(DWORD PTR [Zero]),(DWORD PTR [Zero])
INVOKE glEndList
INC counter
.ENDW
RET
BuildFont endp
KillFont PROC
INVOKE glDeleteLists,base,256
ret
KillFont endp
GLPrint PROC x: UINT,
y: UINT,
string: DWORD,
set: UINT
LOCAL gld_x: REAL8,
gld_y: REAL8
FILD x ; Convertissez le GLuint en GLdoubles pour utiliser avec glTranslated
FSTP gld_x
FILD y ; Convertissez le GLuint en GLdoubles pour utiliser avec glTranslated
FSTP gld_y
.IF (set > 1)
MOV set,1
.ENDIF
invoke glEnable,GL_TEXTURE_2D ; activation du texturing
INVOKE glBindTexture,GL_TEXTURE_2D,texture[TEX_FONTS] ; utiliser la texture 'FONTS'
INVOKE glDisable,GL_DEPTH_TEST ; Desactive le test de profondeur
INVOKE glMatrixMode,GL_PROJECTION ; Choisie la matrice de projection
INVOKE glPushMatrix ; Stock la matrice de projection
INVOKE glLoadIdentity ; Remise a zero de la matrice de projection
_glOrtho 0.0f,640.0f,0.0f,480.0f,-1.0f,1.0f ; Selection le mode Ortho
INVOKE glMatrixMode,GL_MODELVIEW ; Choisie la matrice de projection
INVOKE glPushMatrix ; Stock la matrice de projection
INVOKE glLoadIdentity ; Remise a zero de la matrice de projection
INVOKE glTranslated,(DWORD PTR [gld_x]),(DWORD PTR [gld_x+4]),(DWORD PTR [gld_y]),(DWORD PTR [gld_y+4]),(DWORD PTR [Zero]),(DWORD PTR [Zero])
MOV eax,128 ; Choissi la police
mul set ; eax= (128*set)+base-32
ADD eax,base
sub eax,32
INVOKE glListBase,eax
INVOKE StrLen,string
INVOKE glCallLists,eax,GL_BYTE,string ; Écrit le texte à l'écran
INVOKE glMatrixMode,GL_PROJECTION ; Choisie la matrice de projection
INVOKE glPopMatrix ; Restore l'ancienne matrice de projection
INVOKE glMatrixMode,GL_MODELVIEW ; Choisie la matrice de projection
INVOKE glPopMatrix ; Restore l'ancienne matrice de projection
INVOKE glEnable,GL_DEPTH_TEST ; Active le test de profondeur
invoke glDisable,GL_TEXTURE_2D ; desactive le texturing
ret
GLPrint endp
CreateGLWindow PROC letitle:DWORD,
w: DWORD,
h: DWORD,
bits: DWORD,
flag: BOOL
LOCAL PixelFormat: DWORD,
wc: WNDCLASS,
dwExStyle: DWORD,
dwStyle: DWORD,
rect: RECT,
dmScreenSetting:DEVMODE,
pfd: PIXELFORMATDESCRIPTOR
MOV rect.left,0 ; defini un rectangle de 0,0,w,h
PUSH w
POP rect.right
MOV rect.top,0
PUSH h
POP rect.bottom
.if flag!=0
MOV fullscreen,1
.else
MOV fullscreen,0
.endif
; Definit wc qui contient les attributs de classe de fenêtre pour etre appelé par RegisterClass.
MOV wc.style,CS_HREDRAW or CS_VREDRAW or CS_OWNDC
MOV wc.lpfnWndProc,offset WndProc
MOV wc.cbClsExtra,0
MOV wc.cbWndExtra,0
PUSH hInstance
POP wc.hInstance
MOV wc.hIcon,0
INVOKE LoadCursor,0,IDC_ARROW ; definit le curseur de souris (mode fenetrer uniquement)
.IF (!eax)
INVOKE MessageBox,0,ADDR error_01,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
XOR eax,eax
ret
.ENDIF
MOV wc.hCursor,eax
MOV wc.lpszMenuName,0
MOV wc.lpszClassName,offset ClassName
MOV wc.hbrBackground,0
INVOKE RegisterClass,ADDR wc ; enregistre la classe
.IF (!eax)
INVOKE MessageBox,0,ADDR error_02,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
XOR eax,eax
ret
.ENDIF
.IF (fullscreen) ; si on passe en mode plein ecran, on change la resolution actuelle
ZeroMemory &dmScreenSetting,sizeof(dmScreenSetting)
MOV dmScreenSetting.dmSize,sizeof dmScreenSetting
PUSH w
POP dmScreenSetting.dmPelsWidth
PUSH h
POP dmScreenSetting.dmPelsHeight
PUSH bits
POP dmScreenSetting.dmBitsPerPel
MOV dmScreenSetting.dmFields,DM_BITSPERPEL or DM_PELSWIDTH or DM_PELSHEIGHT
INVOKE ChangeDisplaySettings,ADDR dmScreenSetting,CDS_FULLSCREEN
.IF eax != DISP_CHANGE_SUCCESSFUL
INVOKE MessageBox,0,ADDR error_03,ADDR error_00,MB_YESNO or MB_ICONEXCLAMATION
.IF eax == IDYES
MOV fullscreen,0
.ELSE
INVOKE MessageBox,0,ADDR error_04,ADDR error_00,MB_OK or MB_ICONSTOP
XOR eax,eax
ret
.ENDIF
.ENDIF
.ENDIF
.IF (fullscreen)
MOV dwExStyle,WS_EX_APPWINDOW
MOV dwStyle,WS_POPUP or WS_CLIPSIBLINGS or WS_CLIPCHILDREN
INVOKE ShowCursor,0 ; en mode plein ecran on cache le curseur
.ELSE
MOV dwExStyle,WS_EX_APPWINDOW or WS_EX_WINDOWEDGE
MOV dwStyle,WS_OVERLAPPEDWINDOW or WS_CLIPSIBLINGS or WS_CLIPCHILDREN
.ENDIF
INVOKE AdjustWindowRectEx,ADDR rect,dwStyle,0,dwExStyle
MOV eax,rect.left
sub rect.right,eax
MOV eax,rect.top
sub rect.bottom,eax
INVOKE CreateWindowEx,dwExStyle,ADDR ClassName,ADDR our_title,dwStyle,0,0,rect.right,rect.bottom,0,0,hInstance,0
MOV hWnd,eax
.IF (!eax)
INVOKE KillGLWindow
INVOKE MessageBox,0,ADDR error_05,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
XOR eax,eax
ret
.ENDIF
ZeroMemory &pfd,sizeof(PIXELFORMATDESCRIPTOR)
MOV pfd.nSize,sizeof PIXELFORMATDESCRIPTOR
MOV pfd.nVersion,1
MOV pfd.dwFlags,PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER
MOV pfd.iPixelType,PFD_TYPE_RGBA
MOV eax,bits
MOV pfd.cColorBits,al
MOV pfd.cDepthBits,16
MOV pfd.dwLayerMask,PFD_MAIN_PLANE
INVOKE GetDC,hWnd
MOV hDC,eax
.IF (!eax)
INVOKE KillGLWindow
INVOKE MessageBox,0,ADDR error_06,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
XOR eax,eax
ret
.ENDIF
INVOKE ChoosePixelFormat,hDC, ADDR pfd
MOV PixelFormat,eax
.IF (!eax)
INVOKE KillGLWindow
INVOKE MessageBox,0,ADDR error_07,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
XOR eax,eax
ret
.ENDIF
INVOKE SetPixelFormat,hDC,PixelFormat, ADDR pfd
.IF (!eax)
INVOKE KillGLWindow
INVOKE MessageBox,0,ADDR error_08,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
XOR eax,eax
ret
.ENDIF
INVOKE wglCreateContext,hDC
MOV hRC,eax
.IF (!eax)
INVOKE KillGLWindow
INVOKE MessageBox,0,ADDR error_09,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
XOR eax,eax
ret
.ENDIF
INVOKE wglMakeCurrent,hDC,hRC
.IF (!eax)
INVOKE KillGLWindow
INVOKE MessageBox,0,ADDR error_10,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
XOR eax,eax
ret
.ENDIF
INVOKE ShowWindow,hWnd,SW_SHOW
INVOKE SetForegroundWindow,hWnd ; Met le thread qui a créé la fenêtre indiquée dans le premier plan et active la fenêtre
INVOKE SetFocus,hWnd ; Place le focus de clavier à la fenêtre
INVOKE ReSizeGLScene,w,h
INVOKE InitGL
.IF (!eax)
INVOKE KillGLWindow
INVOKE MessageBox,0,ADDR error_11,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
XOR eax,eax
ret
.ENDIF
MOV eax,1
ret
CreateGLWindow endp
ReSizeGLScene PROC w: DWORD,
h: DWORD
LOCAL ratio: GLdouble
.IF h == 0
inc h ; prevenir d'un division par zero
.ENDIF
INVOKE glViewport,0,0,w,h ; reset viewport
INVOKE glMatrixMode,GL_PROJECTION ; Choisie la matrice de projection
INVOKE glLoadIdentity ; Remise a zero de la matrice de projection
FILD w
FILD h
fDIVp st(1),st(0)
FSTP ratio
_gluPerspective 45.0f,ratio,0.1f,500.0f ; Choisie le mode de perspective
INVOKE glMatrixMode,GL_MODELVIEW ; Choisie la matrice de projection
INVOKE glLoadIdentity ; Remise a zero de la matrice de projection
ret
ReSizeGLScene endp
KillGLWindow PROC
.IF fullscreen
INVOKE ChangeDisplaySettings,NULL,0 ; retourne en mode graphique normal
INVOKE ShowCursor,TRUE ; active la vue du curseur
.ENDIF
.IF hRC
INVOKE wglMakeCurrent,NULL,NULL
INVOKE wglDeleteContext,hRC
MOV hRC,NULL
.ENDIF
.IF hDC
INVOKE ReleaseDC,hWnd,hDC
.if (!eax)
;INVOKE MessageBox,0,ADDR error_12,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
.endif
MOV hDC,NULL
.ENDIF
.IF hWnd
INVOKE DestroyWindow,hWnd
.if (!eax)
;INVOKE MessageBox,0,ADDR error_13,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
.endif
MOV hWnd,NULL
.ENDIF
INVOKE UnregisterClass,addr ClassName,hInstance
.if (!eax)
;INVOKE MessageBox,0,ADDR error_14,ADDR error_00,MB_OK or MB_ICONEXCLAMATION
.endif
MOV hInstance,NULL
INVOKE KillFont
KillGLWindow endp
DrawGLScene PROC
LOCAL x_temp: REAL4,
y_temp: REAL4,
z_temp: REAL4
inc Fps_Count
invoke glPushMatrix ; Stock la matrice de projection
invoke glClear,GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT ; efface l'ecran
INVOKE glLoadIdentity ; Remise a zero de la matrice de projection
FLD X_Pos ; x_temp=-X_Pos
fchs
FSTP x_temp
FLD Z_Pos ; z_temp=-Z_Pos
fchs
FSTP z_temp
FLD Y_Rot ; y_temp=-Y_Pos
fchs
FSTP y_temp
finit
_glRotatef Look_Up_Down,1.0f,0.0f,0.0f ; rotation haut-bas
_glRotatef y_temp,0.0f,1.0f,0.0f ; rotation gauche-droite
_glTranslatef x_temp,0,z_temp ; deplacement en x,y,z
invoke glPushMatrix ; Stock la matrice de projection
_glRotatef Sky_Rotation,0.0f,1.0f,0.0f ; Rotation du cile superieur
invoke glCallList,Sky2 ; Dessin le ciel superieur (rotation)
invoke glPopMatrix ; Restore l'ancienne matrice de projection
invoke glCallList,Sky1 ; Dessine le ciel inferieur (fixe)
invoke glCallList,Room ; Dessine la piece
invoke glCallList,Objects ; Dessine les objets
invoke glPopMatrix ; Restore l'ancienne matrice de projection
invoke glPushMatrix ; Stock la matrice de projection
_glTranslatef 0.45f,0.31f,-1.0f
_glRotatef Y_Rot,0.0f,0.0f,1.0f ; Rotation de la boussole
invoke glCallList,Boussole ; dessine la Boussole
invoke glPopMatrix ; Restore l'ancienne matrice de projection
INVOKE glEnable,GL_BLEND ; Activation du blending
.IF Fps_Active ; doit-on afficher les fps ?
INVOKE GLPrint,0,460, ADDr Fps_,0
.ENDIF
.IF Loop_Active ; doit-on afficher les loops ?
INVOKE GLPrint,0,440, ADDr Loop_,0
.ENDIF
INVOKE glDisable,GL_BLEND ; Desactivation du blending
fld Angle_360 ; if Sky_Rotation>360 then Sky_Rotation=Sky_Rotation-360
fld Sky_Rotation
fcom
fstsw ax
fwait
sahf
jb @f
fsub
@@:
fadd Speed_Sky_Rot ; Sky_Rotation=Sky_Rotation+Speed_Sky_Rot
fst Sky_Rotation
finit
MOV eax,1
ret
DrawGLScene endp
LoadGLTexture PROC
LOCAL File_Handle: DWORD,
File_Size : DWORD,
Buffer_Data: DWORD,
Bytes_Read: DWORD,
Pointer: DWORD,
info: BITMAP,
Bmp_Handle: DWORD,
N_Texture: DWORD
push edi
push esi
mov N_Texture,0
invoke CreateFile, ADDR Texture_File, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0
.IF (eax == INVALID_HANDLE_VALUE)
invoke MessageBox, 0, ADDR error_15, ADDR error_00, MB_OK or MB_ICONEXCLAMATION
xor eax, eax
pop esi
pop edi
ret
.ENDIF
mov File_Handle, eax
invoke GetFileSize, eax, 0
inc eax
mov File_Size , eax
invoke GlobalAlloc, GPTR, File_Size
mov Buffer_Data, eax
dec File_Size
invoke ReadFile, File_Handle, Buffer_Data, File_Size , ADDR Bytes_Read, 0
invoke CloseHandle, File_Handle
push Buffer_Data
pop Pointer
push Pointer
xor ecx, ecx
; on compte le nombre de textures
.while (!ecx)
invoke ReadALine, Pointer, ADDR Buffer
add Pointer, ecx
mov eax, offset Buffer
.IF (BYTE PTR [eax] == 'E')&&(BYTE PTR [eax+1] == 'N')&&(BYTE PTR [eax+2] == 'D')
mov ecx,1
.ELSE
inc N_Texture
xor ecx,ecx
.ENDIF
.endw
invoke glGenTextures,N_Texture,addr texture
mov N_Texture,0
pop Pointer
xor ecx, ecx
.while (!ecx)
invoke ReadALine, Pointer, ADDR Buffer
add Pointer, ecx
mov eax, offset Buffer
.IF (BYTE PTR [eax] == 'E')&&(BYTE PTR [eax+1] == 'N')&&(BYTE PTR [eax+2] == 'D')
mov ecx,1
.ELSE
invoke LoadImage,NULL,ADDR Buffer,IMAGE_BITMAP,0,0,LR_LOADFROMFILE or LR_CREATEDIBSECTION
.if !eax
invoke MessageBox, 0, ADDR Buffer, ADDR error_00, MB_OK or MB_ICONEXCLAMATION
ret
.endif
mov Bmp_Handle,eax
lea edi,Bmp_Handle
mov ebx,N_Texture
invoke glBindTexture,GL_TEXTURE_2D,texture[ebx]
invoke glTexParameteri,GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR
invoke glTexParameteri,GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR
invoke GetObject,[edi],sizeof info,addr info
invoke glTexImage2D,GL_TEXTURE_2D,0,3,info.bmWidth,info.bmHeight,0,GL_BGR_EXT,GL_UNSIGNED_BYTE,info.bmBits
invoke DeleteObject,Bmp_Handle
inc N_Texture
xor ecx,ecx
.ENDIF
.endw
invoke GlobalFree, Buffer_Data
pop esi
pop edi
mov eax,1
ret
LoadGLTexture ENDP
ReadALine PROC pSource:DWORD,
pDest: DWORD
LOCAL cpy: BYTE
push esi
push edi
mov esi, 40000
mov cpy, 1
mov eax, pSource
mov edx, pDest
xor ecx, ecx
.WHILE (BYTE PTR [eax+ecx] != 13)
.IF (BYTE PTR [eax+ecx] == '#')
mov cpy, 0
.IF esi == 40000
mov esi, ecx
.ENDIF
.ENDIF
.IF (cpy)
mov bl, BYTE PTR [eax+ecx]
mov BYTE PTR [edx+ecx], bl
.ENDIF
inc ecx
.ENDW
mov BYTE PTR [edx+ecx], 0
mov eax, ecx
inc ecx
inc ecx
.IF esi == 0
xor eax, eax
.ENDIF
pop edi
pop esi
ret
ReadALine endp
END start
Conclusion :
Je me suis beaucoup inspirer du site de Nehe
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.