Gönderen Konu: Ray Casting  (Okunma sayısı 11528 defa)

Ray Casting

« : 28.11.2003 19:15:07 »
Hızlı düğmeleri aç

skate

İleti: 5.245

A Sinner Scener
Çevrimdışı
  • Administrator
  • *****
  • Hero Member
    • Profili Görüntüle
    • http://www.akaydin.com/
Tüm code'u vermiyorum ancak belki fikir alan olur diye önemli bölümleri yayinliyorum. Benim ilk TC++ 3.0'dan yazdigim ve hemen hemen hic optimizasyona sahip olmayan (ki komik bir de mantik hatasi var olayi yavashlatan) Ray Casting engine'in source'u. Elinizde bulunsun. Yeni versionu çok komplex bir yapiya sahip. Parça pinçik ettim fonksiyonlari. Bu daha anlasilir (umarim). Eger ilgilenir ancak bazi yerleri anlayamazsaniz (yeterli remark yok) buraya mesaj atin acikliim...

Class kullanma sebebi multi-player tasarimi içindi ancak bu versionda MW dogrudan kullaniliyor. Siz RenderScene() fonksiyonuna parametre ekleyerek (örnek WORLD *WLD) daha sonra tim MW. 'lar1 WLD-> ile replace ederek olayi adam edebilirsiniz v.s. Gerisi size kalmish...

Kod: [Seç]
// Includes

#include <conio.h>
#include <math.h>
#include <string.h>
#include <dos.h>

// Definitions

#define BLOCK_SIZE 64
#define BLOCK_AND 63
#define BIT_SHIFT 6
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 200
#define SCREEN_WMID 160
#define SCREEN_HMID 100
#define MAP_WIDTH 30
#define MAP_HEIGHT 30
#define PI 3.14159265
#define NUM_OF_TEXTURES 3
#define DIST_TO_WALL 30
#define ANGLE_0 0
#define ANGLE_90 480
#define ANGLE_180 960
#define ANGLE_270 1440
#define ANGLE_360 1920
#define WALK_SPEED 7
#define TURN_SPEED 7

char far *VIDEO = (char far *) MK_FP(0xa000, 0);
char far *VIDEO2 = (char far *) MK_FP(0xe000, 0);
unsigned char TextBig[BLOCK_SIZE][BLOCK_SIZE][NUM_OF_TEXTURES];
unsigned char TextSmall[BLOCK_SIZE >> 1][BLOCK_SIZE >> 1][NUM_OF_TEXTURES];
float CosT[ANGLE_360], SinT[ANGLE_360], TanT[ANGLE_360];

// World Structre

struct WORLD
{
short gx, gy, tx, ty, sheight, ang, angbl, tnx, tny;
float disth, distv, dist, cdist, vx, vy, rx, ry, isx, isy;
} MW;

// Render Scene

void RenderScene()
{
char cln;
unsigned short i, noft;
ClrScreen(); // !!!user defined!!!
MW.angbl = MW.ang + SCREEN_WMID;
if(MW.angbl >= ANGLE_360)
 MW.angbl -= ANGLE_360;
for(i = 0; i < SCREEN_WIDTH; i++)
{
 // horiz check
 MW.vx = MW.rx;
 MW.vy = MW.ry;
 do
 {
  MW.isy = (((int)MW.vy >> BIT_SHIFT) << BIT_SHIFT) - 1; // optimized
  if(MW.angbl >= ANGLE_180)
  MW.isy += 65; // optimized
  if(TanT[MW.angbl] <= -.001 || TanT[MW.angbl] >= .001)
  MW.isx = MW.vx + (MW.vy - MW.isy) / TanT[MW.angbl]; // optimized
  MW.gx = (int)MW.isx >> BIT_SHIFT; // optimized
  MW.gy = (int)MW.isy >> BIT_SHIFT; // optimized
  MW.vx = MW.isx;
  MW.vy = MW.isy;
 } while(MapBl[MW.gy * MAP_WIDTH + MW.gx] == 0 && MW.gy > 0 && MW.gy < MAP_HEIGHT && MW.gx > 0 && MW.gx < MAP_WIDTH);
 MW.disth = sqrt((MW.rx - MW.vx) * (MW.rx - MW.vx) + (MW.ry - MW.vy) * (MW.ry - MW.vy));
 MW.tx = (int)MW.vx & BLOCK_AND; // optimized
 MW.tnx = MapBl[MW.gy * MAP_WIDTH + MW.gx];
 // vert check
 MW.vx = MW.rx;
 MW.vy = MW.ry;
 do
 {
  MW.isx = (((int)MW.vx >> BIT_SHIFT) << BIT_SHIFT) - 1; // optimized
  if(MW.angbl <= ANGLE_90 || MW.angbl > ANGLE_270)
  MW.isx += 65; // optimized
  MW.isy = MW.vy + (MW.vx - MW.isx) * TanT[MW.angbl]; // optimized
  MW.gx = (int)MW.isx >> BIT_SHIFT; // optimized
  MW.gy = (int)MW.isy >> BIT_SHIFT; // optimized
  MW.vx = MW.isx;
  MW.vy = MW.isy;
 } while(MapBl[MW.gy * MAP_WIDTH + MW.gx] == 0 && MW.gy > 0 && MW.gy < MAP_HEIGHT && MW.gx > 0 && MW.gx < MAP_WIDTH);
 MW.distv = sqrt((MW.rx - MW.vx) * (MW.rx - MW.vx) + (MW.ry - MW.vy) * (MW.ry - MW.vy));
 MW.ty = (int)MW.vy & BLOCK_AND; // optimized
 MW.tny = MapBl[MW.gy * MAP_WIDTH + MW.gx];
  if(MW.distv > MW.disth)
 {
  MW.dist = MW.disth;
  cln = MW.tx;
  noft = MW.tnx - 1;
 }
 else
 {
  MW.dist = MW.distv;
  cln = MW.ty;
  noft = MW.tny - 1;
 }
 MW.cdist = MW.dist * CosT[abs(MW.angbl - MW.ang)];
 MW.sheight = 17728.0 / MW.cdist; // optimized (64 * 277 = 17728)
 VertLine(i, SCREEN_HMID - (MW.sheight >> 1), SCREEN_HMID + (MW.sheight >> 1), cln, noft);
 MW.angbl--;
 if(MW.angbl < ANGLE_0)
  MW.angbl += ANGLE_360;
}
WaitFrameEnd();
_fmemcpy(VIDEO, VIDEO2, 64000);
}


Umarim isinize yarar...