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

📄 t3dlib1.cpp

📁 游戏经典书 3D游戏编程大师技巧 源代码,本书是游戏编程畅销书作者Andre LaMothe的扛鼎之作
💻 CPP
📖 第 1 页 / 共 5 页
字号:
   y_inc = lpitch;
   } // end if line is moving down
else
   {
   y_inc = -lpitch;
   dy    = -dy;  // need absolute value

   } // end else moving up

// compute (dx,dy) * 2
dx2 = dx << 1;
dy2 = dy << 1;

// now based on which delta is greater we can draw the line
if (dx > dy)
   {
   // initialize error term
   error = dy2 - dx; 

   // draw the line
   for (index=0; index <= dx; index++)
       {
       // set the pixel
       *vb_start = color;

       // test if error has overflowed
       if (error >= 0) 
          {
          error-=dx2;

          // move to next line
          vb_start+=y_inc;

	   } // end if error overflowed

       // adjust the error term
       error+=dy2;

       // move to the next pixel
       vb_start+=x_inc;

       } // end for

   } // end if |slope| <= 1
else
   {
   // initialize error term
   error = dx2 - dy; 

   // draw the line
   for (index=0; index <= dy; index++)
       {
       // set the pixel
       *vb_start = color;

       // test if error overflowed
       if (error >= 0)
          {
          error-=dy2;

          // move to next line
          vb_start+=x_inc;

          } // end if error overflowed

       // adjust the error term
       error+=dx2;

       // move to the next pixel
       vb_start+=y_inc;

       } // end for

   } // end else |slope| > 1

// return success
return(1);

} // end Draw_Line

///////////////////////////////////////////////////////////

int Draw_Line16(int x0, int y0, // starting position 
                int x1, int y1, // ending position
                int color,     // color index
                UCHAR *vb_start, int lpitch) // video buffer and memory pitch
{
    // this function draws a line from xo,yo to x1,y1 using differential error
    // terms (based on Bresenahams work)

    int dx,             // difference in x's
        dy,             // difference in y's
        dx2,            // dx,dy * 2
        dy2, 
        x_inc,          // amount in pixel space to move during drawing
        y_inc,          // amount in pixel space to move during drawing
        error,          // the discriminant i.e. error i.e. decision variable
        index;          // used for looping

    int lpitch_2 = lpitch >> 1; // USHORT strided lpitch

    // pre-compute first pixel address in video buffer based on 16bit data
    USHORT *vb_start2 = (USHORT *)vb_start + x0 + y0*lpitch_2;

    // compute horizontal and vertical deltas
    dx = x1-x0;
    dy = y1-y0;

    // test which direction the line is going in i.e. slope angle
    if (dx>=0)
    {
        x_inc = 1;

    } // end if line is moving right
    else
    {
        x_inc = -1;
        dx    = -dx;  // need absolute value

    } // end else moving left

    // test y component of slope

    if (dy>=0)
    {
        y_inc = lpitch_2;
    } // end if line is moving down
    else
    {
        y_inc = -lpitch_2;
        dy    = -dy;  // need absolute value

    } // end else moving up

    // compute (dx,dy) * 2
    dx2 = dx << 1;
    dy2 = dy << 1;

    // now based on which delta is greater we can draw the line
    if (dx > dy)
    {
    // initialize error term
    error = dy2 - dx; 

    // draw the line
    for (index=0; index <= dx; index++)
        {
            // set the pixel
            *vb_start2 = (USHORT)color;

            // test if error has overflowed
            if (error >= 0) 
            {
                error-=dx2;

                // move to next line
                vb_start2+=y_inc;

	        } // end if error overflowed

            // adjust the error term
            error+=dy2;

            // move to the next pixel
            vb_start2+=x_inc;

        } // end for

    } // end if |slope| <= 1
    else
    {
    // initialize error term
    error = dx2 - dy; 

    // draw the line
    for (index=0; index <= dy; index++)
        {
        // set the pixel
        *vb_start2 = (USHORT)color;

        // test if error overflowed
        if (error >= 0)
            {
            error-=dy2;

            // move to next line
            vb_start2+=x_inc;

            } // end if error overflowed

        // adjust the error term
        error+=dx2;

        // move to the next pixel
        vb_start2+=y_inc;

        } // end for

    } // end else |slope| > 1

    // return success
    return(1);

} // end Draw_Line16

///////////////////////////////////////////////////////////

int Draw_Pixel(int x, int y,int color,
               UCHAR *video_buffer, int lpitch)
{
// this function plots a single pixel at x,y with color

video_buffer[x + y*lpitch] = color;

// return success
return(1);

} // end Draw_Pixel

///////////////////////////////////////////////////////////   
   
int Draw_Pixel16(int x, int y,int color,
                        UCHAR *video_buffer, int lpitch)
{
// this function plots a single pixel at x,y with color

((USHORT *)video_buffer)[x + y*(lpitch >> 1)] = color;

// return success
return(1);

} // end Draw_Pixel16

///////////////////////////////////////////////////////////   


