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

📄 3dkit.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    3DKIT   version   1.3    High speed 3D graphics and rendering library for Linux.    Copyright (C) 1996, 1997  Paul Sheer   psheer@icon.co.za    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,    MA 02111-1307, USA*//*File: 3dkit.cComments or suggestions welcome.This 3D graphics tool prints an object in three dimensions on the screen.The object must be made up of one or more surfaces passed in a structure.The algorithm calculates the light intensity at each point and does a colorinterpolation so that surfaces appear uniform with smooth colourgraduations.The TD_Object structure contains an array of surfaces comprising the object.When printing, the surfaces are sorted from furthest to closest bydetermining the distance from the eye point of their respective centres.This removes hidden features.The points of a surface are assumed to form a contorted rectangular meshhaving a length and a width - the number of points along the longitudinaledges and lateral edges respectively. Although the surfaces are restrictedto rectangles, they can be infinitely contorted into spheres, trianglesetc., possibly with a whole side compressed into a single point.It is advisable however to make up complex surfaces out of several lesscontorted surfaces so that the sorting routine can place the correct parts of the surface in front of one another. A sphere for example can bedefined as eight surfaces, each a triangular octant.Besides defining each 3D coord point of each surface array, the user mustalso define the unit normal at each point. so that shading can be calculated.The function TD_initcolor may be called to do this for you.The surfaces are drawn on the screen using one of the following methods.The integer surf.render determines the method.0 : Interpolated trangles are drawn with each rectangle outlined.1 : A wire frame is drawn of the edges of the surface only.2 : Interpolated triangles only.3 : Mesh - each rectangle outlined only.The demo planukit.c demostrates usage in detail.This code represents a complete re-write of the previous version, whichI wrote when I was first learning C (an excuse). It is far more structured,efficient and readable. An important additional feature is that the 3Dcamera position can now be defined, so that this code can be used as aVR tool. Hence an object can be displayed as an object at the screencentre, or as a 3D world. (See plane.h for how to modify the demo).*/#define TD_MULCONSTANT 4096#include <config.h>#include <math.h>#include <stdlib.h>#include <stdio.h>#include <vgagl.h>#include "3dkit.h"#define max(x,y)     (((x) > (y)) ? (x) : (y))#define min(x,y)     (((x) < (y)) ? (x) : (y))/*global for holding a surface temporarily:*/TD_Short_Point *temp;#if defined(__GNUC__) && !defined(__STRICT_ANSI__)/* The optimisation comes from svgalib-1.2.9/gl/line.c: *//* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer *//* line.c       Line drawing */#ifdef __alpha__static inline int muldiv64 (int m1, int m2, int d){    return (long) m1 *(long) m2 / (long) d;}#else#ifdef __i386__/* We use the 32-bit to 64-bit multiply and 64-bit to 32-bit divide of the *//* 386 (which gcc doesn't know well enough) to efficiently perform integer *//* scaling without having to worry about overflows. */static inline int muldiv64 (int m1, int m2, int d){/* int32 * int32 -> int64 / int32 -> int32 */    int result;    int dummy;    __asm__ (		"imull %%edx\n\t"		"idivl %4\n\t"  :		"=a" (result), "=d"(dummy)	/* out */  :		"0" (m1), "1" (m2), "g" (d)	/* in */		/***rjr***:		"ax", "dx"*/	/* mod */	);    return result;}#elsestatic inline int muldiv64(int m1, int m2, int d){    return (double) m1 * (double) m2 / ((double) d);}#endif				/* !__i386__ */#endif				/* !__alpha__ */#else#define muldiv64(a,b,c) ((long) ((double) a * (double) b / ((double) c)))#endifvoid TD_translate (TD_Solid * s, TD_Point * p, TD_Short_Point * scr){/* the following rotational transformation avoids floating point   calculations entirely */    if (s->option_flags & TDOPTION_32BIT_SURFACES) {/* for super accuracy */	double x = p->x + s->x_cam;	double y = p->y + s->y_cam;	double z = p->z + s->z_cam;	double yt = x * s->a21 + y * s->a22 + z * s->a23 + s->s_cam;	if (yt < 1) {	    scr->x = scr->y = 32767;	    return;	} else {	    double xt = x * s->a11 + y * s->a12 + z * s->a13;	    double zt = x * s->a31 + y * s->a32 + z * s->a33;	    scr->x = ((long) ((double) s->posx + xt * s->xscale / yt)) >> 16;	    scr->y = ((long) ((double) s->posy - zt * s->yscale / yt)) >> 16;	    return;	}    } else {	long x = p->x + s->x_cam;	long y = p->y + s->y_cam;	long z = p->z + s->z_cam;	long yt = x * s->a21 + y * s->a22 + z * s->a23 + s->s_cam;/*(FIXME:) There may be problems if yt overflows, this just checks if the point   is behind the cam: */	if (yt < 1) {	    scr->x = scr->y = 32767;	/*line and triangle routines must 					   reject these values. */	    return;	} else {	    long xt = x * s->a11 + y * s->a12 + z * s->a13;	    long zt = x * s->a31 + y * s->a32 + z * s->a33;	    scr->x = s->posx + muldiv64 (xt, s->xscale, yt);	    scr->y = s->posy - muldiv64 (zt, s->yscale, yt);	    return;	}    }}long TD_finddistance (TD_Solid * s, TD_Point * p){/* the following rotational transformation avoids floating point   calculations entirely */    if (s->option_flags & TDOPTION_32BIT_SURFACES) {/* for super accuracy */	double x = p->x + s->x_cam;	double y = p->y + s->y_cam;	double z = p->z + s->z_cam;	return ((long) ((double) x * s->a21 + y * s->a22 + z * s->a23 + s->s_cam)) >> 16;    } else {	long x = p->x + s->x_cam;	long y = p->y + s->y_cam;	long z = p->z + s->z_cam;	return (x * s->a21 + y * s->a22 + z * s->a23 + s->s_cam);    }}long TD_findcolor (TD_Solid * s, TD_Point * p, int which){    long c, shadow = s->surf[which].shadow;    /*this you can fool around with to get different shadowing effects. */    /*c starts off as a signed 28 bit integer. Brightest = -2^28, darkest = +2^28 */    if (s->option_flags & TDOPTION_LIGHT_SOURCE_CAM) {/* do product of translated normal vector with lighting vector: */	c = ((p->dirx * s->a11 + p->diry * s->a12 + p->dirz * s->a13) * s->xlight +	     (p->dirx * s->a21 + p->diry * s->a22 + p->dirz * s->a23) * s->ylight +	     (p->dirx * s->a31 + p->diry * s->a32 + p->dirz * s->a33) * s->zlight);	c = (c >> 20) + 256;    } else {	c = p->dirx * s->xlight +	    p->diry * s->ylight +	    p->dirz * s->zlight;	c = (c >> 8) + 256;    }    /*c now 9 bits *//*    c = s->surf[which].maxcolor	- ((c * c) >> (16 - s->surf[which].depth_per_color));*/    /*:responds quadratically to light or.*/    c = s->surf[which].maxcolor - (c >> (8 - s->surf[which].depth_per_color));    /*:responds linearly to light.*/    if (c < shadow)	return shadow;    else	return c;}void TD_calc_rotation_matrix (TD_Solid * s){/* This matrix comes from "Dynamics of Atmospheric Flight" by Bernard Etkin,   John Wiley & Sons, Inc., and is much easier to copy down than to    derive yourself. */    float tsi = s->alpha, theta = s->beta, phi = s->gamma;    s->a22 = (float) TD_MULCONSTANT * (cos (theta) * cos (tsi));    s->a21 = (float) TD_MULCONSTANT * (cos (theta) * sin (tsi));    s->a23 = (float) TD_MULCONSTANT * (-sin (theta));    s->a12 = (float) TD_MULCONSTANT * (sin (phi) * sin (theta) * cos (tsi) - cos (phi) * sin (tsi));    s->a11 = (float) TD_MULCONSTANT * (sin (phi) * sin (theta) * sin (tsi) + cos (phi) * cos (tsi));    s->a13 = (float) TD_MULCONSTANT * (sin (phi) * cos (theta));    s->a32 = (float) TD_MULCONSTANT * (cos (phi) * sin (theta) * cos (tsi) + sin (phi) * sin (tsi));    s->a31 = (float) TD_MULCONSTANT * (cos (phi) * sin (theta) * sin (tsi) - sin (phi) * cos (tsi));    s->a33 = (float) TD_MULCONSTANT * (cos (phi) * cos (theta));/* this is the classical rotations matrix of aerodynamics *//*    s->a11 = (float) TD_MULCONSTANT * (cos (s->alpha) * cos (s->gamma));    s->a12 = (float) TD_MULCONSTANT * (cos (s->alpha) * sin (s->gamma));    s->a13 = (float) TD_MULCONSTANT * (-sin (s->alpha));    s->a21 = (float) TD_MULCONSTANT * (sin (s->beta) * sin (s->alpha) * cos (s->gamma) - cos (s->beta) * sin (s->gamma));    s->a22 = (float) TD_MULCONSTANT * (sin (s->beta) * sin (s->alpha) * sin (s->gamma) - cos (s->beta) * cos (s->gamma));    s->a23 = (float) TD_MULCONSTANT * (sin (s->beta) * cos (s->alpha));    s->a31 = (float) TD_MULCONSTANT * (cos (s->beta) * sin (s->alpha) * cos (s->gamma) + sin (s->beta) * sin (s->gamma));    s->a32 = (float) TD_MULCONSTANT * (cos (s->beta) * sin (s->alpha) * sin (s->gamma) + sin (s->beta) * cos (s->gamma));    s->a33 = (float) TD_MULCONSTANT * (cos (s->beta) * cos (s->alpha));*//*results are 14 bit + sign integers*/}void TD_drawwire (TD_Solid * s, int which){    TD_Surface *surf = &s->surf[which];    int w = surf->w;    int l = surf->l;    int i = 0, j = 0, c = surf->mesh_color;    void (*dl) (int, int, int, int, int) = s->draw_line;    while (j < w - 1)	TD_translate (s, &surf->point[j++], &temp[i++]);    while (j < (w * l - 1)) {	TD_translate (s, &surf->point[j], &temp[i++]);	j += w;    }    while (j > w * (l - 1))	TD_translate (s, &surf->point[j--], &temp[i++]);    while (j >= 0) {	TD_translate (s, &surf->point[j], &temp[i++]);	j -= w;    }    for (j = 0; j < i - 1; j++) {	(*dl) (temp[j].x, temp[j].y, temp[j + 1].x, temp[j + 1].y, c);    }}void TD_drawmesh (TD_Solid * s, int which){    TD_Surface *surf = &s->surf[which];    int w = surf->w;    int l = surf->l;    int i = 0, j = 0, k = 0, c = surf->mesh_color;    void (*dl) (int, int, int, int, int) = s->draw_line;    while (j < l * w) {	TD_translate (s, &surf->point[j], &temp[j]);	j++;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -