I''m obviously a newbie to this, but I''ve been trying to get a textured quad to show up in DirectX 9 for the longest time.. and I don''t understand what I''m doing wrong. I have 2 classes that are supposed to do this, a Display class and a Sprite class. As of now, the display class holds a vertex buffer for 4 sprite vertices that ALL my sprite objects access (obviously there must do so one at a time). I don''t know if that actually makes things more efficient or not. Anyway here is the code (scattered across various functions in different classes):
Defined sprite vertex:
typedef struct
{
float x, y, z; // 3-D coordinates
DWORD diffuse; // diffuse color component
float u, v; // Texture coordinates
} spriteVertex;
#define SPRITEFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
The setting up stuff:
if (FAILED(_d3ddevice->CreateVertexBuffer( (sizeof (spriteVertex)) * 4, D3DUSAGE_WRITEONLY,
SPRITEFVF, D3DPOOL_MANAGED, &_spritevertexbuffer,
NULL)))
return FALSE;
// set stream source
if (FAILED (_d3ddevice->SetStreamSource(0, _spritevertexbuffer, 0, sizeof (spriteVertex))))
return FALSE;
if (FAILED (_d3ddevice->SetFVF(SPRITEFVF)))
return FALSE;
_d3ddevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
_d3ddevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
_d3ddevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
_d3ddevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
_d3ddevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
_d3ddevice->SetRenderState (D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
if (SetProjection( 1.0f, 1000.0f) == FALSE)
return FALSE;
SetZBuffer (_zbuffer);
if (SetAlphaTest (TRUE) == FALSE)
return FALSE;
// set up view matrix, temporarily to some default
D3DXMATRIX view;
D3DXVECTOR3 eye (0.0f, 0.0f, -1.0f), at(0.0f, 0.0f, 0.0f), up (0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&view, &eye, &at, &up);
if (FAILED (_d3ddevice->SetTransform(D3DTS_VIEW, &view)))
{
return FALSE;
}
// end default set up
if (FAILED (_d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0,0,0,0), 1.0f, 0)))
return FALSE;
return (SUCCEEDED(_d3ddevice->BeginScene()));
My SetProjection function:
D3DXMATRIX projection;
float ratio = (float) _width / (float) _height;
D3DXMatrixPerspectiveFovLH ( &projection , (float) (D3DX_PI / 4.0f), ratio, nearZ, farZ );
return (SUCCEEDED (_d3ddevice->SetTransform(D3DTS_PROJECTION, &projection)));
my setalphatest function:
if (test == _alphatest) // <-- was already set that means
return TRUE;
if (FAILED (_d3ddevice->SetRenderState(D3DRS_ALPHATESTENABLE, test)))
{
return FALSE;
}
if (test == TRUE)
{
if (FAILED (_d3ddevice->SetRenderState(D3DRS_ALPHAREF, 0x08)))
{
return FALSE;
}
if (FAILED (_d3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL)))
{
return FALSE;
}
}
_alphatest = test;
return TRUE;
the sprite is created this way:
if (FAILED (D3DXCreateTextureFromFileEx (display->GetDevice(), filename,
D3DX_DEFAULT, D3DX_DEFAULT, numMipMaps, 0,
display->BPPtoFormat(bpp), D3DPOOL_MANAGED,
filter, filter, _transparent, &info, NULL, &_texture)))
return FALSE;
_width = width;
_height = height;
_totalwidth = info.Width;
_totalheight = info.Height;
and the function for drawing the sprite goes like this:
RECT spriteRect;
spriteVertex * pointer;
D3DXMATRIX translation, x_rotation, y_rotation, z_rotation, scale, world;
spriteRect.left = (_frame % (_totalwidth / _width)) * (_width + 1);
spriteRect.right = spriteRect.left + _width;
spriteRect.top = (int) (_frame / (_totalwidth / _width)) * (_height + 1);
spriteRect.bottom = spriteRect.top + _height;
spriteVertex vertices[4] =
{
{ 0.0f, 0.0f, 0.0f, 0xffffffff, (float)spriteRect.left / (float)_totalwidth, (float)spriteRect.top / (float)_totalheight }, // x, y, z, color, u, v (texture coords)
{ (float) _width, 0.0f, 0.0f, 0xffffffff, (float)spriteRect.right / (float)_totalwidth, (float)spriteRect.top / (float)_totalheight },
{ (float) _width, (float) _height, 0.0f, 0xffffffff, (float)spriteRect.right / (float)_totalwidth, (float)spriteRect.bottom / (float)_totalheight },
{ 0.0f, (float) _height, 0.0f, 0xffffffff, (float)spriteRect.left / (float)_totalwidth, (float)spriteRect.bottom / (float)_totalheight },
};
int i = 3;
UINT size = sizeof(vertices);
if (FAILED(_display->GetSpriteVertexBuffer()->Lock(0, 0, (void**)&pointer, 0)))
return FALSE;
memcpy(pointer, vertices, size);
if (FAILED (_display->GetSpriteVertexBuffer()->Unlock()))
return FALSE;
if (_display->SetAlphaTest(TRUE) == FALSE)
return FALSE;
if (FAILED (_display->GetDevice()->SetTexture(0, _texture)))
return FALSE;
// ** set world transform
D3DXMatrixTranslation(&translation, x, y, z);
D3DXMatrixRotationX(&x_rotation, xAngle);
D3DXMatrixRotationY(&y_rotation, yAngle);
D3DXMatrixRotationZ(&z_rotation, 0.0f);
D3DXMatrixScaling(&scale, 1.0f, 1.0f, 1.0f);
D3DXMatrixIdentity(&world);
D3DXMatrixMultiply(&world, &world, &scale);
D3DXMatrixMultiply(&world, &world, &x_rotation);
D3DXMatrixMultiply(&world, &world, &y_rotation);
D3DXMatrixMultiply(&world, &world, &z_rotation);
D3DXMatrixMultiply(&world, &world, &translation);
if (FAILED (_display->GetDevice()->SetTransform(D3DTS_WORLD, &world)))
return FALSE;
// ** done set world transform **
if (FAILED (_display->GetDevice()->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2)))
{
return FALSE;
}
if (_display->SetAlphaTest(FALSE) == FALSE)
return FALSE;
Finally:
if (SetAlphaTest(FALSE) == FALSE)
return FALSE;
if (FAILED (_d3ddevice->EndScene()))
return FALSE;
return (SUCCEEDED (_d3ddevice->Present(NULL, NULL, NULL, NULL)));
So the flow of the test program creates a display object, a test sprite object w/ an arbitrary texture, then calls setup, sprite drawing, then wrapup. It seems like it should work (the sprite quad is world transformed to the origin, and the camera is positioned at -1.0f on the z axis, looking at the origin), but nothing shows, just a black screen. Can anybody help me out?