pipeutil.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 754 行 · 第 1/2 页
C
754 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
/*
Description:
============
Utility routines used by the 3d graphics pipeline.
The routines in this file use memory as follows:
1. rend_obj's in the first half of the pipeline are kept in local
memory since there will only be one of them being acted upon
at any one time.
2. At the end of the first half of the pipeline the rend_obj being acted
upon is added to the rend_list but is first copied into memory
managed by pipemem (see pipemem.c).
3. The list part of the rend_list is kept in global memory as an array
and is realloc'ed as necessary.
*/
#include "icgr.h"
#include <float.h>
#include <string.h>
#ifndef PROD
#define INCLUDE_DEBUG_ROUTINES
#endif
/* amount to grow a rend_list by when needed */
#define REND_LIST_GROW_SIZE 25
/* rend_list manipulation routines */
static void check_list_size(
/**************************/
rend_list * list
) {
if (list->last + 1 >= list->size) {
list->size += REND_LIST_GROW_SIZE;
_grenew( list->list, list->size );
}
}
extern bool rend_list_init(
/*************************/
rend_list * list
) {
_gnew( list->list, REND_LIST_GROW_SIZE );
list->last = -1; // no entries in use
if (list->list == NULL) {
list->size = 0;
return( FALSE );
} else {
list->size = REND_LIST_GROW_SIZE;
return( TRUE );
}
}
#if 0
/* macroed */
extern bool rend_list_is_empty(
/*****************************/
rend_list * list
) {
return( list->last < 0 );
}
#endif
extern void rend_list_add(
/************************/
rend_list * list,
rend_obj * obj
) {
check_list_size( list );
list->last += 1;
list->list[ list->last ] = obj;
}
extern void rend_list_free(
/*************************/
rend_list * list
) {
_gfree( list->list );
}
extern void rend_list_sort(
/*************************/
rend_list * list,
int (*compare) (const rend_obj **, const rend_obj **)
) {
qsort( list->list, list->last + 1, sizeof(rend_obj *), (int (*)(const void *, const void *))compare );
}
extern void rend_list_bin_insert(
/*******************************/
/* Uses a binary search to insert obj into a sublist of list. The sublist is */
/* given by start and end. */
/* NOTE: if start > end obj is inserted after end */
rend_list * list,
rend_list_ref start,
rend_list_ref end,
rend_obj ** obj,
int (*compare) (const rend_obj **, const rend_obj **)
) {
int high;
int low;
int mid;
int comp_rc;
low = start;
high = end;
mid = (low + high) / 2;
while (low <= high ) {
comp_rc = compare( (const rend_obj **)obj, (const rend_obj **)(list->list + mid) );
if (comp_rc < 0) {
high = mid - 1;
} else if (comp_rc > 0) {
low = mid + 1;
} else {
high = mid;
/**/ break;
}
mid = (low + high) / 2;
}
/* Insert the elemtent after high. If high is -1 this means insert */
/* the element before the first element and rend_list_insert handles */
/* this case. */
rend_list_insert( list, &high, *obj, FALSE );
}
extern void rend_list_insert(
/***************************/
rend_list * list,
rend_list_ref * ref,
rend_obj * obj,
bool before
) {
check_list_size( list );
list->last += 1;
if (before) {
memmove( &(list->list[ *ref + 1 ]), &(list->list[ *ref ]),
(list->last - *ref) * sizeof(rend_obj *) );
} else {
*ref += 1;
memmove( &(list->list[ *ref + 1 ]), &(list->list[ *ref ]),
(list->last - *ref) * sizeof(rend_obj *) );
}
list->list[ *ref ] = obj;
}
extern void rend_list_delete(
/***************************/
rend_list * list,
rend_list_ref * ref
) {
memmove( &(list->list[ *ref ]), &(list->list[ *ref + 1 ]),
(list->last - *ref) * sizeof(rend_obj *) );
list->last -= 1;
if (*ref > list->last) {
*ref = list->last;
}
}
#if 0
/* macroed */
extern rend_obj * rend_list_get_obj(
/**********************************/
rend_list * list,
rend_list_ref ref
) {
return( list->list[ ref ] );
}
#endif
#if 0
/* macroed */
extern void rend_list_set_obj(
/****************************/
rend_list * list,
rend_list_ref ref,
rend_obj * obj
) {
list->list[ ref ] = obj;
}
#endif
#if 0
/* macroed */
extern bool rend_list_next(
/*************************/
rend_list * list,
rend_list_ref * ref
) {
*ref += 1;
return( *ref > list->last );
}
#endif
#if 0
/* macroed */
extern bool rend_list_prev(
/*************************/
rend_list * list,
rend_list_ref * ref
) {
list = list; // other representaions of rend_list may need list
*ref -= 1;
return( *ref < 0 );
}
#endif
#if 0
/* macroed */
extern bool rend_list_is_before_first(
/************************************/
rend_list * list,
rend_list_ref ref
) {
list = list; // other representations of rend_list may need list
return( ref < 0 );
}
#endif
#if 0
/* macroed */
extern bool rend_list_is_after_last(
/**********************************/
rend_list * list,
rend_list_ref ref
) {
return( ref > list->last );
}
#endif
#if 0
/* macroed */
extern void rend_list_first(
/**************************/
rend_list * list,
rend_list_ref * ref
) {
list = list; // other representations of rend_list may need list
*ref = 0;
}
#endif
#if 0
/* macroed */
extern void rend_list_last(
/*************************/
rend_list * list,
rend_list_ref * ref
) {
*ref = list->last;
}
#endif
/* vector manipulation routines */
extern vector cross_prod(
/***********************/
vector v,
vector w
) {
vector r;
r.v[0] = v.v[1]*w.v[2] - v.v[2]*w.v[1];
r.v[1] = v.v[2]*w.v[0] - v.v[0]*w.v[2];
r.v[2] = v.v[0]*w.v[1] - v.v[1]*w.v[0];
return( r );
}
extern float norm(
/****************/
/* This function computes the norm of a vector. Don't confuse this with */
/* the normal vector (of a plane) which is sometime called norm in this code */
vector v
) {
return( sqrt(v.v[0]*v.v[0] + v.v[1]*v.v[1] + v.v[2]*v.v[2]) );
}
#if 0
/* macroed */
extern float dot_prod_vp(
/***********************/
/* Dot product of a vector and a point. Used to evaluate plane equations */
vector vect,
point pt
) {
return( pt.p[0]*vect.v[0] + pt.p[1]*vect.v[1] + pt.p[2]*vect.v[2] +
pt.p[3]*vect.v[3] );
}
extern float dot_prod_vv(
/***********************/
/* Dot product of two vectors */
/* bound. */
vector vect1,
vector vect2
) {
return( vect1.v[0]*vect2.v[0] + vect1.v[1]*vect2.v[1] +
vect1.v[2]*vect2.v[2] + vect1.v[3]*vect2.v[3] );
}
#endif
extern vector calculate_normal_vector(
/************************************/
/* This uses the techniques describe in "Computer Graphics" by Foley et. al. */
/* section 11.1.3, pp. 476, 477 */
int num_pts,
void *data, // passed to get_next_pt only
point (* get_pt) ( void *, int point_num )
) {
vector normal;
float len; // norm of normal
int count;
point curr_pt;
point next_pt;
normal.v[0] = 0.;
normal.v[1] = 0.;
normal.v[2] = 0.;
normal.v[3] = 0.;
for (count = 0; count < num_pts; count++) {
curr_pt = (*get_pt)( data, count );
next_pt = (*get_pt)( data, (count + 1) % num_pts );
normal.v[0] += (next_pt.p[2] + curr_pt.p[2]) *
(next_pt.p[1] - curr_pt.p[1]);
normal.v[1] += (next_pt.p[2] + curr_pt.p[2]) *
(next_pt.p[0] - curr_pt.p[0]);
normal.v[2] += (next_pt.p[1] + curr_pt.p[1]) *
(next_pt.p[0] - curr_pt.p[0]);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?