create window, added directx rendering, assets folder: shader, load files, include math, log and string header

git-svn-id: svn://ammerhai.com/home/mike/pokemon_repo@2 24008968-59e6-ed4c-a10b-0b2c954b24ab
This commit is contained in:
mikeb 2021-02-23 18:18:32 +00:00
parent 1bed76ca70
commit c9a741df87
18 changed files with 1527 additions and 3 deletions

View File

@ -0,0 +1,18 @@
struct PixelShaderInput {
float4 pos : SV_POSITION;
float4 color : COLOR;
};
struct PixelShaderOutput {
float4 color : SV_TARGET;
};
PixelShaderOutput main(PixelShaderInput input) {
PixelShaderOutput output;
#if 1
output.color = input.color;
#else
output.color = float4(1, 0, 1, 1);
#endif
return output;
}

View File

@ -0,0 +1,53 @@
struct VertexShaderInput {
// Per Vertex
float4 pos : VERTEX_POSITION;
uint vid : SV_VertexID;
// Per Instance
float4 pos_size : INSTANCE_POSITION_SIZE;
float4 left_color : LEFT_COLOR;
};
struct VertexShaderOutput {
float4 pos : SV_POSITION;
float4 color : COLOR;
};
VertexShaderOutput main(VertexShaderInput input) {
VertexShaderOutput output;
float2 rect_pos = input.pos_size.xy;
float2 rect_size = input.pos_size.zw;
float3x3 coord_sys = {
2, 0, -1,
0, -2, 1,
0, 0, 1
};
input.pos_size.xy = mul(coord_sys, float3(input.pos_size.xy, 1)).xy;
float3x3 pos = {
1, 0, input.pos_size.x,
0, 1, input.pos_size.y,
0, 0, 1
};
float3x3 size = {
rect_size.x, 0, 0,
0, rect_size.y, 0,
0, 0, 1
};
output.pos.xy = mul(pos, mul(size, input.pos.xyz)).xy;
//output.pos.xy = mul(pos, input.pos.xyz).xy;
output.pos.zw = float2(0, 1);
output.color = input.left_color;
return output;
}

Binary file not shown.

Binary file not shown.

View File

@ -70,8 +70,8 @@
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)bin</OutDir>
<IntDir>$(SolutionDir)vs_trash</IntDir>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>$(SolutionDir)vs_trash\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)bin</OutDir>
@ -106,9 +106,26 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalOptions>-Wno-missing-braces -Wno-parentheses -Wno-reorder-init-list -Wno-unused-variable -Wno-format %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\create_window.cpp" />
<ClCompile Include="src\load_entire_file.cpp" />
<ClCompile Include="src\load_tga_file.cpp" />
<ClCompile Include="src\log.cpp" />
<ClCompile Include="src\main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\create_window.h" />
<ClInclude Include="src\load_entire_file.h" />
<ClInclude Include="src\load_tga_file.h" />
<ClInclude Include="src\log.h" />
<ClInclude Include="src\math_graphics.h" />
<ClInclude Include="src\m_string.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -18,5 +18,37 @@
<ClCompile Include="src\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\create_window.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\log.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\load_tga_file.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\load_entire_file.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\create_window.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\log.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\m_string.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\math_graphics.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\load_entire_file.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\load_tga_file.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -3,4 +3,8 @@
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(ProjectDir)bin</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

25
src/create_window.cpp Normal file
View File

@ -0,0 +1,25 @@
#include "create_window.h"
//create Window
void* create_window(LRESULT (*WindowProc)(HWND, UINT, WPARAM, LPARAM)) {
WNDCLASSEXA window_class_struct = {};
window_class_struct.cbSize = sizeof(WNDCLASSEXW);
window_class_struct.style = CS_CLASSDC | CS_HREDRAW | CS_VREDRAW;
window_class_struct.lpfnWndProc = WindowProc;
window_class_struct.cbClsExtra = 0;
window_class_struct.cbWndExtra = 0;
window_class_struct.hInstance = GetModuleHandle(NULL);
window_class_struct.hIcon = 0;
window_class_struct.hCursor = LoadCursor(NULL, IDC_ARROW);
window_class_struct.hbrBackground = 0;
window_class_struct.lpszMenuName = 0;
window_class_struct.lpszClassName = "DX_WINDOW_CLASS";
window_class_struct.hIconSm = 0;
ATOM window_class = RegisterClassExA(&window_class_struct);
if (!window_class)
return 0;
return CreateWindowExA(0, "DX_WINDOW_CLASS", "Pokemon", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(NULL), 0);
}

3
src/create_window.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
#include <Windows.h>
void* create_window(LRESULT(*WindowProc)(HWND, UINT, WPARAM, LPARAM));

32
src/load_entire_file.cpp Normal file
View File

@ -0,0 +1,32 @@
#define _CRT_SECURE_NO_WARNINGS
#include "load_entire_file.h"
#include <stdio.h>
#include <stdlib.h>
String load_entire_file(const char* filename) {
auto file = fopen(filename, "rb");
if (!file)
return {};
if (fseek(file, 0, SEEK_END))
return {};
auto file_length = ftell(file);
if (file_length == -1)
return {};
if (fseek(file, 0, SEEK_SET))
return {};
auto file_mem = malloc(file_length);
if (!file_mem)
return {};
if (fread(file_mem, file_length, 1, file) != 1) {
free(file_mem);
return {};
}
return { (size_t)file_length, (char*)file_mem };
}

4
src/load_entire_file.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
#include "m_string.h"
String load_entire_file(const char* filename);

153
src/load_tga_file.cpp Normal file
View File

@ -0,0 +1,153 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "load_tga_file.h"
#include "m_string.h"
#include "log.h"
#include "load_entire_file.h"
#define print_value(v) _Generic((v), \
int8_t: printf("%hhd", v), \
int16_t: printf("%hd", v), \
int32_t: printf("%d", v), \
int64_t: printf("%lld", v), \
long: printf("%lld", v), \
\
uint8_t: printf("%hhu", v), \
uint16_t: printf("%hu", v), \
uint32_t: printf("%u", v), \
uint64_t: printf("%llu", v), \
unsigned long: printf("%llu", v) \
)
bool _expect_read(String& file, String expected_value, const char* path, const char* error_msg) {
if (file.length < expected_value.length)
return false;
if (!(String{ expected_value.length, file.data } == expected_value)) {
log_error("'%s' %s expected '%.*s' got '%.*s'\n", path, error_msg, expected_value.length, expected_value.data, expected_value.length, file.data);
return false;
}
advance(file, expected_value.length);
return true;
}
template<typename T>
bool _expect_read(String& file, T expected_value, const char* path, const char* error_msg) {
if (file.length < sizeof(T))
return false;
if (*(T*)file.data != expected_value) {
printf("'%s' %s expected '", path, error_msg);
print_value(expected_value);
printf("' got '");
print_value(*(T*)file.data);
printf("'\n");
return false;
}
advance(file, sizeof(T));
return true;
}
template<typename T, typename S>
bool _expect(T value, S expected_value, const char* path, const char* error_msg) {
if (value != expected_value) {
printf("'%s' %s expected '", path, error_msg);
print_value(expected_value);
printf("' got '");
print_value(value);
printf("'\n");
return false;
}
return true;
}
#define expect_read(expected_value, error_msg) if(!_expect_read(file, expected_value, path, error_msg)) return{0, 0};
#define expect(value, expected_value, error_msg) if(!_expect(value, expected_value, path, error_msg)) return{0, 0};
#pragma pack(1)
struct TGA_Color_Map_Info {
uint16_t index;
uint16_t length;
uint8_t size;
};
#pragma pack(1)
struct TGA_Image_Specification {
uint16_t x_origin;
uint16_t y_origin;
uint16_t width;
uint16_t height;
uint8_t bits_per_pixel;
uint8_t image_descriptor;
};
BMP_Texture load_tga_file(const char* path) {
auto file = load_entire_file(path);
auto start_file = file;
if (!file.length) {
log_error("'%s' failed to load", path);
return{ 0, 0, 0 };
}
auto id_length = read<uint8_t>(file);
auto color_map_type = read<uint8_t>(file);
expect(color_map_type, 0, "wrong color map type");
auto image_type = read<uint8_t>(file);
expect(image_type, 10, "wrong image type");
auto color_map_info = read<TGA_Color_Map_Info >(file);
expect(color_map_info.size, 0, "no existing color map");
auto image_specification = read<TGA_Image_Specification>(file);
expect(image_specification.bits_per_pixel, 32, "not 32 bitsperpixel");
auto descriptor_mask = 0x30;
auto image_origin = image_specification.image_descriptor & descriptor_mask;
expect(image_origin, 32, "wrong image origin");
advance(file, id_length);
uint32_t* start_pixel = (uint32_t*)malloc(image_specification.width * image_specification.height * 4);
uint32_t* pixel = start_pixel;
if (!start_pixel) {
log_error("'%s' malloc failed", path);
return { 0, 0 };
}
auto needed_pixel = image_specification.height * image_specification.width;
for (; needed_pixel;) {
auto type_and_repetition_count = read<uint8_t>(file);
auto repetition_count = type_and_repetition_count & 0x7F;
if ((type_and_repetition_count & 0x80)) {
auto pixel_value = read<uint32_t>(file);
for (; repetition_count + 1; repetition_count--) {
*pixel = pixel_value;
pixel++;
needed_pixel--;
}
}
else {
for (; repetition_count + 1; repetition_count--) {
auto pixel_value = read<uint32_t>(file);
*pixel = pixel_value;
pixel++;
needed_pixel--;
}
}
}
return { image_specification.width, image_specification.height, start_pixel };
}

