home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 16
/
CD_ASCQ_16_0994.iso
/
news
/
vr386
/
renderer
/
horizon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-26
|
7KB
|
262 lines
/* Horizon and window/screen clearing */
/* Written by Dave STampe, December 1993 */
/* All algortims and code in this module by Dave Stampe */
/*
This code is part of the REND386 project, created by Dave Stampe and
Bernie Roehl.
Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
May be freely used to write software for release into the public domain;
all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
for permission to incorporate any part of this software into their
products! Usually there is no charge for under 50-100 items for
low-cost or shareware, and terms are reasonable. Any royalties are used
for development, so equipment is often acceptable payment.
ATTRIBUTION: If you use any part of this source code or the libraries
in your projects, you must give attribution to REND386, Dave Stampe,
and Bernie Roehl in your documentation, source code, and at startup
of your program. Let's keep the freeware ball rolling! No more
code ripoffs please.
CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
See the COPYRITE.H file for more information.
*/
/* Contact: dstampe@sunee.waterloo.edu */
#include <stdio.h>
#include <dos.h>
#include <stdlib.h> /* labs */
#include "3dstruct.h"
#include "rendpriv.h"
#include "renderer.h"
#include "intmath.h"
#include "f3dkitd.h" // for block clears
static void band_horizon(VIEW *v, int page, long step, int nstep, int *colorlist)
{
int l = v->left;
int r = v->right;
int t = v->top;
int b = v->bottom;
int i, j, k;
int vert = 0;
int mfup, mfdn;
int upright;
int cd = 1; /* step direction in thru color list */
int vx[10],vy[10];
long offset;
int olx, orx, oly, ory;
int nlx, nrx, nly, nry;
if(nstep==0) /* just clear screen totally */
{
clr_block(l, t, r, b-1, page, colorlist[0]);
return;
}
if(nstep>20) nstep = 20;
offset = -(step * nstep)/2; /* uppermost position */
mfup = (above_horizon(l,t,v,offset) ) + /* corners with top of horizon */
(above_horizon(r,t,v,offset)<<1) +
(above_horizon(l,b,v,offset)<<2) +
(above_horizon(r,b,v,offset)<<3) ;
mfdn = (above_horizon(l,t,v,-offset) ) + /* corners with bot of horizon */
(above_horizon(r,t,v,-offset)<<1) +
(above_horizon(l,b,v,-offset)<<2) +
(above_horizon(r,b,v,-offset)<<3) ;
if(mfup==15) /* sky only case */
{
clr_block(l, t, r, b-1, page, colorlist[0]);
return;
}
if(mfdn==0) /* ground only case */
{
clr_block(l, t, r, b-1, page, colorlist[nstep]);
return;
}
if(labs(v->eye_xform[0][1]) > labs(v->eye_xform[1][1]) ) /* check slope */
{
vert++; /* horizon is more vertical than horizontal */
upright = (v->eye_xform[0][1]>=0); /* sky on left */
}
else upright = (v->eye_xform[1][1]>=0); /* sky on top */
if(!upright) /* will work backwards through colors */
{ /* and through horizon offsets */
cd = -1;
colorlist += nstep;
step = -step;
offset = step-offset;
}
if(!vert)
{
olx = l; /* forcing top... */
orx = r;
oly = ory = -32000;
}
else
{
oly = t; /* forcing left... */
ory = b;
olx = orx = 32000;
}
for(i=0;i<nstep;i++)
{
int nlx, nrx, nly, nry;
/* compute new division */
if(!vert)
{
nlx = l;
nrx = r;
nly = y_horizon(l, v, offset);
nry = y_horizon(r, v, offset);
}
else
{
nly = t;
nry = b;
nlx = x_horizon(t, v, offset);
nrx = x_horizon(b, v, offset);
}
vx[0] = orx; // clip and render 4-vertex poly (most common)
vy[0] = ory;
vx[1] = olx;
vy[1] = oly;
vx[2] = nlx;
vy[2] = nly;
vx[3] = nrx;
vy[3] = nry;
render_ext_poly(4, vx, vy, *colorlist);
colorlist += cd;
olx = nlx;
oly = nly;
orx = nrx;
ory = nry;
offset += step;
}
vx[0] = orx; /* finish off last slice */
vy[0] = ory;
vx[1] = olx;
vy[1] = oly;
if(!vert)
{
i = 32000; /* force bottom */
vx[2] = l;
vy[2] = i;
vx[3] = r;
vy[3] = i;
}
else
{
i = -32000; /* force right */
vx[2] = i;
vy[2] = t;
vx[3] = i;
vy[3] = b;
}
render_ext_poly(4, vx, vy, *colorlist);
}
/*********** SKY/GROUNDCOLOR INTERFACE *********/
static int h2colors[2] = { 0xAe, 0x8D }; // 2-color horizon default
static int horizon_ncolors = 2; // cached clear arguments
static int *horizon_colors = h2colors;
static int horizon_stepsize = 48;
void set_skycolor(int color)
{
h2colors[0] = color;
horizon_colors = h2colors;
horizon_ncolors = 2;
if(h2colors[0]==h2colors[1]) horizon_ncolors = 1;
}
void set_groundcolor(int color)
{
h2colors[1] = color;
horizon_colors = h2colors;
horizon_ncolors = 2;
if(h2colors[0]==h2colors[1]) horizon_ncolors = 1;
}
/*********** EXTERNAL HORIZON TYPE SETUP *********/
// args: ncolor = 0 for no clear, others 0
// ncolor = 1 for solid clear to skycolor, or skycolor=groundcolor
// ncolor = 2 for normal horizon, or skycolor<>groundcolor
// ncolor > 2 for banded horizon with array of colors from palette
// leave bandsize 0 (unchanged), or use 128 for best size
void set_horizon(int ncolors, int colors[16], int bandsize)
{
horizon_ncolors = ncolors;
if(ncolors==0) return; // horizon off: ignore rest
if(ncolors<3 && colors==NULL) horizon_colors = h2colors;
if(colors!=NULL) horizon_colors = colors;
if(bandsize) horizon_stepsize = bandsize;
}
/************* DRAW HORIZON/CLEAR WINDOW ************/
void horizon(VIEW *v, int page) // clear window or draw horizon
{
set_drawpage(page);
setup_hdwe(0);
switch(horizon_ncolors)
{
case 0: // no clear: whole page done before?
break;
case 1: // solid clear window
clr_block(v->left, v->top, v->right, v->bottom-1, page, horizon_colors[0]);
break;
case 2:
band_horizon(v, page, 0, 1, horizon_colors);
break;
default:
band_horizon(v, page, horizon_stepsize, horizon_ncolors-1, horizon_colors);
break;
}
reset_hdwe();
return;
}
// some test values
//unsigned hcolors[20] = { 0xaf, 0xae, 0xad, 0xac, 0x79, 0x7a, 0x7b, 0x7c };
//
//test_h()
//{
// set_horizon(8, hcolors, 48);
//}