#include "fbgfx.bi" #include once "MyTDT\OpenGL.bas" #define _TrashLock( _P... ) _P #define _WrapSync( _P... ) 'will hang because of other mutexes #define __DebugThrash( _P... ) _P #define __DebugThrashLock( _P... ) #define __DebugThrashDraw( _P... ) '_P #define __DebugThrashState( _P... ) #define __DebugThrashTexture( _P... ) '_P #define __DebugThrashPerFrame( _P... ) '_P #include once "gl\gl.bi" #include once "gl\glext.bi" extern "windows-ms" type u32 as ulong : type s32 as long type f32 as single : type f64 as double type f32x2 : as f32 X, Y : end type type f32x3 : as f32 X, Y, Z : end type type f32x4 : as f32 X, Y, Z, W : end type type f64x2 : as f64 X, Y : end type type f64x3 : as f64 X, Y, Z : end type type f64x4 : as f64 X, Y, Z, W : end type type u32x2 : as u32 X, Y : end type type u32x3 : as u32 X, Y, Z : end type type u32x4 : as u32 X, Y, Z, W : end type type RVX 'RTVLX as f32 fX,fY,fZ as f32 fRHW as u32 ucolor , uSpecular as f32 fU,fV end type enum thPixFmt thPIXEL_FORMAT_NONE = 0 thPIXEL_FORMAT_UNKNOWN = 1 thPIXEL_FORMAT_P8 = 2 'used thPIXEL_FORMAT_R5G5B5 = 3 thPIXEL_FORMAT_R5G6B5 = 4 'used thPIXEL_FORMAT_R8G8B8 = 5 thPIXEL_FORMAT_A8R8G8B8 = 6 thPIXEL_FORMAT_R4G4B4 = 7 'used thPIXEL_FORMAT_A4L4 = 8 'used end enum type thDriverInfo Drivername as zstring ptr end type type thLockInfo as any ptr pdata as u32 Stride as s32 format as u32 width as u32 Height as RECT Rect end type type thTexture as any #macro _WroteCmd(_size) g_pWriteCmd += _size if g_pWriteCmd >= g_pCmdBufferLimit then g_pWriteCmd = g_pCmdBuffer _WrapSync( g_bWrap=1 : mutexlock(g_WrapMutex) ) ': printf("+") InterlockedExchangeAdd( @g_iBuffered , _size ) else InterlockedExchangeAdd( @g_iBuffered , _size ) end if if g_iBuffered > (cuint(g_pCmdBufferLimit)-cuint(g_pCmdBuffer)) then puts("Cross Thread Buffer overflow!"): system end if #endmacro #macro _glCmdInt( _cmd , _lock , _data , _size , _parms... ) scope 'printf(">") using ThrashGL _WrapSync( if g_bWrap then g_bWrap=0 : mutexlock(g_WrapMutex):mutexunlock(g_WrapMutex) ) 'if g_TID <> GetCurrentThreadID() then puts("Thrash from wrong thread!") #if _lock _TrashLock( mutexlock(ThrashGL.g_WriteMutex) ) #endif with *cptr( _cmd##Parms ptr , g_pWriteCmd ) .pfCmd = cast(any ptr,@_cmd) : _parms end with #if len(#_data) memcpy( g_pWriteCmd+sizeof(_cmd##Parms) , _data , _size ) #endif _WroteCmd( _size+sizeof(_cmd##Parms) ) #if _lock _TrashLock( mutexunlock(ThrashGL.g_WriteMutex) ) #endif 'printf("<") end scope #endmacro #define glCmd( _cmd , _parms... ) _glCmdInt( _cmd , 1 , , 0 , _parms ) #define glCmdUnlocked( _cmd , _parms... ) _glCmdInt( _cmd , 0 , , 0 , _parms ) namespace ThrashGL static shared as byte g_bInit = 0 , g_bWrap 'static shared as ulong g_TID static shared as long g_iPage = 0 , g_iBuffered static shared as any ptr g_pSyncMutex , g_WriteMutex , g_pTexMutex , g_WrapMutex static shared as any ptr g_pCmdBuffer , g_pCmdBufferLimit , g_pReadCmd , g_pWriteCmd const cMaxTextures = 255 type Texture pOrgTex as thTexture ptr as any ptr pTexData as ulong lTex as short wWid,wHei as byte bFmt end type static shared as Texture g_tTex(cMaxTextures) = any static shared as long g_iTexCount=0 #define _parms( _n ) end type : type _n##Parms extends mtHeader type mtHeader pfCmd as function stdcall ( as any ptr ) as long _parms(mtScreenres) : as long lWid,lHei _parms(mtGenTexture) : as long lTex _parms(mtTexImage) : as Texture ptr pTex : as u32 ptr pPix,pPal _parms(mtBindTexture) : as Texture ptr pTex _parms(mtClearTextures) : as long lTexCnt _parms(mtFlip ) : as any ptr pSyncMutex _parms(mtClearWindow) : as byte bFullClear _parms(mtWritePixels) : as any ptr pSyncMutex,pData : as long lX,lY,lWid,lHei,lBpp,lPitch _parms(mtDrawLine ) : as RVX a,b _parms(mtDrawTri ) : as RVX a,b,c _parms(mtDrawQuad ) : as RVX a,b,c,d end type #define _X( _fX ) ((_fX)*w) #define _Y( _fY ) ((_fY)*w) #define _Z( _fZ ) ((((_fZ)*2)-1)*w) #define _Color( _Var ) uCor = lCor(_Var.uColor) : glColor4ubv( cast(any ptr,@uCor) ) #define _Vtx( _Var ) w = 1/_Var.frhw : glTexCoord2f( _Var.fU , _Var.fV ): glVertex4f( _X(_Var.fX) , _Y(_Var.fY) , _Z(_Var.fZ) , w ) private function lCor( lCorIn as u32 ) as u32 return (lCorIn and &hFF00FF00) or ((lCorIn and &h0000FF) shl 16) or ((lCorIn and &hFF0000) shr 16) end function private function GetTexFmt( bFormat as long , byref lIntFmt as long , byref lFmt as long , byref lPacking as long ) as long lIntFmt=0 : lFmt=0 : lPacking=0 select case bFormat case thPIXEL_FORMAT_P8 'used lIntFmt = GL_RGB : lFmt = GL_RGBA : lPacking = GL_UNSIGNED_BYTE case -1 'thPIXEL_FORMAT_R5G5B5 case thPIXEL_FORMAT_R5G6B5 'used lIntFmt = GL_RGB : lFmt = GL_RGB : lPacking = GL_UNSIGNED_SHORT_5_6_5 case -1 'thPIXEL_FORMAT_R8G8B8 lIntFmt = GL_RGB : lFmt = GL_RGB : lPacking = GL_UNSIGNED_BYTE case -1 'thPIXEL_FORMAT_A8R8G8B8 lIntFmt = GL_RGBA : lFmt = GL_RGBA : lPacking = GL_UNSIGNED_BYTE case thPIXEL_FORMAT_R4G4B4 'used lIntFmt = GL_RGBA4 : lFmt = GL_RGBA : lPacking = GL_UNSIGNED_SHORT_4_4_4_4 case thPIXEL_FORMAT_A4L4 'used lIntFmt = GL_LUMINANCE4_ALPHA4 : lFmt = GL_LUMINANCE_ALPHA : lPacking = GL_UNSIGNED_BYTE case else puts("Unsupported texture format") end select return bFormat end function private function mtScreenres( pParms as mtScreenresParms ptr ) as long with *pParms screenres .lWid,.lHei,32,,fb.GFX_OPENGL glMatrixMode(GL_PROJECTION) glLoadIdentity() '// Standard OpenGL: 0 is at the bottom, ScreenHeight is at the top glOrtho(0.0f, .lWid, 0.0f, .lHei, -1.0f, 1.0f) glMatrixMode(GL_MODELVIEW) glLoadIdentity() '// flip the rendering upside down and shift it into view glScalef(1.0f, -1.0f, 1.0f) glTranslatef(0.0f, -.lHei, 0.0f) glEnable( GL_TEXTURE ) glEnable( GL_BLEND ) 'glEnable( GL_DEPTH_TEST ) 'glEnable(GL_CULL_FACE) 'glFrontFace(GL_CW) 'inverted because of the negative scale glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 'glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ) 'glPolygonMode( GL_BACK, GL_LINE ) 'screenres 640,480,16,3 : g_iPage=0 : screenset g_iPage,g_iPage xor 1 screencontrol fb.SET_WINDOW_POS,680,0 end with return sizeof(*pParms) end function private function mtGenTexture( pParms as mtGenTextureParms ptr ) as long mutexlock( ThrashGL.g_pTexMutex ) var lTexIDX = pParms->lTex with g_tTex(lTexIDX) glGenTextures(1, @.lTex) glBindTexture(GL_TEXTURE_2D, .lTex) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP) dim as long lInt=any , lFmt=any , lPack=any : GetTexFmt( .bFmt,lInt,lFmt,lPack ) glTexImage2D(GL_TEXTURE_2D,0,lInt,.wWid,.wHei,0,lFmt,lPack,0) if glGetError() then printf(!"Failed to create texture of type %i\n",.bFmt)':getchar() end with mutexunlock( g_pTexMutex ) return sizeof(*pParms) end function private function mtTexImage( pParms as mtTexImageParms ptr ) as long mutexlock( g_pTexMutex ) with *(pParms->pTex) glBindTexture(GL_TEXTURE_2D, .lTex) dim as any ptr pData = pParms->pPix dim as any ptr pTemp = 0 dim as long lInt=any , lFmt=any , lPack=any select case GetTexFmt( .bFmt,lInt,lFmt,lPack ) case thPIXEL_FORMAT_P8 = 2 'used var lPixels = clng(.wWid)*.wHei , pPal = pParms->pPal if pData then if .pTexData = 0 then .pTexData = malloc(lPixels*5) memcpy( .pTexData , pData , lPixels ) end if pData = .pTexData+lPixels dim as const ubyte ptr pIn = .pTexData dim as ubyte ptr pOut = pData for iN as long = 0 to lPixels-1 *pOut = pPal[*pIn] : pIn += 1 : pOut += 1 next case thPIXEL_FORMAT_R5G6B5 = 4 'used case thPIXEL_FORMAT_R4G4B4 = 7 'used case thPIXEL_FORMAT_A4L4 = 8 'used var lPixels = clng(.wWid)*.wHei pTemp = malloc(lPixels) dim as ubyte ptr pIn = pData , pOut = pTemp for iN as long = 0 to (lPixels\2)-1 pOut[0] = *pIn shl 4 pOut[1] = *pIn and &hF0 pIn += 1 : pOut += 2 next end select glTexImage2D(GL_TEXTURE_2D,0,lInt,.wWid,.wHei,0,lFmt,lPack,pData) if glGetError() then puts("Failed to setup texture") if pTemp then free(pTemp) end with mutexunlock( g_pTexMutex ) mutexunlock( ThrashGL.g_pSyncMutex ) return sizeof(*pParms) end function private function mtBindTexture( pParms as mtBindTextureParms ptr ) as long with *pParms var lTex = iif(.pTex,.pTex->lTex,0) glBindTexture(GL_TEXTURE_2D, lTex) end with return sizeof(*pParms) end function private function mtClearTextures( pParms as mtClearTexturesParms ptr ) as long mutexlock( g_pTexMutex ) with *pParms for N as long = 0 to .lTexCnt-1 with g_tTex( N ) glDeleteTextures( 1 , @.lTex ) : .lTex = 0 if .pTexData then free(.pTexData):.pTexData=0 .pOrgTex = 0 : .wWid=0 : .wHei=0 : .bFmt = 0 end with next end with g_iTexCount = 0 mutexunlock( g_pTexMutex ) mutexunlock( g_pSyncMutex ) return sizeof(*pParms) end function private function mtFlip( pParms as mtFlipParms ptr ) as long with *pParms flip mutexunlock( .pSyncMutex ) end with return sizeof(*pParms) end function private function mtClearWindow( pParms as mtClearWindowParms ptr ) as long glClear( iif(pParms->bFullClear,GL_COLOR_BUFFER_BIT,0) or GL_DEPTH_BUFFER_BIT ) return sizeof(*pParms) end function private function mtWritePixels( pParms as mtWritePixelsParms ptr ) as long with *pParms var pImage = iif(.pData,.pData,cast(any ptr,pParms+1)) glRasterPos2i( .lX, .lY ) : glPixelZoom(1, -1) glDrawPixels( .lWid , .lHei , GL_RGB , GL_UNSIGNED_SHORT_5_6_5 , pImage ) if .pSyncMutex then mutexunlock( .pSyncMutex ) return sizeof(*pParms)+iif(.pData,0,.lHei*.lPitch) end with end function private function mtDrawLine( pParms as mtDrawLineParms ptr ) as long dim uCor as ulong = any , w as single = any with *pParms glBegin( GL_LINES ) _Color( .a ) : _Vtx( .a ) _Color( .b ) : _Vtx( .b ) glEnd() end with return sizeof(*pParms) end function private function mtDrawTri( pParms as mtDrawTriParms ptr ) as long dim uCor as ulong = any , w as single = any with *pParms glBegin( GL_TRIANGLES ) _Color( .a ) : _Vtx( .a ) _Color( .b ) : _Vtx( .b ) _Color( .c ) : _Vtx( .c ) glEnd() end with return sizeof(*pParms) end function private function mtDrawQuad( pParms as mtDrawQuadParms ptr ) as long dim uCor as ulong = any , w as single = any with *pParms glBegin( GL_QUADS ) _Color( .a ) : _Vtx( .a ) _Color( .b ) : _Vtx( .b ) _Color( .c ) : _Vtx( .c ) _Color( .d ) : _Vtx( .d ) glEnd() end with return sizeof(*pParms) end function private sub ThrashThread( dummy as any ptr ) 'StartExceptions() dim fnCmd as function stdcall ( pParms as any ptr ) as long SetThreadPriority( GetCurrentThread() , THREAD_PRIORITY_TIME_CRITICAL ) do while g_iBuffered = 0 sleep 1,1 'static as zstring*8 pzTmp = "|/-\" 'static as double dStart : if dStart=0 then dStart=timer 'static as long iPos : iPos = clng((timer-dStart)*8) and 3 'printf(!"%c\8",pzTmp[iPos]) : sleep 1,1 wend fnCmd = *cptr(any ptr ptr,g_pReadCmd) var iSz = fnCmd( g_pReadCmd ) g_pReadCmd += iSz : InterlockedExchangeAdd( @g_iBuffered , -iSz ) if g_pReadCmd >= g_pCmdBufferLimit then 'printf("-") _WrapSync(mutexunlock(g_WrapMutex)) g_pReadCmd = g_pCmdBuffer end if loop end sub end namespace static shared pfTHRASH_about as function() as thDriverInfo ptr function THRASH_about() as thDriverInfo ptr __DebugThrash( puts(__FUNCTION__) ) return pfTHRASH_about() end function static shared pfTHRASH_is as function() as u32 function THRASH_is() as u32 __DebugThrash( puts(__FUNCTION__) ) return pfTHRASH_is() end function static shared pfTHRASH_init as function() as u32 function THRASH_init() as u32 __DebugThrash( puts(__FUNCTION__) ) var uResu = pfTHRASH_init() using ThrashGL if g_pSyncMutex=0 then 'g_TID = GetCurrentThreadID() g_pSyncMutex = mutexcreate() g_pTexMutex = mutexcreate() _TrashLock( g_WriteMutex = mutexcreate() ) _WrapSync( g_WrapMutex = mutexcreate() ) g_pCmdBuffer = malloc(1024*1024) g_pCmdBufferLimit = g_pCmdBuffer+256*1024 end if threadcreate( @ThrashThread , 0 ) g_pReadCmd = g_pCmdBuffer : g_pWriteCmd = g_pCmdBuffer mutexlock( g_pTexMutex ) dim as Texture tBlank for N as long = 0 to cMaxTextures g_tTex(N) = tBlank next N g_iTexCount = 0 mutexunlock( g_pTexMutex ) return uResu end function static shared pfTHRASH_setvideomode as function(mode as const u32, pending as const u32, depth as const u32) as u32 function THRASH_setvideomode(mode as const u32, pending as const u32, depth as const u32) as u32 var resu = pfTHRASH_setvideomode(mode,pending,depth) __DebugThrash( printf(!"THRASH_setvideomode(mode=%i pending=%i depth=%i)=%i\n",mode,pending,depth,resu) ) if ThrashGL.g_bInit = 0 then ThrashGL.g_bInit = 1 : glCmd( mtScreenres , .lWid=640 : .lHei=480 ) end if return resu end function static shared pfTHRASH_lockwindow as function() as thLockInfo ptr function THRASH_lockwindow() as thLockInfo ptr __DebugThrashLock( puts(__FUNCTION__) ) 'screenlock return pfTHRASH_lockwindow() end function static shared pfTHRASH_unlockwindow as function(pInfo as thLockInfo ptr) as u32 function THRASH_unlockwindow(pInfo as thLockInfo ptr) as u32 mutexlock( ThrashGL.g_pSyncMutex ) _TrashLock( mutexlock(ThrashGL.g_WriteMutex) ) #define _sz pInfo->Height*pInfo->Stride #if 0 'offload _glCmdInt( mtWritePixels , 0 , pInfo->pData , _sz , _ : .lX=0:.lY=0 : .pData=0 : .pSyncMutex=0 _ : .lWid=pInfo->width : .lHei=pInfo->height _ : .lBpp=16 : .lPitch=pInfo->Stride _ ) #else 'sync _glCmdInt( mtWritePixels , 0 , , 0 , _ : .lX=0:.lY=0 : .pData=pInfo->pData : .pSyncMutex=0 _ : .lWid=pInfo->width : .lHei=pInfo->height _ : .lBpp=16 : .lPitch=pInfo->Stride _ ) #endif _TrashLock( mutexunlock(ThrashGL.g_WriteMutex) ) glCmd( mtFlip , .pSyncMutex = ThrashGL.g_pSyncMutex ) mutexlock( ThrashGL.g_pSyncMutex ) : mutexunlock( ThrashGL.g_pSyncMutex ) __DebugThrashLock( puts(__FUNCTION__) ) #if 0 with *pInfo var pScr = screenptr, pIn = .pData for Y as long = 0 to .Height-1 memcpy( pScr , pIn , .width*2 ) pIn += .Stride : pScr += .width*2 next Y screenunlock end with #endif var uResu = pfTHRASH_unlockwindow(pInfo) 'mutexlock( ThrashGL.g_pSyncMutex ) : mutexunlock( ThrashGL.g_pSyncMutex ) return uResu end function static shared pfTHRASH_sync as function(dummy as const u32) as u32 function THRASH_sync(dummy as const u32) as u32 __DebugThrash( puts(__FUNCTION__) ) return pfTHRASH_sync(dummy) end function static shared pfTHRASH_clip as function(x as const u32,y as const u32,xx as const u32,yy as const u32) as u32 function THRASH_clip(x as const u32,y as const u32,xx as const u32,yy as const u32) as u32 __DebugThrash( puts(__FUNCTION__) ) return pfTHRASH_clip(x,y,xx,yy) end function static shared pfTHRASH_treset as function() as u32 function THRASH_treset() as u32 __DebugThrash( puts(__FUNCTION__) ) mutexlock( ThrashGL.g_pSyncMutex ) glCmd( mtClearTextures , .lTexCnt = ThrashGL.g_iTexCount ) ThrashGL.g_iTexCount = 0 mutexlock( ThrashGL.g_pSyncMutex ): mutexunlock( ThrashGL.g_pSyncMutex ) return pfTHRASH_treset() end function static shared pfTHRASH_readrect as function(x as const u32,y as const u32,wid as const u32,hei as const u32,pixels as u32 ptr) as u32 function THRASH_readrect(x as const u32,y as const u32,wid as const u32,hei as const u32,pixels as u32 ptr) as u32 __DebugThrash( puts(__FUNCTION__) ) return pfTHRASH_readrect(x,y,wid,hei,pixels) end function static shared pfTHRASH_restore as function() as u32 function THRASH_restore() as u32 __DebugThrash( puts(__FUNCTION__) ) return pfTHRASH_restore() end function static shared pfTHRASH_window as function(idx as const u32) as u32 function THRASH_window(idx as const u32) as u32 var resu = pfTHRASH_window(idx) __DebugThrashLock( printf(!"THRASH_window(idx=%i)=%i\n",idx,resu) ) 'screenset idx : g_iPage=idx return resu end function static shared pfTHRASH_clearwindow as function() as u32 function THRASH_clearwindow() as u32 __DebugThrashPerFrame( puts(__FUNCTION__) ) glCmd( mtClearWindow , .bFullClear=true ) return pfTHRASH_clearwindow() end function static shared pfTHRASH_flushwindow as function() as u32 function THRASH_flushwindow() as u32 __DebugThrashPerFrame( puts(__FUNCTION__) ) 'glFlush() return pfTHRASH_flushwindow() end function static shared pfTHRASH_pageflip as sub() sub THRASH_pageflip() __DebugThrashPerFrame( puts(__FUNCTION__) ) 'g_iPage xor= 1 : screenset g_iPage,g_iPage xor 1 mutexlock( ThrashGL.g_pSyncMutex ) glCmd( mtFlip , .pSyncMutex = ThrashGL.g_pSyncMutex ) pfTHRASH_pageflip() mutexlock( ThrashGL.g_pSyncMutex ) : mutexunlock( ThrashGL.g_pSyncMutex ) end sub static shared pfTHRASH_talloc as function(wid as const u32,hei as const u32,fmt as const u32,pal as const WINBOOL,state as const u32) as thTexture ptr function THRASH_talloc(wid as const u32,hei as const u32,fmt as const u32,pal as const WINBOOL,state as const u32) as thTexture ptr __DebugThrashTexture( puts(__FUNCTION__) ) var pTex = pfTHRASH_talloc(wid,hei,fmt,pal,state) mutexlock( ThrashGL.g_pTexMutex ) with ThrashGL.g_tTex(ThrashGL.g_iTexCount) .pOrgTex = pTex : .pTexData = 0 : .wWid = wid : .wHei = hei : .bFmt = fmt end with glCmd( mtGenTexture , .lTex = g_iTexCount ) function = cptr(thTexture ptr , @ThrashGL.g_tTex(ThrashGL.g_iTexCount) ) ThrashGL.g_iTexCount += 1 mutexunlock( ThrashGL.g_pTexMutex ) select case fmt case 2,4,7,8 case else printf(!"new fmt: %i \n",fmt) getchar() end select end function static shared pfTHRASH_tupdate as function(tex as thTexture ptr, pixels as const u32 ptr, pal as const u32 ptr) as thTexture ptr function THRASH_tupdate(tex as thTexture ptr, pixels as const u32 ptr, pal as const u32 ptr) as thTexture ptr __DebugThrashTexture( puts(__FUNCTION__) ) 'if pal=0 then puts("update without palette :D") while ThrashGL.g_iBuffered > ((cuint(ThrashGL.g_pCmdBufferLimit)-cuint(ThrashGL.g_pCmdBuffer))\2) sleep 1,1 wend dim as any ptr pTex = 0 if pixels then mutexlock( ThrashGL.g_pSyncMutex ) mutexlock( ThrashGL.g_pTexMutex ) if tex then glCmd( mtTexImage , .pTex = cast(any ptr,tex) : .pPix = cast(any ptr,pixels) : .pPal = cast(any ptr,pal) ) pTex = cptr( ThrashGL.Texture ptr , tex )->pOrgTex end if mutexunlock( ThrashGL.g_pTexMutex ) mutexlock( ThrashGL.g_pSyncMutex ) : mutexunlock( ThrashGL.g_pSyncMutex ) elseif tex then pTex = cptr( ThrashGL.Texture ptr , tex )->pOrgTex end if return pfTHRASH_tupdate(pTex,pixels,pal) end function static shared pfTHRASH_setstate as function(state as const u32, value as any ptr) as u32 function THRASH_setstate(state as const u32, value as any ptr) as u32 __DebugThrashState( puts(__FUNCTION__) ) return pfTHRASH_setstate(state,value) end function static shared pfTHRASH_settexture as function(tex as thTexture ptr) as u32 function THRASH_settexture(tex as thTexture ptr) as u32 __DebugThrashState( puts(__FUNCTION__) ) glCmd( mtBindTexture , .pTex = cast(any ptr,tex) ) var pTex = iif( tex , cptr( ThrashGL.Texture ptr , tex )->pOrgTex , 0 ) return pfTHRASH_settexture(pTex) end function static shared pfTHRASH_drawline as sub(a as RVX ptr, b as RVX ptr) sub THRASH_drawline(a as RVX ptr, b as RVX ptr) __DebugThrashDraw( puts(__FUNCTION__) ) glCmd( mtDrawLine , .a = *a : .b = *b ) 'line (a->fX,a->fY)-(b->fX,b->fY),lcor(a->uColor) pfTHRASH_drawline(a,b) end sub static shared pfTHRASH_drawtri as sub(a as RVX ptr, b as RVX ptr, c as RVX ptr) sub THRASH_drawtri(a as RVX ptr, b as RVX ptr, c as RVX ptr) __DebugThrashDraw( puts(__FUNCTION__) ) 'with *a '__DebugThrash( printf(!"drawtri: %f,%f,%f %f %4X %f,%f\n",.fX,.fY,.fZ,.fRHW,.uColor,.fU,.fV) ) 'getchar() 'end with glCmd( mtDrawTri , .a=*a : .b=*b : .c=*c ) 'line (a->fX,a->fY)-(b->fX,b->fY),lcor(a->uColor) 'line -(c->fX,c->fY),lcor(b->uColor) 'line -(a->fX,a->fY),lcor(c->uColor) pfTHRASH_drawtri(a,b,c) end sub static shared pfTHRASH_drawquad as sub(a as RVX ptr, b as RVX ptr, c as RVX ptr, d as RVX ptr) sub THRASH_drawquad(a as RVX ptr, b as RVX ptr, c as RVX ptr, d as RVX ptr) __DebugThrashDraw( puts(__FUNCTION__) ) glCmd( mtDrawQuad , .a=*a : .b=*b : .c=*c : .d=*d ) 'line (a->fX,a->fY)-(b->fX,b->fY),lcor(a->uColor) 'line -(c->fX,c->fY),lcor(b->uColor) 'line -(d->fX,d->fY),lcor(c->uColor) 'line -(a->fX,a->fY),lcor(d->uColor) pfTHRASH_drawquad(a,b,c,d) end sub static shared pfTHRASH_drawtrimesh as sub(count as const u32,verts as RVX ptr, idx as u32 ptr) sub THRASH_drawtrimesh(count as const u32,verts as RVX ptr, idx as u32 ptr) __DebugThrashDraw( puts(__FUNCTION__) ) _TrashLock( mutexlock(ThrashGL.g_WriteMutex) ) 'if ThrashGL.g_TID <> GetCurrentThreadID() then puts("Thrash from wrong thread!") for I as long = 0 to count*3-1 step 3 glCmdUnlocked( mtDrawTri , .a=verts[idx[I+0]] : .b=verts[idx[I+1]] : .c=verts[idx[I+2]] ) next _TrashLock( mutexunlock(ThrashGL.g_WriteMutex) ) #if 0 for I as long = 0 to count*3-1 step 3 line ( verts[idx[I ]].fX , verts[idx[I ]].fY )-( verts[idx[I+1]].fX , verts[idx[I+1]].fY ), lcor(verts[idx[I]].uColor) line -( verts[idx[I+2]].fX , verts[idx[I+2]].fY ), lcor(verts[idx[I+1]].uColor) line -( verts[idx[I ]].fX , verts[idx[I ]].fY ), lcor(verts[idx[I+2]].uColor) next I #endif 'printf( !"drawtrimesh: count: %i\n" , count) 'with verts[0] ' __DebugThrash( printf(!"trimesh[0]: %f,%f,%f %f %4X %f,%f\n",.fX,.fY,.fZ,.fRHW,.uColor,.fU,.fV) ) 'end with 'with verts[1] ' __DebugThrash( printf(!"trimesh[1]: %f,%f,%f %f %4X %f,%f\n",.fX,.fY,.fZ,.fRHW,.uColor,.fU,.fV) ) 'end with 'with verts[2] ' __DebugThrash( printf(!"trimesh[1]: %f,%f,%f %f %4X %f,%f\n",.fX,.fY,.fZ,.fRHW,.uColor,.fU,.fV) ) 'end with 'getchar() pfTHRASH_drawtrimesh(count,verts,idx) end sub end extern