int Draw_Rectangle(int x1, int y1, int x2, int y2, int color,
                   LPDIRECTDRAWSURFACE7 lpdds)
{
// this function uses directdraw to draw a filled rectangle

DDBLTFX ddbltfx; // this contains the DDBLTFX structure
RECT fill_area;  // this contains the destination rectangle

// clear out the structure and set the size field 
DDRAW_INIT_STRUCT(ddbltfx);

// set the dwfillcolor field to the desired color
ddbltfx.dwFillColor = color; 

// fill in the destination rectangle data (your data)
fill_area.top    = y1;
fill_area.left   = x1;
fill_area.bottom = y2;
fill_area.right  = x2;

// ready to blt to surface, in this case blt to primary
lpdds->Blt(&fill_area, // ptr to dest rectangle
           NULL,       // ptr to source surface, NA            
           NULL,       // ptr to source rectangle, NA
           DDBLT_COLORFILL | DDBLT_WAIT,   // fill and wait                   
           &ddbltfx);  // ptr to DDBLTFX structure

// return success
return(1);

} // end Draw_Rectangle

///////////////////////////////////////////////////////////
   
int Set_Palette_Entry(int color_index, LPPALETTEENTRY color)
{
// this function sets a palette color in the palette
lpddpal->SetEntries(0,color_index,1,color);

// set data in shadow palette
memcpy(&palette[color_index],color,sizeof(PALETTEENTRY));

// return success
return(1);
} // end Set_Palette_Entry

///////////////////////////////////////////////////////////   
   
int Get_Palette_Entry(int color_index,LPPALETTEENTRY color)
{
// this function retrieves a palette entry from the color
// palette

// copy data out from shadow palette
memcpy(color, &palette[color_index],sizeof(PALETTEENTRY));

// return success
return(1);
} // end Get_Palette_Entry

///////////////////////////////////////////////////////////
   
int Load_Palette_From_File(char *filename, LPPALETTEENTRY palette)
{
// this function loads a palette from disk into a palette
// structure, but does not set the pallette

FILE *fp_file; // working file

// try and open file
if ((fp_file = fopen(filename,"r"))==NULL)
   return(0);

// read in all 256 colors RGBF
for (int index=0; index<MAX_COLORS_PALETTE; index++)
    {
    // read the next entry in
    fscanf(fp_file,"%d %d %d %d",&palette[index].peRed,
                                 &palette[index].peGreen,
                                 &palette[index].peBlue,                                
                                 &palette[index].peFlags);
    } // end for index

// close the file
fclose(fp_file);

// return success
return(1);
} // end Load_Palette_From_Disk

///////////////////////////////////////////////////////////   
   
int Save_Palette_To_File(char *filename, LPPALETTEENTRY palette)
{
// this function saves a palette to disk

FILE *fp_file; // working file

// try and open file
if ((fp_file = fopen(filename,"w"))==NULL)
   return(0);

// write in all 256 colors RGBF
for (int index=0; index<MAX_COLORS_PALETTE; index++)
    {
    // read the next entry in
    fprintf(fp_file,"\n%d %d %d %d",palette[index].peRed,
                                    palette[index].peGreen,
                                    palette[index].peBlue,                                
                                    palette[index].peFlags);
    } // end for index

// close the file
fclose(fp_file);

// return success
return(1);

} // end Save_Palette_To_Disk

///////////////////////////////////////////////////////////

int Save_Palette(LPPALETTEENTRY sav_palette)
{
// this function saves the current palette 

memcpy(sav_palette, palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));

// return success
return(1);
} // end Save_Palette

///////////////////////////////////////////////////////////   
   
int Set_Palette(LPPALETTEENTRY set_palette)
{
// this function writes the sent palette

// first save the new palette in shadow
memcpy(palette, set_palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));

// now set the new palette
lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,palette);

// return success
return(1);
} // end Set_Palette

///////////////////////////////////////////////////////////

int Rotate_Colors(int start_index, int end_index)
{
// this function rotates the color between start and end

int colors = end_index - start_index + 1;

PALETTEENTRY work_pal[MAX_COLORS_PALETTE]; // working palette

// get the color palette
lpddpal->GetEntries(0,start_index,colors,work_pal);

// shift the colors
lpddpal->SetEntries(0,start_index+1,colors-1,work_pal);

// fix up the last color
lpddpal->SetEntries(0,start_index,1,&work_pal[colors - 1]);

// update shadow palette
lpddpal->GetEntries(0,0,MAX_COLORS_PALETTE,palette);

// return success
return(1);

} // end Rotate_Colors

///////////////////////////////////////////////////////////   
   
int Blink_Colors(int command, BLINKER_PTR new_light, int id)
{
// this function blinks a set of lights

static BLINKER lights[256]; // supports up to 256 blinking lights
static int initialized = 0; // tracks if function has initialized

// test if this is the first time function has ran
if (!initialized)
   {
   // set initialized
   initialized = 1;

   // clear out all structures
   memset((void *)lights,0, sizeof(lights));

   } // end if

// now test what command user is sending
switch (command)
       {
       case BLINKER_ADD: // add a light to the database
            {
            // run thru database and find an open light
            for (int index=0; index < 256; index++)
                {
                // is this light available?
                if (lights[index].state == 0)
                   {
                   // set light up
                   lights[index] = *new_light;

                   // set internal fields up
                   lights[index].counter =  0;
                   lights[index].state   = -1; // off

                   // update palette entry
                   lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].off_color);
 
                   // return id to caller
                   return(index);

                   } // end if

                } // end for index

            } break;

       case BLINKER_DELETE: // delete the light indicated by id
            {
            // delete the light sent in id 
            if (lights[id].state != 0)
               {
               // kill the light
               memset((void *)&lights[id],0,sizeof(BLINKER));

               // return id
               return(id);
 
               } // end if
            else
                return(-1); // problem


            } break;

       case BLINKER_UPDATE: // update the light indicated by id
            { 
            // make sure light is active
            if (lights[id].state != 0)
               {
               // update on/o

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -