Not too shy to talk
Joined: 2011/6/3 13:49 Last Login
: Yesterday 21:39
Group:
Registered Users
|
Hello
I have maded some code to try to decode the given YUV example with Warp3D Unfortunately it dont works on my Sam440 as i dont have W3D_SetDrawRegionTexture in my Warp3D.library (perhaps I need an update...)
Need real Warp3D V5 (not OS3 68k) (not Wazp3D) Need to support rectangular textures Need to support I8 format textures Need to have W3D_SetDrawRegionTexture()
Finally I am not sure this code have any utility :-/
Alain Thellier
/* YUV to RGB using Warp3D - Alain Thellier - 2013 */ #define DODEBUG 1
/*==========================================================================*/ #ifdef __amigaos4__ #define OS4 #else #define OS3 #endif /*==================================================================================*/ #ifdef OS4 #define __USE_INLINE__ #define __USE_BASETYPE__ #define __USE_OLD_TIMEVAL__ #pragma pack(2) #endif /*==================================================================================*/ #ifdef DODEBUG #define REM(message) printf(#message"\n"); #else #define REM(message) ; #endif
#include (((stdlib.h> #include (((stdio.h> #include (((strings.h>
#include (((proto/exec.h> #include (((proto/intuition.h> #include (((proto/dos.h> #include (((proto/Warp3D.h> #include (((proto/graphics.h> #include (((graphics/gfx.h> #include (((intuition/intuition.h> #include (((intuition/intuitionbase.h>
/*==================================================================================*/ typedef struct _Point3D { float x,y,z; float color[4]; float u,v,w; } Point3D; /*==================================================================================*/ struct Library *Warp3DBase; W3D_Context *context = NULL; struct Screen *screen; struct Window *window; ULONG OpenErr, CError; ULONG ModeID,flags,ScreenBits; W3D_Texture *tex2 ; W3D_Texture *tex1 ; void *pic1=NULL; void *pic2=NULL; ULONG error; W3D_Scissor scissor1; W3D_Scissor scissor2; WORD winlarge,winhigh; WORD texlarge,texhigh; FILE *fp; float onetexel; Point3D P[18]; Point3D P2[18]; UBYTE *bmdata; #define SWAP(x,y) {temp=x;x=y;y=temp;} float temp; /*==================================================================*/ struct GfxBase* GfxBase =NULL; struct IntuitionBase* IntuitionBase =NULL; struct Library * CyberGfxBase =NULL; struct Library* Warp3DBase =NULL; /*==================================================================*/ #ifdef OS4 struct GraphicsIFace* IGraphics =NULL; struct IntuitionIFace* IIntuition =NULL; struct CyberGfxIFace* ICyberGfx =NULL; struct Warp3DIFace* IWarp3D =NULL; #endif /*==================================================================================*/ float White[4]={1.0 ,1.0 ,1.0 ,1.0 }; /* From YUV to RGB : R = Y + 1.13983*V G = Y + 0.39465*U + 0.58060*V B = Y + 2.03211*U
r = y + 1.402f*v; g = y - (0.344f*u +0.714f*v); b = y +1.772f*u; */ /*==================================================================================*/ float ColorY[4]={1.0 ,1.0 ,1.0 ,0.5 }; float ColorU[4]={0.0 ,-0.344 ,1.772 ,0.5 }; float ColorV[4]={1.402 ,-0.714 ,0.0 ,0.5 }; /*==================================================================================*/ BOOL OpenAmigaLibraries(void) { #define LIBOPEN(libbase,name,version) libbase =(void*)OpenLibrary(#name,(ULONG)version); if(libbase==NULL) return(FALSE); #define LIBOPEN4(interface,libbase) interface=(void*)GetInterface((struct Library *)libbase, "main", 1, NULL); if(interface==NULL) return(FALSE);
LIBOPEN(GfxBase,graphics.library,0) LIBOPEN(IntuitionBase,intuition.library,0) LIBOPEN(CyberGfxBase,cybergraphics.library,0) LIBOPEN(Warp3DBase,Warp3D.library,4)
#ifdef OS4 LIBOPEN(Warp3DBase,Warp3D.library,5) LIBOPEN4(IExec,SysBase)
LIBOPEN4(IGraphics,GfxBase) LIBOPEN4(IIntuition,IntuitionBase) LIBOPEN4(ICyberGfx,CyberGfxBase) LIBOPEN4(IWarp3D,Warp3DBase) #endif
return(TRUE); } /*======================================================================================*/ void CloseAmigaLibraries() { #define LIBCLOSE(libbase) if(libbase !=NULL) { CloseLibrary((struct Library *)libbase ); libbase=NULL; } #define LIBCLOSE4(interface) if(interface!=NULL) { DropInterface((struct Interface*)interface ); interface=NULL; }
#ifdef OS4 LIBCLOSE4(IGraphics) LIBCLOSE4(IIntuition) LIBCLOSE4(ICyberGfx) LIBCLOSE4(IWarp3D) #endif
LIBCLOSE(GfxBase) LIBCLOSE(IntuitionBase) LIBCLOSE(CyberGfxBase) LIBCLOSE(Warp3DBase)
} /*==================================================================================*/ BOOL StartWarp3D(void) { int x,y; void *bmHandle;
if(!OpenAmigaLibraries()) return(FALSE);
screen = LockPubScreen("Workbench") ; x=screen->Width; y=screen->Height;
window = OpenWindowTags(NULL, WA_Activate, TRUE, WA_Width, winlarge, WA_Height, winhigh, WA_Left, x/2-winlarge/2, WA_Top, y/2-winhigh/2, WA_Title, (ULONG)"YUV to RGB - Thellier 2013", WA_DragBar, TRUE, WA_Backdrop, FALSE, WA_GimmeZeroZero, TRUE, WA_Borderless, FALSE, TAG_DONE);
if (window==NULL) {printf("Unable to open window\n");return FALSE; }
context = W3D_CreateContextTags(&CError, W3D_CC_BITMAP,(ULONG)window->RPort->BitMap, W3D_CC_YOFFSET,0, W3D_CC_DRIVERTYPE,W3D_DRIVER_BEST, W3D_CC_DOUBLEHEIGHT,FALSE, //DoubleHeightON, W3D_CC_FAST,TRUE, TAG_DONE);
if(CError==W3D_SUCCESS){printf("create Warp3D context success!\n");}; if(CError==W3D_ILLEGALINPUT){printf("Illigal input!\n");}; if(CError==W3D_NOMEMORY){printf("no memory\n");}; if(CError==W3D_NODRIVER){printf("no driver\n");}; if(CError==W3D_UNSUPPORTEDFMT){printf("usupportedfmt\n");}; if(CError==W3D_ILLEGALBITMAP){printf("illegal bitmap\n");};
W3D_ClearDrawRegion(context,0); return TRUE; } /*==================================================================================*/ void SetP(Point3D *P,float x, float y, float z,float w,float u, float v,float *color) { P->x=x; P->y=y; P->z=z; P->w=w; P->u=u; P->v=v; P->color[0]=color[0]; P->color[1]=color[1]; P->color[2]=color[2]; P->color[3]=color[3]; } /*==================================================================================*/ void DoQuad(Point3D *P,float x, float y,float xlarge,float yhigh,float u, float v,float ularge,float vhigh,float *color) { float z=0.0; float w=1.0;
w=0.001/(P->z+0.001); SetP(&P[0],x,y+yhigh,z,w,u,v+vhigh,color); SetP(&P[1],x+xlarge,y+yhigh,z,w,u+ularge,v+vhigh,color); SetP(&P[2],x+xlarge,y,z,w,u+ularge,v,color); SetP(&P[3],x,y+yhigh,z,w,u,v+vhigh,color); SetP(&P[4],x+xlarge,y,z,w,u+ularge,v,color); SetP(&P[5],x,y,z,w,u,v,color); } /*==================================================================================*/ void DrawArrWarp3D(Point3D *P,ULONG Pnb,ULONG primitive) { void *VertexPointer; void *TexCoordPointer; void *ColorPointer; UWORD stride=sizeof(Point3D); UWORD off_v,off_w; ULONG format,result;
REM(DrawArrWarp3D)
W3D_Flush(context); W3D_WaitIdle(context); /* dont modify points or pointers during drawing */ /* Warp3D V5 for Os4 ppc only implement W3D_InterleavedArray() not W3D_Vertex/TexCoord/ColorPointer() */ #ifdef OS4 #define ARRAYFORMAT (W3D_VFORMAT_COLOR | W3D_VFORMAT_TCOORD_0 ) VertexPointer =(void *)&(P->x); W3D_InterleavedArray(context,VertexPointer,stride,ARRAYFORMAT,W3D_TEXCOORD_NORMALIZED); #else VertexPointer =(void *)&(P->x); TexCoordPointer =(void *)&(P->u); ColorPointer =(void *)&(P->color); off_v=(UWORD)( (ULONG)&(P->v) - (ULONG)&(P->u)); off_w=(UWORD)( (ULONG)&(P->w) - (ULONG)&(P->u)); result=W3D_VertexPointer(context,VertexPointer,stride,W3D_VERTEX_F_F_F, 0); result=W3D_TexCoordPointer(context,TexCoordPointer,stride,0, off_v, off_w,W3D_TEXCOORD_NORMALIZED); result=W3D_ColorPointer(context,ColorPointer,stride,W3D_COLOR_FLOAT ,W3D_CMODE_RGBA,0); #endif if( W3D_SUCCESS != W3D_LockHardware(context) ) {REM(cant lock!) ; return;} W3D_DrawArray(context,primitive,0,Pnb); /* draw with warp3d */ W3D_UnLockHardware(context); } /*==================================================================================*/ int main(int argc, char *argv[]) { ULONG x,y,high,large;
REM( main )
texlarge=352; texhigh=288; winlarge=texlarge+100; winhigh =texhigh+100;
if(FALSE==StartWarp3D()) goto panic;
REM( load tex ) pic1=malloc(texlarge*texhigh*16/8); pic2=malloc(texlarge*texhigh*16/8); if(pic1==NULL) {printf("cant alloc texture!\n");goto panic;} if(pic1==NULL) {printf("cant alloc texture!\n");goto panic;}
if((fp = fopen("PROGDIR:test.yuv","rb")) == NULL) { printf("can't open picture\n");goto panic;} fread(pic1,texlarge*texhigh*32/8,1,fp); fclose(fp);
REM( YUV loaded) tex1 = W3D_AllocTexObjTags(context, &error, W3D_ATO_IMAGE, (ULONG) pic1, W3D_ATO_FORMAT, W3D_I8, W3D_ATO_WIDTH, texlarge*2, W3D_ATO_HEIGHT, texhigh, TAG_DONE); if(tex1==NULL) {printf("Warp3D cant alloc I8 texture1!\n");goto panic;}
tex2 = W3D_AllocTexObjTags(context, &error, W3D_ATO_IMAGE, (ULONG) pic2, W3D_ATO_FORMAT, W3D_I8, W3D_ATO_WIDTH, texlarge, W3D_ATO_HEIGHT, texhigh*2, TAG_DONE); if(tex2==NULL) {printf("Warp3D cant alloc I8 texture2!\n");goto panic;}
W3D_SetState(context,W3D_TEXMAPPING,W3D_ENABLE);
REM(pass1: unfold interleaved YUV a 3 squares Y U V) scissor2.left=0; scissor2.top=0; scissor2.width=texlarge; scissor2.height=texhigh*2; IWarp3D->W3D_SetDrawRegionTexture(context,tex2,&scissor2); REM( w3d settings ) W3D_BindTexture(context,0,tex1); W3D_SetFilter(context,tex1,W3D_NEAREST,W3D_NEAREST); W3D_SetTexEnv(context,tex1,W3D_REPLACE,NULL); W3D_SetState(context,W3D_BLENDING,W3D_DISABLE); REM( Y U V to 3 quads ) onetexel=1.0/(float)(texlarge*4); DoQuad(&P[0],0,0,texlarge,texhigh,0.0*onetexel,0.0,1.0,1.0,White); DoQuad(&P[6],0,texhigh,texlarge/2,texhigh,1.0*onetexel,0.0,1.0,1.0,White); DoQuad(&P[12],texlarge/2,texhigh,texlarge/2,texhigh,3.0*onetexel,0.0,1.0,1.0,White); REM( draw the 3 quads ) DrawArrWarp3D(P,18,W3D_PRIMITIVE_TRIANGLES); REM(flush) W3D_FlushFrame(context); W3D_WaitIdle(context); Delay(500);
REM(pass2: Merge the 3 squares Y U V to an RGB picture in window-bitmap) x =window->LeftEdge + window->BorderLeft ; y =window->TopEdge + window->BorderTop ; large =window->Width - window->BorderLeft - window->BorderRight ; high =window->Height - window->BorderTop - window->BorderBottom; scissor1.left=x; scissor1.top=y; scissor1.width=large; scissor1.height=high; W3D_SetDrawRegion(context,window->RPort->BitMap,0,&scissor1); REM( w3d settings ) W3D_BindTexture(context,0,tex2); W3D_SetFilter(context,tex2,W3D_LINEAR,W3D_LINEAR); W3D_SetTexEnv(context,tex2,W3D_MODULATE,NULL); W3D_SetState(context,W3D_BLENDING,W3D_ENABLE); W3D_SetBlendMode(context,W3D_SRC_ALPHA,W3D_ONE_MINUS_SRC_ALPHA); REM( Y U V from 3 quads ) DoQuad(&P2[0 ],x,y,large,high,0.0,0.0,1.0,0.5,ColorY); DoQuad(&P2[6 ],x,y,large,high,0.0,0.5,0.5,0.5,ColorU); DoQuad(&P2[12],x,y,large,high,0.5,0.5,0.5,0.5,ColorV); REM( draw the 3 quads ) DrawArrWarp3D(P2,18,W3D_PRIMITIVE_TRIANGLES); REM(flush) W3D_FlushFrame(context); W3D_WaitIdle(context); Delay(500);
panic: REM( Closing down...) if (tex1) W3D_FreeTexObj(context, tex1); if (tex2) W3D_FreeTexObj(context, tex2); if (pic1) free(pic1); if (pic2) free(pic2); if (context) W3D_DestroyContext(context); if (window) CloseWindow(window); CloseAmigaLibraries(); exit(0); }
|