189 lines
6.3 KiB
C++
189 lines
6.3 KiB
C++
/////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// StretchRect
|
|
//
|
|
/////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////
|
|
#include "stdafx.h"
|
|
#include "CKRasterizer.h"
|
|
|
|
CKERROR CreateStretchRectProto(CKBehaviorPrototype **);
|
|
int StretchRect(const CKBehaviorContext& behcontext);
|
|
|
|
|
|
extern CKGUID CKPGUID_CUBEFACE;
|
|
|
|
// input parameters
|
|
enum
|
|
{
|
|
InParam_SrcTexture = 0,
|
|
InParam_SrcRect,
|
|
InParam_SrcCubeFace,
|
|
InParam_DestTexture,
|
|
InParam_DestRect,
|
|
InParam_DestCubeFace,
|
|
InParam_Filtered
|
|
};
|
|
|
|
CKObjectDeclaration *FillBehaviorStretchRect()
|
|
{
|
|
|
|
CKObjectDeclaration *od = CreateCKObjectDeclaration("Stretch Rect");
|
|
od->SetDescription("copy a rectangular area of the framebuffer into a texture, with possible stretching");
|
|
od->SetCategory("Shaders/General");
|
|
od->SetType(CKDLL_BEHAVIORPROTOTYPE);
|
|
od->SetGuid(CKGUID(0x3f1c662a, 0x167e6d7f));
|
|
od->SetAuthorGuid(CKGUID());
|
|
od->SetAuthorName("Virtools");
|
|
od->SetVersion(0x00010000);
|
|
od->SetCreationFunction(CreateStretchRectProto);
|
|
return od;
|
|
}
|
|
|
|
CKERROR CreateStretchRectProto(CKBehaviorPrototype **pproto)
|
|
{
|
|
CKBehaviorPrototype *proto = CreateCKBehaviorPrototype("Stretch Rect");
|
|
if(!proto) return CKERR_OUTOFMEMORY;
|
|
|
|
proto->DeclareInput("In");
|
|
proto->DeclareOutput("Out");
|
|
proto->DeclareOutput("Error");
|
|
|
|
proto->DeclareInParameter("Source Texture", CKPGUID_TEXTURE);
|
|
proto->DeclareInParameter("Source Rect", CKPGUID_RECT, "(0,0),(0,0)" );
|
|
proto->DeclareInParameter("Source Cube Face", CKPGUID_CUBEFACE, "XPos" );
|
|
proto->DeclareInParameter("Dest Texture", CKPGUID_TEXTURE);
|
|
proto->DeclareInParameter("Dest Rect", CKPGUID_RECT, "(0,0),(0,0)" );
|
|
proto->DeclareInParameter("Dest Cube Face", CKPGUID_CUBEFACE, "XPos" );
|
|
proto->DeclareInParameter("Filtered", CKPGUID_BOOL, "TRUE" );
|
|
|
|
proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL);
|
|
proto->SetFunction(StretchRect);
|
|
proto->SetBehaviorFlags(CKBEHAVIOR_TARGETABLE);
|
|
|
|
|
|
*pproto = proto;
|
|
return CK_OK;
|
|
|
|
}
|
|
|
|
|
|
static int SetupCKTextureRstID(const CKBehaviorContext& behcontext, int inputParameter)
|
|
{
|
|
CKBehavior* beh = behcontext.Behavior;
|
|
CKDWORD rstTexID = 0;
|
|
CK_ID texObjectID;
|
|
if (beh->GetInputParameterValue(inputParameter, &texObjectID) == CK_OK)
|
|
{
|
|
CKTexture* destTex = (CKTexture*) behcontext.Context->GetObject(texObjectID);
|
|
if (destTex)
|
|
{
|
|
destTex->EnsureVideoMemory(behcontext.CurrentRenderContext);
|
|
rstTexID = destTex->GetRstTextureIndex();
|
|
}
|
|
}
|
|
return rstTexID;
|
|
}
|
|
|
|
|
|
static CKRECT* vxRectToCKRECT(const VxRect* src, CKRECT& destStorage)
|
|
{
|
|
if (!src) return NULL;
|
|
destStorage.bottom = (int) src->bottom;
|
|
destStorage.top = (int) src->top;
|
|
destStorage.left = (int) src->left;
|
|
destStorage.right = (int) src->right;
|
|
return &destStorage;
|
|
}
|
|
|
|
int StretchRect(const CKBehaviorContext& behcontext)
|
|
{
|
|
CKBehavior* beh = behcontext.Behavior;
|
|
beh->ActivateInput(0,FALSE);
|
|
//
|
|
CKRasterizerContext* rsctx = behcontext.CurrentRenderContext->GetRasterizerContext();
|
|
if (!rsctx)
|
|
{
|
|
beh->ActivateOutput(1);
|
|
return CKBR_OK;
|
|
}
|
|
//
|
|
VxRect fSrcRect;
|
|
VxRect fDestRect;
|
|
CKRECT srcRect;
|
|
CKRECT destRect;
|
|
VxRect* fSrcRectPtr = NULL;
|
|
VxRect* fDestRectPtr = NULL;
|
|
|
|
int srcTexID = SetupCKTextureRstID(behcontext, InParam_SrcTexture);
|
|
int destTexID = SetupCKTextureRstID(behcontext, InParam_DestTexture);
|
|
|
|
if (beh->GetInputParameterValue(InParam_SrcRect, &fSrcRect) == CK_OK)
|
|
{
|
|
fSrcRectPtr = fSrcRect.IsNull() ? NULL : &fSrcRect;
|
|
}
|
|
if (beh->GetInputParameterValue(InParam_DestRect, &fDestRect) == CK_OK)
|
|
{
|
|
fDestRectPtr = fDestRect.IsNull() ? NULL : &fDestRect;
|
|
}
|
|
CKBOOL filter = TRUE;
|
|
beh->GetInputParameterValue(InParam_Filtered, &filter);
|
|
//
|
|
CKDWORD srcCubeFace = CKRST_CUBEFACE_XPOS;
|
|
CKDWORD destCubeFace = CKRST_CUBEFACE_XPOS;
|
|
//
|
|
beh->GetInputParameterValue(InParam_SrcCubeFace, &srcCubeFace);
|
|
beh->GetInputParameterValue(InParam_DestCubeFace, &destCubeFace);
|
|
//
|
|
CKRST_STRETCHRECT_ERROR srErr = (rsctx->StretchRect(destTexID, vxRectToCKRECT(fDestRectPtr, destRect), (CKRST_CUBEFACE) destCubeFace,
|
|
srcTexID, vxRectToCKRECT(fSrcRectPtr, srcRect), (CKRST_CUBEFACE) srcCubeFace, filter));
|
|
if (srErr != CKRST_STRETCHRECT_NO_ERROR)
|
|
{
|
|
char* errMsg;
|
|
switch(srErr)
|
|
{
|
|
case CKRST_STRETCHRECT_UNSUPPORTED:
|
|
errMsg = "Stretch Rect : Rasterizer has no stretch rect support.";
|
|
break;
|
|
case CKRST_STRETCHRECT_DEST_EQUAL_SOURCE_ERROR:
|
|
errMsg = "Stretch Rect : Source and Destination should be different.";
|
|
break;
|
|
case CKRST_STRETCHRECT_BLIT_FROM_MULTISAMPLED_BACKBUFFER_ERROR:
|
|
errMsg = "Stretch Rect : Can't stretch rect from a multisampled render target. \n"
|
|
"You should use the 'Resolve Multisampling' BB prior ro 'Stetch Rect'. \n"
|
|
"You should also activate the 'CK2_3D/OffscreenMultiSampledBuffer' in order to permit such manual multisampling resolve.";
|
|
break;
|
|
case CKRST_STRETCHRECT_BLIT_TO_MULTISAMPLED_BACKBUFFER_ERROR:
|
|
errMsg = "Stretch Rect : Can't stretch rect to a multisampled render target. \n"
|
|
"You should use the 'Resolve Multisampling' BB prior ro 'Stetch Rect'. \n"
|
|
"You should also activate the 'CK2_3D/OffscreenMultiSampledBuffer' in order to permit such manual multisampling resolve.";
|
|
break;
|
|
case CKRST_STRETCHRECT_NONPOW2_SRC_TEX_ERROR:
|
|
errMsg = "Stretch Rect : Source texture dimensions should be powers of 2, unless the source is the back buffer.";
|
|
break;
|
|
case CKRST_STRETCHRECT_NONPOW2_DEST_TEX_ERROR:
|
|
errMsg = "Stretch Rect : Destination texture dimensions should be powers of 2, unless the destination is the back buffer.";
|
|
break;
|
|
case CKRST_STRETCHRECT_SRC_RECT_ERROR:
|
|
errMsg = "Stretch Rect : Source rectangle is outside of the surface.";
|
|
break;
|
|
case CKRST_STRETCHRECT_DEST_RECT_ERROR:
|
|
errMsg = "Stretch Rect : Dest rectangle is outside of the surface.";
|
|
break;
|
|
case CKRST_STRETCHRECT_BAD_CUBE_FACE_ERROR:
|
|
errMsg = "Stretch Rect : Cube map face is invalid."; break;
|
|
break;
|
|
default:
|
|
case CKRST_STRETCHRECT_OPERATION_FAILED_ERROR:
|
|
errMsg = "Stretch Rect : Stretch rect operation failed (possibly due to unsupportedd multisampling / format / texture type combination."; break;
|
|
break;
|
|
}
|
|
beh->m_Context->OutputToConsole(errMsg);
|
|
beh->ActivateOutput(1);
|
|
return CKBR_OK;
|
|
}
|
|
beh->ActivateOutput(0);
|
|
return CKBR_OK;
|
|
}
|