codesamples >> crossplatform cube class

Crossplatform: Cube class

Project:

Crossplatform application (Windows & PS3)

Engine:

Custom

Code language:

C++

Class description:

The cube class for Windows and PS3.

Cube.cpp

#include "Cube.h"
#include "Camera.h"

#if defined(WIN32)
ID3D11Buffer* Cube::m_pVertexBuffer = 0;
ID3D11Buffer* Cube::m_pIndexBuffer = 0;
#endif 

// Constructor
Cube::Cube()
{
	m_Vertices = 8;
	m_Indices = 36;
}

// Destructor
Cube::~Cube()
{
}

bool Cube::InitializeData(DEVICE* device)
{
	// setup data for the construction 
	GeometryTriangles	srcData;

	srcData.AddVertex(-1.0f,  1.0f, -1.0f); // 0
	srcData.AddVertex(1.0f,  1.0f, -1.0f); // 1
	srcData.AddVertex(1.0f, -1.0f, -1.0f); // 2
	srcData.AddVertex(-1.0f, -1.0f, -1.0f); // 3

	srcData.AddVertex(-1.0f,  1.0f,  1.0f); // 4
	srcData.AddVertex(1.0f,  1.0f,  1.0f); // 5
	srcData.AddVertex(1.0f, -1.0f,  1.0f); // 6
	srcData.AddVertex(-1.0f, -1.0f,  1.0f); // 7

	// front face
	srcData.AddTriangle(0, 1, 2);
	srcData.AddTriangle(2, 3, 0);

	// back face
	srcData.AddTriangle(5, 4, 7);
	srcData.AddTriangle(7, 6, 5);

	// left face
	srcData.AddTriangle(4, 0, 3);
	srcData.AddTriangle(3, 7, 4);

	// right face
	srcData.AddTriangle(1, 5, 6);
	srcData.AddTriangle(6, 2, 1);

	// top face
	srcData.AddTriangle(4, 5, 1);
	srcData.AddTriangle(1, 0, 4);

#if defined(PS3)
	m_VertexCount = srcData.GetIndices().size();

	// allocate vertex buffer
	uint32_t vsize = sizeof(Vertex_PS3);
	uint32_t vertexBufferOffset;       // this is vidmem

	m_VertexBuffer = (Vertex_PS3 *)cellGcmUtilAllocateLocalMemory(vsize*m_VertexCount, 128);
	assert(m_VertexBuffer != NULL);
	CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(m_VertexBuffer, &vertexBufferOffset));

	printf("g_VertexBufferOffset:0x%08x\n", vertexBufferOffset);

	//m_VertexCount = GenerateCube(m_VertexBuffer);
	Vertex_PS3 * curBuf = m_VertexBuffer;
	Vertex * vertex;
	// make sure the number of indices is a multiple of 3
	assert((srcData.GetIndices().size()/3)*3 == srcData.GetIndices().size()); 
    

	// fill out the buffer for the shaders
	for(unsigned int numIndex=0; numIndex < srcData.GetIndices().size()  ; numIndex++ )
	{
		vertex = srcData.GetVertexAtIndex( srcData.GetIndices()[ numIndex ] );
		curBuf->Px = vertex->m_x; 
		curBuf->Py = vertex->m_y; 
		curBuf->Pz = vertex->m_z; 
		curBuf->RGBA = 0xFFFFFFFF; 
		curBuf->u = 0.0f; 
		curBuf->v = 0.0f; 
		curBuf++;
	}

#elif(WIN32)

	int numVertices = srcData.GetVertices().size();
	int numIndices = srcData.GetIndices().size();

	D3D11_BUFFER_DESC bd;
	ZeroMemory(&bd, sizeof(bd));
   
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(Vertex) * numVertices;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;

	D3D11_SUBRESOURCE_DATA InitData;
	ZeroMemory(&InitData, sizeof(InitData));

	InitData.pSysMem = &srcData.GetVertices()[0];
	// Create Vertex buffer
	device->GetDevice()->CreateBuffer(&bd, &InitData, &m_pVertexBuffer);

	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(INDEX) * numIndices;
	bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
	bd.CPUAccessFlags = 0;
	InitData.pSysMem = &srcData.GetIndices()[0];
	// Create Index buffer
	device->GetDevice()->CreateBuffer(&bd, &InitData, &m_pIndexBuffer);

#endif

	return true;
}

void Cube::SetLOD(int lod)
{
	//...
}

#if defined(WIN32)
void Cube::Render(Camera* camera, ID3D11DeviceContext* deviceContext, ID3D11VertexShader* vertexShader, 
ID3D11PixelShader* pixelShader, float time)
{
	// Render the cube

	// Rotate cube around the origin
	XMMATRIX mObj;

	// Update variables that change once per frame

	// Set vertex buffer
	UINT stride = sizeof(Vertex);
	UINT offset = 0;
	deviceContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);
	
	// Set index buffer
	deviceContext->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);

	// Set primitive topology
	deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	Update(camera, time);

	mObj = XMMatrixRotationRollPitchYaw(m_AngleX, m_AngleY, m_AngleZ);

	mObj.m[3][0] = m_PosX;
	mObj.m[3][1] = m_PosY;
	mObj.m[3][2] = m_PosZ;
	mObj.m[3][3] = 1.0f;

	CBChangesEveryFrame cb;
	cb.mWorld = XMMatrixTranspose(mObj);
	deviceContext->UpdateSubresource(camera->GetpCBChangesEveryFrame(), 0, NULL, &cb, 0, 0);

	deviceContext->VSSetShader(vertexShader, NULL, 0); 
	deviceContext->VSSetConstantBuffers(0, 1, &camera->GetpCBNeverChanges());
	deviceContext->VSSetConstantBuffers(1, 1, &camera->GetpCBChangeOnResize());

	deviceContext->VSSetConstantBuffers(2, 1, &camera->GetpCBChangesEveryFrame());

	deviceContext->PSSetShader(pixelShader, NULL, 0);
	deviceContext->PSSetConstantBuffers(2, 1, &camera->GetpCBChangesEveryFrame());

	deviceContext->DrawIndexed(m_Indices, 0, 0);
}

void Cube::SetIndexBuffer(ID3D11Buffer* indexBuffer)
{
	m_pIndexBuffer = indexBuffer;
}

void Cube::SetVertexBuffer(ID3D11Buffer* vertexBuffer)
{
	m_pVertexBuffer = vertexBuffer;
}
#endif

#if defined(PS3)


void Cube::Render(Camera* camera, CGprogram cGVertexProgram, CGprogram cGFragmentProgram, 
void* vertexProgramUCode, void* fragmentProgramUCode)
{
	float MLocal[16];
	float MVP[16];

	camera->EulerRotate(MLocal, m_AngleX, m_AngleY, m_AngleZ); 
	MLocal[0*4+3] = m_PosX;
	MLocal[1*4+3] = m_PosY;
	MLocal[2*4+3] = m_PosZ; 

	camera->MatrixMul(MVP, &camera->GetView().m[0][0], MLocal);  
	camera->MatrixMul(MVP, camera->m_MVP, MVP);

	// set uniform variables 
	// NOTE: this modifies the ucode but currently the ucode is inlined into the push buffer
	CGparameter modelViewProj = cellGcmCgGetNamedParameter(cGVertexProgram, "modelViewProj");
	CGparameter objCoord    = cellGcmCgGetNamedParameter(cGVertexProgram, "a2v.objCoord");

	CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT( modelViewProj );
	CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT( objCoord );

	cellGcmSetVertexProgramParameter(modelViewProj, MVP);

	// get Vertex Attribute index
	uint32_t ObjCoordIndex = cellGcmCgGetParameterResource(cGVertexProgram, objCoord) - CG_ATTR0; 

	// bind the shaders
	// NOTE: vertex program constants are copied here
	cellGcmSetVertexProgram(cGVertexProgram, vertexProgramUCode);

	uint32_t fragment_offset;
	CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(fragmentProgramUCode, &fragment_offset));
	cellGcmSetFragmentProgram(cGFragmentProgram, fragment_offset);

	uint32_t vertex_offset[3];
	CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(&m_VertexBuffer->Px, &vertex_offset[0]));
	CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(&m_VertexBuffer->RGBA, &vertex_offset[1]));
	CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(&m_VertexBuffer->u, &vertex_offset[2]));

	// set vertex pointer
	cellGcmSetVertexDataArray(ObjCoordIndex, 0, sizeof(Vertex_PS3), 3,
	CELL_GCM_VERTEX_F, CELL_GCM_LOCATION_LOCAL, vertex_offset[0]);

	// draw
	cellGcmSetDrawArrays(CELL_GCM_PRIMITIVE_TRIANGLES, 0, m_VertexCount);
}
#endif

Cube.h

#ifndef _CUBE_H
#define _CUBE_H

// Crossplatform: Includes
#include "Structs.h"
#include "GeometryTriangles.h"
#include "Primitive.h"

// PS3 Specific: Defines & Includes
#if defined(PS3)
#define __CELL_ASSERT__

#include "gcmutil.h"

using namespace cell::Gcm;
#endif

// DEVICE definition
#if defined(WIN32)
#include "Device_Win32.h"
#elif(PS3)
#include "Device_PS3.h"
#endif

class Camera;

class Cube: public Primitive
{
public:

	// Crossplatform: Functions
	Cube();
	virtual ~Cube();
	virtual void SetLOD(int lod);
	bool InitializeData(DEVICE* device);

	#if defined(WIN32)
	// Windows Specific: Functions
	void Render(Camera* camera, ID3D11DeviceContext* deviceContext, ID3D11VertexShader* vertexShader, 
	ID3D11PixelShader* pixelShader, float time);
	void SetIndexBuffer(ID3D11Buffer* indexBuffer);
	void SetVertexBuffer(ID3D11Buffer* vertexBuffer);
	#endif

	#if defined(PS3)
	// PS3 Specific: Functions
	void Render(Camera* camera, CGprogram cGVertexProgram, CGprogram cGFragmentProgram, 
	void* vertexProgramUCode, void* fragmentProgramUCode);
	#endif

private:
	#if defined(PS3)
	// PS3 Specific: Datamembers			
	Vertex_PS3 *	m_VertexBuffer;
	uint32_t	m_VertexCount;
	#endif

	#if defined(WIN32)
	// Windows Specific: Datamembers
	int	m_Vertices;
	int	m_Indices;
	static ID3D11Buffer* m_pVertexBuffer;
	static ID3D11Buffer* m_pIndexBuffer;
	#endif
};
#endif