diff --git a/ref/dx2/r_context.c b/ref/dx2/r_context.c index 0b85322b..6754eff9 100644 --- a/ref/dx2/r_context.c +++ b/ref/dx2/r_context.c @@ -163,6 +163,83 @@ static qboolean DD_CreateBackSurface() return true; } +static qboolean D3D_Init() +{ + DXCheck(IDirectDraw_QueryInterface(dxc.pdd, &IID_IDirect3D, (void**)&dxc.pd3d)); + gEngfuncs.Con_Printf("IDirectDraw::QueryInterface(IID_IDirect3D) %p\n", dxc.pd3d); + + if (!dxc.pd3d) + return false; + + DXCheck(IDirect3D_CreateViewport(dxc.pd3d, &dxc.viewport, NULL)); + gEngfuncs.Con_Printf("IDirect3D::CreateViewport %p\n", dxc.viewport); + + if (!dxc.viewport) + return false; + + return true; +} + +static qboolean D3D_InitDevice() +{ + if (!dxc.pd3d) + return false; + + D3DFINDDEVICESEARCH search = { 0 }; + memset(&search, 0, sizeof(search)); + search.dwSize = sizeof(search); + search.dwFlags = D3DFDS_COLORMODEL; + search.dcmColorModel = D3DCOLOR_RGB; + D3DFINDDEVICERESULT result = { 0 }; + memset(&result, 0, sizeof(result)); + result.dwSize = sizeof(result); + + DXCheck(IDirect3D_FindDevice(dxc.pd3d, &search, &result)); + DXCheck(IDirectDrawSurface_QueryInterface(dxc.pddsBack, &result.guid, (void**)&dxc.pd3dd)); + gEngfuncs.Con_Printf("IDirectDrawSurface::QueryInterface(IDirect3DDevice) %p\n", dxc.pd3dd); + + if (!dxc.pd3dd) + return false; + + D3DEXECUTEBUFFERDESC ebd = { 0 }; + memset(&ebd, 0, sizeof(ebd)); + ebd.dwSize = sizeof(ebd); + ebd.dwFlags = D3DDEB_BUFSIZE; + ebd.dwBufferSize = 1024 * 64; + DXCheck(IDirect3DDevice_CreateExecuteBuffer(dxc.pd3dd, &ebd, &dxc.pd3deb, NULL)); + gEngfuncs.Con_Printf("IDirect3DDevice::CreateExecuteBuffer %p\n", dxc.pd3deb); + + if (!dxc.pd3deb) + return false; + + if (!dxc.viewport) + return false; + + DXCheck(IDirect3DDevice_AddViewport(dxc.pd3dd, dxc.viewport)); + + DDSURFACEDESC desc = { 0 }; + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT; + DXCheck(IDirectDrawSurface_GetSurfaceDesc(dxc.pddsBack , &desc)); + + D3DVIEWPORT viewport = { 0 }; + viewport.dwSize = sizeof(viewport); + viewport.dwX = 0; + viewport.dwY = 0; + viewport.dwWidth = desc.dwWidth; + viewport.dwHeight = desc.dwHeight; + viewport.dvScaleX = 1; + viewport.dvScaleY = 1; + viewport.dvMaxX = 1; + viewport.dvMaxY = 1; + viewport.dvMinZ = 0; + viewport.dvMaxZ = 1; + DXCheck(IDirect3DViewport_SetViewport(dxc.viewport, &viewport)); + + return true; +} + DEFINE_ENGINE_SHARED_CVAR_LIST() static qboolean R_Init( void ) @@ -221,6 +298,18 @@ static qboolean R_Init( void ) return false; } + if (!D3D_Init()) + { + Mem_FreePool(&r_temppool); + return false; + } + + if (!D3D_InitDevice()) + { + Mem_FreePool(&r_temppool); + return false; + } + dxc.renderMode = kRenderNormal; R_InitImages(); @@ -348,6 +437,47 @@ static void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int ; } +static void D3D_SetVert(D3DTLVERTEX* v, float x, float y, float z, float w, float tu, float tv) +{ + v->sx = x; + v->sy = y; + v->sz = z; + v->rhw = w; + //v->color = RGBA_MAKE(250, 10, 10, 255); + v->tu = tu; + v->tv = tv; +} + +static void D3D_SetTri(D3DTRIANGLE *t, int v1, int v2, int v3) +{ + t->v1 = v1; + t->v2 = v2; + t->v3 = v3; + t->wFlags = D3DTRIFLAG_EDGEENABLETRIANGLE; +} + +static void D3D_PutInstruction(void **dst, BYTE opcode, BYTE size, WORD count) +{ + D3DINSTRUCTION* inst = (D3DINSTRUCTION*)*dst; + inst->bOpcode = opcode; + inst->bSize = size; + inst->wCount = count; + *dst = (void*)(((D3DINSTRUCTION*)*dst) + 1); +} + +static void D3D_PutProcessVertices(void** dst, DWORD flags, WORD start, WORD count) +{ + D3D_PutInstruction(dst, D3DOP_PROCESSVERTICES, sizeof(D3DPROCESSVERTICES), 1); + + D3DPROCESSVERTICES* pv = (D3DPROCESSVERTICES*)*dst; + pv->dwFlags = flags; + pv->wStart = start; + pv->wDest = start; + pv->dwCount = count; + pv->dwReserved = 0; + *dst = (void*)(((D3DPROCESSVERTICES*)*dst) + 1); +} + static void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ) { if (texnum <= 0 || texnum >= MAX_TEXTURES) @@ -357,6 +487,7 @@ static void R_DrawStretchPic( float x, float y, float w, float h, float s1, floa if (!tex->dds) return; +#if 0 RECT dstRect = { x, y, x + w, y + h }; RECT srcRect = { s1 * tex->width, t1 * tex->height, s2 * tex->width, t2 * tex->height}; @@ -373,6 +504,67 @@ static void R_DrawStretchPic( float x, float y, float w, float h, float s1, floa DXCheck(IDirectDrawSurface_Blt(dxc.pddsBack, &dstRect, tex->dds, &srcRect, DDBLT_WAIT | DDBLT_KEYSRC, NULL)); } +#else + + if (!dxc.pd3deb) + return; + { + D3DEXECUTEBUFFERDESC ebDesc = { 0 }; + memset(&ebDesc, 0, sizeof(ebDesc)); + ebDesc.dwSize = sizeof(ebDesc); + ebDesc.dwFlags = D3DDEB_LPDATA; + DXCheck(IDirect3DExecuteBuffer_Lock(dxc.pd3deb, &ebDesc)); + + void* cur = ebDesc.lpData; + + const int vertCount = 4; + //D3DTLVERTEX verts[4]{}; + //D3DTRIANGLE tris[2]{}; + D3DTLVERTEX* verts = (D3DTLVERTEX*)cur; + + verts[0].color = RGBA_MAKE(250, 10, 10, 255); + D3D_SetVert(verts, x, y, 0.5, 1, s1, t1); + verts[1].color = RGBA_MAKE(10, 250, 10, 255); + D3D_SetVert(verts + 1, x + w, y, 0.5, 1, s2, t1); + verts[2].color = RGBA_MAKE(10, 10, 250, 255); + D3D_SetVert(verts + 2, x + w, y + h, 0.5, 1, s2, t2); + verts[3].color = RGBA_MAKE(250, 250, 10, 255); + D3D_SetVert(verts + 3, x, y + h, 0.5, 1, s1, t2); + + cur = (void*)(((D3DTLVERTEX*)cur) + vertCount); + + void* insStart = cur; + + D3D_PutProcessVertices(&cur, D3DPROCESSVERTICES_COPY | D3DPROCESSVERTICES_UPDATEEXTENTS, 0, vertCount); + //align + if (!(((ULONG)cur) & 7)) { + D3D_PutInstruction(&cur, D3DOP_TRIANGLE, sizeof(D3DTRIANGLE), 0); + } + D3D_PutInstruction(&cur, D3DOP_TRIANGLE, sizeof(D3DTRIANGLE), 2); + + D3DTRIANGLE* tris = (D3DTRIANGLE*)cur; + D3D_SetTri(tris, 0, 1, 2); + D3D_SetTri(tris + 1, 0, 2, 3); + cur = (void*)(((D3DTRIANGLE*)cur) + 2); + + D3D_PutInstruction(&cur, D3DOP_EXIT, 0, 0); + + DXCheck(IDirect3DExecuteBuffer_Unlock(dxc.pd3deb)); + + D3DEXECUTEDATA exData = { 0 }; + memset(&exData, 0, sizeof(exData)); + exData.dwSize = sizeof(exData); + exData.dwVertexCount = vertCount; + exData.dwVertexOffset = 0; + exData.dwInstructionOffset = ((char*)insStart - (char*)ebDesc.lpData); + exData.dwInstructionLength = ((char*)cur - (char*)insStart); + DXCheck(IDirect3DExecuteBuffer_SetExecuteData(dxc.pd3deb , &exData)); + } + + DXCheck(IDirect3DDevice_BeginScene(dxc.pd3dd)); + DXCheck(IDirect3DDevice_Execute(dxc.pd3dd, dxc.pd3deb, dxc.viewport, D3DEXECUTE_CLIPPED)); + DXCheck(IDirect3DDevice_EndScene(dxc.pd3dd)); +#endif } static void FillRGBA( int rendermode, float x, float y, float w, float h, byte r, byte g, byte b, byte a ) @@ -682,14 +874,25 @@ void R_EndFrame(void) { dxc.windowWidth = w; dxc.windowHeight = h; + + if( dxc.pd3deb ) + IDirect3DExecuteBuffer_Release(dxc.pd3deb); + dxc.pd3deb = NULL; + if( dxc.pd3dd ) + IDirect3DDevice_Release(dxc.pd3dd); + dxc.pd3dd = NULL; if( dxc.pddsBack ) - DXCheck(IDirectDrawSurface_Release(dxc.pddsBack)); + IDirectDrawSurface_Release(dxc.pddsBack); dxc.pddsBack = NULL; if( dxc.pddBackClipper ) - DXCheck(IDirectDrawClipper_Release(dxc.pddBackClipper)); + IDirectDrawClipper_Release(dxc.pddBackClipper); dxc.pddBackClipper = NULL; - if (!DD_CreateBackSurface()) - dxc.window = 0; + if( DD_CreateBackSurface() ) + { + if( D3D_InitDevice() ) + { + } + } } } diff --git a/ref/dx2/r_local.h b/ref/dx2/r_local.h index 00aadd7d..de61f898 100644 --- a/ref/dx2/r_local.h +++ b/ref/dx2/r_local.h @@ -169,6 +169,10 @@ struct dx_context_s IDirectDrawSurface *pddsBack; IDirectDrawClipper *pddClipper; IDirectDrawClipper *pddBackClipper; + IDirect3D *pd3d; + IDirect3DDevice *pd3dd; + IDirect3DExecuteBuffer *pd3deb; + IDirect3DViewport *viewport; int renderMode; };