我的小作品:三维球体
3dball.zip
(43.11 KB)
这是用VC6写的一个小动画程序,显示一个不断旋转的三维球体和它的包围盒,
同时可以用WSAD四个键调整视角
以下是C语言源代码:
程序代码:
#include "graphics.h" #include <stdio.h> #include <math.h> #define PI 3.1415926535897932384626 const int sc_width = 640; const int sc_height = 640; typedef void * HANDLE; typedef struct STAR { float x; float y; float z; float r; float R; float rad; int color; } *PSTAR; typedef struct SCENE { float dx; float dz; float drz; float fs; int key[4]; PSTAR star; int nMaxStar; } *PSCENE; double frandom() { return (double)random(10000) / 10000; } void InitStar(PSTAR star) { star->y = (float)(frandom() * 2 - 1.0); star->R = (float)sqrt(1 - star->y * star->y); star->r = (float)(frandom() * PI * 2); star->rad = (float)(frandom() * 0.01 + 0.01); star->color = 0xFFFFFF; } void MoveStar(PSTAR star, double dt) { star->r += star->rad * (float)dt; if (star->r > 2*PI) { star->r -= (float)(2*PI); } star->x = (float)(star->R * cos(star->r)); star->z = (float)(star->R * sin(star->r)); } int alpha(int color, float a) { int r = color&0xff, g = (color>>8)&0xff, b = (color>>16)&0xff; r = (int)(r*a); g = (int)(g*a); b = (int)(b*a); return rgb(r, g, b); } void DrawStar(PSTAR star, float dz, float drz) { float bz = 0.5f; int color = star->color; { struct point3d t = {star->x, star->y, star->z}; rotate_point3d_z(&t, drz); { float z = star->z + dz; if (z < 1.0f + bz) { } else if (z > 0) { color = alpha(color, 1.0f / (z - bz)); } draw_point(&t, color); } } } int __stdcall on_msg_key(HANDLE param, unsigned msg, int key) { PSCENE scene = (PSCENE) param; if (msg == MSG_EVENT_DOWN) { if (key == 'W') { scene->key[0] = 1; } else if (key == 'S') { scene->key[1] = 1; } else if (key == 'A') { scene->key[2] = 1; } else if (key == 'D') { scene->key[3] = 1; } } else if (msg == MSG_EVENT_UP) { if (key == 'W') { scene->key[0] = 0; } else if (key == 'S') { scene->key[1] = 0; } else if (key == 'A') { scene->key[2] = 0; } else if (key == 'D') { scene->key[3] = 0; } } return 0; } int __stdcall on_update(HANDLE param, float ms) { PSCENE scene = (PSCENE)param; scene->fs += 0.001f; if (scene->fs >= 1.0f) { scene->fs -= 1.0f; } scene->drz += 0.01f; if (scene->drz > 2*PI) { scene->drz -= (float)(2*PI); } if (scene->key[0]) { scene->dz -= 0.01f; } if (scene->key[1]) { scene->dz += 0.01f; } if (scene->key[2]) { scene->dx -= 0.01f; } if (scene->key[3]) { scene->dx += 0.01f; } return 0; } int __stdcall on_render(HANDLE param, float ms) { double dt = ms * 0.06; PSCENE scene = (PSCENE) param; int i; cleardevice(); { struct point3d t = {scene->dx, 0, -scene->dz}; set_viewpoint(&t); } for (i = 0; i < scene->nMaxStar; i++) { MoveStar(scene->star + i, dt); DrawStar(scene->star + i, scene->dz, scene->drz); } { struct point3d pcenter[2] = { {0, 1, 0}, {0,-1, 0} }; struct point3d pbox[8] = { { 1, 1, 1}, { 1, 1,-1}, { 1,-1, 1}, { 1,-1,-1}, {-1, 1, 1}, {-1, 1,-1}, {-1,-1, 1}, {-1,-1,-1}, }; rotate_point3d_z(&pcenter[0], scene->drz); rotate_point3d_z(&pcenter[1], scene->drz); setcolor(0xFF202020); draw_line(&pbox[0], &pbox[1]); draw_line(&pbox[2], &pbox[3]); draw_line(&pbox[4], &pbox[5]); draw_line(&pbox[6], &pbox[7]); draw_line(&pbox[0], &pbox[3]); draw_line(&pbox[1], &pbox[2]); draw_line(&pbox[4], &pbox[7]); draw_line(&pbox[5], &pbox[6]); draw_line(&pbox[0], &pbox[5]); draw_line(&pbox[1], &pbox[4]); draw_line(&pbox[2], &pbox[7]); draw_line(&pbox[3], &pbox[6]); draw_line(&pcenter[0], &pcenter[1]); setcolor(0x202020); draw_line_f(&pbox[0], &pbox[2]); draw_line_f(&pbox[1], &pbox[3]); draw_line_f(&pbox[4], &pbox[6]); draw_line_f(&pbox[5], &pbox[7]); draw_line_f(&pbox[0], &pbox[4]); draw_line_f(&pbox[1], &pbox[5]); draw_line_f(&pbox[2], &pbox[6]); draw_line_f(&pbox[3], &pbox[7]); } setcolor(HSVtoRGB(scene->fs, 1.0f, 1.0f)); outtextxy(0, 0, (char*)"Press W, S, A or D to move the camera"); return 0; } int main() { #define MAXSTAR 500 struct STAR star[MAXSTAR]; struct SCENE scene = {0}; int i; { int g = TRUECOLORSIZE, m = SIZE2DWORD(sc_width, sc_height); initgraph(&g, &m, "3d Ball"); } scene.star = star; scene.drz = 0; scene.dx = 0; scene.dz = 3; scene.fs = 0; scene.nMaxStar = MAXSTAR; set_3dview((float)(sc_width / 2), (float)(sc_height / 2), (float)(sc_width), (float)(sc_height)); for (i = 0; i < scene.nMaxStar; i++) { InitStar(star + i); } message_addkeyhandler(&scene, on_msg_key); ege_gameloop(on_update, &scene, 60, on_render, &scene, 0); closegraph(); #undef MAXSTAR return 0; }
不过,以上代码想要编译通过的话,还是要整个工程的,是VC6的工程
需要的留下个邮箱吧,我发给你
[ 本帖最后由 御坂美琴 于 2010-9-8 22:34 编辑 ]