📄 t3dlib8.cpp
字号:
char buffer[256]; // working buffer
float col_tstep, row_tstep;
float col_vstep, row_vstep;
int columns, rows;
int rgbwhite;
BITMAP_FILE height_bitmap; // holds the height bitmap
// Step 1: clear out the object and initialize it a bit
memset(obj, 0, sizeof(OBJECT4DV2));
// set state of object to active and visible
obj->state = OBJECT4DV2_STATE_ACTIVE | OBJECT4DV2_STATE_VISIBLE;
// set position of object
obj->world_pos.x = pos->x;
obj->world_pos.y = pos->y;
obj->world_pos.z = pos->z;
obj->world_pos.w = pos->w;
// create proper color word based on selected bit depth of terrain
// rgbcolor is always in rgb5.6.5 format, so only need to downconvert for
// 8-bit mesh
if (poly_attr & POLY4DV1_ATTR_8BITCOLOR)
{
rgbcolor = rgblookup[rgbcolor];
rgbwhite = rgblookup[RGB16Bit(255,255,255)];
} // end if
else
{
rgbwhite = RGB16Bit(255,255,255);
} // end else
// set number of frames
obj->num_frames = 1;
obj->curr_frame = 0;
obj->attr = OBJECT4DV2_ATTR_SINGLE_FRAME;
// clear the bitmaps out
memset(&height_bitmap, 0, sizeof(BITMAP_FILE));
memset(&bitmap16bit, 0, sizeof(BITMAP_FILE));
// Step 2: load in the height field
Load_Bitmap_File(&height_bitmap, height_map_file);
// compute basic information
columns = height_bitmap.bitmapinfoheader.biWidth;
rows = height_bitmap.bitmapinfoheader.biHeight;
col_vstep = twidth / (float)(columns - 1);
row_vstep = theight / (float)(rows - 1);
sprintf(obj->name ,"Terrain:%s%s", height_map_file, texture_map_file);
obj->num_vertices = columns * rows;
obj->num_polys = ((columns - 1) * (rows - 1) ) * 2;
// store some results to help with terrain following
// use the auxialiary variables in the object -- might as well!
obj->ivar1 = columns;
obj->ivar2 = rows;
obj->fvar1 = col_vstep;
obj->fvar2 = row_vstep;
// allocate the memory for the vertices and number of polys
// the call parameters are redundant in this case, but who cares
if (!Init_OBJECT4DV2(obj, // object to allocate
obj->num_vertices,
obj->num_polys,
obj->num_frames))
{
Write_Error("\nTerrain generator error (can't allocate memory).");
} // end if
// load texture map if there is one
if ( (poly_attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE) && texture_map_file)
{
// load the texture from disk
Load_Bitmap_File(&bitmap16bit, texture_map_file);
// create a proper size and bitdepth bitmap
obj->texture = (BITMAP_IMAGE_PTR)malloc(sizeof(BITMAP_IMAGE));
Create_Bitmap(obj->texture,0,0,
bitmap16bit.bitmapinfoheader.biWidth,
bitmap16bit.bitmapinfoheader.biHeight,
bitmap16bit.bitmapinfoheader.biBitCount);
// load the bitmap image (later make this 8/16 bit)
if (obj->texture->bpp == 16)
Load_Image_Bitmap16(obj->texture, &bitmap16bit,0,0,BITMAP_EXTRACT_MODE_ABS);
else
{
Load_Image_Bitmap(obj->texture, &bitmap16bit,0,0,BITMAP_EXTRACT_MODE_ABS);
} // end else 8 bit
// compute stepping factors in texture map for texture coordinate computation
col_tstep = (float)(bitmap16bit.bitmapinfoheader.biWidth-1)/(float)(columns - 1);
row_tstep = (float)(bitmap16bit.bitmapinfoheader.biHeight-1)/(float)(rows - 1);
// flag object as having textures
SET_BIT(obj->attr, OBJECT4DV2_ATTR_TEXTURES);
// done, so unload the bitmap
Unload_Bitmap_File(&bitmap16bit);
} // end if
Write_Error("\ncolumns = %d, rows = %d", columns, rows);
Write_Error("\ncol_vstep = %f, row_vstep = %f", col_vstep, row_vstep);
Write_Error("\ncol_tstep=%f, row_tstep=%f", col_tstep, row_tstep);
Write_Error("\nnum_vertices = %d, num_polys = %d", obj->num_vertices, obj->num_polys);
// Step 4: generate the vertex list, and texture coordinate list in row major form
for (int curr_row = 0; curr_row < rows; curr_row++)
{
for (int curr_col = 0; curr_col < columns; curr_col++)
{
int vertex = (curr_row * columns) + curr_col;
// compute the vertex
obj->vlist_local[vertex].x = curr_col * col_vstep - (twidth/2);
obj->vlist_local[vertex].y = vscale*((float)height_bitmap.buffer[curr_col + (curr_row * columns) ]) / 255;
obj->vlist_local[vertex].z = curr_row * row_vstep - (theight/2);
obj->vlist_local[vertex].w = 1;
// every vertex has a point at least, set that in the flags attribute
SET_BIT(obj->vlist_local[vertex].attr, VERTEX4DTV1_ATTR_POINT);
// need texture coord?
if ( (poly_attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE) && texture_map_file)
{
// now texture coordinates
obj->tlist[vertex].x = curr_col * col_tstep;
obj->tlist[vertex].y = curr_row * row_tstep;
} // end if
Write_Error("\nVertex %d: V[%f, %f, %f], T[%f, %f]", vertex, obj->vlist_local[vertex].x,
obj->vlist_local[vertex].y,
obj->vlist_local[vertex].z,
obj->tlist[vertex].x,
obj->tlist[vertex].y);
} // end for curr_col
} // end curr_row
// perform rotation transformation?
// compute average and max radius
Compute_OBJECT4DV2_Radius(obj);
Write_Error("\nObject average radius = %f, max radius = %f",
obj->avg_radius[0], obj->max_radius[0]);
// Step 5: generate the polygon list
for (int poly=0; poly < obj->num_polys/2; poly++)
{
// polygons follow a regular pattern of 2 per square, row
// major form, finding the correct indices is a pain, but
// the bottom line is we have an array of vertices mxn and we need
// a list of polygons that is (m-1) x (n-1), with 2 triangles per
// square with a consistent winding order... this is one one to arrive
// at the indices, another way would be to use two loops, etc.,
int base_poly_index = (poly % (columns-1)) + (columns * (poly / (columns - 1)) );
// upper left poly
obj->plist[poly*2].vert[0] = base_poly_index;
obj->plist[poly*2].vert[1] = base_poly_index+columns;
obj->plist[poly*2].vert[2] = base_poly_index+columns+1;
// lower right poly
obj->plist[poly*2+1].vert[0] = base_poly_index;
obj->plist[poly*2+1].vert[1] = base_poly_index+columns+1;
obj->plist[poly*2+1].vert[2] = base_poly_index+1;
// point polygon vertex list to object's vertex list
// note that this is redundant since the polylist is contained
// within the object in this case and its up to the user to select
// whether the local or transformed vertex list is used when building up
// polygon geometry, might be a better idea to set to NULL in the context
// of polygons that are part of an object
obj->plist[poly*2].vlist = obj->vlist_local;
obj->plist[poly*2+1].vlist = obj->vlist_local;
// set attributes of polygon with sent attributes
obj->plist[poly*2].attr = poly_attr;
obj->plist[poly*2+1].attr = poly_attr;
// now perform some test to make sure any secondary data elements are
// set properly
// set color of polygon
obj->plist[poly*2].color = rgbcolor;
obj->plist[poly*2+1].color = rgbcolor;
// check for gouraud of phong shading, if so need normals
if ( (obj->plist[poly*2].attr & POLY4DV2_ATTR_SHADE_MODE_GOURAUD) ||
(obj->plist[poly*2].attr & POLY4DV2_ATTR_SHADE_MODE_PHONG) )
{
// the vertices from this polygon all need normals, set that in the flags attribute
SET_BIT(obj->vlist_local[ obj->plist[poly*2].vert[0] ].attr, VERTEX4DTV1_ATTR_NORMAL);
SET_BIT(obj->vlist_local[ obj->plist[poly*2].vert[1] ].attr, VERTEX4DTV1_ATTR_NORMAL);
SET_BIT(obj->vlist_local[ obj->plist[poly*2].vert[2] ].attr, VERTEX4DTV1_ATTR_NORMAL);
SET_BIT(obj->vlist_local[ obj->plist[poly*2+1].vert[0] ].attr, VERTEX4DTV1_ATTR_NORMAL);
SET_BIT(obj->vlist_local[ obj->plist[poly*2+1].vert[1] ].attr, VERTEX4DTV1_ATTR_NORMAL);
SET_BIT(obj->vlist_local[ obj->plist[poly*2+1].vert[2] ].attr, VERTEX4DTV1_ATTR_NORMAL);
} // end if
// if texture in enabled the enable texture coordinates
if (poly_attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE)
{
// apply texture to this polygon
obj->plist[poly*2].texture = obj->texture;
obj->plist[poly*2+1].texture = obj->texture;
// assign the texture coordinates
// upper left poly
obj->plist[poly*2].text[0] = base_poly_index;
obj->plist[poly*2].text[1] = base_poly_index+columns;
obj->plist[poly*2].text[2] = base_poly_index+columns+1;
// lower right poly
obj->plist[poly*2+1].text[0] = base_poly_index;
obj->plist[poly*2+1].text[1] = base_poly_index+columns+1;
obj->plist[poly*2+1].text[2] = base_poly_index+1;
// override base color to make poly more reflective
obj->plist[poly*2].color = rgbwhite;
obj->plist[poly*2+1].color = rgbwhite;
// set texture coordinate attributes
SET_BIT(obj->vlist_local[ obj->plist[poly*2].vert[0] ].attr, VERTEX4DTV1_ATTR_TEXTURE);
SET_BIT(obj->vlist_local[ obj->plist[poly*2].vert[1] ].attr, VERTEX4DTV1_ATTR_TEXTURE);
SET_BIT(obj->vlist_local[ obj->plist[poly*2].vert[2] ].attr, VERTEX4DTV1_ATTR_TEXTURE);
SET_BIT(obj->vlist_local[ obj->plist[poly*2+1].vert[0] ].attr, VERTEX4DTV1_ATTR_TEXTURE);
SET_BIT(obj->vlist_local[ obj->plist[poly*2+1].vert[1] ].attr, VERTEX4DTV1_ATTR_TEXTURE);
SET_BIT(obj->vlist_local[ obj->plist[poly*2+1].vert[2] ].attr, VERTEX4DTV1_ATTR_TEXTURE);
} // end if
// set the material mode to ver. 1.0 emulation
SET_BIT(obj->plist[poly*2].attr, POLY4DV2_ATTR_DISABLE_MATERIAL);
SET_BIT(obj->plist[poly*2+1].attr, POLY4DV2_ATTR_DISABLE_MATERIAL);
// finally set the polygon to active
obj->plist[poly*2].state = POLY4DV2_STATE_ACTIVE;
obj->plist[poly*2+1].state = POLY4DV2_STATE_ACTIVE;
// point polygon vertex list to object's vertex list
// note that this is redundant since the polylist is contained
// within the object in this case and its up to the user to select
// whether the local or transformed vertex list is used when building up
// polygon geometry, might be a better idea to set to NULL in the context
// of polygons that are part of an object
obj->plist[poly*2].vlist = obj->vlist_local;
obj->plist[poly*2+1].vlist = obj->vlist_local;
// set texture coordinate list, this is needed
obj->plist[poly*2].tlist = obj->tlist;
obj->plist[poly*2+1].tlist = obj->tlist;
} // end for poly
#if 0
for (poly=0; poly < obj->num_polys; poly++)
{
Write_Error("\nPoly %d: Vi[%d, %d, %d], Ti[%d, %d, %d]",poly,
obj->plist[poly].vert[0],
obj->plist[poly].vert[1],
obj->plist[poly].vert[2],
obj->plist[poly].text[0],
obj->plist[poly].text[1],
obj->plist[poly].text[2]);
} // end
#endif
// compute the polygon normal lengths
Compute_OBJECT4DV2_Poly_Normals(obj);
// compute vertex normals for any gouraud shaded polys
Compute_OBJECT4DV2_Vertex_Normals(obj);
// return success
return(1);
} // end Generate_Terrain_OBJECT4DV2
//////////////////////////////////////////////////////////////////////////////
int Init_Light_LIGHTV2(LIGHTV2_PTR lights, // light array to work with (new)
int index, // index of light to create (0..MAX_LIGHTS-1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -