Jump to content
  • Advertisement
Sign in to follow this  
Yola

Alpha chanel

This topic is 2560 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Need to detect which object clicked. Every object have texture with alpha, can i check is click was on transparent pixel?

Now i save alpha lyaer as separate array by lock texture extract from it, but it seems to take much memory.

I use DirectX.

Share this post


Link to post
Share on other sites
Advertisement
The fastest way to sample a pixel from a texture is to have a copy of the texture on the CPU. The array getting the data must have the same color representation as the texture. You might want to use a boolean quad tree to save a lot of memory. To speed up loading time, you can save a boolean quad tree for each texture and delete the tree file when the edges has changed.

Here is the code for getting a rectangle from a texture to an array directly from my engine:

struct CPUSurface_Struct {
COLLECTION_STRUCT_DATA(CPUSurface)

ID3D11Texture2D* StagingBuffer;

// Index = X + (Y * Width)
// Size = Width * Height
D3DXVECTOR4* CPUContent;

// Dimensions
int Width;
int Height;
};

void EngineCore::CPUSurface_SetSize(CPUSurface_Struct* Surface, int NewWidth, int NewHeight, float Red, float Green, float Blue, float Alpha) {
if (NewWidth < 1 || NewHeight < 1) {
MQ->InsertMessage(L"CPUSurface_SetSize: A CPU surface can't have non positive dimensions.");
} else if (NewWidth > 8192 || NewHeight > 8192) {
MQ->InsertMessage(L"CPUSurface_SetSize: A CPU surface can't have dimensions larger than 8192.");
} else {

// Release any old data to avoid memory leaks
CPUSurface_Struct_Release(Surface);

// Store dimensions
Surface->Width = NewWidth;
Surface->Height = NewHeight;

// Allocate the CPU array
int Size = NewWidth * NewHeight;
Surface->CPUContent = new D3DXVECTOR4[Size];

// Fill the CPU array with a default value for deterministic behaviour.
CPUSurface_FillWithColor(Surface,Red, Green, Blue, Alpha);

// Create staging buffer
D3D11_TEXTURE2D_DESC StagedDesc = {
NewWidth,//UINT Width;
NewHeight,//UINT Height;
1,//UINT MipLevels;
1,//UINT ArraySize;
DXGI_FORMAT_R32G32B32A32_FLOAT,//DXGI_FORMAT Format;
1, 0,//DXGI_SAMPLE_DESC SampleDesc;
D3D11_USAGE_STAGING,//D3D11_USAGE Usage;
0,//UINT BindFlags;
D3D11_CPU_ACCESS_READ,//UINT CPUAccessFlags;
0//UINT MiscFlags;
};
m_pd3dDevice->CreateTexture2D( &StagedDesc, NULL, &Surface->StagingBuffer );
}
}

