分享到:

C语言网

 找回密码
 加入社区

QQ登录

只需一步,快速开始

查看: 40526|回复: 237

三维球动画程序     [复制链接]

Rank: 1

主题
3
帖子
27
C币
40 枚
在线时间
9 小时
发表于 2010-9-10 21:53:04 |显示全部楼层
本帖最后由 御坂美琴 于 2010-9-10 23:10 编辑

程序见附件

这是用VC6写的一个小动画程序,显示一个不断旋转的三维球体和它的包围盒,
同时可以用WSAD四个键调整视角

以下是源代码:

#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的工程
需要的留下个邮箱吧,我发给你
附件: 你需要登录才可以下载或查看附件。没有帐号?加入社区
2

查看全部评分

Rank: 8Rank: 8

主题
24
帖子
636
C币
761 枚
在线时间
504 小时
发表于 2010-9-10 21:56:03 |显示全部楼层
效果不错啊!
因为执着,所以成功

Rank: 8Rank: 8

主题
24
帖子
636
C币
761 枚
在线时间
504 小时
发表于 2010-9-10 22:07:21 |显示全部楼层
985761582@qq.com麻烦发来看一下哈
因为执着,所以成功

Rank: 1

主题
3
帖子
27
C币
40 枚
在线时间
9 小时
发表于 2010-9-10 22:15:13 |显示全部楼层
本帖最后由 御坂美琴 于 2010-9-10 22:16 编辑

发好了
另外,你知道不知道我发的这个代码怎么弄成彩色的?

Rank: 8Rank: 8

主题
24
帖子
636
C币
761 枚
在线时间
504 小时
发表于 2010-9-10 22:42:24 |显示全部楼层
发好了
另外,你知道不知道我发的这个代码怎么弄成彩色的?
御坂美琴 发表于 2010-9-10 22:15


好的!谢谢你啊!不过那个色彩问题我还没遇到过!

Rank: 1

主题
3
帖子
27
C币
40 枚
在线时间
9 小时
发表于 2010-9-10 22:48:34 |显示全部楼层
你没明白我的意思吗?你正常发代码在论坛,是只有黑色的,如果让你弄成根据语法变成彩色呢?你怎么弄?

Rank: 8Rank: 8

主题
24
帖子
636
C币
761 枚
在线时间
504 小时
发表于 2010-9-10 22:51:00 |显示全部楼层
我知道啊!我以前就是直接发帖!没设置过色彩!不知道怎么一把你的帖子移动过来就变成这样了
因为执着,所以成功

Rank: 1

主题
3
帖子
27
C币
40 枚
在线时间
9 小时
发表于 2010-9-10 22:55:55 |显示全部楼层
这根本和你移不移动帖子无关啊,你还不明白么?这是我故意弄的

Rank: 8Rank: 8

主题
24
帖子
636
C币
761 枚
在线时间
504 小时
发表于 2010-9-10 23:01:31 |显示全部楼层
额!
因为执着,所以成功

Rank: 16Rank: 16Rank: 16Rank: 16

主题
29
帖子
363
C币
3131 枚
在线时间
432 小时
发表于 2010-9-10 23:20:56 |显示全部楼层
您需要登录后才可以回帖 登录 | 加入社区

C语言  C语言论坛 ( 粤ICP备11042647号-2 )

GMT+8, 2017-4-25 20:35

©2009-2015 cyuyan.com.cn

回顶部