├── example ├── screenshot.png └── main.cpp ├── renderer.vcxproj.filters ├── renderer.sln ├── README.md ├── include ├── font.hpp ├── color.hpp ├── renderer.h └── renderer.cpp ├── .gitattributes ├── .gitignore └── renderer.vcxproj /example/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bulb4/renderer/HEAD/example/screenshot.png -------------------------------------------------------------------------------- /renderer.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | include 7 | 8 | 9 | 10 | 11 | {6bf1e545-4448-4a24-927b-9012dfc1b62f} 12 | 13 | 14 | 15 | 16 | include 17 | 18 | 19 | include 20 | 21 | 22 | include 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /renderer.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2042 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{D64122D2-48EB-4A94-B3FC-5451A1E2D240}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {D64122D2-48EB-4A94-B3FC-5451A1E2D240}.Debug|x64.ActiveCfg = Debug|x64 17 | {D64122D2-48EB-4A94-B3FC-5451A1E2D240}.Debug|x64.Build.0 = Debug|x64 18 | {D64122D2-48EB-4A94-B3FC-5451A1E2D240}.Debug|x86.ActiveCfg = Debug|Win32 19 | {D64122D2-48EB-4A94-B3FC-5451A1E2D240}.Debug|x86.Build.0 = Debug|Win32 20 | {D64122D2-48EB-4A94-B3FC-5451A1E2D240}.Release|x64.ActiveCfg = Release|x64 21 | {D64122D2-48EB-4A94-B3FC-5451A1E2D240}.Release|x64.Build.0 = Release|x64 22 | {D64122D2-48EB-4A94-B3FC-5451A1E2D240}.Release|x86.ActiveCfg = Release|Win32 23 | {D64122D2-48EB-4A94-B3FC-5451A1E2D240}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {DA715E33-9EB0-4FA5-A251-D303E62CFAF3} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Example 2 | 3 | [SOURCE \*click*](../master/example/main.cpp) 4 | ![alt text](../master/example/screenshot.png?raw=true "example illustration") 5 | 6 | ## Usage 7 | 8 | #### Include: 9 | ``` 10 | git submodule add https://github.com/Bulb4/renderer.git 11 | ``` 12 | 13 | ```java 14 | #include "..//renderer/include/renderer.h" 15 | ``` 16 | 17 | *** 18 | #### Initializing: 19 | If bUseDynamicSinCos is true, circle drawing will be faster but also it will take more memory. 20 | Use it if you do not change points count in runtime 21 | 22 | ```cpp 23 | cRender* pRender = new cRender(g_pd3dDevice, true);//g_pd3dDevice is our IDirect3DDevice9 24 | 25 | ID3DXFont* font1 = nullptr; 26 | pRender->AddFont(&font1, "Consolas", 48, false); 27 | 28 | pRender->SetFramerateUpdateRate(400U); 29 | ``` 30 | *** 31 | 32 | #### In your drawing function(EndScene, Present, etc.): 33 | ```cpp 34 | pRender->BeginDraw(); 35 | 36 | //drawing stuff 37 | 38 | pRender->EndDraw(); 39 | ``` 40 | *** 41 | #### In your Reset: 42 | ```cpp 43 | pRender->OnLostDevice(); 44 | 45 | if (g_pd3dDevice->Reset(&g_d3dpp) >= 0) 46 | pRender->OnResetDevice(); 47 | ``` 48 | *** 49 | #### Notes: 50 | * Use `pRender->GetFramerate()` for fps monitoring and you can change it's update rate by `pRender->SetFramerateUpdateRate(400U);//ms` 51 | * Use `pRender->PushRenderState(...)` if you need to use some render states while drawing, but you need to return it's previous value after. 52 | * Use `DrawBox(...)` without `short thickness` argument if the thickness is 1. 53 | 54 | *** 55 | ## Contacts: 56 | * Discord: `Bulb4#2901` 57 | * Steam: [`Bulb4<3`](https://steamcommunity.com/id/bulb4_/) 58 | * e-mail: `bulb4main@gmail.com` 59 | 60 | *** 61 | -------------------------------------------------------------------------------- /include/font.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "renderer.h" 4 | 5 | class cFont 6 | { 7 | public: 8 | cFont() { } 9 | cFont(IDirect3DDevice9* pDevice) 10 | { 11 | this->pDevice = pDevice; 12 | Update(); 13 | } 14 | cFont(IDirect3DDevice9* pDevice, const char* szName, uint8_t iSize) 15 | { 16 | sprintf(this->szName, szName); 17 | 18 | this->iSize = iSize; 19 | this->pDevice = pDevice; 20 | 21 | Update(); 22 | } 23 | cFont(IDirect3DDevice9* pDevice, const char* szName, uint8_t iSize, uint16_t iFontWeight, uint16_t iCharset, bool bItalic, bool bAntiAliased) 24 | { 25 | sprintf(this->szName, szName); 26 | 27 | this->iSize = iSize; 28 | this->iFontWeight = iFontWeight; 29 | this->iCharset = iCharset; 30 | this->bItalic = bItalic; 31 | this->bAntiAliased = bAntiAliased; 32 | this->pDevice = pDevice; 33 | 34 | Update(); 35 | } 36 | 37 | ~cFont() 38 | { 39 | RELEASE_INTERFACE(pFont); 40 | } 41 | 42 | IDirect3DDevice9* pDevice; 43 | char szName[32] = "System"; 44 | int32_t iSize = 14; 45 | //0, 100, 200 ... 1000 46 | uint32_t iFontWeight = FW_NORMAL; 47 | uint32_t iCharset = DEFAULT_CHARSET; 48 | bool bItalic = false; 49 | bool bAntiAliased = false; 50 | 51 | bool Update() 52 | { 53 | RELEASE_INTERFACE(pFont); 54 | 55 | return D3DXCreateFontA(pDevice, iSize, 0, 56 | iFontWeight, 1, BOOL(bItalic), iCharset, OUT_DEFAULT_PRECIS, 57 | bAntiAliased ? ANTIALIASED_QUALITY : NONANTIALIASED_QUALITY, 58 | DEFAULT_PITCH, szName, &pFont) == D3D_OK; 59 | } 60 | 61 | ID3DXFont* GetFont() { return pFont; } 62 | 63 | void OnLostDevice() 64 | { 65 | if (pFont) 66 | pFont->OnLostDevice(); 67 | } 68 | void OnResetDevice() 69 | { 70 | if (pFont) 71 | { 72 | pFont->OnResetDevice(); 73 | Update(); 74 | } 75 | } 76 | private: 77 | ID3DXFont* pFont = nullptr; 78 | }; -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /include/color.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #pragma comment(lib,"d3d9.lib") 5 | 6 | #include 7 | #include 8 | 9 | //rgba float[4] to color_t, it should be faster than color_t(float*) constructor 10 | #define PF2COL(color) reinterpret_cast(( \ 11 | (((color[3] * 255.f) & 0xff) << 24) | (((color[0] * 255.f) & 0xff) << 16) | \ 12 | (((color[1] * 255.f) & 0xff) << 8) | ((color[2] * 255.f) & 0xff))) 13 | 14 | struct color_t 15 | { 16 | D3DCOLOR color; 17 | 18 | inline uint8_t* a() { return reinterpret_cast(&color + 3); } 19 | inline uint8_t* r() { return reinterpret_cast(&color + 2); } 20 | inline uint8_t* g() { return reinterpret_cast(&color + 1); } 21 | inline uint8_t* b() { return reinterpret_cast(&color + 0); } 22 | 23 | inline const float get_a() { return *a() / 255.f; } 24 | inline const float get_r() { return *r() / 255.f; } 25 | inline const float get_g() { return *g() / 255.f; } 26 | inline const float get_b() { return *b() / 255.f; } 27 | 28 | inline void set_a(const float a) { reinterpret_cast(&color)[3] = static_cast(a * 255.f); } 29 | inline void set_r(const float r) { reinterpret_cast(&color)[2] = static_cast(r * 255.f); } 30 | inline void set_g(const float g) { reinterpret_cast(&color)[1] = static_cast(g * 255.f); } 31 | inline void set_b(const float b) { reinterpret_cast(&color)[0] = static_cast(b * 255.f); } 32 | 33 | color_t() : color(0) {} 34 | color_t(int value) : color(value) {} 35 | color_t(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 0xFF) : color(D3DCOLOR_RGBA(r, g, b, a)) {} 36 | color_t(float* value) : color(D3DCOLOR_COLORVALUE(value[0], value[1], value[2], value[3])) {} 37 | 38 | inline color_t& operator=(const int& rhs) 39 | { 40 | color = rhs; 41 | return *this; 42 | } 43 | inline color_t& operator=(const D3DCOLOR& rhs) 44 | { 45 | color = rhs; 46 | return *this; 47 | } 48 | inline color_t& operator=(const float* rhs) 49 | { 50 | color = D3DCOLOR_COLORVALUE(rhs[0], rhs[1], rhs[2], rhs[3]); 51 | return *this; 52 | } 53 | inline operator const D3DCOLOR() const { return color; } 54 | inline operator const uint8_t*() const { return (uint8_t*)this; } 55 | 56 | void SetHSV(float h, float s, float v, float a = 1.f) 57 | { 58 | if (s == 0.f)// gray 59 | { 60 | color = D3DCOLOR_COLORVALUE(v, v, v, a); 61 | return; 62 | } 63 | 64 | h = fmodf(h, 1.f) / (60.f / 360.f); 65 | 66 | const int i = static_cast(h); 67 | const float f = h - static_cast(i); 68 | const float q = v * (1.f - s * f); 69 | const float t = v * (1.f - s * (1.0f - f)); 70 | const float p = v * (1.f - s); 71 | 72 | float r, g, b; 73 | 74 | switch (i) 75 | { 76 | case 0: r = v; g = t; b = p; break; 77 | case 1: r = q; g = v; b = p; break; 78 | case 2: r = p; g = v; b = t; break; 79 | case 3: r = p; g = q; b = v; break; 80 | case 4: r = t; g = p; b = v; break; 81 | default: r = v; g = p; b = q; break; 82 | } 83 | 84 | color = D3DCOLOR_COLORVALUE(r, g, b, a); 85 | } 86 | }; 87 | 88 | #define DEF_COLOR(value, name) namespace Colors { static const color_t name = color_t(value); } 89 | 90 | DEF_COLOR(0xFF000000, Black); 91 | DEF_COLOR(0xFFFFFFFF, White); 92 | 93 | DEF_COLOR(0xFFFF0000, Red); 94 | DEF_COLOR(0xFF00FF00, Green); 95 | DEF_COLOR(0xFF0000FF, Blue); 96 | 97 | DEF_COLOR(0xFFFFFF00, Yellow); 98 | DEF_COLOR(0xFF00FFFF, SkyBlue); 99 | DEF_COLOR(0xFFFF00FF, Pink); -------------------------------------------------------------------------------- /include/renderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _CRT_SECURE_NO_WARNINGS 4 | #define _CRT_SECURE_NO_WARNINGS 5 | #endif // ! _CRT_SECURE_NO_WARNINGS 6 | 7 | #ifndef _USE_MATH_DEFINES 8 | #define _USE_MATH_DEFINES 9 | #endif // ! _USE_MATH_DEFINES 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #pragma comment(lib,"d3d9.lib") 20 | #pragma comment(lib,"d3dx9.lib") 21 | 22 | using std::vector; 23 | using std::map; 24 | using std::pair; 25 | 26 | #define RELEASE_INTERFACE(pInterface) if (pInterface) { pInterface->Release(); pInterface = nullptr; } 27 | 28 | #include "color.hpp" 29 | #include "font.hpp" 30 | 31 | 32 | enum RenderDrawType : uint32_t 33 | { 34 | RenderDrawType_None = 0, 35 | RenderDrawType_Outlined = 1 << 0, 36 | RenderDrawType_Filled = 1 << 1, 37 | RenderDrawType_Gradient = 1 << 2, 38 | RenderDrawType_OutlinedGradient = RenderDrawType_Outlined | RenderDrawType_Gradient, 39 | RenderDrawType_FilledGradient = RenderDrawType_Filled | RenderDrawType_Gradient 40 | }; 41 | 42 | 43 | class cRender 44 | { 45 | public: 46 | cRender(IDirect3DDevice9* device, bool bUseDynamicSinCos = false); 47 | ~cRender(); 48 | 49 | void BeginDraw(); 50 | void EndDraw(); 51 | 52 | void OnLostDevice(); 53 | void OnResetDevice(); 54 | 55 | inline void PushRenderState(const D3DRENDERSTATETYPE dwState, DWORD dwValue); 56 | 57 | //if outlined function become 5 times slower 58 | void DrawString(int16_t x, int16_t y, color_t color, cFont* font, bool outlined, bool centered, const char* text, ...); 59 | void DrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, color_t color); 60 | void DrawFilledBox(int16_t x, int16_t y, int16_t width, int16_t height, color_t color); 61 | //use DrawBox without thickness argument if thickness == 1 62 | void DrawBox(int16_t x, int16_t y, int16_t width, int16_t height, int16_t thickness, color_t color); 63 | void DrawBox(int16_t x, int16_t y, int16_t width, int16_t height, color_t color); 64 | void DrawGradientBox(int16_t x, int16_t y, int16_t width, int16_t height, color_t color1, color_t color2, color_t color3, color_t color4); 65 | //use RenderDrawType_Filled for filledcircle, RenderDrawType_Gradient for gradient circle and RenderDrawType_Outlined for outlined circle 66 | void DrawCircle(int16_t x, int16_t y, int16_t radius, uint16_t points, RenderDrawType flags, color_t color1, color_t color2); 67 | void DrawCircleSector(int16_t x, int16_t y, int16_t radius, uint16_t points, uint16_t angle1, uint16_t angle2, color_t color1, color_t color2); 68 | void DrawRing(int16_t x, int16_t y, int16_t radius1, int16_t radius2, uint16_t points, RenderDrawType flags, color_t color1, color_t color2); 69 | void DrawRingSector(int16_t x, int16_t y, int16_t radius1, int16_t radius2, uint16_t points, uint16_t angle1, uint16_t angle2, color_t color1, color_t color2); 70 | void DrawTriangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3, RenderDrawType flags, color_t color1, color_t color2, color_t color3); 71 | 72 | //frames per second 73 | int16_t GetFramerate() const { return m_iFramerate; } 74 | //milliseconds 75 | void SetFramerateUpdateRate(const uint16_t iUpdateRate) { m_iFramerateUpdateRate = iUpdateRate; } 76 | 77 | private: 78 | uint16_t m_iFramerate = 0, m_iFramerateUpdateRate = 1000; 79 | 80 | protected: 81 | struct SinCos_t 82 | { 83 | float flSin = 0.f, flCos = 0.f; 84 | }; 85 | 86 | struct RenderState_t 87 | { 88 | D3DRENDERSTATETYPE dwState; 89 | DWORD dwValue; 90 | }; 91 | 92 | struct Vertex_t 93 | { 94 | Vertex_t() { } 95 | 96 | Vertex_t(int _x, int _y, color_t _color) 97 | { 98 | x = static_cast(_x); 99 | y = static_cast(_y); 100 | z = 0; 101 | rhw = 1; 102 | color = _color.color; 103 | } 104 | 105 | Vertex_t(float _x, float _y, color_t _color) 106 | { 107 | x = _x; 108 | y = _y; 109 | z = 0; 110 | rhw = 1; 111 | color = _color.color; 112 | } 113 | 114 | float x, y, z, rhw; 115 | color_t color = 0; 116 | }; 117 | 118 | map m_SinCosContainer; 119 | //we dont need to calculate sin and cos every frame, we just calculate it one time 120 | SinCos_t* GetSinCos(uint16_t key) 121 | { 122 | if (!m_SinCosContainer.count(key)) 123 | { 124 | SinCos_t* temp_array = new SinCos_t[key + 1]; 125 | 126 | uint16_t i = 0; 127 | for (float angle = 0.0; angle <= 2 * D3DX_PI; angle += (2 * D3DX_PI) / key) 128 | temp_array[i++] = SinCos_t{ sin(angle), cos(angle) }; 129 | 130 | m_SinCosContainer.insert(pair(key, temp_array)); 131 | } 132 | 133 | return m_SinCosContainer[key]; 134 | } 135 | 136 | bool m_bUseDynamicSinCos; 137 | IDirect3DDevice9* m_pDevice; 138 | vector m_RenderStates; 139 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /example/main.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #define DIRECTINPUT_VERSION 0x0800 8 | #include 9 | #pragma comment(lib,"d3d9.lib") 10 | #include 11 | #include 12 | 13 | #include "../include/renderer.h" 14 | 15 | static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; 16 | static D3DPRESENT_PARAMETERS g_d3dpp; 17 | 18 | LPDIRECT3DTEXTURE9 pRadarTexture = nullptr; 19 | LPD3DXSPRITE pRadarSprite = nullptr; 20 | 21 | short GetUsageOfCPU() 22 | { 23 | const static HANDLE hCurrentProcess = GetCurrentProcess(); 24 | 25 | static DWORD dwNumberOfProcessors = 0; 26 | 27 | if (!dwNumberOfProcessors) 28 | { 29 | SYSTEM_INFO info; 30 | GetSystemInfo(&info); 31 | dwNumberOfProcessors = info.dwNumberOfProcessors; 32 | } 33 | 34 | FILETIME now, creation_time, exit_time, kernel_time, user_time; 35 | 36 | GetSystemTimeAsFileTime(&now); 37 | 38 | if (!GetProcessTimes(hCurrentProcess, &creation_time, &exit_time, &kernel_time, &user_time)) 39 | return -1; 40 | 41 | static auto QuadPartFt = [](const FILETIME* ft) -> uint64_t 42 | { 43 | LARGE_INTEGER li; 44 | li.LowPart = ft->dwLowDateTime; 45 | li.HighPart = ft->dwHighDateTime; 46 | 47 | return li.QuadPart; 48 | }; 49 | 50 | const int64_t system_time = (QuadPartFt(&kernel_time) + QuadPartFt(&user_time)) / dwNumberOfProcessors; 51 | const int64_t time = QuadPartFt(&now); 52 | 53 | static int64_t last_system_time = 0, last_time = 0; 54 | 55 | if (!last_system_time || !last_time) 56 | { 57 | last_system_time = system_time; 58 | last_time = time; 59 | return -1; 60 | } 61 | 62 | const int64_t time_delta = time - last_time; 63 | 64 | if (!time_delta) 65 | return -1; 66 | 67 | const auto ret = short(((system_time - last_system_time) * 100 + time_delta / 2) / time_delta); 68 | 69 | last_system_time = system_time; 70 | last_time = time; 71 | 72 | return ret; 73 | } 74 | 75 | LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 76 | { 77 | switch (msg) 78 | { 79 | case WM_DESTROY: 80 | PostQuitMessage(0); 81 | return 0; 82 | } 83 | 84 | return DefWindowProc(hWnd, msg, wParam, lParam); 85 | } 86 | 87 | int CALLBACK WinMain( 88 | _In_ HINSTANCE, _In_ HINSTANCE, 89 | _In_ LPSTR, _In_ int) 90 | { 91 | #define WINDOW_NAME "DirectX9 Example" 92 | 93 | WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, WINDOW_NAME, NULL }; 94 | RegisterClassEx(&wc); 95 | HWND hwnd = CreateWindow(WINDOW_NAME, "DirectX 9 Test", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 720, NULL, NULL, wc.hInstance, NULL); 96 | 97 | LPDIRECT3D9 pD3D; 98 | if ((pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) 99 | { 100 | UnregisterClass(WINDOW_NAME, wc.hInstance); 101 | return 0; 102 | } 103 | 104 | ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); 105 | g_d3dpp.Windowed = TRUE; 106 | g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 107 | g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; 108 | g_d3dpp.EnableAutoDepthStencil = TRUE; 109 | g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 110 | g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//D3DPRESENT_INTERVAL_ONE; 111 | 112 | if (pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0) 113 | { 114 | pD3D->Release(); 115 | UnregisterClass(WINDOW_NAME, wc.hInstance); 116 | return 0; 117 | } 118 | 119 | D3DADAPTER_IDENTIFIER9 AdapterIdentifier; 120 | pD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &AdapterIdentifier); 121 | 122 | SYSTEM_INFO info; 123 | GetSystemInfo(&info); 124 | 125 | 126 | MSG msg; 127 | ZeroMemory(&msg, sizeof(msg)); 128 | ShowWindow(hwnd, SW_SHOWDEFAULT); 129 | UpdateWindow(hwnd); 130 | 131 | cRender* pRender = new cRender(g_pd3dDevice, true); 132 | 133 | cFont font1(g_pd3dDevice, "System", 24); 134 | 135 | pRender->SetFramerateUpdateRate(400U); 136 | 137 | while (msg.message != WM_QUIT) 138 | { 139 | if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) 140 | { 141 | TranslateMessage(&msg); 142 | DispatchMessage(&msg); 143 | continue; 144 | } 145 | 146 | g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false); 147 | g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false); 148 | g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false); 149 | 150 | g_pd3dDevice->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(100, 150, 240), 1.0f, 0); 151 | 152 | if (g_pd3dDevice->BeginScene() >= 0) 153 | { 154 | static float time = 0; 155 | 156 | time += 0.05f; 157 | 158 | if (time > 360.f) 159 | time -= 360.f; 160 | 161 | const uint8_t size = 3; 162 | color_t rainbow_color[size]; 163 | 164 | for (uint8_t i = 1; i <= size; i++) 165 | rainbow_color[i - 1].SetHSV(time / 360.f + 1.f / i, 1.f, 1.f); 166 | 167 | pRender->BeginDraw(); 168 | pRender->PushRenderState(D3DRS_ANTIALIASEDLINEENABLE, TRUE); 169 | 170 | pRender->DrawLine(20, 10, 880, 10, Colors::Black); 171 | 172 | pRender->DrawBox(20, 20, 200, 50, Colors::White); 173 | pRender->DrawFilledBox(240, 20, 200, 50, 0x8000CCCC); 174 | pRender->DrawGradientBox(460, 20, 200, 50, rainbow_color[0], rainbow_color[1], rainbow_color[2], rainbow_color[3]); 175 | pRender->DrawBox(680, 20, 200, 50, 8, Colors::Pink); 176 | 177 | pRender->DrawCircle(120, 190, 100, 32, RenderDrawType_Outlined, Colors::Red, 0); 178 | pRender->DrawCircle(340, 190, 100, 32, RenderDrawType_Filled, Colors::Green, 0); 179 | pRender->DrawCircle(560, 190, 100, 32, RenderDrawType_Gradient, rainbow_color[0], rainbow_color[1]); 180 | 181 | pRender->DrawRing(780, 190, 100, 80, 64, RenderDrawType_Filled, Colors::Blue, 0); 182 | 183 | pRender->DrawTriangle(120, 310, 20, 480, 220, 480, RenderDrawType_Outlined, Colors::Green, 0, 0); 184 | pRender->DrawTriangle(340, 310, 240, 480, 440, 480, RenderDrawType_Filled, Colors::SkyBlue, 0, 0); 185 | pRender->DrawTriangle(560, 310, 460, 480, 660, 480, RenderDrawType_FilledGradient, rainbow_color[0], rainbow_color[1], rainbow_color[2]); 186 | 187 | pRender->DrawCircleSector(780, 380, 80, 30, time, time + 45, rainbow_color[0], rainbow_color[1]); 188 | pRender->DrawRingSector(780, 380, 65, 80, 30, time + 180, time + 225, rainbow_color[2], rainbow_color[2]); 189 | 190 | //text panel 191 | { 192 | static int cpu_usage = 0; 193 | static uint16_t last_fps = 0; 194 | 195 | const uint16_t current_fps = pRender->GetFramerate(); 196 | 197 | if (last_fps != current_fps) 198 | cpu_usage = GetUsageOfCPU(); 199 | 200 | last_fps = current_fps; 201 | 202 | pRender->DrawString( 203 | 900, 10, Colors::White, &font1, true, false, 204 | "CPU: %i%%\nFPS: %d\nCPU Cores: %i\n%s", 205 | cpu_usage, current_fps, 206 | info.dwNumberOfProcessors, 207 | AdapterIdentifier.Description); 208 | } 209 | 210 | pRender->EndDraw(); 211 | 212 | g_pd3dDevice->EndScene(); 213 | } 214 | 215 | if (g_pd3dDevice->Present(NULL, NULL, NULL, NULL) == D3DERR_DEVICELOST && 216 | g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) 217 | { 218 | pRender->OnLostDevice(); 219 | 220 | if (g_pd3dDevice->Reset(&g_d3dpp) >= 0) 221 | pRender->OnResetDevice(); 222 | } 223 | } 224 | 225 | delete pRender; 226 | 227 | if (g_pd3dDevice) 228 | g_pd3dDevice->Release(); 229 | 230 | if (pD3D) 231 | pD3D->Release(); 232 | 233 | DestroyWindow(hwnd); 234 | UnregisterClass(WINDOW_NAME, wc.hInstance); 235 | 236 | return 0; 237 | } -------------------------------------------------------------------------------- /renderer.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {D64122D2-48EB-4A94-B3FC-5451A1E2D240} 24 | renderer 25 | 10.0.17134.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v141 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v141 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v141 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v141 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | $(VC_IncludePath);$(WindowsSDK_IncludePath);E:\Programms\Microsoft DirectX SDK (June 2010)\Include 74 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;E:\Programms\Microsoft DirectX SDK (June 2010)\Lib\x86 75 | 76 | 77 | $(VC_IncludePath);$(WindowsSDK_IncludePath);E:\Programms\Microsoft DirectX SDK (June 2010)\Include 78 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;E:\Programms\Microsoft DirectX SDK (June 2010)\Lib\x86 79 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;E:\Programms\Microsoft DirectX SDK (June 2010)\Lib\x86 80 | 81 | 82 | $(VC_IncludePath);$(WindowsSDK_IncludePath);E:\Programms\Microsoft DirectX SDK (June 2010)\Include 83 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64E:\Programms\Microsoft DirectX SDK (June 2010)\Lib\x64 84 | 85 | 86 | $(VC_IncludePath);$(WindowsSDK_IncludePath);E:\Programms\Microsoft DirectX SDK (June 2010)\Include 87 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;E:\Programms\Microsoft DirectX SDK (June 2010)\Lib\x64 88 | 89 | 90 | 91 | Level3 92 | Disabled 93 | true 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | Disabled 101 | true 102 | true 103 | 104 | 105 | 106 | 107 | Level3 108 | MaxSpeed 109 | true 110 | true 111 | true 112 | true 113 | Speed 114 | 115 | 116 | true 117 | true 118 | 119 | 120 | 121 | 122 | Level3 123 | MaxSpeed 124 | true 125 | true 126 | true 127 | true 128 | 129 | 130 | true 131 | true 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /include/renderer.cpp: -------------------------------------------------------------------------------- 1 | #include "renderer.h" 2 | 3 | cRender::cRender(IDirect3DDevice9* device, bool bUseDynamicSinCos) : 4 | m_bUseDynamicSinCos(bUseDynamicSinCos) 5 | { 6 | if (!device) 7 | throw std::exception("device == nullptr"); 8 | 9 | m_pDevice = device; 10 | } 11 | 12 | cRender::~cRender() 13 | { 14 | for (auto i = m_SinCosContainer.begin(); i != m_SinCosContainer.end(); i++) 15 | { 16 | delete[] i->second; 17 | i->second = nullptr; 18 | } 19 | 20 | m_pDevice = nullptr; 21 | } 22 | 23 | void cRender::BeginDraw() 24 | { 25 | PushRenderState(D3DRS_COLORWRITEENABLE, 0xFFFFFFFF); 26 | PushRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 27 | PushRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 28 | PushRenderState(D3DRS_ALPHABLENDENABLE, TRUE); 29 | PushRenderState(D3DRS_ZENABLE, D3DZB_FALSE); 30 | PushRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 31 | PushRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); 32 | PushRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); 33 | 34 | m_pDevice->SetTexture(0, NULL); 35 | m_pDevice->SetPixelShader(NULL); 36 | 37 | m_pDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); 38 | } 39 | 40 | void cRender::EndDraw() 41 | { 42 | //pop render states 43 | for (auto a : m_RenderStates) 44 | m_pDevice->SetRenderState(a.dwState, a.dwValue); 45 | 46 | m_RenderStates.clear(); 47 | 48 | //framerate calculator 49 | const DWORD dwCurrentTime = GetTickCount(); 50 | static DWORD dwLastUpdateTime = 0, dwElapsedTime = 0; 51 | 52 | dwElapsedTime = dwCurrentTime - dwLastUpdateTime; 53 | 54 | static int16_t iFrames = 0; 55 | iFrames++; 56 | 57 | if (dwElapsedTime >= m_iFramerateUpdateRate) 58 | { 59 | m_iFramerate = int16_t(iFrames * 1000.f / dwElapsedTime); 60 | iFrames = 0; 61 | dwLastUpdateTime = dwCurrentTime; 62 | } 63 | } 64 | 65 | void cRender::PushRenderState(const D3DRENDERSTATETYPE dwState, DWORD dwValue) 66 | { 67 | DWORD dwTempValue; 68 | m_pDevice->GetRenderState(dwState, &dwTempValue); 69 | m_RenderStates.push_back({ dwState, dwTempValue }); 70 | m_pDevice->SetRenderState(dwState, dwValue); 71 | } 72 | 73 | void cRender::OnLostDevice() { } 74 | void cRender::OnResetDevice() { } 75 | 76 | void cRender::DrawString(int16_t x, int16_t y, color_t color, cFont* font, bool outlined, bool centered, const char* text, ...) 77 | { 78 | va_list args; 79 | char buf[256]; 80 | va_start(args, text); 81 | vsprintf_s(buf, text, args); 82 | va_end(args); 83 | 84 | const size_t size = strlen(buf); 85 | 86 | RECT rect = { x, y }; 87 | 88 | if (centered) 89 | { 90 | RECT size_rect = { 0 }; 91 | font->GetFont()->DrawTextA(NULL, buf, size, &size_rect, DT_CALCRECT | DT_NOCLIP, 0); 92 | 93 | rect.left -= size_rect.right / 2; 94 | rect.top -= size_rect.bottom / 2; 95 | } 96 | 97 | if (outlined) 98 | { 99 | //black with alpha from "color" 100 | auto outline_color = static_cast((color.color >> 24) << 24); 101 | 102 | rect.top++; 103 | font->GetFont()->DrawTextA(NULL, buf, size, &rect, DT_NOCLIP, outline_color);//x; y + 1 104 | rect.left++; rect.top--; 105 | font->GetFont()->DrawTextA(NULL, buf, size, &rect, DT_NOCLIP, outline_color);//x + 1; y 106 | rect.left--; rect.top--; 107 | font->GetFont()->DrawTextA(NULL, buf, size, &rect, DT_NOCLIP, outline_color);//x; y - 1 108 | rect.left--; rect.top++; 109 | font->GetFont()->DrawTextA(NULL, buf, size, &rect, DT_NOCLIP, outline_color);//x - 1; y 110 | rect.left++; 111 | } 112 | 113 | font->GetFont()->DrawTextA(NULL, buf, size, &rect, DT_NOCLIP, color); 114 | } 115 | 116 | void cRender::DrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, color_t color) 117 | { 118 | Vertex_t pVertex[2]; 119 | pVertex[0] = Vertex_t(x1, y1, color); 120 | pVertex[1] = Vertex_t(x2, y2, color); 121 | 122 | m_pDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, pVertex, sizeof(Vertex_t)); 123 | } 124 | 125 | void cRender::DrawFilledBox(int16_t x, int16_t y, int16_t width, int16_t height, color_t color) 126 | { 127 | Vertex_t pVertex[4]; 128 | pVertex[0] = Vertex_t(x, y, color); 129 | pVertex[1] = Vertex_t(x + width, y, color); 130 | pVertex[2] = Vertex_t(x, y + height, color); 131 | pVertex[3] = Vertex_t(x + width, y + height, color); 132 | 133 | m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertex, sizeof(Vertex_t)); 134 | } 135 | 136 | void cRender::DrawBox(int16_t x, int16_t y, int16_t width, int16_t height, int16_t thickness, color_t color) 137 | { 138 | DrawFilledBox(x, y, width, thickness, color); 139 | DrawFilledBox(x, y, thickness, height, color); 140 | DrawFilledBox(x + width - thickness, y, thickness, height, color); 141 | DrawFilledBox(x, y + height - thickness, width, thickness, color); 142 | } 143 | 144 | void cRender::DrawBox(int16_t x, int16_t y, int16_t width, int16_t height, color_t color) 145 | { 146 | Vertex_t pVertex[5]; 147 | 148 | pVertex[0] = Vertex_t(x, y, color); 149 | pVertex[1] = Vertex_t(x + width, y, color); 150 | pVertex[2] = Vertex_t(x + width, y + height, color); 151 | pVertex[3] = Vertex_t(x, y + height, color); 152 | pVertex[4] = pVertex[0]; 153 | 154 | m_pDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, 4, pVertex, sizeof(Vertex_t)); 155 | } 156 | 157 | void cRender::DrawGradientBox(int16_t x, int16_t y, int16_t width, int16_t height, color_t color1, color_t color2, color_t color3, color_t color4) 158 | { 159 | Vertex_t pVertex[4]; 160 | pVertex[0] = Vertex_t(x, y, color1); 161 | pVertex[1] = Vertex_t(x + width, y, color2); 162 | pVertex[2] = Vertex_t(x, y + height, color3); 163 | pVertex[3] = Vertex_t(x + width, y + height, color4); 164 | 165 | m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertex, sizeof(Vertex_t)); 166 | } 167 | 168 | void cRender::DrawCircle(int16_t x, int16_t y, int16_t radius, uint16_t points, RenderDrawType flags, color_t color1, color_t color2) 169 | { 170 | const bool gradient = (flags & RenderDrawType_Gradient); 171 | const bool filled = (flags & RenderDrawType_Filled) || gradient; 172 | 173 | Vertex_t* verticles = new Vertex_t[points + gradient + 1]; 174 | 175 | SinCos_t* pSinCos = m_bUseDynamicSinCos ? nullptr : GetSinCos(points); 176 | 177 | if (gradient) 178 | verticles[0] = Vertex_t(x, y, color2); 179 | 180 | for (uint16_t i = gradient; i < points + gradient; i++) 181 | { 182 | if (m_bUseDynamicSinCos) 183 | { 184 | const float angle = (2 * D3DX_PI) / points * (i - gradient); 185 | verticles[i] = Vertex_t(x + cos(angle) *radius, y + sin(angle) * radius, color1); 186 | } 187 | else 188 | { 189 | verticles[i] = Vertex_t(x + pSinCos[i - gradient].flCos * radius, y + pSinCos[i - gradient].flSin * radius, color1); 190 | } 191 | 192 | if (filled) 193 | { 194 | static const float angle = D3DX_PI / 180.f, flSin = sin(angle), flCos = cos(angle); 195 | 196 | verticles[i - gradient].x = static_cast(x + flCos * (verticles[i - gradient].x - x) - flSin * (verticles[i - gradient].y - y)); 197 | verticles[i - gradient].y = static_cast(y + flSin * (verticles[i - gradient].x - x) + flCos * (verticles[i - gradient].y - y)); 198 | } 199 | } 200 | 201 | verticles[points + gradient] = verticles[gradient]; 202 | 203 | m_pDevice->DrawPrimitiveUP( 204 | (flags & RenderDrawType_Outlined) ? D3DPT_LINESTRIP : 205 | filled ? D3DPT_TRIANGLEFAN :D3DPT_POINTLIST, 206 | points, verticles, sizeof(Vertex_t)); 207 | 208 | delete[] verticles; 209 | } 210 | 211 | void cRender::DrawCircleSector(int16_t x, int16_t y, int16_t radius, uint16_t points, uint16_t angle1, uint16_t angle2, color_t color1, color_t color2) 212 | { 213 | angle1 += 270; 214 | angle2 += 270; 215 | 216 | if (angle1 > angle2) 217 | angle2 += 360; 218 | 219 | Vertex_t* verticles = new Vertex_t[points + 2]; 220 | 221 | const float stop = 2 * D3DX_PI * static_cast(angle2) / 360.f; 222 | verticles[points + 1] = Vertex_t(x + cos(stop) * radius, y + sin(stop) * radius, color1); 223 | verticles[0] = Vertex_t(x, y, color2); 224 | 225 | float angle = 2 * D3DX_PI * static_cast(angle1) / 360.f; 226 | const float step = ((2 * D3DX_PI * static_cast(angle2) / 360.f) - angle) / points; 227 | 228 | for (uint16_t i = 1; i != points + 1; angle += step, i++) 229 | verticles[i] = Vertex_t(x + cos(angle) * radius, y + sin(angle) * radius, color1); 230 | 231 | m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, points, verticles, sizeof(Vertex_t)); 232 | delete[] verticles; 233 | } 234 | 235 | void cRender::DrawRing(int16_t x, int16_t y, int16_t radius1, int16_t radius2, uint16_t points, RenderDrawType flags, color_t color1, color_t color2) 236 | { 237 | if (!(flags & RenderDrawType_Gradient)) 238 | color2 = color1; 239 | 240 | if (flags & RenderDrawType_Outlined) 241 | { 242 | DrawCircle(x, y, radius1, points, RenderDrawType_Outlined, color1, 0); 243 | DrawCircle(x, y, radius2, points, RenderDrawType_Outlined, color2, 0); 244 | return; 245 | } 246 | 247 | constexpr uint8_t modifier = 4; 248 | Vertex_t* verticles = new Vertex_t[points * modifier]; 249 | 250 | SinCos_t* pSinCos = m_bUseDynamicSinCos ? nullptr : GetSinCos(points); 251 | 252 | for (uint16_t i = 0; i < points; i++) 253 | { 254 | uint16_t it = i * modifier; 255 | 256 | if (m_bUseDynamicSinCos) 257 | { 258 | const float angle1 = (2 * D3DX_PI) / points * i; 259 | const float angle2 = (2 * D3DX_PI) / points * (i + 1); 260 | 261 | verticles[it] = Vertex_t(x + cos(angle1) * radius1, y + sin(angle1) * radius1, color1); 262 | verticles[it + 1] = Vertex_t(x + cos(angle1) * radius2, y + sin(angle1) * radius2, color2); 263 | verticles[it + 2] = Vertex_t(x + cos(angle2) * radius1, y + sin(angle2) * radius1, color1); 264 | verticles[it + 3] = Vertex_t(x + cos(angle2) * radius2, y + sin(angle2) * radius2, color2); 265 | } 266 | else 267 | { 268 | verticles[it] = Vertex_t(x + pSinCos[i].flCos * radius1, y + pSinCos[i].flSin * radius1, color1); 269 | verticles[it + 1] = Vertex_t(x + pSinCos[i].flCos * radius2, y + pSinCos[i].flSin * radius2, color2); 270 | verticles[it + 2] = Vertex_t(x + pSinCos[i + 1].flCos * radius1, y + pSinCos[i + 1].flSin * radius1, color1); 271 | verticles[it + 3] = Vertex_t(x + pSinCos[i + 1].flCos * radius2, y + pSinCos[i + 1].flSin * radius2, color2); 272 | } 273 | 274 | for (uint8_t a = 0; a < modifier; a++) 275 | { 276 | static const float angle = D3DX_PI / 180.f, flSin = sin(angle), flCos = cos(angle); 277 | 278 | verticles[it].x = static_cast(x + flCos * (verticles[it].x - x) - flSin * (verticles[it].y - y)); 279 | verticles[it].y = static_cast(y + flSin * (verticles[it].x - x) + flCos * (verticles[it].y - y)); 280 | 281 | ++it; 282 | } 283 | } 284 | 285 | --points; 286 | 287 | verticles[points * modifier] = verticles[0]; 288 | verticles[points * modifier + 1] = verticles[1]; 289 | 290 | m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, points * modifier, verticles, sizeof(Vertex_t)); 291 | delete[] verticles; 292 | } 293 | 294 | void cRender::DrawRingSector(int16_t x, int16_t y, int16_t radius1, int16_t radius2, uint16_t points, uint16_t angle1, uint16_t angle2, color_t color1, color_t color2) 295 | { 296 | angle1 += 270; 297 | angle2 += 270; 298 | 299 | if (angle1 > angle2) 300 | angle2 += 360; 301 | 302 | const uint8_t modifier = 4; 303 | Vertex_t* verticles = new Vertex_t[points * modifier]; 304 | 305 | const float start = 2 * D3DX_PI * angle1 / 360.f; 306 | const float stop = 2 * D3DX_PI * angle2 / 360.f; 307 | const float step = (stop - start) / points; 308 | 309 | SinCos_t sincos[2] = { sin(start), cos(start) }; 310 | 311 | for (uint16_t i = 0; i < points; i++) 312 | { 313 | const float temp_angle = start + step * i; 314 | sincos[!(i % 2)] = { sin(temp_angle + step), cos(temp_angle + step) }; 315 | 316 | const uint16_t it = i * modifier; 317 | 318 | verticles[it] = Vertex_t(x + sincos[0].flCos * radius1, y + sincos[0].flSin * radius1, color1); 319 | verticles[it + 1] = Vertex_t(x + sincos[1].flCos * radius2, y + sincos[1].flSin * radius2, color2); 320 | verticles[it + 2] = verticles[it]; 321 | verticles[it + 3] = verticles[it + 1]; 322 | } 323 | 324 | --points; 325 | 326 | verticles[0] = Vertex_t(x, y, color2); 327 | verticles[1] = Vertex_t(x + cos(start) * radius2, y + sin(start) * radius2, color2); 328 | verticles[points * modifier] = Vertex_t(x + cos(stop) * radius1 + 1, y + sin(stop) * radius1, color1); 329 | verticles[points * modifier + 1] = Vertex_t(x + cos(stop) * radius2 + 1, y + sin(stop) * radius2, color2); 330 | 331 | m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, points * modifier, verticles, sizeof(Vertex_t)); 332 | delete[] verticles; 333 | } 334 | 335 | void cRender::DrawTriangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3, RenderDrawType flags, color_t color1, color_t color2, color_t color3) 336 | { 337 | if (!(flags & RenderDrawType_Gradient)) 338 | { 339 | color2 = color1; 340 | color3 = color1; 341 | } 342 | 343 | Vertex_t pVertex[4]; 344 | pVertex[0] = Vertex_t(x1, y1, color1); 345 | pVertex[1] = Vertex_t(x2, y2, color2); 346 | pVertex[2] = Vertex_t(x3, y3, color3); 347 | pVertex[3] = pVertex[0]; 348 | 349 | m_pDevice->DrawPrimitiveUP( 350 | (flags & RenderDrawType_Outlined) ? D3DPT_LINESTRIP : 351 | (flags & RenderDrawType_Filled) ? D3DPT_TRIANGLEFAN : 352 | D3DPT_POINTLIST, 3, pVertex, sizeof(Vertex_t)); 353 | } --------------------------------------------------------------------------------