void EngineCore::CPUSurface_CopyRectFromDrawSurface(DrawSurface_Struct* Input_DrawSurface, CPUSurface_Struct* Output_CPUSurface, int SourceLeft, int SourceTop, int DestLeft, int DestTop, int Width, int Height) {
int i; int X; int Y;
ID3D11Texture2D* InputResource;
if (Input_DrawSurface->FinalSurface == true) {
MQ->InsertMessage(L"CPUSurface_CopyRectFromDrawSurface: The final draw surface can not be used with this method because it does not work like a regular draw surface.");
} else if (DestLeft < 0) {
swprintf_s( MQ->messageBuffer, L"CPUSurface_CopyRectFromDrawSurface: DestLeft = %i < 0.",DestLeft); MQ->InsertMessage(MQ->messageBuffer);
} else if (DestTop < 0) {
swprintf_s( MQ->messageBuffer, L"CPUSurface_CopyRectFromDrawSurface: DestTop = %i < 0.",DestTop); MQ->InsertMessage(MQ->messageBuffer);
} else if (SourceLeft < 0) {
swprintf_s( MQ->messageBuffer, L"CPUSurface_CopyRectFromDrawSurface: SourceLeft = %i < 0.",SourceLeft); MQ->InsertMessage(MQ->messageBuffer);
} else if (SourceTop < 0) {
swprintf_s( MQ->messageBuffer, L"CPUSurface_CopyRectFromDrawSurface: SourceTop = %i < 0.",SourceTop); MQ->InsertMessage(MQ->messageBuffer);
} else if (SourceLeft + Width > Input_DrawSurface->CurrentWidth) {
swprintf_s( MQ->messageBuffer, L"CPUSurface_CopyRectFromDrawSurface: SourceLeft + Width = %i > %i.",SourceLeft + Width,Input_DrawSurface->CurrentWidth); MQ->InsertMessage(MQ->messageBuffer);
} else if (SourceTop + Height > Input_DrawSurface->CurrentHeight) {
swprintf_s( MQ->messageBuffer, L"CPUSurface_CopyRectFromDrawSurface: SourceTop + Height = %i < %i.",SourceTop + Height,Input_DrawSurface->CurrentHeight); MQ->InsertMessage(MQ->messageBuffer);
} else if (DestLeft + Width > Output_CPUSurface->Width) {
swprintf_s( MQ->messageBuffer, L"CPUSurface_CopyRectFromDrawSurface: DestLeft + Width = %i < %i.",DestLeft + Width,Output_CPUSurface->Width); MQ->InsertMessage(MQ->messageBuffer);
} else if (DestTop + Height > Output_CPUSurface->Height ) {
swprintf_s( MQ->messageBuffer, L"CPUSurface_CopyRectFromDrawSurface: DestTop + Height = %i < %i.",DestLeft + Height,Output_CPUSurface->Height); MQ->InsertMessage(MQ->messageBuffer);
} else if (Input_DrawSurface->HasContent == false) {
// Save time if we already know the result
LoopForward(DestTop,Y,DestTop + Height - 1) {
LoopForward(DestLeft,X,DestLeft + Width - 1) {
Output_CPUSurface->CPUContent[X + (Y * Output_CPUSurface->Width)] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
}
}
} else {
// Select all pixels
D3D11_BOX SrcBox;
SrcBox.left = SourceLeft; // Minimum X
SrcBox.right = SourceLeft + Width; // Maximum X
SrcBox.top = SourceTop; // Minimum Y
SrcBox.bottom = SourceTop + Height; // Maximum Y
SrcBox.front = 0; // Always 0 for 2D textures
SrcBox.back = 1; // Always 1 for 2D textures

// Get the texture pointer
if (Input_DrawSurface->HaveExtraColorBuffer == false || Input_DrawSurface->SwapState == true) {
InputResource = Input_DrawSurface->OriginalColorBuffer;
} else {
InputResource = Input_DrawSurface->ExtraColorBuffer;
}

// Copy the draw surface to the staging buffer
m_pImmediateContext->CopySubresourceRegion(Output_CPUSurface->StagingBuffer,0,0,0,0,InputResource,0,&SrcBox);

// Lock the memory
D3D11_MAPPED_SUBRESOURCE MappingResult;
m_pImmediateContext->Map(Output_CPUSurface->StagingBuffer,0,D3D11_MAP_READ,0,&MappingResult);

// Get the data
if (MappingResult.pData == NULL) {
MQ->InsertMessage(L"CPUSurface_CopyRectFromDrawSurface: Could not read the texture because the mapped subresource returned NULL.");
} else {
i = 0;
LoopForward(DestTop,Y,DestTop + Height - 1) {
LoopForward(DestLeft,X,DestLeft + Width - 1) {
Output_CPUSurface->CPUContent[X + (Y * Output_CPUSurface->Width)] = ((D3DXVECTOR4*)MappingResult.pData);
i++;
}
}
}

// Unlock the memory
m_pImmediateContext->Unmap(Output_CPUSurface->StagingBuffer,0);
}
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!