Creating the Scene

The CreateScene function creates the elements making up the 3-D scene. In this sample, the scene consists of a single light, the viewport, the background and surface materials, the three transformation matrices, and the execute buffer holding the state changes and drawing primitives.

static HRESULT

CreateScene(void)

{

HRESULT hRes;

D3DMATERIAL d3dMaterial;

D3DLIGHT d3dLight;

DWORD dwVertexSize;

DWORD dwInstructionSize;

DWORD dwExecuteBufferSize;

D3DEXECUTEBUFFERDESC d3dExecuteBufferDesc;

D3DEXECUTEDATA d3dExecuteData;

ASSERT(NULL != lpd3d);

ASSERT(NULL != lpd3dDevice);

ASSERT(NULL == lpd3dViewport);

ASSERT(NULL == lpd3dMaterial);

ASSERT(NULL == lpd3dBackgroundMaterial);

ASSERT(NULL == lpd3dExecuteBuffer);

ASSERT(NULL == lpd3dLight);

ASSERT(0 == hd3dWorldMatrix);

ASSERT(0 == hd3dViewMatrix);

ASSERT(0 == hd3dProjMatrix);

// Create the light.

hRes = lpd3d->lpVtbl->CreateLight(lpd3d, &lpd3dLight, NULL);

if (FAILED(hRes))

return hRes;

ZeroMemory(&d3dLight, sizeof(d3dLight));

d3dLight.dwSize = sizeof(d3dLight);

d3dLight.dltType = D3DLIGHT_POINT;

d3dLight.dcvColor.dvR = D3DVAL( 1.0);

d3dLight.dcvColor.dvG = D3DVAL( 1.0);

d3dLight.dcvColor.dvB = D3DVAL( 1.0);

d3dLight.dcvColor.dvA = D3DVAL( 1.0);

d3dLight.dvPosition.dvX = D3DVAL( 1.0);

d3dLight.dvPosition.dvY = D3DVAL(-1.0);

d3dLight.dvPosition.dvZ = D3DVAL(-1.0);

d3dLight.dvAttenuation0 = D3DVAL( 1.0);

d3dLight.dvAttenuation1 = D3DVAL( 0.1);

d3dLight.dvAttenuation2 = D3DVAL( 0.0);

hRes = lpd3dLight->lpVtbl->SetLight(lpd3dLight, &d3dLight);

if (FAILED(hRes))

return hRes;

// Create the background material.

hRes = lpd3d->lpVtbl->CreateMaterial(lpd3d,

&lpd3dBackgroundMaterial, NULL);

if (FAILED(hRes))

return hRes;

ZeroMemory(&d3dMaterial, sizeof(d3dMaterial));

d3dMaterial.dwSize = sizeof(d3dMaterial);

d3dMaterial.dcvDiffuse.r = D3DVAL(0.0);

d3dMaterial.dcvDiffuse.g = D3DVAL(0.0);

d3dMaterial.dcvDiffuse.b = D3DVAL(0.0);

d3dMaterial.dcvAmbient.r = D3DVAL(0.0);

d3dMaterial.dcvAmbient.g = D3DVAL(0.0);

d3dMaterial.dcvAmbient.b = D3DVAL(0.0);

d3dMaterial.dcvSpecular.r = D3DVAL(0.0);

d3dMaterial.dcvSpecular.g = D3DVAL(0.0);

d3dMaterial.dcvSpecular.b = D3DVAL(0.0);

d3dMaterial.dvPower = D3DVAL(0.0);

// Since this is the background material, we don't want a ramp to be

// allocated. (We will not be smooth-shading the background.)

d3dMaterial.dwRampSize = 1;

hRes = lpd3dBackgroundMaterial->lpVtbl->SetMaterial

(lpd3dBackgroundMaterial, &d3dMaterial);

if (FAILED(hRes))

return hRes;

hRes = lpd3dBackgroundMaterial->lpVtbl->GetHandle

(lpd3dBackgroundMaterial, lpd3dDevice, &hd3dBackgroundMaterial);

if (FAILED(hRes))

return hRes;

// Create the viewport.

// The viewport parameters are set in the UpdateViewport function,

// which is called in response to WM_SIZE.

hRes = lpd3d->lpVtbl->CreateViewport(lpd3d, &lpd3dViewport, NULL);

if (FAILED(hRes))

return hRes;

hRes = lpd3dDevice->lpVtbl->AddViewport(lpd3dDevice, lpd3dViewport);

if (FAILED(hRes))

return hRes;

hRes = lpd3dViewport->lpVtbl->SetBackground(lpd3dViewport,

hd3dBackgroundMaterial);

if (FAILED(hRes))

return hRes;

hRes = lpd3dViewport->lpVtbl->AddLight(lpd3dViewport, lpd3dLight);

if (FAILED(hRes))

return hRes;

// Create the matrices.

hRes = lpd3dDevice->lpVtbl->CreateMatrix(lpd3dDevice,

&hd3dWorldMatrix);

if (FAILED(hRes))

return hRes;

hRes = lpd3dDevice->lpVtbl->SetMatrix(lpd3dDevice, hd3dWorldMatrix,

&d3dWorldMatrix);

if (FAILED(hRes))

return hRes;

hRes = lpd3dDevice->lpVtbl->CreateMatrix(lpd3dDevice,

&hd3dViewMatrix);

if (FAILED(hRes))

return hRes;

hRes = lpd3dDevice->lpVtbl->SetMatrix(lpd3dDevice, hd3dViewMatrix,

&d3dViewMatrix);

if (FAILED(hRes))

return hRes;

hRes = lpd3dDevice->lpVtbl->CreateMatrix(lpd3dDevice,

&hd3dProjMatrix);

if (FAILED(hRes))

return hRes;

SetPerspectiveProjection(&d3dProjMatrix, HALF_HEIGHT, FRONT_CLIP,

BACK_CLIP);

hRes = lpd3dDevice->lpVtbl->SetMatrix(lpd3dDevice, hd3dProjMatrix,

&d3dProjMatrix);

if (FAILED(hRes))

return hRes;

// Create the surface material.

hRes = lpd3d->lpVtbl->CreateMaterial(lpd3d, &lpd3dMaterial, NULL);

if (FAILED(hRes))

return hRes;

ZeroMemory(&d3dMaterial, sizeof(d3dMaterial));

d3dMaterial.dwSize = sizeof(d3dMaterial);

// Base green with white specular.

d3dMaterial.dcvDiffuse.r = D3DVAL(0.0);

d3dMaterial.dcvDiffuse.g = D3DVAL(1.0);

d3dMaterial.dcvDiffuse.b = D3DVAL(0.0);

d3dMaterial.dcvAmbient.r = D3DVAL(0.0);

d3dMaterial.dcvAmbient.g = D3DVAL(0.4);

d3dMaterial.dcvAmbient.b = D3DVAL(0.0);

d3dMaterial.dcvSpecular.r = D3DVAL(1.0);

d3dMaterial.dcvSpecular.g = D3DVAL(1.0);

d3dMaterial.dcvSpecular.b = D3DVAL(1.0);

d3dMaterial.dvPower = D3DVAL(20.0);

d3dMaterial.dwRampSize = 16;

hRes = lpd3dMaterial->lpVtbl->SetMaterial(lpd3dMaterial,

&d3dMaterial);

if (FAILED(hRes))

return hRes;

hRes = lpd3dMaterial->lpVtbl->GetHandle(lpd3dMaterial, lpd3dDevice,

&hd3dSurfaceMaterial);

if (FAILED(hRes))

return hRes;

// Build the execute buffer.

dwVertexSize = (NUM_VERTICES * sizeof(D3DVERTEX));

dwInstructionSize = (NUM_INSTRUCTIONS * sizeof(D3DINSTRUCTION)) +

(NUM_STATES * sizeof(D3DSTATE)) +

(NUM_PROCESSVERTICES *

sizeof(D3DPROCESSVERTICES)) +

(NUM_TRIANGLES * sizeof(D3DTRIANGLE));

dwExecuteBufferSize = dwVertexSize + dwInstructionSize;

ZeroMemory(&d3dExecuteBufferDesc, sizeof(d3dExecuteBufferDesc));

d3dExecuteBufferDesc.dwSize = sizeof(d3dExecuteBufferDesc);

d3dExecuteBufferDesc.dwFlags = D3DDEB_BUFSIZE;

d3dExecuteBufferDesc.dwBufferSize = dwExecuteBufferSize;

hRes = lpd3dDevice->lpVtbl->CreateExecuteBuffer(lpd3dDevice,

&d3dExecuteBufferDesc, &lpd3dExecuteBuffer, NULL);

if (FAILED(hRes))

return hRes;

// Fill the execute buffer with the required vertices, state

// instructions and drawing primitives.

hRes = FillExecuteBuffer();

if (FAILED(hRes))

return hRes;

// Set the execute data so Direct3D knows how many vertices are in

// the buffer and where the instructions start.

ZeroMemory(&d3dExecuteData, sizeof(d3dExecuteData));

d3dExecuteData.dwSize = sizeof(d3dExecuteData);

d3dExecuteData.dwVertexCount = NUM_VERTICES;

d3dExecuteData.dwInstructionOffset = dwVertexSize;

d3dExecuteData.dwInstructionLength = dwInstructionSize;

hRes = lpd3dExecuteBuffer->lpVtbl->SetExecuteData

(lpd3dExecuteBuffer, &d3dExecuteData);

if (FAILED(hRes))

return hRes;

return DD_OK;

}