Author Topic: [OpenGL] Restore and Save Depth Buffer and Color Buffer to a file  (Read 2867 times)

Farabi

  • Member
  • ****
  • Posts: 970
  • Neuroscience Fans
Code: [Select]
GL_KTX_FRONT_REGION equ 0
GL_KTX_BACK_REGION equ 1
GL_KTX_Z_REGION equ 2
GL_KTX_STENCIL_REGION equ 3

fStaticScene struct
nWidth dd 0
nHeight dd 0
nBitDepth dd 0
byte_used dd 0
lpBmpData dd 0
lpDpthData dd 0
bmpTexID dd 0
dpthTexID dd 0
lpprojmat dd 0
lpmodvmat dd 0
lptextmat dd 0
lprastpos dd 0
flDepthBias dd 0
flDepthScale dd 0
fStaticScene ends

.data
glBufferRegionEnable dd 0
glNewBufferRegion dd 0
glDeleteBufferRegion dd 0
glReadBufferRegion dd 0
glDrawBufferRegion dd 0
.code
fSceneSave proc uses esi edi lpName:dword
LOCAL pmem,byte_needed:dword
LOCAL r:RECT
LOCAL disk_mem,byte_copied:dword
LOCAL buff[256]:dword

invoke mAlloc,sizeof fStaticScene
mov pmem,eax
mov esi,eax

invoke glGetIntegerv,GL_VIEWPORT,addr r

assume esi:ptr fStaticScene
push r.right
pop [esi].nWidth
push r.bottom
pop [esi].nHeight
push 4
pop [esi].nBitDepth

xor edx,edx
mov ecx,r.right
mov eax,r.bottom
mul ecx
shl eax,2
mov byte_needed,eax

push eax
pop [esi].byte_used

invoke mAlloc,byte_needed
push eax
pop [esi].lpBmpData
invoke mAlloc,byte_needed
push eax
pop [esi].lpDpthData

invoke glReadPixels,0,0,[esi].nWidth,[esi].nHeight,GL_DEPTH_COMPONENT,GL_UNSIGNED_INT,[esi].lpDpthData
invoke glReadPixels,0,0,[esi].nWidth,[esi].nHeight,GL_RGBA,GL_UNSIGNED_BYTE,[esi].lpBmpData

mov byte_copied,0
mov eax,[esi].byte_used
shl eax,2
add eax,sizeof fStaticScene
add eax,(16*4)*3 ; The Projection and modelview Matrix
add eax,4*4
invoke mAlloc,eax
mov disk_mem,eax
mov edi,eax

invoke MemCopy,esi,edi,sizeof fStaticScene
mov eax,fStaticScene
add byte_copied,eax
add edi,eax

invoke MemCopy,[esi].lpBmpData,edi,[esi].byte_used
mov eax,[esi].byte_used
add byte_copied,eax
add edi,eax

invoke MemCopy,[esi].lpDpthData,edi,[esi].byte_used
mov eax,[esi].byte_used
add byte_copied,eax
add edi,eax

invoke glGetFloatv,GL_PROJECTION_MATRIX,edi
mov eax,16*4
add byte_copied,eax
add edi,eax
invoke glGetFloatv,GL_MODELVIEW_MATRIX,edi
mov eax,16*4
add byte_copied,eax
add edi,eax
invoke glGetFloatv,GL_TEXTURE_MATRIX,edi
mov eax,16*4
add byte_copied,eax
add edi,eax
invoke glGetIntegerv,GL_CURRENT_RASTER_POSITION,edi
mov eax,4*4
add byte_copied,eax
add edi,eax
invoke glGetFloatv,GL_DEPTH_BIAS,edi
mov eax,4
add byte_copied,eax
add edi,eax
invoke glGetFloatv,GL_DEPTH_SCALE,edi
mov eax,4
add byte_copied,eax
add edi,eax

invoke write_disk_file,lpName,disk_mem,byte_copied



invoke GlobalFree,[esi].lpBmpData
invoke GlobalFree,[esi].lpDpthData

invoke GlobalFree,esi

assume esi:nothing

ret
fSceneSave endp

fSceneLoad proc uses esi edi lpName:dword,lpfStaticScene:dword
LOCAL filesz:dword
LOCAL the_data,bmp_data,depth_data:dword
LOCAL buff[256]:dword
LOCAL q:qword

invoke filesize,lpName
.if eax!=-1
mov filesz,eax
invoke mAlloc,filesz
mov the_data,eax

invoke read_disk_file,lpName,addr the_data,addr filesz

invoke MemCopy,the_data,lpfStaticScene,sizeof fStaticScene
mov edi,the_data
add edi,fStaticScene

mov esi,lpfStaticScene
invoke mAlloc,[esi].fStaticScene.byte_used
mov bmp_data,eax
invoke mAlloc,[esi].fStaticScene.byte_used
mov depth_data,eax

invoke mAlloc,16*4
mov [esi].fStaticScene.lpprojmat,eax
invoke mAlloc,16*4
mov [esi].fStaticScene.lpmodvmat,eax
invoke mAlloc,16*4
mov [esi].fStaticScene.lptextmat,eax
invoke mAlloc,4*4
mov [esi].fStaticScene.lprastpos,eax

invoke MemCopy,edi,bmp_data,[esi].fStaticScene.byte_used
add edi,[esi].fStaticScene.byte_used
invoke MemCopy,edi,depth_data,[esi].fStaticScene.byte_used
add edi,[esi].fStaticScene.byte_used
; Here the Matrix Data stored in Order, Projection-ModelView-Texture
invoke MemCopy,edi,[esi].fStaticScene.lpprojmat,16*4
add edi,16*4
invoke MemCopy,edi,[esi].fStaticScene.lpmodvmat,16*4
add edi,16*4
invoke MemCopy,edi,[esi].fStaticScene.lptextmat,16*4
add edi,16*4
invoke MemCopy,edi,[esi].fStaticScene.lprastpos,4*4
add edi,4*4
invoke MemCopy,edi,addr[esi].fStaticScene.flDepthBias,4
add edi,4
invoke MemCopy,edi,addr[esi].fStaticScene.flDepthScale,4
add edi,4

push bmp_data
pop [esi].fStaticScene.lpBmpData
push depth_data
pop [esi].fStaticScene.lpDpthData

invoke LoadGLTexturev,[esi].fStaticScene.lpBmpData,[esi].fStaticScene.nWidth,[esi].fStaticScene.nHeight
mov [esi].fStaticScene.bmpTexID,eax

invoke GlobalFree,the_data

.else
invoke MessageBox,0,CADD("File not found"),0,0
.endif

ret
fSceneLoad endp

fSceneDraw proc uses esi edi lplpfStaticScene:dword
LOCAL raster:VERTEX
LOCAL lpmem:dword
LOCAL tid:dword
mov esi,lplpfStaticScene

invoke glMatrixMode,GL_PROJECTION
invoke glLoadMatrixf,[esi].fStaticScene.lpprojmat
invoke glMatrixMode,GL_MODELVIEW
invoke glLoadMatrixf,[esi].fStaticScene.lpmodvmat
invoke glMatrixMode,GL_TEXTURE
invoke glLoadMatrixf,[esi].fStaticScene.lptextmat
invoke glMatrixMode,GL_MODELVIEW

