⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t3dlib8.cpp

📁 3D游戏编程大师技巧第十章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// 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 + -