728x90
시작하기 앞서 Framework 안에 Meshes 폴더 만들어서 해당 파일들을 만드는데 중요한건 Mesh.cpp가 다른 클래스들의 부모클래스 되서 사용 된다는 점
Mesh.cpp, h (중요)
더보기
#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();
CreateBuffer();
}
UINT stride = sizeof(VertexMesh);
UINT offset = 0;
D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D::GetDC()->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
D3D::GetDC()->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
sWorld->SetMatrix(world);
sView->SetMatrix(Context::Get()->View());
sProjection->SetMatrix(Context::Get()->Projection());
if (diffuseMap != NULL)
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()
{
return Vector3(world._31, world._32, world._33);
}
Vector3 Mesh::Up()
{
return Vector3(world._21, world._22, world._23);
}
Vector3 Mesh::Right()
{
return Vector3(world._11, world._12, world._13);
}
void Mesh::DiffuseMap(wstring file)
{
SafeDelete(diffuseMap);
diffuseMap = new Texture(file);
}
void Mesh::CreateBuffer()
{
//Create VertexBuffer
{
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = sizeof(VertexMesh) * vertexCount;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA data = { 0 };
data.pSysMem = vertices;
Check(D3D::GetDevice()->CreateBuffer(&desc, &data, &vertexBuffer));
}
//Create IndexBuffer
{
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;
}
#pragma once
class Mesh
{
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;
private:
void CreateBuffer();
void UpdateWorld();
protected:
struct VertexMesh
{
Vector3 Position;
Vector2 Uv;
Vector3 Normal;
VertexMesh()
{
Position = Vector3(0, 0, 0);
Uv = Vector2(0, 0);
Normal = Vector3(0, 0, 0);
}
VertexMesh(float x, float y, float z, float u, float v, float nx, float ny, float nz)
{
Position = Vector3(x, y, z);
Uv = Vector2(u, v);
Normal = Vector3(nx, ny, nz);
}
};
protected:
VertexMesh* 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;
};
MeshQuad.cpp, 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<VertexMesh> v;
v.push_back(VertexMesh(-w, -h, 0, 0, 1, 0, 0, -1));
v.push_back(VertexMesh(-w, +h, 0, 0, 0, 0, 0, -1));
v.push_back(VertexMesh(+w, -h, 0, 1, 1, 0, 0, -1));
v.push_back(VertexMesh(+w, +h, 0, 1, 0, 0, 0, -1));
vertices = new VertexMesh[v.size()];
vertexCount = v.size();
//벡터 -> 배열로 복사
copy(v.begin(), v.end(), stdext::checked_array_iterator<VertexMesh*>(vertices, vertexCount));
indexCount = 6;
indices = new UINT[indexCount]{ 0, 1, 2, 2, 1, 3 };
}
#pragma once
class MeshQuad : public Mesh
{
public:
MeshQuad(Shader* shader);
~MeshQuad();
private:
void Create() override;
};
MeshPlane.cpp, h
더보기
#include "Framework.h"
#include "MeshPlane.h"
MeshPlane::MeshPlane(Shader * shader, float offsetU, float offsetV)
:Mesh(shader), offsetU(offsetU) , offsetV(offsetV)
{
}
MeshPlane::~MeshPlane()
{
}
void MeshPlane::Create()
{
UINT countX = 11;
UINT countZ = 11;
float w = (countX - 1) * 0.5f;
float h = (countZ - 1) * 0.5f;
vector<VertexMesh>v;
for (UINT z = 0; z < countZ; z++)
{
for (UINT x = 0; x < countX; x++)
{
VertexMesh vertex;
vertex.Position = Vector3((float)x - w, 0.0f, (float)z - h);
vertex.Normal = Vector3(0,1,0);
vertex.Uv.x = (float)x / (float)(countX - 1) * offsetU;
vertex.Uv.y = (float)z / (float)(countZ - 1) * offsetV;
v.push_back(vertex);
}
}
vertices = new VertexMesh[v.size()];
vertexCount = v.size();
copy(v.begin(), v.end(), stdext::checked_array_iterator<VertexMesh*>(vertices, vertexCount));
vector<UINT> i;
for (UINT z = 0; z < countZ - 1; z++)
{
for (UINT x = 0; x < countX - 1; x++)
{
i.push_back(countX * z + x);
i.push_back(countX * (z + 1) + x);
i.push_back(countX * z + (x + 1));
i.push_back(countX * z + (x + 1));
i.push_back(countX * (z + 1) + x);
i.push_back(countX * (z + 1) + (x + 1));
}
}
indices = new UINT[i.size()];
indexCount =i.size();
copy(i.begin(), i.end(), stdext::checked_array_iterator<UINT*>(indices, indexCount));
}
#pragma once
class MeshPlane : public Mesh
{
public:
MeshPlane(Shader* shader, float offsetU = 1.0f, float offsetV = 1.0f);
~MeshPlane();
private:
void Create() override;
float offsetU, offsetV; //그림 크기
};
MeshCylinder, MeshSphere 는 추후 코드 이해하면 올릴생각
실행
MeshCube만 uv 관련으로 아래와 같이 정점 순서를 오른쪽껄로 바꿧지만 uv만 맞추면 왼쪽꺼 써도 상관 없음
MeshPlane에 있는 offsetU, offsetV 같은 경우는 기존 그림의 크기는 0 ~ 1 이지만 여기서 벗어나면 SamplerState에서 자동적으로 Warp (기본복사) 되므로 크기가 클수록 같은 그림이 여러개 그려짐
'DirectX > DirectX 3D_(구)' 카테고리의 다른 글
17_Framework (Buffer + hlsl) (0) | 2021.07.07 |
---|---|
16_CubeMap [ 1 / 2 ] (수정) (0) | 2021.07.06 |
13_BaseMap (0) | 2021.07.04 |
12_Normal [1/2] (0) | 2021.07.03 |
11_Terrain (0) | 2021.07.02 |