invoke glMatrixMode,GL_MODELVIEW
invoke glPushMatrix
invoke glLoadIdentity
invoke glMatrixMode,GL_PROJECTION
invoke glPushMatrix
invoke glLoadIdentity
invoke glClear,GL_STENCIL_BUFFER_BIT
invoke glEnable,GL_STENCIL_TEST
invoke glColorMask,GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE
invoke glStencilFunc,GL_ALWAYS,1,1
invoke glStencilOp,GL_KEEP,GL_KEEP,GL_REPLACE
invoke glEnable,GL_DEPTH_TEST
invoke glDepthFunc,GL_ALWAYS
invoke glRasterPos2i,-1,-1
.if [esi].fStaticScene.dpthTexID==0
invoke glDrawPixels,[esi].fStaticScene.nWidth,[esi].fStaticScene.nHeight,GL_DEPTH_COMPONENT,GL_UNSIGNED_INT,[esi].fStaticScene.lpDpthData
.else
push 0
push 0
push 480
push 640
push 0
push 0
push [esi].fStaticScene.dpthTexID
call glDrawBufferRegion
add esp,7*4
.endif

invoke glStencilFunc,GL_EQUAL,1,1
invoke glStencilOp,GL_KEEP,GL_KEEP,GL_KEEP
invoke glDisable,GL_DEPTH_TEST
invoke glColorMask,GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE
invoke glRasterPos2i,-1,-1
invoke glDepthMask,GL_FALSE
invoke Enter_2D_Mode,FP4(640.),FP4(480.)
invoke Draw2DQuad,FP4(0.),FP4(0.),FP4(-1.),FP4(640.),FP4(480.),[esi].fStaticScene.bmpTexID
invoke Leave_2d_Mode
invoke glDepthMask,GL_TRUE
invoke glMatrixMode,GL_PROJECTION
invoke glPopMatrix
invoke glMatrixMode,GL_MODELVIEW
invoke glPopMatrix


invoke glEnable,GL_DEPTH_TEST
invoke glDepthMask,GL_TRUE
invoke glDepthFunc,GL_LESS


.if [esi].fStaticScene.dpthTexID==0
invoke wglGetProcAddress,CADD("glBufferRegionEnabled")
.if eax==0
invoke MessageBox,0,CADD("Sistem anda tidak memperbolehkan menulis langsung ke Depth Buffer"),0,0
jmp no_need_to_continue
.endif
mov glBufferRegionEnable,eax

invoke wglGetProcAddress,CADD("glNewBufferRegion")
.if eax==0
invoke MessageBox,0,CADD("Sistem anda tidak memperbolehkan menulis langsung ke Depth Buffer"),0,0
jmp no_need_to_continue
.endif
mov glNewBufferRegion,eax
invoke wglGetProcAddress,CADD("glDeleteBufferRegion")
.if eax==0
invoke MessageBox,0,CADD("Sistem anda tidak memperbolehkan menulis langsung ke Depth Buffer"),0,0
jmp no_need_to_continue
.endif
mov glDeleteBufferRegion,eax
invoke wglGetProcAddress,CADD("glReadBufferRegion")
.if eax==0
invoke MessageBox,0,CADD("Sistem anda tidak memperbolehkan menulis langsung ke Depth Buffer"),0,0
jmp no_need_to_continue
.endif
mov glReadBufferRegion,eax
invoke wglGetProcAddress,CADD("glDrawBufferRegion")
.if eax==0
invoke MessageBox,0,CADD("Sistem anda tidak memperbolehkan menulis langsung ke Depth Buffer"),0,0
jmp no_need_to_continue
.endif
mov glDrawBufferRegion,eax

call glBufferRegionEnable
.if eax!=1
invoke MessageBox,0,CADD("Sistem anda tidak memperbolehkan menulis langsung ke Depth Buffer"),0,0
.endif
push GL_KTX_Z_REGION
call glNewBufferRegion
add esp,4
mov [esi].fStaticScene.dpthTexID,eax


push 480
push 640
push 0
push 0
push [esi].fStaticScene.dpthTexID
call glReadBufferRegion
add esp,5*4


.endif
no_need_to_continue:
ret
fSceneDraw endp

This will save or restore your frame buffer to a file. I'll make a demo someday. It can speed up a complex scene very high.
http://farabidatacenter.url.ph/MySoftware/
My 3D Game Engine Demo.

Contact me at Whatsapp: 6283818314165