DirectX 11에서 프레임워크는 일반적으로 대화형 3D 애플리케이션을 구축하기 위한 기본 구조를 제공하는 소프트웨어 인프라 또는 라이브러리 집합을 의미다. 여기에는 그래픽 파이프라인 관리, 입출력 장치 처리, 3D 콘텐츠 렌더링 및 표시를 위한 공통 기능 제공 등이 포함된다.

 

목차

     

     


     

     

    Framework

     

    DirectX 11에서 프레임워크는 일반적으로 대화형 3D 애플리케이션을 구축하기 위한 기본 구조를 제공하는 소프트웨어 인프라 또는 라이브러리 집합을 의미다. 여기에는 그래픽 파이프라인 관리, 입출력 장치 처리, 3D 콘텐츠 렌더링 및 표시를 위한 공통 기능 제공 등이 포함된다.

    DirectX 11 자체는 그래픽 하드웨어에 액세스하고 제어하기 위한 낮은 수준의 API를 제공하지만, DirectX 11만을 사용하여 처음부터 완전한 응용 프로그램을 구축하는 것은 복잡하고 시간이 많이 걸리는 작업일 수 있다. 프레임워크는 개발자가 하드웨어 액세스 및 관리에 대한 낮은 수준의 세부 사항에 대해 걱정하지 않고 응용프로그램의 실제 콘텐츠를 만드는 데 집중할 수 있도록 미리 구축된 구성요소와 도구를 제공하여 이 프로세스를 단순화한다.

    프레임워크는 일반적으로 개발자가 3D 객체를 계층적 방식으로 구성하고 조작할 수 있는 장면 그래프와 3D 그래픽의 실제 렌더링을 처리하는 렌더러와 같은 기능을 포함한다. 또한 조명, 물리학 및 충돌 감지와 같은 기능을 지원할 수 있다.

    DirectX 11의 인기 있는 프레임워크로는 XNA, Unity, 언리얼 엔진 등이 있다. 이러한 프레임워크는 단순한 게임에서 복잡한 시뮬레이션 및 가상 현실 경험에 이르기까지 3D 애플리케이션을 구축하기 위한 다양한 기능과 도구를 제공합니다.

    더보기

    In DirectX 11, a framework typically refers to a software infrastructure or a set of libraries that provide a basic structure for building interactive 3D applications. This includes managing the graphics pipeline, handling input and output devices, and providing common functions for rendering and displaying 3D content.

     

    DirectX 11 itself provides a low-level API for accessing and controlling the graphics hardware, but building a complete application from scratch using just DirectX 11 can be a complex and time-consuming task. A framework simplifies this process by providing pre-built components and tools that allow developers to focus on creating the actual content of their application rather than worrying about the low-level details of hardware access and management.

     

    A framework typically includes features such as a scene graph, which allows developers to organize and manipulate 3D objects in a hierarchical manner, and a renderer that handles the actual rendering of 3D graphics. It may also provide support for features such as lighting, physics, and collision detection.

    Some popular frameworks for DirectX 11 include XNA, Unity, and Unreal Engine. These frameworks provide a range of features and tools for building 3D applications, from simple games to complex simulations and virtual reality experiences.


     

    fx

     

    light.fx

    더보기
    struct LightDesc
    {
        float4 Ambient;
        float4 Specular;
        float3 Direction;
        float Padding;
        float3 Position;
    };
    
    cbuffer CB_Light
    {
        LightDesc GlobalLight;
    };
    
    
    Texture2D DiffuseMap;
    Texture2D SpecularMap;
    Texture2D NormalMap;
    TextureCube SkyCubeMap;
    Texture2D ShadowMap;
    SamplerComparisonState ShadowSampler;
    
    struct MaterialDesc
    {
        float4 Ambient;
        float4 Diffuse;
        float4 Specular;
        float4 Emissive;
    };
    
    cbuffer CB_Material
    {
        MaterialDesc Material;
    };
    
    MaterialDesc MakeMaterial()
    {
        MaterialDesc output;
        output.Ambient = float4(0, 0, 0, 0);
        output.Diffuse = float4(0, 0, 0, 0);
        output.Specular = float4(0, 0, 0, 0);
        output.Emissive = float4(0, 0, 0, 0);
    
        return output;
    }
    
    float3 MaterialToColor(MaterialDesc result)
    {
        return (result.Ambient + result.Diffuse + result.Specular + result.Emissive).rgb;
    }
    
    void AddMaterial(inout MaterialDesc result, MaterialDesc val)
    {
        result.Ambient += val.Ambient;
        result.Diffuse += val.Diffuse;
        result.Specular += val.Specular;
        result.Emissive += val.Emissive;
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    void Texture(inout float4 color, Texture2D t, float2 uv, SamplerState samp)
    {
        float4 sampling = t.Sample(samp, uv);
        
        color = color * sampling;
    }
    
    void Texture(inout float4 color, Texture2D t, float2 uv)
    {
        Texture(color, t, uv, LinearSampler);
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    void ComputeLight(out MaterialDesc output, float3 normal, float3 wPosition)
    {
        output = MakeMaterial();
        
        float3 direction = -GlobalLight.Direction;
        float NdotL = dot(direction, normalize(normal));
        
        output.Ambient = GlobalLight.Ambient * Material.Ambient;
        float3 E = normalize(ViewPosition() - wPosition);
    
        [flatten]
        if (NdotL > 0.0f)
        {
            output.Diffuse = Material.Diffuse * NdotL;
            
            [flatten]
            if (Material.Specular.a > 0.0f)
            {
                float3 R = normalize(reflect(-direction, normal));
                float RdotE = saturate(dot(R, E));
                
                float specular = pow(RdotE, Material.Specular.a);
                output.Specular = Material.Specular * specular * GlobalLight.Specular;
            }
        }
        
        [flatten]
        if (Material.Emissive.a > 0.0f)
        {
            float NdotE = dot(E, normalize(normal));
            float emissive = smoothstep(1.0f - Material.Emissive.a, 1.0f, 1.0f - saturate(NdotE));
            
            output.Emissive = Material.Emissive * emissive;
        }
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    #define MAX_POINT_LIGHTS 256
    struct PointLight
    {
        float4 Ambient;
        float4 Diffuse;
        float4 Specular;
        float4 Emissive;
        
        float3 Position;
        float Range;
        
        float Intensity;
        float3 Padding;
    };
    
    cbuffer CB_PointLights
    {
        uint PointLightCount;
        float3 CB_PointLights_Padding;
        
        PointLight PointLights[MAX_POINT_LIGHTS];
    };
    
    void ComputePointLight(inout MaterialDesc output, float3 normal, float3 wPosition)
    {
        output = MakeMaterial();
        MaterialDesc result = MakeMaterial();
    
        for (uint i = 0; i < PointLightCount; i++)
        {
            float3 light = PointLights[i].Position - wPosition;
            float dist = length(light);
            
            
            [flatten]
            if (dist > PointLights[i].Range)
                continue;
            
            
            light /= dist; //Normalize
            
            result.Ambient = PointLights[i].Ambient * Material.Ambient;
            
            float NdotL = dot(light, normalize(normal));
            float3 E = normalize(ViewPosition() - wPosition);
    
            [flatten]
            if (NdotL > 0.0f)
            {
                result.Diffuse = Material.Diffuse * NdotL * PointLights[i].Diffuse;
            
                [flatten]
                if (Material.Specular.a > 0.0f)
                {
                    float3 R = normalize(reflect(-light, normal));
                    float RdotE = saturate(dot(R, E));
                
                    float specular = pow(RdotE, Material.Specular.a);
                    result.Specular = Material.Specular * specular * PointLights[i].Specular;
                }
            }
        
            [flatten]
            if (Material.Emissive.a > 0.0f)
            {
                float NdotE = dot(E, normalize(normal));
                float emissive = smoothstep(1.0f - Material.Emissive.a, 1.0f, 1.0f - saturate(NdotE));
            
                result.Emissive = Material.Emissive * emissive * PointLights[i].Emissive;
            }
            
            float temp = 1.0f / saturate(dist / PointLights[i].Range);
            float att = temp * temp * (1.0f / max(1.0f - PointLights[i].Intensity, 1e-8f));
            
            output.Ambient += result.Ambient * temp;
            output.Diffuse += result.Diffuse * att;
            output.Specular += result.Specular * att;
            output.Emissive += result.Emissive * att;
        }
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    #define MAX_SPOT_LIGHTS 256
    struct SpotLight
    {
        float4 Ambient;
        float4 Diffuse;
        float4 Specular;
        float4 Emissive;
        
        float3 Position;
        float Range;
        
        float3 Direction;
        float Angle;
        
        float Intensity;
        float3 Padding;
    };
    
    cbuffer CB_SpotLights
    {
        uint SpotLightCount;
        float3 CB_SpotLights_Padding;
        
        SpotLight SpotLights[MAX_SPOT_LIGHTS];
    };
    
    void ComputeSpotLight(inout MaterialDesc output, float3 normal, float3 wPosition)
    {
        output = MakeMaterial();
        MaterialDesc result = MakeMaterial();
    
        for (uint i = 0; i < SpotLightCount; i++)
        {
            float3 light = SpotLights[i].Position - wPosition;
            float dist = length(light);
            
            
            [flatten]
            if (dist > SpotLights[i].Range)
                continue;
            
            
            light /= dist; //Normalize
            
            result.Ambient = SpotLights[i].Ambient * Material.Ambient;
            
            float NdotL = dot(light, normalize(normal));
            float3 E = normalize(ViewPosition() - wPosition);
    
            [flatten]
            if (NdotL > 0.0f)
            {
                result.Diffuse = Material.Diffuse * NdotL * SpotLights[i].Diffuse;
            
                [flatten]
                if (Material.Specular.a > 0.0f)
                {
                    float3 R = normalize(reflect(-light, normal));
                    float RdotE = saturate(dot(R, E));
                
                    float specular = pow(RdotE, Material.Specular.a);
                    result.Specular = Material.Specular * specular * SpotLights[i].Specular;
                }
            }
        
            [flatten]
            if (Material.Emissive.a > 0.0f)
            {
                float NdotE = dot(E, normalize(normal));
                float emissive = smoothstep(1.0f - Material.Emissive.a, 1.0f, 1.0f - saturate(NdotE));
            
                result.Emissive = Material.Emissive * emissive * SpotLights[i].Emissive;
            }
            
            
            float temp = pow(saturate(dot(-light, SpotLights[i].Direction)), SpotLights[i].Angle);
            float att = temp * (1.0f / max(1.0f - SpotLights[i].Intensity, 1e-8f));
            
            output.Ambient += result.Ambient * temp;
            output.Diffuse += result.Diffuse * att;
            output.Specular += result.Specular * att;
            output.Emissive += result.Emissive * att;
        }
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    void NormalMapping(float2 uv, float3 normal, float3 tangent, SamplerState samp)
    {
        float4 map = NormalMap.Sample(samp, uv);
        
        [flatten]
        if (any(map.rgb) == false)
            return;
    
        
        float3 coord = map.rgb * 2.0f - 1.0f; //-1 ~ +1
        
        
        //탄젠트 공간
        float3 N = normalize(normal); //Z
        float3 T = normalize(tangent - dot(tangent, N) * N); //X
        float3 B = cross(N, T); //Y
        
        float3x3 TBN = float3x3(T, B, N);
        
        coord = mul(coord, TBN);
        
        Material.Diffuse *= saturate(dot(-GlobalLight.Direction, coord));
    }
    
    void NormalMapping(float2 uv, float3 normal, float3 tangent)
    {
        NormalMapping(uv, normal, tangent, LinearSampler);
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    float4 PS_AllLight(MeshOutput input)
    {
        NormalMapping(input.Uv, input.Normal, input.Tangent);
        
        Texture(Material.Diffuse, DiffuseMap, input.Uv);
        Texture(Material.Specular, SpecularMap, input.Uv);
        
        MaterialDesc output = MakeMaterial();
        MaterialDesc result = MakeMaterial();
        
        ComputeLight(output, input.Normal, input.wPosition);
        AddMaterial(result, output);
        
        ComputePointLight(output, input.Normal, input.wPosition);
        AddMaterial(result, output);
        
        ComputeSpotLight(output, input.Normal, input.wPosition);
        AddMaterial(result, output);
        
        return float4(MaterialToColor(result).rgb, 1.0f);
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    Texture2D ProjectorMap;
    
    struct ProjectorDesc
    {
        matrix View;
        matrix Projection;
        
        float4 Color;
    };
    
    cbuffer CB_Projector
    {
        ProjectorDesc Projector;
    };
    
    void VS_Projector(inout float4 wvp, float4 oPosition)
    {
        wvp = WorldPosition(oPosition);
        wvp = mul(wvp, Projector.View);
        wvp = mul(wvp, Projector.Projection);
    }
    
    void PS_Projector(inout float4 color, float4 wvp)
    {
        float3 uvw = 0;
        
        uvw.x = wvp.x / wvp.w * 0.5f + 0.5f;
        uvw.y = -wvp.y / wvp.w * 0.5f + 0.5f;
        uvw.z = wvp.z / wvp.w;
    
        [flatten]
        if (saturate(uvw.x) == uvw.x && saturate(uvw.y) == uvw.y && saturate(uvw.z) == uvw.z)
        {
            float4 map = ProjectorMap.Sample(LinearSampler, uvw.xy);
            
            map.rgb *= Projector.Color.rgb;
            color = lerp(color, map, map.a);
        }
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    cbuffer CB_Shadow
    {
        matrix ShadowView;
        matrix ShadowProjection;
        
        float2 ShadowMapSize;
        float ShadowBias;
        
        uint ShadowQuality;
    };

     

    InstancingAnimation.fx

    더보기
    #include "00_Global.fx"
    #include "00_Light.fx"
    #include "00_Render.fx"
    
    float4 PS(MeshOutput input) : SV_Target
    {
        float3 normal = normalize(input.Normal);
        float3 light = -GlobalLight.Direction;
        
        return DiffuseMap.Sample(LinearSampler, input.Uv) * dot(light, normal);
    }
    
    technique11 T0
    {
        P_VP(P0, VS_Mesh, PS)
        P_VP(P1, VS_Model, PS)
        P_VP(P2, VS_Animation, PS)
    }

     

     

    Render.fx

    더보기
    #include "00_Global.fx"
    #include "00_Light.fx"
    #include "00_Render.fx"
    
    float4 PS(MeshOutput input) : SV_Target
    {
        float3 normal = normalize(input.Normal);
        float3 light = -GlobalLight.Direction;
        
        return DiffuseMap.Sample(LinearSampler, input.Uv) * dot(light, normal);
    }
    
    technique11 T0
    {
        P_VP(P0, VS_Mesh, PS)
        P_VP(P1, VS_Model, PS)
        P_VP(P2, VS_Animation, PS)
    }

     


     

    Mesh Demo

     

    MeshDemo.h

    더보기
    #pragma once
    #include "Systems/IExecute.h"
    
    class MeshDemo : public IExecute
    {
    public:
    	virtual void Initialize() override;
    	virtual void Ready() override {}
    	virtual void Destroy() override {}
    	virtual void Update() override;
    	virtual void PreRender() override {}
    	virtual void Render() override;
    	virtual void PostRender() override {}
    	virtual void ResizeScreen() override {}
    
    private:
    	void CreateMesh();
    
    	void Pass(UINT mesh, UINT model, UINT anim);
    
    private:
    	Shader* shader;
    
    	Material* floor;
    	Material* stone;
    	Material* brick;
    	Material* wall;
    
    	MeshRender* cube;
    	MeshRender* cylinder;
    	MeshRender* sphere;
    	MeshRender* grid;
    
    	vector<MeshRender *> meshes;
    	vector<ModelRender *> models;
    	vector<ModelAnimator *> animators;
    };
    • Material* floor, stone, brick, wall 추가
    • vector<ㅁ*> meshes, models, animators 추가
    • void Pass(UINT mesh, UINT model, UINT anim); 추가
    • direction 부분 삭제
      • Vector3 direction = Vector3(-1, -1, 1);, ID3DX11EffectVectorVariable* sDirection; 삭제
      • Material과 Light가 통합되면서 이 부분이 필요없어진다. 

     

     

    MeshDemo.cpp

    더보기
    #include "stdafx.h"
    #include "MeshDemo.h"
    
    void MeshDemo::Initialize()
    {
    	Context::Get()->GetCamera()->RotationDegree(20, 0, 0);
    	Context::Get()->GetCamera()->Position(1, 36, -85);
    
    
    	shader = new Shader(L"55_Render.fx");
    	
    	CreateMesh();
    }
    
    void MeshDemo::Update()
    {
    	cube->Update();
    	grid->Update();
    	cylinder->Update();
    	sphere->Update();
    }
    
    void MeshDemo::Render()
    {
    	Pass(0, 1, 2);
    
    	wall->Render();
    	sphere->Render();
    
    	brick->Render();
    	cylinder->Render();
    
    	stone->Render();
    	cube->Render();
    
    	floor->Render();
    	grid->Render();
    }
    
    void MeshDemo::CreateMesh()
    {
    	//Create Material
    	{
    		floor = new Material(shader);
    		floor->DiffuseMap("Floor.png");
    		//floor->SpecularMap("Floor_Specular.png");
    		//floor->NormalMap("Floor_Normal.png");
    		//floor->Specular(1, 1, 1, 20);
    
    		stone = new Material(shader);
    		stone->DiffuseMap("Stones.png");
    		//stone->SpecularMap("Stones_Specular.png");
    		//stone->NormalMap("Stones_Normal.png");
    		//stone->Specular(1, 1, 1, 20);
    
    		brick = new Material(shader);
    		brick->DiffuseMap("Bricks.png");
    		//brick->SpecularMap("Bricks_Specular.png");
    		//brick->NormalMap("Bricks_Normal.png");
    		//brick->Specular(1, 0.3f, 0.3f, 20);
    
    		wall = new Material(shader);
    		wall->DiffuseMap("Wall.png");
    		//wall->SpecularMap("Wall_Specular.png");
    		//wall->NormalMap("Wall_Normal.png");
    		//wall->Specular(1, 1, 1, 20);
    	}
    
    	//Create Mesh
    	{
    		Transform* transform = NULL;
    
    		cube = new MeshRender(shader, new MeshCube());
    		transform = cube->AddTransform();
    		transform->Position(0, 5, 0);
    		transform->Scale(20, 10, 20);
    
    		grid = new MeshRender(shader, new MeshGrid(5, 5));
    		transform = grid->AddTransform();
    		transform->Position(0, 0, 0);
    		transform->Scale(12, 1, 12);
    
    		cylinder = new MeshRender(shader, new MeshCylinder(0.5f, 3.0f, 20, 20));
    		sphere = new MeshRender(shader, new MeshSphere(0.5f, 20, 20));
    		for (UINT i = 0; i < 5; i++)
    		{
    			transform = cylinder->AddTransform();
    			transform->Position(-30, 6, -15.0f + (float)i * 15.0f);
    			transform->Scale(5, 5, 5);
    
    			transform = cylinder->AddTransform();
    			transform->Position(30, 6, -15.0f + (float)i * 15.0f);
    			transform->Scale(5, 5, 5);
    
    
    			transform = sphere->AddTransform();
    			transform->Position(-30, 15.5f, -15.0f + (float)i * 15.0f);
    			transform->Scale(5, 5, 5);
    
    			transform = sphere->AddTransform();
    			transform->Position(30, 15.5f, -15.0f + (float)i * 15.0f);
    			transform->Scale(5, 5, 5);
    		}
    	}
    
    	sphere->UpdateTransforms();
    	cylinder->UpdateTransforms();
    	cube->UpdateTransforms();
    	grid->UpdateTransforms();
    
    	meshes.push_back(sphere);
    	meshes.push_back(cylinder);
    	meshes.push_back(cube);
    	meshes.push_back(grid);
    }
    
    void MeshDemo::Pass(UINT mesh, UINT model, UINT anim)
    {
    	for (MeshRender* temp : meshes)
    		temp->Pass(mesh);
    
    	for (ModelRender* temp : models)
    		temp->Pass(model);
    
    	for (ModelAnimator* temp : animators)
    		temp->Pass(anim);
    }
    • Material를 Mesh에 적용한다.
    • 헤더에 변경된 내용을 적용한다.

     

    Cube Sky Demo

     

    CubeSkyDemo.h

    더보기
    #pragma once
    #include "Systems/IExecute.h"
    
    class CubeSkyDemo : public IExecute
    {
    public:
    	virtual void Initialize() override;
    	virtual void Ready() override {}
    	virtual void Destroy() override {}
    	virtual void Update() override;
    	virtual void PreRender() override {}
    	virtual void Render() override;
    	virtual void PostRender() override {}
    	virtual void ResizeScreen() override {}
    
    private:
    	void CreateMesh();
    
    	void Pass(UINT mesh, UINT model, UINT anim);
    
    private:
    	Shader* shader;
    
    	CubeSky* sky;
    
    	Material* floor;
    	Material* stone;
    	Material* brick;
    	Material* wall;
    
    	MeshRender* cube;
    	MeshRender* cylinder;
    	MeshRender* sphere;
    	MeshRender* grid;
    
    	vector<MeshRender *> meshes;
    	vector<ModelRender *> models;
    	vector<ModelAnimator *> animators;
    };
    • Shader* cubeMapShader;, CubeMap* cubeMap; 삭제
      • 이 예제에서는 cubeMap 사용하지 않을것이기 때문에 삭제한다. 
    • Material* floor, stone, brick, wall 추가
    • vector<ㅁ*> meshes, models, animators 추가
    • void Pass(UINT mesh, UINT model, UINT anim); 추가
    • direction 부분 삭제. 
      • Vector3 direction = Vector3(-1, -1, 1);, ID3DX11EffectVectorVariable* sDirection; 삭제
      • Material과 Light가 통합되면서 이 부분이 필요없어진다. 

     

     

    CubeSkyDemo.cp

    더보기
    #include "stdafx.h"
    #include "CubeSkyDemo.h"
    
    void CubeSkyDemo::Initialize()
    {
    	Context::Get()->GetCamera()->RotationDegree(20, 0, 0);
    	Context::Get()->GetCamera()->Position(1, 36, -85);
    
    
    	shader = new Shader(L"55_Render.fx");
    
    	sky = new CubeSky(L"Environment/GrassCube1024.dds");
    	
    	CreateMesh();
    }
    
    void CubeSkyDemo::Update()
    {
    	sky->Update();
    
    	cube->Update();
    	grid->Update();
    	cylinder->Update();
    	sphere->Update();
    }
    
    void CubeSkyDemo::Render()
    {
    	sky->Render();
    
    	
    	Pass(0, 1, 2);
    
    	wall->Render();
    	sphere->Render();
    
    	brick->Render();
    	cylinder->Render();
    
    	stone->Render();
    	cube->Render();
    
    	floor->Render();
    	grid->Render();
    }
    
    void CubeSkyDemo::CreateMesh()
    {
    	//Create Material
    	{
    		floor = new Material(shader);
    		floor->DiffuseMap("Floor.png");
    		//floor->SpecularMap("Floor_Specular.png");
    		//floor->NormalMap("Floor_Normal.png");
    		//floor->Specular(1, 1, 1, 20);
    
    		stone = new Material(shader);
    		stone->DiffuseMap("Stones.png");
    		//stone->SpecularMap("Stones_Specular.png");
    		//stone->NormalMap("Stones_Normal.png");
    		//stone->Specular(1, 1, 1, 20);
    
    		brick = new Material(shader);
    		brick->DiffuseMap("Bricks.png");
    		//brick->SpecularMap("Bricks_Specular.png");
    		//brick->NormalMap("Bricks_Normal.png");
    		//brick->Specular(1, 0.3f, 0.3f, 20);
    
    		wall = new Material(shader);
    		wall->DiffuseMap("Wall.png");
    		//wall->SpecularMap("Wall_Specular.png");
    		//wall->NormalMap("Wall_Normal.png");
    		//wall->Specular(1, 1, 1, 20);
    	}
    
    	//Create Mesh
    	{
    		Transform* transform = NULL;
    
    		cube = new MeshRender(shader, new MeshCube());
    		transform = cube->AddTransform();
    		transform->Position(0, 5, 0);
    		transform->Scale(20, 10, 20);
    
    		grid = new MeshRender(shader, new MeshGrid(5, 5));
    		transform = grid->AddTransform();
    		transform->Position(0, 0, 0);
    		transform->Scale(12, 1, 12);
    
    		cylinder = new MeshRender(shader, new MeshCylinder(0.5f, 3.0f, 20, 20));
    		sphere = new MeshRender(shader, new MeshSphere(0.5f, 20, 20));
    		for (UINT i = 0; i < 5; i++)
    		{
    			transform = cylinder->AddTransform();
    			transform->Position(-30, 6, -15.0f + (float)i * 15.0f);
    			transform->Scale(5, 5, 5);
    
    			transform = cylinder->AddTransform();
    			transform->Position(30, 6, -15.0f + (float)i * 15.0f);
    			transform->Scale(5, 5, 5);
    
    
    			transform = sphere->AddTransform();
    			transform->Position(-30, 15.5f, -15.0f + (float)i * 15.0f);
    			transform->Scale(5, 5, 5);
    
    			transform = sphere->AddTransform();
    			transform->Position(30, 15.5f, -15.0f + (float)i * 15.0f);
    			transform->Scale(5, 5, 5);
    		}
    	}
    
    	sphere->UpdateTransforms();
    	cylinder->UpdateTransforms();
    	cube->UpdateTransforms();
    	grid->UpdateTransforms();
    
    	meshes.push_back(sphere);
    	meshes.push_back(cylinder);
    	meshes.push_back(cube);
    	meshes.push_back(grid);
    }
    
    void CubeSkyDemo::Pass(UINT mesh, UINT model, UINT anim)
    {
    	for (MeshRender* temp : meshes)
    		temp->Pass(mesh);
    
    	for (ModelRender* temp : models)
    		temp->Pass(model);
    
    	for (ModelAnimator* temp : animators)
    		temp->Pass(anim);
    }
    • 헤더에 변경된 내용을 적용한다.

     

    Context

     

    Context.h

    더보기
    #pragma once
    
    class Context
    {
    public:
    	static Context* Get();
    	static void Create();
    	static void Delete();
    
    private:
    	Context();
    	~Context();
    
    public:
    	void ResizeScreen();
    
    	void Update();
    	void Render();
    
    	Matrix View();
    	Matrix Projection();
    
    	class Perspective* GetPerspective() { return perspective; }
    	class Viewport* GetViewport() { return viewport; }
    	class Camera* GetCamera() { return camera; }
    
    	Color& Ambient() { return ambient; }
    	Color& Specular() { return specular; }
    	Vector3& Direction() { return direction; }
    	Vector3& Position() { return position; }
    
    private:
    	static Context* instance;
    
    private:
    	class Perspective* perspective;
    	class Viewport* viewport;
    	class Camera* camera;
    
    	Color ambient = Color(0, 0, 0, 1);
    	Color specular = Color(1, 1, 1, 1);
    	Vector3 direction = Vector3(-1, -1, 1);
    	Vector3 position = Vector3(0, 0, 0);
    };
    • 조명을 넣어준다.
      • Color& Ambient() { return ambient; }
      • Color& Specular() { return specular; }
      • Vector3& Direction() { return direction; }
      • Vector3& Position() { return position; }

     

     

    Context.cpp

    변경사항 없음

     


     

    마무리

     

    PerFrame.h

    더보기
    #pragma once
    
    class PerFrame
    {
    public:
    	PerFrame(Shader* shader);
    	~PerFrame();
    
    	void Update();
    	void Render();
    
    private:
    	struct Desc
    	{
    		Matrix View;
    		Matrix ViewInverse;
    		Matrix Projection;
    		Matrix VP;
    
    		Plane Culling[4];
    		Plane Clipping;
    
    		float Time;
    		float Padding[3];
    	} desc;
    
    	struct LightDesc
    	{
    		Color Ambient;
    		Color Specular;
    		Vector3 Direction;
    		float Padding; //float4 만들기 위해 Padding으로 끝어준다.
    
    		Vector3 Position;
    		float Padding2;
    	} lightDesc;
    
    private:
    	Shader* shader;
    
    	ConstantBuffer* buffer;
    	ID3DX11EffectConstantBuffer* sBuffer;
    
    	ConstantBuffer* lightBuffer;
    	ID3DX11EffectConstantBuffer* sLightBuffer;
    };
    • Light 정보 넣어주기
      • struct LightDesc {
        Color Ambient;
        Color Specular;
        Vector3 Direction;
        float Padding;
        Vector3 Position;
        float Padding2;
        lightDesc;

     

     

    PerFrame.cpp

    더보기
    #include "Framework.h"
    #include "PerFrame.h"
    
    PerFrame::PerFrame(Shader * shader)
    	: shader(shader)
    {
    	buffer = new ConstantBuffer(&desc, sizeof(Desc));
    	sBuffer = shader->AsConstantBuffer("CB_PerFrame");
    
    	lightBuffer = new ConstantBuffer(&lightDesc, sizeof(LightDesc));
    	sLightBuffer = shader->AsConstantBuffer("CB_Light");
    }
    
    PerFrame::~PerFrame()
    {
    	SafeDelete(buffer);
    	SafeDelete(lightBuffer);
    }
    
    void PerFrame::Update()
    {
    	desc.Time = Time::Get()->Running();
    
    	lightDesc.Ambient = Context::Get()->Ambient();
    	lightDesc.Specular = Context::Get()->Specular();
    	lightDesc.Direction = Context::Get()->Direction();
    	lightDesc.Position = Context::Get()->Position();
    }
    
    void PerFrame::Render()
    {
    	desc.View = Context::Get()->View();
    	D3DXMatrixInverse(&desc.ViewInverse, NULL, &desc.View);
    
    	desc.Projection = Context::Get()->Projection();
    	desc.VP = desc.View * desc.Projection;
    
    	buffer->Render();
    	sBuffer->SetConstantBuffer(buffer->Buffer());
    
    	lightBuffer->Render();
    	sLightBuffer->SetConstantBuffer(lightBuffer->Buffer());
    }
    • lightDesc 적용
      • lightDesc.Ambient = Context::Get()->Ambient();
        lightDesc.Specular = Context::Get()->Specular();
        lightDesc.Direction = Context::Get()->Direction();
        lightDesc.Position = Context::Get()->Position();
      • sLightBuffer->SetConstantBuffer(lightBuffer->Buffer());

     


     

    실행화면