목차

     

     


     

     

    Mesh

     

    짐벌락 현상

    •  x축과 z축이 겹쳐서 돌다가 정상적으로 Rendering되지 않고 사라져버린다.

     

    짐벌락 해결방법 2가지

    • 3DXMatrixRotationYawPitchRoll
    • 사원수

     


    참고사항

     

    copy(v.begin(), v.end(), stdext::checked_array_iterator <MeshVertex *>(vertices, vertexCount));

    벡터의 시작주소, 끝주소,  복사받을 배열의 <자료형> 시작주소, 갯수

     

     


     

    Mesh.fx

     

    Mesh.fx

    더보기
    matrix World;
    matrix View;
    matrix Projection;
    float4 Index;
    Texture2D DiffuseMap;
    float3 Direction;
    
    struct VertexInput
    {
        float4 Position : Position;
        float2 Uv : Uv;
        float3 Normal : Normal;
    };
    
    struct VertexOutput
    {
        float4 Position : SV_Position;
        float2 Uv : Uv;
        float3 Normal : Normal;
    };
    
    VertexOutput VS(VertexInput input)
    {
        VertexOutput output;
        output.Position = mul(input.Position, World);
        output.Position = mul(output.Position, View);
        output.Position = mul(output.Position, Projection);
        
        output.Normal = mul(input.Normal, (float3x3) World);
    
        output.Uv = input.Uv;
    
        return output;
    }
    
    SamplerState LinearSampler
    {
        Filter = MIN_MAG_MIP_LINEAR;
        AddressU = Wrap;
        AddressV = Wrap;
    };
    
    float4 PS(VertexOutput input) : SV_Target
    {
        float3 normal = normalize(input.Normal);
        float3 light = -Direction;
    
        return DiffuseMap.Sample(LinearSampler, input.Uv) * dot(light, normal);
    }
    
    RasterizerState FillMode_Wireframe
    {
        FillMode = Wireframe;
    };
    
    technique11 T0
    {
        pass P0
        {
            SetVertexShader(CompileShader(vs_5_0, VS()));
            SetPixelShader(CompileShader(ps_5_0, PS()));
        }
    
        pass P1
        {
            SetRasterizerState(FillMode_Wireframe);
    
            SetVertexShader(CompileShader(vs_5_0, VS()));
            SetPixelShader(CompileShader(ps_5_0, PS()));
        }
    }

     


     

    Mesh

     

    Mesh.h

    더보기
    #pragma once
    
    class Mesh
    {
    public:
    	typedef VertexTextureNormal MeshVertex;
    
    public:
    	Mesh(Shader* shader);
    	virtual ~Mesh();
    
    	void Update();
    	void Render();
    
    public:
    	void Pass(UINT val) { pass = val; }
    
    	void Position(float x, float y, float z);
    	void Position(Vector3& vec);
    	void Position(Vector3* vec);
    
    	void Rotation(float x, float y, float z);
    	void Rotation(Vector3& vec);
    	void Rotation(Vector3* vec);
    
    	void RotationDegree(float x, float y, float z);
    	void RotationDegree(Vector3& vec);
    	void RotationDegree(Vector3* vec);
    
    	void Scale(float x, float y, float z);
    	void Scale(Vector3& vec);
    	void Scale(Vector3* vec);
    
    	Matrix World() { return world; }
    
    	Vector3 Forward();
    	Vector3 Up();
    	Vector3 Right();
    
    	void DiffuseMap(wstring file);
    
    protected:
    	virtual void Create() = 0; //자식에서 재정의하면서 자식의 정점들이 들어갈 예정.
    	void CreateBuffer();
    
    private:
    	void UpdateWorld();
    
    protected:
    	MeshVertex* vertices = NULL;
    	UINT* indices = NULL;
    
    	UINT vertexCount;
    	UINT indexCount;
    
    private:
    	Shader* shader;
    	UINT pass = 0;
    
    	Vector3 position = Vector3(0, 0, 0);
    	Vector3 scale = Vector3(1, 1, 1);
    	Vector3 rotation = Vector3(0, 0, 0);
    
    	Matrix world;
    
    	ID3D11Buffer* vertexBuffer = NULL;
    	ID3D11Buffer* indexBuffer = NULL;
    
    	ID3DX11EffectMatrixVariable* sWorld, *sView, *sProjection;
    
    	Texture* diffuseMap = NULL;
    	ID3DX11EffectShaderResourceVariable* sDiffuseMap;
    };

     

     

    Mesh.cpp

    더보기
    #include "Framework.h"
    #include "Mesh.h"
    
    Mesh::Mesh(Shader * shader)
    	: shader(shader)
    {
    	D3DXMatrixIdentity(&world);
    
    	sWorld = shader->AsMatrix("World");
    	sView = shader->AsMatrix("View");
    	sProjection = shader->AsMatrix("Projection");
    
    	sDiffuseMap = shader->AsSRV("DiffuseMap");
    }
    
    Mesh::~Mesh()
    {
    	SafeDeleteArray(vertices);
    	SafeDeleteArray(indices);
    
    	SafeRelease(vertexBuffer);
    	SafeRelease(indexBuffer);
    
    	SafeDelete(diffuseMap);
    }
    
    void Mesh::Update()
    {
    }
    
    void Mesh::Render()
    {
    	if (vertexBuffer == NULL && indexBuffer == NULL)
    	{
    		Create(); //Create()함수를 자식이 재정의하면 재정의된 Create()이 호출된다.
    		CreateBuffer(); 
    	}
    
    	UINT stride = sizeof(MeshVertex);
    	UINT offset = 0;
    
    	D3D::GetDC()->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
    	D3D::GetDC()->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
    	D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
    	sWorld->SetMatrix(world);
    	sView->SetMatrix(Context::Get()->View());
    	sProjection->SetMatrix(Context::Get()->Projection());
    
    	sDiffuseMap->SetResource(diffuseMap->SRV());
    
    	shader->DrawIndexed(0, pass, indexCount);
    }
    
    
    void Mesh::Position(float x, float y, float z)
    {
    	Position(Vector3(x, y, z));
    }
    
    void Mesh::Position(Vector3 & vec)
    {
    	position = vec;
    
    	UpdateWorld();
    }
    
    void Mesh::Position(Vector3 * vec)
    {
    	*vec = position;
    }
    
    void Mesh::Rotation(float x, float y, float z)
    {
    	Rotation(Vector3(x, y, z));
    }
    
    void Mesh::Rotation(Vector3 & vec)
    {
    	rotation = vec;
    
    	UpdateWorld();
    }
    
    void Mesh::Rotation(Vector3 * vec)
    {
    	*vec = rotation;
    }
    
    void Mesh::RotationDegree(float x, float y, float z)
    {
    	RotationDegree(Vector3(x, y, z));
    }
    
    void Mesh::RotationDegree(Vector3 & vec)
    {
    	rotation = vec * Math::PI / 180.0f;
    
    	UpdateWorld();
    }
    
    void Mesh::RotationDegree(Vector3 * vec)
    {
    	*vec = rotation * 180.0f / Math::PI;
    }
    
    void Mesh::Scale(float x, float y, float z)
    {
    	Scale(Vector3(x, y, z));
    }
    
    void Mesh::Scale(Vector3 & vec)
    {
    	scale = vec;
    
    	UpdateWorld();
    }
    
    void Mesh::Scale(Vector3 * vec)
    {
    	*vec = scale;
    }
    
    Vector3 Mesh::Forward()
    {   //z방향
    	return Vector3(world._31, world._32, world._33);
    }
    
    Vector3 Mesh::Up()
    {   //y방향
    	return Vector3(world._21, world._22, world._23);
    }
    
    Vector3 Mesh::Right()
    {   //x방향
    	return Vector3(world._11, world._12, world._13);
    }
    
    void Mesh::DiffuseMap(wstring file)
    {
    	SafeDelete(diffuseMap);
    
    	diffuseMap = new Texture(file);
    }
    
    void Mesh::CreateBuffer()
    {
    	//Create Vertex Buffer
    	{
    		D3D11_BUFFER_DESC desc;
    		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
    		desc.ByteWidth = sizeof(MeshVertex) * vertexCount;
    		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    
    		D3D11_SUBRESOURCE_DATA data = { 0 };
    		data.pSysMem = vertices;
    
    		Check(D3D::GetDevice()->CreateBuffer(&desc, &data, &vertexBuffer));
    	}
    
    	//Create Index Buffer
    	{
    		D3D11_BUFFER_DESC desc;
    		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
    		desc.ByteWidth = sizeof(UINT) * indexCount;
    		desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    
    		D3D11_SUBRESOURCE_DATA data = { 0 };
    		data.pSysMem = indices;
    
    		Check(D3D::GetDevice()->CreateBuffer(&desc, &data, &indexBuffer));
    	}
    }
    
    void Mesh::UpdateWorld()
    {
    	Matrix S, R, T;
    	D3DXMatrixScaling(&S, scale.x, scale.y, scale.z);
    	D3DXMatrixRotationYawPitchRoll(&R, rotation.y, rotation.x, rotation.z);
    	D3DXMatrixTranslation(&T, position.x, position.y, position.z);
    
    	world = S * R * T;
    }

     

     

     


     

    MeshQuad

     

    MeshQuad.h

    더보기
    #pragma once
    
    class MeshQuad : public Mesh
    {
    public:
    	MeshQuad(Shader* shader);
    	~MeshQuad();
    
    private:
    	void Create() override; //Mesh.h에 있는 Create() 재정의
    };

     

     

    MeshQuad.h

    더보기
    #include "Framework.h"
    #include "MeshQuad.h"
    
    MeshQuad::MeshQuad(Shader* shader)
    	: Mesh(shader)
    {
    }
    
    MeshQuad::~MeshQuad()
    {
    }
    
    void MeshQuad::Create()
    {
    	float w = 0.5f;
    	float h = 0.5f;
    
    	vector<MeshVertex> v;
    	v.push_back(MeshVertex(-w, -h, 0, 0, 1, 0, 0, -1));
    	v.push_back(MeshVertex(-w, +h, 0, 0, 0, 0, 0, -1));
    	v.push_back(MeshVertex(+w, -h, 0, 1, 1, 0, 0, -1));
    	v.push_back(MeshVertex(+w, +h, 0, 1, 0, 0, 0, -1));
    
    	vertices = new MeshVertex[v.size()];
    	vertexCount = v.size();
    
    	copy(v.begin(), v.end(), stdext::checked_array_iterator <MeshVertex *>(vertices, vertexCount));
    
    	indexCount = 6;
    	indices = new UINT[indexCount]{ 0, 1, 2, 2, 1, 3 };
    }

     


     

    MeshDemo

     

    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:
    	Shader* shader;
    	
    	Vector3 direction = Vector3(-1, -1, 1);
    	ID3DX11EffectVectorVariable* sDirection;
    
    	MeshQuad* quad;
    };

     

     

    MeshDemo.cpp

    더보기
    #include "stdafx.h"
    #include "MeshDemo.h"
    
    void MeshDemo::Initialize()
    {
    	Context::Get()->GetCamera()->RotationDegree(0, 0, 0);
    	Context::Get()->GetCamera()->Position(0, 0, -10);
    
    
    	shader = new Shader(L"25_Mesh.fx");
    	sDirection = shader->AsVector("Direction");
    	
    	quad = new MeshQuad(shader);
    	quad->Scale(2, 2, 2);
    	quad->DiffuseMap(L"Box.png");
    }
    
    void MeshDemo::Destroy()
    {
    	SafeDelete(shader);
    	SafeDelete(quad);
    }
    
    void MeshDemo::Update()
    {
    	Vector3 scale;
    	quad->Scale(&scale);
    
    	ImGui::SliderFloat2("Scale", scale, -3, 3);
    	quad->Scale(scale);
    
    	quad->Update();
    }
    
    void MeshDemo::Render()
    {
    	sDirection->SetFloatVector(direction);
    
    	quad->Render();
    }

     


     

    실행화면