Using Direct 3D's index buffer - c++

I am writing a program that generates a sphere and renders it using a Direct 3D device. I am using an Index buffer and I am having trouble figuring out why my triangles are so messed up. I tested the positions of the vertices sent to the vertex buffer, and they all look like they are in perfekt position.
The primitive type used is D3DPT_TRIANGLESTRIP.
I'd be really happy if someone could point out where in my understanding of index buffers I fail horribly, and maybe tell me how shizzle works.
This is my Code:
bool CGameApp::CreateSphere( ULONG nColor, LPDIRECT3DVERTEXBUFFER9 * ppVertexBuffer, LPDIRECT3DINDEXBUFFER9 * ppIndexBuffer, ULONG & nNumVertices, ULONG & nNumFaces )
{
float x, y = 0.0f, z = 0.0f;
float r = 0.0f; // the radius calculated for each circle
ULONG nUsage= D3DUSAGE_WRITEONLY;
LPDIRECT3DVERTEXBUFFER9 pVertexBuffer = NULL;
LPDIRECT3DINDEXBUFFER9 pIndexBuffer = NULL;
HRESULT hRet;
CVertex * pVertex = NULL;
ULONG * pIndex = NULL;
ULONG nSlices, nStacks, jump= 10;
ULONG nStack, nSlice;
if (ppVertexBuffer != NULL) *ppVertexBuffer = NULL;
if (ppIndexBuffer != NULL) *ppIndexBuffer = NULL;
// Validate parameters
if (ppVertexBuffer == NULL | ppIndexBuffer == NULL )
return false;
// The Poles are hardcoded, the rest generated using trigonometry
x = -1.0f;
m_aSphere.push_back(CVertex(x, y, z, 0xFF0000FF));
for (int degreesX = 180; degreesX >= 0; degreesX -= 10) //stack ( 18 stacks )
{
x = (float)cos(D3DXToRadian(degreesX));
for (int degreesY = 0; degreesY < 360; degreesY+= 10) // slices ( 36 slices )
{
r = (float)sin(D3DXToRadian(degreesX));
y = (float)sin(D3DXToRadian(degreesY)) * r; // regulate each unit circle
z = (float)cos(D3DXToRadian(degreesY)) * r; // by multiplying with radius
m_aSphere.push_back(CVertex(x, y, z, nColor));
}
}
nStacks = 180 / jump;
nSlices = 360 / jump;
x = 1.0f; y = 0.0f; z = 0.0f;
m_aSphere.push_back(CVertex(x, y, z, 0xFF0000FF));
//m_aSphere.push_back(CVertex(0, 0, 0, 0xFF0000FF));
/////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////
nNumFaces= nStacks * nSlices * 2;
nNumVertices = m_aSphere.size();
VERTEXPROCESSING_TYPE vp = m_D3DSettings.GetSettings()->VertexProcessingType;
if (vp != HARDWARE_VP && vp != PURE_HARDWARE_VP) nUsage |= D3DUSAGE_SOFTWAREPROCESSING;
hRet = m_pD3DDevice->CreateVertexBuffer(sizeof(CVertex)* m_aSphere.size(), D3DUSAGE_WRITEONLY,
D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &pVertexBuffer, NULL);
if (FAILED(hRet)) return false;
// Lock the vertex buffer ant run in the array generated.
hRet = pVertexBuffer->Lock(0, sizeof(CVertex)* m_aSphere.size(), (void**)&pVertex, 0);
if (FAILED(hRet))
{
pVertexBuffer->Release();
return false;
}
// Load the Vertices into the vertex buffer
for (int i = 0; i <= m_aSphere.size() - 1; i++)
{
*pVertex++ = m_aSphere[i];
}
pVertexBuffer->Unlock(); // Unlock the Vertex Buffer yet again.
// Initialize the Index Buffer
hRet = m_pD3DDevice->CreateIndexBuffer( nNumFaces * 3 * sizeof(ULONG) , nUsage, D3DFMT_INDEX16,
D3DPOOL_MANAGED, &pIndexBuffer, NULL );
if (FAILED(hRet))
{
pIndexBuffer->Release();
pVertexBuffer->Release();
return false;
}
//Try to Lock the index buffer to apply the index stream
hRet = pIndexBuffer->Lock(0, 0, (void**)&pIndex, 0);
if (FAILED(hRet))
{
pIndexBuffer->Release();
pIndex= NULL;
return false;
} // Lock was Successful!
// Here the vertices will be awesomely interpreted by the Index Buffer!!!!!!
// This is where things go wrong apparently
for (nStack = 10; nStack < nStacks; nStack++)
{
for (nSlice = 10; nSlice < nSlices; nSlice++)
{
*pIndex++ = nStack * nSlice;
*pIndex++ = (nStack + 1) * nSlice;
}
*pIndex++ = (nStack + 1) * nSlice; // Make degenerate triangle, then start new stack!
}
pIndexBuffer->Unlock(); // unlock the index buffer;
//return pointers
*ppVertexBuffer = pVertexBuffer;
*ppIndexBuffer = pIndexBuffer;
// Success!
return true;
}
This is the outcome showed in fillmode Wireframe.:
http://imgur.com/2D4NN5e
Thank you in advance :)

Related

Legacy C++ code not displaying bitmap under Windows 10

