This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository direct3d.

View the commit online.

commit 87907282864570e795acaf9e3e1da779b22ebfe7
Author: Vincent Torri <vto...@outlook.fr>
AuthorDate: Sun Apr 14 18:34:36 2024 +0200

    WIP: code for textures
---
 src/d3d_7.c       | 1145 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/shader_7.hlsl |   41 ++
 2 files changed, 1186 insertions(+)

diff --git a/src/d3d_7.c b/src/d3d_7.c
new file mode 100644
index 0000000..3faedee
--- /dev/null
+++ b/src/d3d_7.c
@@ -0,0 +1,1145 @@
+/*
+ * Tutorial part 7
+ *
+ * Manage texture
+ *
+ * Compilation:
+ *
+ * gcc -g -O2 -Wall -Wextra -o d3d_7 d3d_7.c win.c -ld3d11 -ld3dcompiler -ldxgi -luuid -D_WIN32_WINNT=0x0A00
+ */
+
+#include <stdlib.h> /* calloc() free() malloc() */
+#include <stdio.h>  /* printf() fflush() */
+
+#define _DEBUG
+
+/* C API for d3d11 */
+#define COBJMACROS
+
+#include <dxgi1_3.h>     /* DXGI interface */
+#include <d3d11.h>       /* D3D11 interface */
+#include <d3dcompiler.h> /* compilation of shader */
+#include <dxgidebug.h>   /* IDXGIDebug interface */
+
+#include "win.h"
+
+#ifdef _DEBUG
+# define FCT \
+do { printf(" * %s\n", __FUNCTION__); fflush(stdout); } while (0)
+# define DBG_NAME(interface_, child_, name_) interface_ ## _SetPrivateData(child_, &WKPDID_D3DDebugObjectName, strlen(name_), name_)
+#else
+# define FCT \
+do { } while (0)
+# define DBG_NAME(interface_, child_, name_)
+#endif
+
+typedef enum
+{
+    OBJECT_TYPE_RECTANGLE,
+    OBJECT_TYPE_TEXTURE
+} Object_Type;
+
+struct D3d
+{
+    /* DXGI */
+#ifdef _DEBUG
+    IDXGIDebug *dxgi_debug;
+#endif
+    IDXGIFactory2 *dxgi_factory;
+    IDXGISwapChain1 *dxgi_swapchain;
+    /* D3D11 */
+    ID3D11Device *d3d_device;
+#ifdef _DEBUG
+    ID3D11Debug *d3d_debug;
+#endif
+    ID3D11DeviceContext *d3d_device_ctx;
+    ID3D11RenderTargetView *d3d_render_target_view;
+    ID3D11InputLayout *d3d_input_layout;
+    ID3D11VertexShader *d3d_vertex_shader;
+    ID3D11Buffer *d3d_const_buffer;
+    ID3D11SamplerState *d3d_sampler_state;
+    ID3D11RasterizerState *d3d_rasterizer_state;
+    ID3D11PixelShader *d3d_pixel_shader;
+    D3D11_VIEWPORT viewport;
+    unsigned int vsync : 1;
+};
+
+typedef struct
+{
+    UINT x;
+    UINT y;
+    BYTE r;
+    BYTE g;
+    BYTE b;
+    BYTE a;
+    FLOAT u;
+    FLOAT v;
+} Vertex;
+
+typedef struct
+{
+    int rotation[2][4];
+    float ivps[2];
+    float dummy[2];
+} Const_Buffer;
+
+typedef struct
+{
+    Object_Type type;
+    ID3D11Buffer *vertex_buffer;
+    ID3D11Buffer *index_buffer;
+    ID3D11Texture2D *texture;
+    ID3D11ShaderResourceView *texture_view;
+    UINT stride;
+    UINT offset;
+    UINT index_count;
+} Object;
+
+static Object *objects[1];
+
+/************************** D3D11 **************************/
+
+static void d3d_refresh_rate_get(D3d *d3d, UINT *num, UINT *den)
+{
+    DXGI_MODE_DESC *display_mode_list = NULL; /* 28 bytes */
+    IDXGIAdapter *dxgi_adapter;
+    IDXGIOutput *dxgi_output;
+    UINT nbr_modes;
+    UINT i;
+    HRESULT res;
+
+    *num = 0U;
+    *den = 1U;
+
+    if (!d3d->vsync)
+        return;
+
+    /* adapter of primary desktop : pass 0U */
+    res = IDXGIFactory_EnumAdapters(d3d->dxgi_factory, 0U, &dxgi_adapter);
+    if (FAILED(res))
+        return;
+
+    /* output of primary desktop : pass 0U */
+    res = IDXGIAdapter_EnumOutputs(dxgi_adapter, 0U, &dxgi_output);
+    if (FAILED(res))
+        goto release_dxgi_adapter;
+
+    /* number of mode that fit the format */
+     res = IDXGIOutput_GetDisplayModeList(dxgi_output,
+                                         DXGI_FORMAT_B8G8R8A8_UNORM,
+                                         DXGI_ENUM_MODES_INTERLACED,
+                                         &nbr_modes, NULL);
+    if (FAILED(res))
+        goto release_dxgi_output;
+
+    printf("display mode list : %d\n", nbr_modes);
+    fflush(stdout);
+    display_mode_list = (DXGI_MODE_DESC *)malloc(nbr_modes * sizeof(DXGI_MODE_DESC));
+    if (!display_mode_list)
+        goto release_dxgi_output;
+
+    /* fill the mode list */
+    res = IDXGIOutput_GetDisplayModeList(dxgi_output,
+                                         DXGI_FORMAT_B8G8R8A8_UNORM,
+                                         DXGI_ENUM_MODES_INTERLACED,
+                                         &nbr_modes, display_mode_list);
+    if (FAILED(res))
+        goto free_mode_list;
+
+    for (i = 0; i < nbr_modes; i++)
+    {
+        if ((display_mode_list[i].Width == (UINT)GetSystemMetrics(SM_CXSCREEN)) &&
+            (display_mode_list[i].Height == (UINT)GetSystemMetrics(SM_CYSCREEN)))
+        {
+            *num = display_mode_list[i].RefreshRate.Numerator;
+            *den = display_mode_list[i].RefreshRate.Denominator;
+            break;
+        }
+    }
+
+#ifdef _DEBUG
+    {
+        DXGI_ADAPTER_DESC adapter_desc;
+
+        IDXGIAdapter_GetDesc(dxgi_adapter, &adapter_desc);
+        printf(" * video mem: %llu B, %llu MB\n",
+               adapter_desc.DedicatedVideoMemory,
+               adapter_desc.DedicatedVideoMemory / 1024 / 1024);
+        fflush(stdout);
+        wprintf(L" * description: %ls\n", adapter_desc.Description);
+        fflush(stdout);
+    }
+#endif
+
+  free_mode_list:
+    free(display_mode_list);
+  release_dxgi_output:
+    IDXGIOutput_Release(dxgi_output);
+  release_dxgi_adapter:
+    IDXGIFactory_Release(dxgi_adapter);
+}
+
+D3d *d3d_init(Window *win, int vsync)
+{
+    D3D11_INPUT_ELEMENT_DESC desc_ie[] =
+    {
+        { "POSITION", 0, DXGI_FORMAT_R32G32_UINT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+        { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+        { "UV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
+    };
+    DXGI_SWAP_CHAIN_DESC1 desc_sw;
+    DXGI_SWAP_CHAIN_FULLSCREEN_DESC desc_fs;
+    D3D11_BUFFER_DESC desc_buf;
+    D3D11_SAMPLER_DESC desc_ss;
+    D3D11_RASTERIZER_DESC desc_rs;
+    D3d *d3d;
+    RECT r;
+    HRESULT res;
+    UINT flags;
+    UINT num;
+    UINT den;
+    D3D_FEATURE_LEVEL feature_level[4];
+    ID3DBlob *vs_blob; /* vertex shader blob ptr */
+    ID3DBlob *ps_blob; /* pixel shader blob ptr */
+    ID3DBlob *err_blob; /* error blob ptr */
+
+    d3d = (D3d *)calloc(1, sizeof(D3d));
+    if (!d3d)
+        return NULL;
+
+    d3d->vsync = vsync;
+    win->d3d = d3d;
+
+    /* create the DXGI factory */
+    flags = 0;
+#ifdef _DEBUG
+    flags = DXGI_CREATE_FACTORY_DEBUG;
+#endif
+    res = CreateDXGIFactory2(flags, &IID_IDXGIFactory2, (void **)&d3d->dxgi_factory);
+    if (FAILED(res))
+        goto free_d3d;
+
+#ifdef _DEBUG
+    IDXGIFactory2_SetPrivateData(d3d->dxgi_factory,
+                                 &WKPDID_D3DDebugObjectName,
+                                 sizeof("Factory2") - 1, "Factory2");
+    res = DXGIGetDebugInterface(&IID_IDXGIDebug,
+                                (void **)&d3d->dxgi_debug);
+    if (FAILED(res))
+        goto release_dxgi_factory2;
+#endif
+
+    /* software engine functions are called from the main loop */
+    flags = D3D11_CREATE_DEVICE_SINGLETHREADED |
+            D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+#ifdef _DEBUG
+    flags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+
+    feature_level[0] = D3D_FEATURE_LEVEL_11_1;
+    feature_level[1] = D3D_FEATURE_LEVEL_11_0;
+    feature_level[2] = D3D_FEATURE_LEVEL_10_1;
+    feature_level[3] = D3D_FEATURE_LEVEL_10_0;
+
+    /* create device and device context with hardware support */
+    res = D3D11CreateDevice(NULL,
+                            D3D_DRIVER_TYPE_HARDWARE,
+                            NULL,
+                            flags,
+                            feature_level,
+                            3U,
+                            D3D11_SDK_VERSION,
+                            &d3d->d3d_device,
+                            NULL,
+                            &d3d->d3d_device_ctx);
+    if (FAILED(res))
+        goto release_dxgi_factory2;
+
+#ifdef _DEBUG
+    ID3D11Device_SetPrivateData(d3d->d3d_device,
+                                &WKPDID_D3DDebugObjectName,
+                                sizeof("Device") - 1, "Device");
+    res = ID3D11Debug_QueryInterface(d3d->d3d_device, &IID_ID3D11Debug,
+                                     (void **)&d3d->d3d_debug);
+    if (FAILED(res))
+        goto release_d3d_device;
+#endif
+
+    DBG_NAME(ID3D11DeviceContext, d3d->d3d_device_ctx, "Device Context");
+
+    if (!GetClientRect(win->win, &r))
+        goto release_d3d_device;
+
+    /*
+     * create the swap chain. It needs some settings...
+     * the size of the internal buffers
+     * the image format
+     * the number of back buffers (>= 2 for flip model, see SwapEffect field)
+     * vsync enabled: need refresh rate
+     */
+
+    d3d_refresh_rate_get(d3d, &num, &den);
+
+    desc_sw.Width = r.right - r.left;
+    desc_sw.Height = r.bottom - r.top;
+    desc_sw.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+    desc_sw.Stereo = FALSE;
+    desc_sw.SampleDesc.Count = 1U;
+    desc_sw.SampleDesc.Quality = 0U;
+    desc_sw.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+    desc_sw.BufferCount = 2U;
+    desc_sw.Scaling = DXGI_SCALING_NONE;
+    desc_sw.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+    desc_sw.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
+    desc_sw.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+
+    desc_fs.RefreshRate.Numerator = num;
+    desc_fs.RefreshRate.Denominator = den;
+    desc_fs.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+    desc_fs.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+    desc_fs.Windowed = TRUE;
+
+    res = IDXGIFactory2_CreateSwapChainForHwnd(d3d->dxgi_factory,
+                                               (IUnknown *)d3d->d3d_device,
+                                               win->win,
+                                               &desc_sw,
+                                               &desc_fs,
+                                               NULL,
+                                               &d3d->dxgi_swapchain);
+    if (FAILED(res))
+        goto release_d3d_device;
+
+    DBG_NAME(IDXGIFactory, d3d->dxgi_swapchain, "Swap Chain");
+
+    /* sampler state */
+    desc_ss.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+    desc_ss.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+    desc_ss.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+    desc_ss.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+    desc_ss.MipLODBias = 0.0f;
+    desc_ss.MaxAnisotropy = 1U;
+    desc_ss.ComparisonFunc = D3D11_COMPARISON_NEVER;
+    desc_ss.BorderColor[0] = 1.0f;
+    desc_ss.BorderColor[1] = 1.0f;
+    desc_ss.BorderColor[2] = 1.0f;
+    desc_ss.BorderColor[3] = 1.0f;
+    desc_ss.MinLOD = 0.0f;
+    desc_ss.MaxLOD = D3D11_FLOAT32_MAX;
+
+    res = ID3D11Device_CreateSamplerState(d3d->d3d_device,
+                                          &desc_ss,
+                                          &d3d->d3d_sampler_state);
+    if (FAILED(res))
+        goto release_dxgi_swapchain;
+
+    DBG_NAME(ID3D11Device, d3d->d3d_sampler_state, "Sampler State");
+
+    /* rasterizer */
+    desc_rs.FillMode = D3D11_FILL_SOLID;
+    desc_rs.CullMode = D3D11_CULL_NONE;
+    desc_rs.FrontCounterClockwise = FALSE;
+    desc_rs.DepthBias = 0;
+    desc_rs.DepthBiasClamp = 0.0f;
+    desc_rs.SlopeScaledDepthBias = 0.0f;
+    desc_rs.DepthClipEnable = TRUE;
+    desc_rs.ScissorEnable = FALSE;
+    desc_rs.MultisampleEnable = FALSE;
+    desc_rs.AntialiasedLineEnable = FALSE;
+
+    res = ID3D11Device_CreateRasterizerState(d3d->d3d_device,
+                                             &desc_rs,
+                                             &d3d->d3d_rasterizer_state);
+    if (FAILED(res))
+        goto release_d3D_sampler_state;
+
+    DBG_NAME(ID3D11Device, d3d->d3d_rasterizer_state, "Rasterizer State");
+
+    /* Vertex shader */
+    flags = D3DCOMPILE_ENABLE_STRICTNESS;
+#ifdef _DEBUG
+    flags |= D3DCOMPILE_DEBUG;
+#endif
+    vs_blob = NULL;
+    res = D3DCompileFromFile(L"shader_7.hlsl",
+                             NULL,
+                             D3D_COMPILE_STANDARD_FILE_INCLUDE,
+                             "main_vs",
+                             "vs_5_0",
+                             flags,
+                             0U,
+                             &vs_blob,
+                             &err_blob );
+
+    if (FAILED(res))
+    {
+        printf(" * vs error : %s\n", (char *)ID3D10Blob_GetBufferPointer(err_blob));
+        goto release_d3D_rasterizer;
+    }
+
+    res = ID3D11Device_CreateVertexShader(d3d->d3d_device,
+                                          ID3D10Blob_GetBufferPointer(vs_blob),
+                                          ID3D10Blob_GetBufferSize(vs_blob),
+                                          NULL,
+                                          &d3d->d3d_vertex_shader);
+
+    if (FAILED(res))
+    {
+        printf(" * CreateVertexShader() failed\n");
+        ID3D10Blob_Release(vs_blob);
+        goto release_d3D_rasterizer;
+    }
+
+    DBG_NAME(ID3D11Device, d3d->d3d_vertex_shader, "Vertex Shader");
+
+    /* create the input layout */
+    res = ID3D11Device_CreateInputLayout(d3d->d3d_device,
+                                         desc_ie,
+                                         sizeof(desc_ie) / sizeof(D3D11_INPUT_ELEMENT_DESC),
+                                         ID3D10Blob_GetBufferPointer(vs_blob),
+                                         ID3D10Blob_GetBufferSize(vs_blob),
+                                         &d3d->d3d_input_layout);
+    ID3D10Blob_Release(vs_blob);
+    if (FAILED(res))
+    {
+        printf(" * CreateInputLayout() failed\n");
+        goto release_vertex_shader;
+    }
+
+    DBG_NAME(ID3D11Device, d3d->d3d_input_layout, "Input Layout");
+
+    /* Pixel shader */
+    ps_blob = NULL;
+    res = D3DCompileFromFile(L"shader_7.hlsl",
+                             NULL,
+                             D3D_COMPILE_STANDARD_FILE_INCLUDE,
+                             "main_ps",
+                             "ps_5_0",
+                             flags,
+                             0U,
+                             &ps_blob,
+                             &err_blob );
+
+    if (FAILED(res))
+    {
+        printf(" * ps blob error : %s\n", (char *)ID3D10Blob_GetBufferPointer(err_blob));
+        goto release_input_layout;
+    }
+
+    res = ID3D11Device_CreatePixelShader(d3d->d3d_device,
+                                         ID3D10Blob_GetBufferPointer(ps_blob),
+                                         ID3D10Blob_GetBufferSize(ps_blob),
+                                         NULL,
+                                         &d3d->d3d_pixel_shader);
+    ID3D10Blob_Release(ps_blob);
+    if (FAILED(res))
+    {
+        printf(" * CreatePixelShader() failed\n");
+        goto release_input_layout;
+    }
+
+    DBG_NAME(ID3D11Device, d3d->d3d_pixel_shader, "Pixel Shader");
+
+    desc_buf.ByteWidth = sizeof(Const_Buffer);
+    desc_buf.Usage = D3D11_USAGE_DYNAMIC; /* because buffer is updated when the window has resized */
+    desc_buf.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+    desc_buf.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    desc_buf.MiscFlags = 0;
+    desc_buf.StructureByteStride = 0;
+
+    res = ID3D11Device_CreateBuffer(d3d->d3d_device,
+                                    &desc_buf,
+                                    NULL,
+                                    &d3d->d3d_const_buffer);
+    if (FAILED(res))
+    {
+        printf(" * CreateBuffer() failed 0x%lx\n", res);
+        goto release_pixel_shader;
+    }
+
+    DBG_NAME(ID3D11Device, d3d->d3d_const_buffer, "Constant Buffer");
+
+    return d3d;
+
+  release_pixel_shader:
+    ID3D11PixelShader_Release(d3d->d3d_pixel_shader);
+  release_input_layout:
+    ID3D11InputLayout_Release(d3d->d3d_input_layout);
+  release_vertex_shader:
+    ID3D11VertexShader_Release(d3d->d3d_vertex_shader);
+  release_d3D_rasterizer:
+    ID3D11RasterizerState_Release(d3d->d3d_rasterizer_state);
+  release_d3D_sampler_state:
+    ID3D11SamplerState_Release(d3d->d3d_sampler_state);
+  release_dxgi_swapchain:
+    IDXGISwapChain1_SetFullscreenState(d3d->dxgi_swapchain, FALSE, NULL);
+    IDXGISwapChain1_Release(d3d->dxgi_swapchain);
+  release_d3d_device:
+#ifdef _DEBUG
+    if (d3d->d3d_debug)
+        ID3D11Debug_Release(d3d->d3d_debug);
+#endif
+    ID3D11DeviceContext_Release(d3d->d3d_device_ctx);
+    ID3D11Device_Release(d3d->d3d_device);
+  release_dxgi_factory2:
+    IDXGIFactory2_Release(d3d->dxgi_factory);
+  free_d3d:
+    free(d3d);
+
+    return NULL;
+}
+
+void d3d_shutdown(D3d *d3d)
+{
+#ifdef _DEBUG
+    IDXGIDebug *dxgi_debug;
+    ID3D11Debug *d3d_debug;
+#endif
+
+    if (!d3d)
+        return;
+
+#ifdef _DEBUG
+    dxgi_debug = d3d->dxgi_debug;
+    d3d_debug = d3d->d3d_debug;
+#endif
+
+    ID3D11Buffer_Release(d3d->d3d_const_buffer);
+    ID3D11PixelShader_Release(d3d->d3d_pixel_shader);
+    ID3D11InputLayout_Release(d3d->d3d_input_layout);
+    ID3D11VertexShader_Release(d3d->d3d_vertex_shader);
+    ID3D11RasterizerState_Release(d3d->d3d_rasterizer_state);
+    ID3D11SamplerState_Release(d3d->d3d_sampler_state);
+    ID3D11RenderTargetView_Release(d3d->d3d_render_target_view);
+    IDXGISwapChain1_SetFullscreenState(d3d->dxgi_swapchain, FALSE, NULL);
+    IDXGISwapChain1_Release(d3d->dxgi_swapchain);
+    ID3D11DeviceContext_Release(d3d->d3d_device_ctx);
+    ID3D11Device_Release(d3d->d3d_device);
+    IDXGIFactory2_Release(d3d->dxgi_factory);
+    free(d3d);
+
+#ifdef _DEBUG
+    ID3D11Debug_ReportLiveDeviceObjects(d3d_debug, D3D11_RLDO_DETAIL);
+    IDXGIDebug_ReportLiveObjects(dxgi_debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL);
+    ID3D11Debug_Release(d3d_debug);
+    IDXGIDebug_Release(dxgi_debug);
+#endif
+}
+
+void d3d_resize(D3d *d3d, int rot, UINT width, UINT height)
+{
+    D3D11_RENDER_TARGET_VIEW_DESC desc_rtv;
+    D3D11_MAPPED_SUBRESOURCE mapped;
+    ID3D11Texture2D *back_buffer;
+    HRESULT res;
+
+    FCT;
+
+    res = ID3D11DeviceContext_Map(d3d->d3d_device_ctx,
+                                  (ID3D11Resource *)d3d->d3d_const_buffer,
+                                  0U, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
+
+    if (FAILED(res))
+    {
+        printf("Map() failed\n");
+        fflush(stdout);
+        return;
+    }
+
+    switch (rot)
+    {
+        /*
+         * no rotation
+         *
+         * 1 0 0
+         * 0 1 0
+         */
+        case 0:
+            ((Const_Buffer *)mapped.pData)->rotation[0][0] = 1;
+            ((Const_Buffer *)mapped.pData)->rotation[0][1] = 0;
+            ((Const_Buffer *)mapped.pData)->rotation[0][2] = 0;
+            ((Const_Buffer *)mapped.pData)->rotation[1][0] = 0;
+            ((Const_Buffer *)mapped.pData)->rotation[1][1] = 1;
+            ((Const_Buffer *)mapped.pData)->rotation[1][2] = 0;
+            break;
+        /*
+         * rotation 90° clock-wise
+         *
+         * 0 -1 w-1
+         * 1  0 0
+         */
+        case 1:
+            ((Const_Buffer *)mapped.pData)->rotation[0][0] = 0;
+            ((Const_Buffer *)mapped.pData)->rotation[0][1] = -1;
+            ((Const_Buffer *)mapped.pData)->rotation[0][2] = width - 1;
+            ((Const_Buffer *)mapped.pData)->rotation[1][0] = 1;
+            ((Const_Buffer *)mapped.pData)->rotation[1][1] = 0;
+            ((Const_Buffer *)mapped.pData)->rotation[1][2] = 0;
+            break;
+        /*
+         * rotation 180° clock-wise
+         *
+         * -1  0 w-1
+         *  0 -1 h-1
+         */
+        case 2:
+            ((Const_Buffer *)mapped.pData)->rotation[0][0] = -1;
+            ((Const_Buffer *)mapped.pData)->rotation[0][1] = 0;
+            ((Const_Buffer *)mapped.pData)->rotation[0][2] = width - 1;
+            ((Const_Buffer *)mapped.pData)->rotation[1][0] = 0;
+            ((Const_Buffer *)mapped.pData)->rotation[1][1] = -1;
+            ((Const_Buffer *)mapped.pData)->rotation[1][2] = height - 1;
+            break;
+        /*
+         * rotation 270° clock-wise
+         *
+         *  0 1 0
+         * -1 0 h-1
+         */
+        case 3:
+            ((Const_Buffer *)mapped.pData)->rotation[0][0] = 0;
+            ((Const_Buffer *)mapped.pData)->rotation[0][1] = 1;
+            ((Const_Buffer *)mapped.pData)->rotation[0][2] = 0;
+            ((Const_Buffer *)mapped.pData)->rotation[1][0] = -1;
+            ((Const_Buffer *)mapped.pData)->rotation[1][1] = 0;
+            ((Const_Buffer *)mapped.pData)->rotation[1][2] = height - 1;
+            break;
+    }
+    ((Const_Buffer *)mapped.pData)->ivps[0] = 1.0f / (float)width;
+    ((Const_Buffer *)mapped.pData)->ivps[1] = 1.0f / (float)height;
+
+    ID3D11DeviceContext_Unmap(d3d->d3d_device_ctx,
+                              (ID3D11Resource *)d3d->d3d_const_buffer,
+                              0U);
+
+    /* unset the render target view in the output merger */
+    ID3D11DeviceContext_OMSetRenderTargets(d3d->d3d_device_ctx,
+                                           0U, NULL, NULL);
+
+    /* release the render target view */
+    if (d3d->d3d_render_target_view)
+        ID3D11RenderTargetView_Release(d3d->d3d_render_target_view);
+
+    /* resize the internal nuffers of the swapt chain to the new size */
+    res = IDXGISwapChain1_ResizeBuffers(d3d->dxgi_swapchain,
+                                        0U, /* preserve buffer count */
+                                        width, height,
+                                        DXGI_FORMAT_UNKNOWN, /* preserve format */
+                                        0U);
+    if ((res == DXGI_ERROR_DEVICE_REMOVED) ||
+        (res == DXGI_ERROR_DEVICE_RESET) ||
+        (res == DXGI_ERROR_DRIVER_INTERNAL_ERROR))
+    {
+        return;
+    }
+
+    if (FAILED(res))
+    {
+        printf("ResizeBuffers() failed\n");
+        fflush(stdout);
+        return;
+    }
+
+    /* get the internal buffer of the swap chain */
+    res = IDXGISwapChain1_GetBuffer(d3d->dxgi_swapchain, 0,
+                                    &IID_ID3D11Texture2D,
+                                    (void **)&back_buffer);
+    if (FAILED(res))
+    {
+        printf("swapchain GetBuffer() failed\n");
+        fflush(stdout);
+        return;
+    }
+
+    ZeroMemory(&desc_rtv, sizeof(D3D11_RENDER_TARGET_VIEW_DESC));
+    desc_rtv.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+    desc_rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+
+    /* create the new render target view from this internal buffer */
+    res = ID3D11Device_CreateRenderTargetView(d3d->d3d_device,
+                                              (ID3D11Resource *)back_buffer,
+                                              &desc_rtv,
+                                              &d3d->d3d_render_target_view);
+
+    DBG_NAME(ID3D11Device, d3d->d3d_render_target_view, "Render Target View resized");
+
+    ID3D11Texture2D_Release(back_buffer);
+
+    /* update the pipeline with the new render target view */
+    ID3D11DeviceContext_OMSetRenderTargets(d3d->d3d_device_ctx,
+                                           1U, &d3d->d3d_render_target_view,
+                                           NULL);
+
+    /* set viewport, depends on size of the window */
+    d3d->viewport.TopLeftX = 0.0f;
+    d3d->viewport.TopLeftY = 0.0f;
+    d3d->viewport.Width = (float)width;
+    d3d->viewport.Height = (float)height;
+    d3d->viewport.MinDepth = 0.0f;
+    d3d->viewport.MaxDepth = 1.0f;
+
+    /* update the pipeline with the new viewport */
+    ID3D11DeviceContext_RSSetViewports(d3d->d3d_device_ctx,
+                                       1U, &d3d->viewport);
+}
+
+/*** texture_data ***/
+
+unsigned int *data_new(int w, int h)
+{
+    unsigned int *d;
+    unsigned int *iter;
+    int i;
+    int j;
+
+    d = malloc(w * h * sizeof(unsigned int));
+    if (!d)
+        return NULL;
+
+    iter = d;
+    for (j = 0; j < h; j++)
+    {
+        if (j < h/2)
+        {
+            /* red, otherwise green */
+            for (i = 0; i < w; i++, iter++)
+                *iter = (i < w/2) ? 0xffff0000 : 0xff00ff00;
+        }
+        else
+        {
+            /* blue, otherwise yellow */
+            for (i = 0; i < w; i++, iter++)
+                *iter = (i < w/2) ? 0xff0000ff : 0xffffff00;
+        }
+    }
+
+    /* pink on corners, coords (i,j) --> i*h+j */
+    d[0] = 0xffff00ff;
+    d[w -1] = 0xffff00ff;
+    d[w * (h - 1)] = 0xffff00ff;
+    d[w * h - 1] = 0xffff7f00;
+
+    return d;
+}
+
+/*** texture ***/
+
+Object *texture_new(D3d *d3d,
+                    int x, int y,
+                    int w, int h,
+                    unsigned int *img)
+{
+    Vertex vertices[4];
+    unsigned int indices[6];
+    D3D11_BUFFER_DESC desc_buffer;
+    D3D11_TEXTURE2D_DESC desc_tex;
+    D3D11_SUBRESOURCE_DATA data_sr;
+    ID3D11Texture2D *tex;
+    Object *o;
+    HRESULT res;
+
+    o = (Object *)calloc(1, sizeof(Object));
+    if (!o)
+        return NULL;
+
+    /** vertex and index buffers **/
+
+    /* vertex upper left */
+    vertices[0].x = x;
+    vertices[0].y = y;
+    vertices[0].r = 0;
+    vertices[0].g = 0;
+    vertices[0].b = 0;
+    vertices[0].a = 0;
+    vertices[0].u = 0.0f;
+    vertices[0].v = 0.0f;
+    /* vertex upper right*/
+    vertices[1].x = x + w;
+    vertices[1].y = y;
+    vertices[1].r = 0;
+    vertices[1].g = 0;
+    vertices[1].b = 0;
+    vertices[1].a = 0;
+    vertices[0].u = 1.0f;
+    vertices[0].v = 0.0f;
+    /* vertex bottom right*/
+    vertices[2].x = x + w;
+    vertices[2].y = y + h;
+    vertices[2].r = 0;
+    vertices[2].g = 0;
+    vertices[2].b = 0;
+    vertices[2].a = 0;
+    vertices[0].u = 1.0f;
+    vertices[0].v = 1.0f;
+    /* vertex bottom left*/
+    vertices[3].x = x;
+    vertices[3].y = y + h;
+    vertices[3].r = 0;
+    vertices[3].g = 0;
+    vertices[3].b = 0;
+    vertices[3].a = 0;
+    vertices[0].u = 0.0f;
+    vertices[0].v = 1.0f;
+
+    /* triangle upper left */
+    indices[0] = 0;
+    indices[1] = 1;
+    indices[2] = 3;
+    /* triangle bottom right */
+    indices[3] = 1;
+    indices[4] = 2;
+    indices[5] = 3;
+
+    o->stride = sizeof(Vertex);
+    o->offset = 0U;
+    o->index_count = 6U;
+
+    desc_buffer.ByteWidth = sizeof(vertices);
+    desc_buffer.Usage = D3D11_USAGE_DYNAMIC;
+    desc_buffer.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+    desc_buffer.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    desc_buffer.MiscFlags = 0U;
+    desc_buffer.StructureByteStride = 0U;
+
+    data_sr.pSysMem = vertices;
+    data_sr.SysMemPitch = 0U;
+    data_sr.SysMemSlicePitch = 0U;
+
+    res =ID3D11Device_CreateBuffer(d3d->d3d_device,
+                                   &desc_buffer,
+                                   &data_sr,
+                                   &o->vertex_buffer);
+    if (FAILED(res))
+    {
+        goto free_o;
+    }
+
+    desc_buffer.ByteWidth = sizeof(indices);
+    desc_buffer.Usage = D3D11_USAGE_DYNAMIC;
+    desc_buffer.BindFlags = D3D11_BIND_INDEX_BUFFER;
+    desc_buffer.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    desc_buffer.MiscFlags = 0U;
+    desc_buffer.StructureByteStride = 0U;
+
+    data_sr.pSysMem = indices;
+    data_sr.SysMemPitch = 0U;
+    data_sr.SysMemSlicePitch = 0U;
+
+    res =ID3D11Device_CreateBuffer(d3d->d3d_device,
+                                   &desc_buffer,
+                                   &data_sr,
+                                   &o->index_buffer);
+    if (FAILED(res))
+    {
+        goto release_vertex_buffer;
+    }
+
+    /** texture 2D **/
+
+    desc_tex.Width = w;
+    desc_tex.Height = h;
+    desc_tex.MipLevels = 1;
+    desc_tex.ArraySize = 1;
+    desc_tex.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+    desc_tex.SampleDesc.Count = 1U;
+    desc_tex.SampleDesc.Quality = 0U;
+    desc_tex.Usage = D3D11_USAGE_DYNAMIC;
+    desc_tex.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+    desc_tex.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    desc_tex.MiscFlags = 0U;
+
+    data_sr.pSysMem = img;
+    data_sr.SysMemPitch = 4U * (unsigned int)w;
+    data_sr.SysMemSlicePitch = 0U; /* for 3D resources only */
+
+    tex = NULL;
+    res = ID3D11Device_CreateTexture2D(d3d->d3d_device,
+                                       &desc_tex,
+                                       &data_sr,
+                                       &tex);
+    if (FAILED(res))
+    {
+        goto release_index_buffer;
+    }
+
+    res = ID3D11Device_CreateShaderResourceView(d3d->d3d_device,
+                                                (ID3D11Resource *)tex,
+                                                NULL,
+                                                &o->texture_view);
+    if (FAILED(res))
+    {
+        goto release_texture;
+    }
+
+    o->type = OBJECT_TYPE_TEXTURE;
+
+    return o;
+
+  release_texture:
+    ID3D11Texture2D_Release(tex);
+  release_index_buffer:
+    ID3D11Buffer_Release(o->index_buffer);
+  release_vertex_buffer:
+    ID3D11Buffer_Release(o->vertex_buffer);
+  free_o:
+    free(o);
+    return NULL;
+}
+
+/*** rectangle ***/
+
+Object *rectangle_new(D3d *d3d,
+                      int x, int y,
+                      int w, int h,
+                      unsigned char r,
+                      unsigned char g,
+                      unsigned char b,
+                      unsigned char a)
+{
+    Vertex vertices[4];
+    unsigned int indices[6];
+    D3D11_BUFFER_DESC desc_buffer;
+    D3D11_SUBRESOURCE_DATA data_sr;
+    Object *o;
+    HRESULT res;
+
+    o = (Object *)calloc(1, sizeof(Object));
+    if (!o)
+        return NULL;
+
+    /* vertex upper left */
+    vertices[0].x = x;
+    vertices[0].y = y;
+    vertices[0].r = r;
+    vertices[0].g = g;
+    vertices[0].b = b;
+    vertices[0].a = a;
+    /* vertex upper right*/
+    vertices[1].x = x + w;
+    vertices[1].y = y;
+    vertices[1].r = r;
+    vertices[1].g = g;
+    vertices[1].b = b;
+    vertices[1].a = a;
+    /* vertex bottom right*/
+    vertices[2].x = x + w;
+    vertices[2].y = y + h;
+    vertices[2].r = r;
+    vertices[2].g = g;
+    vertices[2].b = b;
+    vertices[2].a = a;
+    /* vertex bottom left*/
+    vertices[3].x = x;
+    vertices[3].y = y + h;
+    vertices[3].r = r;
+    vertices[3].g = g;
+    vertices[3].b = b;
+    vertices[3].a = a;
+
+    /* triangle upper left */
+    indices[0] = 0;
+    indices[1] = 1;
+    indices[2] = 3;
+    /* triangle bottom right */
+    indices[3] = 1;
+    indices[4] = 2;
+    indices[5] = 3;
+
+    o->stride = sizeof(Vertex);
+    o->offset = 0U;
+    o->index_count = 6U;
+
+    desc_buffer.ByteWidth = sizeof(vertices);
+    desc_buffer.Usage = D3D11_USAGE_DYNAMIC;
+    desc_buffer.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+    desc_buffer.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    desc_buffer.MiscFlags = 0U;
+    desc_buffer.StructureByteStride = 0U;
+
+    data_sr.pSysMem = vertices;
+    data_sr.SysMemPitch = 0U;
+    data_sr.SysMemSlicePitch = 0U;
+
+    res =ID3D11Device_CreateBuffer(d3d->d3d_device,
+                                   &desc_buffer,
+                                   &data_sr,
+                                   &o->vertex_buffer);
+    if (FAILED(res))
+    {
+        free(o);
+        return NULL;
+    }
+
+    desc_buffer.ByteWidth = sizeof(indices);
+    desc_buffer.Usage = D3D11_USAGE_DYNAMIC;
+    desc_buffer.BindFlags = D3D11_BIND_INDEX_BUFFER;
+    desc_buffer.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    desc_buffer.MiscFlags = 0U;
+    desc_buffer.StructureByteStride = 0U;
+
+    data_sr.pSysMem = indices;
+    data_sr.SysMemPitch = 0U;
+    data_sr.SysMemSlicePitch = 0U;
+
+    res =ID3D11Device_CreateBuffer(d3d->d3d_device,
+                                   &desc_buffer,
+                                   &data_sr,
+                                   &o->index_buffer);
+    if (FAILED(res))
+    {
+        ID3D11Buffer_Release(o->vertex_buffer);
+        free(o);
+        return NULL;
+    }
+
+    o->type = OBJECT_TYPE_RECTANGLE;
+
+    return o;
+}
+
+void object_free(Object *o)
+{
+    if (!o)
+        return ;
+
+    if (o->texture_view)
+        ID3D11ShaderResourceView_Release(o->texture_view);
+    if (o->texture)
+        ID3D11Texture2D_Release(o->texture);
+    ID3D11Buffer_Release(o->index_buffer);
+    ID3D11Buffer_Release(o->vertex_buffer);
+    free(o);
+}
+
+void d3d_scene_begin(D3d *d3d)
+{
+    Object *o;
+    unsigned int *data;
+    int w, h;
+
+    w = 203;
+    h = 101;
+    data = "" h);
+
+    o = texture_new(d3d,
+                    220, 20,
+                    w, h,
+                    data);
+    objects[0] = o;
+
+    /* o = rectangle_new(d3d, */
+    /*                   520, 120, */
+    /*                   200, 100, */
+    /*                   0, 0, 255, 255); /\* r, g, b, a *\/ */
+    /* objects[1] = o; */
+}
+
+void d3d_scene_end(void)
+{
+    size_t i;
+
+    for (i = 0; i < sizeof(objects) / sizeof(Object *); i++)
+        object_free(objects[i]);
+}
+
+void d3d_render(D3d *d3d)
+{
+    DXGI_PRESENT_PARAMETERS pp;
+    const FLOAT color[4] = { 0.10f, 0.18f, 0.24f, 1.0f };
+    size_t i;
+    HRESULT res;
+
+    FCT;
+
+    /* clear render target */
+    ID3D11DeviceContext_ClearRenderTargetView(d3d->d3d_device_ctx,
+                                              d3d->d3d_render_target_view,
+                                              color);
+    /* Input Assembler (IA) stage */
+    ID3D11DeviceContext_IASetPrimitiveTopology(d3d->d3d_device_ctx,
+                                               D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+    ID3D11DeviceContext_IASetInputLayout(d3d->d3d_device_ctx,
+                                         d3d->d3d_input_layout);
+
+    /* vertex shader stage */
+    ID3D11DeviceContext_VSSetShader(d3d->d3d_device_ctx,
+                                    d3d->d3d_vertex_shader,
+                                    NULL,
+                                    0);
+    ID3D11DeviceContext_VSSetConstantBuffers(d3d->d3d_device_ctx,
+                                             0,
+                                             1,
+                                             &d3d->d3d_const_buffer);
+
+    /*
+     * Rasterizer Stage
+     *
+     * RSSetViewports() called in the resize() callback
+     */
+    ID3D11DeviceContext_RSSetState(d3d->d3d_device_ctx,
+                                   d3d->d3d_rasterizer_state);
+
+    /* pixel shader stage */
+    ID3D11DeviceContext_PSSetShader(d3d->d3d_device_ctx,
+                                    d3d->d3d_pixel_shader,
+                                    NULL,
+                                    0);
+    ID3D11DeviceContext_PSSetSamplers(d3d->d3d_device_ctx,
+                                      0,
+                                      1,
+                                      &d3d->d3d_sampler_state);
+
+    /*
+     * Output Merger stage
+     *
+     * OMSetRenderTargets() called in the resize() callback
+     */
+
+
+    for (i = 0; i < sizeof(objects) / sizeof(Object *); i++)
+    {
+        /* Input Assembler (IA) stage */
+        ID3D11DeviceContext_IASetVertexBuffers(d3d->d3d_device_ctx,
+                                               0,
+                                               1,
+                                               &objects[i]->vertex_buffer,
+                                               &objects[i]->stride,
+                                               &objects[i]->offset);
+        ID3D11DeviceContext_IASetIndexBuffer(d3d->d3d_device_ctx,
+                                             objects[i]->index_buffer,
+                                             DXGI_FORMAT_R32_UINT,
+                                             0);
+
+        /* pixel shader stage */
+        if (objects[i]->texture_view)
+            ID3D11DeviceContext_PSSetShaderResources(d3d->d3d_device_ctx,
+                                                     0,
+                                                     1,
+                                                     &objects[i]->texture_view);
+
+        /* draw */
+        ID3D11DeviceContext_DrawIndexed(d3d->d3d_device_ctx,
+                                        objects[i]->index_count,
+                                        0, 0);
+    }
+
+    /*
+     * present frame, that is, flip the back buffer and the front buffer
+     * if no vsync, we present immediatly
+     */
+    pp.DirtyRectsCount = 0;
+    pp.pDirtyRects = NULL;
+    pp.pScrollRect = NULL;
+    pp.pScrollOffset = NULL;
+    res = IDXGISwapChain1_Present1(d3d->dxgi_swapchain,
+                                   d3d->vsync ? 1 : 0, 0, &pp);
+    if (res == DXGI_ERROR_DEVICE_RESET || res == DXGI_ERROR_DEVICE_REMOVED)
+    {
+        printf("device removed or lost, need to recreate everything\n");
+        fflush(stdout);
+    }
+    else if (res == DXGI_STATUS_OCCLUDED)
+    {
+        printf("window is not visible, so vsync won't work. Let's sleep a bit to reduce CPU usage\n");
+        fflush(stdout);
+    }
+}
diff --git a/src/shader_7.hlsl b/src/shader_7.hlsl
new file mode 100644
index 0000000..3bb5865
--- /dev/null
+++ b/src/shader_7.hlsl
@@ -0,0 +1,41 @@
+cbuffer cv_viewport : register(b0)
+{
+    row_major int2x3 rotation_matrix;
+    float2 ivps;
+}
+
+struct vs_input
+{
+    uint2 position : POSITION;
+    float4 color : COLOR;
+    float2 uv : UV;
+};
+
+struct ps_input
+{
+    float4 position : SV_POSITION;
+    float4 color : COLOR;
+    float2 uv : UV;
+};
+
+ps_input main_vs(vs_input input )
+{
+    ps_input output;
+    float2 o = float2(mul(rotation_matrix, int3(input.position, 1))) * ivps;
+    o *= 2.0f;
+    o -= 1.0f;
+    o.y *= -1.0f;
+    output.position = float4(o, 0.0f, 1.0f);
+    output.color = input.color;
+    output.uv = input.uv;
+    return output;
+}
+
+Texture2D texture_ : register(t0);
+SamplerState sampler_ : register(s0);
+
+float4 main_ps(ps_input input) : SV_TARGET
+{
+    //return input.color;
+    return texture_.Sample(sampler_, input.uv);
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to