11
src/load_tga_file.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#include <stdint.h>
struct BMP_Texture {
int64_t bmp_width;
int64_t bmp_height;
uint32_t* pixel;
};
BMP_Texture load_tga_file(const char* path);

25
src/log.cpp Normal file
View File

@ -0,0 +1,25 @@
#include "log.h"
#include <stdio.h>
#include <stdarg.h>
void _log(const char* function_name, const char* format, ...) {
printf("[%s] ", function_name);
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
printf("\n");
}
void _log_error(const char* function_name, const char* format, ...) {
printf("[%s]ERROR: ", function_name);
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
printf("\n");
}

6
src/log.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
#define log(format, ...) _log(__FUNCTION__, format, __VA_ARGS__)
#define log_error(format, ...) _log_error(__FUNCTION__, format, __VA_ARGS__)
void _log(const char* function_name, const char* format, ...);
void _log_error(const char* function_name, const char* format, ...);

67
src/m_string.h Normal file
View File

@ -0,0 +1,67 @@
#pragma once
#define min(a,b) (((a) < (b)) ? (a) : (b))
struct String {
size_t length;
char* data;
constexpr String() : length(0), data(0) {};
constexpr String(size_t length, char* data) : length(length), data(data) {};
template<size_t _len> constexpr String(const char(&data)[_len]) : length(_len - 1), data((char*)data) {};
char operator[](int index) {
if (index < 0) {
return 0;
}
if (index < length) {
return data[index];
}
return 0;
}
};
inline String operator""_str(const char* str, size_t length) {
return { length, (char*)str };
}
inline bool operator==(String a, String b) {
if (a.length != b.length)
return false;
if (a.data == b.data)
return true;
for (int i = 0; i < a.length; i++)
if (a[i] != b[i])
return false;
return true;
}
inline void advance(String& s, int num = 1) {
int to_advance = min(s.length, num);
s.data = s.data + to_advance;
s.length = s.length - to_advance;
}
inline bool starts_with(String s, String start) {
if (s.length < start.length) {
return false;
}
for (int i = 0; i < start.length; i++) {
if (s[i] != start[i]) {
return false;
}
}
return true;
}
template <typename T>
inline T read(String& file) {
if (file.length < sizeof(T))
return {};
T value = *(T*)file.data;
advance(file, sizeof(T));
return value;
}

View File

@ -1,3 +1,373 @@
int main() {
#define NOMINMAX
#pragma comment(lib, "d3dcompiler.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxguid.lib")
#include <d3d11.h>
#include <D3DCompiler.h>
#include <Windows.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include "create_window.h"
#include "log.h"
#include "m_string.h"
#include "math_graphics.h"
#include "load_tga_file.h"
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
IDXGISwapChain* swap_chain;
ID3D11Device* device;
ID3D11DeviceContext* devicecontext;
ID3D11DepthStencilState* depth_stencil_state;
ID3D11RenderTargetView* render_target_view;
ID3D11InputLayout* input_layout;
ID3D11Buffer* vertex_buffer;
ID3D11Buffer* index_buffer;
ID3D11Buffer* instance_buffer;
ID3DBlob* vertex_shader_code;
ID3D11VertexShader* vertex_shader;
ID3DBlob* pixel_shader_code;
ID3D11PixelShader* pixel_shader;
bool Running = true;
BMP_Texture tex1 = load_tga_file("../assets/strawberry.tga");
struct Vertex {
V4 pos;
};
Vertex vertices[] = {
{{ -1, 1, 1, 1 } },
{{ 1, -1, 1, 1 } },
{{ -1, -1, 1, 1 } },
{{ 1, 1, 1, 1 } },
};
uint16 indices[] = {
0, 1, 2,
0, 3, 1,
};
struct Instance {
V4 pos_size;
V4 left_color;
V4 right_color;
};
Instance instances[1] = {
{{0.1, 0.1, 0.2, 0.2}, {0, 1, 1, 1}, {1, 0, 1, 1}},
};
bool LoadShaders() {
ID3DBlob* error_msgs = 0;
HRESULT error_code = 0;
if (error_code = D3DCompileFromFile(L"../Assets/Shader/basic_vertex_shader.hlsl", 0, 0, "main", "vs_5_0", D3DCOMPILE_DEBUG | D3DCOMPILE_WARNINGS_ARE_ERRORS | D3DCOMPILE_OPTIMIZATION_LEVEL0 | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &vertex_shader_code, &error_msgs)) {
log("CompileFromFile has failed");
if (error_msgs)
log_error("%.*s", error_msgs->GetBufferSize(), error_msgs->GetBufferPointer());
return false;
}
if (device->CreateVertexShader(vertex_shader_code->GetBufferPointer(), vertex_shader_code->GetBufferSize(), 0, &vertex_shader)) {
log_error("CreateVertexShader has failed");
return false;
}
if (error_code = D3DCompileFromFile(L"../Assets/Shader/basic_pixel_shader.hlsl", 0, 0, "main", "ps_5_0", D3DCOMPILE_DEBUG | D3DCOMPILE_WARNINGS_ARE_ERRORS | D3DCOMPILE_OPTIMIZATION_LEVEL0, 0, &pixel_shader_code, &error_msgs)) {
log("CompileFromFile has failed");
if (error_msgs)
log_error("%.*s", error_msgs->GetBufferSize(), error_msgs->GetBufferPointer());
return false;
}
if (device->CreatePixelShader(pixel_shader_code->GetBufferPointer(), pixel_shader_code->GetBufferSize(), 0, &pixel_shader)) {
log_error("CreatePixelShader has failed");
return false;
}
return true;
}
LRESULT WindowMsgs(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam) {
LRESULT Result = 0;
switch (Message) {
case WM_SIZE: {
if(swap_chain)
swap_chain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
printf("size\n");
} break;
case WM_DESTROY: {
PostQuitMessage(0);
printf("destroy\n");
} break;
case WM_CLOSE: {
Running = false;
printf("close\n");
} break;
case WM_ACTIVATEAPP: {
printf("app\n");
} break;
case WM_KEYDOWN: {
if (!(lParam & (1 << 30))) {
//key_down[wParam] = true;
}
if (wParam == VK_F5) {
//LoadShaders();
}
} break;
case WM_KEYUP: {
//key_down[wParam] = false;
} break;
default: {
Result = DefWindowProc(Window, Message, wParam, lParam);
} break;
}
return Result;
}
void DX11SetDebugName(ID3D11DeviceChild* child, String name) {
#ifdef _DEBUG
if (child && name.data)
child->SetPrivateData(WKPDID_D3DDebugObjectName, name.length, name.data);
#endif
}
ID3D11Buffer* CreateBuffer(String name, uint32 num_bytes, void* data = 0, uint32 BindFlags = D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE Usage = D3D11_USAGE_DEFAULT, uint32 CPUAccessFlags = 0, uint32 MiscFlags = 0, uint32 StructureByteStride = 0, uint32 SysMemPitch = 0, uint32 SysMemSlicePitch = 0) {
D3D11_BUFFER_DESC buffer_desc = {
.ByteWidth = num_bytes,
.Usage = Usage,
.BindFlags = BindFlags,
.CPUAccessFlags = CPUAccessFlags,
.MiscFlags = MiscFlags,
.StructureByteStride = StructureByteStride,
};
D3D11_SUBRESOURCE_DATA subresource_data = {
.pSysMem = data,
.SysMemPitch = SysMemPitch,
.SysMemSlicePitch = SysMemSlicePitch,
};
ID3D11Buffer* buffer;
if (device->CreateBuffer(&buffer_desc, &subresource_data, &buffer)) {
return 0;
}
DX11SetDebugName(buffer, name);
return buffer;
}
bool init_directx11(HWND Window) {
D3D_FEATURE_LEVEL feature_levels[] = { D3D_FEATURE_LEVEL_11_0 };
DXGI_RATIONAL refresh_rate = {
.Numerator = 60,
.Denominator = 1,
};
DXGI_MODE_DESC buffer_desc = {
.Width = 0,
.Height = 0,
.RefreshRate = refresh_rate,
.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
.Scaling = DXGI_MODE_SCALING_UNSPECIFIED,
};
DXGI_SAMPLE_DESC sample_desc = {
.Count = 1,
.Quality = 0,
};
DXGI_SWAP_CHAIN_DESC swap_chain_desc = {
.BufferDesc = buffer_desc,
.SampleDesc = sample_desc,
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
.BufferCount = 2,
.OutputWindow = Window,
.Windowed = TRUE,
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
.Flags = 0,
};
if (D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_DEBUG, feature_levels, 1, D3D11_SDK_VERSION, &swap_chain_desc, &swap_chain, &device, 0, &devicecontext)) {
log_error("D3D11CreateDeviceAndSwapChain has failed.");
return 1;
}
ID3D11Texture2D* present_buffer;
if (swap_chain->GetBuffer(0, IID_PPV_ARGS(&present_buffer))) {
log_error("PresentBuffer getting failed");
return 1;
}
if (device->CreateRenderTargetView(present_buffer, 0, &render_target_view)) {
log_error("CreateRenderTargetView has failed");
return 1;
}
present_buffer->Release();
D3D11_DEPTH_STENCIL_DESC depth_stencil_desc = {
.DepthEnable = FALSE,
.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL,
.DepthFunc = D3D11_COMPARISON_LESS,
.StencilEnable = FALSE,
.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK,
.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK,
.FrontFace = {
.StencilFunc = D3D11_COMPARISON_ALWAYS,
.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP,
.StencilFailOp = D3D11_STENCIL_OP_KEEP,
.StencilPassOp = D3D11_STENCIL_OP_KEEP,
},
.BackFace = {
.StencilFunc = D3D11_COMPARISON_ALWAYS,
.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP,
.StencilFailOp = D3D11_STENCIL_OP_KEEP,
.StencilPassOp = D3D11_STENCIL_OP_KEEP,
},
};
if (device->CreateDepthStencilState(&depth_stencil_desc, &depth_stencil_state)) {
log_error("CreateDepthStencilState has failed.");
return 1;
}
if (!LoadShaders()) {
log_error("LoadShaders has failed");
return 1;
}
//device->CreateVertexShader()
D3D11_INPUT_ELEMENT_DESC input_element_desc[] = {
{ "VERTEX_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "INSTANCE_POSITION_SIZE", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
{ "LEFT_COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
{ "RIGHT_COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 32, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
};
if (device->CreateInputLayout(input_element_desc, sizeof(input_element_desc) / sizeof(*input_element_desc), vertex_shader_code->GetBufferPointer(), vertex_shader_code->GetBufferSize(), &input_layout)) {
log_error("CreateInputLayout has failed");
return 1;
}
RECT rect;
if (!GetClientRect(Window, &rect)) {
log_error("GetClientRect has failed.");
return 1;
}
D3D11_VIEWPORT viewport = {
.TopLeftX = 0,
.TopLeftY = 0,
.Width = (float)(rect.right),
.Height = (float)(rect.bottom),
.MinDepth = 0,
.MaxDepth = 1,
};
devicecontext->RSSetViewports(1, &viewport);
vertex_buffer = CreateBuffer("vertex_buffer", sizeof(vertices), vertices, D3D11_BIND_VERTEX_BUFFER);
index_buffer = CreateBuffer("index_buffer", sizeof(indices), indices, D3D11_BIND_INDEX_BUFFER);
instance_buffer = CreateBuffer("instance_buffer", sizeof(instances), instances, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
return 0;
}
int main() {
CoInitializeEx(0, COINIT_MULTITHREADED);
auto Window = (HWND)create_window(WindowMsgs);
if (!Window) {
printf("CreateWindow failed!\n");
return 1;
}
if (init_directx11(Window))
return 1;
MSG Message;
while (Running) {
while (PeekMessage(&Message, 0, 0, 0, PM_REMOVE)) {
if (Message.message == WM_QUIT) {
Running = false;
}
TranslateMessage(&Message);
DispatchMessage(&Message);
}
devicecontext->OMSetRenderTargets(1, &render_target_view, 0);
V4 clear_color = { 0, 0, 0, 1 };
devicecontext->ClearRenderTargetView(render_target_view, clear_color.E);
//Quad rendern
D3D11_MAPPED_SUBRESOURCE mapped_subresource;
devicecontext->Map(instance_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_subresource);
memcpy(mapped_subresource.pData, instances, sizeof(instances));
devicecontext->Unmap(instance_buffer, 0);
devicecontext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
devicecontext->IASetInputLayout(input_layout);
ID3D11Buffer* input_buffers[] = {
vertex_buffer,
instance_buffer,
};
UINT input_strides[] = {
sizeof(Vertex),
sizeof(Instance),
};
UINT input_offsets[] = {
0,
0,
};
devicecontext->IASetVertexBuffers(0, sizeof(input_buffers) / sizeof(*input_buffers), input_buffers, input_strides, input_offsets);
devicecontext->IASetIndexBuffer(index_buffer, DXGI_FORMAT_R16_UINT, 0);
devicecontext->IASetInputLayout(input_layout);
devicecontext->VSSetShader(vertex_shader, 0, 0);
devicecontext->PSSetShader(pixel_shader, 0, 0);
devicecontext->DrawIndexedInstanced(6, 1, 0, 0, 0);
//
swap_chain->Present(0, 0);
}
return 0;
}

704
src/math_graphics.h Normal file
View File

@ -0,0 +1,704 @@
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <emmintrin.h>
#include <immintrin.h>
#include <xmmintrin.h>
#include <stdint.h>
#include <assert.h>
#undef min
#undef max
//clamp
constexpr inline float clamp(float min, float a, float max) {
float result = a;
if (a < min)
result = min;
if (a > max)
result = max;
return result;
}
//clamp für 0-1 Bereich (Grafik)
constexpr inline float clamp01(float a) {
return clamp(0, a, 1);
}
//wurzelberechnung
inline float square_root(float a) {
return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(a)));
}
inline float reciprocal_square_root(float a) {
return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(a)));
}
constexpr inline float min(float a, float b) {
return a < b ? a : b;
}
constexpr inline float max(float a, float b) {
return a > b ? a : b;
}
constexpr inline double min(double a, double b) {
return a < b ? a : b;
}
constexpr inline double max(double a, double b) {
return a > b ? a : b;
}
constexpr inline int64_t min(int64_t a, int64_t b) {
return a < b ? a : b;
}
template<typename T>
constexpr inline T min(T a, T b) {
return a < b ? a : b;
}
constexpr float lerp(float a, float t, float b) {
return (1.0f - t) * a + t * b;
}
//-----------------------------------------------
//Vektorberechnung 2-dim
union V2 {
struct {
float x;
float y;
};
struct {
float u;
float v;
};
struct {
float width;
float height;
};
struct {
float E[2];
};
float operator [](size_t index) {
assert(index < 2);
return E[index];
}
};
//Negation von 2-dim Vektor
inline V2 operator -(V2 a) {
return {
-a.x,
-a.y
};
}
//Addition 2er 2-dim Vektoren
inline V2 operator +(V2 a, V2 b) {
return {
a.x + b.x,
a.y + b.y
};
}
//Subtraktion 2er 2-dim Vektoren
inline V2 operator -(V2 a, V2 b) {
return {
a.x - b.x,
a.y - b.y
};
}
//Skalarmultiplikation -> erst Skalar, dann Vektor
inline V2 operator *(float a, V2 b) {
return {
a * b.x,
a * b.y
};
}
//Skalarmultiplikation -> erst Vektor, dann Skalar
inline V2 operator *(V2 a, float b) {
return {
a.x * b,
a.y * b
};
}
//Division mit nem Skalar Oo -> Skalar geteilt durch Vektor
inline V2 operator /(float a, V2 b) {
return {
a / b.x,
a / b.y
};
}
//Division mit nem Skalar Oo -> Vektor geteilt durch Skalar
inline V2 operator /(V2 a, float b) {
return {
a.x / b,
a.y / b
};
}
//Skalarprodukt
inline float dot(V2 a, V2 b) {
return a.x * b.x + a.y * b.y;
}
//Hadamard-Produkt
inline V2 hadamard(V2 a, V2 b) {
return {
a.x * b.x,
a.y * b.y
};
}
//Betrag des Vektors quadrieren
inline float length_squared(V2 a) {
return dot(a, a);
}
//Betrag eines Vektors
inline float length(V2 a) {
return square_root(length_squared(a));
}
//Reziproke der Länge
inline float reciprocal_length(V2 a) {
return reciprocal_square_root(length_squared(a));
}
//Einheitsvektor
inline V2 normalize(V2 a) {
return a * reciprocal_length(a);
}
//Vektor der 90°
inline V2 perp(V2 a) {
return {
-a.y,
a.x
};
}
//clamp für 2-dim Vektor
inline V2 clamp01(V2 a) {
return {
clamp01(a.x),
clamp01(a.y)
};
}
inline V2 min(V2 a, V2 b) {
return {
min(a.x, b.x),
min(a.y, b.y),
};
}
inline V2 max(V2 a, V2 b) {
return {
max(a.x, b.x),
max(a.y, b.y),
};
}
inline float min(V2 a) {
return min(a.x, a.y);
}
inline float max(V2 a) {
return max(a.x, a.y);
}
//-----------------------------------------------
//Vektorberechnung 3-dim
union V3 {
struct {
float x;
float y;
float z;
};
//farbvektor
struct {
float r;
float g;
float b;
};
//texturvektor
struct {
float u;
float v;
float s;
};
//von V3 zu V2 ohne z
struct {
V2 xy;
float _z;
};
//von V3 zu V2 ohne x
struct {
float _x;
V2 yz;
};
struct {
float E[3];
};
float operator [](size_t index) {
assert(index < 3);
return E[index];
}
};
//Negation von 2-dim Vektor
inline V3 operator -(V3 a) {
return {
-a.x,
-a.y,
-a.z
};
}
//Addition 2er 2-dim Vektoren
inline V3 operator +(V3 a, V3 b) {
return {
a.x + b.x,
a.y + b.y,
a.z + b.z
};
}
//Subtraktion 2er 2-dim Vektoren
inline V3 operator -(V3 a, V3 b) {
return {
a.x - b.x,
a.y - b.y,
a.z - b.z
};
}
//Skalarmultiplikation -> erst Skalar, dann Vektor
inline V3 operator *(float a, V3 b) {
return {
a * b.x,
a * b.y,
a * b.z
};
}
//Skalarmultiplikation -> erst Vektor, dann Skalar
inline V3 operator *(V3 a, float b) {
return {
a.x * b,
a.y * b,
a.z * b
};
}
//Division mit nem Skalar Oo -> Skalar geteilt durch Vektor
inline V3 operator /(float a, V3 b) {
return {
a / b.x,
a / b.y,
a / b.z
};
}
//Division mit nem Skalar Oo -> Vektor geteilt durch Skalar
inline V3 operator /(V3 a, float b) {
return {
a.x / b,
a.y / b,
a.z / b
};
}
//Skalarprodukt
inline float dot(V3 a, V3 b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
}
//Hadamard-Produkt
inline V3 hadamard(V3 a, V3 b) {
return {
a.x * b.x,
a.y * b.y,
a.z * b.z
};
}
//Kreuzprodukt
inline V3 cross(V3 a, V3 b) {
return {
a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.x * b.y - a.y * b.x
};
}
//Betrag des Vektors quadrieren
inline float length_squared(V3 a) {
return dot(a, a);
}
//Betrag eines Vektors
inline float length(V3 a) {
return square_root(length_squared(a));
}
//Reziproke der Länge
inline float reciprocal_length(V3 a) {
return reciprocal_square_root(length_squared(a));
}
//Einheitsvektor
inline V3 normalize(V3 a) {
return a * reciprocal_length(a);
}
union V4 {
struct {
float x;
float y;
float z;
float w;
};
//farbvektor
struct {
float r;
float g;
float b;
float a;
};
//texturvektor
struct {
float u;
float v;
float s;
float t;
};
//von V3 zu V2 ohne z
struct {
V2 xy;
V2 zw;
};
//von V3 zu V2 ohne x
struct {
float _x;
V2 yz;
float _w;
};
struct {
float E[4];
};
V4(V2 a, V2 b) { xy = a; zw = b; }
V4(float a, float b, float c, float d) { x = a; y = b; z = c; w = d; }
V4(float a, float b, float c) { x = a; y = b; z = c; w = 1; }
V4() {}
float operator [](size_t index) {
assert(index < 4);
return E[index];
}
};
//-----------------------------------------------
//2x2 Matrix
//M2x2 m;
//m.E[0][1]
//m.V[1]
//m[1][0]
union M2x2 {
struct {
float x1; float x2;
float y1; float y2;
};
struct {
float E[2][2];
};
struct {
V2 V[2];
};
V2 &operator [](size_t index) {
assert(index < 2);
return V[index];
}
};
//Matrix negieren
inline M2x2 operator -(M2x2 a){
return {
-a[0][0], -a[0][1],
-a[1][0], -a[1][1]
};
}
//Matrix Addition
inline M2x2 operator +(M2x2 a, M2x2 b) {
return {
a[0][0] + b[0][0], a[0][1] + b[0][1],
a[1][0] + b[1][0], a[1][1] + b[1][1]
};
}
//Matrix Subtraktion
inline M2x2 operator -(M2x2 a, M2x2 b) {
return {
a[0][0] - b[0][0], a[0][1] - b[0][1],
a[1][0] - b[1][0], a[1][1] - b[1][1]
};
}
//Matrix Skalarmultiplikation
inline M2x2 operator *(M2x2 a, float b) {
return {
a[0][0] * b, a[0][1] * b,
a[1][0] * b, a[1][1] * b
};
}
//Matrix Skalarmultiplikation
inline M2x2 operator *(float a, M2x2 b) {
return {
a * b[0][0], a * b[0][1],
a * b[1][0], a * b[1][1]
};
}
//Matrix Multiplikation
inline M2x2 operator *(M2x2 a, M2x2 b) {
return {
a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1],
a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]
};
}
//Matrix * Vektor
inline V2 operator *(M2x2 a, V2 b) {
return {
a[0][0] * b[0] + a[0][1] * b[1],
a[1][0] * b[0] + a[1][1] * b[1],
};
}
//Matrix Transponieren
inline M2x2 transpose(M2x2 a) {
return {
a[0][0], a[1][0],
a[0][1], a[1][1]
};
}
//Einheitsmatrix (oder Identitätsmatrix)
constexpr inline M2x2 identityM2x2() {
return {
1.0f, 0.0f,
0.0f, 1.0f
};
}
//-----------------------------------------------
//3x3 Matrix
union M3x3 {
struct {
float x1; float x2; float x3;
float y1; float y2; float y3;
float z1; float z2; float z3;
};
struct {
float E[3][3];
};
struct {
V3 V[3];
};
V3& operator [](size_t index) {
assert(index < 3);
return V[index];
}
};
//Matrix negieren
inline M3x3 operator -(M3x3 a) {
return {
-a[0][0], -a[0][1], -a[0][1],
-a[1][0], -a[1][1], -a[1][2],
-a[2][0], -a[2][1], -a[2][2]
};
}
//Matrix Addition
inline M3x3 operator +(M3x3 a, M3x3 b) {
return {
a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2],
a[1][0] + b[1][0], a[1][1] + b[1][1], a[1][2] + b[1][2],
a[2][0] + b[2][0], a[2][1] + b[2][1], a[2][2] + b[2][2]
};
}
//Matrix Subtraktion
inline M3x3 operator -(M3x3 a, M3x3 b) {
return {
a[0][0] - b[0][0], a[0][1] - b[0][1], a[0][2] - b[0][2],
a[1][0] - b[1][0], a[1][1] - b[1][1], a[1][2] - b[1][2],
a[2][0] - b[2][0], a[2][1] - b[2][1], a[2][2] - b[2][2]
};
}
//Matrix Skalarmultiplikation
inline M3x3 operator *(M3x3 a, float b) {
return {
a[0][0] * b, a[0][1] * b, a[0][2] * b,
a[1][0] * b, a[1][1] * b, a[1][2] * b,
a[2][0] * b, a[2][1] * b, a[2][2] * b
};
}
//Matrix Skalarmultiplikation
inline M3x3 operator *(float a, M3x3 b) {
return {
a * b[0][0], a * b[0][1], a * b[0][2],
a * b[1][0], a * b[1][1], a * b[1][2],
a * b[2][0], a * b[2][1], a * b[2][2]
};
}
//Matrix Multiplikation
inline M3x3 operator *(M3x3 a, M3x3 b) {
return {
a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0], a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1], a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2],
a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0], a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1], a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[0][2] * b[2][2],
a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0], a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1], a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[0][2] * b[2][2]
};
}
//Matrix * V2
inline V2 operator *(M3x3 a, V2 b) {
return {
b.x * a[0][0] + b.y * a[0][1] + 1.0f * a[0][2],
b.x * a[1][0] + b.y * a[1][1] + 1.0f * a[1][2],
};
}
//Matrix * V3
inline V3 operator *(M3x3 a, V3 b) {
return {
b.x * a[0][0] + b.y * a[0][1] + b.z * a[0][2],
b.x * a[1][0] + b.y * a[1][1] + b.z * a[1][2],
b.x * a[2][0] + b.y * a[2][1] + b.z * a[2][2]
};
}
//Matrix transponieren
inline M3x3 transpose(M3x3 a) {
return {
a[0][0], a[1][0], a[2][0],
a[0][1], a[1][1], a[2][1],
a[0][2], a[1][2], a[2][2]
};
}
//Einheitsmatrix (oder Identitätsmatrix)
inline M3x3 identityM3x3() {
return {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f
};
}
//-----------------------------------------------
//m128i
struct m128i {
__m128i val;
};
inline __m128i operator &(m128i a, m128i b) {
return _mm_and_si128(a.val, b.val);
}
inline __m128i operator |(m128i a, m128i b) {
return _mm_or_si128(a.val, b.val);
}
inline __m128i operator >>(m128i a, int b) {
return _mm_srli_epi32(a.val, b);
}
inline __m128i operator <<(m128i a, int b) {
return _mm_slli_epi32(a.val, b);
}
//-----------------------------------------------
//m128
struct m128 {
__m128 val;
};
inline __m128 operator +(m128 a, m128 b) {
return _mm_mul_ps(a.val, b.val);
}
inline __m128 operator *(m128 a, m128 b) {
return _mm_mul_ps(a.val, b.val);
}
inline __m128 operator *(float a, m128 b) {
return _mm_mul_ps(_mm_set1_ps(a), b.val);
}
inline __m128 square_root(__m128 a) {
return _mm_sqrt_ps(a);
}
inline __m128 operator /(m128 a, m128 b) {
return _mm_div_ps(a.val, b.val);
}
inline __m128 lerp(__m128 a, float t, float b) {
return (1.0f - t) * a + (t * b);
}