?? demo8_9.cpp
字號:
// DEMO8_9.CPP 8-bit general polygon fill demo
// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN // just say no to MFC
#define INITGUID
#include <windows.h> // include important windows stuff
#include <windowsx.h>
#include <mmsystem.h>
#include <iostream.h> // include important C/C++ stuff
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>
#include <ddraw.h> // include directdraw
// DEFINES ////////////////////////////////////////////////
// defines for windows
#define WINDOW_CLASS_NAME "WINCLASS1"
// default screen size
#define SCREEN_WIDTH 640 // size of screen
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 8 // bits per pixel
#define BITMAP_ID 0x4D42 // universal id for a bitmap
#define MAX_COLORS_PALETTE 256
const double PI = 3.1415926535;
// TYPES //////////////////////////////////////////////////////
// basic unsigned types
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
// a 2D vertex
typedef struct VERTEX2DI_TYP
{
int x,y; // the vertex
} VERTEX2DI, *VERTEX2DI_PTR;
// a 2D vertex
typedef struct VERTEX2DF_TYP
{
float x,y; // the vertex
} VERTEX2DF, *VERTEX2DF_PTR;
// a 2D polygon
typedef struct POLYGON2D_TYP
{
int state; // state of polygon
int num_verts; // number of vertices
int x0,y0; // position of center of polygon
int xv,yv; // initial velocity
DWORD color; // could be index or PALETTENTRY
VERTEX2DF *vlist; // pointer to vertex list
} POLYGON2D, *POLYGON2D_PTR;
// PROTOTYPES //////////////////////////////////////////////
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color);
void Draw_Filled_Polygon2D(POLYGON2D_PTR poly, UCHAR *vbuffer, int mempitch);
int Translate_Polygon2D(POLYGON2D_PTR poly, int dx, int dy);
int Rotate_Polygon2D(POLYGON2D_PTR poly, int theta);
int Scale_Polygon2D(POLYGON2D_PTR poly, float sx, float sy);
int Set_Palette_Entry(int color_index, LPPALETTEENTRY color);
int Draw_Text_GDI(char *text, int x,int y,int color, LPDIRECTDRAWSURFACE7 lpdds);
// MACROS /////////////////////////////////////////////////
// tests if a key is up or down
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
// initializes a direct draw struct
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }
// some math macros
#define DEG_TO_RAD(ang) ((ang)*PI/180)
#define RAD_TO_DEG(rads) ((rads)*180/PI)
// GLOBALS ////////////////////////////////////////////////
HWND main_window_handle = NULL; // globally track main window
int window_closed = 0; // tracks if window is closed
HINSTANCE hinstance_app = NULL; // globally track hinstance
// directdraw stuff
LPDIRECTDRAW7 lpdd = NULL; // dd object
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWSURFACE7 lpddsback = NULL; // dd back surface
LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette
LPDIRECTDRAWCLIPPER lpddclipper = NULL; // dd clipper
PALETTEENTRY palette[256]; // color palette
PALETTEENTRY save_palette[256]; // used to save palettes
DDSURFACEDESC2 ddsd; // a direct draw surface description struct
DDBLTFX ddbltfx; // used to fill
DDSCAPS2 ddscaps; // a direct draw surface capabilities struct
HRESULT ddrval; // result back from dd calls
DWORD start_clock_count = 0; // used for timing
// global clipping region
int min_clip_x = 0, // clipping rectangle
max_clip_x = SCREEN_WIDTH - 1,
min_clip_y = 0,
max_clip_y = SCREEN_HEIGHT - 1;
char buffer[80]; // general printing buffer
// storage for our lookup tables
float cos_look[360];
float sin_look[360];
POLYGON2D object; // the polygon object
// FUNCTIONS ////////////////////////////////////////////////
int Draw_Text_GDI(char *text, int x,int y,int color, LPDIRECTDRAWSURFACE7 lpdds)
{
// this function draws the sent text on the sent surface
// using color index as the color in the palette
HDC xdc; // the working dc
// get the dc from surface
if (FAILED(lpdds->GetDC(&xdc)))
return(0);
// set the colors for the text up
SetTextColor(xdc,RGB(palette[color].peRed,palette[color].peGreen,palette[color].peBlue) );
// set background mode to transparent so black isn't copied
SetBkMode(xdc, TRANSPARENT);
// draw the text a
TextOut(xdc,x,y,text,strlen(text));
// release the dc
lpdds->ReleaseDC(xdc);
// return success
return(1);
} // end Draw_Text_GDI
///////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////
void Draw_Filled_Polygon2D(POLYGON2D_PTR poly, UCHAR *vbuffer, int mempitch)
{
// this function draws a general n sided polygon
int ydiff1, ydiff2, // difference between starting x and ending x
xdiff1, xdiff2, // difference between starting y and ending y
start, // starting offset of line between edges
length, // distance from edge 1 to edge 2
errorterm1, errorterm2, // error terms for edges 1 & 2
offset1, offset2, // offset of current pixel in edges 1 & 2
count1, count2, // increment count for edges 1 & 2
xunit1, xunit2; // unit to advance x offset for edges 1 & 2
// initialize count of number of edges drawn:
int edgecount = poly->num_verts-1;
// determine which vertex is at top of polygon:
int firstvert=0; // start by assuming vertex 0 is at top
int min_y=poly->vlist[0].y; // find y coordinate of vertex 0
for (int index=1; index < poly->num_verts; index++)
{
// Search thru vertices
if ((poly->vlist[index].y) < min_y)
{
// is another vertex higher?
firstvert=index;
min_y=poly->vlist[index].y;
} // end if
} // end for index
// finding starting and ending vertices of first two edges:
int startvert1=firstvert; // get starting vertex of edge 1
int startvert2=firstvert; // get starting vertex of edge 2
int xstart1=poly->vlist[startvert1].x+poly->x0;
int ystart1=poly->vlist[startvert1].y+poly->y0;
int xstart2=poly->vlist[startvert2].x+poly->x0;
int ystart2=poly->vlist[startvert2].y+poly->y0;
int endvert1=startvert1-1; // get ending vertex of edge 1
if (endvert1 < 0)
endvert1=poly->num_verts-1; // check for wrap
int xend1=poly->vlist[endvert1].x+poly->x0; // get x & y coordinates
int yend1=poly->vlist[endvert1].y+poly->y0; // of ending vertices
int endvert2=startvert2+1; // get ending vertex of edge 2
if (endvert2==(poly->num_verts))
endvert2=0; // Check for wrap
int xend2=poly->vlist[endvert2].x+poly->x0; // get x & y coordinates
int yend2=poly->vlist[endvert2].y+poly->y0; // of ending vertices
// draw the polygon:
while (edgecount>0)
{
// continue drawing until all edges drawn
offset1=mempitch*ystart1+xstart1; // offset of edge 1
offset2=mempitch*ystart2+xstart2; // offset of edge 2
// initialize error terms
// for edges 1 & 2
errorterm1=0;
errorterm2=0;
// get absolute value of
if ((ydiff1=yend1-ystart1) < 0)
ydiff1=-ydiff1;
// x & y lengths of edges
if ((ydiff2=yend2-ystart2) < 0)
ydiff2=-ydiff2;
if ((xdiff1=xend1-xstart1) < 0)
{
// get value of length
xunit1=-1; // calculate X increment
xdiff1=-xdiff1;
} // end if
else
{
xunit1=1;
} // end else
if ((xdiff2=xend2-xstart2) < 0)
{
// Get value of length
xunit2=-1; // calculate X increment
xdiff2=-xdiff2;
} // end else
else
{
xunit2=1;
} // end else
// choose which of four routines to use
if (xdiff1 > ydiff1)
{
// if x length of edge 1 is greater than y length
if (xdiff2 > ydiff2)
{
// if X length of edge 2 is greater than y length
// increment edge 1 on X and edge 2 on X:
count1=xdiff1; // count for x increment on edge 1
count2=xdiff2; // count for x increment on edge 2
while (count1 && count2)
{
// continue drawing until one edge is done
// calculate edge 1:
while ((errorterm1 < xdiff1) && (count1 > 0))
{
// finished w/edge 1?
if (count1--)
{
// count down on edge 1
offset1+=xunit1; // increment pixel offset
xstart1+=xunit1;
} // end if
errorterm1+=ydiff1; // increment error term
if (errorterm1 < xdiff1)
{ // if not more than XDIFF
vbuffer[offset1]=(UCHAR)poly->color; // ...plot a pixel
} // end if
} // end while
errorterm1-=xdiff1; // if time to increment X, restore error term
// calculate edge 2:
while ((errorterm2 < xdiff2) && (count2 > 0))
{
// finished w/edge 2?
if (count2--)
{
// count down on edge 2
offset2+=xunit2; // increment pixel offset
xstart2+=xunit2;
} // end if
errorterm2+=ydiff2; // increment error term
if (errorterm2 < xdiff2)
{ // if not more than XDIFF
vbuffer[offset2]=(UCHAR)poly->color; // ...plot a pixel
} // end if
} // end while
errorterm2-=xdiff2; // if time to increment X, restore error term
// draw line from edge 1 to edge 2:
length=offset2-offset1; // determine length of horizontal line
if (length < 0)
{ // if negative...
length=-length; // make it positive
start=offset2; // and set START to edge 2
} // end if
else
start=offset1; // else set START to edge 1
for (int index=start; index < start+length+1; index++)
{ // From edge to edge...
vbuffer[index]=(UCHAR)poly->color; // ...draw the line
} // end for index
offset1+=mempitch; // advance edge 1 offset to next line
ystart1++;
offset2+=mempitch; // advance edge 2 offset to next line
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -