home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
REND.LZH
/
REND
/
EDGELIST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-28
|
4KB
|
206 lines
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "reader.h"
#include "glib.h"
typedef struct _Work {
int x, y ;
long z ;
AtrTable *atr ;
}
Work ;
static int polyid = 1 ; /* ポリゴンのid */
static int bufsize = 0 ; /* ワークバッファのサイズ */
static Work *work = NULL ; /* ワークバッファ */
static ColorCode code ; /* カラーコード */
#ifdef WIREVIEW
extern int wiresize;
#endif
/*
proto edgelist -s > temp
*/
static void appendedgelist( Work*, Work*, unsigned char[3], int );
static void DDAset( DDA*, int, int, int );
/* エッジリストの初期化 */
void InitEdgeList()
{
int i ;
for( i = 0 ; i < MAXLINE ; ++i )
EdgeBuf[i] = NULL ;
polyid = 1 ;
}
/* エッジリストの作成 */
void SetEdgeList( point, atrtable, n, patr )
Point *point ; /* 頂点座標 */
AtrTable *atrtable ; /* アトリビュートデータ */
int n ; /* 頂点数 */
Pointer(Atr*) patr ; /* アトリビュート */
{
int i, mapflag ;
unsigned char tra[3] ;
Work *wp ;
Atr *atr ;
(*interrupt)();
/* ワークバッファのサイズチェック */
if ( n > bufsize )
{
if ( bufsize > 0 )
tempfree( work );
bufsize = n ;
work = tempalloc( sizeof( Work ) * bufsize );
}
/* ワークバッファにコピー */
wp = work ;
for( i = 0 ; i < n ; ++i )
{
wp->x = (int)( point[i][0] + minscale );
wp->y = (int)( point[i][1] + minscale );
wp->z = (long)point[i][2] ;
/* wp->z = (int)((double)(point[i][2])) ;*/
if ( ShadingModel == GOURAUD_SHADE )
wp->atr = atrtable + i ;
wp ++ ;
}
if ( ShadingModel == FLAT_SHADE )
code = GetColorCode( &(atrtable->shade), NULL );
/* アトリビュート */
atr = pointer( patr );
for( i = 0 ; i < 3 ; ++i )
tra[i] = (unsigned char)( ( atr->tra[i] * 128 ) >> COLOR_SHIFT );
mapflag = ( atr->maptype != NO_MAP );
for( i = 0 ; i < n-1 ; ++i )
appendedgelist( work+i, work+i+1, tra, mapflag );
appendedgelist( work+n-1, work, tra, mapflag );
polyid++ ;
}
/* エッジリストの追加 */
static void appendedgelist( w1, w2, tra, mapflag )
REGISTER Work *w1, *w2 ;
unsigned char tra[3] ;
int mapflag ;
{
Work *w ;
int i, dx ;
long dz ;
Pointer(EdgeList*) p ;
REGISTER int dy ;
REGISTER EdgeList *edge ;
/* 表示 */
#ifdef WIREVIEW
if (wiresize > 0) {
unsigned short color;
if (wiresize > 1) {
color = ColorCodeToX68kcolor(code);
} else {
color = 0xfffe;
}
wirelineout(w1->x, w1->y, w2->x, w2->y, color);
return;
}
#endif
if ( LineOutput != NULL )
(*LineOutput)( w1->x, w1->y, w2->x, w2->y );
if ( w1->y == w2->y )
return ;
/* w1->y のほうが大きければ入れ替え */
if ( w1->y > w2->y )
{
w = w1 ;
w1 = w2 ;
w2 = w ;
}
dx = w2->x - w1->x ;
dy = w2->y - w1->y ;
dz = w2->z - w1->z ;
/* エッジリストの確保 */
if ( ShadingModel == GOURAUD_SHADE )
{
if ( mapflag )
p = dataalloc( sizeof( EdgeList ) ) ;
else
p = dataalloc( sizeof( EdgeList ) - sizeof( MapTable ) );
}
else
p = dataalloc( sizeof( EdgeList ) - sizeof( ShadeTable ) - sizeof( MapTable ) );
edge = pointer( p );
/* データセット */
edge->n = dy ;
DDAset( &(edge->dxdy), w1->x, dx, dy );
edge->z = w1->z ;
if ( dz > 0 )
edge->dzdy = ( dz + dy / 2 ) / dy ;
else
edge->dzdy = - ( ( - dz + dy / 2 ) / dy );
edge->polyid = polyid ;
edge->flag = FALSE ;
edge->code = code ;
edge->traflag = (char)( ! ( tra[0] == 0 && tra[1] == 0 && tra[2] == 0 ) );
for( i = 0 ; i < 3 ; ++i )
edge->tra[i] = tra[i] ;
if ( ShadingModel == GOURAUD_SHADE )
{
edge->shade = w1->atr->shade ;
if ( mapflag )
{
edge->mapflag = TRUE ;
edge->map = w1->atr->map ;
SetAtrStep( &( edge->shade ), &(w2->atr->shade),
&( edge->map ), &(w2->atr->map), dy );
#ifdef EXTENDMAP
SetAtrStepMap(w1->z, w2->z,
&( edge->map ), &(w2->atr->map), dy );
#endif
}
else
{
edge->mapflag = FALSE ;
SetAtrStep( &( edge->shade ), &(w2->atr->shade), NULL, NULL, dy );
}
}
/* エッジリストの結合 */
edge->next = EdgeBuf[w1->y] ;
EdgeBuf[w1->y] = p ;
}
/* DDA のデータセット */
static void DDAset( dda, x, dx, dy )
REGISTER DDA *dda ;
int x, dx, dy ;
{
dda->x = x ;
dda->totalmod = dy / 2 ;
if ( dx < 0 )
{
dda->dxdy = - ( ( - dx ) / dy ) - 1 ;
dda->mod = dy - ( ( -dx ) % dy ) ;
}
else
{
dda->dxdy = dx / dy ;
dda->mod = dx % dy ;
}
dda->dy = dy ;
dda->dx = dx ;
}