?? demo8_8.cpp
字號(hào):
// DEMO8_8.CPP 8-bit quad drawing 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;
// fixed point mathematics constants
#define FIXP16_SHIFT 16
#define FIXP16_MAG 65536
#define FIXP16_DP_MASK 0x0000ffff
#define FIXP16_WP_MASK 0xffff0000
#define FIXP16_ROUND_UP 0x00008000
// 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);
// 2d 8-bit triangle rendering
void Draw_Top_Tri(int x1,int y1,int x2,int y2, int x3,int y3,int color,UCHAR *dest_buffer, int mempitch);
void Draw_Bottom_Tri(int x1,int y1, int x2,int y2, int x3,int y3,int color,UCHAR *dest_buffer, int mempitch);
void Draw_Top_TriFP(int x1,int y1,int x2,int y2, int x3,int y3,int color,UCHAR *dest_buffer, int mempitch);
void Draw_Bottom_TriFP(int x1,int y1, int x2,int y2, int x3,int y3,int color,UCHAR *dest_buffer, int mempitch);
void Draw_Triangle_2D(int x1,int y1,int x2,int y2,int x3,int y3,
int color,UCHAR *dest_buffer, int mempitch);
void Draw_TriangleFP_2D(int x1,int y1,int x2,int y2,int x3,int y3,
int color,UCHAR *dest_buffer, int mempitch);
inline void Draw_QuadFP_2D(int x0,int y0,int x1,int y1,
int x2,int y2,int x3, int y3,
int color,UCHAR *dest_buffer, 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 ////////////////////////////////////////////////
inline void Draw_QuadFP_2D(int x0,int y0,
int x1,int y1,
int x2,int y2,
int x3, int y3,
int color,
UCHAR *dest_buffer, int mempitch)
{
// this function draws a 2D quadrilateral
// simply call the triangle function 2x, let it do all the work
Draw_TriangleFP_2D(x0,y0,x1,y1,x3,y3,color,dest_buffer,mempitch);
Draw_TriangleFP_2D(x1,y1,x2,y2,x3,y3,color,dest_buffer,mempitch);
} // end Draw_QuadFP_2D
////////////////////////////////////////////////////////////////////////////////
void Draw_Top_TriFP(int x1,int y1,
int x2,int y2,
int x3,int y3,
int color,
UCHAR *dest_buffer, int mempitch)
{
// this function draws a triangle that has a flat top using fixed point math
int dx_right, // the dx/dy ratio of the right edge of line
dx_left, // the dx/dy ratio of the left edge of line
xs,xe, // the starting and ending points of the edges
height; // the height of the triangle
int temp_x, // used during sorting as temps
temp_y,
right, // used by clipping
left;
UCHAR *dest_addr;
// test for degenerate
if (y1==y3 || y2==y3)
return;
// test order of x1 and x2
if (x2 < x1)
{
temp_x = x2;
x2 = x1;
x1 = temp_x;
} // end if swap
// compute delta's
height = y3-y1;
dx_left = ((x3-x1)<<FIXP16_SHIFT)/height;
dx_right = ((x3-x2)<<FIXP16_SHIFT)/height;
// set starting points
xs = (x1<<FIXP16_SHIFT);
xe = (x2<<FIXP16_SHIFT);
// perform y clipping
if (y1<min_clip_y)
{
// compute new xs and ys
xs = xs+dx_left*(-y1+min_clip_y);
xe = xe+dx_right*(-y1+min_clip_y);
// reset y1
y1=min_clip_y;
} // end if top is off screen
if (y3>max_clip_y)
y3=max_clip_y;
// compute starting address in video memory
dest_addr = dest_buffer+y1*mempitch;
// test if x clipping is needed
if (x1>=min_clip_x && x1<=max_clip_x &&
x2>=min_clip_x && x2<=max_clip_x &&
x3>=min_clip_x && x3<=max_clip_x)
{
// draw the triangle
for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
memset((UCHAR *)dest_addr+((xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT),
color, (((xe-xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT)+1));
// adjust starting point and ending point
xs+=dx_left;
xe+=dx_right;
} // end for
} // end if no x clipping needed
else
{
// clip x axis with slower version
// draw the triangle
for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
// do x clip
left = ((xs+FIXP16_ROUND_UP)>>16);
right = ((xe+FIXP16_ROUND_UP)>>16);
// adjust starting point and ending point
xs+=dx_left;
xe+=dx_right;
// clip line
if (left < min_clip_x)
{
left = min_clip_x;
if (right < min_clip_x)
continue;
}
if (right > max_clip_x)
{
right = max_clip_x;
if (left > max_clip_x)
continue;
}
memset((UCHAR *)dest_addr+(unsigned int)left,
color,(unsigned int)(right-left+1));
} // end for
} // end else x clipping needed
} // end Draw_Top_TriFP
/////////////////////////////////////////////////////////////////////////////
void Draw_Bottom_TriFP(int x1,int y1,
int x2,int y2,
int x3,int y3,
int color,
UCHAR *dest_buffer, int mempitch)
{
// this function draws a triangle that has a flat bottom using fixed point math
int dx_right, // the dx/dy ratio of the right edge of line
dx_left, // the dx/dy ratio of the left edge of line
xs,xe, // the starting and ending points of the edges
height; // the height of the triangle
int temp_x, // used during sorting as temps
temp_y,
right, // used by clipping
left;
UCHAR *dest_addr;
if (y1==y2 || y1==y3)
return;
// test order of x1 and x2
if (x3 < x2)
{
temp_x = x2;
x2 = x3;
x3 = temp_x;
} // end if swap
// compute delta's
height = y3-y1;
dx_left = ((x2-x1)<<FIXP16_SHIFT)/height;
dx_right = ((x3-x1)<<FIXP16_SHIFT)/height;
// set starting points
xs = (x1<<FIXP16_SHIFT);
xe = (x1<<FIXP16_SHIFT);
// perform y clipping
if (y1<min_clip_y)
{
// compute new xs and ys
xs = xs+dx_left*(-y1+min_clip_y);
xe = xe+dx_right*(-y1+min_clip_y);
// reset y1
y1=min_clip_y;
} // end if top is off screen
if (y3>max_clip_y)
y3=max_clip_y;
// compute starting address in video memory
dest_addr = dest_buffer+y1*mempitch;
// test if x clipping is needed
if (x1>=min_clip_x && x1<=max_clip_x &&
x2>=min_clip_x && x2<=max_clip_x &&
x3>=min_clip_x && x3<=max_clip_x)
{
// draw the triangle
for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
memset((UCHAR *)dest_addr+((xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT),
color, (((xe-xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT)+1));
// adjust starting point and ending point
xs+=dx_left;
xe+=dx_right;
} // end for
} // end if no x clipping needed
else
{
// clip x axis with slower version
// draw the triangle
for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
// do x clip
left = ((xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT);
right = ((xe+FIXP16_ROUND_UP)>>FIXP16_SHIFT);
// adjust starting point and ending point
xs+=dx_left;
xe+=dx_right;
// clip line
if (left < min_clip_x)
{
left = min_clip_x;
if (right < min_clip_x)
continue;
}
if (right > max_clip_x)
{
right = max_clip_x;
if (left > max_clip_x)
continue;
}
memset((UCHAR *)dest_addr+left,
color, (right-left+1));
} // end for
} // end else x clipping needed
} // end Draw_Bottom_TriFP
////////////////////////////////////////////////////////////////
void Draw_Top_Tri(int x1,int y1,
int x2,int y2,
int x3,int y3,
int color,
UCHAR *dest_buffer, int mempitch)
{
// this function draws a triangle that has a flat top
float dx_right, // the dx/dy ratio of the right edge of line
dx_left, // the dx/dy ratio of the left edge of line
xs,xe, // the starting and ending points of the edges
height; // the height of the triangle
int temp_x, // used during sorting as temps
temp_y,
right, // used by clipping
left;
// destination address of next scanline
UCHAR *dest_addr = NULL;
// test order of x1 and x2
if (x2 < x1)
{
temp_x = x2;
x2 = x1;
x1 = temp_x;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -