📄 shaded.c
字号:
/* shaded.c 1.1 92/07/30 */#include <usercore.h>#include <sun/fbio.h>#include <math.h>#include <stdio.h>#include "demolib.h"#define MAXVERT 800#define MAXPOLY 800#define MAXPVERT 6400static int nvert, npoly;static float bbox[3][2];static float planeq[MAXPOLY][4];static float vertices[MAXVERT][3];static float normal[MAXVERT][3];static int cindex[MAXVERT];static short normalcount[MAXVERT];static int npvert[MAXPOLY];static short *pvertptr[MAXPOLY];static short pvert[MAXPVERT];static float xlist[10], ylist[10], zlist[10];static float dxlist[10], dylist[10], dzlist[10];static int indxlist[10];static float red[256], grn[256], blu[256];static float dred[256], dgrn[256], dblu[256];static int renderstyle=1;static int renderhue=0;static float xcut[2]={0.,1.}, zcut0[2]={0.,0.}, zcut[2]={0.,1.};main(argc, argv) int argc; char *argv[];{ char string[81]; int button, length = 0, visible(); float x, y, z; if (argc < 2) { printf("Usage: shadeobj objfile\n"); exit(1); } if (getobjdat(argv[1])) exit(2); initvw(); get_view_surface(our_surface,argv); start_up_core(); x = 0.0; y = 0.0; z = bbox[2][1] + (bbox[0][1] > bbox[1][1] ? bbox[0][1] : bbox[1][1]); for (;;) { new_frame(); getxyz(&x, &y, &z); new_frame(); setvwpo(x, y, z); create_temporary_segment(); set_primitive_attributes( &PRIMATTS); set_polygon_interior_style( SHADED); drawobj(); close_temporary_segment(); do { await_any_button(0, &button); if (button == 3) break; await_keyboard(0, 1, string, &length); } while (length == 0); if (length != 0) break; } shut_down_core(); return 0; }start_up_core(){ int i; initialize_core(BASIC, SYNCHRONOUS, THREED); our_surface->cmapsize = 256; our_surface->cmapname[0] = '\0'; if(initialize_view_surface(our_surface, TRUE)) exit(1); initialize_device( BUTTON, 1); /* initialize input devices */ initialize_device( BUTTON, 2); /* initialize input devices */ initialize_device( BUTTON, 3); /* initialize input devices */ initialize_device( PICK, 1); set_echo_surface( PICK, 1, our_surface); set_echo( PICK, 1, 0); select_view_surface(our_surface); set_light_direction( -0.4,0.4,-1.); inquire_color_indices(our_surface,0,255,dred,dgrn,dblu); for (i=1; i<=255; i++) { /* load color LUT */ red[i] = (float)i * 0.003921568; grn[i] = (float)i * 0.003921568; blu[i] = (float)i * 0.003921568;; } red[0] = 0.; grn[0] = .7; blu[0] = 0.; define_color_indices( our_surface,0,255,red,grn,blu); /* ambient,diffuse,specular,flood,bump,hue,style */ set_shading_parameters( .01, .96, .0, 0., 7.,0,0); initialize_device(KEYBOARD, 1); set_echo_surface( KEYBOARD, 1, our_surface); set_keyboard(1, 80, "", 1); initialize_device(LOCATOR, 1); set_echo(LOCATOR, 1, 0); set_echo_surface( LOCATOR, 1, our_surface); setvwpv(); build_menu(); set_font(1); }shut_down_core(){ terminate_device(KEYBOARD, 1); deselect_view_surface(our_surface); terminate_view_surface(our_surface); terminate_core(); }int getobjdat(filename)char *filename; { int i, j, k; short vtmp, v1, v2, v3; float ftmp, maxd, scale, offset[3]; float x,y,z,x0,y0,z0,length; FILE *fptr; if ((fptr = fopen(filename, "r")) == NULL) { printf("Can't open file: %s\n", filename); return(1); } fscanf(fptr, "%d%d", &nvert, &npoly); if ((nvert > MAXVERT) || (npoly > MAXPOLY)) { printf("Too many object vertices or polygons\n"); return(2); } fscanf(fptr, "%f%f%f%f%f%f", &bbox[0][0], &bbox[0][1], &bbox[1][0], &bbox[1][1], &bbox[2][0], &bbox[2][1]); maxd = 0.0; for (i = 0; i < 3; i++) { offset[i] = (bbox[i][0] + bbox[i][1]) / 2.0; bbox[i][0] -= offset[i]; bbox[i][1] -= offset[i]; if (bbox[i][0] > bbox[i][1]) { ftmp = bbox[i][0]; bbox[i][0] = bbox[i][1]; bbox[i][1] = ftmp; } if (maxd < bbox[i][1]) maxd = bbox[i][1]; } scale = 1000.0 / maxd; for (i = 0; i < 3; i++) { bbox[i][0] *= scale; bbox[i][1] *= scale; } for (i = 0; i < nvert; i++) { fscanf(fptr, "%f%f%f", &vertices[i][0], &vertices[i][1], &vertices[i][2]); vertices[i][0] = (vertices[i][0] - offset[0]) * scale; vertices[i][1] = (vertices[i][1] - offset[1]) * scale; vertices[i][2] = (vertices[i][2] - offset[2]) * scale; normal[i][0] = 0.0; normal[i][1] = 0.0; normal[i][2] = 0.0; normalcount[i] = 0; } k = 0; for (i = 0; i < npoly; i++) { fscanf(fptr, "%d", &npvert[i]); if ((k + npvert[i]) > MAXPVERT) { printf("Too many polygon vertices\n"); return(3); } pvertptr[i] = &pvert[k]; for (j = 0; j < npvert[i]; j++) { fscanf(fptr, "%hd", &vtmp); pvert[k++] = vtmp - 1; } planeq[i][0] = planeq[i][1] = planeq[i][2] = planeq[i][3] = 0.0; v1 = pvert[k - 1]; v2 = pvert[k - 2]; v3 = pvert[k - 3]; for (j = 0; j < 3; j++) { planeq[i][0] += vertices[v1][1] * (vertices[v2][2] - vertices[v3][2]); planeq[i][1] += vertices[v1][0] * (vertices[v3][2] - vertices[v2][2]); planeq[i][2] += vertices[v1][0] * (vertices[v2][1] - vertices[v3][1]); planeq[i][3] += vertices[v1][0] * ((vertices[v3][1] * vertices[v2][2]) - (vertices[v2][1] * vertices[v3][2])); vtmp = v1; v1 = v2; v2 = v3; v3 = vtmp; }/* if (planeq[i][3] > 0.0) for (j = 0; j <= 3; j++) planeq[i][j] = -planeq[i][j];*/ for (j = 1; j <= npvert[i]; j++) { /* accum normls */ vtmp = pvert[k-j]; x = planeq[i][0]; y = planeq[i][1]; z = planeq[i][2]; length = sqrt( x*x + y*y + z*z); normal[vtmp][0] += x/length; normal[vtmp][1] += y/length; normal[vtmp][2] += z/length; normalcount[vtmp]++; } } for (i = 0; i < nvert; i++) { normal[i][0] /= normalcount[i]; normal[i][1] /= normalcount[i]; normal[i][2] /= normalcount[i]; } fclose(fptr); return(0); }setvwpo(vx, vy, vz)float vx, vy, vz; { int i; float diag, del, objdist, near; set_view_reference_point(vx, vy, vz); set_view_plane_normal(-vx, -vy, -vz); set_projection(PERSPECTIVE, 0., 0., 0.); set_view_plane_distance(256.0); if ((vx == 0.0) && (vz == 0.0)) set_view_up_3(0.0, 0.0, vy); else set_view_up_3(0.0, 1.0, 0.0); set_window(-80.0, 80.0, -80.0, 80.0); diag = 0.0; for (i = 0; i < 3; i++) { del = bbox[i][1] - bbox[i][0]; diag += del * del; } diag = sqrt(diag) / 2.0; objdist = sqrt( vx*vx + vy*vy + vz*vz); near = (diag >= objdist) ? objdist/2.0 : objdist-diag; set_view_depth( near, objdist + diag); set_window_clipping(TRUE); set_front_plane_clipping(TRUE); set_back_plane_clipping(TRUE); set_viewport_3(.125, .874, 0., .749, 0.0, 1.0); }static float invxform[4][4];drawobj() { int i; float x,y,z,x0,y0,z0,length; char ch; if (renderstyle && renderstyle<3) map_ndc_to_world_3( -348., 348., -870., &x,&y,&z); map_ndc_to_world_3( 0.0, 0.0, 0.0, &x0,&y0,&z0); x -= x0; y -= y0; z -= z0; length = sqrt( x*x + y*y + z*z); if (length != 0.0) { x /= length; y /= length; z /= length; } for (i = 0; i < nvert; i++) { cindex[i] = fabs(normal[i][0]*x +normal[i][1]*y +normal[i][2]*z) * 254.; if (cindex[i] < 4) cindex[i] = 4; if (cindex[i] > 248) cindex[i] = 248; } /* inquire_inverse_composite_matrix(invxform); */ if (renderstyle == 3) set_zbuffer_cut( our_surface, xcut, zcut, 2); else set_zbuffer_cut( our_surface, xcut, zcut0, 2); for (i = 0; i < npoly; i++) { /* if (visible(planeq[i])) */ drawface(i); } }int visible(pln)float pln[]; { int i; float c; c = 0.0; for (i = 0; i < 4; i++) c += invxform[2][i] * pln[i]; return(c < 0.0); }drawface(p) int p;{ int i, j, k; short *ptr; ptr = pvertptr[p]; for (i = 0; i < npvert[p]; i++) { j = *ptr++; xlist[i] = vertices[j][0]; ylist[i] = vertices[j][1]; zlist[i] = vertices[j][2]; if (renderstyle < 3) { indxlist[i] = cindex[j]; }else { dxlist[i] = normal[j][0]; dylist[i] = normal[j][1]; dzlist[i] = normal[j][2]; } } if (renderstyle < 2) { if (renderhue) { j = indxlist[0]>>2; if (j > 62) j = 62; set_fill_index( j + renderhue*64 -63); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -