📄 t3dlib1.cpp
字号:
{
// this function waits for a vertical blank to begin
lpdd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);
// return success
return(1);
} // end DDraw_Wait_For_Vsync
///////////////////////////////////////////////////////////
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color)
{
DDBLTFX ddbltfx; // this contains the DDBLTFX structure
// clear out the structure and set the size field
DDRAW_INIT_STRUCT(ddbltfx);
// set the dwfillcolor field to the desired color
ddbltfx.dwFillColor = color;
// ready to blt to surface
lpdds->Blt(NULL, // 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 DDraw_Fill_Surface
///////////////////////////////////////////////////////////
UCHAR *DDraw_Lock_Surface(LPDIRECTDRAWSURFACE4 lpdds, int *lpitch)
{
// this function locks the sent surface and returns a pointer to it
// is this surface valid
if (!lpdds)
return(NULL);
// lock the surface
DDRAW_INIT_STRUCT(ddsd);
lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
// set the memory pitch
if (lpitch)
*lpitch = ddsd.lPitch;
// return pointer to surface
return((UCHAR *)ddsd.lpSurface);
} // end DDraw_Lock_Surface
///////////////////////////////////////////////////////////
int DDraw_Unlock_Surface(LPDIRECTDRAWSURFACE4 lpdds)
{
// this unlocks a general surface
// is this surface valid
if (!lpdds)
return(0);
// unlock the surface memory
lpdds->Unlock(NULL);
// return success
return(1);
} // end DDraw_Unlock_Surface
///////////////////////////////////////////////////////////
UCHAR *DDraw_Lock_Primary_Surface(void)
{
// this function locks the priamary surface and returns a pointer to it
// and updates the global variables primary_buffer, and primary_lpitch
// is this surface already locked
if (primary_buffer)
{
// return to current lock
return(primary_buffer);
} // end if
// lock the primary surface
DDRAW_INIT_STRUCT(ddsd);
lpddsprimary->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
// set globals
primary_buffer = (UCHAR *)ddsd.lpSurface;
primary_lpitch = ddsd.lPitch;
// return pointer to surface
return(primary_buffer);
} // end DDraw_Lock_Primary_Surface
///////////////////////////////////////////////////////////
int DDraw_Unlock_Primary_Surface(void)
{
// this unlocks the primary
// is this surface valid
if (!primary_buffer)
return(0);
// unlock the primary surface
lpddsprimary->Unlock(NULL);
// reset the primary surface
primary_buffer = NULL;
primary_lpitch = 0;
// return success
return(1);
} // end DDraw_Unlock_Primary_Surface
//////////////////////////////////////////////////////////
UCHAR *DDraw_Lock_Back_Surface(void)
{
// this function locks the secondary back surface and returns a pointer to it
// and updates the global variables secondary buffer, and back_lpitch
// is this surface already locked
if (back_buffer)
{
// return to current lock
return(back_buffer);
} // end if
// lock the primary surface
DDRAW_INIT_STRUCT(ddsd);
lpddsback->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
// set globals
back_buffer = (UCHAR *)ddsd.lpSurface;
back_lpitch = ddsd.lPitch;
// return pointer to surface
return(back_buffer);
} // end DDraw_Lock_Back_Surface
///////////////////////////////////////////////////////////
int DDraw_Unlock_Back_Surface(void)
{
// this unlocks the secondary
// is this surface valid
if (!back_buffer)
return(0);
// unlock the secondary surface
lpddsback->Unlock(NULL);
// reset the secondary surface
back_buffer = NULL;
back_lpitch = 0;
// return success
return(1);
} // end DDraw_Unlock_Back_Surface
///////////////////////////////////////////////////////////
DWORD Get_Clock(void)
{
// this function returns the current tick count
// return time
return(GetTickCount());
} // end Get_Clock
///////////////////////////////////////////////////////////
DWORD Start_Clock(void)
{
// this function starts the clock, that is, saves the current
// count, use in conjunction with Wait_Clock()
return(start_clock_count = Get_Clock());
} // end Start_Clock
////////////////////////////////////////////////////////////
DWORD Wait_Clock(DWORD count)
{
// this function is used to wait for a specific number of clicks
// since the call to Start_Clock
while((Get_Clock() - start_clock_count) < count);
return(Get_Clock());
} // end Wait_Clock
///////////////////////////////////////////////////////////
int Draw_Clip_Line(int x0,int y0, int x1, int y1,UCHAR color,
UCHAR *dest_buffer, int lpitch)
{
// this function draws a wireframe triangle
int cxs, cys,
cxe, cye;
// clip and draw each line
cxs = x0;
cys = y0;
cxe = x1;
cye = y1;
// clip the line
if (Clip_Line(cxs,cys,cxe,cye))
Draw_Line(cxs, cys, cxe,cye,color,dest_buffer,lpitch);
// return success
return(1);
} // end Draw_Clip_Line
///////////////////////////////////////////////////////////
int Clip_Line(int &x1,int &y1,int &x2, int &y2)
{
// this function clips the sent line using the globally defined clipping
// region
// internal clipping codes
#define CLIP_CODE_C 0x0000
#define CLIP_CODE_N 0x0008
#define CLIP_CODE_S 0x0004
#define CLIP_CODE_E 0x0002
#define CLIP_CODE_W 0x0001
#define CLIP_CODE_NE 0x000a
#define CLIP_CODE_SE 0x0006
#define CLIP_CODE_NW 0x0009
#define CLIP_CODE_SW 0x0005
int xc1=x1,
yc1=y1,
xc2=x2,
yc2=y2;
int p1_code=0,
p2_code=0;
// determine codes for p1 and p2
if (y1 < min_clip_y)
p1_code|=CLIP_CODE_N;
else
if (y1 > max_clip_y)
p1_code|=CLIP_CODE_S;
if (x1 < min_clip_x)
p1_code|=CLIP_CODE_W;
else
if (x1 > max_clip_x)
p1_code|=CLIP_CODE_E;
if (y2 < min_clip_y)
p2_code|=CLIP_CODE_N;
else
if (y2 > max_clip_y)
p2_code|=CLIP_CODE_S;
if (x2 < min_clip_x)
p2_code|=CLIP_CODE_W;
else
if (x2 > max_clip_x)
p2_code|=CLIP_CODE_E;
// try and trivially reject
if ((p1_code & p2_code))
return(0);
// test for totally visible, if so leave points untouched
if (p1_code==0 && p2_code==0)
return(1);
// determine end clip point for p1
switch(p1_code)
{
case CLIP_CODE_C: break;
case CLIP_CODE_N:
{
yc1 = min_clip_y;
xc1 = x1 + 0.5+(min_clip_y-y1)*(x2-x1)/(y2-y1);
} break;
case CLIP_CODE_S:
{
yc1 = max_clip_y;
xc1 = x1 + 0.5+(max_clip_y-y1)*(x2-x1)/(y2-y1);
} break;
case CLIP_CODE_W:
{
xc1 = min_clip_x;
yc1 = y1 + 0.5+(min_clip_x-x1)*(y2-y1)/(x2-x1);
} break;
case CLIP_CODE_E:
{
xc1 = max_clip_x;
yc1 = y1 + 0.5+(max_clip_x-x1)*(y2-y1)/(x2-x1);
} break;
// these cases are more complex, must compute 2 intersections
case CLIP_CODE_NE:
{
// north hline intersection
yc1 = min_clip_y;
xc1 = x1 + 0.5+(min_clip_y-y1)*(x2-x1)/(y2-y1);
// test if intersection is valid, of so then done, else compute next
if (xc1 < min_clip_x || xc1 > max_clip_x)
{
// east vline intersection
xc1 = max_clip_x;
yc1 = y1 + 0.5+(max_clip_x-x1)*(y2-y1)/(x2-x1);
} // end if
} break;
case CLIP_CODE_SE:
{
// south hline intersection
yc1 = max_clip_y;
xc1 = x1 + 0.5+(max_clip_y-y1)*(x2-x1)/(y2-y1);
// test if intersection is valid, of so then done, else compute next
if (xc1 < min_clip_x || xc1 > max_clip_x)
{
// east vline intersection
xc1 = max_clip_x;
yc1 = y1 + 0.5+(max_clip_x-x1)*(y2-y1)/(x2-x1);
} // end if
} break;
case CLIP_CODE_NW:
{
// north hline intersection
yc1 = min_clip_y;
xc1 = x1 + 0.5+(min_clip_y-y1)*(x2-x1)/(y2-y1);
// test if intersection is valid, of so then done, else compute next
if (xc1 < min_clip_x || xc1 > max_clip_x)
{
xc1 = min_clip_x;
yc1 = y1 + 0.5+(min_clip_x-x1)*(y2-y1)/(x2-x1);
} // end if
} break;
case CLIP_CODE_SW:
{
// south hline intersection
yc1 = max_clip_y;
xc1 = x1 + 0.5+(max_clip_y-y1)*(x2-x1)/(y2-y1);
// test if intersection is valid, of so then done, else compute next
if (xc1 < min_clip_x || xc1 > max_clip_x)
{
xc1 = min_clip_x;
yc1 = y1 + 0.5+(min_clip_x-x1)*(y2-y1)/(x2-x1);
} // end if
} break;
default:break;
} // end switch
// determine clip point for p2
switch(p2_code)
{
case CLIP_CODE_C: break;
case CLIP_CODE_N:
{
yc2 = min_clip_y;
xc2 = x2 + (min_clip_y-y2)*(x1-x2)/(y1-y2);
} break;
case CLIP_CODE_S:
{
yc2 = max_clip_y;
xc2 = x2 + (max_clip_y-y2)*(x1-x2)/(y1-y2);
} break;
case CLIP_CODE_W:
{
xc2 = min_clip_x;
yc2 = y2 + (min_clip_x-x2)*(y1-y2)/(x1-x2);
} break;
case CLIP_CODE_E:
{
xc2 = max_clip_x;
yc2 = y2 + (max_clip_x-x2)*(y1-y2)/(x1-x2);
} break;
// these cases are more complex, must compute 2 intersections
case CLIP_CODE_NE:
{
// north hline intersection
yc2 = min_clip_y;
xc2 = x2 + 0.5+(min_clip_y-y2)*(x1-x2)/(y1-y2);
// test if intersection is valid, of so then done, else compute next
if (xc2 < min_clip_x || xc2 > max_clip_x)
{
// east vline intersection
xc2 = max_clip_x;
yc2 = y2 + 0.5+(max_clip_x-x2)*(y1-y2)/(x1-x2);
} // end if
} break;
case CLIP_CODE_SE:
{
// south hline intersection
yc2 = max_clip_y;
xc2 = x2 + 0.5+(max_clip_y-y2)*(x1-x2)/(y1-y2);
// test if intersection is valid, of so then done, else compute next
if (xc2 < min_clip_x || xc2 > max_clip_x)
{
// east vline intersection
xc2 = max_clip_x;
yc2 = y2 + 0.5+(max_clip_x-x2)*(y1-y2)/(x1-x2);
} // end if
} break;
case CLIP_CODE_NW:
{
// north hline intersection
yc2 = min_clip_y;
xc2 = x2 + 0.5+(min_clip_y-y2)*(x1-x2)/(y1-y2);
// test if intersection is valid, of so then done, else compute next
if (xc2 < min_clip_x || xc2 > max_clip_x)
{
xc2 = min_clip_x;
yc2 = y2 + 0.5+(min_clip_x-x2)*(y1-y2)/(x1-x2);
} // end if
} break;
case CLIP_CODE_SW:
{
// south hline intersection
yc2 = max_clip_y;
xc2 = x2 + 0.5+(max_clip_y-y2)*(x1-x2)/(y1-y2);
// test if intersection is valid, of so then done, else compute next
if (xc2 < min_clip_x || xc2 > max_clip_x)
{
xc2 = min_clip_x;
yc2 = y2 + 0.5+(min_clip_x-x2)*(y1-y2)/(x1-x2);
} // end if
} break;
default:break;
} // end switch
// do bounds check
if ((xc1 < min_clip_x) || (xc1 > max_clip_x) ||
(yc1 < min_clip_y) || (yc1 > max_clip_y) ||
(xc2 < min_clip_x) || (xc2 > max_clip_x) ||
(yc2 < min_clip_y) || (yc2 > max_clip_y) )
{
return(0);
} // end if
// store vars back
x1 = xc1;
y1 = yc1;
x2 = xc2;
y2 = yc2;
return(1);
} // end Clip_Line
///////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -