//////////////////////// 32位色彩下全屏和窗口的2D 数学模型图形引擎的demo /////////////////////////
////这个程序应用的是24位图在32位全频模式下的图像 场景直接切换/////////////////////////////////////
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <iostream.h>
#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"
#define WINDOW_CLASS_NAME "WINCLASS1" //全局变量宏
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_BIT 32
#define BITMAPID 0x4D42
#define WORLD_WIDTH SCREEN_WIDTH*2
#define WORLD_HEIGHT SCREEN_HEIGHT
const double PI = 3.1415926535; //const说明在程序中不能改变这个变量,必须赋初值
const int min_clip_y=0;
const int max_clip_y=SCREEN_HEIGHT-1;
const int min_clip_x=0;
const int max_clip_x=SCREEN_WIDTH-1;
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) //宏操作
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
#define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))
#define INIT_STRUCT(mstruct) { memset(&mstruct,0,sizeof(mstruct)); mstruct.dwSize=sizeof(mstruct); }
typedef unsigned char UCHAR; //8bit //自定义数据类型
typedef unsigned char UBYTE; //8bit
typedef unsigned short USHORT; //16bit
typedef unsigned short WORD; //16bit
typedef unsigned int UINT; //32bit
typedef struct tag_Vertex2DI //结构体
{
int x;
int y;
}VERTEX2DI,*PVERTEX2DI;
typedef struct tag_Vertex2DF
{
float x;
float y;
}VERTEX2DF, *PVERTEX2DF;
typedef struct tag_Polygon2D //这个结构的限制就是每个点按照逆时针顺序进行存储,不然画的时候会乱掉,连线顺序会走样的
{
int state; //当前这个凸多边形的状态
int num_vertexs; //有多少个点组成
int x0,y0; //凸多边形的中心,自身坐标原点,图形在结构体中保存属于自己的坐标系的好处就是,移动的时候只要改变中心点即可
int xv,yv; //移动速度
DWORD color; //颜色
VERTEX2DF* vlist; //这些点的用链表结构存起来,这里每个点的坐标是图形坐标系,不是世界坐标系,即存的是相对坐标
}POLYGON2D,*PPOLYGON2D;
typedef struct tag_bitmap
{
BITMAPFILEHEADER fileheader;
BITMAPINFOHEADER infoheader;
PALETTEENTRY palette[256];
BYTE* Buffer;
}BITMAP_FILE,*PBITMAP_FILE;
typedef struct tag_object
{
POLYGON2D* poly;
int cur_map;
}OBJECT,*POBJECT;
typedef struct tag_map
{
LPDIRECTDRAWSURFACE7 lpdds;
int width;
int height;
int x; //左上角的坐标
int y;
}OBJ_MAP,*POBJ_MAP;
LPDIRECTDRAW7 lpdd = NULL ; //全局变量
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL ;
LPDIRECTDRAWSURFACE7 lpddsback = NULL ;
LPDIRECTDRAWSURFACE7 lpddsbackground[2] ;
LPDIRECTDRAWCLIPPER lpddclipper = NULL ;
DDSURFACEDESC2 ddsd ;
RECT SCREEN_RECT[256] ;
LPRGNDATA region_data ;
DDBLTFX ddbltfx ;
HWND WND_APP = NULL;
HINSTANCE hinstance_app = NULL;
int Unit_Per_Line = NULL;
POLYGON2D m_pol;
OBJECT m_obj;
OBJ_MAP m_map[2];
char buf[80]; //用来屏幕输出,是GDI的,用来输出一些屏幕或者提示信息
int per_line = 0 ; //是VRAM中每行的BYTE数量
DWORD start_time = 0 ;
float cos_look[360]; //用来存放360个角度的cos和sin函数,打表查找,因为在实时系统中调用cpu的系统进行计算3角函数实在是太愚蠢的方法了
float sin_look[360];
int world_x; //世界当前坐标点,即视点位置
int world_y;
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds, DWORD color);
int Draw_Line(int x0, int y0, int x1, int y1, DWORD color, DWORD *vb_start, int lpitch);
int Clip_Line(int &x1,int &y1,int &x2, int &y2);
int Draw_Clip_Line(int x0,int y0, int x1, int y1,DWORD color,DWORD *dest_buffer, int lpitch);
int Draw_Polygon2D(PPOLYGON2D, DWORD *vbuffer, int lpitch);
int Translate_Polygon2D(PPOLYGON2D poly, int dx, int dy);
int Rotate_Polygon2D(PPOLYGON2D poly, int theta);
int Scale_Polygon2D(PPOLYGON2D poly, float sx, float sy);
int Draw_Text_GDI(char *text, int x,int y,DWORD color, LPDIRECTDRAWSURFACE7 lpdds);
int Init_Cos_Sin_Look_chart();
LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width, int height, int mem_flags, DWORD color_key);
int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height);
int Scan_Image_Bitmap( PBITMAP_FILE bitmap, LPDIRECTDRAWSURFACE7 lpdds );
int Load_Bitmap_File( PBITMAP_FILE bitmap, char *filename);
int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source,int x,int y,int width,int height,LPDIRECTDRAWSURFACE7 dest,int transparent);
LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,int num_rects,LPRECT clip_list);
LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,
int num_rects,
LPRECT clip_list)
{
int i;
if( FAILED(lpdd->CreateClipper(NULL,&lpddclipper,NULL)) )
return 0;
region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+sizeof(RECT)*num_rects); //指针要用的时候就要 分配内存的,不然这个结构根本没内存,无法赋值
//另外就是 这个 RGNDATA一定要全局变量用指针的形式来声明,因为它的内存空间 需要动态分配,根据NUM_RECTS的不同而分配不同大小的内存....
memcpy(region_data->Buffer,clip_list,sizeof(RECT)*num_rects);
region_data->rdh.dwSize = sizeof(RGNDATAHEADER);
region_data->rdh.iType = RDH_RECTANGLES;
region_data->rdh.nCount = num_rects;
region_data->rdh.nRgnSize = num_rects*sizeof(RECT);
region_data->rdh.rcBound.left = 40000 ;
region_data->rdh.rcBound.top = 40000 ;
region_data->rdh.rcBound.bottom =-40000 ;
region_data->rdh.rcBound.right =-40000 ;
for(i=0;i<num_rects;i++)
{
if( clip_list[i].left < region_data->rdh.rcBound.left )
region_data->rdh.rcBound.left=clip_list[i].left;
if( clip_list[i].top < region_data->rdh.rcBound.top )
region_data->rdh.rcBound.top=clip_list[i].top;
if( clip_list[i].right > region_data->rdh.rcBound.right )
region_data->rdh.rcBound.right=clip_list[i].right;
if( clip_list[i].bottom > region_data->rdh.rcBound.bottom )
region_data->rdh.rcBound.bottom=clip_list[i].bottom;
}
if( FAILED(lpddclipper->SetClipList(region_data,NULL)) )
return 0;
if( FAILED(lpdds->SetClipper(lpddclipper)) )
{ free(region_data);
return 0;
}
free(region_data);
return lpddclipper;
}
int Unload_Bitmap_File(PBITMAP_FILE bitmap)
{
if (bitmap->Buffer)
{
free(bitmap->Buffer);
bitmap->Buffer = NULL;
}
return(1);
}
int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source,
int x, int y,
int width, int height,
LPDIRECTDRAWSURFACE7 dest,
int transparent = 1)
{
RECT dest_rect, source_rect;
dest_rect.left = x;
dest_rect.top = y;
dest_rect.right = x+width; //这里不要减一了 比较经典的
dest_rect.bottom = y+height;
source_rect.left = 0; // 不同用1 不然寻址,就太慢了,一定从0开始快很多
source_rect.top = 0;
source_rect.right = width;
source_rect.bottom = height;
if(transparent)
{
if( FAILED(dest->Blt(&dest_rect,source,&source_rect,DDBLT_WAIT|DDBLT_KEYSRC ,NULL)) )
return 0;
}
else
{
if( FAILED(dest->Blt(&dest_rect,source,&source_rect,DDBLT_WAIT,NULL)) )
return 0;
}
return 1;
}
int Scan_Image_Bitmap( PBITMAP_FILE bitmap, LPDIRECTDRAWSURFACE7 lpdds )
{
int i;
INIT_STRUCT(ddsd);
if( FAILED(lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL)) )
return 0;
int height=ddsd.dwHeight;
int width=ddsd.dwWidth;
DWORD* dst_ptr ;