游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4746|回复: 12

[求教]关于圆顶天空的问题!

[复制链接]

20

主题

398

帖子

398

积分

中级会员

Rank: 3Rank: 3

积分
398
发表于 2005-2-27 12:22:00 | 显示全部楼层 |阅读模式
前段时间看了一篇关于圆顶天空的文章《3D场景中的圆形天空顶》,算法是这样的:

#define PI 3.1415926535897f
#define DTOR (PI / 180.0f)  

typedef struct
{
        float x, y, z;
        DWORD color;
        float u, v;
} VERTEX;

Vertex *Vertices;
int theta, phi;
float rad;
int dtheta = 15;
int dphi = 15;
int NumVertices = (int) ((360/dtheta) * (90/dphi) * 4);
Vertices = new VERTEX[NumVertices];

int n = 0;
for (phi = 0; phi <= 90 - dphi; phi += (int)dphi)
{
    for (theta = 0; theta <= 360 - dtheta; theta += (int)dtheta)
    {
        Vertices[n].x = radius * sinf(phi * DTOR) * cosf(theta * DTOR);
        Vertices[n].y = radius * sinf(phi * DTOR) * sinf(theta * DTOR);
        Vertices[n].z = radius * cosf(phi * DTOR);
        n++;
        Vertices[n].x = radius * sinf((phi + dphi) * DTOR) * cosf(theta * DTOR);
        Vertices[n].y = radius * sinf((phi + dphi) * DTOR) * sinf(theta * DTOR);
        Vertices[n].z = radius * cosf((phi + dphi) * DTOR);
        n++;
        Vertices[n].x = radius * sinf(phi * DTOR) * cosf((theta + dtheta) * DTOR);
        Vertices[n].y = radius * sinf(phi * DTOR) * sinf((theta + dtheta) * DTOR);
        Vertices[n].z = radius * cosf(phi * DTOR);
        n++;
        if (phi > -90 && phi < 90)
        {
        Vertices[n].x = radius * sinf((phi + dphi) * DTOR) * cosf((theta + dtheta) * TOR);
        Vertices[n].y = radius * sinf((phi + dphi) * DTOR) * sinf((theta + dtheta) * DTOR);
        Vertices[n].z = radius * cosf((phi + dphi) * DTOR);
        n++;
        }
    }
}

      1)我已经生成了天空半球,请问如何贴纹理啊?
      2)还有谁有适合圆顶天空的高质量纹理啊?

      偶刚开始学D3D,请高手指点,谢谢啦!





[em20] [em20]abcabcabc

108

主题

180

帖子

250

积分

中级会员

Rank: 3Rank: 3

积分
250
QQ
发表于 2005-2-27 13:27:00 | 显示全部楼层

Re:[求教]关于圆顶天空的问题!

我劝你还是看一下数学,先把他的原理搞清楚。

1

主题

56

帖子

56

积分

注册会员

Rank: 2

积分
56
QQ
发表于 2005-2-27 14:11:00 | 显示全部楼层

Re:[求教]关于圆顶天空的问题!

我感觉各位高手回答问题时,总爱说让大家自己研究数学原理去。
其实我们很多人开发游戏或者一些程序主要是做应用,找出可用
代码段会组合就行了,也没必要所有算法原理都搞清楚,那得到
什么时间才能出产品啊。

1

主题

56

帖子

56

积分

注册会员

Rank: 2

积分
56
QQ
发表于 2005-2-27 14:14:00 | 显示全部楼层

Re:[求教]关于圆顶天空的问题!

圆形天空是个挺老的功能了,有本OPENGL高级编程和可视化系统开发书里
就有这个例子。我贴一段代码给你参考吧:
typedef struct
{
        float x,y,z;
        unsigned int color;
        float u, v;
} VERTEX;
        VERTEX *Vertices;

void CMySkyView::GenerateDome(float radius, float dtheta, float dphi, float hTile, float vTile)
{
        int theta, phi;

        // 如果顶点序列存在,则清空顶点序列
        if (Vertices)
        {
                delete Vertices;
                Vertices = NULL;
                NumVertices = 0;
        }

        // 初始化顶点序列
        NumVertices = (int)((360/dtheta)*(90/dphi)*4);
        Vertices = new VERTEX[NumVertices];
        ZeroMemory(Vertices, sizeof(VERTEX)*NumVertices);

        // 用来计算 UV 坐标
        float vx, vy, vz, mag;

        // 生成拱形天空dome
        int n = 0;
        for (phi=0; phi <= 90 - dphi; phi += (int)dphi)
        {
                for (theta=0; theta <= 360 - dtheta; theta += (int)dtheta)
                {
                        // 计算顶点的 phi, theta
                        Vertices[n].x = radius * sinf(phi*DTOR) * cosf(DTOR*theta);
                        Vertices[n].y = radius * sinf(phi*DTOR) * sinf(DTOR*theta);
                        Vertices[n].z = radius * cosf(phi*DTOR);

                        // 计算从原点到该顶点的矢量
                        vx = Vertices[n].x;
                        vy = Vertices[n].y;
                        vz = Vertices[n].z;

                        // 矢量正交化
                        mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
                        vx /= mag;
                        vy /= mag;
                        vz /= mag;

                        // 计算球形纹理坐标
                        Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
                        Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;               
                        n++;

                        // 计算位置在phi+dphi, theta处的顶点
                        Vertices[n].x = radius * sinf((phi+dphi)*DTOR) * cosf(theta*DTOR);
                        Vertices[n].y = radius * sinf((phi+dphi)*DTOR) * sinf(theta*DTOR);
                        Vertices[n].z = radius * cosf((phi+dphi)*DTOR);
                       
                        // 计算纹理坐标
                        vx = Vertices[n].x;
                        vy = Vertices[n].y;
                        vz = Vertices[n].z;

                        mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
                        vx /= mag;
                        vy /= mag;
                        vz /= mag;

                        Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
                        Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;               
                        n++;

                        // 计算位于phi, theta+dtheta处的顶点坐标
                        Vertices[n].x = radius * sinf(DTOR*phi) * cosf(DTOR*(theta+dtheta));
                        Vertices[n].y = radius * sinf(DTOR*phi) * sinf(DTOR*(theta+dtheta));
                        Vertices[n].z = radius * cosf(DTOR*phi);
                       
                        // 计算纹理坐标
                        vx = Vertices[n].x;
                        vy = Vertices[n].y;
                        vz = Vertices[n].z;

                        mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
                        vx /= mag;
                        vy /= mag;
                        vz /= mag;

                        Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
                        Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;               
                        n++;

                        if (phi > -90 && phi < 90)
                        {
                                // 计算位于 phi+dphi, theta+dtheta处的顶点坐标
                                Vertices[n].x = radius * sinf((phi+dphi)*DTOR) * cosf(DTOR*(theta+dtheta));
                                Vertices[n].y = radius * sinf((phi+dphi)*DTOR) * sinf(DTOR*(theta+dtheta));
                                Vertices[n].z = radius * cosf((phi+dphi)*DTOR);
                               
                                // 计算纹理坐标
                                vx = Vertices[n].x;
                                vy = Vertices[n].y;
                                vz = Vertices[n].z;

                                mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
                                vx /= mag;
                                vy /= mag;
                                vz /= mag;

                                Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
                                Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;               
                                n++;
                        }
                }
        }
        // 修改纹理坐标
        for (int i=0; i < NumVertices-3; i++)
        {
                if (Vertices.u - Vertices[i+1].u > 0.9f)
                        Vertices[i+1].u += 1.0f;

                if (Vertices[i+1].u - Vertices.u > 0.9f)
                        Vertices.u += 1.0f;

                if (Vertices.u - Vertices[i+2].u > 0.9f)
                        Vertices[i+2].u += 1.0f;

                if (Vertices[i+2].u - Vertices.u > 0.9f)
                        Vertices.u += 1.0f;

                if (Vertices[i+1].u - Vertices[i+2].u > 0.9f)
                        Vertices[i+2].u += 1.0f;

                if (Vertices[i+2].u - Vertices[i+1].u > 0.9f)
                        Vertices[i+1].u += 1.0f;

                if (Vertices.v - Vertices[i+1].v > 0.8f)
                        Vertices[i+1].v += 1.0f;

                if (Vertices[i+1].v - Vertices.v > 0.8f)
                        Vertices.v += 1.0f;

                if (Vertices.v - Vertices[i+2].v > 0.8f)
                        Vertices[i+2].v += 1.0f;

                if (Vertices[i+2].v - Vertices.v > 0.8f)
                        Vertices.v += 1.0f;

                if (Vertices[i+1].v - Vertices[i+2].v > 0.8f)
                        Vertices[i+2].v += 1.0f;

                if (Vertices[i+2].v - Vertices[i+1].v > 0.8f)
                        Vertices[i+1].v += 1.0f;
        }
}

1

主题

56

帖子

56

积分

注册会员

Rank: 2

积分
56
QQ
发表于 2005-2-27 14:16:00 | 显示全部楼层

Re:[求教]关于圆顶天空的问题!

int CMySkyView::RenderSkyDome()
{
        glPushMatrix();
        glTranslatef(0.0f, -250.0f, 0.0f);
        glRotatef(timeGetTime()/200.0f,0.0f, 1.0f, 0.0f);
        glRotatef(270, 1.0f, 0.0f, 0.0f);

        glBegin(GL_TRIANGLE_STRIP);

        for (int i=0; i < NumVertices; i++)
        {
                glColor3f(1.0f, 1.0f, 1.0f);

                glTexCoord2f(Vertices.u, Vertices.v);
                glVertex3f(Vertices.x, Vertices.y, Vertices.z);
        }

        glEnd();

        glPopMatrix();
        return 1;
}

void CMySkyView::ReleaseDome()
{
        if (Vertices)
        {
                delete Vertices;
                Vertices = NULL;
        }
}

20

主题

398

帖子

398

积分

中级会员

Rank: 3Rank: 3

积分
398
 楼主| 发表于 2005-2-27 17:00:00 | 显示全部楼层

Re:[求教]关于圆顶天空的问题!

多谢高手指点!!!努力学习中……

[再问一下] 使用什么样的纹理贴图比较好?能给发几张吗?

31

主题

630

帖子

635

积分

高级会员

Rank: 4

积分
635
发表于 2005-2-27 17:24:00 | 显示全部楼层

Re:[求教]关于圆顶天空的问题!

photoshop里面有个云滤镜很好用。

62

主题

296

帖子

302

积分

中级会员

Rank: 3Rank: 3

积分
302
QQ
发表于 2005-2-27 17:53:00 | 显示全部楼层

Re:[求教]关于圆顶天空的问题!

Ballance里的天空贴图不错,不过是用在立方体天空顶上的,不知道楼主需不需要。

20

主题

398

帖子

398

积分

中级会员

Rank: 3Rank: 3

积分
398
 楼主| 发表于 2005-2-27 19:16:00 | 显示全部楼层

Re:[求教]关于圆顶天空的问题!

多谢各位帮助!!!

谢谢skice,请把Ballance里的天空贴图发给我吧,也许能用到。

E-Mail:edward_hx@163.com

15

主题

1268

帖子

1268

积分

金牌会员

Rank: 6Rank: 6

积分
1268
发表于 2005-2-28 11:14:00 | 显示全部楼层

Re:[求教]关于圆顶天空的问题!

结果是什么?贴张图好吗
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-24 04:09

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表