ImGui 활용한 DirectX 11 3D를 이용한 2D를 만드는 내용입니다.
본 내용은 똑같이 사용할 수 없음을 알립니다. (참고및 공부자료로 만들어진내용임을 밝힙니다.)
전 과정에 대해 이해를 해야 다음 이 부분에 대한 이해를 할 수 있음을 밝힙니다
이전 자료) https://ppatabox.tistory.com/39
알파블렌딩 이전 시간에 배웠었음
1) 객체 지향의 4대속성 및 사용
객체지향 4대 속성 : FastCampus Tstory // 여기 링크 확인해서 이번 시간꺼 다뤄보자
이론설명 부분 부터
객체지향에는 4가지 속성이 있다.
1) 캡슐화
: 퍼블릭 프라이벳 같은
Class 블라블라(캡슐화)
{
public:
private:
void happycoding()
}
예를 들어 우리가 캐릭터라는 클래스가 있고
캐릭터의 종류라고 생각해보면
플레이어 : PC
nonplayer :pc
class Character
{
}
그외에도 몬스터 보스 등등등 많이 존재한다
그러면 캐릭터의 모두가 가져야할 특징을 이 클래스 안에 넣어두는 것이다.
그런다음
player 정의 하는데
캐릭터 부터 상속을 받는 것
그러면 위 클래스의 특징이 아래 클래스에 그대로 온다
위에 멤버나 함수들이 그대로 온다
class PC:public character
{
}
예를 들어
class character
{
Vector2 Position;
}
//=====================
class PC:public character
{
} // 아무것도 정의가 안되어있지만 Position을 가지고 있는게 된다.
그래서
PC ob; 이런식으로 객체를 만들면
ob라는 영역이 생기고 주소가 따라 붙을 것이다.
그런다음
플레이어는 입력받은 어떤 Key입력을 받았느냐 해서
이 Key가 ob의 영역에 들어간다.
그런데 부모도 ob안에 들어간다.
원칙대로 접근을 하게되면
ob안에 .캐릭터 안에 포지션
그래서 그냥 ob에 포지션이라고 쓰는데
착각할 수 있는게 ob안에 포지션이 들어가 있는게 아니라
ob안에 character의 부모의 구역에 만들어진 position 이 있는 것이다.
이렇게 공통적인 것을 캐릭터에 모아둔다고 치면
각각의 PC 나 몬스터 등을 정의 하기 편해진다
이게 바로 상속이다.
추상성이 좀 뭔가 말이 어렵다.
책이나 교수님이 가르쳐준것이. 완전히 맞지는 않다.
현시점에서 플레이어 캐릭터 클래스 랑 PC캐릭터 클래스 둘중 뭐를 먼저 정의 해야 할까.?
아까도 말했지만 당연히 PC캐릭터 클래스 먼저 하면 다른 클래스 만들기가 편해지니까
당연히 PC캐릭터 클래스 부터 만들 것이다.
캐릭터를 정의하는데
이러한 함수 (추상화는 함수단위)
Move 라는 어떤 함수를 했다.
예시
class Character
{
void Move();
}
그런데 지금 생각해 보니 몬스터, NPC의 움직임이 다 다를 거 같다.
어떻게 해야 할지 모르겠다.
그럴때 해결방법으로
잘모르겠다 일단 정의 해둔다
class Character
{
virtual void Move() { };
}
class PC:public character
{
//Move는 상속받아서 그대로 있음
} // 그런데 Virtual은 PC입장에서 니 필요에 의해서 다시 재정의 해서 써라
캐릭터에서 정의한move는 함수에 그대로 상속되어있지만
Virtual은
PC입장에서 니 필요에 의해서 다시 재정의 해서 써라
나는 지금 어떻게 써야 할지 모르니까.
(대부분이렇게 쓰지 않을까 하고 잡아놓았으니까 너가 필요한대로 재정의 해서 써라)
다형성의 오버라이징( 재정의 한다)
Virtual 부분이 가상함수라고 불리는데 가상함수를 추가하는게 추상성 이고
virtual void Move() { }; //가상함수
얘를 상속 받아서 다시 재정의 하는게 오버 라이징 (재정의) 이다.
그런데 이럴 경우가 있다.
나는 도저히 감이 안잡힌다.
예를 들어 엔진 프로그래밍 하시는 분들이 클라이언트들이 어떻게 쓸지 감이 안잡힌다.
현재 도형이라는 클래스는 정의 했다고 치자.
가로 세로를 가진다.
넓이를 구해주는 함수를 만들고 싶다.
삼각형 정의하는데 도형으로 부터 상속
사각형 정의하는데 도형으로 부터 상속
이렇게 되면 이 상속받을애 부터 하는게 아니라
위에있는 도형 부터 정의하게 될 것인데.
도형
{
가로, 세로
넓이()
}
도형을 정의하는 입장에서 넓이를 어떻게 구하는지 알 수 있을까?
둘은 다르다
이때가 정확한 추상화의 의미 이긴한데
이 가상함수도 추상이라고 얘기 하니까 추상이라고 얘기 한다.
virtual void Move() { }; //가상함수
이게 사실은 C의 개념에서는 추상성은 아니다.
우리나라에서 그렇게 정의해둠
면접할때 그렇게 다 배워옴 (면접관들도 그리 알고 있음)
그래서 이럴경우 나는 너가 어떻게 쓸지 감이 안잡힌다 하였을때
virtual void Move()=0; //순수가상함수
뒤에 0을 넣는다.
가상함수의 순수하다 라고 몸체가 없다 라고 해서
순수가상함수라고 불린다. 0을 넣으면
정말 중요한 특징
순수 가상함수로 부터 상속받은 클래스는
반드시 여기서 재정의 해줘야 한다.
순수 가상함수를 하나라도 포함하고 있는 클래스를
추상 클래스 라고 불린다.
추상 클래스는 함수의 몸체가 없다.
그래서 함수도 몸체가 있어야 메모리에 할당이 된다.
(함수도 실제로 주소공간을 가진다.=함수포인터 부분)
몸체가 없어서 메모리 할당이 안되고
그냥 도면상에만 존재하고
그래서 추상클래스는 절대로 메모리 할당이 불가하다
상속받은 클래스도 재정의 안하면
순수가상함수 상태일 것이다.
그래서 상속받은 클래스도 추상클래스 이다.
그런데 상속받은 클래스에서 필요에의해 재정의 되었다 하면
몸체가 나오게 되니까. 해당 클래스는 일반 클래스가 된다.
class Character
{
virtual void Move() = 0;
}
class PC:public character
{
void Move()
{
} // 재정의로 일반클래스 됨
}
그렇다면 왜 이렇게 순수가상 함수로 묶어 놔야 할까?
그냥 안써도 되는 것인데?
생각해보자
객체지향이 등장했던 이유는
가장 중요한 것은 유지보수 라고 했다.
예를 들어
플레이어 캐릭터는 이동
적은 'Move'
다른 것은 '절로가'
이렇게 하면 이름이 다 달라져 버린다.
관리가 당연히 안된다.
그래서 이 추상클래스를
상속받을 애들에게서
강제로 넣는 것이다.
그리고 이 현재 순수가상함수를 어떻게 정의 할지 모르니까.
이 이름으로 강제로 써라 라고
강제로 일으킴
추상화 라는 것은 어떻게 상속(파생)받을 클래스에서 쓰일지
현시점에서 결정할 수 없기에
상속받을 클라 쪽에서 편한대로 구현해서 재정의 해서 쓰게끔 할려고
사용함
다형성(다양한 형태를 갖는다) 은 하나더 있는데
오버로딩 이라고 있음
에를들어 이동이 한가지 방법만 있지는 않다.
그럼 Move라는 함수가 나왔다.
파라미터가 다르면 다른애로 간주 한다고 했었는데
그래서 move .x y를 줘서 이동하고
어떤 move는 x, y speed를 줘서 이동하고
이동이니까 이름은 다 통일하는데 뒤에 파라미터만 다른 것
그걸 오버 로딩이라고 한다.
다양한 형태를 갖는다 인데 low함수를 주는 것
(프로그래머 사이에서도 오버라이딩이 추상성에 포함되어야 하는거 아니냐 라는 의문을 갖기도함)
그냥 배울꺼 원어로 통일하는게 좋다.
그냥 회사에서 어떤 프로그래밍을 할때 사전을 통일해 두는게 좋다
클래스명 짓기
함수명 짓기 등이 고민이 많이 될터다.
상속을 이용해서 사용을 해볼것이다.
렉트를 상속받아서 텍스쳐를 만들어 볼 것이다.
다음 시간 내용 링크 :
다음시간 다룰 내용 폴더 정리
상속 : Inheritance
이번시간 다룰 내용에 대한 폴더 설정은 이러하다.
별 중요한 것은 아니지만. 지금 상속에 대한 내용 설명과 추후
과정 진행을 위해서
이렇게 설정을 한다.
Renders 폴더를 새로 만들어 주고.
해당 프로젝트 폴더에 도 똑같이 만들어준다.
Render안에는 LIne. Rect(새로 만들어진것). Text 많이 사용될 아이들을 집어넣어 주었다.
stdafx.h에 경로 설정을 전역으로 자동 추가 시키기 위해서 설정해주자
stdafx.h 에서 순서상 확인을 하길 바란다.
#pragma once
#include <windows.h>
#include <assert.h>
#include <string>
#include <vector>
#include <time.h>
#include <stdlib.h>
using namespace std;
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dX10.h>
#include <d3dx10math.h>
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dx10.lib")
//ImGui
#include <ImGui_New/imgui.h>
#include <ImGui_New/imgui_impl_dx11.h>
#include <ImGui_New/imgui_impl_win32.h>
#pragma comment(lib, "ImGui_New/imgui.lib")
const UINT Width = 1024;
const UINT Height = 768;
extern HWND Hwnd;
extern wstring Title;
extern IDXGISwapChain* SwapChain;
extern ID3D11Device* Device;
extern ID3D11DeviceContext* DeviceContext;
extern ID3D11RenderTargetView* RTV;
extern float BgColor[4]; //Device에서 배경색을 쉽게 바꾸기 위함 ->Device.cpp
struct ImGuiText
{
ImVec2 Position;
ImColor Color;
string Content;
};
extern vector<ImGuiText> Texts;
#define SAFE_RELEASE(p) { if(p != NULL){ p->Release(); p = NULL; } }
#define SAFE_DELETE(p) { if(p != NULL){ delete p; p = NULL; } }
#include "System/Device.h"
#include "System/Keyboard.h" //키보드 여기 있어서 아래
#include "System/Shader.h"
#include "System/Buffer.h"
#include "Renders/Line.h"
#include "Renders/Text.h"
#include "Utilities/Math.h"
extern Keyboard* Key;
디바이스 가서 전시간에 바꿔둔 화면색도 바꿔주자
이렇게 해서 변수선언 하여 좀 쉽게 사용하기 위함 이란 것만 알고 있으면 됨
다음시간 )
각주)
- 상속 부모에 정의 되어있는 함수를 가져다가 쓰겠음 [본문으로]
'🅿🆁🅾🅶🆁🅰🅼🅼🅸🅽🅶 > DɪʀᴇᴄᴛX 2D' 카테고리의 다른 글
[C++]DirectX 벡터와 배열과 범위 Array | Scale (0) | 2021.11.23 |
---|---|
[C++] DirectX 알파 블렌딩 과 렌더타겟 | Alpha blending with Render Target (0) | 2021.11.23 |
[C++] DirectX 원과 회전 Rotation (0) | 2021.11.22 |