I have to get some legacy (XP) MFC code running under Windows 10. It runs fine under Windows 7. I haven't tried any other versions.
The idea is that there is a buffer in memory that contains the image pixel values in RGB.
Then to display the image to the screen it is transformed into a bitmap and then copied to the DC.
This is the function that does the display of the object to the screen.
It seems to work, but then nothing gets shown on the screen except a white box.
(The comments were already there! someone else must have had some fun with this as well!)
WORD* CFBuffer24::getBitmap(int nBitsPerPixel)
{
// check operation is valid
ASSERT(m_pFB[RED] && m_pFB[GREEN] && m_pFB[BLUE]);
if (nBitsPerPixel == 24)
{
if(NULL == m_pbm24)
m_pbm24 = new UCHAR[((m_fbSize.cx*3+3) & ~3)*m_fbSize.cy];
ASSERT(m_pbm24);
UCHAR* rptr = m_pFB[RED]->getPointer(0,0);
UCHAR* gptr = m_pFB[GREEN]->getPointer(0,0);
UCHAR* bptr = m_pFB[BLUE]->getPointer(0,0);
UCHAR* sptr = m_pbm24;
if (m_dGamma == 1.0)
{
for (int i = 0; i < m_fbSize.cx*m_fbSize.cy; i++, rptr++, gptr++, bptr++)
{
// Assumes 24bit display ie. B R G format
*sptr++ = *bptr;
*sptr++ = *gptr;
*sptr++ = *rptr;
}
}
else
{
UCHAR* wLUT = new UCHAR[256];
for (int i = 0; i < 256; i++)
{
int val = (int) (255.0 * pow((double) i / 255.0,1.0/m_dGamma) + 0.5);
if (val > 255)
val = 255;
wLUT[i] = UCHAR(val);
}
for (i = 0; i < m_fbSize.cx*m_fbSize.cy; i++, rptr++, gptr++, bptr++)
{
// Assumes 16bit display ie. 5R:6G:5B format
*sptr++ = wLUT[*bptr];
*sptr++ = wLUT[*gptr];
*sptr++ = wLUT[*rptr];
}
delete [] wLUT;
}
return((WORD*)m_pbm24);
}
//
if (nBitsPerPixel == 16)
{
if(NULL == m_pbm16)
m_pbm16= new WORD[((m_fbSize.cx*2+3) & ~3)*m_fbSize.cy];
ASSERT(NULL != m_pbm16);
UCHAR* rptr = m_pFB[RED]->getPointer(0,0);
UCHAR* gptr = m_pFB[GREEN]->getPointer(0,0);
UCHAR* bptr = m_pFB[BLUE]->getPointer(0,0);
WORD* sptr = m_pbm16;
if (m_dGamma == 1.0)
{
for (int i = 0; i < m_fbSize.cx*m_fbSize.cy; i++, rptr++, gptr++, bptr++)
{
// Assumes 16bit display ie. 5R:6G:5B format
*sptr++ = (WORD) ((((WORD)*bptr>>3)&0x001F) |
(((WORD)*gptr<<3)&0x07E0) |
(((WORD)*rptr<<8)&0xF800));
}
}
else
{
WORD* wLUT = new WORD[256];
for (int i = 0; i < 256; i++)
{
wLUT[i] = (WORD) (255.0 * pow((double) i / 255.0,1.0/m_dGamma) + 0.5);
if (wLUT[i] > 255)
wLUT[i] = 255;
}
for (i = 0; i < m_fbSize.cx*m_fbSize.cy; i++, rptr++, gptr++, bptr++)
{
// Assumes 16bit display ie. 5R:6G:5B format
*sptr++ = (WORD) (((wLUT[*bptr]>>3)&0x001F) |
((wLUT[*gptr]<<3)&0x07E0) |
((wLUT[*rptr]<<8)&0xF800));
}
delete [] wLUT;
}
return(m_pbm16);
}
// Bits per pixel must be wrong
return 0;
}
bool CImDisplay::CheckDisplaySize(CSize Imsize)
{
if (Imsize != m_Imsize) // resize the buffer
{
m_Imsize = Imsize;
// check the display capabilities
CDC* pDC;
pDC = m_pWnd->GetDC();
//Get the display capabilities
m_nBitPlanes = pDC->GetDeviceCaps( PLANES ); //Usually 1
m_nBitsPerPixel = pDC->GetDeviceCaps( BITSPIXEL );//Usually number of colours
m_pWnd->ReleaseDC(pDC);
if( m_nBitsPerPixel != 16 && m_nBitsPerPixel != 24 )
{
::MessageBox(::GetActiveWindow(),"Video mode is not compatable with\noutput resolution. Change Screen/Settings to 16 or 24 bits.","Unable to Display image", MB_ICONSTOP);
return false;
}
if (m_pBuf != 0)
delete [] m_pBuf;
m_pBuf = new UCHAR[m_Imsize.cx * m_Imsize.cy * m_nBitsPerPixel / 8];
if( !m_Map.CreateBitmap( m_Imsize.cx, m_Imsize.cy, m_nBitPlanes, m_nBitsPerPixel, m_pBuf ) )
::MessageBox(::GetActiveWindow(),"Can not create bitmap","Unable to Display image", MB_ICONSTOP);
}
return true;
}
void CImDisplay::Display(CFBuffer24* Image, CRect subRect)
{
CheckWindowPointer();
// Build the bastard bitmap
CSize imsize = Image->getBufferSize();
CheckDisplaySize(imsize);
// Write the Data to the Bit map
// Copies the image from our 24bit buffer into a bitmap and returns the pointer to the bitmap
DWORD dRet = m_Map.SetBitmapBits(imsize.cx*imsize.cy*m_nBitsPerPixel/8, Image->getBitmap(m_nBitsPerPixel) );
//Draw the bastard thing
CDC* pDC;
pDC = m_pWnd->GetDC();
CDC MemDC;
MemDC.CreateCompatibleDC( pDC );
CBitmap *pOldBitmap = MemDC.SelectObject( &m_Map );
pDC->SetStretchBltMode(COLORONCOLOR); // this gets the colours looking correct
pDC->StretchBlt( m_Location.TopLeft().x, m_Location.TopLeft().y,
m_Location.Width(), m_Location.Height(),
&MemDC, imSubRect.left, imSubRect.top,
imSubRect.Width(), imSubRect.Height(), SRCCOPY );
MemDC.SelectObject( pOldBitmap ); //Release the object
m_pWnd->ReleaseDC(pDC);
}
I run the program in compatibility 16bit colour on Windows 10. This is so it will actually run, and it runs fine otherwise.
I have been able to get something to display on Windows 10 when I have used CreateCompatibleBitmap() instead of CreateBitmap(), but the colours are all garbled. On Windows 7, they are fine. Perhaps this is a clue, but I can't work out what it means.
Your code can miscalculate required space for bitmaps if the width is not multiple of 4. It should be required_size = ( (width * bits_per_pixel / 8 + 3) & ~3 ) * height.
If CFBuffer24 handles stride (bytes per row) correctly, you can do stretching blit directly to device context:
void CImDisplay::Display(CFBuffer24* Image, CRect subRect)
{
CheckWindowPointer();
CDC* pDC = m_pWnd->GetDC();
m_nBitPlanes = pDC->GetDeviceCaps( PLANES ); //Usually 1
m_nBitsPerPixel = pDC->GetDeviceCaps( BITSPIXEL );
if( m_nBitsPerPixel != 16 && m_nBitsPerPixel != 24 && m_nBitsPerPixel != 32 )
{
::MessageBox(::GetActiveWindow(),"Video mode is not compatable with\noutput resolution. Change Screen/Settings to 16 or 24 bits.","Unable to Display image", MB_ICONSTOP);
return;
}
if ( m_nBitsPerPixel == 32 )
m_nBitsPerPixel = 24;
m_Imsize = Image->getBufferSize();
// Bitmap rows are aligned to multiplies of 4 bytes
int stride = (m_Imsize.cx * m_nBitsPerPixel / 8 + 3) & ~3;
BITMAPINFO bi =
{
sizeof( BITMAPINFOHEADER ),
stride,
-m_Imsize.cy, // If bitmap looks upside down remove minus
1,
m_nBitsPerPixel,
BI_RGB,
0,
0,
0,
0,
0
};
pDC->SetStretchBltMode(COLORONCOLOR);
::StretchDIBits(
pDC,
m_Location.TopLeft().x,
m_Location.TopLeft().y,
m_Location.Width(),
m_Location.Height(),
// !!!! I don't know what imSubRect is. Is it related to subRect?
imSubRect.left,
imSubRect.top,
imSubRect.Width(),
imSubRect.Height(),
Image->getBitmap(m_nBitsPerPixel),
&bi,
DIB_RGB_COLORS,
SRCCOPY );
m_pWnd->ReleaseDC(pDC);
}
Above code leaves conversion from 24 to 32 bits to the StretchDIBits. It should be OK performance wise. Alternatively you can implement 32 bit case in the CFBuffer24.

fill texture3d slice wise

I try to fill a texture3D slice wise with 2d images.
my result only gives me back the first of the 6 images like you can see in this picture:
to be sure that it is not a render problem like wrong uvw coordinates I also give you the picture of the uvw coordinates:
here is the code of the creation of the texture3d:
if (ETextureType::Texture3D == TextureType)
{
ID3D11Texture3D* pTexture3D = nullptr;
D3D11_TEXTURE3D_DESC TextureDesc;
ZeroMemory(&TextureDesc, sizeof(TextureDesc));
TextureDesc.Width = nWidth;
TextureDesc.Height = nHeight;
TextureDesc.MipLevels = nMipMaps;
TextureDesc.Depth = nDepth;
TextureDesc.Usage = D3D11_USAGE_DEFAULT;
TextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
switch (TextureFormat)
{
case ETextureFormat::R8G8B8A8:
{
TextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
}
break;
case ETextureFormat::R32FG32FB32FA32F:
{
TextureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
}
break;
default:
DebugAssertOnce(UNKNOWN_TEXTURE_FORMAT);
}
HRESULT hr = m_pD3D11Device->CreateTexture3D(&TextureDesc, nullptr, &pTexture3D);
if (FAILED(hr))
{
DebugAssertOnce(UNABLE_TO_CREATE_TEXTURE);
return false;
}
if (bCreateShaderResourceView)
{
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
ZeroMemory(&SRVDesc, sizeof(SRVDesc));
SRVDesc.Format = TextureDesc.Format;
SRVDesc.Texture3D.MipLevels = TextureDesc.MipLevels;
SRVDesc.Texture3D.MostDetailedMip = 0;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
hr = m_pD3D11Device->CreateShaderResourceView(pTexture3D, &SRVDesc, &pShaderResourceView);
if (FAILED(hr))
{
pTexture3D->Release();
DebugAssertOnce(UNABLE_TO_CREATE_SHADER_RESOURCE_VIEW);
return false;
}
}
else if (bCreateRenderTargetView)
{
ID3D11RenderTargetView* pRenderTargetView = nullptr;
hr = m_pD3D11Device->CreateRenderTargetView(pTexture3D, nullptr, &pRenderTargetView);
if (FAILED(hr))
{
pShaderResourceView->Release();
pTexture3D->Release();
DebugAssertOnce(UNABLE_TO_CREATE_RENDERTARGET_VIEW);
return false;
}
pView = pRenderTargetView;
}
*ppTexture = new CTextureDX11(TextureType, pTexture3D, pShaderResourceView, pView);
return true;
}
and also the filling part:
bool CGraphicsDriverDX11::CreateTexture3DFromImageBuffers(CTexture** ppTexture, const std::vector<CImageBuffer*>* pvecImageBuffers)
{
uint32_t nWidth = pvecImageBuffers->front()->GetWidth();
uint32_t nHeight = pvecImageBuffers->front()->GetHeight();
uint32_t nMipMapLevels = 1;
bool bRet = CreateTexture(ppTexture, nWidth, nHeight, ETextureType::Texture3D, ETextureFormat::R8G8B8A8, nMipMapLevels, false, true, false, static_cast<UINT>(pvecImageBuffers->size()));
if (bRet)
{
ID3D11Texture3D* pD3DTexture = static_cast<ID3D11Texture3D*>((*ppTexture)->GetTexture());
for (size_t nImageBuffer = 0; nImageBuffer < pvecImageBuffers->size(); ++nImageBuffer)
{
uint32_t nIndex = D3D11CalcSubresource(static_cast<UINT>(nImageBuffer), 0, 1);
m_pD3D11DeviceContext->UpdateSubresource(pD3DTexture, nIndex, nullptr, pvecImageBuffers->at(nImageBuffer)->GetData(), nWidth * 4, 0);
}
}
return bRet;
}
I tried a lot... for example I changed this code to texture2DArray and it worked fine. so the mistake is not my CImageBuffer class. also the nDepth variable has the correct value... I think I have to use another command for UpdateSubresource or at least change the parameters somehow.
I also didn't find some examples in the internet.
Thank you in advanced
All the depth textures in a slice are side-by-side in a single subresource. You also need to compute how many depth images are present in a slice for a given miplevel.
This gives you the subresource index which contains the entire slice:
D3D11CalcSubresource(level, 0, mipLevels);
This gives you the number of images in a slice for a given miplevel:
std::max(depth >> level, 1);
Each image in the slice has a pitch of D3D11_MAPPED_SUBRESOURCE.RowPitch laid out one after another in the subresource, with the total size in bytes of the slice as D3D11_MAPPED_SUBRESOURCE.DepthPitch.
For example, here is some code from DirectXTex trimmed down a bit to make it easier to read. It is reading the data out of a captured 3D volume texture, but the logic is the same when filling out textures.
if (metadata.IsVolumemap())
{
assert(metadata.arraySize == 1);
size_t height = metadata.height;
size_t depth = metadata.depth;
for (size_t level = 0; level < metadata.mipLevels; ++level)
{
UINT dindex = D3D11CalcSubresource(level, 0, metadata.mipLevels);
D3D11_MAPPED_SUBRESOURCE mapped;
HRESULT hr = pContext->Map(pSource, dindex, D3D11_MAP_READ, 0, &mapped);
if (FAILED(hr))
// error
auto pslice = reinterpret_cast<const uint8_t*>(mapped.pData);
size_t lines = ComputeScanlines(metadata.format, height);
// For uncompressed images, lines == height
for (size_t slice = 0; slice < depth; ++slice)
{
const Image* img = result.GetImage(level, 0, slice);
const uint8_t* sptr = pslice;
uint8_t* dptr = img->pixels;
for (size_t h = 0; h < lines; ++h)
{
size_t msize = std::min<size_t>(img->rowPitch, mapped.RowPitch);
memcpy_s(dptr, img->rowPitch, sptr, msize);
sptr += mapped.RowPitch;
dptr += img->rowPitch;
}
pslice += mapped.DepthPitch;
}
pContext->Unmap(pSource, dindex);
if (height > 1)
height >>= 1;
if (depth > 1)
depth >>= 1;
}
}

C++, DirecX 9: Render Self-made Vertex Struct

I'm new on StackOverflow and this is my first question.
I'm very new to C++ and DirectX9 so their may be a lot of Issues in my Code!
My Question:
I would like to Render an Structure of "D3DXVECTOR3"s for making a Heightmap from a .raw.
I have a working FP Camera System and want to implement a Heightmap. I followed the Tutorial "Terrain in DirectX9 and C++" (https://www.tutorials.de/threads/tutorial-terrain-in-directx-9-und-c-teil-1.343473/), but the Code don't work properly (The Tutorial is in "Bad" German, I used It because I didn't found any Tutorial for a Heightmap in DirectX9. ...And I'm german).
All it output is This (Ignore the Cylinder, it's only a test):
renderissue
Here are some relevant Parts of the Code:
Heightmap.cpp
BOOL LoadMapFromRAW(char* pcHMAP, UINT sizePerSide, BYTE **ppData)
{
BYTE *pData = NULL;
FILE *pFile = NULL;
// Open as Binary
pFile = fopen(pcHMAP, "rb");
if (!pFile)
return false;
// Memory
pData = new BYTE[sizePerSide*sizePerSide];
// Read
fread(&pData, 1, sizePerSide*sizePerSide, pFile);
*ppData = pData;
return true;
}
BOOL CreateVertices(UINT sizePerSide, BYTE *pVertexData, STerrainVector **ppVertices, UINT *uiTriangleCount)
{
UINT uiSizePerSide = sizePerSide - 1;
*uiTriangleCount = uiSizePerSide*uiSizePerSide*2;
// Memory for Vertices
STerrainVector *pVertices = new STerrainVector[(*uiTriangleCount) * 3];
// Buffer
int index = 0;
for (int x = 0; x < uiSizePerSide; x++)
for (int z = 0; z < uiSizePerSide; z++)
{
index += 6;
pVertices[index + 0].vPos = D3DXVECTOR3(x, pVertexData[z * sizePerSide + x], z);
pVertices[index + 1].vPos = D3DXVECTOR3(x, pVertexData[(z + 1) * sizePerSide + x], z + 1);
pVertices[index + 2].vPos = D3DXVECTOR3(x + 1, pVertexData[z * sizePerSide + x + 1], z);
pVertices[index + 3].vPos = D3DXVECTOR3(x + 1, pVertexData[(z) * sizePerSide + x + 1], z);
pVertices[index + 4].vPos = D3DXVECTOR3(x, pVertexData[(z + 1) * sizePerSide + x], z + 1);
pVertices[index + 5].vPos = D3DXVECTOR3(x + 1, pVertexData[(z + 1) * sizePerSide + x + 1], z + 1);
}
// Done
*ppVertices = pVertices;
return true;
}
main.cpp
//////////////UPDATE///////////////////
{
gDXdevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(160, 200, 255), 1.0f, 0);
gDXdevice->BeginScene();
// Get and set the view matrix
D3DXMATRIX viewMatrix;
gCamera->CalculateViewMatrix(&viewMatrix);
gDXdevice->SetTransform(D3DTS_VIEW, &viewMatrix)
// Draw Heightmap
gDXdevice->SetFVF(D3DFVF_XYZ);
gDXdevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, uiTriangleCount, (void*)&pVertices, sizeof(STerrainVector));
gDXdevice->EndScene();
gDXdevice->Present(0, 0, 0, 0);}
<pre> <code>
////////////////////////Part in Setup////////////////////////
bool SetupDirect3D(HWND hWnd)
{
// Standart Directx Init
gDX3dObject = Direct3DCreate9(D3D_SDK_VERSION);
if (!gDX3dObject)
return 0;
D3DPRESENT_PARAMETERS presParams;
ZeroMemory(&presParams, sizeof(presParams));
presParams.Windowed = TRUE;
presParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
presParams.BackBufferFormat = D3DFMT_UNKNOWN;
presParams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
presParams.EnableAutoDepthStencil = TRUE;
presParams.AutoDepthStencilFormat = D3DFMT_D16;
HRESULT hr = gDX3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &presParams, &gDXdevice);
if (FAILED(hr))
return false;
// Z-Buffer
gDXdevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
// Create a Model to View
hr = D3DXCreateCylinder(gDXdevice, 0.1f, 0.1f, 1.0f, 10, 10, &gCylinderMesh, 0);
if (FAILED(hr))
return false;
hr = D3DXCreatePolygon(gDXdevice, 10.0f, 4, &gPlateMesh, 0);
if (FAILED(hr))
return false;
// Light for Model
gDXdevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(20, 20, 20));
gDXdevice->SetRenderState(D3DRS_LIGHTING, TRUE);
// A light-structure
D3DLIGHT9 light;
ZeroMemory(&light, sizeof(D3DLIGHT9));
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse.a = 1.0f;
light.Diffuse.b = 1.0f;
light.Diffuse.g = 1.0f;
light.Diffuse.r = 1.0f;
light.Range = 1000.0f;
// Direction for Light
D3DXVECTOR3 vecDir;
vecDir = D3DXVECTOR3(0.0f, -0.3f, 0.7f);
D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &vecDir);
// Turn it on!
gDXdevice->SetLight(0, &light);
gDXdevice->LightEnable(0, TRUE);
// Create World
hr = LoadMapFromRAW("heightMap.raw", 1024, &pHeightData);
if (!hr)
return false;
hr = CreateVertices(1024, pHeightData, &pVertices, &uiTriangleCount);
if (!hr)
return false;
// Set up a Matrix
RECT rect;
GetClientRect(hWnd, &rect);
D3DXMATRIX matProj;
float aspect = (rect.right - rect.left) / (float)(rect.bottom - rect.top);
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, aspect, 1.0f, 100.0f);
gDXdevice->SetTransform(D3DTS_PROJECTION, &matProj);
return true;
}
....Had a Hard time with the Code.....
The "*pHeightData; *pVertices; uiTriangleCount" are defined at the start of the Code.
I Hope you can help me!
I apologize for the the bad english: I'm German and still in School! :-)
Thanks in Advance!
So... I solved by myself. The solution was: Complete rewrite! For anyone with the same/similar problem: http://www.riemers.net/eng/Tutorials/DirectX/C++/Series1/tut13.php That is a very good Tutorial I've found! Try It!

How to unlock a locked bitmap

I want to unlock a locked ID2D1Bitmap I have tried m_pBitmap1->Release(); but it doesn't seem to work
hr=m_pBitmap1->CopyFromRenderTarget(nullptr, m_pRenderTarget2, nullptr); gives an access violation error:
"Unhandled exception at 0x00fb2a46 in dent_detection_sys.exe: 0xC0000005: Access violation reading location 0x00000024."
WICRect rcLock = { 0, 0, sc_bitmapWidth , sc_bitmapHeight };
IWICBitmapLock *pILock=NULL;
hr =pWICBitmap->Lock(&rcLock, WICBitmapLockWrite, &pILock);
hr=pRT->CreateSharedBitmap(
IID_IWICBitmapLock,
static_cast<void *>(pILock),
&bp2,
&m_pBitmap1
);
hr=m_pBitmap1->Release();
hr=m_pBitmap1->CopyFromRenderTarget(nullptr, m_pRenderTarget2, nullptr);
To unlock the WIC bitmap, release the IWICBitmapLock:
pILock->Release();
You should only release m_pBitmap1 when you don't want to use it anymore.
hr=m_pBitmap1->CopyFromRenderTarget(nullptr, m_pRenderTarget2, nullptr);
hr=m_pBitmap1->Release();
According to the MSDN to use a shared WIC bitmap the render target type must be D2D1_RENDER_TARGET_TYPE_SOFTWARE when the render target is created.
cdemo is a structure object with basic d2d, wic, dwrite interface pointers.
example: cdemo->d2d.factory->CreateSomething(), cdemo->wic.factory->CreateSomething(), cdemo->dwrite.factory->CreateSomething, cdemo->xaudio.factory->CreateSomething, etc.
cbmp is a pointer to a structure that has interfaces and properties related to a WIC bitmap
The following example does not work as is without some tweaks and typo fixes, but it can be used to demonstrate how to use wic for editing a bitmap and directly accessing pixels
This code assumes that the cdemo->d2d.factory and cdemo->wic.factory are already created.
#define DEBUG_FAILED_GOTO(a,b) MessageBox(m_hwnd, a, L"FAILED", MB_OK); goto b
#define DEBUG_DISPLAY(a) MessageBox(m_hwnd, a, L"DEBUG", MB_OK)
#define USING_SHARED_WIC_BITMAP
#define USING_WIC_RENDER_TARGET
#define USING_WICBMP_COPY_TO_D2DBMP
struct COMMON_WIC_BGRA { BYTE b, g, r, a };
struct COMMON_WIC_BMP
{
//// Miscelaneous variables
bool ready;
bool using_d2d_bmp;
bool using_shared_bmp;
bool using_render_tgt;
bool ready_d2d_bmp;
bool ready_shared_bmp;
bool ready_render_tgt;
UINT BPPPP; // Bit-Per-Pixel-Per-Plane
UINT stride; // cbStride = row size;
UINT buff_size; // (org_size.y * stride);
POINT org_size, clip_TpLt, padding;
POINT cur_size, clip_BtRt;
D2D1_BITMAP_PROPERTIES props_bmp; // = D2D1::BitmapProperties();
D2D1_RENDER_TARGET_PROPERTIES props_tgt; // = D2D1::RenderTargetProperties();
WICPixelFormatGUID formatGUID; // = GUID_WICPixelFormat32bppPBGRA;
WICRect rc_lock; // the lock region, usually the entire
//// Interfaces
IWICBitmap* ifc_bmp; // WIC bitmap: lock and unlock bmp data;
IWICBitmapLock* ifc_lock; // Used to access the pixels to read/write
ID2D1RenderTarget* ifc_render_tgt; // Creates a d2d render target
ID2D1Bitmap* ifc_d2d_bmp; // creates an d2d bitmap for display
ID2D1Bitmap* ifc_shared_bmp; // creates a shared bitmap for display
ID2D1SolidColorBrush* ifc_render_brush; // This is needed for the render target
//// Data pointers
BYTE* byte; // Points to a pixel's byte; 8 bits
COMMON_WIC_BGRA* wpixel; // Points to a pixel; 32 bits
};
BOOL Lock_Release (COMON_WIC_BMP *cbmp);
BOOL Lock_Start (COMMON_INTERFACE_STUFF *cdemo, COMMON_WIC_BMP *cbmp, DWORD flags);
void Create_BMP_n_Stuff (
COMMON_INTERFACE_STUFF *cdemo,
COMMON_WIC_BMP *cbmp,
int org_xsize,
int org_ysize)
{
DEBUG_DISPLAY(L"Gate 0-1 Open: started xxx process");
if (cbmp == NULL) { return E_FAIL; }
if (cdemo == NULL) { return E_FAIL; }
DEBUG_DISPLAY(L"Gate 0-2 Open: passed the sanity test");
HRESULT hr = S_OK;
ZeroMemory(cbmp, sizeof(COMMON_WIC_BMP));
// Create a Direct2D render target.
if (cdemo->d2d.hwnd_tgt == NULL)
{
RECT rc;
GetClientRect(m_hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU((rc.right - rc.left), (rc.bottom - rc.top));
cdemo->d2d.props_tgt = D2D1::HwndRenderTargetProperties(m_hwnd, size);
cdemo->d2d.props_tgt_type = D2D1_RENDER_TARGET_TYPE_SOFTWARE;
cdemo->d2d.props_bmp = D2D1::BitmapProperties();
hr = cdemo->d2d.factory->CreateHwndRenderTarget(
cdemo->d2d.props_tgt_type,
cdemo->d2d.props_tgt,
&cdemo->d2d.hwnd_tgt);
if (FAILED(hr)) { goto CleanUp; }
}
DEBUG_DISPLAY(L"Gate 1 Open: hwnd_tgt created");
cbmp->ready = false; // type is: bool
// this option is compatible to D2D bitmap without conversion
cbmp->formatGUID = GUID_WICPixelFormat32bppPBGRA; // type is: WICPixelFormatGUID
cbmp->buff_size = 0; // type is: UINT32
cbmp->stride = 0; // type is: UINT32
cbmp->clip_TpLt.x = 0; // type is: POINT or POINTS
cbmp->clip_TpLt.y = 0;
cbmp->clip_BtRt.x = cbmp->org_size.x = org_xsize; // type is: POINT or POINTS
cbmp->clip_BtRt.y = cbmp->org_size.y = org_ysize;
cbmp->byte = NULL; // type is: pointer to BYTE, BYTE*
cbmp->pixel = NULL; // type is: pointer to COMMON_WIC_BGRA, COMMON_WIC_BGRA*
cbmp->ifc_bmp = NULL; // type is: IWICBitmap*
cbmp->ifc_d2d_bmp = NULL; // type is: ID2D1Bitmap*
cbmp->ifc_lock = NULL; // type is: IWICBitmapLock*
cbmp->ifc_shared_bmp = NULL; // type is: ID2D1Bitmap*
cbmp->ifc_render_tgt = NULL; // type is: ID2D1RenderTarget*
cbmp->ifc_render_brush = NULL; // type is: ID2D1SolidColorBrush*
//D2D1_BITMAP_PROPERTIES props_bmp; = D2D1::BitmapProperties();
//D2D1_RENDER_TARGET_PROPERTIES props_tgt; = D2D1::RenderTargetProperties();
//bool ready;
//bool using_d2d_bmp;
//bool using_shared_bmp;
//bool using_render_tgt;
//bool ready_d2d_bmp;
//bool ready_shared_bmp;
//bool ready_render_tgt;
//UINT BPPPP; // Bit-Per-Pixel-Per-Plane
if (cdemo->wic.factory == NULL)
{ // (re)create the WIC factory
hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
reinterpret_cast<void **>(&cdemo->wic.factory));
if (FAILED(hr)) { goto CleanUp; }
}
hr = cdemo->wic.factory->CreateBitmap(
cbmp->org_size.x,
cbmp->org_size.y,
cbmp->formatGUID,
WICBitmapCacheOnDemand,
&cbmp->ifc_bmp);
// Experimental debug
//if (FAILED(hr)) { DEBUG_FAILED_GOTO(L"FAILED creating wic bitmap", CleanUp); }
if (FAILED(hr)) { goto CleanUp; }
DEBUG_DISPLAY(L"Gate 2 Open: created the WIC bitmap");
// type is: WICRect;
cbmp->rc_lock = { 0, 0, (UINT)cbmp->org_size.x, (UINT)cbmp->org_size.y };
hr = cbmp->ifc_bmp->Lock(&cbmp->rc_lock, WICBitmapLockWrite, &cbmp->ifc_lock);
hr = cbmp->ifc_lock->GetStride(&cbmp->stride); //row size = (xsize*BPPP) + xpadding
hr = cbmp->ifc_lock->GetDataPointer(&cbmp->buff_size, &cbmp->byte);
cbmp->wpixel = (COMMON_WIC_BRGA *)cbmp->byte;
// clear the bitmap
ZeroMemory(cbmp->byte, cbmp->buff_size);
#ifdef USING_SHARED_WIC_BITMAP
cbmp->props_bmp = D2D1:BitmapProperties();
hr = demo->d2d.hwnd_tgt->CreateSharedBitmap(
IID_IWICBitmapLock,
(void*)cbmp->ifc_lock,
&cbmp->props_bmp,
&cbmp->ifc_shared_bmp);
if (SUCCEDED(hr))
{
cbmp->using_shared_bmp = true;
DEBUG_DISPLAY(L"Gate 4-1 Open: created shared wic bitmap");
}
#endif
#ifdef USING_WICBMP_COPY_TO_D2DBMP
hr = cdemo->d2d.factory->CreateBitmapFromWicBitmap(
cbmp->ifc_bmp,
&cbmp->props_bmp,
&cbmp->ifc_d2d_bmp);
if (SUCCEDED(hr))
{
cbmp->using_d2d_bmp = true;
DEBUG_DISPLAY(L"Gate 4-2 Open: created d2d bitmap ");
}
#endif
#ifdef USING_WIC_RENDER_TARGET
cbmp->props_tgt = D2D1::RenderTargetProperties();
cbmp->props_tgt.type = D2D1_RENDER_TARGET_TYPE_SOFTWARE;
hr = cdemo->d2d.factory->CreateWicBitmapRenderTarget(
cbmp->ifc_bmp,
&cbmp->props_tgt,
&cbmp->ifc_render_tgt);
if (SUCCEDED(hr))
{
hr = cbmp->ifc_render_tgt->CreateSolidColorBrush(
{ 1.0f, 1.0f, 1.0f, 1.0f }, // Solid white
&cbmp->ifc_render_brush);
cbmp->using_shared_bmp = true;
DEBUG_DISPLAY(L"Gate 4-3 Open: created wic render target and brush");
}
#endif
if (FAILED(hr)) { goto CleanUp; }
cbmp->ready = true;
// Rules of engagement if using all possible combinations above
// 1) After SafeRelease(&cbmp->ifc_lock) you cannot use cbmp->byte or cbmp->wpixel
// 2) To use cbmp->ifc_render_tgt you must first SafeRelease(cbmp->ifc_lock) and
// SafeRelease(&cbmp->ifc_shared_bmp). Later reinitialize them as needed.
// 3) To display the wic bitmap (cbmp->ifc_bmp) onto cdemo->d2d.hwnd_tgt:
// you cannot copy the wic bitmap (cbmp->ifc_bmp) directly to an hwnd render target
// option 1: This is whole point of creating the shared bmp
// cdemo->d2d.hwnd_tgt->DrawBMP( [ &dst_rc, ] cbmp->ifc_shared_bmp);
// option 2: Copy the pixels to the d2d bitmap, copy the d2d bitmap to the target
// cbmp->ifc_d2d_bmp->CopyFromMemory(cbmp->byte, &dst_rc, cbmp->stride);
// cdemo->d2d.hwnd_tgt->DrawBMP( [ &dst_rc, ] cbmp->ifc_d2d_bmp);
// option 3: Copy from the render target to the d2d bitmap
// cbmp->ifc_d2d_bmp->CopyFromRenderTarget(&pt_dst, cbmp->ifc_render_tgt, &src_rc);
// cdemo->d2d.hwnd_tgt->DrawBMP( [ &dst_rc, ] cbmp->ifc_d2d_bmp);
// 4) When drawing directly to the wic bitmap either use cbmp->ifc_render_tgt or
// cbmp->ifc_lock + cbmp->byte + your own algorithms to draw shapes
//
// 5) for simplicty: it can get confusing when trying to use all methods
option 1: use the ifc_lock with the ifc_shared_bmp + your own algorithms
option 2: use the ifc_render_tgt with the ifc_d2d_bmp
// Example: Draw a filled 12x15 rectangle example:
int x = 20, byte_col = 0, wpixel_col = 0, sizey = 12;
int y = 35, byte_row = 0, wpixel_row = 0, sizex = 15;
D2D1_COLOR_F d2d_colr = { 0.50f, 0.10f, 0.80f, 1.00f }; //some random color
COMMON_WIC_BGRA wic_colr = { 0, 0, 0, 0 };
D2D1_POINT_2U d2d_pt_dst_f = { 0, 0 };
D2D_RECT_F d2d_outputrect = { 0.0f, 0.0f, 0.0f, 0.0f };
D2D1_RECT_F d2d_dst_rcf =
{ 0.0f, 0.0f, (FLOAT)cbmp->org_size.x, (FLOAT)cbmp->org_size.y };
D2D1_RECT_U d2d_src_rcu =
{ 0, 0, (UINT32)cbmp->org_size.x, (UINT32)cbmp->org_size.y };
WIC_RECT_U wic_dst_rcu =
{ 0, 0, (UINT32)cbmp->org_size.x, (UINT32)cbmp->org_size.y };
WIC_RECT_U wic_src_rcu = wic_dst_rcu
// must release the lock and shared bitmap before using the render target
Lock_End(cbmp);
// This should look familiar
d2d_outputrect = { (FLOAT)x, (FLOAT)y, (FLOAT)(x+sizex-1), (FLOAT)(y+sizey-1) };
cbmp->ifc_render_tgt->BeginDraw();
cbmp->ifc_render_brush->SetColor(d2d_colr);
cbmp->ifc_render_tgt->SetTransform(D2D1::IdentityMatrix());
cbmp->ifc_render_tgt->FillRectangle(&d2d_outputrect, cbmp->ifc_render_brush);
hr = cbmp->ifc_render_tgt->EndDraw();
// display the wic bitmap on the hwnd render target
hr = cbmp->ifc_d2d_bmp->CopyFromRenderTarget(
&d2d_pt_dst,
cbmp->ifc_render_tgt,
&d2d_src_rc);
hr = cdemo->d2d.hwnd_tgt->DrawBMP(&d2d_dst_rc, cbmp->ifc_d2d_bmp);
// Alternative: using the ifc_lock with the ifc_shared_bmp + home grown algorithms
if (!Lock_Start(cdemo, cbmp, WICBitmapLockWrite)) { goto CleanUp; }
// convert D2D1_COLOR_F { b, g, r, a} to BYTE { b, g, r, a }
wic_colr.b = (BYTE)ceil(d2d_colr.b * 255);
wic_colr.g = (BYTE)ceil(d2d_colr.g * 255);
wic_colr.r = (BYTE)ceil(d2d_colr.r * 255);
wic_colr.a = (BYTE)ceil(d2d_colr.a * 255);
for (int run_y = 0; run_y < sizey; ++run_y)
{
// clipping for the y values
if (((run_y + y) < cbmp->clip_TpLt.y) || ((run_y + y) >= clip_BtRt.y))
{ continue; }
// convert the y to a byte position
byte_row = ((run_y + y) * cbmp->stride);
wpixel_row = ((run_y + y) * cbmp->org_size.x) + cbmp->padding.x; //optional
for (int run_x = 0; run_x < sizex; ++run_x)
{
// clipping for the x values
if (((run_x + x) < cbmp->clip_TpLt.x) || ((run_x + x) >= clip_BtRt.x))
{ continue; }
// convert the x to an offset position
byte_col = ((run_x + x) * 4); // must multiply by 4 bytes (b, g, r, a)
wpixel_col = (run_x + x); // cbmp->wpixel points to every 4 bytes
// access the pixels by means of pointer[(y_position + x_offset)]
cbmp->byte[(byte_row + byte_col + 0)] = wic_colr.b;
cbmp->byte[(byte_row + byte_col + 1)] = wic_colr.g;
cbmp->byte[(byte_row + byte_col + 2)] = wic_colr.r;
cbmp->byte[(byte_row + byte_col + 3)] = wic_colr.a;
cbmp->wpixel[(wpixel_row + wpixel_col)] = wic_colr; // Alternative
// Another method
cbmp->wpixel[(wpixel_row + wpixel_col)].b = wic_colr.b; // Alternatives
cbmp->wpixel[(wpixel_row + wpixel_col)].g = wic_colr.g; // Alternatives
cbmp->wpixel[(wpixel_row + wpixel_col)].r = wic_colr.r; // Alternatives
cbmp->wpixel[(wpixel_row + wpixel_col)].a = wic_colr.a; // Alternatives
}
}
// display the wic bitmap on the hwnd render target
cdemo->d2d.hwnd_tgt->DrawBMP(&dst_rc, cbmp->ifc_shared_bmp);
// Optionally release the lock after every use
// Lock_Release(cbmp);
return; // commnent out if cleanup is required
CleanUp:
// SafeRelease everything that needs to be released
}
BOOL Lock_Start (
COMMON_INTERFACE_STUFF *cdemo,
COMMON_WIC_BMP *cbmp,
DWORD flags)
{
if (cdemo == NULL) { return FALSE; }
//if (!cdemo->ready) { CreateResouces(cdemo); }
if (cbmp == NULL) { return FALSE; }
if (cbmp->ifc_lock != NULL) { return TRUE; }
SafeRelease(&cbmp->ifc_lock);
hr = cbmp->ifc_bmp->Lock(&cbmp->rc_lock, flags, &cbmp->ifc_lock);
if (FAILED(hr)) { return FALSE; }
hr = cbmp->ifc_lock->GetStride(&cbmp->stride);
hr = cbmp->ifc_lock->GetDataPointer(&cbmp->buff_size, &cbmp->byte);
cbmp->wpixel = (COMMON_WIC_BGRA *)cbmp->byte;
// recreate the shared bitmap
SafeRelease(&cbmp->ifc_shared_bmp);
hr = cdemo->d2d.factory->CreateSharedBitmap(
IID_IWICBitmapLock,
(void*)cbmp->ifc_lock,
&cbmp->props_bmp,
&cbmp->ifc_shared_bmp);
return TRUE;
}
BOOL Lock_Release (COMON_WIC_BMP *cbmp)
{
if (cbmp == NULL) { return FALSE; }
if (cbmp->ifc_lock == NULL) { return TRUE; }
SafeRelease(&cbmp->ifc_lock);
SafeRelease(&cbmp->ifc_shared_bmp);
cbmp->byte = NULL;
cbmp->wpixel = NULL;
if (cbmp->using_render_tgt) { cbmp->ready_render_tgt = true; }
return TRUE;
}

c++ DirectX function Present() not working

I'm working on simple graphic library in DirectX. I use Dx 9 because I'm pretty new in it and I have found a good programming book written for 9th version. Anyway, I can't get anything on the screen because Device's function Present() returns E_FAIL code 0x80004005 (which what I've read mean 'Unspecified failure').
I've also checked all Dx functions used in program and none of them returns fail (except Present() obviously).
The program works fine if I comment line kAnimation.Render() from main.cpp
Here's the causing problems part of code:
main.cpp:
//...
if(FAILED(g_pkD3DDevice->BeginScene())) return ErrorBeginScene;
kAnimation.Render();
if(FAILED(g_pkD3DDevice->EndScene())) return ErrorEndScene;
HRESULT hr;
hr = g_pkD3DDevice->Present(NULL, NULL, NULL, NULL); //Returns E_FAIL
if(FAILED(hr)) return ErrorPresent;
Animation.cpp:
#define D3DFVF_MYVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
Error Animation::Render()
{
//...
//This is what contain fX[4] and fY[4] and other variables while debugging
//float fX[4]
//float fY[4]
//fX[0] = -16; fX[1] = 16; fX[2] = -16; fX[3] = 16;
//fY[0] = 16; fY[1] = 16; fY[2] = -16; fY[3] = -16;
//m_iCellHeight = 32
//m_iCellWidth = 32
//m_iTextureWidth = 128
//m_iTextureHeight = 128
//kTextCoord.Left = 1/128; .Right = 33/128; .Top = 1/128; .Bottom = 33/128;
Rect kTextCoord = GetUV(CellID(0,0));
Vertex kVertices[] =
{ //x, y, z, w, color, texture coord (u, v)
{ fX[2], fY[2], 0, 1.0f, iColor, kTextCoord.Left, kTextCoord.Top},
{ fX[3], fY[3], 0, 1.0f, iColor, kTextCoord.Right, kTextCoord.Top},
{ fX[1], fY[1], 0, 1.0f, iColor, kTextCoord.Right, kTextCoord.Bottom},
{ fX[0], fY[0], 0, 1.0f, iColor, kTextCoord.Left, kTextCoord.Boottom},
};
g_D3DDevice->SetTexture(0, m_pkD3DTexture);
g_D3DDevice->SetFVF(D3DFVF_MYVERTEX);
if(FAILED(g_D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, kVertices, sizeof(Vertex)))
return ErrorDrawPrimitive;
return NoError;
}
Rect Animation::GetUV(CellID kPosition)
{
Rect kUVRect;
kUVRect.Left = (1 + ((1 + m_iCellWidth) * kPosition.x)) / m_iTextureWidth;
kUVRect.Right = (1 + ((1 + m_iCellWidth) * kPosition.x) + m_iCellWidth) / m_iTextureWidth;
kUVRect.Top = (1 + ((1 + m_iCellHeight) * kPosition.y)) / m_iTextureHeight;
kUVRect.Bottom =(1 + ((1 + m_iCellHeight) * kPosition.y) + m_iCellHeight) / m_iTextureHeight;
return kUVRect;
}
Rest you need:
class Rect
{
public:
float Left;
float Right;
float Top;
float Bottom;
};
//Position of single cell in animation texture
class CellID
{
public:
unsigned long x;
unsigned long y;
};
My operating system is Windows 7 Ultimate. I'm using VS c++ 2010
If you would like to see entire solution there's link: http://speedy.sh/CmBRb/ConWinLib.rar
(It's a bit different than that because I wanted to make code as short as I could)
Thank you for any help!
EDIT
Answering to your questions:
#tbridge The Device should be good because I created few small programs before and they were working prefectly. But anyway there's the code:
//...
g_pkD3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS kPresentParams;
unsigned long iDeviceType = D3DDEVTYPE_REF; //I have already checked D3DDEVTYPE_HAL and it doesn't work either
ZeroMemory(&kPresentParams, sizeof(D3DPRESENT_PARAMETERS));
kPresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
D3DDISPLAYMODE kCurrentMode;
if(FAILED(g_pkD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &kCurrentMode)))
return ErrorGetAdapterDisplayMode;
kPresentParams.Windowed = true;
kPresentParams.BackBufferCount = 1;
kPresentParams.BackBufferFormat = kCurrentMode.Format;
if(FAILED(g_pkD3D->CreateDevice(D3DADAPTER_DEFAULT, (D3DDEVTYPE)iDeviceType, hWindow,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &kPresentParams, &g_pkD3DDevice)))
return ErrorCreateDevice;
g_pkD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_pkD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_pkD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pkD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pkD3DDevice->SetRenderState(D3DRSDESTBLEND, D3DBLEND_INVSRCALPHA);
g_pkD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_pkD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
c