ImGui 활용한 DirectX 11 3D를 이용한 2D를 만드는 내용입니다.
본 내용은 똑같이 사용할 수 없음을 알립니다. (참고 및 공부자료로 만들어진 내용임을 밝힙니다.)
전 과정에 대해 이해를 해야 다음 이 부분에 대한 이해를 할 수 있음을 밝힙니다
이전 자료)
다뤄 볼 내용 -검색어로 Ctlr + F =검색기능 사용
1) Screen_Line
2) Multie_Line
3) Define
4) LineClass
1) Screen_Line
선을 뽑은 것이 보인다.
우리가 화면비에서 사각형 안에 어떻게 되는지 전에 다뤄 본적이 있다.
이 출력 내용을
아래 코드 내용으로 한번 확인해보자
사진) 0-01
화면은 0~600이라고 치고
이 비율로 만들어야 하는데
대략 점을 긋고 점과 점의 x좌표
x좌표를 구해야한다.
200지점의 -1 부터 1까지의 어느 비율인지를 구해야 그곳에 선을 그릴 수 있다.
픽셀로 그리면 편하다.
잘 생각해보자 비율만 만들면 된다.
0~1까지의 비율
200 / 600 값의 범위는 -> 0~1 * 2-1 하면됨
-1 부터 1까지 바꿔주면됨
예를 들어
0일때 *2-1 =-1
0.5 일때 * 2-1 = 0
1일때 * 2-1 = 1
형식으로 됨
화면크기를 두고 곱하기 2-1하면됨
아래 코드와 결과인 사진0-01을 참고하자
1) Line.h 수정
2) Line.cpp
3) main.cpp
--- 코드 실행시 아래에 선이 생기는 걸 볼 수 있다.
하지만 왼쪽 위가 될려면
실제로는 아래가 -1 위에가 +1 이다
이런 좌표 공간을 NDC 라고 부른다 "
y 만 뒤집어 주면 된다.
1) Line.h 에서 position전체 를 괄호로 묶어주고 - 를 붙여준다.
----- 실행시 선이 좌상단에 보인다.
name : Line.cpp
#include "stdafx.h"
#include "System/Device.h"
#include "Line.h"
Line::Line(float x, float y, float x2, float y2)
{
x = GetWidth(x); // Line.h에서 x 넣어주면 계산해서 다시 돌려줌 (position에서)
y = GetHeight(y); //잘기억해두셈
x2 = GetWidth(x2);
y2 = GetHeight(y2);//위와 마찬가지 -> main.cpp
Location[0] = { x, y, 1 };
Location[1] = { x2, y2, 1 };
D3D11_INPUT_ELEMENT_DESC layoutDesc[] =
{
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0
};
UINT elementCount = ARRAYSIZE(layoutDesc);
Device->CreateInputLayout(layoutDesc, elementCount, VsBlob->GetBufferPointer(), VsBlob->GetBufferSize(), &InputLayout);
D3D11_BUFFER_DESC desc = { 0 };
desc.Usage = D3D11_USAGE_DEFAULT;
desc.ByteWidth = sizeof(D3DXVECTOR3) * 2;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA data = { 0 };
data.pSysMem = Location;
Device->CreateBuffer(&desc, &data, &VertexBuffer);
}
Line::~Line()
{
VertexBuffer->Release();
InputLayout->Release();
}
void Line::Render()
{
UINT stride = sizeof(D3DXVECTOR3);
UINT offset = 0;
DeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
DeviceContext->IASetInputLayout(InputLayout);
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
DeviceContext->Draw(2, 0);
}
name : Line.h
#pragma once
class Line
{
public:
Line(float x, float y, float x2, float y2);
~Line();
void Render();
private:
float GetWidth(float position) { return position / (float)Width * 2.0f - 1.0f; }
// 받은 포지션에 화면넓이 width앞에 float 자료형 안넣으면 자료형 짤림)
float GetHeight(float position) { return -(position / (float)Height * 2.0f - 1.0f); }
// Line.cpp //하나만 position에 마이너스 주변 뒤집힌다. 전체 계산을 위해 안에괄호로 묶어준다.
private:
D3DXVECTOR3 Location[2];
ID3D11Buffer* VertexBuffer;
ID3D11InputLayout* InputLayout;
};
name : main.cpp
#include "stdafx.h"
#include "System/Device.h"
#include "Text.h"
#include "Line.h"
Line* line = NULL;
void InitScene()
{
line = new Line(200, 100, 400, 100); //화면크기의 비율에 따른 크기 (1024X768)
} // 1) 초반에는 좌하단 아래에 선이 그려져 있다.
void DestroyScene()
{
delete line;
line = NULL;
}
void Update()
{
}
void Render()
{
line->Render();
}
name : Text.cpp
#include "stdafx.h"
#include "System/Device.h"
#include "Text.h"
Text::Text()
{
Location = { 0, 0 };
Color = { 0, 0, 0, 1 };
Content = "Text";
}
Text::Text(float x, float y, BYTE r, BYTE g, BYTE b, string content)
{
Location = { x, y };
Color = { r / 255.0f, g / 255.0f , b / 255.0f, 1.0f };
Content = content;
}
void Text::MoveRight()
{
Location.x += 0.1f;
}
void Text::MoveLeft()
{
Location.x -= 0.1f;
}
void Text::MoveUp()
{
Location.y -= 0.1f;
}
void Text::MoveDown()
{
Location.y += 0.1f;
}
void Text::Render()
{
RenderImGuiText(Location.x, Location.y, (BYTE)Color.r * 255, (BYTE)Color.g * 255, (BYTE)Color.b * 255, Content);
}
name : Text.h
#pragma once
class Text
{
public:
Text();
Text(float x, float y, BYTE r, BYTE g, BYTE b, string content);
public:
void MoveRight();
void MoveLeft();
void MoveUp();
void MoveDown();
public:
void Render();
private:
D3DXVECTOR2 Location;
D3DXCOLOR Color;
string Content;
};
name : stdafx.h
#pragma once
#include <windows.h>
#include <assert.h>
#include <string>
#include <vector>
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")
#include "System/Keyboard.h"
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 ID3D11VertexShader* VertexShader;
extern ID3D11PixelShader* PixelShader;
extern ID3D10Blob* VsBlob;
extern ID3D10Blob* PsBlob;
extern Keyboard* Key;
struct ImGuiText
{
ImVec2 Position;
ImColor Color;
string Content;
};
extern vector<ImGuiText> Texts;
-----------------------===============================================================
2) Multie_Line (선을 여려개)
위 상황과 다르게 Line.cpp/ main.cpp/ Line.h 만 바꿔 주었다
---- 실행 시
-----UI는 ImGui 를 불러들임 기존 실행시 그냥 선 3개만 나옴
Line.cpp에 Draw를 보게 되면
Vertex Count start Vertex Location 이라고 뜬다.
이름에 의미가 있음
Start Vertex Location이란 . 사진에서
0번 찍고 1번으로 쭉 이어짐
2번 찍고 3번으로 이어지고
4번찍고 5번으로 이어짐
위치 하나가 정점이고 이걸 Vertex라고 부른다
Vertex Count의 의미는 (몆개를 그릴 것인가?)
----- 해당 파일을 실행 하게 되면
위에서 5개로 줄이니 아래 선 하나가 사라졌다.
4개로 해도 안보이고 3개로 하면 2번째 선이 사라지고 2개로 해도 안보이고
자 의미는 두개가 쌍으로 연결됨을 알 수 있다. 라인에서는 2개가 쌍임을 알아야한다.
DeviceContext
>IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); //이것으로 인해서 2개가 쌍으로 그려짐
4에서 5가 안나와서 쌍이 아니여서 자체가 안나오게 되는 원리 이다.
그리고
Line.cpp에서
DeviceContext->Draw(DrawCount, 0); 이 뒤에 부분은 갯수가 아니라 번호 이다. (0) 번호 정점의 번호
몆번의 정점의 번호 부터 그려라 라는 의미
ex) Draw(2, 2) 하게 되면 앞에서 2개를 그려라 2번 부터
뒤 숫자 부터 생각하면 됨 몆번 부터 몆개를 그려라 라는 말
StartVertex부분을 삽입해주고 하게되면 2번 부터 두번 그려라 해서 중간이 나오는걸 볼 수 있다.
이처럼 중간이 나오는 걸 볼 수 있다.
하지만 이곳에서 홀수도 나올 수 있다
기존에는 쌍으로 이어져야 했는데
짝수와 홀수가 만나 대각선이 나오는 것을 볼 수 있다.
1~5 번을 지정해 주고 보게 되면 각각의 점에서 대각선이
나오는 걸 볼 수 있다.
1번 부터 시작해서 2번
3번 부터 4번 을 묶는 형식의 대각선이 나옴
TOPOLOGY에서 보면
LINELIST는 2개씩 쌍으로 해서 끊어서 그린다.
이곳에 LINESTRIP이라고 있다.
처음에 하나가 들어오면 첫번째 위치를 하나 찍는다
또하나 들어오면 연결 한다. 이것은 비슷
그다음에 들어오는 2번은 strip의 경우 2번이 1번과 연결 시켜 버린다. (대각선)
즉 1~5번 까지 strip을 이용하면
이렇게 처음부터 다 연결 시켜 버린다.
STRIP은 bool형으로 불러들여 본다. 라인 스트립을 이용하게 되면 저렇게 표현 된다고 보면 된다.
끝에서 잘보면 startvertex 5DrawCount2개 하면 맨끝이 시작
5번이 시작 반대로 봐야함
name : Line.cpp
#include "stdafx.h"
#include "System/Device.h"
#include "Line.h"
Line::Line()
{
Location[0] = {GetWidth(200), GetHeight(200), 1 };
Location[1] = {GetWidth(800), GetHeight(200), 1 };
Location[2] = {GetWidth(200), GetHeight(400), 1 };
Location[3] = {GetWidth(800), GetHeight(400), 1 };
Location[4] = {GetWidth(200), GetHeight(600), 1 };
Location[5] = {GetWidth(800), GetHeight(600), 1 }; //바뀐부분
CreateBuffer(); //바뀐부분
}
void Line::CreateBuffer()
{
D3D11_INPUT_ELEMENT_DESC layoutDesc[] =
{
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0
};
UINT elementCount = ARRAYSIZE(layoutDesc);
Device->CreateInputLayout(layoutDesc, elementCount, VsBlob->GetBufferPointer(), VsBlob->GetBufferSize(), &InputLayout);
D3D11_BUFFER_DESC desc = { 0 };
desc.Usage = D3D11_USAGE_DEFAULT;
desc.ByteWidth = sizeof(D3DXVECTOR3) * 6; //6개로 늘어난 것을 갯수가 6으로 늘었다는 뜻 //바뀐부분
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA data = { 0 };
data.pSysMem = Location;
Device->CreateBuffer(&desc, &data, &VertexBuffer);
}
Line::~Line()
{
VertexBuffer->Release();
InputLayout->Release();
}
void Line::Render()
{
ImGui::Cheakbox("LineStrip", &bLineStrip);
ImGui::SliderInt("DrawCount", &DrawCount, 1, 6); //Line.h연결 됨 1~6개
ImGui::SliderInt("StartVertex", &StartVertex, 0, 5); // 번호이니 0~5까지
UINT stride = sizeof(D3DXVECTOR3);
UINT offset = 0;
DeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
DeviceContext->IASetInputLayout(InputLayout);
/*LineStrip선언*/
if (bLineStrip)
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP); //2개를 쌍으로 해서 라인을 그려라
else
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
DeviceContext->Draw(DrawCount, StartVertex); // 정점의 갯수 //바뀐부분
}
name : Line.h
#pragma once
class Line
{
public:
Line();
~Line();
void Render();
private:
float GetWidth(float position) { return position / (float)Width * 2.0f - 1.0f; }
float GetHeight(float position) { return -(position / (float)Height * 2.0f - 1.0f); }
private:
bool bLineStrip = false; //LINESTRIP
int DrawCount = 6; //imGui사용 DrawCount 몆개를 쓸것이냐?
int StartVertex = 0; //Line.cpp
D3DXVECTOR3 Location[6]; //6개로 //바뀐부분
ID3D11Buffer* VertexBuffer;
ID3D11InputLayout* InputLayout;
};
name : main.cpp
#include "stdafx.h"
#include "System/Device.h"
#include "Text.h"
#include "Line.h"
Line* line = NULL;
void InitScene()
{
line = new Line(); //생성자에서 아무것도 안받음 //바뀐부분
}
void DestroyScene()
{
delete line;
line = NULL;
}
void Update()
{
}
void Render()
{
line->Render();
}
============================================================================
3) Define (언제든지 입력받아서 라인을 움직이고 싶은 실시간으로 키보드로 움직이기도 하고 )
보게 되면
처음에 소스파일 작성할때 (.cpp) -> 빌드 과정에 들어가면
전처리기가 가장 먼저 붙는다 ( 헤더파일과 함께 #이 붙은 것들 #define모두 다 파일 불러 들일꺼 불러들이고)
나머지 번역을 위해서 헤더파일이 필요하니 전처리기가 먼저 헤더파일을 불러들이는 것임
전처리기 과정이 끝나면 컴파일 과정에 들어가는데 이때 바로 실제로 번역이 시작이 된다.
컴파일 과정이 끝나면 Obj라는 파일이 나옴
obj파일에 링커라는게 결합이 된다.
뒤에 가면 (.lib)파일이 나옴 (dx실행하는 )
#stdfx.h를 보면
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dx10.lib")
//얘네들은 #이 붙었지만 전처리기가 아니라 링커가 처리한다.
링커가 obj결과에다가 라이브러리라는 것을 연결하게됨
그렇게 해서 최종적으로 실행 파일(.exe)가 뜬다.
또한 실행하게 되면
한번이라도 컴파일 과정을 했다면 .Debug파일이 생성된다.
obj 파일들은 각 cpp파일을 번역해서 나오게 되고
헤더는 이곳에 합쳐져 있어 obb에 같이 들어감
.exe파일그냥 실행안되고 상단 폴더에 옮기면 그대로 실행된다.
전처리기가 처리하는 데 Define에 써둔 문자가 코드에 그대로 온다고 생각하면됨
아주 재밌는 현상이 생긴다 - (문자그대로 들어옴) ☆중요
#define TEST a+b
{
int a = 10;
int b = 20;
int c = TEST; //전처리기가 TEST가 있네 하면서 컴파일러 실행 전에 define에 써있는 문자를 그대로 가져온다.
}
//즉 아래처럼 바뀐다.
// int c = a + b; //로 바뀐다.
Const int a = 1000; // a라는 공간을 어디에 생기고 const수정할 수 없도록 함수화
b = a + 1;
//혹은
b = 1000 + 1; //문자열 자체로 생성되는 것은 메모리 공간이 안생긴다.
//or
/*전처리기가 A를 인식해서 A에 define에 있는 걸로 대체 됨*/
#define A 1000;
b = A + 1; //A = 1000; //상수랑은 연산방법이 다르다(그냥 문자를 때려박는것)
가끔 쓰다 보면 색이 나오는 것이 나오는데 자홍색 같은 대문자 쓰임 여기서
아래 Line.h에 #define MAX_LINE_COUNT 이렇듯 전부 매크로 함수 이다.
1)main.cpp ex)예제로 가보자 main cpp에도 NULL도 들어가보면 그냥 0으로 되어있다.
Line.h
#pragma once
#define MAX_LINE_COUNT 1000 //매크로 상수 (관례상 대문자를 사용)
//MAX_LINE_COUNT를 이용해 1000을 사용하겠음
class Line
{
public:
Line();
~Line();
void CreateBuffer();
void Render();
private:
float GetWidth(float position) { return position / (float)Width * 2.0f - 1.0f; }
float GetHeight(float position) { return -(position / (float)Height * 2.0f - 1.0f); }
private:
//이곳 안에다 상수를 정의하는 방법이 있고 매크로로 하는 것이 있는데
//int LineCount = 1000; //이러면 변수
//Const int LineCount = 1000; // 이러면 상수
bool bLineStrip = false;
int DrawCount = 6;
int StartVertex = 0;
D3DXVECTOR3 Location[6];
ID3D11Buffer* VertexBuffer;
ID3D11InputLayout* InputLayout;
};
main.cpp ex1)예제1 (매크로에는 함정이 있다)
void InitScene()
{
int a = 10;
int b = 20;
int c = MAX(a,b)//산항연산자가 있음(MAX 매크로) 지금 이곳에서는 실제 실행시
// a > b ? a : b; 로 바뀜
line = new Line();
}
main.cpp ex2) 예제2
void Render()
{
int c = 42; // 이리하면 ImGui창에 10이 뜨는 걸 볼 수 있다.
ImGui::Text("%d", c); // print 문법이랑 똑같음
line->Render();
}
아래에 MUL 매크로를 돌려보자 (함정문제)
아래에 보게 되면 define부분 함수 부분에
#define MUL( x, y ) { x * y }
void Render()
{
int a = 5;
int b = 6;
//int c = MUL(a, b);
int c = MUL(a, b); // 이렇게 하면 출력결과는 5 * 6 = 30 정상적으로 출력되는게 보인다.
ImGui::Text("c = %d", c);
line->Render();
}
#define MUL( x, y ) { x * y }
void Render()
{
int a = 5;
int b = 6;
//int c = MUL(a, b);
int c = MUL(a + 1, b + 1); // 이렇게 하면 어떻게 될까?
ImGui::Text("c = %d", c);
line->Render();
} // -------------출력하면 12가 나온다. 왜일까?
그러나 12가 나온다. 왜일까? ) 이것은
#define MUL(x,y){x * y}
//처음
int c = MUL(5, 6) // MUL 5*6 문자가 그대로 치환되서 x * y = 5 * 6이 된다 x = 5 y = 6
//다음 함정 이걸 바꿔보자
#define MUL(x,y){x * y}
//처음
int c = MUL(5 + 1, 6 + 1) // 문자를 그대로 치환 하는게 함정
// MUL(5 + 1, 6 + 1) 하게 되면 5 + 1 * 6 + 1 이렇게 되어서 더하기를 먼저하는게 아니라.
//수학적 개념으로 생각하면 문자열로 바뀌게 되어 곱하기가 우선순위를 갖게 된다.
// (5 + 1) * (6 + 1) 즉 이렇게가 아니라 5 + (1 * 6) + 1 이렇게 된다.
//그래서 매크로 를 쓸때는 항상
#define MUL(x,y){(x) * (y)}이렇게 묶어 줘야 한다.
//그러면 정상적인 값이 출력된다.
원하는 값이 정상적으로 출력되는 걸 볼 수 있다.
Main.cpp
#include "stdafx.h"
#include "System/Device.h"
#include "Text.h"
#include "Line.h"
#define MUL(x, y) { (x) * (y) } //확인부분
Line* line = NULL;
void InitScene()
{
line = new Line();
}
void DestroyScene()
{
delete line;
line = NULL;
}
void Update()
{
}
void Render()
{
int a = 5;
int b = 6;
//int c = MUL(a, b);
int c = MUL(a + 1, b + 1);
ImGui::Text("c = %d", c); //확인부분
line->Render();
}
==================================================================L4) Line_Class (define을 활용한 선 갯수 늘리기)
Line.h
#pragma once
#define MAX_LINE_COUNT 1000 //활용 선을 한 500개 LineList는 2개씩 묶이는데 1000이니까 500개
class Line
{
public:
Line();
~Line();
void Add(float x, float y, float x2, float y2); // Add 함수 만들기
void CreateBuffer();
void Render();
private:
float GetWidth(float position) { return position / (float)Width * 2.0f - 1.0f; }
float GetHeight(float position) { return -(position / (float)Height * 2.0f - 1.0f); }
private:
UINT DrawCount = 0; // 그릴갯수는 마이너스라는것이 없어 Unsigned int형 DrawCount = 0 -> Location
D3DXVECTOR3 Location[MAX_LINE_COUNT]; //변경됨
ID3D11Buffer* VertexBuffer;
ID3D11InputLayout* InputLayout;
};
.h에 DrawCount 를 이용해서 입력 받은 갯수 만큼만 렌더링 할 것이다.
선을 입력받은 갯수 만큼 잡는 것은 최댓값 드로우 카운터를 이용해서 끊으면 된다.
desc.ByteWidth = sizeof(D3DXVECTOR3) * MAX_LINE_COUNT; //MAX_LINE_COUNT최댓값
Line.cpp
#include "stdafx.h"
#include "System/Device.h"
#include "Line.h"
Line::Line()
{
}
void Line::Add(float x, float y, float x2, float y2) //Line.h 에서 불러들임
{
Location[DrawCount++] = { GetWidth(x), GetHeight(y), 1 }; //Line.h
Location[DrawCount++] = { GetWidth(x2), GetHeight(y2), 1 }; // 뒤에 ++ 는 1넣어놓고 증가시킴
}
void Line::CreateBuffer()
{
D3D11_INPUT_ELEMENT_DESC layoutDesc[] =
{
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0
};
UINT elementCount = ARRAYSIZE(layoutDesc);
Device->CreateInputLayout(layoutDesc, elementCount, VsBlob->GetBufferPointer(), VsBlob->GetBufferSize(), &InputLayout);
D3D11_BUFFER_DESC desc = { 0 };
desc.Usage = D3D11_USAGE_DEFAULT;
desc.ByteWidth = sizeof(D3DXVECTOR3) * MAX_LINE_COUNT; //최댓값
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA data = { 0 };
data.pSysMem = Location;
Device->CreateBuffer(&desc, &data, &VertexBuffer);
}
Line::~Line()
{
VertexBuffer->Release();
InputLayout->Release();
}
void Line::Render()
{
UINT stride = sizeof(D3DXVECTOR3);
UINT offset = 0;
DeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
DeviceContext->IASetInputLayout(InputLayout);
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
//거의 LINELIST를 사용함
DeviceContext->Draw(DrawCount, 0);
}
main.cpp
#include "stdafx.h"
#include "System/Device.h"
#include "Text.h"
#include "Line.h"
Line* line = NULL;
void InitScene()
{
line = new Line();
line->Add(100, 200, 500, 200); // Add하면서 첫번째 정점이 시작 Line.cpp
line->Add(100, 400, 500, 400);
line->Add(100, 600, 500, 600);
line->CreateBuffer(); // CreateBuffer 호출
}
void DestroyScene()
{
delete line;
line = NULL;
}
void Update()
{
//line->Add(100, 600, 500, 600); 여기에다 이러한 값을 넣어봤자 실시간으로 수정이 안된다. 버퍼가 걸려있어서
}
void Render()
{
int c = rand() % 20;
ImGui::Text("c = %d", c);
line->Render();
}
변경후
처음에 Add를 하면서 첫번쨰 정점이 시작으로 만들어주고
드로우 카운트는 1로 증가
1증가 됬으니 Line.cpp / DrawCount++ 는 1이니까
그상태에 2번째 꺼 넣고 1증가 다하면 DrawCount는 6이 된다.
0 ~ 1 2~3 4~5 최종 6 어차피 갯수는 1증가 되있어야함
지금은 미리 만들어둔 선만 쓸 수 있음 Add에 입력값을 해두면 실시간으로 Line을 추가하거나 안된다.
이미Line.cpp에서 들어온 상태에서 버퍼는 고정된다.
Update에 넣어봤자 아무런 의미가 없어진다.
왜 고정이 될까?
우리가 처음 line -> Add를 하고 CreatBuffer을 한다.
CreatBuffer에 데이터를 넣어 받는데 내부적으로 어떻게 하는가
위 Line.cpp 파일안에서
void Line::CreateBuffer()
{
D3D11_SUBRESOURCE_DATA data = { 0 };
data.pSysMem = Location;//&시작주소
Device->CreateBuffer(&desc, &data, &VertexBuffer);
}
//CreateBuffer에 데이터가 들어가 있는데 이안에서 내부적으로
/* SSD -> RAM -> CPU 이렇게 처리를 해주고
ram에서 Vram으로 보내는 부분이 &data이부분이다.
Location Line.h의 시작주소 배열의 이름은 배열의 시작주소
이애를 Vram쪽으로 복사해주는데
desc.ByteWidth = sizeof(D3DXVECTOR3) * MAX_LINE_COUNT;이만큼의 길이 용량을 해준다.
그러면 MAX_LINE_COUNT가 1000개 니까. Location1000개의 사이즈
D3DXVECTOR3 = 12byte니까 12000byte가 GPU로 복사가 될 것이다.
RAM -> 12000byte ->복사하고나면 VRAM/GPU는 렌더링 하는데 데이터가 묶여버린다.
다시 RAM에서 보내주는 코드가 없어서 그냥
CreateBuffer가 RAM->에서 넘겨주고 더이상 넘어갈 수 없다.
RAM에서 VRAM으로 데이터를 복사 할수 있도록 해야한다. (실시간으로)
한가지만 더 봐보자
stdafx.h
#pragma once
#include <windows.h>
#include <assert.h>
#include <string>
#include <vector>
#include <time.h> //
#include <stdlib.h> // 스탠다드 라이브러리 렌더만 사용할려고 타임의 하나가 Seed로 들어가는것
//렌덤은 시작할때 초기화를 한번 해야함 system /Device.cpp
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")
#include "System/Keyboard.h"
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 ID3D11VertexShader* VertexShader;
extern ID3D11PixelShader* PixelShader;
extern ID3D10Blob* VsBlob;
extern ID3D10Blob* PsBlob;
extern Keyboard* Key;
struct ImGuiText
{
ImVec2 Position;
ImColor Color;
string Content;
};
extern vector<ImGuiText> Texts;
렌덤은 시작할때 초기화를 한번 해야함 system /Device.cpp
DX가 시작하는 기점이 void InitDirect3D
WPARAM Running() - Init ImGui등등 을 call 한다.
srand((UINT)time(NULL)); //넣어주었다. Running안에
main.cpp
void Render()
{
int c = rand() % 20;
ImGui::Text("c = %d", c);
line->Render();
}
20안에서 계속 렌더가 메프레임마다 호출하고 있다. 범위가 최대 20 /Alt키 누르면 멈추고 다시 누르면 다시 돌아간다.
정확히 0~19 까지 나오니까 +1 을 해주면 된다.
다음시간에 무작위 호출에 대해 다뤄보자 2021-11-09
다음시간 )
'🅿🆁🅾🅶🆁🅰🅼🅼🅸🅽🅶 > DɪʀᴇᴄᴛX 2D' 카테고리의 다른 글
[C++] DirectX 실시간 처리를 위한 Dynamic과 범위 지정 (1) | 2021.11.10 |
---|---|
[C++] DirectX Graphics part/ 2차 포인터 / 동적할당 (0) | 2021.11.08 |
[C++] DirectX Struct와 Class and Constructor 구조체 와 클래스 그리고 생성자 (0) | 2021.11.05 |