⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t3dlib8.cpp

📁 3D游戏编程大师技巧第十章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
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 + -