• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
benp444

2D blending not work with DXUT

7 posts in this topic

Hi All,
I have built a simple library which worked perfectly for 2D sprites. However when I ported this over to DXUT I am getting strange blending problems. At first everything seemed fine as the alpha channels for the sprites were transparent against the background, but when the sprites crossed each other the bounding box of the sprite became visible. See file attached.

I have created the simplest piece of code I can to demonstrate how I am doing things. I have based this on EmptyProject10.cpp that is comes with the DirectX SDK:

..\MicrosoftDirectXSDKJune2010\Samples\C++\Direct3D10\EmptyProject10

within this there are only two callback functions that I use OnD3D10ResizedSwapChain() and OnD3D10FrameRender(). All the code and the variables are below.

Any help would be greatly appreciated as I have been stuck on this for a long time.

Edit: I have also just realised that the colours are washed out when I am using DXUT. I have read somewhere that this is related to DXUT using DXGI_FORMAT_R8G8B8A8_UNORM_SRGB. However I have already spent ages tinkering with either trying to get DXUT to use DXGI_FORMAT_R8G8B8A8_UNORM or to get my textures to be DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.

[CODE]
#define NUM_POOL_SPRITES 32
D3DX10_SPRITE spritePool[NUM_POOL_SPRITES];
ID3DX10Sprite *pSpriteObject = NULL;
ID3D10ShaderResourceView *gSpriteTextureRV = NULL;
#define MAX_SPRITES 4
// Sprite structure
typedef struct
{
// sprite details
float width;
float height;
// sprite position
float posX;
float posY;
// sprite movement
float moveX;
float moveY;
BOOL visible;
}GameSprite2;
GameSprite2 sprites[MAX_SPRITES] = {0};
// the number of active sprites
int numActiveSprites = 0;
[/CODE]

[CODE]
HRESULT CALLBACK GameApplication::OnD3D10ResizedSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain* pSwapChain,
const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
// create and set the viewport
D3D10_VIEWPORT viewPort;
viewPort.Width = DXUTGetWindowHeight();
viewPort.Height = DXUTGetWindowWidth();
viewPort.MinDepth = 0.0f;
viewPort.MaxDepth = 1.0f;
viewPort.TopLeftX = 0;
viewPort.TopLeftY = 0;
DXUTGetD3D10Device()->RSSetViewports(1, &viewPort);
// Create the default projection matrix
D3DXMatrixOrthoOffCenterLH(&matProjection,
(float)viewPort.TopLeftX,
(float)viewPort.Width,
(float)viewPort.TopLeftY,
(float)viewPort.Height,
0.1f,
10);


ID3D10Texture2D* texture = NULL;
ID3D10Resource* pRes = NULL;
//HRESULT hr = D3DX10CreateTextureFromFile(DXUTGetD3D10Device(), TEXT("./brick.bmp"), NULL, NULL, &pRes, NULL);
HRESULT hr = D3DX10CreateTextureFromFile(DXUTGetD3D10Device(), TEXT("./bitmaps/spheremapsmall.png"), NULL, NULL, &pRes, NULL);
testHr("OnD3D10ResizedSwapChain:D3DX10CreateTextureFromFile",hr);

// Translates the ID3D10Resource object into a ID3D10Texture2D object
pRes->QueryInterface(__uuidof( ID3D10Texture2D ), (LPVOID*)&texture);
pRes->Release();
if (texture == NULL)
{
CLogger::WriteInfoLog("failed to create texture");
return false;
}
// Get the texture details
D3D10_TEXTURE2D_DESC desc;
texture->GetDesc(&desc);
// Create a shader resource view of the texture
D3D10_SHADER_RESOURCE_VIEW_DESC SRVDesc;
ZeroMemory(&SRVDesc, sizeof(SRVDesc));
SRVDesc.Format = desc.Format;
SRVDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MipLevels = desc.MipLevels;
hr=DXUTGetD3D10Device()->CreateShaderResourceView(texture, &SRVDesc, &gSpriteTextureRV);
testHr("OnD3D10ResizedSwapChain:CreateShaderResourceView",hr);
// release the texture
texture->Release();
// Create the Sprite Batch, all sprite drawing is done through
// this object
hr = D3DX10CreateSprite(DXUTGetD3D10Device(), 0, &pSpriteObject);
testHr("OnD3D10ResizedSwapChain:D3DX10CreateSprite",hr);

// Initialize the blend state for alpha drawing
D3D10_BLEND_DESC StateDesc;
ZeroMemory(&StateDesc, sizeof(D3D10_BLEND_DESC));
StateDesc.AlphaToCoverageEnable = FALSE;
StateDesc.BlendEnable[0] = TRUE;
StateDesc.SrcBlend = D3D10_BLEND_SRC_ALPHA;
StateDesc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
StateDesc.BlendOp = D3D10_BLEND_OP_ADD;
StateDesc.SrcBlendAlpha = D3D10_BLEND_ZERO;
StateDesc.DestBlendAlpha = D3D10_BLEND_ZERO;
StateDesc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
StateDesc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
hr=DXUTGetD3D10Device()->CreateBlendState(&StateDesc, &pBlendState10);
testHr("OnD3D10ResizedSwapChain:CreateBlendState",hr);
// Loop through and set the defaults for the
// sprites in the pool
for (int i = 0; i < NUM_POOL_SPRITES; i++)
{
// Texture for this sprite to use
spritePool[i].pTexture = gSpriteTextureRV;
spritePool[i].TextureIndex = 0;
// top-left location in U,V coords
spritePool[i].TexCoord.x = 0;
spritePool[i].TexCoord.y = 0;
// Determine the texture size in U,V coords
spritePool[i].TexSize.x = 1;
spritePool[i].TexSize.y = 1;
spritePool[i].ColorModulate = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
}
// Create a diagonal line of overlapping sprites
for (int curSprite = 0; curSprite < MAX_SPRITES-1; curSprite++)
{
// Set the width and height of the sprite
sprites[curSprite].width = 64.0f;
sprites[curSprite].height = 64.0f;
// position in a diagonal so you can see overlap
sprites[curSprite].posX = 300+(curSprite*15);
sprites[curSprite].posY = 100+(curSprite*15);

sprites[curSprite].moveX = 0;
sprites[curSprite].moveY = 0;
// This sprite is visible
sprites[curSprite].visible = TRUE;
}

//create a single sprite on its own
sprites[MAX_SPRITES-1].width = 64.0f;
sprites[MAX_SPRITES-1].height = 64.0f;
sprites[MAX_SPRITES-1].posX = 100;
sprites[MAX_SPRITES-1].posY = 100;
sprites[MAX_SPRITES-1].visible = TRUE;

D3DXMATRIX matScaling;
D3DXMATRIX matTranslation;
int curPoolIndex = 0;
// Loop through the sprites
for (int i = 0; i < MAX_SPRITES; i++)
{
// only update visible sprites
if (sprites[i].visible)
{
CLogger::WriteInfoLog("OnFrameMove: moving sprites");
// set the proper scale for the sprite
D3DXMatrixScaling(&matScaling, sprites[i].width, sprites[i].height, 1.0f);
// Move the sprite to spritePosX, spritePosY
// SpriteWidth and SpriteHeight are divided by 2 to move the
// translation point to the top-left sprite corner instead of
// the center of the sprite.
D3DXMatrixTranslation(&matTranslation,
(float)sprites[i].posX + (sprites[i].width/2),
(float)(DXUTGetWindowHeight() - sprites[i].posY - (sprites[i].height/2)), 0.1f);
// Update the sprites position and scale
spritePool[curPoolIndex].matWorld = matScaling * matTranslation;
// Increment the pool index
curPoolIndex++;
}
}
// set the number of active sprites
numActiveSprites = curPoolIndex;
return S_OK;
}
[/CODE]

[CODE]
void CALLBACK GameApplication::OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
float ClearColor[4] = { 0.176f, 0.196f, 0.667f, 0.0f };

pd3dDevice->ClearRenderTargetView( DXUTGetD3D10RenderTargetView(), ClearColor );
//pd3dDevice->ClearRenderTargetView( DXUTGetD3D10RenderTargetView(), D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f) );
pd3dDevice->ClearDepthStencilView( DXUTGetD3D10DepthStencilView(), D3D10_CLEAR_DEPTH, 1.0, 0 );
FLOAT OriginalBlendFactor[4];
UINT OriginalSampleMask = 0;
if (DXUTGetD3D10Device() != NULL)
{
// clear the target buffer
//pD3DDevice->ClearRenderTargetView(pRenderTargetView, D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f));
if (pSpriteObject != NULL)
{

HRESULT hr = pSpriteObject->SetProjectionTransform(&matProjection);
testHr("OnD3D10FrameRender:SetProjectionTransform",hr);
// start drawing the sprites
hr=pSpriteObject->Begin(D3DX10_SPRITE_SORT_TEXTURE);
testHr("OnD3D10FrameRender:Begin",hr);
// Draw all the sprites in the pool

hr=pSpriteObject->DrawSpritesBuffered(spritePool, numActiveSprites);
testHr("OnD3D10FrameRender:DrawSpritesBuffered",hr);
// Save the current blend state
DXUTGetD3D10Device()->OMGetBlendState(&pOriginalBlendState10, OriginalBlendFactor, &OriginalSampleMask);
// Set the blend state for alpha drawing
if(pBlendState10)
{
FLOAT NewBlendFactor[4] = {0,0,0,0};
DXUTGetD3D10Device()->OMSetBlendState(pBlendState10, NewBlendFactor, 0xffffffff);
}
// Finish up and send the sprites to the hardware
hr=pSpriteObject->Flush();
testHr("OnD3D10FrameRender:Flush",hr);
hr=pSpriteObject->End();
testHr("OnD3D10FrameRender:End",hr);
}
// Restore the previous blend state
DXUTGetD3D10Device()->OMSetBlendState(pOriginalBlendState10, OriginalBlendFactor, OriginalSampleMask);
}
}
[/CODE] Edited by benp444
0

Share this post


Link to post
Share on other sites
Alpha blended sprites need to be sorted back to front.

The problem lies in the fact that the depth buffer values for a pixel get written even though said pixel would appear to be transparent due to its alpha value.
1

Share this post


Link to post
Share on other sites
Thanks for your response. I changed the code above from

[CODE]
hr=pSpriteObject->Begin(D3DX10_SPRITE_SORT_TEXTURE);
[/CODE]

to

[CODE]
hr=pSpriteObject->Begin(D3DX10_SPRITE_SORT_DEPTH_BACK_TO_FRONT);
[/CODE]

However this hasn't changed the result in any way. I still get the image attached to the OP.

Is there something else I need to be doing?
0

Share this post


Link to post
Share on other sites
If you don't care about the sprite ordering, disable depth testing (and don't sort). If you do care about the ordering, assign meaningful depth values to the sprites for the depth sort to work :)
1

Share this post


Link to post
Share on other sites
Thanks Niko for your help. I have disabled the depth and the the bounding boxes are no longer visible.

To fix the issue I have added the following code to the OnD3D10ResizedSwapChain() method:

[CODE]
//START NEW CODE
D3D10_DEPTH_STENCIL_DESC depthDisabledStencilDesc;
ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc));

depthDisabledStencilDesc.DepthEnable = false;
depthDisabledStencilDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
depthDisabledStencilDesc.DepthFunc = D3D10_COMPARISON_LESS;
depthDisabledStencilDesc.StencilEnable = true;
depthDisabledStencilDesc.StencilReadMask = 0xFF;
depthDisabledStencilDesc.StencilWriteMask = 0xFF;
depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
depthDisabledStencilDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
depthDisabledStencilDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
depthDisabledStencilDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
depthDisabledStencilDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;

hr = DXUTGetD3D10Device()->CreateDepthStencilState(&depthDisabledStencilDesc, &g_pDepthDisabledStencilState);
DXUTGetD3D10Device()->OMSetDepthStencilState(g_pDepthDisabledStencilState, 1);
testHr("CreateDepthStencilState",hr);
//END NEW CODE
[/CODE]

The colours are still washed out, but this is a separate issue may raise seperately.

Cheers,
Ben. Edited by benp444
0

Share this post


Link to post
Share on other sites
Color washout is a separate issue. It is usually related to color space and/or gamma issues. Search for "srgb d3d" to find more info ;)
0

Share this post


Link to post
Share on other sites
Great! and the solution to the washed out colour is to create a new SRGB texture in memory (not from file), copy the non-SRGB texture (from file) into it and use that to create the texture resource. See method below. Now my balls are perfect!

[CODE]
ID3D10Texture2D* GameManager::convertTextureToSRGB(ID3D10Texture2D* srcTexture){
if(srcTexture==NULL) {
throw GameException(E_POINTER,"GameManager::convertTextureToSRGB: srcTexture was null");
}
D3D10_TEXTURE2D_DESC origDesc;
srcTexture->GetDesc(&origDesc);
D3D10_TEXTURE2D_DESC srgbDesc;
ZeroMemory( &srgbDesc, sizeof(srgbDesc));
srgbDesc.Width = origDesc.Width;
srgbDesc.Height = origDesc.Height;
srgbDesc.MipLevels = 1;
srgbDesc.ArraySize = 1;
srgbDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
srgbDesc.SampleDesc.Count = 1;
srgbDesc.Usage = D3D10_USAGE_DYNAMIC;
srgbDesc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
srgbDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
ID3D10Texture2D *pSRGBTexture = NULL;
HRESULT hr=DXUTGetD3D10Device()->CreateTexture2D( &srgbDesc, NULL, &pSRGBTexture );
testHr("CreateTexture2D:CreateTexture2D",hr);
//copy the original texture in the into the SRGB texture
D3D10_BOX sourceRegion;
sourceRegion.left = 0;
sourceRegion.right = origDesc.Width;
sourceRegion.top = 0;
sourceRegion.bottom = origDesc.Height;
sourceRegion.front = 0;
sourceRegion.back = 1;
DXUTGetD3D10Device()->CopySubresourceRegion(pSRGBTexture, 0, 0, 0, 0, srcTexture, 0,&sourceRegion);
return pSRGBTexture;
}
[/CODE]
0

Share this post


Link to post
Share on other sites
This process (in general) is usually called "color space conversion" and can be avoided if you author the textures in the destination space to begin with. Alternatively, you can specify a destination format manually (via the pLoadInfo parameter of the load function) when you load the texture.

Glad to hear you got your balls working [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img] Edited by Nik02
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0