个人中心

联系我们

搜索 登录 免费注册
界面美化
业务优化
开发工具
图像管理
文档管理
Parasoft

文章详情

如何开始使用SilverLining(中文教程二):渲染场景

2023-07-07 10:55:56

如何开始使用 SilverLining


本文为如何开始使用SilverLining(中文教程二):渲染场景,继续查看>>

如何开始使用SilverLining(中文教程一):演示示例

如何开始使用SilverLining(中文教程三):资源内存管理

如何开始使用SilverLining(中文教程四):集成技巧

如何开始使用SilverLining(中文教程五):调整外观


将SilverLining与你的渲染循环结合起来

这就是初始化的基本内容。现在,你如何将SilverLining与每一帧的渲染结合起来?这很简单。当你渲染一帧动画的时候,你要遵循以下步骤:


  • 设置模型视图和投影矩阵来表示你的摄像机位置和场景。

  • 调用Atmosphere::DrawSky()来绘制天空并计算照明信息。

  • 通过使用Atmosphere::GetSunOrMoonPosition(), Atmosphere::GetSunOrMoonColor()和Atmosphere::GetAmbientColor()返回的信息来设置场景的照明。

  • 通过使用从Atmosphere::GetFogEnabled()和Atmosphere::GetFogSettings()返回的信息来设置你的场景的雾。

  • 绘制你的场景对象。

  • 调用Atmosphere::DrawObjects()来绘制云彩。

下面是一个OpenGL下的渲染循环的例子:


void Display()

{

        glMatrixMode(GL_PROJECTION);

        glLoadIdentity();

        gluPerspective(45.0, aspectRatio, 2, 100000);

 

        // Increment the yaw each frame to spin the camera around 

        yaw += 0.05;

 

        glMatrixMode(GL_MODELVIEW);

        glLoadIdentity();

        glRotatef(-10, 1, 0, 0);

        glRotatef(yaw, 0, 1, 0);

        glTranslatef(0, -100, 0);

 

        // Pass in the view and projection matrices to SilverLining.

        double mv[16], proj[16];

        glGetDoublev(GL_MODELVIEW_MATRIX, mv);

        glGetDoublev(GL_PROJECTION_MATRIX, proj);

        atm->SetCameraMatrix(mv);

        atm->SetProjectionMatrix(proj);

 

        // After setting up your projection and modelview matrices to reflect the current

        // camera position, call Atmosphere::DrawSky() to draw the sky and do the lighting

        // pass on the clouds, if necessary.

        atm->DrawSky(true);

 

        // Now, do all your own drawing...

        SetSceneLighting();

        SetSceneFog();

        DrawGroundPlane();

 

        // When you're done, call Atmosphere::DrawObjects() to draw all the clouds from back to front.

        atm->DrawObjects();

 

        // Now swap the back and front buffers.

        glutSwapBuffers();

 

        glutPostRedisplay();

}


还有一个DirectX 9下的主渲染循环......注意,这个例子使用的是右手坐标系。手性必须与你在初始化Atmosphere对象时指定的一致。这个例子没有处理丢失的设备;请参阅Atmosphere::D3D9DeviceLost()和Atmosphere::D3D9DeviceReset()方法来正确处理这个问题。


DirectX11将是类似的,但不是像DirectX9那样将视图和投影矩阵设置到设备的固定函数管道中,而是需要将这些直接传递给你的顶点程序。请参阅SDK提供的DirectX 11示例代码以了解完整的例子。


static void RenderFrame(HWND hWnd)

{

        static float lastTime = (float)timeGetTime();

 

        if (atm && device)

        {

                D3DXMATRIX Rot, Yaw, Pitch;

                D3DXMatrixRotationX(&Pitch, -10.0f * (3.14f / 360.0f));

                D3DXMatrixRotationY(&Yaw, yaw);

                D3DXMatrixMultiply(&Rot, &Yaw, &Pitch);

                D3DXMATRIX Pos;

                D3DXMatrixTranslation(&Pos, 0, -100, 0);

                D3DXMATRIX view;

                D3DXMatrixMultiply(&view, &Pos, &Rot);

 

                device->SetTransform(D3DTS_VIEW, &view);

 

                //

                // Set projection matrix.

                //

                D3DVIEWPORT9 vp;

                device->GetViewport(&vp);

 

                D3DXMATRIX proj;

                D3DXMatrixPerspectiveFovRH(

                        &proj,

                        45.0 * (D3DX_PI / 180.0),

                        (float)vp.Width / (float)vp.Height,

                        2.0f,

                        200000.0f);

                device->SetTransform(D3DTS_PROJECTION, &proj);

 

                // Set view and proj matrices with SilverLining

                if (atm)

                {

                        double pView[16], pProj[16];

                        int i = 0;

                        for (int row = 0; row < 4; row++)

                        {

                                for (int col = 0; col < 4; col++)

                                {

                                        pView[i] = view(row, col);

                                        pProj[i] = proj(row, col);

                                        i++;

                                }

                        }

 

            atm->SetCameraMatrix(pView);

            atm->SetProjectionMatrix(pProj);

        }

 

                device->BeginScene();

 

                // Call DrawSky after scene has begun and modelview / projection matrices 

                // properly set for the camera position. This will draw the sky if you pass true.

                atm->DrawSky(true);

 

                // Now, do all your own drawing...

                SetSceneLighting();

                SetSceneFog();

                DrawGroundPlane();

 

                // Call DrawObjects to draw all the clouds from back to front.

                atm->DrawObjects();

 

                device->EndScene();

 

                device->Present(0, 0, 0, 0);

 

                // Trigger another redraw.

                InvalidateRect(hWnd, NULL, FALSE);

 

                lastTime = currTime;

        }

}


用SilverLining为你的场景照明

为了使你的场景中的物体与天空的外观保持一致,SilverLining允许你查询其建模的方向性和环境光信息。使用这些信息来照亮你的场景是很容易的。下面是一个使用SilverLining作为指导在OpenGL下设置照明的例子:


void SetSceneLighting()

{

        float x, y, z, r, g, b, ra, ga, ba;

        atm->GetSunOrMoonPosition(&x, &y, &z);

        atm->GetSunOrMoonColor(&r, &g, &b);

        atm->GetAmbientColor(&ra, &ga, &ba);

 

        GLfloat light_ambient[] = {ra, ga, ba, 1.0};

        GLfloat light_diffuse[] = {r, g, b, 1.0};

        GLfloat light_specular[] = {0.0, 0.0, 0.0, 1.0};

        GLfloat light_position[] = {x, y, z, 0};

 

        glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);

        glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);

        glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

        glLightfv(GL_LIGHT0, GL_POSITION, light_position);

        glEnable(GL_LIGHT0);

 

        GLfloat mat_amb_diff[] = {1.0, 1.0, 1.0, 1.0};

        GLfloat no_mat[] = {0, 0, 0, 0};

        glMaterialfv(GL_FRONT, GL_AMBIENT, mat_amb_diff);

        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_amb_diff);

        glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);

        glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);

}


而在DirectX9下,设置场景照明的功能也是如此:


static void SetSceneLighting()

{

        D3DXCOLOR light_ambient, light_diffuse, light_specular;

        D3DXVECTOR3 light_position;

 

        atm->GetSunOrMoonPosition(&light_position.x, &light_position.y, &light_position.z);

        atm->GetSunOrMoonColor(&light_diffuse.r, &light_diffuse.g, &light_diffuse.b);

        atm->GetAmbientColor(&light_ambient.r, &light_ambient.g, &light_ambient.b);

 

        light_diffuse.a = light_ambient.a = 1.0;

 

        D3DLIGHT9 light;

        ::ZeroMemory(&light, sizeof(light));

 

        light.Type = D3DLIGHT_DIRECTIONAL;

        light.Ambient = light_ambient;

        light.Diffuse = light_diffuse;

        light.Specular = D3DXCOLOR(1, 1, 1, 1);

        light.Direction = D3DXVECTOR3(-light_position.x, -light_position.y, -light_position.z);

 

        if (device)

        {

                device->SetLight(0, &light);

                device->LightEnable(0, true);

                device->SetRenderState(D3DRS_NORMALIZENORMALS, true);

                device->SetRenderState(D3DRS_SPECULARENABLE, false);

        }

}


DirectX 11将是类似的,但你将把照明值和位置传给你的着色器,而不是传给设备。


如果你有任何问题,请随时联系我们 https://www.dhorde.com/ 在线客服,电话 023-62585653,或邮箱 sales@dhorde.com


本文为如何开始使用SilverLining(中文教程二):渲染场景,继续查看>>

如何开始使用SilverLining(中文教程一):演示示例

如何开始使用SilverLining(中文教程三):资源内存管理

如何开始使用SilverLining(中文教程四):集成技巧

如何开始使用SilverLining(中文教程五):调整外观


联系我们

周一至周日 8:00-23:00

免费热线

023-62585653

Gavin:13082556879

Jillian:17558866126

Angela:13057566525

开发外包

ERP-一体化

小程序

企业微信客服二维码

企业微信客服

版权所有:重庆庚乾信息科技有限公司 ©2025 Gengqian Information Technology Co., Ltd. 渝ICP备2022008063号-2 渝公网安备50010702505508

版权所有:重庆庚乾信息科技有限公司

©2025 Gengqian Information Technology Co., Ltd. 渝ICP备2022008063号-2 渝公网安备50010702505508