Hello, I'm trying to simply draw a square onto the screen...I have created a custom vertex struct for each of 4 vertices, and locked them into a vertex buffer...I have followed the tutorials to draw the primitives, however, when the program executes, I can see only a portion of the square in the upper left corner of the screen (also, I have a camera set up that can move around the 3D space with mouse and keyboard commands...the square stays in the corner of screen).
Is this because the square hasn't been transformed into World Space? How do I move the square into world space? Or fix this problem...here is my code: the function to create the square is within the TerrainTwo function of graphics.cpp
square.h:
[code]#define SQUAREFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
struct SQUARE {
float x, y, z, rhw;
DWORD color;
};
SQUARE vert[] =
{
{ -10.0f, -10.0f, 10.0f, 1.0f, D3DCOLOR_XRGB(0,0,0)},
{ -10.0f, 10.0f, 10.0f, 1.0f, D3DCOLOR_XRGB(0,0,0)},
{ 10.0f, 10.0f, 10.0f, 1.0f, D3DCOLOR_XRGB(0,0,0)},
{ 10.0f, -10.0f, 10.0f, 1.0f, D3DCOLOR_XRGB(0,0,0)},
};[/code]
graphics.cpp:
[code]#include "Graphics.h"
#include "3D Shapes.h"
#include "assert.h"
#include "Square.h"
#include "dxManager.h"
static dxManager& dxMgr = dxManager::getInstance();
CGraphics::CGraphics(IDirect3DDevice9 *device) : m_d3ddev(device), m_vertexBuffer(0)
{
for(unsigned int i = 0; i < sizeof(LPDIRECT3DTEXTURE9)/sizeof(m_textures); i++)
{
m_textures[i] = 0;
m_terrainVertexBuffer = NULL;
m_terrainIndexBuffer = NULL;
}
}
CGraphics::~CGraphics(void)
{
if(m_vertexBuffer)
{
m_vertexBuffer->Release();
m_vertexBuffer=0;
}
if(m_d3ddev)
{
m_d3ddev->Release();
m_d3ddev=0;
}
if(m_terrainVertexBuffer){
m_terrainVertexBuffer->Release();
m_terrainVertexBuffer=0;
}
if(m_terrainIndexBuffer){
m_terrainIndexBuffer->Release();
m_terrainIndexBuffer=0;
}
}
bool CGraphics::SkyBox(void)
{
HRESULT hr;
hr = m_d3ddev->CreateVertexBuffer(sizeof(TEXTUREVERTEX) * 24, 0, CUSTOMFVF, D3DPOOL_MANAGED,
&m_vertexBuffer, NULL);
if(FAILED(hr))
{
MessageBox(NULL, L"Failed to 'Create Vertex Buffer for SkyBox'", L"ERROR", MB_OK);
return false;
}
void* pVertices = NULL;
m_vertexBuffer->Lock(0, sizeof(TEXTUREVERTEX)*24, (void**)&pVertices, 0);
memcpy(pVertices, skyBox, sizeof(TEXTUREVERTEX)*24);
m_vertexBuffer->Unlock();
hr = D3DXCreateTextureFromFileA(m_d3ddev, fileF.c_str(), &m_textures[0]);
hr |= D3DXCreateTextureFromFileA(m_d3ddev, fileB.c_str(), &m_textures[1]);
hr |= D3DXCreateTextureFromFileA(m_d3ddev, fileL.c_str(), &m_textures[2]);
hr |= D3DXCreateTextureFromFileA(m_d3ddev, fileR.c_str(), &m_textures[3]);
hr |= D3DXCreateTextureFromFileA(m_d3ddev, fileTop.c_str(), &m_textures[4]);
hr |= D3DXCreateTextureFromFileA(m_d3ddev, fileBottom.c_str(), &m_textures[5]);
if ( FAILED(hr) )
{
MessageBox(NULL, L"Failed to open 1 or more images files!", L"Error Opening Texture Files", MB_OK);
return false;
}
return true;
}
void CGraphics::UpdateSkyBox(void)
{
D3DXMATRIX matView, matSave, matWorld;
m_d3ddev->GetTransform(D3DTS_VIEW, &matSave);
matView = matSave;
matView._41 = 0.0f; matView._42 = -0.4f; matView._43 = 0.0f;
m_d3ddev->SetTransform(D3DTS_VIEW, &matView);
D3DXMatrixIdentity(&matWorld);
m_d3ddev->SetTransform(D3DTS_WORLD, &matWorld);
RenderSkyBox();
m_d3ddev->SetTransform(D3DTS_VIEW, &matSave);
}
void CGraphics::RenderSkyBox(void)
{
m_d3ddev->SetRenderState(D3DRS_ZENABLE, false);
m_d3ddev->SetRenderState(D3DRS_ZWRITEENABLE, false);
m_d3ddev->SetRenderState(D3DRS_LIGHTING, false);
m_d3ddev->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
m_d3ddev->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
m_d3ddev->SetFVF(CUSTOMFVF);
m_d3ddev->SetStreamSource(0, m_vertexBuffer, 0, sizeof(TEXTUREVERTEX));
for(unsigned int i = 0; i < 6; i ++)
{
m_d3ddev->SetTexture(0, m_textures[i]);
m_d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, i*4, 2);
}
m_d3ddev->SetRenderState(D3DRS_ZENABLE, true);
m_d3ddev->SetRenderState(D3DRS_ZWRITEENABLE, true);
m_d3ddev->SetRenderState(D3DRS_LIGHTING, true);
}
bool CGraphics::TerrainTwo(D3DXVECTOR3 minB, D3DXVECTOR3 maxB, int numCellsW, int numCellsL)
{
HRESULT hr;
void* pVoid;
hr = m_d3ddev->CreateVertexBuffer(sizeof(SQUARE)*4,0,
CUSTOMFVF,D3DPOOL_DEFAULT,&m_terrainVertexBuffer,NULL);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Vertex Buffer", L"ERROR", MB_OK);
return false;
}
hr = m_terrainVertexBuffer->Lock(0, sizeof(SQUARE), (void**)&pVoid, NULL);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Lock Vertex Buffer", L"ERROR", MB_OK);
return false;
}
memcpy(pVoid, &vert, sizeof(vert));
m_terrainVertexBuffer->Unlock();
/*hr = m_d3ddev->CreateIndexBuffer(sizeof(DWORD)*sizeof(indices),0,
D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_terrainIndexBuffer, NULL);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Index Buffer", L"ERROR", MB_OK);
return false;
}
hr = m_terrainIndexBuffer->Lock(0, 0, (void**)&pVoid, 0);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Vertex Buffer", L"ERROR", MB_OK);
return false;
}
memcpy(pVoid, indices, sizeof(indices));
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Vertex Buffer", L"ERROR", MB_OK);
return false;
}
m_terrainIndexBuffer->Unlock();*/
return true;
}
bool CGraphics::Terrain(D3DXVECTOR3 minB, D3DXVECTOR3 maxB, int numCellsW, int numCellsL)
{
HRESULT hr = D3DXCreateTextureFromFileA(m_d3ddev, (LPCSTR)texFileTerrain.c_str(), &m_terrainTexture);
if(FAILED(hr))
{
MessageBox(NULL, L"Could not 'Load Texture(Terrain)'", L"ERROR", MB_OK);
return false;
}
TERRAIN terra = {minB,maxB,numCellsW,numCellsL,numCellsW+1,numCellsL+1,(maxB.x - minB.x)/numCellsW,
(maxB.z - minB.z)/numCellsL,
terra.vertices = new VERTEXARRAY[terra.numVertsX*terra.numVertsZ],
};
m_numVertices = terra.numVertsX*terra.numVertsZ;
m_numFaces = terra.numCellsX*terra.numCellsZ*2;
DWORD *indices = new DWORD[terra.numCellsX*terra.numCellsZ*6];
for(int i = 0; i < sizeof(indices); i++)
{
indices[i] = 0;
}
D3DXVECTOR3 pos(minB.x, 0, minB.z);
int vIter = 0;
for(int z = 0; z < terra.numVertsZ; z++)
{
for(int x = 0; x < terra.numVertsX; x++)
{
terra.vertices[vIter].x = 0;
terra.vertices[vIter].y = 0;
terra.vertices[vIter].z = 0;
terra.vertices[vIter].tu = 0;
terra.vertices[vIter].tv = 0;
vIter++;
}
}
double curTexPosZ = 1.0;
vIter=0;
for(double z = 0; z < (double)terra.numVertsZ; z++)
{
pos.x = minB.x;
curTexPosZ = (double)((double)terra.numCellsZ - z) / (double)(terra.numCellsZ);
for(double x = 0; x < terra.numVertsX; x++)
{
terra.vertices[vIter].x = pos.x;
terra.vertices[vIter].y = pos.y;
terra.vertices[vIter].z = pos.z;
//terra.vertices[vIter].color = D3DCOLOR_ARGB(0,255,255,255);
terra.vertices[vIter].rhw = 1.0f;
terra.vertices[vIter].tu = (float)(x / (double)terra.numCellsX);
terra.vertices[vIter].tv = (float)curTexPosZ;
pos.x += terra.stepX;
vIter++;
}
pos.z += terra.stepZ;
}
assert(vIter <= terra.numVertsX*terra.numVertsZ);
vIter = 0;
int iPos =0;
for(int z =0; z< terra.numCellsZ; z++)
{
for(int x = 0; x< terra.numCellsX; x++)
{
indices[iPos] = vIter; iPos++;
indices[iPos] = vIter+terra.numVertsX; iPos++;
indices[iPos] = vIter+terra.numVertsX+1; iPos++;
indices[iPos] = vIter; iPos++;
indices[iPos] = vIter+terra.numVertsX+1; iPos++;
indices[iPos] = vIter+1; iPos++;
vIter++;
}
vIter++;
}
assert(vIter <= terra.numCellsX*terra.numCellsZ*6);
void* pVoid;
hr = m_d3ddev->CreateVertexBuffer(sizeof(VERTEXARRAY)*terra.numVertsX*terra.numVertsZ,0,
CUSTOMFVF,D3DPOOL_MANAGED,&m_terrainVertexBuffer,NULL);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Vertex Buffer", L"ERROR", MB_OK);
return false;
}
hr = m_terrainVertexBuffer->Lock(0, 0, (void**)&pVoid, NULL);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Lock Vertex Buffer", L"ERROR", MB_OK);
return false;
}
memcpy(pVoid, terra.vertices, sizeof(terra.vertices));
m_terrainVertexBuffer->Unlock();
hr = m_d3ddev->CreateIndexBuffer(sizeof(DWORD)*sizeof(indices),0,
D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_terrainIndexBuffer, NULL);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Index Buffer", L"ERROR", MB_OK);
return false;
}
hr = m_terrainIndexBuffer->Lock(0, 0, (void**)&pVoid, 0);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Vertex Buffer", L"ERROR", MB_OK);
return false;
}
memcpy(pVoid, indices, sizeof(indices));
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Vertex Buffer", L"ERROR", MB_OK);
return false;
}
m_terrainIndexBuffer->Unlock();
return true;
}
void CGraphics::RenderTerrain(void)
{
//m_d3ddev->SetTexture(0, m_terrainTexture);
m_d3ddev->SetStreamSource(0, m_terrainVertexBuffer, 0, sizeof(VERTEXARRAYTWO));
//m_d3ddev->SetIndices(m_terrainIndexBuffer);
m_d3ddev->SetFVF(CUSTOMFVF);
m_d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
}[/code]
dxManager.h:
[code]#include ".dxmanager.h"
#include "Camera.h"
dxManager::dxManager(void)
{
d3d = NULL;
d3ddev = NULL;
pCam = NULL;
}
dxManager::~dxManager(void)
{
}
/********************************************************************
* init
* Initializes DirectX
********************************************************************/
bool dxManager::init(HWND hwnd)
{
if( NULL == ( d3d = Direct3DCreate9( D3D_SDK_VERSION ) ) )
{
MessageBox(NULL, L"Could Create D3D Object", L"ERROR", MB_OK);
return false;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.BackBufferCount = 1;
//d3dpp.BackBufferHeight = SCREEN_WIDTH;
//d3dpp.BackBufferWidth = SCREEN_HEIGHT;
d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.hDeviceWindow = hwnd;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
if( FAILED( d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &d3ddev ) ) )
{
if (FAILED( d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &d3ddev ) ) )
{
MessageBox(NULL, L"Could not create Direct 3D Device", L"ERROR", MB_OK);
return false;
}
}
//d3ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
// Setup basic render state
//d3ddev->SetRenderState( D3DRS_LIGHTING, TRUE );
d3ddev->SetRenderState( D3DRS_DITHERENABLE, TRUE );
d3ddev->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
d3ddev->SetRenderState( D3DRS_ZENABLE, TRUE );
d3ddev->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
d3ddev->SetRenderState( D3DRS_AMBIENT, 0x99999999 );
d3ddev->SetRenderState( D3DRS_NORMALIZENORMALS, FALSE );
// Setup states effecting texture rendering:
d3ddev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
d3ddev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3ddev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
d3ddev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
d3ddev->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
d3ddev->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
d3ddev->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
d3ddev->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
// Set the projection matrix
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1024.0f/768.0f, 1.0f, 5000.0f );
d3ddev->SetTransform( D3DTS_PROJECTION, &matProj );
// Lighting
d3ddev->SetRenderState( D3DRS_LIGHTING, TRUE );
// Create a directional light
D3DLIGHT9 light;
ZeroMemory( &light, sizeof(D3DLIGHT9) );
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse.r = 1.0f;
light.Diffuse.g = 1.0f;
light.Diffuse.b = 1.0f;
light.Diffuse.a = 1.0f;
light.Range = 1000.0f;
// Direction for our light - it must be normalized - pointing down and along z
D3DXVECTOR3 vecDir;
vecDir = D3DXVECTOR3(0.0f,-0.3f,0.5f);
D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );
d3ddev->SetLight( 0, &light );
d3ddev->LightEnable( 0, TRUE );
// Plus some non directional ambient lighting
d3ddev->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB(80,80,80));
pCam = new CCamera(D3DXVECTOR3(0,0,-5.0));
return true;
}
/********************************************************************
* shutdown
* Releases the DirectX interfaces
********************************************************************/
void dxManager::shutdown(void)
{
if( d3ddev != NULL)
{
d3ddev->Release();
d3ddev = NULL;
}
if( d3d != NULL)
{
d3d->Release();
d3d = NULL;
}
if(pCam){
delete pCam;
pCam=0;
}
}
/********************************************************************
* beginRender
* Prepares DirectX for rendering each frame
********************************************************************/
void dxManager::beginRender()
{
if( NULL == d3ddev )
return;
D3DXMATRIX matView;
pCam->CalculateViewMatrix(&matView);
d3ddev->SetTransform(D3DTS_VIEW, &matView);
// Clear the backbuffer to a black color
d3ddev->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 );
d3ddev->BeginScene();
}
/********************************************************************
* endRender
* Called after rendering has completed. Presents the result to the
* screen.
********************************************************************/
void dxManager::endRender(void)
{
d3ddev->EndScene();
// Present the backbuffer contents to the display
d3ddev->Present( NULL, NULL, NULL, NULL );
}
/********************************************************************
* getSurfaceFromBitmap
* Utility function to load in a bitmap
********************************************************************/
IDirect3DSurface9* dxManager::getSurfaceFromBitmap(LPCTSTR filename)
{
IDirect3DSurface9* surface = NULL;
D3DXIMAGE_INFO imageInfo;
// Get the width and height info from this bitmap
hr = D3DXGetImageInfoFromFile(filename, &imageInfo);
if FAILED (hr)
{
MessageBox(NULL, L"Could Not 'Load Image Info'", L"ERROR", MB_OK);
return NULL;
}
hr = d3ddev->CreateOffscreenPlainSurface(imageInfo.Width, imageInfo.Height, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
if (FAILED(hr))
return NULL;
hr = D3DXLoadSurfaceFromFile(surface, NULL, NULL, filename, NULL, D3DX_DEFAULT, 0, NULL);
if (FAILED(hr))
return NULL;
return surface;
}
/********************************************************************
* getBackBuffer
* Utility function used to return a pointer to the current back
* buffer
********************************************************************/
IDirect3DSurface9* dxManager::getBackBuffer(void)
{
IDirect3DSurface9* backbuffer = NULL;
if (!d3ddev)
return NULL;
hr = d3ddev->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, &backbuffer);
if (FAILED(hr))
{
MessageBox(NULL, L"Could not 'Get Back Buffer'", L"ERROR", MB_OK);
return NULL;
}
else
return backbuffer;
}
/********************************************************************
* blitToSurface
* Utility function used to copy an off screen surface to the back
* buffer
********************************************************************/
void dxManager::blitToSurface(IDirect3DSurface9* srcSurface, const RECT *srcRect, const RECT *destRect)
{
d3ddev->StretchRect(srcSurface, srcRect, getBackBuffer(), destRect, D3DTEXF_NONE);
}
/********************************************************************
* createVertexBuffer
* Utility function used to create a vertex buffer of a particular
* size and format.
********************************************************************/
LPDIRECT3DVERTEXBUFFER9 dxManager::createVertexBuffer(int size, DWORD usage)
{
LPDIRECT3DVERTEXBUFFER9 buffer;
// Create the vertex buffer.
if( FAILED(d3ddev->CreateVertexBuffer(size,0, usage,D3DPOOL_DEFAULT, &buffer, NULL )))
return NULL;
return buffer;
}[/code]
Are there any settings in dxManager.h that need to be changed? is it my rendering process? Any help would be appreciated! Thanks in advance!