FACES.C

/*========================================================================== 
*
* Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
*
* File: faces.c
*
***************************************************************************/

/*
* Example program to demonstrate MeshAddFaces
*/

#include "rmdemo.h"

D3DVECTOR cube_vertices[] = {-D3DVAL(0.5), -D3DVAL(0.5), -D3DVAL(0.5),
-D3DVAL(0.5), -D3DVAL(0.5), D3DVAL(0.5),
-D3DVAL(0.5), D3DVAL(0.5), -D3DVAL(0.5),
-D3DVAL(0.5), D3DVAL(0.5), D3DVAL(0.5),
D3DVAL(0.5), -D3DVAL(0.5), -D3DVAL(0.5),
D3DVAL(0.5), -D3DVAL(0.5), D3DVAL(0.5),
D3DVAL(0.5), D3DVAL(0.5), -D3DVAL(0.5),
D3DVAL(0.5), D3DVAL(0.5), D3DVAL(0.5)
};

/*
* face_data is a vertex count followed by the vertex reference in the
* vertices list. If normal_count > 0, then pairs of vectors are
* referenced: first the vertex and secondly the normal reference. the
* list is terminated by a 0 (vertex count to a face)
*/


BOOL
build_face1(LPDIRECT3DRMMESHBUILDER msh)
{
/*
* add a single face to a mesh.
*/

/*
* Single face with all normals pointing in the same direction.
*/

int vertex_count = 4;
D3DVECTOR vertices[4] = {D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0),
D3DVAL(1.0), D3DVAL(0.0), D3DVAL(1.0),
D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0)
};
int normal_count = 4;
D3DVECTOR normals[4] = {D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
};
int face_data[] = {4, 0, 0, 1, 1, 2, 2, 3, 3, 0};

if (FAILED(msh->lpVtbl->AddFaces(msh, vertex_count, vertices, normal_count,
normals, face_data, NULL)))
return FALSE;
return TRUE;
}

BOOL
build_face2(LPDIRECT3DRMMESHBUILDER msh)
{
/*
* Single face with normals pointing in different directions to
* approximate a curved surface.
*/
int vertex_count = 4;
D3DVECTOR vertices[4] = {D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0),
D3DVAL(1.0), D3DVAL(0.0), D3DVAL(1.0),
D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0)
};
int normal_count = 4;
D3DVECTOR normals[4] = {
D3DVAL(0.5), D3DVAL(0.7), D3DVAL(0.5),
D3DVAL(0.5), D3DVAL(0.7), -D3DVAL(0.5),
-D3DVAL(0.5), D3DVAL(0.7), -D3DVAL(0.5),
-D3DVAL(0.5), D3DVAL(0.7), D3DVAL(0.5)
};
int face_data[] = {4, 0, 0, 1, 1, 2, 2, 3, 3, 0};

if (FAILED(msh->lpVtbl->AddFaces(msh, vertex_count, vertices, normal_count,
normals, face_data, NULL)))
return FALSE;
return TRUE;
}

BOOL
build_cube1(LPDIRECT3DRMMESHBUILDER msh)
{
/*
* cube 1 has planar faces, one normal is shared by all vertices of a
* face
*/
int face1_data[] = {
4, 1, 0, 5, 1, 7, 2, 3, 3,
4, 2, 4, 3, 5, 7, 6, 6, 7,
4, 5, 8, 4, 9, 6, 10, 7, 11,
4, 0, 12, 2, 13, 6, 14, 4, 15,
4, 0, 16, 4, 17, 5, 18, 1, 19,
4, 0, 20, 1, 21, 3, 22, 2, 23,
0};

D3DVECTOR cube1_normals[] = {
D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0),
D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0),
D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0),
D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0),
D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(0.0), -D3DVAL(1.0),
D3DVAL(0.0), D3DVAL(0.0), -D3DVAL(1.0),
D3DVAL(0.0), D3DVAL(0.0), -D3DVAL(1.0),
D3DVAL(0.0), D3DVAL(0.0), -D3DVAL(1.0),
D3DVAL(0.0), -D3DVAL(1.0), D3DVAL(0.0),
D3DVAL(0.0), -D3DVAL(1.0), D3DVAL(0.0),
D3DVAL(0.0), -D3DVAL(1.0), D3DVAL(0.0),
D3DVAL(0.0), -D3DVAL(1.0), D3DVAL(0.0),
-D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0)
- D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0)
- D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0)
- D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0)
};

if (FAILED(msh->lpVtbl->AddFaces(msh, 8, cube_vertices, 6 * 4, cube1_normals,
face1_data, NULL)))
return FALSE;
return TRUE;
}

BOOL
build_cube2(LPDIRECT3DRMMESHBUILDER msh)
{
/*
* cube 2 has rounded faces, the normals radiate out at each vertex,
* one normal to each vertex
*/

int face2_data[] = {
4, 1, 1, 5, 5, 7, 7, 3, 3,
4, 2, 2, 3, 3, 7, 7, 6, 6,
4, 5, 5, 4, 4, 6, 6, 7, 7,
4, 0, 0, 2, 2, 6, 6, 4, 4,
4, 0, 0, 4, 4, 5, 5, 1, 1,
4, 0, 0, 1, 1, 3, 3, 2, 2,
0};

D3DVECTOR cube2_normals[] = {
-D3DVAL(1.0), -D3DVAL(1.0), -D3DVAL(1.0),
-D3DVAL(1.0), -D3DVAL(1.0), D3DVAL(1.0),
-D3DVAL(1.0), D3DVAL(1.0), -D3DVAL(1.0),
-D3DVAL(1.0), D3DVAL(1.0), D3DVAL(1.0),
D3DVAL(1.0), -D3DVAL(1.0), -D3DVAL(1.0),
D3DVAL(1.0), -D3DVAL(1.0), D3DVAL(1.0),
D3DVAL(1.0), D3DVAL(1.0), -D3DVAL(1.0),
D3DVAL(1.0), D3DVAL(1.0), D3DVAL(1.0)
};
if (FAILED(msh->lpVtbl->AddFaces(msh, 8, cube_vertices, 8, cube2_normals,
face2_data, NULL)))
return FALSE;
return TRUE;
}

BOOL
BuildScene(LPDIRECT3DRMDEVICE dev, LPDIRECT3DRMVIEWPORT view,
LPDIRECT3DRMFRAME scene, LPDIRECT3DRMFRAME camera)
{
D3DRMRENDERQUALITY quality = D3DRMRENDER_GOURAUD;
LPDIRECT3DRMMESHBUILDER light_builder, face1_builder, face2_builder;
LPDIRECT3DRMMESHBUILDER cube1_builder, cube2_builder;
LPDIRECT3DRMMESH light_mesh, face1_mesh, face2_mesh, cube1_mesh, cube2_mesh;
LPDIRECT3DRMFRAME frame1, frame2, face_frame1, face_frame2, light_frame;
LPDIRECT3DRMFRAME lights;
LPDIRECT3DRMLIGHT light1, light2;
HRESULT rval;

view = view;/* not used */
light_builder = NULL; face1_builder = NULL; face2_builder = NULL;
cube1_builder = NULL; cube2_builder = NULL;
light_mesh = NULL; face1_mesh = NULL; face2_mesh = NULL;
cube1_mesh = NULL; cube2_mesh = NULL;
frame1 = NULL; frame2 = NULL; face_frame1 = NULL; face_frame2 = NULL;
light_frame = NULL; lights = NULL; light1 = NULL; light2 = NULL;

/*
* This Demo shows the construction of planar faces\n"); with vertex
* normals for realistic modelling of\n"); flat and curved surfaces by
* polygonal approximation.\n");
*/

if (FAILED(dev->lpVtbl->SetQuality(dev, quality)))
goto generic_error;

if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &face_frame1)))
goto generic_error;
if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &face_frame2)))
goto generic_error;
if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &frame1)))
goto generic_error;
if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &frame2)))
goto generic_error;
if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, scene, &light_frame)))
goto generic_error;
if (FAILED(lpD3DRM->lpVtbl->CreateFrame(lpD3DRM, light_frame, &lights)))
goto generic_error;

if (FAILED(lights->lpVtbl->SetPosition(lights, light_frame, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(2.2))))
goto generic_error;
if (FAILED(light_frame->lpVtbl->SetPosition(light_frame, scene, D3DVAL(0.0), D3DVAL(0.4), D3DVAL(0.0))))
goto generic_error;

if (FAILED(lpD3DRM->lpVtbl->CreateLightRGB(lpD3DRM, D3DRMLIGHT_POINT, D3DVAL(0.9),
D3DVAL(0.8), D3DVAL(0.7), &light1)))
goto generic_error;
if (FAILED(lpD3DRM->lpVtbl->CreateLightRGB(lpD3DRM, D3DRMLIGHT_AMBIENT, D3DVAL(0.02),
D3DVAL(0.01), D3DVAL(0.01), &light2)))
goto generic_error;
if (FAILED(lights->lpVtbl->AddLight(lights, light1)))
goto generic_error;
if (FAILED(scene->lpVtbl->AddLight(scene, light2)))
goto generic_error;
RELEASE(light1);
RELEASE(light2);

if (FAILED(lpD3DRM->lpVtbl->CreateMeshBuilder(lpD3DRM, &face1_builder)))
goto generic_error;
if (FAILED(lpD3DRM->lpVtbl->CreateMeshBuilder(lpD3DRM, &face2_builder)))
goto generic_error;
if (FAILED(lpD3DRM->lpVtbl->CreateMeshBuilder(lpD3DRM, &cube1_builder)))
goto generic_error;
if (FAILED(lpD3DRM->lpVtbl->CreateMeshBuilder(lpD3DRM, &cube2_builder)))
goto generic_error;

if (!build_face1(face1_builder))
goto generic_error;
if (!build_face2(face2_builder))
goto generic_error;
if (!build_cube1(cube1_builder))
goto generic_error;
if (!build_cube2(cube2_builder))
goto generic_error;

if (FAILED(face1_builder->lpVtbl->CreateMesh(face1_builder, &face1_mesh)))
goto generic_error;
if (FAILED(face2_builder->lpVtbl->CreateMesh(face2_builder, &face2_mesh)))
goto generic_error;
if (FAILED(cube1_builder->lpVtbl->CreateMesh(cube1_builder, &cube1_mesh)))
goto generic_error;
if (FAILED(cube2_builder->lpVtbl->CreateMesh(cube2_builder, &cube2_mesh)))
goto generic_error;

RELEASE(face1_builder);
RELEASE(face2_builder);
RELEASE(cube1_builder);
RELEASE(cube2_builder);

if (FAILED(face_frame1->lpVtbl->AddVisual(face_frame1, (LPDIRECT3DRMVISUAL) face1_mesh)))
goto generic_error;
if (FAILED(face_frame2->lpVtbl->AddVisual(face_frame2, (LPDIRECT3DRMVISUAL) face2_mesh)))
goto generic_error;
if (FAILED(frame1->lpVtbl->AddVisual(frame1, (LPDIRECT3DRMVISUAL) cube1_mesh)))
goto generic_error;
if (FAILED(frame2->lpVtbl->AddVisual(frame2, (LPDIRECT3DRMVISUAL) cube2_mesh)))
goto generic_error;

if (FAILED(lpD3DRM->lpVtbl->CreateMeshBuilder(lpD3DRM, &light_builder)))
goto generic_error;
rval = light_builder->lpVtbl->Load(light_builder, "sphere0.x", NULL,
D3DRMLOAD_FROMFILE, NULL, NULL);
if (rval != D3DRM_OK) {
Msg("Failed to load sphere0.x\n");
goto ret_with_error;
}
if (FAILED(light_builder->lpVtbl->SetColorRGB(light_builder, D3DVAL(1), D3DVAL(1),
D3DVAL(1))))
goto generic_error;
if (FAILED(light_builder->lpVtbl->Scale(light_builder, D3DVAL(0.1), D3DVAL(0.1),
D3DVAL(0.1))))
goto generic_error;
if (FAILED(light_builder->lpVtbl->SetQuality(light_builder, D3DRMRENDER_UNLITFLAT)))
goto generic_error;
if (FAILED(light_builder->lpVtbl->CreateMesh(light_builder, &light_mesh)))
goto generic_error;
RELEASE(light_builder);

if (FAILED(lights->lpVtbl->AddVisual(lights, (LPDIRECT3DRMVISUAL) light_mesh)))
goto generic_error;

if (FAILED(camera->lpVtbl->SetPosition(camera, scene, D3DVAL(0.0), D3DVAL(2), -D3DVAL(5))))
goto generic_error;
if (FAILED(face_frame1->lpVtbl->SetPosition(face_frame1, scene, -D3DVAL(0.5),
D3DVAL(0.5), D3DVAL(2))))
goto generic_error;
if (FAILED(face_frame2->lpVtbl->SetPosition(face_frame2, scene, -D3DVAL(0.5),
-D3DVAL(1.5), D3DVAL(2))))
goto generic_error;
if (FAILED(frame1->lpVtbl->SetPosition(frame1, scene, -D3DVAL(2.0), D3DVAL(0.0), D3DVAL(2))))
goto generic_error;
if (FAILED(frame2->lpVtbl->SetPosition(frame2, scene, D3DVAL(1.5), D3DVAL(0.0), D3DVAL(2))))
goto generic_error;

if (FAILED(face_frame1->lpVtbl->SetOrientation(face_frame1, scene, D3DVAL(0.0), D3DVAL(1), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(0.0), -D3DVAL(1))))
goto generic_error;
if (FAILED(face_frame2->lpVtbl->SetOrientation(face_frame2, scene, D3DVAL(0.0), D3DVAL(1), D3DVAL(0.0),
D3DVAL(0.0), D3DVAL(0.0), -D3DVAL(1))))
goto generic_error;
if (FAILED(camera->lpVtbl->SetOrientation(camera, scene, D3DVAL(0.0), -D3DVAL(0.2), D3DVAL(1),
D3DVAL(0.0), D3DVAL(1), D3DVAL(0.0))))
goto generic_error;
if (FAILED(frame1->lpVtbl->SetRotation(frame1, scene, D3DVAL(1), D3DVAL(0.0), D3DVAL(1),
-D3DVAL(0.005))))
goto generic_error;
if (FAILED(frame2->lpVtbl->SetRotation(frame2, scene, D3DVAL(0.0), D3DVAL(1), D3DVAL(1),
-D3DVAL(0.005))))
goto generic_error;
if (FAILED(light_frame->lpVtbl->SetRotation(light_frame, scene, D3DVAL(0.0), D3DVAL(1), D3DVAL(0.0),
-D3DVAL(0.02))))
goto generic_error;

RELEASE(light_mesh);
RELEASE(face1_mesh);
RELEASE(face2_mesh);
RELEASE(cube1_mesh);
RELEASE(cube2_mesh);

RELEASE(frame1);
RELEASE(frame2);
RELEASE(face_frame1);
RELEASE(face_frame2);
RELEASE(light_frame);
RELEASE(lights);
return TRUE;
generic_error:
Msg("An error has occurred while building the scene.\n");
ret_with_error:
RELEASE(light_builder);
RELEASE(face1_builder);
RELEASE(face2_builder);
RELEASE(cube1_builder);
RELEASE(cube2_builder);
RELEASE(light_mesh);
RELEASE(face1_mesh);
RELEASE(face2_mesh);
RELEASE(cube1_mesh);
RELEASE(cube2_mesh);
RELEASE(frame1);
RELEASE(frame2);
RELEASE(face_frame1);
RELEASE(face_frame2);
RELEASE(light_frame);
RELEASE(lights);
RELEASE(light1);
RELEASE(light2);
return FALSE;
}

void
OverrideDefaults(Defaults *defaults)
{
defaults->bNoTextures = TRUE;
defaults->bConstRenderQuality = TRUE;
lstrcpy(defaults->Name, "Faces Direct3DRM Example");
}