📄 t3dlib8.cpp
字号:
// T3DLIB8.CPP - clipping, terrain, and new lighting
// I N C L U D E S ///////////////////////////////////////////////////////////
#define DEBUG_ON
#define WIN32_LEAN_AND_MEAN
#include <windows.h> // include important windows stuff
#include <windowsx.h>
#include <mmsystem.h>
#include <objbase.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 <direct.h>
#include <wchar.h>
#include <limits.h>
#include <float.h>
#include <search.h>
#include <ddraw.h> // needed for defs in T3DLIB1.H
#include "T3DLIB1.H"
#include "T3DLIB4.H"
#include "T3DLIB5.H"
#include "T3DLIB6.H"
#include "T3DLIB7.H"
#include "T3DLIB8.H"
// DEFINES //////////////////////////////////////////////////////////////////
// GLOBALS //////////////////////////////////////////////////////////////////
LIGHTV2 lights2[MAX_LIGHTS]; // lights in system
// FUNCTIONS ////////////////////////////////////////////////////////////////
void Clip_Polys_RENDERLIST4DV2(RENDERLIST4DV2_PTR rend_list, CAM4DV1_PTR cam, int clip_flags)
{
// this function clips the polygons in the list against the requested clipping planes
// and sets the clipped flag on the poly, so it's not rendered
// note the function ONLY performs clipping on the near and far clipping plane
// but will perform trivial tests on the top/bottom, left/right clipping planes
// if a polygon is completely out of the viewing frustrum in these cases, it will
// be culled, however, this test isn't as effective on games based on objects since
// in most cases objects that are visible have polygons that are visible, but in the
// case where the polygon list is based on a large object that ALWAYS has some portion
// visible, testing for individual polys is worthwhile..
// the function assumes the polygons have been transformed into camera space
// internal clipping codes
#define CLIP_CODE_GZ 0x0001 // z > z_max
#define CLIP_CODE_LZ 0x0002 // z < z_min
#define CLIP_CODE_IZ 0x0004 // z_min < z < z_max
#define CLIP_CODE_GX 0x0001 // x > x_max
#define CLIP_CODE_LX 0x0002 // x < x_min
#define CLIP_CODE_IX 0x0004 // x_min < x < x_max
#define CLIP_CODE_GY 0x0001 // y > y_max
#define CLIP_CODE_LY 0x0002 // y < y_min
#define CLIP_CODE_IY 0x0004 // y_min < y < y_max
#define CLIP_CODE_NULL 0x0000
int vertex_ccodes[3]; // used to store clipping flags
int num_verts_in; // number of vertices inside
int v0, v1, v2; // vertex indices
float z_factor, // used in clipping computations
z_test; // used in clipping computations
float xi, yi, x01i, y01i, x02i, y02i, // vertex intersection points
t1, t2, // parametric t values
ui, vi, u01i, v01i, u02i, v02i; // texture intersection points
int last_poly_index, // last valid polygon in polylist
insert_poly_index; // the current position new polygons are inserted at
VECTOR4D u,v,n; // used in vector calculations
POLYF4DV2 temp_poly; // used when we need to split a poly into 2 polys
// set last, current insert index to end of polygon list
// we don't want to clip poly's two times
insert_poly_index = last_poly_index = rend_list->num_polys;
// traverse polygon list and clip/cull polygons
for (int poly = 0; poly < last_poly_index; poly++)
{
// acquire current polygon
POLYF4DV2_PTR curr_poly = rend_list->poly_ptrs[poly];
// is this polygon valid?
// test this polygon if and only if it's not clipped, not culled,
// active, and visible and not 2 sided. Note we test for backface in the event that
// a previous call might have already determined this, so why work
// harder!
if ((curr_poly==NULL) || !(curr_poly->state & POLY4DV2_STATE_ACTIVE) ||
(curr_poly->state & POLY4DV2_STATE_CLIPPED ) ||
(curr_poly->state & POLY4DV2_STATE_BACKFACE) )
continue; // move onto next poly
// clip/cull to x-planes
if (clip_flags & CLIP_POLY_X_PLANE)
{
// clip/cull only based on x clipping planes
// for each vertice determine if it's in the clipping region or beyond it and
// set the appropriate clipping code
// we do NOT clip the final triangles, we are only trying to trivally reject them
// we are going to clip polygons in the rasterizer to the screen rectangle
// but we do want to clip/cull polys that are totally outside the viewfrustrum
// since we are clipping to the right/left x-planes we need to use the FOV or
// the plane equations to find the z value that at the current x position would
// be outside the plane
z_factor = (0.5)*cam->viewplane_width/cam->view_dist;
// vertex 0
z_test = z_factor*curr_poly->tvlist[0].z;
if (curr_poly->tvlist[0].x > z_test)
vertex_ccodes[0] = CLIP_CODE_GX;
else
if (curr_poly->tvlist[0].x < -z_test)
vertex_ccodes[0] = CLIP_CODE_LX;
else
vertex_ccodes[0] = CLIP_CODE_IX;
// vertex 1
z_test = z_factor*curr_poly->tvlist[1].z;
if (curr_poly->tvlist[1].x > z_test)
vertex_ccodes[1] = CLIP_CODE_GX;
else
if (curr_poly->tvlist[1].x < -z_test)
vertex_ccodes[1] = CLIP_CODE_LX;
else
vertex_ccodes[1] = CLIP_CODE_IX;
// vertex 2
z_test = z_factor*curr_poly->tvlist[2].z;
if (curr_poly->tvlist[2].x > z_test)
vertex_ccodes[2] = CLIP_CODE_GX;
else
if (curr_poly->tvlist[2].x < -z_test)
vertex_ccodes[2] = CLIP_CODE_LX;
else
vertex_ccodes[2] = CLIP_CODE_IX;
// test for trivial rejections, polygon completely beyond right or left
// clipping planes
if ( ((vertex_ccodes[0] == CLIP_CODE_GX) &&
(vertex_ccodes[1] == CLIP_CODE_GX) &&
(vertex_ccodes[2] == CLIP_CODE_GX) ) ||
((vertex_ccodes[0] == CLIP_CODE_LX) &&
(vertex_ccodes[1] == CLIP_CODE_LX) &&
(vertex_ccodes[2] == CLIP_CODE_LX) ) )
{
// clip the poly completely out of frustrum
SET_BIT(curr_poly->state, POLY4DV2_STATE_CLIPPED);
// move on to next polygon
continue;
} // end if
} // end if x planes
// clip/cull to y-planes
if (clip_flags & CLIP_POLY_Y_PLANE)
{
// clip/cull only based on y clipping planes
// for each vertice determine if it's in the clipping region or beyond it and
// set the appropriate clipping code
// we do NOT clip the final triangles, we are only trying to trivally reject them
// we are going to clip polygons in the rasterizer to the screen rectangle
// but we do want to clip/cull polys that are totally outside the viewfrustrum
// since we are clipping to the top/bottom y-planes we need to use the FOV or
// the plane equations to find the z value that at the current y position would
// be outside the plane
z_factor = (0.5)*cam->viewplane_width/cam->view_dist;
// vertex 0
z_test = z_factor*curr_poly->tvlist[0].z;
if (curr_poly->tvlist[0].y > z_test)
vertex_ccodes[0] = CLIP_CODE_GY;
else
if (curr_poly->tvlist[0].y < -z_test)
vertex_ccodes[0] = CLIP_CODE_LY;
else
vertex_ccodes[0] = CLIP_CODE_IY;
// vertex 1
z_test = z_factor*curr_poly->tvlist[1].z;
if (curr_poly->tvlist[1].y > z_test)
vertex_ccodes[1] = CLIP_CODE_GY;
else
if (curr_poly->tvlist[1].y < -z_test)
vertex_ccodes[1] = CLIP_CODE_LY;
else
vertex_ccodes[1] = CLIP_CODE_IY;
// vertex 2
z_test = z_factor*curr_poly->tvlist[2].z;
if (curr_poly->tvlist[2].y > z_test)
vertex_ccodes[2] = CLIP_CODE_GY;
else
if (curr_poly->tvlist[2].x < -z_test)
vertex_ccodes[2] = CLIP_CODE_LY;
else
vertex_ccodes[2] = CLIP_CODE_IY;
// test for trivial rejections, polygon completely beyond top or bottom
// clipping planes
if ( ((vertex_ccodes[0] == CLIP_CODE_GY) &&
(vertex_ccodes[1] == CLIP_CODE_GY) &&
(vertex_ccodes[2] == CLIP_CODE_GY) ) ||
((vertex_ccodes[0] == CLIP_CODE_LY) &&
(vertex_ccodes[1] == CLIP_CODE_LY) &&
(vertex_ccodes[2] == CLIP_CODE_LY) ) )
{
// clip the poly completely out of frustrum
SET_BIT(curr_poly->state, POLY4DV2_STATE_CLIPPED);
// move on to next polygon
continue;
} // end if
} // end if y planes
// clip/cull to z planes
if (clip_flags & CLIP_POLY_Z_PLANE)
{
// clip/cull only based on z clipping planes
// for each vertice determine if it's in the clipping region or beyond it and
// set the appropriate clipping code
// then actually clip all polygons to the near clipping plane, this will result
// in at most 1 additional triangle
// reset vertex counters, these help in classification
// of the final triangle
num_verts_in = 0;
// vertex 0
if (curr_poly->tvlist[0].z > cam->far_clip_z)
{
vertex_ccodes[0] = CLIP_CODE_GZ;
}
else
if (curr_poly->tvlist[0].z < cam->near_clip_z)
{
vertex_ccodes[0] = CLIP_CODE_LZ;
}
else
{
vertex_ccodes[0] = CLIP_CODE_IZ;
num_verts_in++;
}
// vertex 1
if (curr_poly->tvlist[1].z > cam->far_clip_z)
{
vertex_ccodes[1] = CLIP_CODE_GZ;
}
else
if (curr_poly->tvlist[1].z < cam->near_clip_z)
{
vertex_ccodes[1] = CLIP_CODE_LZ;
}
else
{
vertex_ccodes[1] = CLIP_CODE_IZ;
num_verts_in++;
}
// vertex 2
if (curr_poly->tvlist[2].z > cam->far_clip_z)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -