• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當(dāng)自強(qiáng)而不息

            創(chuàng)建3D圖形引擎(4)【OO改良版】

             

            本篇是創(chuàng)建3D圖形引擎(3)【OO改良版】的續(xù)篇,以創(chuàng)建游戲內(nèi)核【OO改良版】中編寫(xiě)的代碼為基礎(chǔ)進(jìn)行開(kāi)發(fā),細(xì)節(jié)說(shuō)明請(qǐng)參閱創(chuàng)建3D圖形引擎(4)。

             

            下載源碼和工程

             

            接口:

            /*************************************************************************
            PURPOSE:
                Interface for sky box.
            *************************************************************************/


            #ifndef _SKY_BOX_H
            #define _SKY_BOX_H

            #include "core_common.h"

            enum SKY_BOX_SIDES  { TOP = 0, BOTTOM, LEFT, RIGHT, FRONT, BACK };

            //=====================================================================================
            // This calss encapsulate how to make sky box.
            //=====================================================================================
            typedef class SKY_BOX
            {
            private:
                typedef 
            struct SKY_BOX_VERTEX
                {
                    
            float x, y, z;
                    
            float u, v;
                } *SKY_BOX_VERTEX_PTR;

                
            #define SKY_BOX_FVF (D3DFVF_XYZ | D3DFVF_TEX1)

            private:    
                TEXTURE         m_textures[6];      
            // face texture (0 - 5)
                VERTEX_BUFFER   m_vertex_buffer;    // mesh vertex buffer
                WORLD_POSITION  m_pos;              // sky box position

            public:
                SKY_BOX();
                ~SKY_BOX();

                BOOL create();
                
            void free();

                
            void set_default_state();
                BOOL load_texture(
            short side, pcstr filename, D3DCOLOR transparent, D3DFORMAT format);

                
            void rotate(float x_rot, float y_rot, float z_rot);
                
            void rotate_rel(float x_rot, float y_rot, float z_rot);

                BOOL render(CAMERA_PTR camera, BOOL alpha_blend);
            } *SKY_BOX_PTR;

            #endif

            實(shí)現(xiàn):
             
            /*************************************************************************
            PURPOSE:
                Implement for sky box.
            *************************************************************************/


            #include "core_common.h"
            #include "core_graphics.h"
            #include "sky_box.h"

            //----------------------------------------------------------------------------------
            // Constructor, initialize member data.
            //----------------------------------------------------------------------------------
            SKY_BOX::SKY_BOX()
            {    
            }

            //----------------------------------------------------------------------------------
            // Destructor, release allocated resource.
            //----------------------------------------------------------------------------------
            SKY_BOX::~SKY_BOX()
            {
                free();
            }

            //----------------------------------------------------------------------------------
            // Release allocated resource.
            //----------------------------------------------------------------------------------
            void SKY_BOX::free()
            {    
                
            for(short i = 0; i < 6; i++)
                    m_textures[i].free();

                m_vertex_buffer.free();
            }

            //----------------------------------------------------------------------------------
            // Set default state for sky box.
            //----------------------------------------------------------------------------------
            void SKY_BOX::set_default_state()
            {
                m_pos.set_default_state();
            }

            //----------------------------------------------------------------------------------
            // Create a sky box class object.
            //----------------------------------------------------------------------------------
            BOOL SKY_BOX::create()
            {
                SKY_BOX_VERTEX verts[24] = {
                    { -10.0f,  10.0f, -10.0f, 0.0f, 0.0f },  
            // Top
                    {  10.0f,  10.0f, -10.0f, 1.0f, 0.0f },
                    { -10.0f,  10.0f,  10.0f, 0.0f, 1.0f },
                    {  10.0f,  10.0f,  10.0f, 1.0f, 1.0f },

                    { -10.0f, -10.0f,  10.0f, 0.0f, 0.0f },  
            // Bottom
                    {  10.0f, -10.0f,  10.0f, 1.0f, 0.0f },
                    { -10.0f, -10.0f, -10.0f, 0.0f, 1.0f },
                    {  10.0f, -10.0f, -10.0f, 1.0f, 1.0f },

                    { -10.0f,  10.0f, -10.0f, 0.0f, 0.0f },  
            // Left
                    { -10.0f,  10.0f,  10.0f, 1.0f, 0.0f },
                    { -10.0f, -10.0f, -10.0f, 0.0f, 1.0f },
                    { -10.0f, -10.0f,  10.0f, 1.0f, 1.0f },

                    {  10.0f,  10.0f,  10.0f, 0.0f, 0.0f },  
            // Right
                    {  10.0f,  10.0f, -10.0f, 1.0f, 0.0f },
                    {  10.0f, -10.0f,  10.0f, 0.0f, 1.0f },
                    {  10.0f, -10.0f, -10.0f, 1.0f, 1.0f },

                    { -10.0f,  10.0f,  10.0f, 0.0f, 0.0f },  
            // Front
                    {  10.0f,  10.0f,  10.0f, 1.0f, 0.0f },
                    { -10.0f, -10.0f,  10.0f, 0.0f, 1.0f },
                    {  10.0f, -10.0f,  10.0f, 1.0f, 1.0f },
                    
                    {  10.0f,  10.0f, -10.0f, 0.0f, 0.0f },  
            // Back
                    { -10.0f,  10.0f, -10.0f, 1.0f, 0.0f },
                    {  10.0f, -10.0f, -10.0f, 0.0f, 1.0f },
                    { -10.0f, -10.0f, -10.0f, 1.0f, 1.0f },
                };

                free();     
            // free a prior sky box

                // error checking
                if(g_d3d_device == NULL)
                    
            return FALSE;

                
            // create the vertex buffer (and copy over sky box vertices)
                if(m_vertex_buffer.create(24, sizeof(SKY_BOX_VERTEX), SKY_BOX_FVF))
                    m_vertex_buffer.fill_in(0, 24, (
            void*)verts);

                
            // rotate the sky box into default orientation
                rotate(0.0f, 0.0f, 0.0f);

                
            return TRUE;
            }

            //----------------------------------------------------------------------------------
            // Set a specific side's texture map, allow for transparent and storage format changes.
            //----------------------------------------------------------------------------------
            BOOL SKY_BOX::load_texture(short side, pcstr filename, D3DCOLOR transparent, D3DFORMAT format)
            {
                
            // error checking
                if(g_d3d_device == NULL || side < 0 || side > 5)
                    
            return FALSE;

                m_textures[side].free();    
            // free prior texture

                
            return m_textures[side].load(filename, transparent, format);
            }

            //----------------------------------------------------------------------------------
            // Rotate box to an absolute rotation.
            //----------------------------------------------------------------------------------
            void SKY_BOX::rotate(float x_rot, float y_rot, float z_rot)
            {
                m_pos.rotate(x_rot, y_rot, z_rot);
            }

            //----------------------------------------------------------------------------------
            // Rotate box to an relative rotation.
            //----------------------------------------------------------------------------------
            void SKY_BOX::rotate_rel(float x_rot, float y_rot, float z_rot)
            {
                m_pos.rotate_rel(x_rot, y_rot, z_rot);
            }

            //----------------------------------------------------------------------------------
            // Render the sky box (using optional alpha-blending) and using current view 
            // transformation from camera.
            //----------------------------------------------------------------------------------
            BOOL SKY_BOX::render(CAMERA_PTR camera, BOOL alpha_blend)
            {
                
            // error checking
                if(g_d3d_device == NULL || camera == NULL)
                    
            return FALSE;

                
            // position sky box around viewer
                m_pos.move(camera->get_x_pos(), camera->get_y_pos(), camera->get_z_pos());
                g_d3d_device->SetTransform(D3DTS_WORLD, m_pos.get_world_matrix());    

                
            // enable alpha testing and alpha blending

                enable_alpha_testing();

                
            if(alpha_blend)
                    enable_alpha_blending(D3DBLEND_SRCCOLOR, D3DBLEND_DESTCOLOR);

                
            // draw each layer
                for(short i = 0; i < 6; i++)
                {
                    
            if(m_textures[i].is_loaded())
                    {
                        g_d3d_device->SetTexture(0, m_textures[i].get_d3d_texture());            
                        m_vertex_buffer.render(i * 4, 2, D3DPT_TRIANGLESTRIP);
                    }
                }

                
            // disable alpha testing and alpha blending

               disable_alpha_testing();

                
            if(alpha_blend)
                    disable_alpha_blending();

                
            return TRUE;
            }

            測(cè)試代碼:
            /************************************************************************************
            PURPOSE:
                 node tree mesh test.
            ************************************************************************************/


            #include "core_common.h"
            #include "core_framework.h"
            #include "core_graphics.h"
            #include "core_input.h"
            #include "core_sound.h"
            #include "frustum.h"
            #include "node_tree_mesh.h"
            #include "sky_box.h"

            class APP : public FRAMEWORK
            {
            public:
                BOOL init()
                {
                    
            if(! create_display(g_hwnd, get_client_width(g_hwnd), get_client_height(g_hwnd), 16, TRUE, TRUE))
                        
            return FALSE;
                    
                    set_perspective(D3DX_PI / 4, 1.3333f, 1.0f, 10000.0f);

                    ShowCursor(TRUE);
                
                    
            // enable lighting and setup light

                    g_d3d_device->SetRenderState(D3DRS_LIGHTING, TRUE);
                    set_ambient_light(24, 24, 24);
                    g_d3d_device->LightEnable(0, TRUE);        
                    
                    m_light.set_default_state();
                    m_light.set_attenuation_0(0.4f);
                    m_light.set_range(1000.0f);

                    m_camera.set_default_state();

                    
            // initialize input and input device
                    m_input.create(g_hwnd, get_window_inst());
                    m_keyboard.create_keyboard(&m_input);
                    m_mouse.create_mouse(&m_input, TRUE);

                    
            // load the mesh and create a nodetree mesh from it

                    
            if(! m_mesh.load("..\\Data\\Level.x", "..\\Data\\"))
                        
            return FALSE;

                    m_node_tree_mesh.create(&m_mesh, QUADTREE, 256.0f, 32);

                    
            // position view at origin
                    m_x_pos = m_y_pos = m_z_pos = 0.0f;

                    
            // setup sky box
                    m_sky_box.create();
                    m_sky_box.set_default_state();

                    
            for(short i = 0; i < 6; i++)
                        m_sky_box.load_texture(i, "..\\data\\stars.bmp", 0, D3DFMT_UNKNOWN);

                    
            // initialize the sound system to play with
                    m_sound.init(g_hwnd, 22050, 1, 16, DSSCL_PRIORITY);
                    m_sound_data.load_wav("..\\data\\cricket.wav");

                    
            for(short i = 0; i < 3; i++)
                        m_sound_channel[i].create(&m_sound, 22050, 1, 16);

                    
            return TRUE;
                }

                BOOL frame()
                {
                    
            static DWORD time_now = timeGetTime();

                    
            // play a random cricket sound
                    for(short i = 0; i< 3; i++)
                    {
                        
            if(!m_sound_channel[i].is_playing() && rand()%256 < 16)
                            m_sound_channel[i].play(&m_sound_data, 10, 1);
                    }

                    
            // calculate elapsed time (plus speed boost)
                    ulong time_elapsed = timeGetTime() - time_now;
                    time_now = timeGetTime();

                    
            // read keyboard and mouse data        
                    m_keyboard.read();
                    m_mouse.read();

                    
            // process input and update everything, ESC quits program.

                    
            if(m_keyboard.get_key_state(KEY_ESC))
                        
            return FALSE;

                    
            float x_move, z_move;

                    
            // process movement
                    x_move = z_move = 0.0f;

                    
            if(m_keyboard.get_key_state(KEY_UP) || m_keyboard.get_key_state(KEY_W))
                    {
                        x_move = (
            float) sin(m_camera.get_y_rotation()) * time_elapsed;
                        z_move = (
            float) cos(m_camera.get_y_rotation()) * time_elapsed;
                    }
                    
                    
            if(m_keyboard.get_key_state(KEY_DOWN) || m_keyboard.get_key_state(KEY_S))
                    {
                        x_move = (
            float) -sin(m_camera.get_y_rotation()) * time_elapsed;
                        z_move = (
            float) -cos(m_camera.get_y_rotation()) * time_elapsed;
                    }

                    
            if(m_keyboard.get_key_state(KEY_LEFT) || m_keyboard.get_key_state(KEY_A))
                    {
                        x_move = (
            float) sin(m_camera.get_y_rotation() - 1.57f) * time_elapsed;
                        z_move = (
            float) cos(m_camera.get_y_rotation() - 1.57f) * time_elapsed;
                    }

                    
            if(m_keyboard.get_key_state(KEY_RIGHT) || m_keyboard.get_key_state(KEY_D))
                    {
                        x_move = (
            float) sin(m_camera.get_y_rotation() + 1.57f) * time_elapsed;
                        z_move = (
            float) cos(m_camera.get_y_rotation() + 1.57f) * time_elapsed;
                    }

                    
            // check for height changes (can step up to 64 units)
                    float height = m_node_tree_mesh.closest_height_below_object(m_x_pos, m_y_pos + m_above_floor, m_z_pos);

                    
            if(m_y_pos > height)
                    {
                        
            // dropping
                        if((m_y_pos -= (float)time_elapsed) < height)
                            m_y_pos = height;
                        
            else
                            x_move = z_move = 0.0f;
                    }
                    
            else
                    {
                        
            // climbing
                        m_y_pos = height;
                    }

                    
            float dist;

                    
            // check for movement collision - can not walk past anything blocking path.
                    if(m_node_tree_mesh.is_ray_intersect_mesh(m_x_pos, m_y_pos + m_above_floor, m_z_pos,
                                                             m_x_pos + x_move, m_y_pos + m_above_floor, m_z_pos + z_move,
                                                             &dist))
                    {
                        
            // adjust coordinates to be exactly 2.5 units away from target

                        
            float diff = dist - 2.5f;

                        D3DXVECTOR2 dir;
                        D3DXVec2Normalize(&dir, &D3DXVECTOR2(x_move, z_move));

                        dir *= diff;

                        x_move = dir.x;
                        z_move = dir.y;
                    }

                    
            // update view coordinats
                    m_x_pos += x_move;
                    m_z_pos += z_move;

                    
            // position camera and rotate based on mouse position

                    m_camera.move(m_x_pos, m_y_pos + 50.0f, m_z_pos);

                    
            // m_mouse.get_y_delta():
                    //      get mouse's relative x movement coordinate.
                    //
                    // m_mouse.get_x_delta():
                    //      get mouse's relative y movement coordinate.
                    m_camera.rotate_rel((float) m_mouse.get_y_delta() / 200.0f, (float) m_mouse.get_x_delta() / 200.0f, 0.0f);

                    
            // position
                    m_light.move(m_x_pos, m_y_pos + 60.0f, m_z_pos);
                    g_d3d_device->SetLight(0, m_light.get_d3d_light());        

                    FRUSTUM frustum;

                    
            // set camera and calculate frustum    
                    g_d3d_device->SetTransform(D3DTS_VIEW, m_camera.get_view_matrix());        
                    frustum.create(0.0f);
                    
                    
            // render everything
                    clear_display_zbuffer(1.0f);               

                    
            //clear_display(0, 1.0f);               

                    // begin render now
                    if(SUCCEEDED(g_d3d_device->BeginScene()))        
                    {
                        g_d3d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
                        g_d3d_device->SetRenderState(D3DRS_LIGHTING, FALSE);            
                        m_sky_box.render(&m_camera, FALSE);

                        g_d3d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
                        g_d3d_device->SetRenderState(D3DRS_LIGHTING, TRUE);            
                        m_node_tree_mesh.render(&frustum, 0.0f);

                        g_d3d_device->EndScene();            
                    }

                    present_display();

                    
            return TRUE;
                }

                BOOL shutdown()
                {
                    
            return TRUE;
                }

            private:  
                CAMERA          m_camera;
                LIGHT           m_light;

                SOUND           m_sound;
                SOUND_DATA      m_sound_data;
                SOUND_CHANNEL   m_sound_channel[3];

                SKY_BOX         m_sky_box;

                INPUT           m_input;
                INPUT_DEVICE    m_keyboard;
                INPUT_DEVICE    m_mouse;    

                MESH            m_mesh;
                NODE_TREE_MESH  m_node_tree_mesh;

                
            float           m_x_pos, m_y_pos, m_z_pos;
                
                
            static const float m_above_floor;
            };

            const float APP::m_above_floor = 64.0f;

            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
            {
                DWORD client_width  = 640;
                DWORD client_height = 480;
                DWORD x_pos = (get_screen_width()  - client_width) / 2;
                DWORD y_pos = (get_screen_height() - client_height) / 4;

                
            if(! build_window(inst, "node_tree_mesh_class", "node tree mesh test", 
                                  WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
                                  x_pos, y_pos, client_width, client_height))
                {
                    
            return -1;
                }

                APP app;
                app.run();

                
            return 0;
            }
             

            posted on 2007-10-25 15:07 lovedday 閱讀(360) 評(píng)論(0)  編輯 收藏 引用

            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(lèi)(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            囯产精品久久久久久久久蜜桃| 久久香蕉超碰97国产精品| 91精品婷婷国产综合久久| 国产精品乱码久久久久久软件 | 亚洲国产成人久久精品动漫| 国产精品成人99久久久久| 久久综合亚洲鲁鲁五月天| 欧洲精品久久久av无码电影| 久久婷婷综合中文字幕| 久久天天躁狠狠躁夜夜网站| 亚洲国产成人久久综合碰碰动漫3d| 性做久久久久久免费观看| 亚洲一区中文字幕久久| 久久婷婷国产剧情内射白浆 | 无码人妻久久久一区二区三区| 亚洲午夜久久久| 亚洲AV伊人久久青青草原| 精品久久久久久亚洲| 一本久久a久久精品综合香蕉| 精品久久一区二区三区| 久久久精品2019免费观看| 18禁黄久久久AAA片| 国产ww久久久久久久久久| 性欧美大战久久久久久久久 | 久久99国产综合精品| 91麻豆国产精品91久久久| 国产精品久久久久一区二区三区| 色婷婷综合久久久久中文| 一本综合久久国产二区| 久久夜色精品国产亚洲av| 久久精品国产影库免费看| 国产精品女同久久久久电影院 | 国产三级精品久久| 一本久久久久久久| 久久国产精品99久久久久久老狼| 久久亚洲精品中文字幕| 精品久久久久香蕉网| 2021久久精品国产99国产精品| 久久综合狠狠综合久久激情 | 国产精品99久久久久久猫咪| 日本久久久精品中文字幕|