글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자입니다

 

목차

     

     


     

     

     

    Instancing Mesh

     

    Shader
      00_Global.fx
    00_Render.fx
    51_InstancingMesh
    Framework
      Environment
      CubeSky.h .cpp
      Meshes
      Mesh.h .cpp
    MeshCube.h. cpp
    MeshCylinder.h .cpp
    MeshGrid.h .cpp
    MeshQuad.h .cpp
    MeshSphere.h .cpp

    MeshRender.h .cpp
      Model
      ModelMesh.h .cpp
    ModelEditor
      Demo
      MeshDemo.h .cpp
    ModelDemo.h .cpp 
    하늘 제거
      Main.h .cpp

     

     


     

    fx

     

    00_Global.fx

    더보기
    cbuffer CB_PerFrame
    {
        matrix View; 
        matrix ViewInverse;//View의 역행렬
        matrix Projection;
        matrix VP;
        
        float4 Culling[4];
        float4 Clipping;
        
        float Time; //게임시간
    };
    
    cbuffer CB_World
    {
        matrix World;
    };
    
    Texture2D DiffuseMap;
    Texture2D SpecularMap;
    Texture2D NormalMap;
    
    TextureCube SkyCubeMap;
    
    ///////////////////////////////////////////////////////////////////////////////
    
    static const float PI = 3.14159265f;
    
    ///////////////////////////////////////////////////////////////////////////////
    
    float4 WorldPosition(float4 position)
    {
        return mul(position, World);
    }
    
    float4 ViewProjection(float4 position)
    {
        return mul(position, VP);
    
        //position = mul(position, View);
        //return mul(position, Projection);
    }
    
    float3 WorldNormal(float3 normal)
    {
        return mul(normal, (float3x3) World);
    }
    
    float3 WorldTangent(float3 tangent)
    {
        return mul(tangent, (float3x3) World);
    }
    
    float3 ViewPosition()
    {
        return ViewInverse._41_42_43;
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    struct Vertex
    {
        float4 Position : Position;
    };
    
    struct VertexNormal
    {
        float4 Position : Position;
        float3 Normal : Normal;
    };
    
    struct VertexColor
    {
        float4 Position : Position;
        float4 Color : Color;
    };
    
    struct VertexColorNormal
    {
        float4 Position : Position;
        float4 Color : Color;
        float3 Normal : Normal;
    };
    
    struct VertexTexture
    {
        float4 Position : Position;
        float2 Uv : Uv;
    };
    
    struct VertexTextureNormal
    {
        float4 Position : Position;
        float2 Uv : Uv;
        float3 Normal : Normal;
    };
    
    
    ///////////////////////////////////////////////////////////////////////////////
    
    struct MeshOutput
    {
        float4 Position : SV_Position0; //Rasterizing Position
        float3 oPosition : Position1;   //Original Position
    
        float3 Normal : Normal;
        float2 Uv : Uv;
    };
    
    ///////////////////////////////////////////////////////////////////////////////
    
    SamplerState LinearSampler
    {
        Filter = MIN_MAG_MIP_LINEAR;
    
        AddressU = Wrap;
        AddressV = Wrap;
    };
    
    SamplerState PointSampler
    {
        Filter = MIN_MAG_MIP_POINT;
    
        AddressU = Wrap;
        AddressV = Wrap;
    };
    
    RasterizerState FrontCounterClockwise_True
    {
        FrontCounterClockwise = true;
    };
    
    RasterizerState FillMode_WireFrame
    {
        FillMode = WireFrame;
    };
    
    //RasterizerState CullMode_None
    //{
    //    CullMode = None;
    //};
    
    DepthStencilState DepthEnable_False
    {
        DepthEnable = false;
    };
    
    
    ///////////////////////////////////////////////////////////////////////////////
    
    
    ///////////////////////////////////////////////////////////////////////////////
    // Vertex / Pixel
    ///////////////////////////////////////////////////////////////////////////////
    #define P_VP(name, vs, ps) \
    pass name \
    { \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_RS_VP(name, rs, vs, ps) \
    pass name \
    { \
        SetRasterizerState(rs); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_BS_VP(name, bs, vs, ps) \
    pass name \
    { \
        SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_DSS_VP(name, dss, vs, ps) \
    pass name \
    { \
        SetDepthStencilState(dss, 1); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_RS_DSS_VP(name, rs, dss, vs, ps) \
    pass name \
    { \
        SetRasterizerState(rs); \
        SetDepthStencilState(dss, 1); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_RS_BS_VP(name, rs, bs, vs, ps) \
    pass name \
    { \
        SetRasterizerState(rs); \
        SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_DSS_BS_VP(name, dss, bs, vs, ps) \
    pass name \
    { \
        SetDepthStencilState(dss, 1); \
        SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    // Vertex / Geometry / Pixel
    ///////////////////////////////////////////////////////////////////////////////
    #define P_VGP(name, vs, gs, ps) \
    pass name \
    { \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetGeometryShader(CompileShader(gs_5_0, gs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_RS_VGP(name, rs, vs, gs, ps) \
    pass name \
    { \
        SetRasterizerState(rs); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetGeometryShader(CompileShader(gs_5_0, gs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_BS_VGP(name, bs, vs, gs, ps) \
    pass name \
    { \
        SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetGeometryShader(CompileShader(gs_5_0, gs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_DSS_VGP(name, dss, vs, gs, ps) \
    pass name \
    { \
        SetDepthStencilState(dss, 1); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetGeometryShader(CompileShader(gs_5_0, gs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_RS_DSS_VGP(name, rs, dss, vs, gs, ps) \
    pass name \
    { \
        SetRasterizerState(rs); \
        SetDepthStencilState(dss, 1); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetGeometryShader(CompileShader(gs_5_0, gs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_RS_BS_VGP(name, rs, bs, vs, gs, ps) \
    pass name \
    { \
        SetRasterizerState(rs); \
        SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetGeometryShader(CompileShader(gs_5_0, gs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_DSS_BS_VGP(name, dss, bs, vs, gs, ps) \
    pass name \
    { \
        SetDepthStencilState(dss, 1); \
        SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetGeometryShader(CompileShader(gs_5_0, gs())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    
    ///////////////////////////////////////////////////////////////////////////////
    // Vertex / Tessellation / Pixel
    ///////////////////////////////////////////////////////////////////////////////
    #define P_VTP(name, vs, hs, ds, ps) \
    pass name \
    { \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetHullShader(CompileShader(hs_5_0, hs())); \
        SetDomainShader(CompileShader(ds_5_0, ds())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_RS_VTP(name, rs, vs, hs, ds, ps) \
    pass name \
    { \
        SetRasterizerState(rs); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetHullShader(CompileShader(hs_5_0, hs())); \
        SetDomainShader(CompileShader(ds_5_0, ds())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_BS_VTP(name, bs, vs, hs, ds, ps) \
    pass name \
    { \
        SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetHullShader(CompileShader(hs_5_0, hs())); \
        SetDomainShader(CompileShader(ds_5_0, ds())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_DSS_VTP(name, dss, vs, hs, ds, ps) \
    pass name \
    { \
        SetDepthStencilState(dss, 1); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetHullShader(CompileShader(hs_5_0, hs())); \
        SetDomainShader(CompileShader(ds_5_0, ds())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_RS_DSS_VTP(name, rs, dss, vs, hs, ds, ps) \
    pass name \
    { \
        SetRasterizerState(rs); \
        SetDepthStencilState(dss, 1); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetHullShader(CompileShader(hs_5_0, hs())); \
        SetDomainShader(CompileShader(ds_5_0, ds())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_RS_BS_VTP(name, rs, bs, vs, hs, ds, ps) \
    pass name \
    { \
        SetRasterizerState(rs); \
        SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetHullShader(CompileShader(hs_5_0, hs())); \
        SetDomainShader(CompileShader(ds_5_0, ds())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_DSS_BS_VTP(name, dss, bs, vs, hs, ds, ps) \
    pass name \
    { \
        SetDepthStencilState(dss, 1); \
        SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetHullShader(CompileShader(hs_5_0, hs())); \
        SetDomainShader(CompileShader(ds_5_0, ds())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }
    
    #define P_RS_DSS_BS_VTP(name, rs, dss, bs, vs, hs, ds, ps) \
    pass name \
    { \
        SetRasterizerState(rs); \
        SetDepthStencilState(dss, 1); \
        SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
        SetVertexShader(CompileShader(vs_5_0, vs())); \
        SetHullShader(CompileShader(hs_5_0, hs())); \
        SetDomainShader(CompileShader(ds_5_0, ds())); \
        SetPixelShader(CompileShader(ps_5_0, ps())); \
    }

     

    00_Render.fx

    더보기
    float4 PS_Sky(MeshOutput input) : SV_Target
    {
        return SkyCubeMap.Sample(LinearSampler, input.oPosition);
    }
    ///////////////////////////////////////////////////////////////////////////////
    
    struct VertexMesh
    {
        float4 Position : Position;
        float2 Uv : Uv;
        float3 Normal : Normal;
        float3 Tangent : Tangent;
        
        matrix Transform : Inst1_Transform;
        float4 Color : Inst2_Color;
    };
    
    ///////////////////////////////////////////////////////////////////////////////
    
    #define VS_GENERATE \
    output.oPosition = input.Position.xyz; \
    \
    output.Position = WorldPosition(input.Position); \
    output.wPosition = output.Position.xyz; \
    output.Position = ViewProjection(output.Position); \
    output.wvpPosition = output.Position; \
    output.wvpPosition_Sub = output.Position; \
    \
    output.sPosition = WorldPosition(input.Position); \
    output.sPosition = mul(output.sPosition, ShadowView); \
    output.sPosition = mul(output.sPosition, ShadowProjection); \
    \
    output.Normal = WorldNormal(input.Normal); \
    output.Tangent = WorldTangent(input.Tangent); \
    \
    output.Uv = input.Uv; \
    output.Color = input.Color;
    
    ///////////////////////////////////////////////////////////////////////////////
    
    struct DepthOutput
    {
        float4 Position : SV_Position;
        float4 sPosition : Position1;
    };
    
    float4 PS_Depth(DepthOutput input) : SV_Target
    {
        float depth = input.Position.z / input.Position.w;
        
        return float4(depth, depth, depth, 1.0f);
    }
    
    #define VS_DEPTH_GENERATE \
    output.Position = WorldPosition(input.Position); \
    output.Position = mul(output.Position, ShadowView); \
    output.Position = mul(output.Position, ShadowProjection); \
    \
    output.sPosition = output.Position;
    
    ///////////////////////////////////////////////////////////////////////////////
    
    void SetMeshWorld(inout matrix world, VertexMesh input)
    {
        world = input.Transform;
    }
    
    MeshOutput VS_Mesh(VertexMesh input)
    {
        MeshOutput output;
        
        SetMeshWorld(World, input);
        VS_GENERATE
        
        return output;
    }
    
    DepthOutput VS_Depth_Mesh(VertexMesh input)
    {
        DepthOutput output;
        
        SetMeshWorld(World, input);
        VS_DEPTH_GENERATE
        
        return output;
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    struct VertexModel
    {
        float4 Position : Position;
        float2 Uv : Uv;
        float3 Normal : Normal;
        float3 Tangent : Tangent;
        float4 BlendIndices : BlendIndices;
        float4 BlendWeights : BlendWeights;
        
        uint InstanceID : SV_InstanceID;
        
        matrix Transform : Inst1_Transform;
        float4 Color : Inst2_Color;
    };
    
    Texture2DArray TransformsMap;
    #define MAX_MODEL_TRANSFORMS 250
    
    cbuffer CB_Bone
    {
        //matrix BoneTransforms[MAX_MODEL_TRANSFORMS];
        
        uint BoneIndex;
    };
    
    void SetModelWorld(inout matrix world, VertexModel input)
    {
        //world = mul(BoneTransforms[BoneIndex], world);
        
        float4 m0 = TransformsMap.Load(int4(BoneIndex * 4 + 0, input.InstanceID, 0, 0));
        float4 m1 = TransformsMap.Load(int4(BoneIndex * 4 + 1, input.InstanceID, 0, 0));
        float4 m2 = TransformsMap.Load(int4(BoneIndex * 4 + 2, input.InstanceID, 0, 0));
        float4 m3 = TransformsMap.Load(int4(BoneIndex * 4 + 3, input.InstanceID, 0, 0));
        
        matrix transform = matrix(m0, m1, m2, m3);
        world = mul(transform, input.Transform);
    }
    
    MeshOutput VS_Model(VertexModel input)
    {
        MeshOutput output;
        
        SetModelWorld(World, input);
        VS_GENERATE
        
        return output;
    }
    
    DepthOutput VS_Depth_Model(VertexModel input)
    {
        DepthOutput output;
        
        SetModelWorld(World, input);
        VS_DEPTH_GENERATE
        
        return output;
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    #define MAX_MODEL_KEYFRAMES 500
    #define MAX_MODEL_INSTANCE 500
    
    struct AnimationFrame
    {
        int Clip;
    
        uint CurrFrame;
        uint NextFrame;
    
        float Time;
        float Running;
    
        float3 Padding;
    };
    
    struct TweenFrame
    {
        float TakeTime;
        float TweenTime;
        float RunningTime;
        float Padding;
    
        AnimationFrame Curr;
        AnimationFrame Next;
    };
    
    cbuffer CB_TweenFrame
    {
        TweenFrame TweenFrames[MAX_MODEL_INSTANCE];
    };
    
    void SetTweenWorld(inout matrix world, VertexModel input)
    {
        float indices[4] = { input.BlendIndices.x, input.BlendIndices.y, input.BlendIndices.z, input.BlendIndices.w };
        float weights[4] = { input.BlendWeights.x, input.BlendWeights.y, input.BlendWeights.z, input.BlendWeights.w };
        
        
        int clip[2];
        int currFrame[2];
        int nextFrame[2];
        float time[2];
        
        clip[0] = TweenFrames[input.InstanceID].Curr.Clip;
        currFrame[0] = TweenFrames[input.InstanceID].Curr.CurrFrame;
        nextFrame[0] = TweenFrames[input.InstanceID].Curr.NextFrame;
        time[0] = TweenFrames[input.InstanceID].Curr.Time;
        
        clip[1] = TweenFrames[input.InstanceID].Next.Clip;
        currFrame[1] = TweenFrames[input.InstanceID].Next.CurrFrame;
        nextFrame[1] = TweenFrames[input.InstanceID].Next.NextFrame;
        time[1] = TweenFrames[input.InstanceID].Next.Time;
        
        
        
        float4 c0, c1, c2, c3;
        float4 n0, n1, n2, n3;
        
        matrix curr = 0, next = 0;
        matrix currAnim = 0;
        matrix nextAnim = 0;
        
        matrix transform = 0;
        
        [unroll(4)]
        for (int i = 0; i < 4; i++)
        {
            c0 = TransformsMap.Load(int4(indices[i] * 4 + 0, currFrame[0], clip[0], 0));
            c1 = TransformsMap.Load(int4(indices[i] * 4 + 1, currFrame[0], clip[0], 0));
            c2 = TransformsMap.Load(int4(indices[i] * 4 + 2, currFrame[0], clip[0], 0));
            c3 = TransformsMap.Load(int4(indices[i] * 4 + 3, currFrame[0], clip[0], 0));
            curr = matrix(c0, c1, c2, c3);
            
            n0 = TransformsMap.Load(int4(indices[i] * 4 + 0, nextFrame[0], clip[0], 0));
            n1 = TransformsMap.Load(int4(indices[i] * 4 + 1, nextFrame[0], clip[0], 0));
            n2 = TransformsMap.Load(int4(indices[i] * 4 + 2, nextFrame[0], clip[0], 0));
            n3 = TransformsMap.Load(int4(indices[i] * 4 + 3, nextFrame[0], clip[0], 0));
            next = matrix(n0, n1, n2, n3);
            
            currAnim = lerp(curr, next, time[0]);
            
            
            [flatten]
            if (clip[1] > -1)
            {
                c0 = TransformsMap.Load(int4(indices[i] * 4 + 0, currFrame[1], clip[1], 0));
                c1 = TransformsMap.Load(int4(indices[i] * 4 + 1, currFrame[1], clip[1], 0));
                c2 = TransformsMap.Load(int4(indices[i] * 4 + 2, currFrame[1], clip[1], 0));
                c3 = TransformsMap.Load(int4(indices[i] * 4 + 3, currFrame[1], clip[1], 0));
                curr = matrix(c0, c1, c2, c3);
            
                n0 = TransformsMap.Load(int4(indices[i] * 4 + 0, nextFrame[1], clip[1], 0));
                n1 = TransformsMap.Load(int4(indices[i] * 4 + 1, nextFrame[1], clip[1], 0));
                n2 = TransformsMap.Load(int4(indices[i] * 4 + 2, nextFrame[1], clip[1], 0));
                n3 = TransformsMap.Load(int4(indices[i] * 4 + 3, nextFrame[1], clip[1], 0));
                next = matrix(n0, n1, n2, n3);
            
                nextAnim = lerp(curr, next, time[1]);
                
                currAnim = lerp(currAnim, nextAnim, TweenFrames[input.InstanceID].TweenTime);
            }
            
            
            transform += mul(weights[i], currAnim);
        }
        
        world = mul(transform, input.Transform);
    }
    
    struct BlendFrame
    {
        uint Mode;
        float Alpha;
        float2 Padding;
        
        AnimationFrame Clip[3];
    };
    
    cbuffer CB_BlendFrame
    {
        BlendFrame BlendFrames[MAX_MODEL_INSTANCE];
    };
    
    void SetBlendWorld(inout matrix world, VertexModel input)
    {
        float indices[4] = { input.BlendIndices.x, input.BlendIndices.y, input.BlendIndices.z, input.BlendIndices.w };
        float weights[4] = { input.BlendWeights.x, input.BlendWeights.y, input.BlendWeights.z, input.BlendWeights.w };
        
        
        float4 c0, c1, c2, c3;
        float4 n0, n1, n2, n3;
        
        matrix curr = 0, next = 0;
        matrix currAnim[3];
        matrix anim = 0;
        matrix transform = 0;
        
        BlendFrame frame = BlendFrames[input.InstanceID];
        
        [unroll(4)]
        for (int i = 0; i < 4; i++)
        {
            [unroll(3)]
            for (int k = 0; k < 3; k++)
            {
                c0 = TransformsMap.Load(int4(indices[i] * 4 + 0, frame.Clip[k].CurrFrame, frame.Clip[k].Clip, 0));
                c1 = TransformsMap.Load(int4(indices[i] * 4 + 1, frame.Clip[k].CurrFrame, frame.Clip[k].Clip, 0));
                c2 = TransformsMap.Load(int4(indices[i] * 4 + 2, frame.Clip[k].CurrFrame, frame.Clip[k].Clip, 0));
                c3 = TransformsMap.Load(int4(indices[i] * 4 + 3, frame.Clip[k].CurrFrame, frame.Clip[k].Clip, 0));
                curr = matrix(c0, c1, c2, c3);
            
                n0 = TransformsMap.Load(int4(indices[i] * 4 + 0, frame.Clip[k].NextFrame, frame.Clip[k].Clip, 0));
                n1 = TransformsMap.Load(int4(indices[i] * 4 + 1, frame.Clip[k].NextFrame, frame.Clip[k].Clip, 0));
                n2 = TransformsMap.Load(int4(indices[i] * 4 + 2, frame.Clip[k].NextFrame, frame.Clip[k].Clip, 0));
                n3 = TransformsMap.Load(int4(indices[i] * 4 + 3, frame.Clip[k].NextFrame, frame.Clip[k].Clip, 0));
                next = matrix(n0, n1, n2, n3);
            
                currAnim[k] = lerp(curr, next, frame.Clip[k].Time);
            }
           
            int clipA = (int) frame.Alpha;
            int clipB = clipA + 1;
            
            float alpha = frame.Alpha;
            if (alpha >= 1.0f)
            {
                alpha = frame.Alpha - 1.0f;
                
                if (frame.Alpha >= 2.0f)
                {
                    clipA = 1;
                    clipB = 2;
                }
            }
            
            anim = lerp(currAnim[clipA], currAnim[clipB], alpha);
            
            transform += mul(weights[i], anim);
        }
        
        world = mul(transform, input.Transform);
    }
    
    MeshOutput VS_Animation(VertexModel input)
    {
        MeshOutput output;
        
        if (BlendFrames[input.InstanceID].Mode == 0)
            SetTweenWorld(World, input);
        else
            SetBlendWorld(World, input);
        
        VS_GENERATE
        
        return output;
    }
    
    DepthOutput VS_Depth_Animation(VertexModel input)
    {
        DepthOutput output;
        
        if (BlendFrames[input.InstanceID].Mode == 0)
            SetTweenWorld(World, input);
        else
            SetBlendWorld(World, input);
        
        VS_DEPTH_GENERATE
        
        return output;
    }

     

     

    51_InstancingMesh

    더보기
    #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)
    }

     

     


     

    Mesh

     

    Mesh.h

    더보기
    #pragma once
    
    class Mesh
    {
    public:
    	typedef VertexTextureNormal MeshVertex;
    
    public:
    	Mesh();
    	virtual ~Mesh();
    
    	void SetShader(Shader* shader);
    	void Pass(UINT val) { pass = val; }
    
    	void Update();
    	void Render(UINT drawCount);
    
    protected:
    	virtual void Create() = 0;
    
    protected:
    	Shader* shader;
    	UINT pass = 0;
    
    	PerFrame* perFrame = NULL;
    
    	VertexBuffer* vertexBuffer = NULL;
    	IndexBuffer* indexBuffer = NULL;
    
    	MeshVertex* vertices;
    	UINT* indices;
    
    	UINT vertexCount, indexCount;
    };

     

     

    Mesh.cpp

    더보기
    #include "Framework.h"
    #include "Mesh.h"
    
    Mesh::Mesh()
    {
    
    }
    
    Mesh::~Mesh()
    {
    	SafeDelete(perFrame);
    
    	SafeDelete(vertexBuffer);
    	SafeDelete(indexBuffer);
    
    	SafeDeleteArray(vertices);
    	SafeDeleteArray(indices);
    }
    
    void Mesh::SetShader(Shader * shader)
    {
    	this->shader = shader;
    
    	SafeDelete(perFrame);
    	perFrame = new PerFrame(shader);
    }
    
    void Mesh::Update()
    {
    	perFrame->Update();
    }
    
    void Mesh::Render(UINT drawCount)
    {
    	if (vertexBuffer == NULL || indexBuffer == NULL)
    	{
    		Create();
    
    		vertexBuffer = new VertexBuffer(vertices, vertexCount, sizeof(MeshVertex));
    		indexBuffer = new IndexBuffer(indices, indexCount);
    	}
    
    	perFrame->Render();
    	vertexBuffer->Render();
    	indexBuffer->Render();
    
    	D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    	shader->DrawIndexedInstanced(0, pass, indexCount, drawCount);
    }
    • void Mesh::Render(UINT drawCoung)에서 그릴 개수를 정해준다. 
      • DrawIndexedInstanced(0, pass, indexCount, drawCount)
        • drawCount = 그릴 개수
        • 들여온 정보를 인스턴싱화한다. 

     

     


     

    MeshCube, MeshCylinder, MeshGrid, MeshQuad, MeshSphere에서 shader 부분 삭제 

     

    MeshCube, MeshCylinder, MeshGrid, MeshQuad, MeshSphere에서 shader 부분을 삭제해준다.

     


     

    MeshRender 

     

    MeshRender.h

    더보기
    #pragma once
    #define MAX_MESH_INSTANCE 500
    
    class MeshRender
    {
    public:
    	MeshRender(Shader* shader, Mesh* mesh);
    	~MeshRender();
    
    	Mesh* GetMesh() { return mesh; }
    
    	void Update();
    	void Render();
    
    	void Pass(UINT val) { mesh->Pass(val); }
    
    	Transform* AddTransform();
    	Transform* GetTransform(UINT index) { return transforms[index]; }
    	void UpdateTransforms();
    
    private:
    	Mesh* mesh;
    
    	vector<Transform *> transforms;
    	Matrix worlds[MAX_MESH_INSTANCE];
    
    	VertexBuffer* instanceBuffer;
    };
    • Transform 관련 삭제
      • Instancing을 통해 여러개를 그릴 예정이기 때문에 사용하지 않는다.
    • bool bRead = False; 삭제
      • Texture를 넣기 때문에 Texture의 유무에 따라 데이터를 읽어들였음을 판단할 수 있음. 

     

     

    MeshRender.cpp

    더보기
    #include "Framework.h"
    #include "MeshRender.h"
    
    MeshRender::MeshRender(Shader * shader, Mesh * mesh)
    	: mesh(mesh)
    {
    	Pass(0);
    	mesh->SetShader(shader);
    
    	for (UINT i = 0; i < MAX_MESH_INSTANCE; i++)
    		D3DXMatrixIdentity(&worlds[i]);
    
    	//
    	instanceBuffer = new VertexBuffer(worlds, MAX_MESH_INSTANCE, sizeof(Matrix), 1, true);
    }
    
    MeshRender::~MeshRender()
    {
    	for (Transform* transform : transforms)
    		SafeDelete(transform);
    
    	SafeDelete(instanceBuffer);
    	SafeDelete(mesh);
    }
    
    void MeshRender::Update()
    {
    	mesh->Update();
    }
    
    void MeshRender::Render()
    {
    	instanceBuffer->Render();
    
    	mesh->Render(transforms.size());
    }
    
    Transform * MeshRender::AddTransform()
    {
    	Transform* transform = new Transform();
    	transforms.push_back(transform);
    
    	return transform;
    }
    
    void MeshRender::UpdateTransforms()
    {
    	for (UINT i = 0; i < transforms.size(); i++)
    		memcpy(worlds[i], transforms[i]->World(), sizeof(Matrix));
    
    	D3D11_MAPPED_SUBRESOURCE subResource;
    	D3D::GetDC()->Map(instanceBuffer->Buffer(), 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
    	{
    		memcpy(subResource.pData, worlds, sizeof(Matrix) * MAX_MESH_INSTANCE);
    	}
    	D3D::GetDC()->Unmap(instanceBuffer->Buffer(), 0);
    }
    • Transform 관련 삭제
      • Instancing을 통해 여러개를 그릴 예정이기 때문에 사용하지 않는다.
    • instanceBuffer = new VertexBuffer(worlds, MAX_MESH_INSTANCE, sizeof(Matrix), 1, true);
      • sizeof(Matrix): 하나의 크기 할당.
      • 1: 1번 슬롯
      • true: CPU가 쓸 수 있도록 열어준다.
    • CreateTexture();

     


     

     

    ModelDemo, AnimationDemo 불필요한 곳 지우기

     

    ModelDemo.h .cpp

    하늘 지우기. pass 필요없으니 지우기.

     

    AnimationDemo.h .cpp

    테스트용으로 만든 ImGui와 이에 연결된 것들 지우기.

     

     


     

     

     

    MeshDemo

     

    ModelDemo.h

    더보기
    #pragma once
    #include "Systems/IExecute.h"
    
    class ModelDemo : 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 Airplane();
    	void Tower();
    	void Tank();
    	void Kachujin();
    
    private:
    	Shader* shader;
    
    	ModelRender* airplane = NULL;
    	ModelRender* tower = NULL;
    	ModelRender* tank = NULL;
    };

     

     

    ModelDemo.cpp

    더보기
    #include "stdafx.h"
    #include "ModelDemo.h"
    #include "Converter.h"
    
    void ModelDemo::Initialize()
    {
    	Context::Get()->GetCamera()->RotationDegree(20, 0, 0);
    	Context::Get()->GetCamera()->Position(1, 36, -85);
    
    
    	shader = new Shader(L"52_InstancingModel.fx");
    
    	Airplane();
    	Tower();
    	Tank();
    
    }
    
    void ModelDemo::Update()
    {
    	if (airplane != NULL) airplane->Update();
    	if (tower != NULL) tower->Update();
    	if (tank != NULL) tank->Update();
    }
    
    void ModelDemo::Render()
    {
    	if (airplane != NULL)
    		airplane->Render();
    
    	if (tower != NULL)
    		tower->Render();
    
    	if (tank != NULL)
    		tank->Render();
    }
    
    void ModelDemo::Airplane()
    {
    	airplane = new ModelRender(shader);
    	airplane->ReadMesh(L"B787/Airplane");
    	airplane->ReadMaterial(L"B787/Airplane");
    
    	for (float x = -50; x <= 50; x += 2.5f)
    	{
    		Transform* transform = airplane->AddTransform();
    
    		transform->Position(Vector3(x, 0.0f, 2.5f));
    		transform->RotationDegree(0, Math::Random(-180.0f, 180.0f), 0);
    		transform->Scale(0.00025f, 0.00025f, 0.00025f);
    	}
    	airplane->UpdateTransforms();
    	airplane->Pass(1);
    }
    
    void ModelDemo::Tower()
    {
    	tower = new ModelRender(shader);
    	tower->ReadMesh(L"Tower/Tower");
    	tower->ReadMaterial(L"Tower/Tower");
    
    	for (float x = -50; x <= 50; x += 2.5f)
    	{
    		Transform* transform = tower->AddTransform();
    
    		transform->Position(Vector3(x, 0.0f, 7.5f));
    		transform->RotationDegree(0, Math::Random(-180.0f, 180.0f), 0);
    		transform->Scale(0.003f, 0.003f, 0.003f);
    	}
    	tower->UpdateTransforms();
    	tower->Pass(1);
    }
    
    void ModelDemo::Tank()
    {
    	tank = new ModelRender(shader);
    	tank->ReadMesh(L"Tank/Tank");
    	tank->ReadMaterial(L"Tank/Tank");
    
    	for (float x = -50; x <= 50; x += 2.5f)
    	{
    		Transform* transform = tank->AddTransform();
    
    		transform->Position(Vector3(x, 0.0f, 5.0f));
    		transform->RotationDegree(0, Math::Random(-180.0f, 180.0f), 0);
    		transform->Scale(0.1f, 0.1f, 0.1f);
    	}
    	tank->UpdateTransforms();
    	tank->Pass(1);
    }

     


     

    CubeSky

     

    MeshSphere를 MeshRender로 수정

     

     


     

     

     

     

     

    Instancing Model

     

    Shader
      00_Global.fx
    00_Render.fx
    51_InstancingMesh
    52_InstancingModel
    Framework
      Environment
      CubeSky.h .cpp
      Meshes
      Mesh.h .cpp
    MeshCube.h. cpp
    MeshCylinder.h .cpp
    MeshGrid.h .cpp
    MeshQuad.h .cpp
    MeshSphere.h .cpp
    MeshRender.h .cpp
      Model
      Model.h .cpp
    ModelMesh.h .cpp

    ModelRender.h .cpp
    ModelEditor
      Demo
      MeshDemo.h .cpp
    ModelDemo.h .cpp 
       
       
      Main.h .cpp

     

     


     

    2차원 배열 

     

    2차원 배열 만들기

    • 250 x 500 x 64 Byte

     

    InstancingModel.fx

     

    52_InstancingModel.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)
    }

     


     

     

    Model 

     

    Model.h

    더보기
    #pragma once
    #define MAX_MODEL_TRANSFORMS 250
    #define MAX_MODEL_KEYFRAMES 500
    #define MAX_MODEL_INSTANCE 500
    
    class ModelBone;
    class ModelMesh;
    class ModelClip;
    
    class Model
    {
    public:
    	typedef VertexTextureNormalTangentBlend ModelVertex;
    
    public:
    	Model();
    	~Model();
    
    	UINT BoneCount() { return bones.size(); }
    	vector<ModelBone *>& Bones() { return bones; }
    	ModelBone* BoneByIndex(UINT index) { return bones[index]; }
    	ModelBone* BoneByName(wstring name);
    
    	UINT MeshCount() { return meshes.size(); }
    	vector<ModelMesh *>& Meshes() { return meshes; }
    	ModelMesh* MeshByIndex(UINT index) { return meshes[index]; }
    	ModelMesh* MeshByName(wstring name);
    
    	UINT MaterialCount() { return materials.size(); }
    	vector<Material *>& Materials() { return materials; }
    	Material* MaterialByIndex(UINT index) { return materials[index]; }
    	Material* MaterialByName(wstring name);
    
    	UINT ClipCount() { return clips.size(); }
    	vector<ModelClip *>& Clips() { return clips; }
    	ModelClip* ClipByIndex(UINT index) { return clips[index]; }
    	ModelClip* ClipByName(wstring name);
    
    public:
    	void ReadMesh(wstring file);
    	void ReadMaterial(wstring file);
    	void ReadClip(wstring file);
    
    private:
    	void BindBone();
    	void BindMesh();
    
    private:
    	ModelBone* root;
    	vector<ModelBone *> bones;
    	vector<ModelMesh *> meshes;
    	vector<Material *> materials;
    	vector<ModelClip *> clips;
    };

     

     

    Model.cpp

    더보기
    #include "Framework.h"
    #include "Model.h"
    #include "Utilities/BinaryFile.h"
    #include "Utilities/Xml.h"
    
    Model::Model()
    {
    }
    
    Model::~Model()
    {
    	for (ModelBone* bone : bones)
    		SafeDelete(bone);
    
    	for (ModelMesh* mesh : meshes)
    		SafeDelete(mesh);
    
    	for (Material* material : materials)
    		SafeDelete(material);
    
    	for (ModelClip* clip : clips)
    		SafeDelete(clip);
    }
    
    ModelBone * Model::BoneByName(wstring name)
    {
    	for (ModelBone* bone : bones)
    	{
    		if (bone->Name() == name)
    			return bone;
    	}
    
    	return NULL;
    }
    
    ModelMesh * Model::MeshByName(wstring name)
    {
    	for (ModelMesh* mesh : meshes)
    	{
    		if (mesh->Name() == name)
    			return mesh;
    	}
    
    	return NULL;
    }
    
    Material * Model::MaterialByName(wstring name)
    {
    	for (Material* material : materials)
    	{
    		if (material->Name() == name)
    			return material;
    	}
    
    	return NULL;
    }
    
    ModelClip * Model::ClipByName(wstring name)
    {
    	for (ModelClip* clip : clips)
    	{
    		if (clip->name == name)
    			return clip;
    	}
    
    	return NULL;
    }
    
    void Model::ReadMesh(wstring file)
    {
    	file = L"../../_Models/" + file + L".mesh";
    
    
    	BinaryReader* r = new BinaryReader();
    	r->Open(file);
    
    	UINT count = 0;
    	count = r->UInt();
    	for (UINT i = 0; i < count; i++)
    	{
    		ModelBone* bone = new ModelBone();
    		bone->index = r->Int();
    		bone->name = String::ToWString(r->String());
    		bone->parentIndex = r->Int();
    		bone->transform = r->Matrix();
    
    		bones.push_back(bone);
    	}
    
    	count = r->UInt();
    	for (UINT i = 0; i < count; i++)
    	{
    		ModelMesh* mesh = new ModelMesh();
    
    		mesh->name = String::ToWString(r->String());
    		mesh->boneIndex = r->Int();
    
    		mesh->materialName = String::ToWString(r->String());
    
    		//VertexData
    		{
    			UINT count = r->UInt();
    
    			vector<Model::ModelVertex> vertices;
    			vertices.assign(count, Model::ModelVertex());
    
    			void* ptr = (void *)&(vertices[0]);
    			r->Byte(&ptr, sizeof(Model::ModelVertex) * count);
    
    
    			mesh->vertices = new Model::ModelVertex[count];
    			mesh->vertexCount = count;
    			copy
    			(
    				vertices.begin(), vertices.end(),
    				stdext::checked_array_iterator<Model::ModelVertex *>(mesh->vertices, count)
    			);
    		}
    
    		//IndexData
    		{
    			UINT count = r->UInt();
    
    			vector<UINT> indices;
    			indices.assign(count, UINT());
    
    			void* ptr = (void *)&(indices[0]);
    			r->Byte(&ptr, sizeof(UINT) * count);
    
    
    			mesh->indices = new UINT[count];
    			mesh->indexCount = count;
    			copy
    			(
    				indices.begin(), indices.end(),
    				stdext::checked_array_iterator<UINT *>(mesh->indices, count)
    			);
    		}
    
    		meshes.push_back(mesh);
    	}
    
    	r->Close();
    	SafeDelete(r);
    
    	BindBone();
    }
    
    void Model::BindBone()
    {
    	root = bones[0];
    
    	for (ModelBone* bone : bones)
    	{
    		if (bone->parentIndex > -1)
    		{
    			bone->parent = bones[bone->parentIndex];
    			bone->parent->childs.push_back(bone);
    		}
    		else
    		{
    			bone->parent = NULL;
    		}
    	}
    }
    
    void Model::BindMesh()
    {
    	for (ModelMesh* mesh : meshes)
    	{
    		mesh->bone = bones[mesh->boneIndex];
    
    		mesh->Binding(this);
    	}
    }
    
    void Model::ReadMaterial(wstring file)
    {
    	file = L"../../_Textures/" + file + L".material";
    
    	Xml::XMLDocument* document = new Xml::XMLDocument();
    	Xml::XMLError error = document->LoadFile(String::ToString(file).c_str());
    	assert(error == Xml::XML_SUCCESS);
    
    	Xml::XMLElement* root = document->FirstChildElement();
    	Xml::XMLElement* materialNode = root->FirstChildElement();
    
    	do
    	{
    		Material* material = new Material();
    
    
    		Xml::XMLElement* node = NULL;
    
    		node = materialNode->FirstChildElement();
    		material->Name(String::ToWString(node->GetText()));
    
    		wstring directory = Path::GetDirectoryName(file);
    		String::Replace(&directory, L"../../_Textures", L"");
    
    
    		wstring texture = L"";
    
    		node = node->NextSiblingElement();
    		texture = String::ToWString(node->GetText());
    		if (texture.length() > 0)
    			material->DiffuseMap(directory + texture);
    
    		node = node->NextSiblingElement();
    		texture = String::ToWString(node->GetText());
    		if (texture.length() > 0)
    			material->SpecularMap(directory + texture);
    
    		node = node->NextSiblingElement();
    		texture = String::ToWString(node->GetText());
    		if (texture.length() > 0)
    			material->NormalMap(directory + texture);
    
    
    		Color color;
    
    		node = node->NextSiblingElement();
    		color.r = node->FloatAttribute("R");
    		color.g = node->FloatAttribute("G");
    		color.b = node->FloatAttribute("B");
    		color.a = node->FloatAttribute("A");
    		material->Ambient(color);
    
    		node = node->NextSiblingElement();
    		color.r = node->FloatAttribute("R");
    		color.g = node->FloatAttribute("G");
    		color.b = node->FloatAttribute("B");
    		color.a = node->FloatAttribute("A");
    		material->Diffuse(color);
    
    		node = node->NextSiblingElement();
    		color.r = node->FloatAttribute("R");
    		color.g = node->FloatAttribute("G");
    		color.b = node->FloatAttribute("B");
    		color.a = node->FloatAttribute("A");
    		material->Specular(color);
    
    		node = node->NextSiblingElement();
    		color.r = node->FloatAttribute("R");
    		color.g = node->FloatAttribute("G");
    		color.b = node->FloatAttribute("B");
    		color.a = node->FloatAttribute("A");
    		material->Emissive(color);
    
    		materials.push_back(material);
    
    		materialNode = materialNode->NextSiblingElement();
    	} while (materialNode != NULL);
    
    	BindMesh();
    }
    
    void Model::ReadClip(wstring file)
    {
    	file = L"../../_Models/" + file + L".clip";
    
    	BinaryReader* r = new BinaryReader();
    	r->Open(file);
    
    
    	ModelClip* clip = new ModelClip();
    
    	clip->name = String::ToWString(r->String());
    	clip->duration = r->Float();
    	clip->frameRate = r->Float();
    	clip->frameCount = r->UInt();
    
    	UINT keyframesCount = r->UInt();
    	for (UINT i = 0; i < keyframesCount; i++)
    	{
    		ModelKeyframe* keyframe = new ModelKeyframe();
    		keyframe->BoneName = String::ToWString(r->String());
    
    
    		UINT size = r->UInt();
    		if (size > 0)
    		{
    			keyframe->Transforms.assign(size, ModelKeyframeData());
    
    			void* ptr = (void *)&keyframe->Transforms[0];
    			r->Byte(&ptr, sizeof(ModelKeyframeData) * size);
    		}
    
    		clip->keyframeMap[keyframe->BoneName] = keyframe;
    	}
    
    	r->Close();
    	SafeDelete(r);
    
    	clips.push_back(clip);
    }

     


     

     

    Model Mesh

     

    ModelMesh.h

    더보기
    #pragma once
    
    class ModelBone
    {
    public:
    	friend class Model;
    
    private:
    	ModelBone();
    	~ModelBone();
    
    public:
    	int Index() { return index; }
    
    	int ParentIndex() { return parentIndex; }
    	ModelBone* Parent() { return parent; }
    
    	wstring Name() { return name; }
    
    	Matrix& Transform() { return transform; }
    	void Transform(Matrix& matrix) { transform = matrix; }
    
    	vector<ModelBone *>& Childs() { return childs; }
    
    private:
    	int index;
    	wstring name;
    
    	int parentIndex;
    	ModelBone* parent;
    
    	Matrix transform;
    	vector<ModelBone *> childs;
    };
    
    ///////////////////////////////////////////////////////////////////////////////
    
    class ModelMesh
    {
    public:
    	friend class Model;
    
    private:
    	ModelMesh();
    	~ModelMesh();
    
    	void Binding(Model* model);
    
    public:
    	void Pass(UINT val) { pass = val; }
    	void SetShader(Shader* shader);
    
    	void Update();
    	void Render();
    	void Render(UINT drawCount);
    
    	wstring Name() { return name; }
    
    	int BoneIndex() { return boneIndex; }
    	class ModelBone* Bone() { return bone; }
    
    	void Transforms(Matrix* transforms);
    	void SetTransform(Transform* transform);
    
    	void TransformsSRV(ID3D11ShaderResourceView* srv) { transformsSRV = srv; }
    
    private:
    	struct BoneDesc
    	{
    		//Matrix Transforms[MAX_MODEL_TRANSFORMS];
    
    		UINT Index;
    		float Padding[3];
    	} boneDesc;
    
    private:
    	wstring name;
    
    	Shader* shader;
    	UINT pass = 0;
    
    	Transform* transform = NULL;
    	PerFrame* perFrame = NULL;
    
    	wstring materialName = L"";
    	Material* material;
    
    	int boneIndex;
    	class ModelBone* bone;
    
    	VertexBuffer* vertexBuffer;
    	UINT vertexCount;
    	Model::ModelVertex* vertices;
    
    	IndexBuffer* indexBuffer;
    	UINT indexCount;
    	UINT* indices;
    
    	ConstantBuffer* boneBuffer;
    	ID3DX11EffectConstantBuffer* sBoneBuffer;
    
    	ID3D11ShaderResourceView* transformsSRV = NULL;
    	ID3DX11EffectShaderResourceVariable* sTransformsSRV;
    };

     

     

    ModelMesh.cpp

    더보기
    #include "Framework.h"
    #include "ModelMesh.h"
    
    ModelBone::ModelBone()
    {
    
    }
    
    ModelBone::~ModelBone()
    {
    
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    ModelMesh::ModelMesh()
    {
    	boneBuffer = new ConstantBuffer(&boneDesc, sizeof(BoneDesc));
    }
    
    ModelMesh::~ModelMesh()
    {
    	SafeDelete(transform);
    	SafeDelete(perFrame);
    
    	SafeDelete(material);
    
    	SafeDeleteArray(vertices);
    	SafeDeleteArray(indices);
    
    	SafeDelete(vertexBuffer);
    	SafeDelete(indexBuffer);
    
    	SafeDelete(boneBuffer);
    }
    
    void ModelMesh::Binding(Model * model)
    {
    	vertexBuffer = new VertexBuffer(vertices, vertexCount, sizeof(Model::ModelVertex));
    	indexBuffer = new IndexBuffer(indices, indexCount);
    
    
    	Material* srcMaterial = model->MaterialByName(materialName);
    
    	material = new Material();
    	material->CopyFrom(srcMaterial);
    }
    
    void ModelMesh::SetShader(Shader * shader)
    {
    	this->shader = shader;
    
    	SafeDelete(transform);
    	transform = new Transform(shader);
    
    	SafeDelete(perFrame);
    	perFrame = new PerFrame(shader);
    
    	sBoneBuffer = shader->AsConstantBuffer("CB_Bone");
    
    	material->SetShader(shader);
    
    	sTransformsSRV = shader->AsSRV("TransformsMap");
    }
    
    void ModelMesh::Update()
    {
    	boneDesc.Index = boneIndex;
    
    	perFrame->Update();
    	transform->Update();
    }
    
    void ModelMesh::Render()
    {
    	boneBuffer->Render();
    	sBoneBuffer->SetConstantBuffer(boneBuffer->Buffer());
    
    	perFrame->Render();
    	transform->Render();
    	material->Render();
    
    	vertexBuffer->Render();
    	indexBuffer->Render();
    
    	if (transformsSRV != NULL)
    		sTransformsSRV->SetResource(transformsSRV);
    
    	D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
    	shader->DrawIndexed(0, pass, indexCount);
    }
    
    void ModelMesh::Render(UINT drawCount)
    {
    	boneBuffer->Render();
    	sBoneBuffer->SetConstantBuffer(boneBuffer->Buffer());
    
    	perFrame->Render();
    	transform->Render();
    	material->Render();
    
    	vertexBuffer->Render();
    	indexBuffer->Render();
    
    	if (transformsSRV != NULL)
    		sTransformsSRV->SetResource(transformsSRV);
    
    	D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
    	shader->DrawIndexedInstanced(0, pass, indexCount, drawCount);
    }
    
    void ModelMesh::Transforms(Matrix * transforms)
    {
    	//memcpy(boneDesc.Transforms, transforms, sizeof(Matrix) * MAX_MODEL_TRANSFORMS);
    }
    
    void ModelMesh::SetTransform(Transform * transform)
    {
    	this->transform->Set(transform);
    }

     


     

    Model Render

     

    ModelRender.h

    더보기
    #pragma once
    
    class ModelRender
    {
    public:
    	ModelRender(Shader* shader);
    	~ModelRender();
    
    	void Update();
    	void Render();
    
    public:
    	void ReadMesh(wstring file);
    	void ReadMaterial(wstring file);
    
    	Model* GetModel() { return model; }
    
    	Transform* AddTransform();
    	Transform* GetTransform(UINT index) { return transforms[index]; }
    	void UpdateTransforms();
    
    	void Pass(UINT pass);
    
    	void UpdateTransform(UINT instanceId, UINT boneIndex, Transform& transform);
    
    private:
    	void CreateTexture();
    
    private:
    	Shader* shader;
    	Model* model;
    
    	vector<Transform *> transforms;
    	Matrix worlds[MAX_MODEL_INSTANCE];
    
    	VertexBuffer* instanceBuffer;
    
    	Matrix boneTransforms[MAX_MODEL_INSTANCE][MAX_MODEL_TRANSFORMS];
    
    	ID3D11Texture2D* texture = NULL;
    	ID3D11ShaderResourceView* srv;
    };

     

     

    ModelRender.cpp

    더보기
    #include "Framework.h"
    #include "ModelRender.h"
    
    ModelRender::ModelRender(Shader * shader)
    	: shader(shader)
    {
    	model = new Model();
    
    	for (UINT i = 0; i < MAX_MODEL_INSTANCE; i++)
    		D3DXMatrixIdentity(&worlds[i]);
    
    	instanceBuffer = new VertexBuffer(worlds, MAX_MODEL_INSTANCE, sizeof(Matrix), 1, true);
    }
    
    ModelRender::~ModelRender()
    {
    	SafeDelete(model);
    
    	for (Transform* transform : transforms)
    		SafeDelete(transform);
    
    	SafeDelete(instanceBuffer);
    
    	SafeRelease(texture);
    	SafeRelease(srv);
    }
    
    void ModelRender::Update()
    {
    	if (texture == NULL)
    	{
    		for (ModelMesh* mesh : model->Meshes())
    			mesh->SetShader(shader);
    
    		CreateTexture();
    	}
    
    	for (ModelMesh* mesh : model->Meshes())
    		mesh->Update();
    }
    
    void ModelRender::Render()
    {
    	instanceBuffer->Render();
    
    	for (ModelMesh* mesh : model->Meshes())
    		mesh->Render(transforms.size());
    }
    
    void ModelRender::ReadMesh(wstring file)
    {
    	model->ReadMesh(file);
    }
    
    void ModelRender::ReadMaterial(wstring file)
    {
    	model->ReadMaterial(file);
    }
    
    void ModelRender::Pass(UINT pass)
    {
    	for (ModelMesh* mesh : model->Meshes())
    		mesh->Pass(pass);
    }
    
    void ModelRender::CreateTexture()
    {
    	D3D11_TEXTURE2D_DESC desc;
    	ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
    	desc.Width = MAX_MODEL_TRANSFORMS * 4;
    	desc.Height = MAX_MODEL_INSTANCE;
    	desc.ArraySize = 1;
    	desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    	desc.Usage = D3D11_USAGE_DYNAMIC;
    	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    	desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    	desc.MipLevels = 1;
    	desc.SampleDesc.Count = 1;
    
    	Matrix bones[MAX_MODEL_TRANSFORMS];
    	for (UINT i = 0; i < MAX_MODEL_INSTANCE; i++)
    	{
    		for (UINT b = 0; b < model->BoneCount(); b++)
    		{
    			ModelBone* bone = model->BoneByIndex(b);
    
    			Matrix parent;
    			int parentIndex = bone->ParentIndex();
    
    			if (parentIndex < 0) //Root인 경우
    				D3DXMatrixIdentity(&parent);//Root의 부모는 Identity
    			else
    				parent = bones[parentIndex];//Root가 아닌 경우
    
    			Matrix matrix = bone->Transform();
    			bones[b] = parent;
    			boneTransforms[i][b] = matrix * bones[b];
    		}//for(b)
    	}//for(i)
    
    	D3D11_SUBRESOURCE_DATA subResource;
    	subResource.pSysMem = boneTransforms;
    	subResource.SysMemPitch = MAX_MODEL_TRANSFORMS * sizeof(Matrix);
    	subResource.SysMemSlicePitch = MAX_MODEL_TRANSFORMS * sizeof(Matrix) * MAX_MODEL_INSTANCE;
    
    	Check(D3D::GetDevice()->CreateTexture2D(&desc, &subResource, &texture));
    
    
    	D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    	ZeroMemory(&srvDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
    	srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
    	srvDesc.Texture2D.MipLevels = 1;
    	srvDesc.Format = desc.Format;
    
    	Check(D3D::GetDevice()->CreateShaderResourceView(texture, &srvDesc, &srv));
    
    
    	for (ModelMesh* mesh : model->Meshes())
    		mesh->TransformsSRV(srv);
    }
    
    Transform * ModelRender::AddTransform()
    {
    	Transform* transform = new Transform();
    	transforms.push_back(transform);
    
    	return transform;
    }
    
    void ModelRender::UpdateTransforms()
    {
    	for (UINT i = 0; i < transforms.size(); i++)
    		memcpy(worlds[i], transforms[i]->World(), sizeof(Matrix));
    
    	D3D11_MAPPED_SUBRESOURCE subResource;
    	D3D::GetDC()->Map(instanceBuffer->Buffer(), 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
    	{
    		memcpy(subResource.pData, worlds, sizeof(Matrix) * MAX_MESH_INSTANCE);
    	}
    	D3D::GetDC()->Unmap(instanceBuffer->Buffer(), 0);
    }
    
    void ModelRender::UpdateTransform(UINT instanceId, UINT boneIndex, Transform& transform)
    {
    	Matrix destMatrix = transform.World();
    
    	ModelBone* bone = model->BoneByIndex(boneIndex);
    	boneTransforms[instanceId][boneIndex] = destMatrix * boneTransforms[instanceId][boneIndex];
    
    	int tempBoneIndex = boneIndex;
    	for (ModelBone* child : bone->Childs())
    	{
    		Matrix parent = boneTransforms[instanceId][boneIndex];
    
    		Matrix invParent;
    		D3DXMatrixInverse(&invParent, NULL, &parent);
    		tempBoneIndex++;
    
    		Matrix temp = boneTransforms[instanceId][tempBoneIndex] * invParent;
    		boneTransforms[instanceId][tempBoneIndex] = temp * destMatrix * parent;
    	}
    
    	D3D11_MAPPED_SUBRESOURCE subResource;
    	D3D::GetDC()->Map(texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
    	{
    		memcpy(subResource.pData, boneTransforms, MAX_MODEL_INSTANCE * MAX_MODEL_TRANSFORMS * sizeof(Matrix));
    	}
    	D3D::GetDC()->Unmap(texture, 0);
    }

     


     

    ModelDemo

     

    ModelDemo.h

    더보기
    #pragma once
    #include "Systems/IExecute.h"
    
    class ModelDemo : 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 Airplane();
    	void Tower();
    	void Tank();
    	void Kachujin();
    
    private:
    	Shader* shader;
    
    	ModelRender* airplane = NULL;
    	ModelRender* tower = NULL;
    	ModelRender* tank = NULL;
    };

     

     

    ModelDemo.cpp

    더보기
    #include "stdafx.h"
    #include "ModelDemo.h"
    #include "Converter.h"
    
    void ModelDemo::Initialize()
    {
    	Context::Get()->GetCamera()->RotationDegree(20, 0, 0);
    	Context::Get()->GetCamera()->Position(1, 36, -85);
    
    
    	shader = new Shader(L"52_InstancingModel.fx");
    
    	Airplane();
    	Tower();
    	Tank();
    
    }
    
    void ModelDemo::Update()
    {
    	if (airplane != NULL) airplane->Update();
    	if (tower != NULL) tower->Update();
    	if (tank != NULL) tank->Update();
    }
    
    void ModelDemo::Render()
    {
    	if (airplane != NULL)
    		airplane->Render();
    
    	if (tower != NULL)
    		tower->Render();
    
    	if (tank != NULL)
    		tank->Render();
    }
    
    void ModelDemo::Airplane()
    {
    	airplane = new ModelRender(shader);
    	airplane->ReadMesh(L"B787/Airplane");
    	airplane->ReadMaterial(L"B787/Airplane");
    
    	for (float x = -50; x <= 50; x += 2.5f)
    	{
    		Transform* transform = airplane->AddTransform();
    
    		transform->Position(Vector3(x, 0.0f, 2.5f));
    		transform->RotationDegree(0, Math::Random(-180.0f, 180.0f), 0);
    		transform->Scale(0.00025f, 0.00025f, 0.00025f);
    	}
    	airplane->UpdateTransforms();
    	airplane->Pass(1);
    }
    
    void ModelDemo::Tower()
    {
    	tower = new ModelRender(shader);
    	tower->ReadMesh(L"Tower/Tower");
    	tower->ReadMaterial(L"Tower/Tower");
    
    	for (float x = -50; x <= 50; x += 2.5f)
    	{
    		Transform* transform = tower->AddTransform();
    
    		transform->Position(Vector3(x, 0.0f, 7.5f));
    		transform->RotationDegree(0, Math::Random(-180.0f, 180.0f), 0);
    		transform->Scale(0.003f, 0.003f, 0.003f);
    	}
    	tower->UpdateTransforms();
    	tower->Pass(1);
    }
    
    void ModelDemo::Tank()
    {
    	tank = new ModelRender(shader);
    	tank->ReadMesh(L"Tank/Tank");
    	tank->ReadMaterial(L"Tank/Tank");
    
    	for (float x = -50; x <= 50; x += 2.5f)
    	{
    		Transform* transform = tank->AddTransform();
    
    		transform->Position(Vector3(x, 0.0f, 5.0f));
    		transform->RotationDegree(0, Math::Random(-180.0f, 180.0f), 0);
    		transform->Scale(0.1f, 0.1f, 0.1f);
    	}
    	tank->UpdateTransforms();
    	tank->Pass(1);
    }

     


     

     

    실행화면

     

     

    '⭐ DirectX > DirectX11 3D' 카테고리의 다른 글

    [DirectX11] 055 Framework  (0) 2023.02.22
    [DirectX11] 053~54 Instancing Animation, Process vs. Thread  (0) 2023.02.21
    [DirectX11] 050 Instancing  (0) 2023.02.18
    [DirectX11] 048 Play Animation  (0) 2023.02.16
    [DirectX11] 045 Model Animator  (0) 2023.02.13