połączenie "widok" z "master" i drobne zmiany

This commit is contained in:
Kacper 2024-01-14 22:38:12 +01:00
commit 50d6283291
302 changed files with 107778 additions and 3063 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
################################################################################
# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
################################################################################
/.vs
/grk/.vs

BIN
grk/Debug/Planeta.exe Normal file

Binary file not shown.

BIN
grk/Debug/Planeta.pdb Normal file

Binary file not shown.

273
grk/UpgradeLog.htm Normal file
View File

@ -0,0 +1,273 @@
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html xmlns:msxsl="urn:schemas-microsoft-com:xslt"><head><meta content="en-us" http-equiv="Content-Language" /><meta content="text/html; charset=utf-16" http-equiv="Content-Type" /><title _locID="ConversionReport0">
Migration Report
</title><style>
/* Body style, for the entire document */
body
{
background: #F3F3F4;
color: #1E1E1F;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
padding: 0;
margin: 0;
}
/* Header1 style, used for the main title */
h1
{
padding: 10px 0px 10px 10px;
font-size: 21pt;
background-color: #E2E2E2;
border-bottom: 1px #C1C1C2 solid;
color: #201F20;
margin: 0;
font-weight: normal;
}
/* Header2 style, used for "Overview" and other sections */
h2
{
font-size: 18pt;
font-weight: normal;
padding: 15px 0 5px 0;
margin: 0;
}
/* Header3 style, used for sub-sections, such as project name */
h3
{
font-weight: normal;
font-size: 15pt;
margin: 0;
padding: 15px 0 5px 0;
background-color: transparent;
}
/* Color all hyperlinks one color */
a
{
color: #1382CE;
}
/* Table styles */
table
{
border-spacing: 0 0;
border-collapse: collapse;
font-size: 10pt;
}
table th
{
background: #E7E7E8;
text-align: left;
text-decoration: none;
font-weight: normal;
padding: 3px 6px 3px 6px;
}
table td
{
vertical-align: top;
padding: 3px 6px 5px 5px;
margin: 0px;
border: 1px solid #E7E7E8;
background: #F7F7F8;
}
/* Local link is a style for hyperlinks that link to file:/// content, there are lots so color them as 'normal' text until the user mouse overs */
.localLink
{
color: #1E1E1F;
background: #EEEEED;
text-decoration: none;
}
.localLink:hover
{
color: #1382CE;
background: #FFFF99;
text-decoration: none;
}
/* Center text, used in the over views cells that contain message level counts */
.textCentered
{
text-align: center;
}
/* The message cells in message tables should take up all avaliable space */
.messageCell
{
width: 100%;
}
/* Padding around the content after the h1 */
#content
{
padding: 0px 12px 12px 12px;
}
/* The overview table expands to width, with a max width of 97% */
#overview table
{
width: auto;
max-width: 75%;
}
/* The messages tables are always 97% width */
#messages table
{
width: 97%;
}
/* All Icons */
.IconSuccessEncoded, .IconInfoEncoded, .IconWarningEncoded, .IconErrorEncoded
{
min-width:18px;
min-height:18px;
background-repeat:no-repeat;
background-position:center;
}
/* Success icon encoded */
.IconSuccessEncoded
{
/* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
/* [---XsltValidateInternal-Base64EncodedImage:IconSuccess#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABcElEQVR4Xq2TsUsCURzHv15g8ZJcBWlyiYYgCIWcb9DFRRwMW5TA2c0/QEFwFkxxUQdxVlBwCYWOi6IhWgQhBLHJUCkhLr/BW8S7gvrAg+N+v8/v+x68Z8MGy+XSCyABQAXgBgHGALoASkIIDWSLeLBetdHryMjd5IxQPWT4rn1c/P7+xxp72Cs9m5SZ0Bq2vPnbPFafK2zDvmNHypdC0BPkLlQhxJsCAhQoZwdZU5mwxh720qGo8MzTxTTKZDPCx2HoVzp6lz0Q9tKhyx0kGs8Ny+TkWRKk8lCROwEduhyg9l/6lunOPSfmH3NUH6uQ0KHLAe7JYvJjevm+DAMGJHToKtigE+vwvIidxLamb8IBY9e+C5LiXREkfho3TSd06HJA13/oh6T51MTsfQbHrsMynQ5dDihFjiK8JJAU9AKIWTp76dCVN7HWHrajmUEGvyF9nkbAE6gLIS7kTUyuf2gscLoJrElZo/Mvj+nPz/kLTmfnEwP3tB0AAAAASUVORK5CYII=);
}
/* Information icon encoded */
.IconInfoEncoded
{
/* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
/* [---XsltValidateInternal-Base64EncodedImage:IconInformation#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR4Xs2TsUoDQRRF7wwoziokjZUKadInhdhukR9YP8DMX1hYW+QvdsXa/QHBbcXC7W0CamWTQnclFutceIQJwwaWNLlwm5k5d94M76mmaeCrrmsLYOocY12FcxZFUeozCqKqqgYA8uevv1H6VuPxcwlfk5N92KHBxfFeCSAxxswlYAW/Xr989x/mv9gkhtyMDhcAxgzRsp7flj8B/HF1RsMXq+NZMkopaHe7lbKxQUEIGbKsYNoGn969060hZBkQex/W8oRQwsQaW2o3Ago2SVcJUzAgY3N0lTCZZm+zPS8HB51gMmS1DEYyOz9acKO1D8JWTlafKIMxdhvlfdyT94Vv5h7P8Ky7nQzACmhvKq3zk3PjW9asz9D/1oigecsioooAAAAASUVORK5CYII=);
}
/* Warning icon encoded */
.IconWarningEncoded
{
/* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
/* [---XsltValidateInternal-Base64EncodedImage:IconWarning#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAx0lEQVR4XpWSMQ7CMAxFf4xAyBMLCxMrO8dhaBcuwdCJS3RJBw7SA/QGTCxdWJgiQYWKXJWKIXHIlyw5lqr34tQgEOdcBsCOx5yZK3hCCKdYXneQkh4pEfqzLfu+wVDSyyzFoJjfz9NB+pAF+eizx2Vruts0k15mPgvS6GYvpVtQhB61IB/dk6AF6fS4Ben0uIX5odtFe8Q/eW1KvFeH4e8khT6+gm5B+t3juyDt7n0jpe+CANTd+oTUjN/U3yVaABnSUjFz/gFq44JaVSCXeQAAAABJRU5ErkJggg==);
}
/* Error icon encoded */
.IconErrorEncoded
{
/* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
/* [---XsltValidateInternal-Base64EncodedImage:IconError#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4XqWTvUoEQRCE6wYPZUA80AfwAQz23uCMjA7MDRQEIzPBVEyNTQUFIw00vcQTTMzuAh/AxEQQT8HF/3G/oGGnEUGuoNnd6qoZuqltyKEsyzVJq5I6rnUp6SjGeGhESikzzlc1eL7opfuVbrqbU1Zw9NCgtQMaZpY0eNnaaL2fHusvTK5vKu7sjSS1Y4y3QUA6K3e3Mau5UFDyMP7tYF9o8cAHZv68vipoIJg971PZIZ5HiwdvYGGvFVFHmGmZ2MxwmQYPXubPl9Up0tfoMQGetXd6mRbvhBw+boZ6WF7Mbv1+GsHRk0fQmPAH1GfmZirbCfDJ61tw3Px8/8pZsPAG4jlVhcPgZ7adwNWBB68lkRQWFiTgFlbnLY3DGGM7izIJIyT/jjIvEJw6fdJTc6krDzh6aMwMP9bvDH4ADSsa9uSWVJkAAAAASUVORK5CYII=);
}
</style><script type="text/javascript" language="javascript">
// Startup
// Hook up the the loaded event for the document/window, to linkify the document content
var startupFunction = function() { linkifyElement("messages"); };
if(window.attachEvent)
{
window.attachEvent('onload', startupFunction);
}
else if (window.addEventListener)
{
window.addEventListener('load', startupFunction, false);
}
else
{
document.addEventListener('load', startupFunction, false);
}
// Toggles the visibility of table rows with the specified name
function toggleTableRowsByName(name)
{
var allRows = document.getElementsByTagName('tr');
for (i=0; i < allRows.length; i++)
{
var currentName = allRows[i].getAttribute('name');
if(!!currentName && currentName.indexOf(name) == 0)
{
var isVisible = allRows[i].style.display == '';
isVisible ? allRows[i].style.display = 'none' : allRows[i].style.display = '';
}
}
}
function scrollToFirstVisibleRow(name)
{
var allRows = document.getElementsByTagName('tr');
for (i=0; i < allRows.length; i++)
{
var currentName = allRows[i].getAttribute('name');
var isVisible = allRows[i].style.display == '';
if(!!currentName && currentName.indexOf(name) == 0 && isVisible)
{
allRows[i].scrollIntoView(true);
return true;
}
}
return false;
}
// Linkifies the specified text content, replaces candidate links with html links
function linkify(text)
{
if(!text || 0 === text.length)
{
return text;
}
// Find http, https and ftp links and replace them with hyper links
var urlLink = /(http|https|ftp)\:\/\/[a-zA-Z0-9\-\.]+(:[a-zA-Z0-9]*)?\/?([a-zA-Z0-9\-\._\?\,\/\\\+&%\$#\=~;\{\}])*/gi;
return text.replace(urlLink, '<a href="$&">$&</a>') ;
}
// Linkifies the specified element by ID
function linkifyElement(id)
{
var element = document.getElementById(id);
if(!!element)
{
element.innerHTML = linkify(element.innerHTML);
}
}
function ToggleMessageVisibility(projectName)
{
if(!projectName || 0 === projectName.length)
{
return;
}
toggleTableRowsByName("MessageRowClass" + projectName);
toggleTableRowsByName('MessageRowHeaderShow' + projectName);
toggleTableRowsByName('MessageRowHeaderHide' + projectName);
}
function ScrollToFirstVisibleMessage(projectName)
{
if(!projectName || 0 === projectName.length)
{
return;
}
// First try the 'Show messages' row
if(!scrollToFirstVisibleRow('MessageRowHeaderShow' + projectName))
{
// Failed to find a visible row for 'Show messages', try an actual message row
scrollToFirstVisibleRow('MessageRowClass' + projectName);
}
}
</script></head><body><h1 _locID="ConversionReport">
Migration Report - </h1><div id="content"><h2 _locID="OverviewTitle">Overview</h2><div id="overview"><table><tr><th></th><th _locID="ProjectTableHeader">Project</th><th _locID="PathTableHeader">Path</th><th _locID="ErrorsTableHeader">Errors</th><th _locID="WarningsTableHeader">Warnings</th><th _locID="MessagesTableHeader">Messages</th></tr><tr><td class="IconErrorEncoded" /><td><strong><a href="#grk-cw1">grk-cw1</a></strong></td><td>cw 1\grk-cw1.vcxproj</td><td class="textCentered"><a href="#grk-cw1Error">1</a></td><td class="textCentered"><a>0</a></td><td class="textCentered"><a href="#">0</a></td></tr><tr><td class="IconSuccessEncoded" /><td><strong><a href="#Solution"><span _locID="OverviewSolutionSpan">Solution</span></a></strong></td><td>grk-cw.sln</td><td class="textCentered"><a>0</a></td><td class="textCentered"><a>0</a></td><td class="textCentered"><a href="#" onclick="ScrollToFirstVisibleMessage('Solution'); return false;">1</a></td></tr></table></div><h2 _locID="SolutionAndProjectsTitle">Solution and projects</h2><div id="messages"><a name="grk-cw1" /><h3>grk-cw1</h3><table><tr id="grk-cw1HeaderRow"><th></th><th class="messageCell" _locID="MessageTableHeader">Message</th></tr><tr name="ErrorRowClassgrk-cw1"><td class="IconErrorEncoded"><a name="grk-cw1Error" /></td><td class="messageCell"><strong>cw 1\grk-cw1.vcxproj:
</strong><span>The application which this project type is based on was not found. Please try this link for further information: 8bc9ceb8-8b4a-11d0-8d11-00a0c91bc942</span></td></tr></table><a name="Solution" /><h3 _locID="ProjectDisplayNameHeader">Solution</h3><table><tr id="SolutionHeaderRow"><th></th><th class="messageCell" _locID="MessageTableHeader">Message</th></tr><tr name="MessageRowHeaderShowSolution"><td class="IconInfoEncoded" /><td class="messageCell"><a _locID="ShowAdditionalMessages" href="#" name="SolutionMessage" onclick="ToggleMessageVisibility('Solution'); return false;">
Show 1 additional messages
</a></td></tr><tr name="MessageRowClassSolution" style="display: none"><td class="IconInfoEncoded"><a name="SolutionMessage" /></td><td class="messageCell"><strong>grk-cw.sln:
</strong><span>The solution file does not require migration.</span></td></tr><tr style="display: none" name="MessageRowHeaderHideSolution"><td class="IconInfoEncoded" /><td class="messageCell"><a _locID="HideAdditionalMessages" href="#" name="SolutionMessage" onclick="ToggleMessageVisibility('Solution'); return false;">
Hide 1 additional messages
</a></td></tr></table></div></div></body></html>

Binary file not shown.

View File

@ -0,0 +1,26 @@
d:\studia\planeta\grk\cw 6\debug\vc143.pdb
d:\studia\planeta\grk\cw 6\debug\vc143.idb
d:\studia\planeta\grk\cw 6\debug\texture.obj
d:\studia\planeta\grk\cw 6\debug\shader_loader.obj
d:\studia\planeta\grk\cw 6\debug\render_utils.obj
d:\studia\planeta\grk\cw 6\debug\main.obj
d:\studia\planeta\grk\cw 6\debug\camera.obj
d:\studia\planeta\grk\cw 6\debug\stb_image_aug.obj
d:\studia\planeta\grk\cw 6\debug\soil.obj
d:\studia\planeta\grk\cw 6\debug\image_helper.obj
d:\studia\planeta\grk\cw 6\debug\image_dxt.obj
d:\studia\planeta\grk\cw 6\debug\box.obj
d:\studia\planeta\grk\cw 6\debug\vc142.idb
d:\studia\planeta\grk\cw 6\debug\vc142.pdb
d:\studia\planeta\grk\debug\planeta.pdb
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\cl.command.1.tlog
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\cl.items.tlog
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\cl.read.1.tlog
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\cl.write.1.tlog
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\link-cvtres.read.1.tlog
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\link-cvtres.write.1.tlog
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\link-rc.read.1.tlog
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\link-rc.write.1.tlog
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\link.command.1.tlog
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\link.read.1.tlog
d:\studia\planeta\grk\cw 6\debug\planeta.tlog\link.write.1.tlog

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,9 @@
D:\STUDIA\Planeta\grk\cw 6\src\Camera.cpp;D:\STUDIA\Planeta\grk\cw 6\Debug\Camera.obj
D:\STUDIA\Planeta\grk\cw 6\src\main.cpp;D:\STUDIA\Planeta\grk\cw 6\Debug\main.obj
D:\STUDIA\Planeta\grk\cw 6\src\Render_Utils.cpp;D:\STUDIA\Planeta\grk\cw 6\Debug\Render_Utils.obj
D:\STUDIA\Planeta\grk\cw 6\src\Shader_Loader.cpp;D:\STUDIA\Planeta\grk\cw 6\Debug\Shader_Loader.obj
D:\STUDIA\Planeta\grk\cw 6\src\SOIL\image_DXT.c;D:\STUDIA\Planeta\grk\cw 6\Debug\image_DXT.obj
D:\STUDIA\Planeta\grk\cw 6\src\SOIL\image_helper.c;D:\STUDIA\Planeta\grk\cw 6\Debug\image_helper.obj
D:\STUDIA\Planeta\grk\cw 6\src\SOIL\SOIL.c;D:\STUDIA\Planeta\grk\cw 6\Debug\SOIL.obj
D:\STUDIA\Planeta\grk\cw 6\src\SOIL\stb_image_aug.c;D:\STUDIA\Planeta\grk\cw 6\Debug\stb_image_aug.obj
D:\STUDIA\Planeta\grk\cw 6\src\Texture.cpp;D:\STUDIA\Planeta\grk\cw 6\Debug\Texture.obj

View File

@ -0,0 +1,2 @@
PlatformToolSet=v143:VCToolArchitecture=Native32Bit:VCToolsVersion=14.38.33130:TargetPlatformVersion=10.0.22000.0:
Debug|Win32|D:\STUDIA\Planeta\grk\|

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,17 +0,0 @@
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\vc142.pdb
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\vc142.idb
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\shader_loader.obj
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\render_utils.obj
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\main_3_1.obj
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\camera.obj
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\box.obj
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\vcpkg.applocal.log
c:\users\andrzej\desktop\grk\zipy\grk-cw\debug\grk-cw3.exe
c:\users\andrzej\desktop\grk\zipy\grk-cw\debug\grk-cw3.pdb
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\grk-cw3.tlog\cl.command.1.tlog
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\grk-cw3.tlog\cl.read.1.tlog
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\grk-cw3.tlog\cl.write.1.tlog
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\grk-cw3.tlog\grk-cw3.write.1u.tlog
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\grk-cw3.tlog\link.command.1.tlog
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\grk-cw3.tlog\link.read.1.tlog
c:\users\andrzej\desktop\grk\zipy\grk-cw\cw 3\debug\grk-cw3.tlog\link.write.1.tlog

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ProjectOutputs>
<ProjectOutput>
<FullPath>C:\Users\Andrzej\Desktop\grk\2021\rozwiązania\Debug\grk-cw3.exe</FullPath>
</ProjectOutput>
</ProjectOutputs>
<ContentFiles />
<SatelliteDlls />
<NonRecipeFileRefs />
</Project>

View File

@ -1,8 +0,0 @@
 Using triplet "x86-windows" from "C:\Users\Andrzej\Desktop\openvdb\vcpkg\installed\x86-windows\"
main.cpp
C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared\minwindef.h(130,1): warning C4005: 'APIENTRY': macro redefinition
C:\Users\Andrzej\Desktop\grk\2021\rozwiązania\dependencies\glfw-3.3.8.bin.WIN32\include\GLFW\glfw3.h(123): message : see previous definition of 'APIENTRY'
C:\Users\Andrzej\Desktop\grk\2021\rozwiązania\cw 3\src\ex_3_1.hpp(76,16): warning C4305: 'initializing': truncation from 'double' to 'float'
Box.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
grk-cw3.vcxproj -> C:\Users\Andrzej\Desktop\grk\2021\rozwiązania\Debug\grk-cw3.exe

View File

@ -1,2 +0,0 @@
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29333:TargetPlatformVersion=10.0.19041.0:
Debug|Win32|C:\Users\Andrzej\Desktop\grk\2021\rozwiązania\|

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ProjectOutputs>
<ProjectOutput>
<FullPath>C:\Users\Andrzej\Desktop\grk\2021\grk glfw test\Debug\grk-cw4.exe</FullPath>
</ProjectOutput>
</ProjectOutputs>
<ContentFiles />
<SatelliteDlls />
<NonRecipeFileRefs />
</Project>

View File

@ -1,10 +0,0 @@
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppBuild.targets(491,5): warning MSB8028: The intermediate directory (Debug\) contains files shared from another project (grk-cw3.vcxproj). This can lead to incorrect clean and rebuild behavior.
Using triplet "x86-windows" from "C:\Users\Andrzej\Desktop\openvdb\vcpkg\installed\x86-windows\"
main.cpp
C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared\minwindef.h(130,1): warning C4005: 'APIENTRY': macro redefinition
C:\Users\Andrzej\Desktop\grk\2021\grk glfw test\dependencies\glfw-3.3.8.bin.WIN32\include\GLFW\glfw3.h(123): message : see previous definition of 'APIENTRY'
C:\Users\Andrzej\Desktop\grk\2021\grk glfw test\cw 4\src\ex_4_1.hpp(63,16): warning C4305: 'initializing': truncation from 'double' to 'float'
C:\Users\Andrzej\Desktop\grk\2021\grk glfw test\cw 4\src\ex_4_1.hpp(84,13): warning C4244: 'initializing': conversion from 'double' to 'float', possible loss of data
Box.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
grk-cw4.vcxproj -> C:\Users\Andrzej\Desktop\grk\2021\grk glfw test\Debug\grk-cw4.exe

View File

@ -1,2 +0,0 @@
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29333:TargetPlatformVersion=10.0.19041.0:
Debug|Win32|C:\Users\Andrzej\Desktop\grk\2021\grk glfw test\|

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ProjectOutputs>
<ProjectOutput>
<FullPath>C:\Users\Andrzej\Desktop\grk\2021\grk glfw test\Debug\grk-cw5.exe</FullPath>
</ProjectOutput>
</ProjectOutputs>
<ContentFiles />
<SatelliteDlls />
<NonRecipeFileRefs />
</Project>

View File

@ -1,3 +0,0 @@
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppBuild.targets(491,5): warning MSB8028: The intermediate directory (Debug\) contains files shared from another project (grk-cw3.vcxproj, grk-cw4.vcxproj). This can lead to incorrect clean and rebuild behavior.
Using triplet "x86-windows" from "C:\Users\Andrzej\Desktop\openvdb\vcpkg\installed\x86-windows\"
grk-cw5.vcxproj -> C:\Users\Andrzej\Desktop\grk\2021\grk glfw test\Debug\grk-cw5.exe

View File

@ -1,2 +0,0 @@
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29333:TargetPlatformVersion=10.0.19041.0:
Debug|Win32|C:\Users\Andrzej\Desktop\grk\2021\grk glfw test\|

View File

@ -1,10 +0,0 @@
e:\micha\studia\grafika_komputerowa\grk\grk\cw 6\debug\vc142.pdb
e:\micha\studia\grafika_komputerowa\grk\grk\cw 6\debug\vc142.idb
e:\micha\studia\grafika_komputerowa\grk\grk\cw 6\debug\texture.obj
e:\micha\studia\grafika_komputerowa\grk\grk\cw 6\debug\shader_loader.obj
e:\micha\studia\grafika_komputerowa\grk\grk\cw 6\debug\render_utils.obj
e:\micha\studia\grafika_komputerowa\grk\grk\cw 6\debug\camera.obj
e:\micha\studia\grafika_komputerowa\grk\grk\cw 6\debug\box.obj
e:\micha\studia\grafika_komputerowa\grk\grk\cw 6\debug\grk-cw6.tlog\cl.read.1.tlog
e:\micha\studia\grafika_komputerowa\grk\grk\cw 6\debug\grk-cw6.tlog\cl.write.1.tlog
e:\micha\studia\grafika_komputerowa\grk\grk\cw 6\debug\grk-cw6.tlog\cl.command.1.tlog

View File

@ -1,2 +0,0 @@
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.29.30133:TargetPlatformVersion=10.0.19041.0:
Debug|Win32|E:\micha\studia\grafika_komputerowa\grk\grk\|

BIN
grk/cw 6/Debug/imgui.obj Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
grk/cw 6/Debug/vc143.idb Normal file

Binary file not shown.

BIN
grk/cw 6/Debug/vc143.pdb Normal file

Binary file not shown.

144
grk/cw 6/Zadania 2.html Normal file
View File

@ -0,0 +1,144 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Zadania 2</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<link rel="stylesheet" href="style.css" />
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<h2 id="ładowanie-vao-i-vbo">Ładowanie VAO i VBO</h2>
<p>W trakcie tych zajęć przećwiczymy ładowanie danych do pamięci. Tym razem, zamiast korzystać z gotowej funkcji utworzymy je samodzielnie. W openglu wykorzystujemy do tego VBO (Vertex Buffer Object) i VAO (Vertex Array Object). Pierwsza jest buforem, który zawiera dane modeli. Natomiast drugi zawiera informacje jak dane bufory interpretować.</p>
<p>W zadaniu <code>2_1</code> będziemy przesyłać prostopadłościan. Tablica zawierająca jego definicję jest w pliku <code>Box.cpp</code>. Każdy wierzchołek składa się z ośmiu floatów, pierwsze cztery określają jego pozycję, a cztery kolejny określają jego kolor.</p>
<p>Inicjalizacje będziemy wykonywać wewnątrz funkcji <code>init</code>. Pierwszym krokiem jest wygenerowanie jednego VAO i jednego VBO. Wykorzystuje się do tego odpowiednio funkcje <code>glGenVertexArrays</code> i <code>glGenBuffers</code>. Pierwszym argumentem jest liczba buforów czy array object, które tworzymy, drugim jest adres, w którym ma być bufor/array object umieszczony. W naszym przypadku pierwszym argumentem będzie 1, natomiast drugim będzie wskaźnik na zmienną <code>VAO</code> i <code>VBO</code> odpowiednio. Następnie należy aktywować <code>VAO</code> za pomocą funkcji <code>glBindVertexArray</code>, po czym podpiąć do niego bufor <code>VBO</code> za pomocą <code>glBindBuffer(GLenum target, GLuint buffer)</code> nasz target to <code>GL_ARRAY_BUFFER</code>, czyli bufor, który oznacza atrybuty wierzchołków.</p>
<p>Kolejnym krokiem jest umieszczenie danych w buforze za pomocą funkcji <code>glBufferData(GLenum target, GLsizeiptr size, const void * data, GLenum usage)</code>. Pierwszym argumentem jest ponownie <code>GL_ARRAY_BUFFER</code>, drugi to rozmiar tablicy w bajtach, trzecim adres tablicy, a czwartym sposób używania tablicy, w naszym przypadku <code>GL_STATIC_DRAW</code>.</p>
<p>Pozostaje opisanie atrybutów wierzchołków, musimy opisać, gdzie się znajdują, jaką mają strukturę i jak ma się do nich odnieść shader. My mamy 2 atrybuty, jest to pozycja i kolor. Pierwszym krokiem jest aktywacja atrybutów za pomocą <code>glEnableVertexAttribArray(GLuint index)</code>, przy czym po indeksie będą one odnajdywane przez shader. W naszym przypadku będą to odpowiednio 0 i 1. Następnie należy opisać jak GPU ma odczytywać atrybuty z bufora za pomocą funkcji <code>glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * offset)</code>. Jej argumenty to kolejno: * <code>index</code> - indeksy odpowiadające atrybutowi, * <code>size</code> - liczba elementów w atrybucie wierzchołka, może wynosić 1, 2, 3 lub 4, * <code>type</code> - typ danych jako enum, w naszym przypadku <code>GL_FLOAT</code>, * <code>normalized</code> - określa czy wartość ma być znormalizowana, u nas będzie to <code>GL_FALSE</code>, * <code>stride</code> - określa dystans pomiędzy atrybutami w kolejnych wierzchołkach * <code>offset</code> - wskaźnik na pierwszy atrybut w tablicy, licząc względem początku tablicy i typu (void *)</p>
<p>Struktura naszego prostopadłościanu ma na przemian pozycje i kolory, dlatego w obu przypadkach stride będzie wynosił ośmiokrotność rozmiaru <em>floata</em>. Natomiast <em>offest</em> będzie wynosił zero i czterokrotność rozmiaru <em>floata</em>.</p>
<p><img src="./img/stride_offest.jpg" /></p>
<p>Na koniec uwolnij <code>VAO</code> za pomocą instrukcji: <code>glBindVertexArray(0);</code>.</p>
<p>Pozostaje narysować prostopadłościan. W funkcji <code>renderScene</code> wywołaj <code>glBindVertexArray</code> z argumentem <code>VAO</code>. Następnie narysuj za pomocą <code>glDrawArrays(GLenum mode, GLint first, GLsizei count)</code>. Pierwszym argumentem jest typ rysowanego obiektu, w naszym przypadku jest to <code>GL_TRIANGLES</code>, indeks pierwszego wierzchołka, czyli 0 i liczba wierzchołków czyli 36.</p>
<h3 id="zadanie">Zadanie</h3>
<p>podążając za powyższymi instrukcjami zainicjalizuj box, następnie obróć go za pomocą funkcji <code>glm::eulerAngleXYZ</code> tak, żeby było widać trzy ściany prostopadłościany. Dodaj również obrót wokół osi Y w czasie z użyciem funkcji <code>glm::eulerAngleXYZ</code>.</p>
<h3 id="zadanie-1">Zadanie*</h3>
<p>Wykonaj zadania z <code>ex_2_1b.hpp</code>.</p>
<h2 id="shadery">Shadery</h2>
<p>Shadery są programami uruchamianymi na karcie graficznej. W openglu wykorzystujemy język GLSL, który jest bardzo podobny do C++, posiada on liczne słowa kluczowe i funkcje matematyczne. Istnieją różne rodzaje shaderów, w tej sekcji skupimy się na dwóch z nich: shader wierzchołków i shader fragmentów. Pierwszy rodzaj wykonują operacje na wierzchołkach, przykładowo w tym zadaniu odpowiada za przemnożenie macierzy obrotu przez wierzchołki. Natomiast drugi określa kolor konkretnego fragmentu/piksela. Shadery są łączone w <em>pipeline</em>, to znaczy wykonuje się je sekwencyjnie, dane z poprzedniego są wysyłane do następnego. W zadaniu <code>2_1</code> wykorzystujemy następujące shadery</p>
<p>shader wierzchołków</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode glsl"><code class="sourceCode glsl"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#version 430 core</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">layout</span>(<span class="dt">location</span> = <span class="dv">0</span>) <span class="dt">in</span> <span class="dt">vec4</span> vertexPosition;</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="kw">layout</span>(<span class="dt">location</span> = <span class="dv">1</span>) <span class="dt">in</span> <span class="dt">vec4</span> vertexColor;</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">uniform</span> <span class="dt">mat4</span> transformation;</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> <span class="fu">main</span>()</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a> <span class="bu">gl_Position</span> = transformation * vertexPosition;</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>shader fragmentów</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode glsl"><code class="sourceCode glsl"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#version 430 core</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="dt">out</span> <span class="dt">vec4</span> out_color;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> <span class="fu">main</span>()</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a> out_color = <span class="dt">vec4</span>(<span class="fl">0.8</span>,<span class="fl">0.2</span>,<span class="fl">0.9</span>,<span class="fl">1.0</span>);</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Shader wierzchołków odbiera 2 typy danych. Pierwszym są dane z bufora w liniach.</p>
<pre><code>layout(location = 0) in vec4 vertexPosition;
layout(location = 1) in vec4 vertexColor;</code></pre>
<p>są one różne dla każdego wierzchołka. Zmienną, która ma odebrać te dane deklaruje się globalnie funkcją <code>main</code> i poprzedza się słowem kluczowym <code>in</code>. Prefiks <code>layout(location = ..)</code> jest opcjonalny i służy określeniu indeksu atrybutu, jest to ta sama wartość, którą ustawiliśmy w <code>glVertexAttribPointer</code>. Można je usunąć, wtedy o indeksie będzie decydować kolejność. Drugim typem jest <code>uniform</code>, w przeciwieństwie do danych z bufora, są one takie same dla każdego wierzchołka. W tym przypadku przesyłamy za jej pomocą macierz obrotu.</p>
<p>Shader również wysyła dane. Domyślnie musi wysłać wyjściową pozycję wierzchołka, robi to przez zapisanie w <code>gl_Position</code> wektora 4-wymiarowego w funkcji <code>main</code>. Poza tym może również przesłać inne informacje. Wykonuje się to przez deklaracje zmiennej globalnej, którą poprzedza się słowem kluczowym <code>out</code>. Następnie należy ją wypełnić. W tym przypadku przesyłamy kolor wierzchołka.</p>
<p>Shader fragmentów odbiera kolor z Shadera wierzchołków. Podobnie jak z obieraniem danych z buforu robimy to za pomocą słowa kluczowego <code>in</code>, w przypadku przesyłania zmiennej z jednego shadera do drugiego nazwy zmiennych muszą być <strong>takie same</strong> przy słowie kluczowym <code>out</code> i <code>in</code>. Zmiennej obranej nie można modyfikować.</p>
<p>W najnowszej wersji opengla fragment shader nie ma domyślnego wyjścia na kolor, musimy sami je z definiować. Robimy to instrukcją <code>out vec4 out_color</code> następnie w funkcji <code>main</code> przypisujemy mu jakąś wartość.</p>
<h3 id="zadanie-2">Zadanie</h3>
<p>W tej chwili nasz prostopadłościan jest jednolitego koloru i nie możemy rozróżnić jego ścian. Przesłana przez nas wcześniej informacja o kolorze nie została wykorzystana. Bazując na powyższych informacjach prześlij wartość koloru zapisaną w <code>vertexColor</code> do shadera fragmentu i przypisz ją do wyjściowego koloru. Dodaj zmienną <code>in vec4 color</code> w shaderze fragmentów, następnie w funkcji <code>main</code> przypisz do niej wartość koloru. W shaderze fragmentów odbierz ją za pomocą <code>out</code> i przypisz do wyjściowego koloru.</p>
<p>Zauważ, że kolor ścian nie jest jednolity, zamiast tego przechodzą gradientem od jednego koloru do drugiego. Dzieje się tak, ponieważ na etapie rasteryzacji kolor jest interpolowany. To znaczy: wartość jest uśredniana pomiędzy wierzchołkami trójkąta.</p>
<h3 id="zadanie-3">Zadanie</h3>
<p>Sprawdź, jak będzie wyglądać prostopadłościan z wyłączoną interpolacją. Dodaj przed <code>in</code> i <code>out</code> <code>color</code> słowo kluczowe <code>flat</code>.</p>
<h3 id="zadanie-4">Zadanie</h3>
<p>Prześlij czas od startu aplikacji do shadera fragmentów. Użyj funkcji <code>glfwGetTime</code>, by uzyskać czas. Utwórz zmienną <code>uniform</code> typu <code>float</code> we shaderze fragmentów. Następnie prześlij do niej wynik funkcji <code>glfwGetTime</code>. Aby przesłać czas do shadera, wykorzystaj funkcje <code>glUniform1f</code>. Pierwszym argumentem jest lokacja uniforma, drugim przypisywana wartość. Lokację uzyskamy za pomocą funckji <code>glGetUniformLocation(progam,"time")</code> pierwszym argumentem jest program, którego używamy a drugim nazwa zmiennej uniform. Podziel kolor przez czas, by uzyskać efekt, w którym prostopadłościan robi się czarny.</p>
<h3 id="zadanie-5">Zadanie*</h3>
<p>Wykorzystaj przesłany czas, żeby sprawić, żeby prostopadłościan znikał przez mieszanie go z kolorem tła. Wykorzystaj do tego następujące funkcje GLSL: <code>mix</code>, <code>sin</code>, <code>vec4</code>. Opis ich działania możesz znaleźć w dokumentacji https://docs.gl/.</p>
<h3 id="zadanie-6">Zadanie</h3>
<p>Prześlij pozycję lokalną i globalną pozycję wierzchołków do shadera fragmentów i wyświetl ją.</p>
<p>W shaderze wierzchołków obok deklaracji <code>out vec4 color;</code> dodaj analogiczne o nazwie <code>pos_local</code> i <code>pos_global</code>. Do <code>pos_local</code> przypisz <code>vertexPosition</code>, a do <code>pos_global</code> przypisz <code>transformation * vertexPosition</code>. Podobnie dopisz odebranie ich w shaderze fragmentów. Użyj <code>pos_local</code>, następnie <code>pos_global</code> jako zamiast koloru. Dlaczego otrzymaliśmy taki efekt?</p>
<h3 id="zadanie-7">Zadanie*</h3>
<p>Użyj jednej ze zmiennych z poprzedniego zadania do zrobienia pasków na przynajmniej jednej ze ścian sześcianu. Wykorzystaj czas, żeby paski się przesuwały.</p>
</body>
</html>

105
grk/cw 6/Zadania 2.md Normal file
View File

@ -0,0 +1,105 @@
## Ładowanie VAO i VBO
W trakcie tych zajęć przećwiczymy ładowanie danych do pamięci. Tym razem, zamiast korzystać z gotowej funkcji utworzymy je samodzielnie. W openglu wykorzystujemy do tego VBO (Vertex Buffer Object) i VAO (Vertex Array Object). Pierwsza jest buforem, który zawiera dane modeli. Natomiast drugi zawiera informacje jak dane bufory interpretować.
W zadaniu `2_1` będziemy przesyłać prostopadłościan. Tablica zawierająca jego definicję jest w pliku `Box.cpp`. Każdy wierzchołek składa się z ośmiu floatów, pierwsze cztery określają jego pozycję, a cztery kolejny określają jego kolor.
Inicjalizacje będziemy wykonywać wewnątrz funkcji `init`. Pierwszym krokiem jest wygenerowanie jednego VAO i jednego VBO. Wykorzystuje się do tego odpowiednio funkcje `glGenVertexArrays` i `glGenBuffers`. Pierwszym argumentem jest liczba buforów czy array object, które tworzymy, drugim jest adres, w którym ma być bufor/array object umieszczony.
W naszym przypadku pierwszym argumentem będzie 1, natomiast drugim będzie wskaźnik na zmienną `VAO` i `VBO` odpowiednio. Następnie należy aktywować `VAO` za pomocą funkcji `glBindVertexArray`, po czym podpiąć do niego bufor `VBO` za pomocą `glBindBuffer(GLenum target, GLuint buffer)` nasz target to `GL_ARRAY_BUFFER`, czyli bufor, który oznacza atrybuty wierzchołków.
Kolejnym krokiem jest umieszczenie danych w buforze za pomocą funkcji `glBufferData(GLenum target, GLsizeiptr size, const void * data, GLenum usage)`. Pierwszym argumentem jest ponownie `GL_ARRAY_BUFFER`, drugi to rozmiar tablicy w bajtach, trzecim adres tablicy, a czwartym sposób używania tablicy, w naszym przypadku `GL_STATIC_DRAW`.
Pozostaje opisanie atrybutów wierzchołków, musimy opisać, gdzie się znajdują, jaką mają strukturę i jak ma się do nich odnieść shader. My mamy 2 atrybuty, jest to pozycja i kolor. Pierwszym krokiem jest aktywacja atrybutów za pomocą `glEnableVertexAttribArray(GLuint index)`, przy czym po indeksie będą one odnajdywane przez shader. W naszym przypadku będą to odpowiednio 0 i 1. Następnie należy opisać jak GPU ma odczytywać atrybuty z bufora za pomocą funkcji `glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * offset)`. Jej argumenty to kolejno:
* `index` - indeksy odpowiadające atrybutowi,
* `size` - liczba elementów w atrybucie wierzchołka, może wynosić 1, 2, 3 lub 4,
* `type` - typ danych jako enum, w naszym przypadku `GL_FLOAT`,
* `normalized` - określa czy wartość ma być znormalizowana, u nas będzie to `GL_FALSE`,
* `stride` - określa dystans pomiędzy atrybutami w kolejnych wierzchołkach
* `offset` - wskaźnik na pierwszy atrybut w tablicy, licząc względem początku tablicy i typu (void \*)
Struktura naszego prostopadłościanu ma na przemian pozycje i kolory, dlatego w obu przypadkach stride będzie wynosił ośmiokrotność rozmiaru *floata*. Natomiast *offest* będzie wynosił zero i czterokrotność rozmiaru *floata*.
![](./img/stride_offest.jpg)
Na koniec uwolnij `VAO` za pomocą instrukcji: `glBindVertexArray(0);`.
Pozostaje narysować prostopadłościan. W funkcji `renderScene` wywołaj `glBindVertexArray` z argumentem `VAO`. Następnie narysuj za pomocą `glDrawArrays(GLenum mode, GLint first, GLsizei count)`. Pierwszym argumentem jest typ rysowanego obiektu, w naszym przypadku jest to `GL_TRIANGLES`, indeks pierwszego wierzchołka, czyli 0 i liczba wierzchołków czyli 36.
### Zadanie
podążając za powyższymi instrukcjami zainicjalizuj box, następnie obróć go za pomocą funkcji `glm::eulerAngleXYZ` tak, żeby było widać trzy ściany prostopadłościany. Dodaj również obrót wokół osi Y w czasie z użyciem funkcji `glm::eulerAngleXYZ`.
### Zadanie*
Wykonaj zadania z `ex_2_1b.hpp`.
## Shadery
Shadery są programami uruchamianymi na karcie graficznej. W openglu wykorzystujemy język GLSL, który jest bardzo podobny do C++, posiada on liczne słowa kluczowe i funkcje matematyczne. Istnieją różne rodzaje shaderów, w tej sekcji skupimy się na dwóch z nich: shader wierzchołków i shader fragmentów. Pierwszy rodzaj wykonują operacje na wierzchołkach, przykładowo w tym zadaniu odpowiada za przemnożenie macierzy obrotu przez wierzchołki. Natomiast drugi określa kolor konkretnego fragmentu/piksela. Shadery są łączone w *pipeline*, to znaczy wykonuje się je sekwencyjnie, dane z poprzedniego są wysyłane do następnego.
W zadaniu `2_1` wykorzystujemy następujące shadery
shader wierzchołków
```GLSL
#version 430 core
layout(location = 0) in vec4 vertexPosition;
layout(location = 1) in vec4 vertexColor;
uniform mat4 transformation;
void main()
{
gl_Position = transformation * vertexPosition;
}
```
shader fragmentów
```GLSL
#version 430 core
out vec4 out_color;
void main()
{
out_color = vec4(0.8,0.2,0.9,1.0);
}
```
Shader wierzchołków odbiera 2 typy danych. Pierwszym są dane z bufora w liniach.
```
layout(location = 0) in vec4 vertexPosition;
layout(location = 1) in vec4 vertexColor;
```
są one różne dla każdego wierzchołka. Zmienną, która ma odebrać te dane deklaruje się globalnie funkcją `main` i poprzedza się słowem kluczowym `in`. Prefiks `layout(location = ..)` jest opcjonalny i służy określeniu indeksu atrybutu, jest to ta sama wartość, którą ustawiliśmy w `glVertexAttribPointer`. Można je usunąć, wtedy o indeksie będzie decydować kolejność.
Drugim typem jest `uniform`, w przeciwieństwie do danych z bufora, są one takie same dla każdego wierzchołka. W tym przypadku przesyłamy za jej pomocą macierz obrotu.
Shader również wysyła dane. Domyślnie musi wysłać wyjściową pozycję wierzchołka, robi to przez zapisanie w `gl_Position` wektora 4-wymiarowego w funkcji `main`. Poza tym może również przesłać inne informacje. Wykonuje się to przez deklaracje zmiennej globalnej, którą poprzedza się słowem kluczowym `out`. Następnie należy ją wypełnić. W tym przypadku przesyłamy kolor wierzchołka.
Shader fragmentów odbiera kolor z Shadera wierzchołków. Podobnie jak z obieraniem danych z buforu robimy to za pomocą słowa kluczowego `in`, w przypadku przesyłania zmiennej z jednego shadera do drugiego nazwy zmiennych muszą być **takie same** przy słowie kluczowym `out` i `in`. Zmiennej obranej nie można modyfikować.
W najnowszej wersji opengla fragment shader nie ma domyślnego wyjścia na kolor, musimy sami je z definiować. Robimy to instrukcją `out vec4 out_color` następnie w funkcji `main` przypisujemy mu jakąś wartość.
### Zadanie
W tej chwili nasz prostopadłościan jest jednolitego koloru i nie możemy rozróżnić jego ścian. Przesłana przez nas wcześniej informacja o kolorze nie została wykorzystana. Bazując na powyższych informacjach prześlij wartość koloru zapisaną w `vertexColor` do shadera fragmentu i przypisz ją do wyjściowego koloru. Dodaj zmienną `in vec4 color` w shaderze fragmentów, następnie w funkcji `main` przypisz do niej wartość koloru. W shaderze fragmentów odbierz ją za pomocą `out` i przypisz do wyjściowego koloru.
Zauważ, że kolor ścian nie jest jednolity, zamiast tego przechodzą gradientem od jednego koloru do drugiego. Dzieje się tak, ponieważ na etapie rasteryzacji kolor jest interpolowany. To znaczy: wartość jest uśredniana pomiędzy wierzchołkami trójkąta.
### Zadanie
Sprawdź, jak będzie wyglądać prostopadłościan z wyłączoną interpolacją. Dodaj przed `in` i `out` ` color` słowo kluczowe `flat`.
### Zadanie
Prześlij czas od startu aplikacji do shadera fragmentów. Użyj funkcji `glfwGetTime`, by uzyskać czas. Utwórz zmienną `uniform` typu `float` we shaderze fragmentów. Następnie prześlij do niej wynik funkcji `glfwGetTime`. Aby przesłać czas do shadera, wykorzystaj funkcje `glUniform1f`. Pierwszym argumentem jest lokacja uniforma, drugim przypisywana wartość. Lokację uzyskamy za pomocą funckji `glGetUniformLocation(progam,"time")` pierwszym argumentem jest program, którego używamy a drugim nazwa zmiennej uniform.
Podziel kolor przez czas, by uzyskać efekt, w którym prostopadłościan robi się czarny.
### Zadanie*
Wykorzystaj przesłany czas, żeby sprawić, żeby prostopadłościan znikał przez mieszanie go z kolorem tła. Wykorzystaj do tego następujące funkcje GLSL: `mix`, `sin`, `vec4`. Opis ich działania możesz znaleźć w dokumentacji https://docs.gl/.
### Zadanie
Prześlij pozycję lokalną i globalną pozycję wierzchołków do shadera fragmentów i wyświetl ją.
W shaderze wierzchołków obok deklaracji `out vec4 color;` dodaj analogiczne o nazwie `pos_local` i `pos_global`. Do `pos_local` przypisz `vertexPosition`, a do `pos_global` przypisz `transformation * vertexPosition`. Podobnie dopisz odebranie ich w shaderze fragmentów. Użyj `pos_local`, następnie `pos_global` jako zamiast koloru. Dlaczego otrzymaliśmy taki efekt?
### Zadanie*
Użyj jednej ze zmiennych z poprzedniego zadania do zrobienia pasków na przynajmniej jednej ze ścian sześcianu. Wykorzystaj czas, żeby paski się przesuwały.

101
grk/cw 6/Zadania 4.html Normal file
View File

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Zadania 4</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<style>
.code-block {
background-color: #f4f4f4;
border-left: 5px solid #f36d33;
margin: 20px 0;
padding: 10px 20px;
font-family: Consolas, "Courier New", Courier, monospace;
color: #333;
overflow: auto;
}
</style>
<link rel="stylesheet" href="style.css" />
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<h2 id="ładowanie-obiektów-za-pomocą-assimpa">Ładowanie obiektów za pomocą Assimp</h2>
<p>W projekcie zaimplementowano ładowanie modeli przy użyciu biblioteki Assimp. Obiekty są ładowane za pomocą funkcji <code>loadModelToContext(std::string path, Core::RenderContext&amp; context)</code>. Pierwszym argumentem tej funkcji jest ścieżka, pod którą znajduje się model, a drugim jest referencja do <code>RenderContext</code>. Ta struktura przechowuje informacje o modelu, m.in. o jego VAO czy liczbie wierzchołków. Rysowanie obiektu odbywa się za pomocą funkcji <code>Core::DrawContext(Core::RenderContext&amp; context)</code>. Obecnie na przykładzie rysowana jest sfera ładowana z pliku.</p>
<p>Podczas poprzednich zadań zdefiniowaliśmy funkcje tworzące macierze widoku i projekcji. Aby narysować model, należy najpierw zdefiniować macierz modelu, przemnożyć ją przez macierz kamery i macierz widoku, a następnie wysłać ją do GPU i dopiero potem narysować model. Te operacje są bardzo powtarzalne, dlatego można je przenieść do osobnej funkcji. W pliku <code>ex_4_1.hpp</code> znajduje się funkcja <code>drawObjectColor</code>, która przyjmuje rysowany obiekt jako <code>Core::RenderContext&amp;</code>, macierz modelu jako <code>glm::mat4</code> oraz kolor jako <code>glm::vec3</code>. <h3 id="zadanie">Zadanie</h3> Wszystkie obiekty rysowane przez <code>drawObjectColor</code> są w jednym kolorze napraw to. Wewnątrz funkcji przekaż kolor jako <code>uniform</code> do GPU (za pomocą funkcji <code>glUniform3f</code>) i odpowiednio zmodyfikuj shader fragmentów, aby wyznaczyć go jako kolor wyjściowy.</p>
<p>Korzystając z tej funkcji, stwórz układ słoneczny z przynajmniej jedną planetą, która posiada księżyc. Planeta powinna poruszać się wokół słońca, a księżyc wokół planety.</p>
<h3 id="zadanie">Zadanie*</h3>
<p>Rozbuduj układ planetarny do przynajmniej 5 planet i pasa asteroid. Ściągnij z internetu/stwórz kilka prostych modeli asteroid, z których zbudujesz pas asteroid.</p>
<h3 id="zadanie-1">Zadanie</h3>
<p>Celem tego zadania jest dodanie statku, który będzie latać po układzie planetarnym.</p>
<p>Załaduj model statku, który jest w pliku <code>spaceship.obj</code>. Stwórz zmienne globalne <code>spaceshipPos</code> oraz <code>spaceshipDir</code>, które będą określać pozycję i kierunek, w którym statek się porusza. Później będziemy je zmieniać za pomocą przycisków, na razie wewnątrz funkcji <code>processInput</code> przypisz do nich odpowiednio <code>cameraPos+1.5*cameraDir+glm::vec3(0,-0.5f,0)</code> oraz <code>cameraDir</code>. W ten sposób po prawidłowym ustawieniu macierzy statek będzie znajdował się zawsze przed kamerą.</p>
<p>Przesuń i obróć statek w odpowiedni sposób. Przesunięcie zrealizujemy przez translację do <code>spaceshipPos</code> natomiast macierz statku liczy się tak samo, jak macierz kamery, tylko zamiast <code>-cameraDir</code> bierzemy <code>spaceshipDir</code> i na końcu trzeba tę macierz odwrócić (lub transponować, co jest tym samym, ponieważ mówimy o macierzy ortonormalnej).</p>
<h3 id="zadanie-2">Zadanie</h3>
<h3 id="zadanie-3">Zadanie*</h3>
<p>Obecnie klawisze regulują ustawienia kamery, do której jest podpięty statek. Zmodyfikuj aplikację, aby klawisze umożliwiały poruszanie się statkiem, a kamera podążała za nim. W tym celu w obsłudze klawiatury modyfikuj wektory <code>spaceshipPos</code> i <code>spaceshipDir</code>. Następnie dostosuj <code>cameraPos</code> i <code>cameraDir</code> w zależności od wektorów <code>spaceshipPos</code> i <code>spaceshipDir</code>.</p>
<h3 id="zadanie-4">Zadanie*</h3>
<p>Obecnie szybkość ruchu statku lub kamery zależy od liczby klatek, co może powodować różne efekty na różnych komputerach, co nie jest pożądane. Aby to skorygować, musimy obliczyć czas, jaki upłynął między poszczególnymi klatkami i dostosować do niego przesunięcia oraz obroty. Utwórz zmienne globalne <code>float lastFrameTime</code> oraz <code>float deltaTime</code>, następnie w funkcji <code>renderScene</code> dodaj oblicz <code>deltaTime = time-lastFrameTime</code> i przypisz do zmiennej <code>lastFrameTime</code> wartość <code>time</code>. Nie chcemy, żeby wartość <code>deltaTime</code> była zbyt duża, gdy nagle spadnie liczba klatek, dlatego ucinamy ją od góry przez <code>0.1</code>.</p>
<p>Wykorzystaj <code>deltaTime</code> w funkcji <code>processInput</code> aby uniezależnić prędkość poruszania się od liczby klatek na sekundę.</p>
<h3 id="zadanie-5">Zadanie*</h3>
<p>Zastąp model statku innym modelem.</p>
<h2 id="bufor-głębokości">Bufor głębokości</h2>
<p>Bufor głębokości rejestruje odległość danego piksela od kamery. Pozwala to podczas rysowania kolejnych obiektów odrzucić piksele, które znajdowałyby się za już narysowanymi. Ten mechanizm jest automatycznie, żeby go uruchomić, wystarczy dodać instrukcję <code>glEnable(GL_DEPTH_TEST)</code>, poza tym przed rysowaniem klatki należy wyczyścić bufor głębokości, co robimy w instrukcji <code>glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)</code>.</p>
<h3 id="zadanie-7">Zadanie</h3>
<p>Sprawdź, co się stanie, gdy nie włączymy <code>glEnable(GL_DEPTH_TEST)</code> oraz sprawdź co, się dzieje, gdy nie czyścimy żadnego bufora lub gdy czyścimy tylko bufor koloru czy tylko bufor głębokości. Dlaczego dzieje się to, co widzisz?</p>
<h2 id="wizualizacja-bufora-głębokości">Wizualizacja bufora głębokości</h2>
<p>W tej części zwizualizujemy jak wygląda bufor głębokości przy pomocy skali szarości. Zrealizujemy poprzez napisanie odpowiedniego shadera.</p>
<blockquote>
<p><strong>Uwaga</strong> nie jest to faktycznie rysowanie bufora głębokości, to wymagałoby stworzenie FrameBufferObject renderowanie głębokości do niego i narysowanie wyniku na ekranie. Zrobimy to na późniejszych zajęciach przy okazji rysowania cieni.</p>
</blockquote>
<p>Wykorzystamy wbudowaną zmienną <code>gl_FragCoord</code> we fragment shaderze. Zawiera ona informacje o pozycji fragmentu.</p>
<h3 id="zadanie-8">Zadanie</h3>
<p>We fragment shaderze podmień wartości R G B w shaderze fragmentów na <code>gl_FragCoord.z</code>.</p>
<p>Zauważ, że obiekty są bardzo jasne i stają się ciemniejsze, dopiero gdy kamera podjedzie bardzo blisko. Wynika to z tego, że wartości <code>z</code> w <code>gl_FragCoord</code> nie są liniowe ze względu na rzutowanie perspektywiczne omówione na poprzednich zajęciach. Poniższy wykres prezentuje przykładową różnicę między faktyczną wartością a wartością w <code>gl_FragCoord</code>. <img src="./img/z_depth_graph2.jpg" /></p>
<p>My chcielibyśmy wyświetlać je liniowo. W tym celu będziemy musieli wrócić do współrzędnych w przestrzeni świata. Zauważ, że wartości <code>gl_FragCoord.z</code> są z zakresu od <span class="math inline">\([0,1]\)</span> a nie <span class="math inline">\([-1,1]\)</span> jak są zapisane współrzędne w przestrzeni ekranu. Dlatego pierwszym krokiem będzie przekonwertowanie ich (poprzez pomnożenie przez 2 i odjęcie 1). Współrzędne w przestrzeni ekranu obliczamy wzorem <span class="math display">\[z&#39;=-\frac{(n + f)}{(n - f)}- \frac{(2 n f)}{z(n - f)}.\]</span>My chcemy obliczyć <span class="math inline">\(z\)</span> po przekształceniu wzoru otrzymujemy: <span class="math display">\[z=\frac{-2nf}{z&#39;(n-f)+n+f}.\]</span> <h3 id="zadanie-9">Zadanie</h3> We fragment shaderze uwórz funkcję, która oblicza <span class="math inline">\(z\)</span> i wyświetl zlinearyzowaną odległość. Pamiętaj, że wartość <span class="math inline">\(z\)</span> jest z zakresu od <span class="math inline">\(n\)</span> do <span class="math inline">\(f\)</span>, dlatego zmień podziel ją przez <span class="math inline">\(-f\)</span> przed rysowaniem.</p>
<h3 id="zadanie-9">Zadanie</h3>
<p>Wykorzystaj informację o odległości, żeby dodać do sceny efekt mgły. Zmieszaj kolor (funkcja "mix" w glsl) obiektu z kolorem tła, jako współczynnik weź wartość z poprzedniego zadania.</p>
<h2 id="kreatywne-wykorzystanie-bufora-głębokości">Kreatywne wykorzystanie bufora głębokości</h2>
<p>Czasem chcielibyśmy, żeby niektóre wyświetlane elementy były inaczej traktowane przez bufor głębokości. Przykładowo chcielibyśmy stworzyć bardziej złożone tło dla naszej sceny. Chcemy wtedy, żeby to tło było ,,za każdym innym obiektem w scenie. Możemy to osiągnąć poprzez namalowanie tła na początku, a następnie usunięcie zawartości bufora głębokości.</p>
<h3 id="zadanie-10">Zadanie*</h3>
<p>Dodaj jakiś rodzaj tła w sposób opisany powyżej. Mogą być to na przykład małe sfery udające gwiazdy. Prostokąt w przestrzeni ekranu, który będzie zmieniał kolory czy kręcący się prostopadłościan.</p>
<h2 id="kreatywne-wykorzystanie-bufora-głębokości">Implementacja ruchu kamery w symulatorze kosmicznym bez synchronizacji modelu statku</h2>
<h3 id="zadanie-6">Zadanie*</h3>
<p>W tym ćwiczeniu zajmiemy się implementacją systemu kontroli kamery, który pozwoli na interaktywne sterowanie widokiem w symulatorze lotu. Będzie to wymagało obsługi wejścia myszy do kontroli ruchów pitch i yaw. Dodaj nastepujace zmienne globalne do kodu.
<pre class="code-block"><code>
float pitch = 0.0f;
float yaw = -90.0f;
float lastX = 800.0f / 2.0;
float lastY = 600.0 / 2.0;
bool firstMouse = true;
</code></pre></p>
Zaimplementuj w funkcji processinput logikę odpowiedzialną za przetwarzanie wejścia myszy. Użyj funkcji glfwGetCursorPos do uzyskania bieżącej pozycji kursora. Dodaj zmienną sensitivity do regulacji czułości myszy. Na początku sprawdzamy, czy jest to pierwsze uchwycenie pozycji myszy po uruchomieniu aplikacji. Jeśli tak, to zapisujemy bieżącą pozycję myszy jako punkt odniesienia (lastX i lastY) i ustawiamy zmienną firstMouse na false. To zapobiega gwałtownemu skoku kamery, gdybyśmy po raz pierwszy poruszyli myszą. Następnie obliczamy różnicę (xoffset i yoffset) między aktualną pozycją kursora a ostatnią zapisaną pozycją. Zauważ, że wartość yoffset jest odwrócona, ponieważ w systemach okienkowych współrzędna y zwykle rośnie w dół ekranu, a chcemy, aby ruch w górę odpowiadał wzrostowi kąta widzenia kamery. Po obliczeniu przesunięć skalujemy je wartością sensitivity, która pozwala na dostosowanie reakcji kamery na ruch myszy. Mała wartość czułości sprawi, że kamera będzie reagować łagodniej, podczas gdy większa wartość uczyni ruchy bardziej gwałtownymi. Na koniec, dodajemy przeskalowane przesunięcia do naszych kątów orientacji kamery: yaw (odpowiedzialny za obrót wokół osi pionowej) i pitch (odpowiedzialny za obrót wokół osi poziomej). Trzeba tu uważać, aby nie przekroczyć pewnych granic. Na przykład, nie chcemy, aby kamera "przewracała się" do góry nogami, dlatego ograniczamy kąt pitch do wartości pomiędzy -89 a 89 stopni. Dodaj logikę do ograniczenia kąta pitch, aby uniknąć "przewrócenia" kamery.
<pre class="code-block"><code> if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
</code></pre></p>
Zastosuj funkcje trygonometryczne do przeliczenia kątów na wektor kierunku kamery:<pre class="code-block"><code>
glm::vec3 front;
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
cameraDir = glm::normalize(front);</code></pre></p>
Na zakończenie ćwiczenia oczekujemy, że symulator będzie poprawnie implementował ruch kamery, lecz dołączony model statku kosmicznego nie będzie jeszcze obracał się razem z kamerą.
</body>
</html>

74
grk/cw 6/Zadania 4.md Normal file
View File

@ -0,0 +1,74 @@
## Ładowanie obiektów za pomocą assimpa
W projekcie zaimplentowane jest ładowanie modeli z użyciem biblioteki assimp. Obiekty ładuje się za pomocą funkcji `loadModelToContext(std::string path, Core::RenderContext& context)` pierwszym jej argumentem jest ścieżka, pod którą znajduje się model, drugim argumentem jest referencja do `RenderContext`. Ta struktura przechowuje informacje o modelu, m.in. jego VAO czy liczba wierzchołku. Rysuje się go za pomocą funkcji `Core::DrawContext(Core::RenderContext& context)`. Teraz przykładowo rysowana jest sfera ładowana z pliku.
W trakcie poprzednich zadań zdefiniowaliśmy funkcje tworzące macierze widoku i projekcji. Aby narysować model, należy najpierw zdefiniować macierz modelu, przemnożyć ją przez macierz kamery i macierz widoku i wysłać ją do GPU i dopiero narysować model. Te operacje są bardzo powtarzalne i można je przenieść do osobnej funkcji. Dlatego w `ex_4_1.hpp` znajduje funkcja `drawObjectColor` która przyjmuje rysowany obiekt jako `Core::RenderContext&`, macierz modelu jako `glm::mat4` i kolor jako `glm::vec3`.
### Zadanie
Wszystkie obiekty rysowane przez `drawObjectColor` rysują się na jeden kolor, napraw to. Wewnątrz funkcji prześlij kolor jako `uniform` do GPU (za pomocą funkcji `glUniform3f`) i tak zmodyfikuj shader fragmentów, żeby ustalić go kolorem wyjściowym.
Korzystając z tej funkcji, stwórz układ słoneczny z przynajmniej jedną planetą, która posiada księżyc. Planeta powinna poruszać się wokół słońca a księżyc wokół planety.
### Zadanie*
Rozbuduj układ planetarny do przynajmniej 5 planet i pasa asteroid. Ściągnij z internetu/stwórz kilka prostych modeli asteroid, z których zbudujesz pas asteroid.
### Zadanie
Celem tego zadania jest dodanie statku, który będzie latać po układzie planetarnym.
Załaduj model statku, który jest w pliku `spaceship.obj`. Stwórz zmienne globalne `spaceshipPos` oraz `spaceshipDir`, które będą określać pozycję i kierunek, w którym statek się porusza. Później będziemy je zmieniać za pomocą przycisków, na razie wewnątrz funkcji `processInput` przypisz do nich odpowiednio `cameraPos+1.5*cameraDir+glm::vec3(0,-0.5f,0)` oraz `cameraDir`. W ten sposób po prawidłowym ustawieniu macierzy statek będzie znajdował się zawsze przed kamerą.
Przesuń i obróć statek w odpowiedni sposób. Przesunięcie zrealizujemy przez translację do `spaceshipPos` natomiast macierz statku liczy się tak samo, jak macierz kamery, tylko zamiast `cameraDir` bierzemy `spaceshipDir` i na końcu trzeba tę macierz odwrócić (lub transponować, co jest tym samym, ponieważ mówimy o macierzy ortonormalnej).
Możliwe, że model nie jest skierowany w stronę tej samej osi, co domyślnie w openGL, w tym wypadku musisz dodać dodatkową rotację o stały kąt, która naprawi ten problem.
### Zadanie
### Zadanie*
W tej chwili klawisze ustawiają kamerę, do której podczepiony jest statek. Zmodyfikuj aplikację, żeby klawisze przesuwały statek, a kamera była do niego podczepiona. Aby to zrobić, wystarczy w obsłudze klawiatury modyfikować wektory `spaceshipPos` i `spaceshipDir`. Natomiast `cameraPos` i `cameraDir` uzależnić od wektorów `spaceshipPos` i `spaceshipDir`.
### Zadanie*
W tej chwili szybkość poruszania się statku/kamery jest uzależniona od liczby klatek, co daje różne efekty na różnych komputerach i jest raczej niepożądane. Aby to naprawić, musimy obliczyć, ile czasu minęło między klatkami i od tego uzależnić przesunięcia oraz obroty. Utwórz zmienne globalne `float lastFrameTime` oraz `float deltaTime`, następnie w funkcji `renderScene` dodaj oblicz `deltaTime = time-lastFrameTime` i przypisz do zmiennej `lastFrameTime` wartość `time`. Nie chcemy, żeby wartość `deltaTime` była zbyt duża, gdy nagle spadnie liczba klatek, dlatego ucinamy ją od góry przez `0.1`.
Wykorzystaj `deltaTime` w funkcji `processInput` aby uniezależnić prędkość poruszania się od liczby klatek na sekundę.
### Zadanie*
Podmień model statku na jakiś inny.
### Zadanie**
dodaj obsługę myszki, która będzie obracać kamerą.
## Bufor głębokości
Bufor głębokości zapisuje, w jakiej odległości od kamery znajduje dany piksel. Dzięki temu przy rysowaniu kolejnych obiektów można odrzucić te piksele, które znajdowałyby się za narysowanymi. Ten mechanizm jest automatycznie, żeby go uruchomić, wystarczy dodać instrukcję `glEnable(GL_DEPTH_TEST)`, poza tym przed rysowaniem klatki należy wyczyścić bufor głębokości, co robimy w instrukcji `glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)`.
### Zadanie
Sprawdź, co się stanie, gdy nie włączymy `glEnable(GL_DEPTH_TEST)` oraz sprawdź co, się dzieje, gdy nie czyścimy żadnego bufora lub gdy czyścimy tylko bufor koloru czy tylko bufor głębokości. Dlaczego dzieje się to, co widzisz?
## Wizualizacja bufora głębokości
W tej części zwizualizujemy jak wygląda bufor głębokości przy pomocy skali szarości. Zrealizujemy poprzez napisanie odpowiedniego shadera.
> **Uwaga** nie jest to faktycznie rysowanie bufora głębokości, to wymagałoby stworzenie FrameBufferObject renderowanie głębokości do niego i narysowanie wyniku na ekranie. Zrobimy to na późniejszych zajęciach przy okazji rysowania cieni.
Wykorzystamy wbudowaną zmienną `gl_FragCoord` we fragment shaderze. Zawiera ona informacje o pozycji fragmentu.
### Zadanie
We fragment shaderze podmień wartości R G B w shaderze fragmentów na `gl_FragCoord.z`.
Zauważ, że obiekty są bardzo jasne i stają się ciemniejsze, dopiero gdy kamera podjedzie bardzo blisko. Wynika to z tego, że wartości `z` w `gl_FragCoord` nie są liniowe ze względu na rzutowanie perspektywiczne omówione na poprzednich zajęciach. Poniższy wykres prezentuje przykładową różnicę między faktyczną wartością a wartością w `gl_FragCoord`.
![](./img/z_depth_graph2.jpg)
My chcielibyśmy wyświetlać je liniowo. W tym celu będziemy musieli wrócić do współrzędnych w przestrzeni świata.
Zauważ, że wartości `gl_FragCoord.z` są z zakresu od $[0,1]$ a nie $[-1,1]$ jak są zapisane współrzędne w przestrzeni ekranu. Dlatego pierwszym krokiem będzie przekonwertowanie ich (poprzez pomnożenie przez 2 i odjęcie 1). Współrzędne w przestrzeni ekranu obliczamy wzorem $$z'=-\frac{(n + f)}{(n - f)}- \frac{(2 n f)}{z(n - f)}.$$My chcemy obliczyć $z$ po przekształceniu wzoru otrzymujemy:
$$z=\frac{-2nf}{z'(n-f)+n+f}.$$
### Zadanie
We fragment shaderze uwórz funkcję, która oblicza $z$ i wyświetl zlinearyzowaną odległość. Pamiętaj, że wartość $z$ jest z zakresu od $n$ do $f$, dlatego zmień podziel ją przez $f$ przed rysowaniem.
### Zadanie*
Wykorzystaj informację o odległości, żeby dodać do sceny efekt mgły. Zmieszaj kolor obiektu z kolorem tła, jako współczynnik weź wartość z poprzedniego zadania.
## Kreatywne wykorzystanie bufora głębokości
Czasem chcielibyśmy, żeby niektóre wyświetlane elementy były inaczej traktowane przez bufor głębokości. Przykładowo chcielibyśmy stworzyć bardziej złożone tło dla naszej sceny. Chcemy wtedy, żeby to tło było ,,za'' każdym innym obiektem w scenie. Możemy to osiągnąć poprzez namalowanie tła na początku, a następnie usunięcie zawartości bufora głębokości.
### Zadanie
Dodaj jakiś rodzaj tła w sposób opisany powyżej. Mogą być to na przykład małe sfery udające gwiazdy. Prostokąt w przestrzeni ekranu, który będzie zmieniał kolory czy kręcący się prostopadłościan.

92
grk/cw 6/Zadania 5.md Normal file
View File

@ -0,0 +1,92 @@
## Oświetlenie Phonga
W trakcie tych zajęć zajmiemy się implementacją modelu oświetlenia Phonga. Na poprzednich zajęciach zbudowaliśmy układ słoneczny. Wykorzystamy go w trakcie tych zajęć. Jeżeli go zrobiłeś, to przekopiuj do `ex_5_1.hpp` kod z poprzednich zajęć. W przeciwnym wypadku wykorzystaj ten, który jest zaimplementowany w `ex_5_1.hpp`. W zadaniu będzie nam potrzebny statek latający przed kamerą, jak nie ma tego w Twojej scenie to skopiuj to z `ex_5_1.hpp`.
## Zadanie - *diffuse*
Oblicz we fragment shaderze oświetlenie obiektu przy użyciu modelu Phonga dla odbicia rozproszonego (*diffuse)
1. Przekaż źródło światła. Na razie przyjmiemy kierunkowy model oświetlenia, dlatego źródło będzie opisane jako wektor kierunkowy:
- Prześlij do shadera fragmentów zmienna typu `uniform vec3` (nazwij ją np. `lightDir`), w której będzie się znajdować wektor kierunkowy.
- Należy to zrobić podobnie do tego, jak przesyłany jest kolor.
- Jako kierunek światła wybierz dowolny wektor jednostkowy. (Możesz wziąć dowolny niezerowy wektor następnie go znormalizować).
* Dodatkowo prześlij drugą zmienną `uniform vec3 lightColor`, w której umieścimy kolor światła. Prześlij tam wartości ze zmiennej `glm::vec3 lightColor`.
2. Oblicz natężenie w shaderze fragmentów:
- prześlij normalne z shadera fragmentów do shadera wierzchołków
- znormalizuj wektor normalny przed użyciem go w obliczeniach (uśrednianie wektorów normalnych wierzchołków może spowodować, że przestaje one być jednostkowe).
- Natężenie to iloczyn skalarny wektora normalnego powierzchni i odwrotnego wektora kierunku padania światła. Skorzystaj z funkcji `dot`.
- Natężenie nie może być ujemne. Przytnij natężenie do zera przy użyciu: `x = max(x, 0.0)`
3. Zastosuj obliczone natężenie, aby zmodyfikować kolor obiektu:
- Przemnóż kolor RGB fragmentu przez obliczone natężenie i przez kolor światła z `lightColor`.
## Zadanie - obsługa obrotów
Dlaczego oświetlenie statku nie zmienia się podczas jego obracania?
(Wektory normalne są w układzie lokalnym modelu, a wektor padania światła w układzie świata)
Należy wykonać transformacje wektorów normalnych do przestrzeni świata:
- Prześlij macierz modelu rysowanego obiektu (_model Matrix_) jako osobna zmienna do vertex shadera (`uniform mat4`).
- Przemnóż przez te macierz wektor normalny wierzchołka przed przesłaniem go do shadera fragmentów.
- Współrzędna **w** dopisana do wektora przed mnożeniem przez macierz powinna być ustawiona na 0. Wynika to z tego, że w przypadku transformacji wektorów reprezentujących kierunki w przestrzeni, nie chcemy dokonywać translacji — np. wektor normalny do powierzchni zależy od orientacji obiektu, ale nie od jego pozycji (przesunięcia) w przestrzeni świata.
## Zadanie - *specular*
Uzupełnił model o czynnik odbicia zwierciadlanego (*specular*). W tym celu:
1. Potrzebny będzie wektor od rysowanego fragmentu do pozycji kamery:
- Wyślij pozycje kamery (`cameraPos`) jako kolejna zmienna do fragment shadera.
- Podobnie jak wektory normalne prześlij z vertex do fragment shadera pozycje wierzchołków (`vertexPosition`) w przestrzeni świata (czyli pomnożone przez macierz **modelMatrix**). Pamiętaj, że tym razem wektory reprezentują punkty, a nie kierunki - współrzędna **w** przed mnożeniem musi być ustawiona na 1. W wyniku rasteryzacji otrzymamy w shaderze fragmentu jego pozycję (nazywaną pozycją fragmentu)
- Oblicz wektor **V** (_view direction_) jako znormalizowaną różnice pozycji kamery i pozycji fragmentu.
2. Oblicz natężenie światła odbitego we _fragment shaderze_:
- Oblicz wektor kierunku odbicia światła **R** przy użyciu funkcji [`reflect`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/reflect.xhtml). Pamiętaj, żeby przesłać do funkcji odwrócony wektor kierunku światła.
- Oblicz natężenie: iloczyn skalarny **V** i **R**, przycięty do zera ( `max(...,0.0)` ), a następnie podniesiony do wysokiej potęgi (np. 8, 50, 1000), która jest miara połyskliwości powierzchni.
3. Ustal ostateczny kolor piksela na `objectColor * diffuse + lightColor * specular`. Oznacza to najprostszy przypadek, gdy kolor światła odbitego jest biały.
## Zadanie - oświetlenie punktowe
W układzie planetarnym obiektem oświetlającym powinno być słońce, dlatego zamień oświetlenie kierunkowe na punktowe:
- Zamiast przesyłać (w `lightDir`) kierunek światła, prześlij pozycję słońca do fragment shadera (taką jak ustawiłeś w punkcie powyżej) jako uniform vec3 (nazwij go `lightPos`).
- Oblicz kierunek światła odejmując od pozycji fragmentu pozycję światła, znormalizuj wynik. Zapisz wynik w zmiennej `lightDir`.
- Słońce będzie czarne, nie martw się tym, tylko spójrz na punkt następny.
## Zadanie - shader słońca
Źródło światła znajduje się wewnątrz kuli, która reprezentuje słońce, dlatego jest czarna. By to naprawić, utwórz osobny shader, który będzie odpowiadać za renderowanie słońca.
Celem tego zadania jest stworzenie shadera (**shader_4_sun.vert**_ i **shader_4_sun.frag**), który będzie odpowiadał wyłącznie za rysowanie słońca. Poprzednie shadery (**shader_4_1.vert**_ i **shader_4_1.frag**) nadal mają rysować pozostałe obiekty. a) zainicjalizuj _program_ (shadery): - Pliki **shader_4_sun.vert** i **shader_4_sun.frag** są identyczne z 4_1** przed zmianami, będą punktem wyjścia dla _shadera_ słońca.
1. Utwórz zmienną globalną `GLuint programSun` na adres shadera słońca. Stwórz _program_ za pomocą `shaderLoader.CreateProgram` analogicznie jak tworzy się `program` z **shader_4_1.vert** i **shader_4_1.frag** (parametry wejściowe to ścieżka do shadera wierzchołków i fragmentów **shader_4_sun.vert** i **shader_4_sun.frag**).
2. W skomplikowanym projekcie różne typy obiektów rysuje się przy użyciu różnych shaderów, zate potrzebna jest w programie architektura, która na to pozwala. Ustaw odpowiedni _program_ (shadery) do rysowania słońca:
- funkcja `drawObject` korzysta z globalnej zmiennej `program`, żeby wskazywać shadery do rysowania. Dodaj argument do funkcji, który będziesz przekazywać adres _programu_, który ma być wykorzystany do rysowania.
- dodaj odpowiedni _program_ w wywołaniach `drawObject`.
## Osłabienie światła, tone mapping
### Zadanie - Osłabienie światła (attenuation)
Światło pochodzące z punktowego źródła traci na sile wraz z dystansem. Wynika to z tego, że rozprasza się na większą powierzchnię.
Dodaj ten efekt do shadera. Zamiast brać kolor światła bezpośrednio, podziel go przez kwadrat dystansu od źródła świata.
#### Tone mapping
Przez obecną zmianę scena stała się ciemna. Wymaga to od nas zmiany 'koloru' światła na wartości dużo większe niż do tej pory. Jeśli teraz to zrobimy i przesadzimy w drugą stronę, otrzymamy efekt prześwietlenia. Wynika to z ograniczenia zakresu kolorów do $[0,1]$ (obsługą wyższych wartości nazywamy HDR). Rozwiązaniem jest pracowanie na wartościach powyżej 1 wykorzystanie *tone mappingu* do przeniesienia ich w zakres $[0,1]$. Istnieje wiele wzorów, które są wykorzystywane do tego, jeden z nich to:
$$C_{mapped} = 1-e^{-C * E},$$
gdzie C to kolor sceny a E to parametr ekspozycji (z zakresu $(0,\infty)$, który może być dostosowany w zależności od jasności.
### Zadanie - Tone mapping*
Zwiększ siłę słońca przynajmniej stukrotnie. Zaimplementuj powyższą metodę tone mappingu i dodaj możliwość sterowania ekspozycją za pomocą klawiszy 1 i 2.
### Zadanie*
Dodaj drugie źródło oświetlenia w postaci reflektora statku. Reflektor świeci tylko w określonym stożku,dlatego oprócz pozycji `spotPos` posiada również kierunek `spotDir` i kąt świecenia $\phi$. Po obliczeniu dla niego `lightDir` należy sprawdzić, czy iloczyn skalarny pomiędzy `lightDir` a `spodDir` jest większy niż $\cos\phi$ . Jeżeli nie jest, to stożek nie świeci w tym miejscu. Można ułatwić sobie implementację wielu źródeł światła poprzez przeniesienie obliczeń oświetlenia do funkcji, która przyjmuje kierunek światła i siłę naświetlenie.
Zwróć uwagę, że SpotDir to co innego niż light Dir w poprzednich zadaniach
![](./img/spotlight.png)
## Zmień shader słońca na bardziej realistyczny.
### Zadanie*
Na poniższym obrazku jest zdjęcie słońca. Jest ono ciemniejsze na brzegach spróbuj uzyskać podobny efekt. Przydadzą się wektory z poprzednich punktów jak wektor normalny i wektor **V**.
![](./img/sun.png)

View File

@ -11,7 +11,6 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Box.cpp" />
<ClCompile Include="src\Camera.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\Render_Utils.cpp" />
@ -24,7 +23,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Camera.h" />
<ClInclude Include="src\ex_6_1.hpp" />
<ClInclude Include="src\Planet.hpp" />
<ClInclude Include="src\objload.h" />
<ClInclude Include="src\Render_Utils.h" />
<ClInclude Include="src\Shader_Loader.h" />
@ -37,33 +36,33 @@
<ClInclude Include="src\Texture.h" />
</ItemGroup>
<ItemGroup>
<None Include="shaders\shader_5_1.frag" />
<None Include="shaders\shader_5_1.vert" />
<None Include="shaders\shader_5_1_tex.frag" />
<None Include="shaders\shader_5_1_tex.vert" />
<None Include="shaders\shader_5_sun.frag" />
<None Include="shaders\shader_5_sun.vert" />
<None Include="shaders\shader.frag" />
<None Include="shaders\shader.vert" />
<None Include="shaders\shader_tex.frag" />
<None Include="shaders\shader_tex.vert" />
<None Include="shaders\shader_sun.frag" />
<None Include="shaders\shader_sun.vert" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3952C396-B1C6-44CD-96DD-C1AC15D32978}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>grk-cw6</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>grk-cw6</ProjectName>
<WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
<ProjectName>Planeta</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@ -93,6 +92,8 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpp14</LanguageStandard>
<AdditionalIncludeDirectories>D:\STUDIA\Planeta\grk\cw 6\src\imgui-master;D:\STUDIA\Planeta\grk\cw 6\src\imgui-master\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -110,6 +111,8 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpp14</LanguageStandard>
<AdditionalIncludeDirectories>D:\STUDIA\Planeta\grk\cw 6\src\imgui-master;D:\STUDIA\Planeta\grk\cw 6\src\imgui-master\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View File

@ -27,9 +27,6 @@
<ClCompile Include="src\Shader_Loader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Box.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Camera.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -86,27 +83,27 @@
<ClInclude Include="src\SOIL\image_DXT.h">
<Filter>Source Files\SOIL</Filter>
</ClInclude>
<ClInclude Include="src\ex_6_1.hpp">
<ClInclude Include="src\Planet.hpp">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="shaders\shader_5_sun.frag">
<None Include="shaders\shader_sun.frag">
<Filter>Shader Files</Filter>
</None>
<None Include="shaders\shader_5_sun.vert">
<None Include="shaders\shader_sun.vert">
<Filter>Shader Files</Filter>
</None>
<None Include="shaders\shader_5_1.frag">
<None Include="shaders\shader.frag">
<Filter>Shader Files</Filter>
</None>
<None Include="shaders\shader_5_1.vert">
<None Include="shaders\shader.vert">
<Filter>Shader Files</Filter>
</None>
<None Include="shaders\shader_5_1_tex.vert">
<None Include="shaders\shader_tex.vert">
<Filter>Shader Files</Filter>
</None>
<None Include="shaders\shader_5_1_tex.frag">
<None Include="shaders\shader_tex.frag">
<Filter>Shader Files</Filter>
</None>
</ItemGroup>

View File

@ -1,315 +0,0 @@
# Blender v2.90.0 OBJ File: 'spaceship.blend'
# www.blender.org
mtllib spaceship.mtl
o spaceship
v -0.466043 -0.046099 0.061004
v -0.496632 -0.038727 -0.744142
v -0.284772 -0.093266 -0.411636
v -0.169612 -0.147446 -0.381196
v -0.169612 -0.147446 0.061004
v -0.091309 -0.100093 0.472421
v -0.182617 -0.069341 0.472421
v -0.182617 -0.001722 0.472421
v -0.466043 0.045632 0.061004
v -0.647568 0.071442 -0.238048
v -0.169612 0.164038 0.061004
v -0.284772 0.045632 -0.411636
v -0.169612 0.116537 -0.381196
v -0.053437 -0.049075 0.720448
v -0.053437 -0.102143 0.720448
v -0.040834 -0.049075 0.734564
v -0.040834 -0.102143 0.734564
v 0.000000 -0.049075 0.744142
v 0.000000 -0.118734 0.744142
v 0.040834 -0.049075 0.734564
v 0.000000 0.045779 0.472421
v 0.000000 -0.116684 0.472421
v 0.091309 -0.100093 0.472421
v 0.040834 -0.102143 0.734564
v 0.000000 0.116537 -0.350755
v 0.000000 0.164038 0.061004
v 0.169612 -0.147446 -0.381196
v 0.000000 -0.164038 -0.350755
v 0.169612 0.164038 0.061004
v 0.169612 0.116537 -0.381196
v 0.000000 -0.164038 0.061004
v 0.169612 -0.147446 0.061004
v -0.647568 -0.038727 -0.238048
v -0.496632 0.071442 -0.744142
v -0.091309 0.045779 0.472421
v 0.466043 -0.046099 0.061004
v 0.647568 0.071442 -0.238048
v 0.466043 0.045632 0.061004
v 0.496632 -0.038727 -0.744142
v 0.647568 -0.038727 -0.238048
v 0.284772 -0.093266 -0.411636
v 0.182617 -0.001722 0.472421
v 0.182617 -0.069341 0.472421
v 0.284772 0.045632 -0.411636
v 0.053437 -0.049075 0.720448
v 0.053437 -0.102143 0.720448
v 0.496632 0.071442 -0.744142
v 0.091309 0.045779 0.472421
vt 0.542758 0.543965
vt 0.356004 0.244407
vt 0.504680 0.319696
vt 0.553316 0.302407
vt 0.649859 0.471001
vt 0.766053 0.611338
vt 0.733075 0.633795
vt 0.942531 0.273938
vt 0.916601 0.470616
vt 0.908930 0.272020
vt 0.906245 0.133229
vt 0.060793 0.659810
vt 0.095301 0.442790
vt 0.182444 0.620892
vt 0.912119 0.905444
vt 0.989612 0.943366
vt 0.900946 0.955153
vt 0.229586 0.822972
vt 0.045790 0.812939
vt 0.871970 0.876051
vt 0.270733 0.797357
vt 0.928563 0.581569
vt 0.948002 0.582679
vt 0.928200 0.588981
vt 0.833604 0.696984
vt 0.841128 0.699424
vt 0.941370 0.472030
vt 0.927606 0.601110
vt 0.953122 0.602566
vt 0.116239 0.298971
vt 0.134935 0.296266
vt 0.170287 0.416872
vt 0.947639 0.590091
vt 0.858040 0.692927
vt 0.798664 0.589407
vt 1.000000 0.000000
vt 0.975078 0.013585
vt 0.974484 0.001457
vt 0.830416 0.568707
vt 0.869911 0.680359
vt 0.785184 0.955792
vt 0.850736 0.970525
vt 0.334379 0.757520
vt 0.252163 0.593452
vt 0.740866 0.846584
vt 0.807753 0.855379
vt 0.321881 0.566013
vt 0.410170 0.742478
vt 0.620171 0.273802
vt 0.672876 0.223217
vt 0.710068 0.430790
vt 0.769418 0.391811
vt 0.946599 0.135534
vt 0.413299 0.472597
vt 0.208789 0.994633
vt 0.953122 0.002304
vt 0.980750 0.982793
vt 0.912767 0.000000
vt 0.101366 0.309478
vt 0.132755 0.431644
vt 0.099001 0.317265
vt 0.989409 0.328628
vt 0.953122 0.469337
vt 0.955808 0.330547
vt 0.871271 0.326374
vt 0.706080 0.012535
vt 0.869769 0.170254
vt 0.705415 0.186739
vt 0.963479 0.131951
vt 0.988248 0.130536
vt 0.443922 0.509019
vt 0.463695 0.730833
vt 0.578150 0.603414
vt 0.692001 0.855970
vt 0.680828 0.905679
vt 0.605734 0.857085
vt 0.719632 0.941058
vt 0.975441 0.020998
vt 0.994879 0.019888
vt 0.142931 0.299975
vt 0.245429 0.383703
vt 0.994516 0.012475
vt 0.871271 0.672035
vt 0.861802 0.548533
vt 0.993477 0.467033
vt 1.000000 0.600262
vt 0.959645 0.602566
vt 0.617066 0.833945
vt 0.596872 0.896513
vt 0.207819 0.402100
vn -0.2502 -0.9682 0.0006
vn -0.3235 -0.9462 -0.0000
vn -0.3158 -0.9343 0.1651
vn -0.3186 -0.9329 0.1677
vn -0.3148 -0.9349 0.1641
vn -0.8235 0.0000 0.5673
vn -0.8548 0.0000 0.5189
vn -0.3487 0.8731 0.3407
vn 0.8434 0.0000 -0.5374
vn -0.4103 -0.9095 -0.0666
vn 0.0862 0.9958 0.0321
vn 0.0832 0.9962 0.0257
vn 0.0868 0.9957 0.0333
vn 0.2556 0.0000 -0.9668
vn -0.5043 0.8586 -0.0922
vn -0.8869 0.0000 0.4619
vn -0.7459 0.0000 0.6660
vn 0.0112 -0.9999 -0.0100
vn -0.2284 0.0000 0.9736
vn 0.0771 0.9413 0.3286
vn -0.1788 -0.9839 -0.0074
vn 0.2284 0.0000 0.9736
vn 0.3892 -0.9187 0.0677
vn 0.1766 0.0000 -0.9843
vn 0.0000 0.9934 -0.1146
vn -0.1766 0.0000 -0.9843
vn -0.0192 0.9941 -0.1068
vn 0.0974 -0.9952 -0.0000
vn -0.0974 -0.9952 -0.0000
vn -0.0965 -0.9866 0.1319
vn 0.1776 -0.9776 0.1125
vn -0.0272 -0.9996 -0.0081
vn 0.0827 0.9963 0.0247
vn -0.9583 -0.0000 -0.2858
vn -0.3892 -0.9187 0.0677
vn 0.0000 0.9403 0.3403
vn -0.4230 0.8237 0.3776
vn -0.4240 0.8230 0.3780
vn -0.4228 0.8239 0.3775
vn 0.0192 0.9941 -0.1068
vn -0.3672 0.9194 -0.1408
vn 0.0000 0.9611 0.2763
vn -0.4366 0.8392 0.3243
vn -0.3189 -0.9328 0.1681
vn -0.4270 0.8209 0.3792
vn -0.0771 0.9413 0.3286
vn -0.1776 -0.9776 0.1125
vn 0.1788 -0.9839 -0.0074
vn -0.3189 -0.9469 0.0409
vn 0.8548 -0.0000 0.5189
vn 0.0272 -0.9996 -0.0081
vn 0.4103 -0.9095 -0.0666
vn 0.3158 -0.9343 0.1651
vn 0.3186 -0.9329 0.1677
vn 0.3189 -0.9328 0.1681
vn 0.8235 0.0000 0.5673
vn 0.3672 0.9194 -0.1408
vn -0.0868 0.9957 0.0333
vn -0.0832 0.9962 0.0257
vn -0.0862 0.9958 0.0321
vn 0.2502 -0.9682 0.0006
vn -0.2556 0.0000 -0.9668
vn -0.8434 0.0000 -0.5374
vn 0.7459 0.0000 0.6660
vn 0.4228 0.8239 0.3775
vn 0.4240 0.8230 0.3780
vn 0.4230 0.8237 0.3776
vn 0.3189 -0.9469 0.0409
vn 0.8869 0.0000 0.4619
vn 0.9583 -0.0000 -0.2858
vn -0.0827 0.9963 0.0247
vn -0.0112 -0.9999 -0.0100
vn 0.4270 0.8209 0.3792
vn 0.5043 0.8586 -0.0922
vn 0.3487 0.8731 0.3407
vn 0.3235 -0.9462 -0.0000
vn 0.0965 -0.9866 0.1319
vn 0.4366 0.8392 0.3243
vn 0.3148 -0.9349 0.1641
usemtl cube1_auv
s 1
f 1/1/1 2/2/1 3/3/1
f 1/1/2 4/4/2 5/5/2
f 1/1/3 6/6/4 7/7/5
f 1/8/6 8/9/6 9/10/6
f 9/10/7 10/11/7 1/8/7
f 9/12/8 8/13/8 11/14/8
f 3/15/9 2/16/9 12/17/9
f 3/3/10 4/4/10 1/1/10
f 12/18/11 10/19/12 9/12/13
f 12/17/14 4/20/14 3/15/14
f 12/18/15 11/14/15 13/21/15
f 14/22/16 8/9/16 15/23/16
f 15/23/17 16/24/17 14/22/17
f 15/25/18 6/6/18 17/26/18
f 15/23/16 8/9/16 7/27/16
f 18/28/19 16/24/19 19/29/19
f 18/30/20 20/31/20 21/32/20
f 19/29/19 16/24/19 17/33/19
f 19/34/21 6/6/21 22/35/21
f 19/36/22 20/37/22 18/38/22
f 19/34/23 23/39/23 24/40/23
f 25/41/24 4/20/24 13/42/24
f 25/43/25 11/14/25 26/44/25
f 25/41/26 27/45/26 28/46/26
f 25/43/27 29/47/27 30/48/27
f 28/46/24 4/20/24 25/41/24
f 28/49/28 27/50/28 31/51/28
f 26/44/25 29/47/25 25/43/25
f 31/51/29 4/4/29 28/49/29
f 31/51/30 6/6/30 5/5/30
f 31/51/28 27/50/28 32/52/28
f 31/51/31 23/39/31 22/35/31
f 33/53/7 1/8/7 10/11/7
f 33/54/32 2/2/32 1/1/32
f 10/19/12 12/18/11 34/55/33
f 10/11/34 2/56/34 33/53/34
f 34/57/9 12/17/9 2/16/9
f 34/58/34 2/56/34 10/11/34
f 17/33/17 16/24/17 15/23/17
f 17/26/35 6/6/35 19/34/35
f 16/59/36 21/32/36 35/60/36
f 16/59/37 8/13/38 14/61/39
f 13/42/14 4/20/14 12/17/14
f 13/21/40 11/14/40 25/43/40
f 11/14/41 12/18/41 9/12/41
f 11/14/42 21/32/42 26/44/42
f 11/14/43 8/13/43 35/60/43
f 5/5/29 4/4/29 31/51/29
f 5/5/44 6/6/4 1/1/3
f 35/60/42 21/32/42 11/14/42
f 35/60/45 8/13/38 16/59/37
f 21/32/46 16/59/46 18/30/46
f 21/32/42 29/47/42 26/44/42
f 22/35/47 6/6/47 31/51/47
f 22/35/48 23/39/48 19/34/48
f 7/7/49 6/6/49 15/25/49
f 7/27/6 8/9/6 1/8/6
f 36/62/50 37/63/50 38/64/50
f 36/65/51 39/66/51 40/67/51
f 36/65/52 27/50/52 41/68/52
f 36/65/53 23/39/54 32/52/55
f 36/62/56 42/69/56 43/70/56
f 38/71/57 44/72/57 29/47/57
f 38/71/58 37/73/59 44/72/60
f 38/64/56 42/69/56 36/62/56
f 41/68/61 39/66/61 36/65/61
f 41/74/62 27/45/62 44/75/62
f 44/75/63 39/76/63 41/74/63
f 44/75/62 27/45/62 30/77/62
f 45/78/64 20/37/64 46/79/64
f 45/80/65 42/81/66 20/31/67
f 46/79/64 20/37/64 24/82/64
f 46/83/68 23/39/68 43/84/68
f 46/79/69 42/69/69 45/78/69
f 40/85/70 39/86/70 37/63/70
f 37/63/50 36/62/50 40/85/50
f 37/63/70 39/86/70 47/87/70
f 47/88/71 44/72/60 37/73/59
f 39/76/63 44/75/63 47/89/63
f 24/82/22 20/37/22 19/36/22
f 24/40/72 23/39/72 46/83/72
f 20/31/67 42/81/66 48/90/73
f 30/77/26 27/45/26 25/41/26
f 30/48/74 29/47/74 44/72/74
f 29/47/42 21/32/42 48/90/42
f 29/47/75 42/81/75 38/71/75
f 32/52/76 27/50/76 36/65/76
f 32/52/77 23/39/77 31/51/77
f 48/90/36 21/32/36 20/31/36
f 48/90/78 42/81/78 29/47/78
f 43/84/79 23/39/54 36/65/53
f 43/70/69 42/69/69 46/79/69

File diff suppressed because it is too large Load Diff

View File

@ -4,15 +4,18 @@ float AMBIENT = 0.1;
uniform vec3 color;
uniform vec3 lightPos;
uniform vec3 lightDir;
in vec3 vecNormal;
in vec3 worldPos;
out vec4 outColor;
void main()
{
vec3 lightDir = normalize(lightPos-worldPos);
//vec3 lightDir = normalize(lightPos - worldPos);
vec3 normal = normalize(vecNormal);
float diffuse=max(0,dot(normal,lightDir));
outColor = vec4(color*min(1,AMBIENT+diffuse), 1.0);
float diffuse = max(0, dot(normal, lightDir));
outColor = vec4(color * min(1, AMBIENT + diffuse), 1.0);
}

View File

@ -12,7 +12,7 @@ out vec3 worldPos;
void main()
{
worldPos = (modelMatrix* vec4(vertexPosition,1)).xyz;
vecNormal = (modelMatrix* vec4(vertexNormal,0)).xyz;
worldPos = (modelMatrix * vec4(vertexPosition,1)).xyz;
vecNormal = (modelMatrix * vec4(vertexNormal,0)).xyz;
gl_Position = transformation * vec4(vertexPosition, 1.0);
}

View File

@ -2,10 +2,8 @@
float AMBIENT = 0.1;
uniform vec3 color;
uniform vec3 lightPos;
in vec3 vecNormal;
in vec3 worldPos;
in vec2 vtc;
@ -21,5 +19,5 @@ void main()
float diffuse = max(0, dot(normal, lightDir));
vec4 textureColor = texture2D(colorTexture, vtc);
outColor = vec4(vec3(textureColor) * min(1, AMBIENT + diffuse), 1.0) * 7.0;
outColor = vec4(vec3(textureColor) * min(1, AMBIENT + diffuse), 1.0) * 2.0;
}

View File

@ -17,6 +17,6 @@ void main()
vecNormal = (modelMatrix * vec4(vertexNormal, 1)).xyz;
gl_Position = transformation * vec4(vertexPosition, 1.0);
//vtc = vec2(vertexTexCoord.x, 1.0 - vertexTexCoord.y);
vtc = vertexTexCoord;
vtc = vec2(vertexTexCoord.x, 1.0 - vertexTexCoord.y);
//vtc = vertexTexCoord;
}

View File

@ -2,7 +2,6 @@
float AMBIENT = 0.1;
uniform vec3 color;
uniform vec3 lightPos;
in vec3 vecNormal;

View File

@ -9,14 +9,14 @@ uniform mat4 modelMatrix;
out vec3 vecNormal;
out vec3 worldPos;
out vec2 vtc;
void main()
{
worldPos = (modelMatrix* vec4(vertexPosition,1)).xyz;
vecNormal = (modelMatrix* vec4(vertexNormal,0)).xyz;
worldPos = (modelMatrix * vec4(vertexPosition, 1)).xyz;
vecNormal = (modelMatrix * vec4(vertexNormal, 0)).xyz;
gl_Position = transformation * vec4(vertexPosition, 1.0);
vtc = vec2(vertexTexCoord.x, 1.0 - vertexTexCoord.y);
//vtc = vertexTexCoord;
}

View File

@ -1,55 +0,0 @@
// dane 36 wierzcholkow i kolorow opisujace model pudelka
const float box[] = {
// points colors
0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
-0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
-0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
-0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.25f, 0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
0.25f, 0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
0.25f, -0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
0.25f, 0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
0.25f, 0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
};

View File

@ -1,15 +1,28 @@
#include "glew.h"
//#include "imgui.h"
//#include "imgui_impl_glfw.h"
//#include "imgui_impl_opengl3.h"
//#include <stdio.h>
//#define GL_SILENCE_DEPRECATION
//#if defined(IMGUI_IMPL_OPENGL_ES2)
//#include <GLES2/gl2.h>
//#endif
#include <GLFW/glfw3.h>
#include "glm.hpp"
#include "ext.hpp"
#include <iostream>
#include <cmath>
//#if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS)
//#pragma comment(lib, "legacy_stdio_definitions")
//#endif
#include "Shader_Loader.h"
#include "Render_Utils.h"
#include "Texture.h"
#include "Box.cpp"
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
@ -39,20 +52,41 @@ GLuint programTex;
Core::Shader_Loader shaderLoader;
Core::RenderContext shipContext;
//Core::RenderContext shipContext;
Core::RenderContext sphereContext;
glm::vec3 cameraPos = glm::vec3(-4.f, 0, 0);
glm::vec3 sunPosition = glm::vec3(12.f, 0.f, 12.f);
glm::vec3 cameraPos = glm::vec3(-1.f, 0.f, 0.f);
glm::vec3 cameraDir = glm::vec3(1.f, 0.f, 0.f);
GLuint VAO, VBO;
glm::vec3 shipPos = glm::vec3(-4.f, 0, 0);
glm::vec3 shipDir = glm::vec3(1.f, 0.f, 0.f);
float aspectRatio = 1.77f;
float aspectRatio = 1.f;
//glm::vec3 shipPos = glm::vec3(-4.f, 0, 0);
//glm::vec3 shipDir = glm::vec3(1.f, 0.f, 0.f);
glm::vec3 lightColor = glm::vec3(0.9, 0.7, 0.8);
//glm::vec3 lightColor = glm::vec3(0.9, 0.7, 0.8);
/*
glm::mat4 createShipMatrix()
{
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0.f, 1.f, 0.f)));
glm::vec3 cameraUp = glm::normalize(glm::cross(cameraSide, cameraDir));
glm::mat4 shipRotationMatrix = glm::mat4({
cameraSide.x,cameraSide.y,cameraSide.z,0,
cameraUp.x,cameraUp.y,cameraUp.z ,0,
shipDir.x,shipDir.y,shipDir.z,0,
0.,0.,0.,1.,
});
shipRotationMatrix = glm::transpose(shipRotationMatrix);
return shipRotationMatrix;
}
*/
glm::mat4 createCameraMatrix()
{
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0.f, 1.f, 0.f)));
@ -72,34 +106,19 @@ glm::mat4 createCameraMatrix()
return cameraMatrix;
}
glm::mat4 createShipMatrix()
{
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0.f, 1.f, 0.f)));
glm::vec3 cameraUp = glm::normalize(glm::cross(cameraSide, cameraDir));
glm::mat4 shipRotationMatrix = glm::mat4({
cameraSide.x,cameraSide.y,cameraSide.z,0,
cameraUp.x,cameraUp.y,cameraUp.z ,0,
shipDir.x,shipDir.y,shipDir.z,0,
0.,0.,0.,1.,
});
shipRotationMatrix = glm::transpose(shipRotationMatrix);
return shipRotationMatrix;
}
glm::mat4 createPerspectiveMatrix()
{
glm::mat4 perspectiveMatrix;
float n = 0.05;
float f = 20.;
float a1 = glm::min(aspectRatio, 1.f);
float a2 = glm::min(1 / aspectRatio, 1.f);
float n = 0.05f;
float f = 20.f;
float fov = 105.f;
float PI = 3.14159265359f;
float S = 1 / (tan((fov / 2) * (PI / 180)));
perspectiveMatrix = glm::mat4({
1,0.,0.,0.,
0.,1,0.,0.,
S,0.,0.,0.,
0.,S * aspectRatio,0.,0.,
0.,0.,(f + n) / (n - f),2 * f * n / (n - f),
0.,0.,-1.,0.,
});
@ -117,23 +136,23 @@ void drawObjectTexture(Core::RenderContext& context, glm::mat4 modelMatrix, GLui
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
glUniformMatrix4fv(glGetUniformLocation(programTex, "transformation"), 1, GL_FALSE, (float*)&transformation);
glUniformMatrix4fv(glGetUniformLocation(programTex, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
glUniform3f(glGetUniformLocation(program, "lightPos"), 0.0, 0.0, 0.0);
glUniform3f(glGetUniformLocation(programTex, "lightPos"), sunPosition.x, sunPosition.y, sunPosition.z);
Core::DrawContext(context);
glUseProgram(0);
}
void drawSun(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint texture) {
glUseProgram(programSun);
Core::SetActiveTexture(texture, "colorTexture", programSun, 3);
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
glUniformMatrix4fv(glGetUniformLocation(programSun, "transformation"), 1, GL_FALSE, (float*)&transformation);
glUniformMatrix4fv(glGetUniformLocation(programSun, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
Core::SetActiveTexture(texture, "colorTexture", programSun, 3);
glUniform3f(glGetUniformLocation(programSun, "lightPos"), 0, 0, 0);
glUniform3f(glGetUniformLocation(programSun, "lightPos"), sunPosition.x, sunPosition.y, sunPosition.z);
Core::DrawContext(context);
glUseProgram(0);
}
/*
void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) {
glUseProgram(program);
glUniform3f(glGetUniformLocation(program, "color"), color.x, color.y, color.z);
@ -144,15 +163,15 @@ void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::v
Core::DrawContext(context);
glUseProgram(0);
}
*/
void renderScene(GLFWwindow* window)
{
glClearColor(0.0f, 0.0f, 0.2f, 1.0f);
glClearColor(0.0f, 0.0f, 0.15f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 transformation;
float time = glfwGetTime();
glm::mat4 sunScale = glm::scale(glm::vec3(1.75));
/*
glm::mat4 mercuryScale = glm::scale(glm::vec3(0.24));
glm::mat4 mercuryRotate = glm::rotate(time * 0.24f, glm::vec3(0, 1, 0));
glm::mat4 mercuryTranslate = glm::translate(glm::vec3(0, 0, -3));
@ -177,14 +196,15 @@ void renderScene(GLFWwindow* window)
glm::mat4 shipRotate = createShipMatrix();
glm::mat4 shipTranslate = glm::translate(shipPos);
//glUseProgram(program);
//glUniform3f(glGetUniformLocation(program, "lightDir"), 1.0, -1.0, 0.0);
//glUniform3f(glGetUniformLocation(program, "lightColor"), lightColor.x, lightColor.y, lightColor.z);
//glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z);
//glUniform3f(glGetUniformLocation(program, "lightPos"), 0.0, 0.0, 0.0);
//glUseProgram(0);
drawSun(sphereContext, sunScale, texture::sun);
drawObjectColor(sphereContext, sunScale, glm::vec3(0.9, 0.9, 0.2)); //sun
drawObjectTexture(sphereContext, mercuryRotate * mercuryTranslate * mercuryScale, texture::mercury); //mercury
drawObjectTexture(sphereContext, venusRotate * venusTranslate * venusScale, texture::venus); //venus
@ -196,14 +216,32 @@ void renderScene(GLFWwindow* window)
drawObjectTexture(sphereContext, marsRotate * marsTranslate * marsScale, texture::mars); //mars
drawObjectTexture(shipContext, shipTranslate * shipRotate * shipScale, texture::ship); //ship
*/
//glUseProgram(programTex);
//glUniform3f(glGetUniformLocation(programTex, "lightDir"), cameraDir.x, cameraDir.y, cameraDir.z);
//glUseProgram(0);
glm::mat4 sunScale = glm::scale(glm::vec3(0.04f));
glm::mat4 sunTranslate = glm::translate(glm::vec3(sunPosition.x, sunPosition.y, sunPosition.z));
drawSun(sphereContext, sunTranslate * sunScale, texture::sun);
glm::mat4 planetScale = glm::scale(glm::vec3(0.005f)); // model jest bardzo duży, dlatego taka niska skala
glm::mat4 planetRotate = glm::rotate(time * 0.0416f, glm::vec3(0, 1, 0)); // 1 godzina mija w 1 sekundę, obrót z zachodu na wschód
glm::mat4 planetTranslate = glm::translate(glm::vec3(0, 0, 0)); // zostaje na domyślnej pozycji
drawObjectTexture(sphereContext, planetRotate * planetTranslate * planetScale, texture::earth);
glfwSwapBuffers(window);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
aspectRatio = width / float(height);
aspectRatio = float(width) / float(height);
glViewport(0, 0, width, height);
}
void loadModelToContext(std::string path, Core::RenderContext& context)
{
Assimp::Importer import;
@ -222,26 +260,15 @@ void init(GLFWwindow* window)
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glEnable(GL_DEPTH_TEST);
program = shaderLoader.CreateProgram("shaders/shader_5_1.vert", "shaders/shader_5_1.frag");
programTex = shaderLoader.CreateProgram("shaders/shader_5_1_tex.vert", "shaders/shader_5_1_tex.frag");
programSun = shaderLoader.CreateProgram("shaders/shader_5_sun.vert", "shaders/shader_5_sun.frag");
program = shaderLoader.CreateProgram("shaders/shader.vert", "shaders/shader.frag");
programTex = shaderLoader.CreateProgram("shaders/shader_tex.vert", "shaders/shader_tex.frag");
programSun = shaderLoader.CreateProgram("shaders/shader_sun.vert", "shaders/shader_sun.frag");
loadModelToContext("./models/sphere.obj", sphereContext);
loadModelToContext("./models/spaceship.obj", shipContext);
texture::earth = Core::LoadTexture("./textures/earth2.png");
texture::clouds = Core::LoadTexture("./textures/clouds.jpg");
texture::moon = Core::LoadTexture("./textures/moon.jpg");
texture::ship = Core::LoadTexture("./textures/metal.jpg");
texture::grid = Core::LoadTexture("./textures/grid.png");
texture::mercury = Core::LoadTexture("./textures/mercury.jpg");
texture::venus = Core::LoadTexture("./textures/venus.jpg");
texture::mars = Core::LoadTexture("./textures/mars.jpg");
texture::sun = Core::LoadTexture("./textures/sun.jpg");
//texture::earthNormal = Core::LoadTexture("./textures/earth_normalmap.png");
//texture::asteroidNormal = Core::LoadTexture("./textures/moon_normals.png");
//texture::shipNormal = Core::LoadTexture("./textures/spaceship_normal.jpg");
}
void shutdown(GLFWwindow* window)
@ -254,9 +281,9 @@ void processInput(GLFWwindow* window)
{
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0.f, 1.f, 0.f)));
float angleSpeed = 0.001f;
float moveSpeed = 0.003f;
float angleSpeed = 0.02f;
float moveSpeed = 0.04f;
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
@ -272,22 +299,98 @@ void processInput(GLFWwindow* window)
cameraDir = glm::vec3(glm::eulerAngleY(angleSpeed) * glm::vec4(cameraDir, 0));
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
cameraDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(cameraDir, 0));
shipPos = cameraPos + 0.75 * cameraDir + glm::vec3(0, -0.25f, 0);
shipDir = cameraDir;
//shipPos = cameraPos + 0.75 * cameraDir + glm::vec3(0, -0.25f, 0);
//shipDir = cameraDir;
//cameraDir = glm::normalize(-cameraPos);
}
// Our state
//bool show_demo_window = true;
//bool show_another_window = false;
//ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// funkcja jest glowna petla
void renderLoop(GLFWwindow* window) {
// Setup Dear ImGui context
//IMGUI_CHECKVERSION();
//ImGui::CreateContext();
//ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
//ImGui::StyleColorsDark();
while (!glfwWindowShouldClose(window))
{
processInput(window);
/*glfwPollEvents();
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
{
static float f = 0.0f;
static int counter = 0;
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
ImGui::Checkbox("Another Window", &show_another_window);
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
counter++;
ImGui::SameLine();
ImGui::Text("counter = %d", counter);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
ImGui::End();
}
// 3. Show another simple window.
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
show_another_window = false;
ImGui::End();
}
// Rendering
ImGui::Render();
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
*/
processInput(window);
renderScene(window);
glfwPollEvents();
}
/*
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;*/
}
//}

View File

@ -0,0 +1,28 @@
# See http://editorconfig.org to read about the EditorConfig format.
# - In theory automatically supported by VS2017+ and most common IDE or text editors.
# - In practice VS2019-VS2022 stills don't trim trailing whitespaces correctly :(
# - Suggest installing this to trim whitespaces:
# GitHub https://github.com/madskristensen/TrailingWhitespace
# VS2019 https://marketplace.visualstudio.com/items?itemName=MadsKristensen.TrailingWhitespaceVisualizer
# VS2022 https://marketplace.visualstudio.com/items?itemName=MadsKristensen.TrailingWhitespace64
# (in spite of its name doesn't only visualize but also trims)
# - Alternative for older VS2010 to VS2015: https://marketplace.visualstudio.com/items?itemName=EditorConfigTeam.EditorConfig
# top-most EditorConfig file
root = true
# Default settings:
# Use 4 spaces as indentation
[*]
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[imstb_*]
indent_size = 3
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
indent_size = 4

View File

@ -0,0 +1,30 @@
* text=auto
*.c text
*.cpp text
*.h text
*.m text
*.mm text
*.md text
*.txt text
*.html text
*.bat text
*.frag text
*.vert text
*.mkb text
*.icf text
*.sln text eol=crlf
*.vcxproj text eol=crlf
*.vcxproj.filters text eol=crlf
*.natvis text eol=crlf
Makefile text eol=lf
*.sh text eol=lf
*.pbxproj text eol=lf
*.storyboard text eol=lf
*.plist text eol=lf
*.png binary
*.ttf binary
*.lib binary

View File

@ -0,0 +1 @@
custom: ['https://github.com/ocornut/imgui/wiki/Sponsors']

View File

@ -0,0 +1 @@
blank_issues_enabled: false

View File

@ -0,0 +1,90 @@
name: "Ask a question, report a bug, request a feature, etc."
description: "Ask any question, discuss best practices, report a bug, request a feature."
body:
- type: markdown
attributes:
value: |
FOR FIRST-TIME USERS ISSUES COMPILING/LINKING/RUNNING or LOADING FONTS, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions)
For anything else: we are happy to use 'GitHub Issues' for many types of open-ended questions. We are encouraging 'Issues' becoming a large, centralized and cross-referenced database of Dear ImGui contents.
Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users.
- type: markdown
attributes:
value: |
**Prerequisites:**
- I have read [Frequently Asked Questions](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md).
- I have read [Contributing Guidelines -> General Advices](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#getting-started--general-advice).
- I have read [Contributing Guidelines -> How to open an Issue](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#how-to-open-an-issue).
- I have searched [Github Issues and PR](https://github.com/ocornut/imgui/issues?q=) for discussion of similar topics.
----
- type: input
id: specs_version
attributes:
label: "Version/Branch of Dear ImGui:"
description: "(please specify if you have made substantial modifications to your copy)"
value: "Version 1.XX, Branch: XXX (master/docking/etc.)"
placeholder: "Version 1.XX, Branch: XXX (master/docking/etc.)"
validations:
required: true
- type: input
id: specs_backend
attributes:
label: "Back-ends:"
description: (or specify when using custom engine/back-ends)
value: "imgui_impl_XXX.cpp + imgui_impl_XXX.cpp"
placeholder: "imgui_impl_XXX.cpp + imgui_impl_XXX.cpp or n/a"
validations:
required: true
- type: input
id: specs_compiler_os
attributes:
label: "Compiler, OS:"
placeholder: "e.g. Windows 11 + MSVC 2022, macOS + Clang 12, Linux + GCC etc."
validations:
required: true
- type: textarea
id: specs_full
attributes:
label: "Full config/build information:"
placeholder: |
(If you can run, you may go to 'Demo->Tools->About Dear ImGui->Config/Build Info' to obtain detailed information that you can paste here)
validations:
required: false
- type: textarea
id: issue_description
attributes:
label: "Details:"
description: "Try to be explicit with your goals, your expectations and what you have tried. Be mindful of [The XY Problem](https://xyproblem.info). What you have in mind or in your code is not obvious to other people. People frequently discuss problems and suggest incorrect solutions without first clarifying their goals. When requesting a new feature, please describe the usage context (how you intend to use it, why you need it, etc.). If you tried something and it failed, show us what you tried. If you are reporting a bug, explain what's the bug, how does it occur, etc. If you are reporting a crash, please include a debugger callstack."
value: |
**My Issue/Question:**
XXX _(please provide as much context as possible)_
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: "Screenshots/Video:"
description: "Attach screenshots or gif/videos to clarify the context. They often convey useful information that is omitted by the description."
placeholder: "(You can drag files here)"
validations:
required: false
- type: textarea
id: repro_code
attributes:
label: "Minimal, Complete and Verifiable Example code:"
description: "Provide an [MCVE](https://stackoverflow.com/help/mcve) to demonstrate your problem. An ideal submission includes a small piece of code that anyone can paste into one of the examples applications (examples/*/main.cpp) or the demo (imgui_demo.cpp) to understand and reproduce it. Narrowing your problem to its shortest and purest form is the easiest way to understand it, explain it and fix it. Please test your shortened code to ensure it exhibits the problem. Often while creating the MCVE you will solve the problem! Many questions that are missing a standalone verifiable example are missing the actual cause of their issue in the description, which ends up wasting everyone's time."
value: |
```cpp
// Here's some code anyone can copy and paste to reproduce your issue
ImGui::Begin("Example Bug");
MoreCodeToExplainMyIssue();
ImGui::End();
```
validations:
required: false
- type: markdown
attributes:
value: |
Thank you for taking the time to read prerequisites, filling this template and double-checking your message and your code!

View File

@ -0,0 +1,6 @@
(Click "Preview" to turn any http URL into a clickable link)
1. PLEASE CAREFULLY READ: [Contributing Guidelines](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md)
2. Clear this template before submitting your PR.

View File

@ -0,0 +1,507 @@
name: build
on:
push:
pull_request:
workflow_run:
# Use a workflow as a trigger of scheduled builds. Forked repositories can disable scheduled builds by disabling
# "scheduled" workflow, while maintaining ability to perform local CI builds.
workflows:
- scheduled
branches:
- master
- docking
types:
- requested
jobs:
Windows:
runs-on: windows-2019
env:
VS_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\
MSBUILD_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\
steps:
- uses: actions/checkout@v3
- name: Install Dependencies
shell: powershell
run: |
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL2-devel-2.26.3-VC.zip" -OutFile "SDL2-devel-2.26.3-VC.zip"
Expand-Archive -Path SDL2-devel-2.26.3-VC.zip
echo "SDL2_DIR=$(pwd)\SDL2-devel-2.26.3-VC\SDL2-2.26.3\" >>${env:GITHUB_ENV}
Invoke-WebRequest -Uri "https://github.com/ocornut/imgui/files/3789205/vulkan-sdk-1.1.121.2.zip" -OutFile vulkan-sdk-1.1.121.2.zip
Expand-Archive -Path vulkan-sdk-1.1.121.2.zip
echo "VULKAN_SDK=$(pwd)\vulkan-sdk-1.1.121.2\" >>${env:GITHUB_ENV}
- name: Fix Projects
shell: powershell
run: |
# CI workers do not supporter older Visual Studio versions. Fix projects to target newer available version.
gci -recurse -filter "*.vcxproj" | ForEach-Object {
(Get-Content $_.FullName) -Replace "<PlatformToolset>v\d{3}</PlatformToolset>","<PlatformToolset>v142</PlatformToolset>" | Set-Content -Path $_.FullName
(Get-Content $_.FullName) -Replace "<WindowsTargetPlatformVersion>[\d\.]+</WindowsTargetPlatformVersion>","<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>" | Set-Content -Path $_.FullName
}
# Not using matrix here because it would inflate job count too much. Check out and setup is done for every job and that makes build times way too long.
- name: Build example_null (extra warnings, mingw 64-bit)
run: mingw32-make -C examples/example_null WITH_EXTRA_WARNINGS=1
- name: Build example_null (mingw 64-bit, as DLL)
shell: bash
run: |
echo '#ifdef _EXPORT' > example_single_file.cpp
echo '# define IMGUI_API __declspec(dllexport)' >> example_single_file.cpp
echo '#else' >> example_single_file.cpp
echo '# define IMGUI_API __declspec(dllimport)' >> example_single_file.cpp
echo '#endif' >> example_single_file.cpp
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
g++ -I. -Wall -Wformat -D_EXPORT -shared -o libimgui.dll -Wl,--out-implib,libimgui.a example_single_file.cpp -limm32
g++ -I. -Wall -Wformat -o example_null.exe examples/example_null/main.cpp -L. -limgui
rm -f example_null.exe libimgui.* example_single_file.*
- name: Build example_null (extra warnings, msvc 64-bit)
shell: cmd
run: |
cd examples\example_null
call "%VS_PATH%\VC\Auxiliary\Build\vcvars64.bat"
.\build_win32.bat /W4
- name: Build example_null (single file build)
shell: bash
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp -limm32
- name: Build example_null (with IMGUI_DISABLE_WIN32_FUNCTIONS)
shell: bash
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_DISABLE_WIN32_FUNCTIONS
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp -limm32
- name: Build example_null (as DLL)
shell: cmd
run: |
call "%VS_PATH%\VC\Auxiliary\Build\vcvars64.bat"
echo #ifdef _EXPORT > example_single_file.cpp
echo # define IMGUI_API __declspec(dllexport) >> example_single_file.cpp
echo #else >> example_single_file.cpp
echo # define IMGUI_API __declspec(dllimport) >> example_single_file.cpp
echo #endif >> example_single_file.cpp
echo #define IMGUI_IMPLEMENTATION >> example_single_file.cpp
echo #include "misc/single_file/imgui_single_file.h" >> example_single_file.cpp
cl.exe /D_USRDLL /D_WINDLL /D_EXPORT /I. example_single_file.cpp /LD /FeImGui.dll /link
cl.exe /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp
- name: Build Win32 example_glfw_opengl2
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=Win32 /p:Configuration=Release'
- name: Build Win32 example_glfw_opengl3
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build Win32 example_glfw_vulkan
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj /p:Platform=Win32 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build Win32 example_sdl2_vulkan
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj /p:Platform=Win32 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build Win32 example_sdl2_opengl2
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj /p:Platform=Win32 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build Win32 example_sdl2_opengl3
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
- name: Build Win32 example_sdl2_directx11
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build Win32 example_win32_directx9
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=Win32 /p:Configuration=Release'
- name: Build Win32 example_win32_directx10
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=Win32 /p:Configuration=Release'
- name: Build Win32 example_win32_directx11
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build x64 example_glfw_opengl2
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build x64 example_glfw_opengl3
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
- name: Build x64 example_glfw_vulkan
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
- name: Build x64 example_sdl2_vulkan
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build x64 example_sdl2_opengl2
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build x64 example_sdl2_opengl3
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build x64 example_sdl2_directx11
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
- name: Build x64 example_win32_directx9
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=x64 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build x64 example_win32_directx10
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=x64 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build x64 example_win32_directx11
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
if: github.event_name == 'workflow_run'
- name: Build x64 example_win32_directx12
shell: cmd
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx12/example_win32_directx12.vcxproj /p:Platform=x64 /p:Configuration=Release'
Linux:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y libglfw3-dev libsdl2-dev gcc-multilib g++-multilib libfreetype6-dev libvulkan-dev
- name: Build example_null (extra warnings, gcc 32-bit)
run: |
make -C examples/example_null clean
CXXFLAGS="$CXXFLAGS -m32 -Werror" make -C examples/example_null WITH_EXTRA_WARNINGS=1
- name: Build example_null (extra warnings, gcc 64-bit)
run: |
make -C examples/example_null clean
CXXFLAGS="$CXXFLAGS -m64 -Werror" make -C examples/example_null WITH_EXTRA_WARNINGS=1
- name: Build example_null (extra warnings, clang 32-bit)
run: |
make -C examples/example_null clean
CXXFLAGS="$CXXFLAGS -m32 -Werror" CXX=clang++ make -C examples/example_null WITH_EXTRA_WARNINGS=1
- name: Build example_null (extra warnings, clang 64-bit)
run: |
make -C examples/example_null clean
CXXFLAGS="$CXXFLAGS -m64 -Werror" CXX=clang++ make -C examples/example_null WITH_EXTRA_WARNINGS=1
- name: Build example_null (extra warnings, empty IM_ASSERT)
run: |
cat > example_single_file.cpp <<'EOF'
#define IM_ASSERT(x)
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -std=c++11 -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp
- name: Build example_null (freetype)
run: |
make -C examples/example_null clean
make -C examples/example_null WITH_FREETYPE=1
- name: Build example_null (single file build)
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with ImWchar32)
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_USE_WCHAR32
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with large ImDrawIdx + pointer ImTextureID)
run: |
cat > example_single_file.cpp <<'EOF'
#define ImTextureID void*
#define ImDrawIdx unsigned int
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_OBSOLETE_KEYIO)
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_DISABLE_OBSOLETE_KEYIO
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_DEBUG_TOOLS)
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_DISABLE_DEMO_WINDOWS
#define IMGUI_DISABLE_DEBUG_TOOLS
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS)
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_DISABLE_FILE_FUNCTIONS
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR)
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_USE_BGRA_PACKED_COLOR
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA)
run: |
cat > example_single_file.cpp <<'EOF'
struct MyVec2 { float x; float y; MyVec2(float x, float y) : x(x), y(y) { } };
struct MyVec4 { float x; float y; float z; float w;
MyVec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { } };
#define IM_VEC2_CLASS_EXTRA \
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
operator MyVec2() const { return MyVec2(x, y); }
#define IM_VEC4_CLASS_EXTRA \
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
operator MyVec4() const { return MyVec4(x, y, z, w); }
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (without c++ runtime, Clang)
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_IMPLEMENTATION
#define IMGUI_DISABLE_DEMO_WINDOWS
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
- name: Build example_glfw_opengl2
run: make -C examples/example_glfw_opengl2
- name: Build example_glfw_opengl3
run: make -C examples/example_glfw_opengl3
if: github.event_name == 'workflow_run'
- name: Build example_sdl2_opengl2
run: make -C examples/example_sdl2_opengl2
if: github.event_name == 'workflow_run'
- name: Build example_sdl2_opengl3
run: make -C examples/example_sdl2_opengl3
- name: Build with IMGUI_IMPL_VULKAN_NO_PROTOTYPES
run: g++ -c -I. -std=c++11 -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp
MacOS:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Install Dependencies
run: |
brew install glfw3 sdl2
- name: Build example_null (extra warnings, clang 64-bit)
run: make -C examples/example_null WITH_EXTRA_WARNINGS=1
- name: Build example_null (single file build)
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
clang++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (without c++ runtime)
run: |
cat > example_single_file.cpp <<'EOF'
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
- name: Build example_glfw_opengl2
run: make -C examples/example_glfw_opengl2
- name: Build example_glfw_opengl3
run: make -C examples/example_glfw_opengl3
if: github.event_name == 'workflow_run'
- name: Build example_glfw_metal
run: make -C examples/example_glfw_metal
- name: Build example_sdl2_metal
run: make -C examples/example_sdl2_metal
- name: Build example_sdl2_opengl2
run: make -C examples/example_sdl2_opengl2
if: github.event_name == 'workflow_run'
- name: Build example_sdl2_opengl3
run: make -C examples/example_sdl2_opengl3
- name: Build example_apple_metal
run: xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_macos
- name: Build example_apple_opengl2
run: xcodebuild -project examples/example_apple_opengl2/example_apple_opengl2.xcodeproj -target example_osx_opengl2
iOS:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Build example_apple_metal
run: |
# Code signing is required, but we disable it because it is irrelevant for CI builds.
xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_ios CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
Emscripten:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Install Dependencies
run: |
wget -q https://github.com/emscripten-core/emsdk/archive/master.tar.gz
tar -xvf master.tar.gz
emsdk-master/emsdk update
emsdk-master/emsdk install latest
emsdk-master/emsdk activate latest
- name: Build example_sdl2_opengl3 with Emscripten
run: |
pushd emsdk-master
source ./emsdk_env.sh
popd
make -C examples/example_sdl2_opengl3 -f Makefile.emscripten
- name: Build example_emscripten_wgpu
run: |
pushd emsdk-master
source ./emsdk_env.sh
popd
make -C examples/example_emscripten_wgpu
Android:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Build example_android_opengl3
run: |
cd examples/example_android_opengl3/android
gradle assembleDebug --stacktrace

View File

@ -0,0 +1,15 @@
#
# This is a dummy workflow used to trigger scheduled builds. Forked repositories most likely should disable this
# workflow to avoid daily builds of inactive repositories.
#
name: scheduled
on:
schedule:
- cron: '0 9 * * *'
jobs:
scheduled:
runs-on: ubuntu-latest
steps:
- run: exit 0

View File

@ -0,0 +1,46 @@
name: static-analysis
on:
workflow_run:
# Perform static analysis together with build workflow. Build triggers of "build" workflow do not need to be repeated here.
workflows:
- build
types:
- requested
jobs:
PVS-Studio:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Install Dependencies
env:
# The Secret variable setup in GitHub must be in format: "name_or_email key", on a single line
PVS_STUDIO_LICENSE: ${{ secrets.PVS_STUDIO_LICENSE }}
run: |
if [[ "$PVS_STUDIO_LICENSE" != "" ]];
then
wget -q https://files.viva64.com/etc/pubkey.txt
sudo apt-key add pubkey.txt
sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.viva64.com/etc/viva64.list
sudo apt-get update
sudo apt-get install -y pvs-studio
pvs-studio-analyzer credentials -o pvs-studio.lic $PVS_STUDIO_LICENSE
fi
- name: PVS-Studio static analysis
run: |
if [[ ! -f pvs-studio.lic ]];
then
echo "PVS Studio license is missing. No analysis will be performed."
echo "If you have a PVS Studio license please create a project secret named PVS_STUDIO_LICENSE with your license."
echo "You may use a free license. More information at https://www.viva64.com/en/b/0457/"
exit 0
fi
cd examples/example_null
pvs-studio-analyzer trace -- make WITH_EXTRA_WARNINGS=1
pvs-studio-analyzer analyze -e ../../imstb_rectpack.h -e ../../imstb_textedit.h -e ../../imstb_truetype.h -l ../../pvs-studio.lic -o pvs-studio.log
plog-converter -a 'GA:1,2;OP:1' -d V1071 -t errorfile -w pvs-studio.log

59
grk/cw 6/src/imgui-master/.gitignore vendored Normal file
View File

@ -0,0 +1,59 @@
## OSX artifacts
.DS_Store
## Dear ImGui artifacts
imgui.ini
## General build artifacts
*.o
*.obj
*.exe
examples/*/Debug/*
examples/*/Release/*
examples/*/x64/*
## Visual Studio artifacts
.vs
ipch
*.opensdf
*.log
*.pdb
*.ilk
*.user
*.sdf
*.suo
*.VC.db
*.VC.VC.opendb
## Getting files created in JSON/Schemas/Catalog/ from a VS2022 update
JSON/
## Commonly used CMake directories
build*/
## Xcode artifacts
project.xcworkspace
xcuserdata
## Emscripten artifacts
examples/*.o.tmp
examples/*.out.js
examples/*.out.wasm
examples/example_glfw_opengl3/web/*
examples/example_sdl2_opengl3/web/*
examples/example_emscripten_wgpu/web/*
## JetBrains IDE artifacts
.idea
cmake-build-*
## Unix executables from our example Makefiles
examples/example_glfw_metal/example_glfw_metal
examples/example_glfw_opengl2/example_glfw_opengl2
examples/example_glfw_opengl3/example_glfw_opengl3
examples/example_glut_opengl2/example_glut_opengl2
examples/example_null/example_null
examples/example_sdl2_metal/example_sdl2_metal
examples/example_sdl2_opengl2/example_sdl2_opengl2
examples/example_sdl2_opengl3/example_sdl2_opengl3
examples/example_sdl2_sdlrenderer/example_sdl2_sdlrenderer

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2024 Omar Cornut
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,613 @@
// dear imgui: Renderer + Platform Backend for Allegro 5
// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.)
// Implemented features:
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: Clipboard support (from Allegro 5.1.12)
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Issues:
// [ ] Renderer: The renderer is suboptimal as we need to convert vertices manually.
// [ ] Platform: Missing gamepad support.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2022-11-30: Renderer: Restoring using al_draw_indexed_prim() when Allegro version is >= 5.2.5.
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
// 2021-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: Change blending equation to preserve alpha in output buffer.
// 2020-08-10: Inputs: Fixed horizontal mouse wheel direction.
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
// 2019-05-11: Inputs: Don't filter character value from ALLEGRO_EVENT_KEY_CHAR before calling AddInputCharacter().
// 2019-04-30: Renderer: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2018-11-30: Platform: Added touchscreen support.
// 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window.
// 2018-06-13: Platform: Added clipboard support (from Allegro 5.1.12).
// 2018-06-13: Renderer: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
// 2018-06-13: Renderer: Stopped using al_draw_indexed_prim() as it is buggy in Allegro's DX9 backend.
// 2018-06-13: Renderer: Backup/restore transform and clipping rectangle.
// 2018-06-11: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag.
// 2018-04-18: Misc: Renamed file from imgui_impl_a5.cpp to imgui_impl_allegro5.cpp.
// 2018-04-18: Misc: Added support for 32-bit vertex indices to avoid conversion at runtime. Added imconfig_allegro5.h to enforce 32-bit indices when included from imgui.h.
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplAllegro5_RenderDrawData() in the .h file so you can call it yourself.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_allegro5.h"
#include <stdint.h> // uint64_t
#include <cstring> // memcpy
// Allegro
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#ifdef _WIN32
#include <allegro5/allegro_windows.h>
#endif
#define ALLEGRO_HAS_CLIPBOARD (ALLEGRO_VERSION_INT >= ((5 << 24) | (1 << 16) | (12 << 8))) // Clipboard only supported from Allegro 5.1.12
#define ALLEGRO_HAS_DRAW_INDEXED_PRIM (ALLEGRO_VERSION_INT >= ((5 << 24) | (2 << 16) | ( 5 << 8))) // DX9 implementation of al_draw_indexed_prim() got fixed in Allegro 5.2.5
// Visual Studio warnings
#ifdef _MSC_VER
#pragma warning (disable: 4127) // condition expression is constant
#endif
struct ImDrawVertAllegro
{
ImVec2 pos;
ImVec2 uv;
ALLEGRO_COLOR col;
};
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 float as well..
// FIXME-OPT: Consider inlining al_map_rgba()?
// see https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L554
// and https://github.com/liballeg/allegro5/blob/master/include/allegro5/internal/aintern_pixels.h
#define DRAW_VERT_IMGUI_TO_ALLEGRO(DST, SRC) { (DST)->pos = (SRC)->pos; (DST)->uv = (SRC)->uv; unsigned char* c = (unsigned char*)&(SRC)->col; (DST)->col = al_map_rgba(c[0], c[1], c[2], c[3]); }
// Allegro Data
struct ImGui_ImplAllegro5_Data
{
ALLEGRO_DISPLAY* Display;
ALLEGRO_BITMAP* Texture;
double Time;
ALLEGRO_MOUSE_CURSOR* MouseCursorInvisible;
ALLEGRO_VERTEX_DECL* VertexDecl;
char* ClipboardTextData;
ImVector<ImDrawVertAllegro> BufVertices;
ImVector<int> BufIndices;
ImGui_ImplAllegro5_Data() { memset((void*)this, 0, sizeof(*this)); }
};
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
static ImGui_ImplAllegro5_Data* ImGui_ImplAllegro5_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplAllegro5_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr; }
static void ImGui_ImplAllegro5_SetupRenderState(ImDrawData* draw_data)
{
// Setup blending
al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
// Setup orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
{
float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
ALLEGRO_TRANSFORM transform;
al_identity_transform(&transform);
al_use_transform(&transform);
al_orthographic_transform(&transform, L, T, 1.0f, R, B, -1.0f);
al_use_projection_transform(&transform);
}
}
// Render function.
void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
{
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
// Backup Allegro state that will be modified
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform();
int last_clip_x, last_clip_y, last_clip_w, last_clip_h;
al_get_clipping_rectangle(&last_clip_x, &last_clip_y, &last_clip_w, &last_clip_h);
int last_blender_op, last_blender_src, last_blender_dst;
al_get_blender(&last_blender_op, &last_blender_src, &last_blender_dst);
// Setup desired render state
ImGui_ImplAllegro5_SetupRenderState(draw_data);
// Render command lists
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
ImVector<ImDrawVertAllegro>& vertices = bd->BufVertices;
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM
vertices.resize(cmd_list->VtxBuffer.Size);
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
{
const ImDrawVert* src_v = &cmd_list->VtxBuffer[i];
ImDrawVertAllegro* dst_v = &vertices[i];
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
}
const int* indices = nullptr;
if (sizeof(ImDrawIdx) == 2)
{
// FIXME-OPT: Allegro doesn't support 16-bit indices.
// You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices.
// Otherwise, we convert them from 16-bit to 32-bit at runtime here, which works perfectly but is a little wasteful.
bd->BufIndices.resize(cmd_list->IdxBuffer.Size);
for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
bd->BufIndices[i] = (int)cmd_list->IdxBuffer.Data[i];
indices = bd->BufIndices.Data;
}
else if (sizeof(ImDrawIdx) == 4)
{
indices = (const int*)cmd_list->IdxBuffer.Data;
}
#else
// Allegro's implementation of al_draw_indexed_prim() for DX9 was broken until 5.2.5. Unindex buffers ourselves while converting vertex format.
vertices.resize(cmd_list->IdxBuffer.Size);
for (int i = 0; i < cmd_list->IdxBuffer.Size; i++)
{
const ImDrawVert* src_v = &cmd_list->VtxBuffer[cmd_list->IdxBuffer[i]];
ImDrawVertAllegro* dst_v = &vertices[i];
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
}
#endif
// Render command lists
ImVec2 clip_off = draw_data->DisplayPos;
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback)
{
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplAllegro5_SetupRenderState(draw_data);
else
pcmd->UserCallback(cmd_list, pcmd);
}
else
{
// Project scissor/clipping rectangles into framebuffer space
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue;
// Apply scissor/clipping rectangle, Draw
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID();
al_set_clipping_rectangle(clip_min.x, clip_min.y, clip_max.x - clip_min.x, clip_max.y - clip_min.y);
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM
al_draw_indexed_prim(&vertices[0], bd->VertexDecl, texture, &indices[pcmd->IdxOffset], pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
#else
al_draw_prim(&vertices[0], bd->VertexDecl, texture, pcmd->IdxOffset, pcmd->IdxOffset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
#endif
}
}
}
// Restore modified Allegro state
al_set_blender(last_blender_op, last_blender_src, last_blender_dst);
al_set_clipping_rectangle(last_clip_x, last_clip_y, last_clip_w, last_clip_h);
al_use_transform(&last_transform);
al_use_projection_transform(&last_projection_transform);
}
bool ImGui_ImplAllegro5_CreateDeviceObjects()
{
// Build texture atlas
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
// Create texture
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
int flags = al_get_new_bitmap_flags();
int fmt = al_get_new_bitmap_format();
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
if (!img)
return false;
ALLEGRO_LOCKED_REGION* locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
if (!locked_img)
{
al_destroy_bitmap(img);
return false;
}
memcpy(locked_img->data, pixels, sizeof(int) * width * height);
al_unlock_bitmap(img);
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
if (!cloned_img)
return false;
// Store our identifier
io.Fonts->SetTexID((ImTextureID)(intptr_t)cloned_img);
bd->Texture = cloned_img;
// Create an invisible mouse cursor
// Because al_hide_mouse_cursor() seems to mess up with the actual inputs..
ALLEGRO_BITMAP* mouse_cursor = al_create_bitmap(8, 8);
bd->MouseCursorInvisible = al_create_mouse_cursor(mouse_cursor, 0, 0);
al_destroy_bitmap(mouse_cursor);
return true;
}
void ImGui_ImplAllegro5_InvalidateDeviceObjects()
{
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
if (bd->Texture)
{
io.Fonts->SetTexID(0);
al_destroy_bitmap(bd->Texture);
bd->Texture = nullptr;
}
if (bd->MouseCursorInvisible)
{
al_destroy_mouse_cursor(bd->MouseCursorInvisible);
bd->MouseCursorInvisible = nullptr;
}
}
#if ALLEGRO_HAS_CLIPBOARD
static const char* ImGui_ImplAllegro5_GetClipboardText(void*)
{
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
if (bd->ClipboardTextData)
al_free(bd->ClipboardTextData);
bd->ClipboardTextData = al_get_clipboard_text(bd->Display);
return bd->ClipboardTextData;
}
static void ImGui_ImplAllegro5_SetClipboardText(void*, const char* text)
{
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
al_set_clipboard_text(bd->Display, text);
}
#endif
static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
{
switch (key_code)
{
case ALLEGRO_KEY_TAB: return ImGuiKey_Tab;
case ALLEGRO_KEY_LEFT: return ImGuiKey_LeftArrow;
case ALLEGRO_KEY_RIGHT: return ImGuiKey_RightArrow;
case ALLEGRO_KEY_UP: return ImGuiKey_UpArrow;
case ALLEGRO_KEY_DOWN: return ImGuiKey_DownArrow;
case ALLEGRO_KEY_PGUP: return ImGuiKey_PageUp;
case ALLEGRO_KEY_PGDN: return ImGuiKey_PageDown;
case ALLEGRO_KEY_HOME: return ImGuiKey_Home;
case ALLEGRO_KEY_END: return ImGuiKey_End;
case ALLEGRO_KEY_INSERT: return ImGuiKey_Insert;
case ALLEGRO_KEY_DELETE: return ImGuiKey_Delete;
case ALLEGRO_KEY_BACKSPACE: return ImGuiKey_Backspace;
case ALLEGRO_KEY_SPACE: return ImGuiKey_Space;
case ALLEGRO_KEY_ENTER: return ImGuiKey_Enter;
case ALLEGRO_KEY_ESCAPE: return ImGuiKey_Escape;
case ALLEGRO_KEY_QUOTE: return ImGuiKey_Apostrophe;
case ALLEGRO_KEY_COMMA: return ImGuiKey_Comma;
case ALLEGRO_KEY_MINUS: return ImGuiKey_Minus;
case ALLEGRO_KEY_FULLSTOP: return ImGuiKey_Period;
case ALLEGRO_KEY_SLASH: return ImGuiKey_Slash;
case ALLEGRO_KEY_SEMICOLON: return ImGuiKey_Semicolon;
case ALLEGRO_KEY_EQUALS: return ImGuiKey_Equal;
case ALLEGRO_KEY_OPENBRACE: return ImGuiKey_LeftBracket;
case ALLEGRO_KEY_BACKSLASH: return ImGuiKey_Backslash;
case ALLEGRO_KEY_CLOSEBRACE: return ImGuiKey_RightBracket;
case ALLEGRO_KEY_TILDE: return ImGuiKey_GraveAccent;
case ALLEGRO_KEY_CAPSLOCK: return ImGuiKey_CapsLock;
case ALLEGRO_KEY_SCROLLLOCK: return ImGuiKey_ScrollLock;
case ALLEGRO_KEY_NUMLOCK: return ImGuiKey_NumLock;
case ALLEGRO_KEY_PRINTSCREEN: return ImGuiKey_PrintScreen;
case ALLEGRO_KEY_PAUSE: return ImGuiKey_Pause;
case ALLEGRO_KEY_PAD_0: return ImGuiKey_Keypad0;
case ALLEGRO_KEY_PAD_1: return ImGuiKey_Keypad1;
case ALLEGRO_KEY_PAD_2: return ImGuiKey_Keypad2;
case ALLEGRO_KEY_PAD_3: return ImGuiKey_Keypad3;
case ALLEGRO_KEY_PAD_4: return ImGuiKey_Keypad4;
case ALLEGRO_KEY_PAD_5: return ImGuiKey_Keypad5;
case ALLEGRO_KEY_PAD_6: return ImGuiKey_Keypad6;
case ALLEGRO_KEY_PAD_7: return ImGuiKey_Keypad7;
case ALLEGRO_KEY_PAD_8: return ImGuiKey_Keypad8;
case ALLEGRO_KEY_PAD_9: return ImGuiKey_Keypad9;
case ALLEGRO_KEY_PAD_DELETE: return ImGuiKey_KeypadDecimal;
case ALLEGRO_KEY_PAD_SLASH: return ImGuiKey_KeypadDivide;
case ALLEGRO_KEY_PAD_ASTERISK: return ImGuiKey_KeypadMultiply;
case ALLEGRO_KEY_PAD_MINUS: return ImGuiKey_KeypadSubtract;
case ALLEGRO_KEY_PAD_PLUS: return ImGuiKey_KeypadAdd;
case ALLEGRO_KEY_PAD_ENTER: return ImGuiKey_KeypadEnter;
case ALLEGRO_KEY_PAD_EQUALS: return ImGuiKey_KeypadEqual;
case ALLEGRO_KEY_LCTRL: return ImGuiKey_LeftCtrl;
case ALLEGRO_KEY_LSHIFT: return ImGuiKey_LeftShift;
case ALLEGRO_KEY_ALT: return ImGuiKey_LeftAlt;
case ALLEGRO_KEY_LWIN: return ImGuiKey_LeftSuper;
case ALLEGRO_KEY_RCTRL: return ImGuiKey_RightCtrl;
case ALLEGRO_KEY_RSHIFT: return ImGuiKey_RightShift;
case ALLEGRO_KEY_ALTGR: return ImGuiKey_RightAlt;
case ALLEGRO_KEY_RWIN: return ImGuiKey_RightSuper;
case ALLEGRO_KEY_MENU: return ImGuiKey_Menu;
case ALLEGRO_KEY_0: return ImGuiKey_0;
case ALLEGRO_KEY_1: return ImGuiKey_1;
case ALLEGRO_KEY_2: return ImGuiKey_2;
case ALLEGRO_KEY_3: return ImGuiKey_3;
case ALLEGRO_KEY_4: return ImGuiKey_4;
case ALLEGRO_KEY_5: return ImGuiKey_5;
case ALLEGRO_KEY_6: return ImGuiKey_6;
case ALLEGRO_KEY_7: return ImGuiKey_7;
case ALLEGRO_KEY_8: return ImGuiKey_8;
case ALLEGRO_KEY_9: return ImGuiKey_9;
case ALLEGRO_KEY_A: return ImGuiKey_A;
case ALLEGRO_KEY_B: return ImGuiKey_B;
case ALLEGRO_KEY_C: return ImGuiKey_C;
case ALLEGRO_KEY_D: return ImGuiKey_D;
case ALLEGRO_KEY_E: return ImGuiKey_E;
case ALLEGRO_KEY_F: return ImGuiKey_F;
case ALLEGRO_KEY_G: return ImGuiKey_G;
case ALLEGRO_KEY_H: return ImGuiKey_H;
case ALLEGRO_KEY_I: return ImGuiKey_I;
case ALLEGRO_KEY_J: return ImGuiKey_J;
case ALLEGRO_KEY_K: return ImGuiKey_K;
case ALLEGRO_KEY_L: return ImGuiKey_L;
case ALLEGRO_KEY_M: return ImGuiKey_M;
case ALLEGRO_KEY_N: return ImGuiKey_N;
case ALLEGRO_KEY_O: return ImGuiKey_O;
case ALLEGRO_KEY_P: return ImGuiKey_P;
case ALLEGRO_KEY_Q: return ImGuiKey_Q;
case ALLEGRO_KEY_R: return ImGuiKey_R;
case ALLEGRO_KEY_S: return ImGuiKey_S;
case ALLEGRO_KEY_T: return ImGuiKey_T;
case ALLEGRO_KEY_U: return ImGuiKey_U;
case ALLEGRO_KEY_V: return ImGuiKey_V;
case ALLEGRO_KEY_W: return ImGuiKey_W;
case ALLEGRO_KEY_X: return ImGuiKey_X;
case ALLEGRO_KEY_Y: return ImGuiKey_Y;
case ALLEGRO_KEY_Z: return ImGuiKey_Z;
case ALLEGRO_KEY_F1: return ImGuiKey_F1;
case ALLEGRO_KEY_F2: return ImGuiKey_F2;
case ALLEGRO_KEY_F3: return ImGuiKey_F3;
case ALLEGRO_KEY_F4: return ImGuiKey_F4;
case ALLEGRO_KEY_F5: return ImGuiKey_F5;
case ALLEGRO_KEY_F6: return ImGuiKey_F6;
case ALLEGRO_KEY_F7: return ImGuiKey_F7;
case ALLEGRO_KEY_F8: return ImGuiKey_F8;
case ALLEGRO_KEY_F9: return ImGuiKey_F9;
case ALLEGRO_KEY_F10: return ImGuiKey_F10;
case ALLEGRO_KEY_F11: return ImGuiKey_F11;
case ALLEGRO_KEY_F12: return ImGuiKey_F12;
default: return ImGuiKey_None;
}
}
bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
// Setup backend capabilities flags
ImGui_ImplAllegro5_Data* bd = IM_NEW(ImGui_ImplAllegro5_Data)();
io.BackendPlatformUserData = (void*)bd;
io.BackendPlatformName = io.BackendRendererName = "imgui_impl_allegro5";
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
bd->Display = display;
// Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, uv) },
{ ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ImDrawVertAllegro, col) },
{ 0, 0, 0 }
};
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
#if ALLEGRO_HAS_CLIPBOARD
io.SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText;
io.GetClipboardTextFn = ImGui_ImplAllegro5_GetClipboardText;
io.ClipboardUserData = nullptr;
#endif
return true;
}
void ImGui_ImplAllegro5_Shutdown()
{
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplAllegro5_InvalidateDeviceObjects();
if (bd->VertexDecl)
al_destroy_vertex_decl(bd->VertexDecl);
if (bd->ClipboardTextData)
al_free(bd->ClipboardTextData);
io.BackendPlatformName = io.BackendRendererName = nullptr;
io.BackendPlatformUserData = nullptr;
io.BackendFlags &= ~ImGuiBackendFlags_HasMouseCursors;
IM_DELETE(bd);
}
// ev->keyboard.modifiers seems always zero so using that...
static void ImGui_ImplAllegro5_UpdateKeyModifiers()
{
ImGuiIO& io = ImGui::GetIO();
ALLEGRO_KEYBOARD_STATE keys;
al_get_keyboard_state(&keys);
io.AddKeyEvent(ImGuiMod_Ctrl, al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL));
io.AddKeyEvent(ImGuiMod_Shift, al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT));
io.AddKeyEvent(ImGuiMod_Alt, al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR));
io.AddKeyEvent(ImGuiMod_Super, al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN));
}
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev)
{
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
if (ev->mouse.display == bd->Display)
{
io.AddMousePosEvent(ev->mouse.x, ev->mouse.y);
io.AddMouseWheelEvent(-ev->mouse.dw, ev->mouse.dz);
}
return true;
case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
if (ev->mouse.display == bd->Display && ev->mouse.button > 0 && ev->mouse.button <= 5)
io.AddMouseButtonEvent(ev->mouse.button - 1, ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN);
return true;
case ALLEGRO_EVENT_TOUCH_MOVE:
if (ev->touch.display == bd->Display)
io.AddMousePosEvent(ev->touch.x, ev->touch.y);
return true;
case ALLEGRO_EVENT_TOUCH_BEGIN:
case ALLEGRO_EVENT_TOUCH_END:
case ALLEGRO_EVENT_TOUCH_CANCEL:
if (ev->touch.display == bd->Display && ev->touch.primary)
io.AddMouseButtonEvent(0, ev->type == ALLEGRO_EVENT_TOUCH_BEGIN);
return true;
case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY:
if (ev->mouse.display == bd->Display)
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
return true;
case ALLEGRO_EVENT_KEY_CHAR:
if (ev->keyboard.display == bd->Display)
if (ev->keyboard.unichar != 0)
io.AddInputCharacter((unsigned int)ev->keyboard.unichar);
return true;
case ALLEGRO_EVENT_KEY_DOWN:
case ALLEGRO_EVENT_KEY_UP:
if (ev->keyboard.display == bd->Display)
{
ImGui_ImplAllegro5_UpdateKeyModifiers();
ImGuiKey key = ImGui_ImplAllegro5_KeyCodeToImGuiKey(ev->keyboard.keycode);
io.AddKeyEvent(key, (ev->type == ALLEGRO_EVENT_KEY_DOWN));
io.SetKeyEventNativeData(key, ev->keyboard.keycode, -1); // To support legacy indexing (<1.87 user code)
}
return true;
case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT:
if (ev->display.source == bd->Display)
io.AddFocusEvent(false);
return true;
case ALLEGRO_EVENT_DISPLAY_SWITCH_IN:
if (ev->display.source == bd->Display)
{
io.AddFocusEvent(true);
#if defined(ALLEGRO_UNSTABLE)
al_clear_keyboard_state(bd->Display);
#endif
}
return true;
}
return false;
}
static void ImGui_ImplAllegro5_UpdateMouseCursor()
{
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return;
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
{
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
al_set_mouse_cursor(bd->Display, bd->MouseCursorInvisible);
}
else
{
ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT;
switch (imgui_cursor)
{
case ImGuiMouseCursor_TextInput: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT; break;
case ImGuiMouseCursor_ResizeAll: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE; break;
case ImGuiMouseCursor_ResizeNS: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N; break;
case ImGuiMouseCursor_ResizeEW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E; break;
case ImGuiMouseCursor_ResizeNESW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE; break;
case ImGuiMouseCursor_ResizeNWSE: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW; break;
case ImGuiMouseCursor_NotAllowed: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE; break;
}
al_set_system_mouse_cursor(bd->Display, cursor_id);
}
}
void ImGui_ImplAllegro5_NewFrame()
{
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplAllegro5_Init()?");
if (!bd->Texture)
ImGui_ImplAllegro5_CreateDeviceObjects();
ImGuiIO& io = ImGui::GetIO();
// Setup display size (every frame to accommodate for window resizing)
int w, h;
w = al_get_display_width(bd->Display);
h = al_get_display_height(bd->Display);
io.DisplaySize = ImVec2((float)w, (float)h);
// Setup time step
double current_time = al_get_time();
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
bd->Time = current_time;
// Setup mouse cursor shape
ImGui_ImplAllegro5_UpdateMouseCursor();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -0,0 +1,38 @@
// dear imgui: Renderer + Platform Backend for Allegro 5
// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.)
// Implemented features:
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: Clipboard support (from Allegro 5.1.12)
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Issues:
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
// [ ] Platform: Missing gamepad support.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ALLEGRO_DISPLAY;
union ALLEGRO_EVENT;
IMGUI_IMPL_API bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display);
IMGUI_IMPL_API void ImGui_ImplAllegro5_Shutdown();
IMGUI_IMPL_API void ImGui_ImplAllegro5_NewFrame();
IMGUI_IMPL_API void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data);
IMGUI_IMPL_API bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* event);
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplAllegro5_InvalidateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -0,0 +1,306 @@
// dear imgui: Platform Binding for Android native app
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
// Implemented features:
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
// Missing features:
// [ ] Platform: Clipboard support.
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [ ] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
// Important:
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
// - FIXME: Unicode character inputs needs to be passed by Dear ImGui by the application (see examples/ and issue #3446)
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-03-04: Initial version.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_android.h"
#include <time.h>
#include <android/native_window.h>
#include <android/input.h>
#include <android/keycodes.h>
#include <android/log.h>
// Android data
static double g_Time = 0.0;
static ANativeWindow* g_Window;
static char g_LogTag[] = "ImGuiExample";
static ImGuiKey ImGui_ImplAndroid_KeyCodeToImGuiKey(int32_t key_code)
{
switch (key_code)
{
case AKEYCODE_TAB: return ImGuiKey_Tab;
case AKEYCODE_DPAD_LEFT: return ImGuiKey_LeftArrow;
case AKEYCODE_DPAD_RIGHT: return ImGuiKey_RightArrow;
case AKEYCODE_DPAD_UP: return ImGuiKey_UpArrow;
case AKEYCODE_DPAD_DOWN: return ImGuiKey_DownArrow;
case AKEYCODE_PAGE_UP: return ImGuiKey_PageUp;
case AKEYCODE_PAGE_DOWN: return ImGuiKey_PageDown;
case AKEYCODE_MOVE_HOME: return ImGuiKey_Home;
case AKEYCODE_MOVE_END: return ImGuiKey_End;
case AKEYCODE_INSERT: return ImGuiKey_Insert;
case AKEYCODE_FORWARD_DEL: return ImGuiKey_Delete;
case AKEYCODE_DEL: return ImGuiKey_Backspace;
case AKEYCODE_SPACE: return ImGuiKey_Space;
case AKEYCODE_ENTER: return ImGuiKey_Enter;
case AKEYCODE_ESCAPE: return ImGuiKey_Escape;
case AKEYCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
case AKEYCODE_COMMA: return ImGuiKey_Comma;
case AKEYCODE_MINUS: return ImGuiKey_Minus;
case AKEYCODE_PERIOD: return ImGuiKey_Period;
case AKEYCODE_SLASH: return ImGuiKey_Slash;
case AKEYCODE_SEMICOLON: return ImGuiKey_Semicolon;
case AKEYCODE_EQUALS: return ImGuiKey_Equal;
case AKEYCODE_LEFT_BRACKET: return ImGuiKey_LeftBracket;
case AKEYCODE_BACKSLASH: return ImGuiKey_Backslash;
case AKEYCODE_RIGHT_BRACKET: return ImGuiKey_RightBracket;
case AKEYCODE_GRAVE: return ImGuiKey_GraveAccent;
case AKEYCODE_CAPS_LOCK: return ImGuiKey_CapsLock;
case AKEYCODE_SCROLL_LOCK: return ImGuiKey_ScrollLock;
case AKEYCODE_NUM_LOCK: return ImGuiKey_NumLock;
case AKEYCODE_SYSRQ: return ImGuiKey_PrintScreen;
case AKEYCODE_BREAK: return ImGuiKey_Pause;
case AKEYCODE_NUMPAD_0: return ImGuiKey_Keypad0;
case AKEYCODE_NUMPAD_1: return ImGuiKey_Keypad1;
case AKEYCODE_NUMPAD_2: return ImGuiKey_Keypad2;
case AKEYCODE_NUMPAD_3: return ImGuiKey_Keypad3;
case AKEYCODE_NUMPAD_4: return ImGuiKey_Keypad4;
case AKEYCODE_NUMPAD_5: return ImGuiKey_Keypad5;
case AKEYCODE_NUMPAD_6: return ImGuiKey_Keypad6;
case AKEYCODE_NUMPAD_7: return ImGuiKey_Keypad7;
case AKEYCODE_NUMPAD_8: return ImGuiKey_Keypad8;
case AKEYCODE_NUMPAD_9: return ImGuiKey_Keypad9;
case AKEYCODE_NUMPAD_DOT: return ImGuiKey_KeypadDecimal;
case AKEYCODE_NUMPAD_DIVIDE: return ImGuiKey_KeypadDivide;
case AKEYCODE_NUMPAD_MULTIPLY: return ImGuiKey_KeypadMultiply;
case AKEYCODE_NUMPAD_SUBTRACT: return ImGuiKey_KeypadSubtract;
case AKEYCODE_NUMPAD_ADD: return ImGuiKey_KeypadAdd;
case AKEYCODE_NUMPAD_ENTER: return ImGuiKey_KeypadEnter;
case AKEYCODE_NUMPAD_EQUALS: return ImGuiKey_KeypadEqual;
case AKEYCODE_CTRL_LEFT: return ImGuiKey_LeftCtrl;
case AKEYCODE_SHIFT_LEFT: return ImGuiKey_LeftShift;
case AKEYCODE_ALT_LEFT: return ImGuiKey_LeftAlt;
case AKEYCODE_META_LEFT: return ImGuiKey_LeftSuper;
case AKEYCODE_CTRL_RIGHT: return ImGuiKey_RightCtrl;
case AKEYCODE_SHIFT_RIGHT: return ImGuiKey_RightShift;
case AKEYCODE_ALT_RIGHT: return ImGuiKey_RightAlt;
case AKEYCODE_META_RIGHT: return ImGuiKey_RightSuper;
case AKEYCODE_MENU: return ImGuiKey_Menu;
case AKEYCODE_0: return ImGuiKey_0;
case AKEYCODE_1: return ImGuiKey_1;
case AKEYCODE_2: return ImGuiKey_2;
case AKEYCODE_3: return ImGuiKey_3;
case AKEYCODE_4: return ImGuiKey_4;
case AKEYCODE_5: return ImGuiKey_5;
case AKEYCODE_6: return ImGuiKey_6;
case AKEYCODE_7: return ImGuiKey_7;
case AKEYCODE_8: return ImGuiKey_8;
case AKEYCODE_9: return ImGuiKey_9;
case AKEYCODE_A: return ImGuiKey_A;
case AKEYCODE_B: return ImGuiKey_B;
case AKEYCODE_C: return ImGuiKey_C;
case AKEYCODE_D: return ImGuiKey_D;
case AKEYCODE_E: return ImGuiKey_E;
case AKEYCODE_F: return ImGuiKey_F;
case AKEYCODE_G: return ImGuiKey_G;
case AKEYCODE_H: return ImGuiKey_H;
case AKEYCODE_I: return ImGuiKey_I;
case AKEYCODE_J: return ImGuiKey_J;
case AKEYCODE_K: return ImGuiKey_K;
case AKEYCODE_L: return ImGuiKey_L;
case AKEYCODE_M: return ImGuiKey_M;
case AKEYCODE_N: return ImGuiKey_N;
case AKEYCODE_O: return ImGuiKey_O;
case AKEYCODE_P: return ImGuiKey_P;
case AKEYCODE_Q: return ImGuiKey_Q;
case AKEYCODE_R: return ImGuiKey_R;
case AKEYCODE_S: return ImGuiKey_S;
case AKEYCODE_T: return ImGuiKey_T;
case AKEYCODE_U: return ImGuiKey_U;
case AKEYCODE_V: return ImGuiKey_V;
case AKEYCODE_W: return ImGuiKey_W;
case AKEYCODE_X: return ImGuiKey_X;
case AKEYCODE_Y: return ImGuiKey_Y;
case AKEYCODE_Z: return ImGuiKey_Z;
case AKEYCODE_F1: return ImGuiKey_F1;
case AKEYCODE_F2: return ImGuiKey_F2;
case AKEYCODE_F3: return ImGuiKey_F3;
case AKEYCODE_F4: return ImGuiKey_F4;
case AKEYCODE_F5: return ImGuiKey_F5;
case AKEYCODE_F6: return ImGuiKey_F6;
case AKEYCODE_F7: return ImGuiKey_F7;
case AKEYCODE_F8: return ImGuiKey_F8;
case AKEYCODE_F9: return ImGuiKey_F9;
case AKEYCODE_F10: return ImGuiKey_F10;
case AKEYCODE_F11: return ImGuiKey_F11;
case AKEYCODE_F12: return ImGuiKey_F12;
default: return ImGuiKey_None;
}
}
int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event)
{
ImGuiIO& io = ImGui::GetIO();
int32_t event_type = AInputEvent_getType(input_event);
switch (event_type)
{
case AINPUT_EVENT_TYPE_KEY:
{
int32_t event_key_code = AKeyEvent_getKeyCode(input_event);
int32_t event_scan_code = AKeyEvent_getScanCode(input_event);
int32_t event_action = AKeyEvent_getAction(input_event);
int32_t event_meta_state = AKeyEvent_getMetaState(input_event);
io.AddKeyEvent(ImGuiMod_Ctrl, (event_meta_state & AMETA_CTRL_ON) != 0);
io.AddKeyEvent(ImGuiMod_Shift, (event_meta_state & AMETA_SHIFT_ON) != 0);
io.AddKeyEvent(ImGuiMod_Alt, (event_meta_state & AMETA_ALT_ON) != 0);
io.AddKeyEvent(ImGuiMod_Super, (event_meta_state & AMETA_META_ON) != 0);
switch (event_action)
{
// FIXME: AKEY_EVENT_ACTION_DOWN and AKEY_EVENT_ACTION_UP occur at once as soon as a touch pointer
// goes up from a key. We use a simple key event queue/ and process one event per key per frame in
// ImGui_ImplAndroid_NewFrame()...or consider using IO queue, if suitable: https://github.com/ocornut/imgui/issues/2787
case AKEY_EVENT_ACTION_DOWN:
case AKEY_EVENT_ACTION_UP:
{
ImGuiKey key = ImGui_ImplAndroid_KeyCodeToImGuiKey(event_key_code);
if (key != ImGuiKey_None)
{
io.AddKeyEvent(key, event_action == AKEY_EVENT_ACTION_DOWN);
io.SetKeyEventNativeData(key, event_key_code, event_scan_code);
}
break;
}
default:
break;
}
break;
}
case AINPUT_EVENT_TYPE_MOTION:
{
int32_t event_action = AMotionEvent_getAction(input_event);
int32_t event_pointer_index = (event_action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
event_action &= AMOTION_EVENT_ACTION_MASK;
switch (AMotionEvent_getToolType(input_event, event_pointer_index))
{
case AMOTION_EVENT_TOOL_TYPE_MOUSE:
io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
break;
case AMOTION_EVENT_TOOL_TYPE_STYLUS:
case AMOTION_EVENT_TOOL_TYPE_ERASER:
io.AddMouseSourceEvent(ImGuiMouseSource_Pen);
break;
case AMOTION_EVENT_TOOL_TYPE_FINGER:
default:
io.AddMouseSourceEvent(ImGuiMouseSource_TouchScreen);
break;
}
switch (event_action)
{
case AMOTION_EVENT_ACTION_DOWN:
case AMOTION_EVENT_ACTION_UP:
{
// Physical mouse buttons (and probably other physical devices) also invoke the actions AMOTION_EVENT_ACTION_DOWN/_UP,
// but we have to process them separately to identify the actual button pressed. This is done below via
// AMOTION_EVENT_ACTION_BUTTON_PRESS/_RELEASE. Here, we only process "FINGER" input (and "UNKNOWN", as a fallback).
int tool_type = AMotionEvent_getToolType(input_event, event_pointer_index);
if (tool_type == AMOTION_EVENT_TOOL_TYPE_FINGER || tool_type == AMOTION_EVENT_TOOL_TYPE_UNKNOWN)
{
io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
io.AddMouseButtonEvent(0, event_action == AMOTION_EVENT_ACTION_DOWN);
}
break;
}
case AMOTION_EVENT_ACTION_BUTTON_PRESS:
case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
{
int32_t button_state = AMotionEvent_getButtonState(input_event);
io.AddMouseButtonEvent(0, (button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0);
io.AddMouseButtonEvent(1, (button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0);
io.AddMouseButtonEvent(2, (button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0);
break;
}
case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse)
case AMOTION_EVENT_ACTION_MOVE: // Touch pointer moves while DOWN
io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
break;
case AMOTION_EVENT_ACTION_SCROLL:
io.AddMouseWheelEvent(AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_HSCROLL, event_pointer_index), AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_VSCROLL, event_pointer_index));
break;
default:
break;
}
}
return 1;
default:
break;
}
return 0;
}
bool ImGui_ImplAndroid_Init(ANativeWindow* window)
{
g_Window = window;
g_Time = 0.0;
// Setup backend capabilities flags
ImGuiIO& io = ImGui::GetIO();
io.BackendPlatformName = "imgui_impl_android";
return true;
}
void ImGui_ImplAndroid_Shutdown()
{
ImGuiIO& io = ImGui::GetIO();
io.BackendPlatformName = nullptr;
}
void ImGui_ImplAndroid_NewFrame()
{
ImGuiIO& io = ImGui::GetIO();
// Setup display size (every frame to accommodate for window resizing)
int32_t window_width = ANativeWindow_getWidth(g_Window);
int32_t window_height = ANativeWindow_getHeight(g_Window);
int display_width = window_width;
int display_height = window_height;
io.DisplaySize = ImVec2((float)window_width, (float)window_height);
if (window_width > 0 && window_height > 0)
io.DisplayFramebufferScale = ImVec2((float)display_width / window_width, (float)display_height / window_height);
// Setup time step
struct timespec current_timespec;
clock_gettime(CLOCK_MONOTONIC, &current_timespec);
double current_time = (double)(current_timespec.tv_sec) + (current_timespec.tv_nsec / 1000000000.0);
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f);
g_Time = current_time;
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -0,0 +1,36 @@
// dear imgui: Platform Binding for Android native app
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
// Implemented features:
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
// Missing features:
// [ ] Platform: Clipboard support.
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [ ] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
// Important:
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
// - FIXME: Unicode character inputs needs to be passed by Dear ImGui by the application (see examples/ and issue #3446)
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ANativeWindow;
struct AInputEvent;
IMGUI_IMPL_API bool ImGui_ImplAndroid_Init(ANativeWindow* window);
IMGUI_IMPL_API int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event);
IMGUI_IMPL_API void ImGui_ImplAndroid_Shutdown();
IMGUI_IMPL_API void ImGui_ImplAndroid_NewFrame();
#endif // #ifndef IMGUI_DISABLE

View File

@ -0,0 +1,589 @@
// dear imgui: Renderer Backend for DirectX10
// This needs to be used along with a Platform Backend (e.g. Win32)
// Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: DirectX10: Change blending equation to preserve alpha in output buffer.
// 2019-07-21: DirectX10: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData().
// 2019-05-29: DirectX10: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: DirectX10: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-07-13: DirectX10: Fixed unreleased resources in Init and Shutdown functions.
// 2018-06-08: Misc: Extracted imgui_impl_dx10.cpp/.h away from the old combined DX10+Win32 example.
// 2018-06-08: DirectX10: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
// 2018-04-09: Misc: Fixed erroneous call to io.Fonts->ClearInputData() + ClearTexData() that was left in DX10 example but removed in 1.47 (Nov 2015) on other backends.
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX10_RenderDrawData() in the .h file so you can call it yourself.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2016-05-07: DirectX10: Disabling depth-write.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx10.h"
// DirectX
#include <stdio.h>
#include <d3d10_1.h>
#include <d3d10.h>
#include <d3dcompiler.h>
#ifdef _MSC_VER
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
#endif
// DirectX data
struct ImGui_ImplDX10_Data
{
ID3D10Device* pd3dDevice;
IDXGIFactory* pFactory;
ID3D10Buffer* pVB;
ID3D10Buffer* pIB;
ID3D10VertexShader* pVertexShader;
ID3D10InputLayout* pInputLayout;
ID3D10Buffer* pVertexConstantBuffer;
ID3D10PixelShader* pPixelShader;
ID3D10SamplerState* pFontSampler;
ID3D10ShaderResourceView* pFontTextureView;
ID3D10RasterizerState* pRasterizerState;
ID3D10BlendState* pBlendState;
ID3D10DepthStencilState* pDepthStencilState;
int VertexBufferSize;
int IndexBufferSize;
ImGui_ImplDX10_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
};
struct VERTEX_CONSTANT_BUFFER_DX10
{
float mvp[4][4];
};
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
{
return ImGui::GetCurrentContext() ? (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
// Functions
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx)
{
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
// Setup viewport
D3D10_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D10_VIEWPORT));
vp.Width = (UINT)draw_data->DisplaySize.x;
vp.Height = (UINT)draw_data->DisplaySize.y;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0;
ctx->RSSetViewports(1, &vp);
// Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0;
ctx->IASetInputLayout(bd->pInputLayout);
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->VSSetShader(bd->pVertexShader);
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
ctx->PSSetShader(bd->pPixelShader);
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
ctx->GSSetShader(nullptr);
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
ctx->RSSetState(bd->pRasterizerState);
}
// Render function
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
{
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
ID3D10Device* ctx = bd->pd3dDevice;
// Create and grow vertex/index buffers if needed
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
{
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
D3D10_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
desc.Usage = D3D10_USAGE_DYNAMIC;
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
if (ctx->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
return;
}
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
{
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D10_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
desc.Usage = D3D10_USAGE_DYNAMIC;
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
if (ctx->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
return;
}
// Copy and convert all vertices into a single contiguous buffer
ImDrawVert* vtx_dst = nullptr;
ImDrawIdx* idx_dst = nullptr;
bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size;
}
bd->pVB->Unmap();
bd->pIB->Unmap();
// Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
{
void* mapped_resource;
if (bd->pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return;
VERTEX_CONSTANT_BUFFER_DX10* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX10*)mapped_resource;
float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
float mvp[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
};
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
bd->pVertexConstantBuffer->Unmap();
}
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
struct BACKUP_DX10_STATE
{
UINT ScissorRectsCount, ViewportsCount;
D3D10_RECT ScissorRects[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
D3D10_VIEWPORT Viewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
ID3D10RasterizerState* RS;
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
UINT StencilRef;
ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
ID3D10VertexShader* VS;
ID3D10GeometryShader* GS;
D3D10_PRIMITIVE_TOPOLOGY PrimitiveTopology;
ID3D10Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
DXGI_FORMAT IndexBufferFormat;
ID3D10InputLayout* InputLayout;
};
BACKUP_DX10_STATE old = {};
old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
ctx->VSGetShader(&old.VS);
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
ctx->GSGetShader(&old.GS);
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
ctx->IAGetInputLayout(&old.InputLayout);
// Setup desired DX state
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
// Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them)
int global_vtx_offset = 0;
int global_idx_offset = 0;
ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback)
{
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
else
pcmd->UserCallback(cmd_list, pcmd);
}
else
{
// Project scissor/clipping rectangles into framebuffer space
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue;
// Apply scissor/clipping rectangle
const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
ctx->RSSetScissorRects(1, &r);
// Bind texture, Draw
ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->GetTexID();
ctx->PSSetShaderResources(0, 1, &texture_srv);
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
}
}
global_idx_offset += cmd_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size;
}
// Restore modified DX state
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release();
ctx->GSSetShader(old.GS); if (old.GS) old.GS->Release();
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
}
static void ImGui_ImplDX10_CreateFontsTexture()
{
// Build texture atlas
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
// Upload texture to graphics system
{
D3D10_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = width;
desc.Height = height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
ID3D10Texture2D* pTexture = nullptr;
D3D10_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels;
subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0;
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
IM_ASSERT(pTexture != nullptr);
// Create texture view
D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
ZeroMemory(&srv_desc, sizeof(srv_desc));
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
srv_desc.Texture2D.MipLevels = desc.MipLevels;
srv_desc.Texture2D.MostDetailedMip = 0;
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srv_desc, &bd->pFontTextureView);
pTexture->Release();
}
// Store our identifier
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
// Create texture sampler
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
{
D3D10_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP;
desc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP;
desc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP;
desc.MipLODBias = 0.f;
desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
desc.MinLOD = 0.f;
desc.MaxLOD = 0.f;
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
}
}
bool ImGui_ImplDX10_CreateDeviceObjects()
{
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
if (!bd->pd3dDevice)
return false;
if (bd->pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects();
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
// If you would like to use this DX10 sample code but remove this dependency you can:
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
// Create the vertex shader
{
static const char* vertexShader =
"cbuffer vertexBuffer : register(b0) \
{\
float4x4 ProjectionMatrix; \
};\
struct VS_INPUT\
{\
float2 pos : POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
PS_INPUT main(VS_INPUT input)\
{\
PS_INPUT output;\
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
output.col = input.col;\
output.uv = input.uv;\
return output;\
}";
ID3DBlob* vertexShaderBlob;
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pVertexShader) != S_OK)
{
vertexShaderBlob->Release();
return false;
}
// Create the input layout
D3D10_INPUT_ELEMENT_DESC local_layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
{
vertexShaderBlob->Release();
return false;
}
vertexShaderBlob->Release();
// Create the constant buffer
{
D3D10_BUFFER_DESC desc;
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX10);
desc.Usage = D3D10_USAGE_DYNAMIC;
desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVertexConstantBuffer);
}
}
// Create the pixel shader
{
static const char* pixelShader =
"struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
sampler sampler0;\
Texture2D texture0;\
\
float4 main(PS_INPUT input) : SV_Target\
{\
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
return out_col; \
}";
ID3DBlob* pixelShaderBlob;
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), &bd->pPixelShader) != S_OK)
{
pixelShaderBlob->Release();
return false;
}
pixelShaderBlob->Release();
}
// Create the blending setup
{
D3D10_BLEND_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.AlphaToCoverageEnable = false;
desc.BlendEnable[0] = true;
desc.SrcBlend = D3D10_BLEND_SRC_ALPHA;
desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
desc.BlendOp = D3D10_BLEND_OP_ADD;
desc.SrcBlendAlpha = D3D10_BLEND_ONE;
desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState);
}
// Create the rasterizer state
{
D3D10_RASTERIZER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.FillMode = D3D10_FILL_SOLID;
desc.CullMode = D3D10_CULL_NONE;
desc.ScissorEnable = true;
desc.DepthClipEnable = true;
bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState);
}
// Create depth-stencil State
{
D3D10_DEPTH_STENCIL_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.DepthEnable = false;
desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
desc.StencilEnable = false;
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
desc.BackFace = desc.FrontFace;
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
}
ImGui_ImplDX10_CreateFontsTexture();
return true;
}
void ImGui_ImplDX10_InvalidateDeviceObjects()
{
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
if (!bd->pd3dDevice)
return;
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = nullptr; }
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = nullptr; }
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = nullptr; }
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = nullptr; }
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = nullptr; }
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = nullptr; }
}
bool ImGui_ImplDX10_Init(ID3D10Device* device)
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags
ImGui_ImplDX10_Data* bd = IM_NEW(ImGui_ImplDX10_Data)();
io.BackendRendererUserData = (void*)bd;
io.BackendRendererName = "imgui_impl_dx10";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
// Get factory from device
IDXGIDevice* pDXGIDevice = nullptr;
IDXGIAdapter* pDXGIAdapter = nullptr;
IDXGIFactory* pFactory = nullptr;
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
{
bd->pd3dDevice = device;
bd->pFactory = pFactory;
}
if (pDXGIDevice) pDXGIDevice->Release();
if (pDXGIAdapter) pDXGIAdapter->Release();
bd->pd3dDevice->AddRef();
return true;
}
void ImGui_ImplDX10_Shutdown()
{
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplDX10_InvalidateDeviceObjects();
if (bd->pFactory) { bd->pFactory->Release(); }
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
io.BackendRendererName = nullptr;
io.BackendRendererUserData = nullptr;
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
IM_DELETE(bd);
}
void ImGui_ImplDX10_NewFrame()
{
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX10_Init()?");
if (!bd->pFontSampler)
ImGui_ImplDX10_CreateDeviceObjects();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -0,0 +1,31 @@
// dear imgui: Renderer Backend for DirectX10
// This needs to be used along with a Platform Backend (e.g. Win32)
// Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ID3D10Device;
IMGUI_IMPL_API bool ImGui_ImplDX10_Init(ID3D10Device* device);
IMGUI_IMPL_API void ImGui_ImplDX10_Shutdown();
IMGUI_IMPL_API void ImGui_ImplDX10_NewFrame();
IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -0,0 +1,605 @@
// dear imgui: Renderer Backend for DirectX11
// This needs to be used along with a Platform Backend (e.g. Win32)
// Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility.
// 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions.
// 2018-06-08: Misc: Extracted imgui_impl_dx11.cpp/.h away from the old combined DX11+Win32 example.
// 2018-06-08: DirectX11: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2016-05-07: DirectX11: Disabling depth-write.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx11.h"
// DirectX
#include <stdio.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#ifdef _MSC_VER
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
#endif
// DirectX11 data
struct ImGui_ImplDX11_Data
{
ID3D11Device* pd3dDevice;
ID3D11DeviceContext* pd3dDeviceContext;
IDXGIFactory* pFactory;
ID3D11Buffer* pVB;
ID3D11Buffer* pIB;
ID3D11VertexShader* pVertexShader;
ID3D11InputLayout* pInputLayout;
ID3D11Buffer* pVertexConstantBuffer;
ID3D11PixelShader* pPixelShader;
ID3D11SamplerState* pFontSampler;
ID3D11ShaderResourceView* pFontTextureView;
ID3D11RasterizerState* pRasterizerState;
ID3D11BlendState* pBlendState;
ID3D11DepthStencilState* pDepthStencilState;
int VertexBufferSize;
int IndexBufferSize;
ImGui_ImplDX11_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
};
struct VERTEX_CONSTANT_BUFFER_DX11
{
float mvp[4][4];
};
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
{
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
// Functions
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
{
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
// Setup viewport
D3D11_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
vp.Width = draw_data->DisplaySize.x;
vp.Height = draw_data->DisplaySize.y;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0;
ctx->RSSetViewports(1, &vp);
// Setup shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0;
ctx->IASetInputLayout(bd->pInputLayout);
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
ctx->GSSetShader(nullptr, nullptr, 0);
ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
// Setup blend state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
ctx->RSSetState(bd->pRasterizerState);
}
// Render function
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
{
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
ID3D11DeviceContext* ctx = bd->pd3dDeviceContext;
// Create and grow vertex/index buffers if needed
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
{
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
return;
}
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
{
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
return;
}
// Upload vertex/index data into a single contiguous GPU buffer
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
return;
if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size;
}
ctx->Unmap(bd->pVB, 0);
ctx->Unmap(bd->pIB, 0);
// Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
{
D3D11_MAPPED_SUBRESOURCE mapped_resource;
if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return;
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
float mvp[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
};
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
ctx->Unmap(bd->pVertexConstantBuffer, 0);
}
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
struct BACKUP_DX11_STATE
{
UINT ScissorRectsCount, ViewportsCount;
D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
ID3D11RasterizerState* RS;
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
UINT StencilRef;
ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
ID3D11VertexShader* VS;
ID3D11GeometryShader* GS;
UINT PSInstancesCount, VSInstancesCount, GSInstancesCount;
ID3D11ClassInstance *PSInstances[256], *VSInstances[256], *GSInstances[256]; // 256 is max according to PSSetShader documentation
D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology;
ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
DXGI_FORMAT IndexBufferFormat;
ID3D11InputLayout* InputLayout;
};
BACKUP_DX11_STATE old = {};
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
ctx->IAGetInputLayout(&old.InputLayout);
// Setup desired DX state
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
// Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them)
int global_idx_offset = 0;
int global_vtx_offset = 0;
ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != nullptr)
{
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
else
pcmd->UserCallback(cmd_list, pcmd);
}
else
{
// Project scissor/clipping rectangles into framebuffer space
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue;
// Apply scissor/clipping rectangle
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
ctx->RSSetScissorRects(1, &r);
// Bind texture, Draw
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
ctx->PSSetShaderResources(0, 1, &texture_srv);
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
}
}
global_idx_offset += cmd_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size;
}
// Restore modified DX state
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
}
static void ImGui_ImplDX11_CreateFontsTexture()
{
// Build texture atlas
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
// Upload texture to graphics system
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = width;
desc.Height = height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
ID3D11Texture2D* pTexture = nullptr;
D3D11_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels;
subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0;
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
IM_ASSERT(pTexture != nullptr);
// Create texture view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &bd->pFontTextureView);
pTexture->Release();
}
// Store our identifier
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
// Create texture sampler
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
{
D3D11_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
desc.MipLODBias = 0.f;
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
desc.MinLOD = 0.f;
desc.MaxLOD = 0.f;
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
}
}
bool ImGui_ImplDX11_CreateDeviceObjects()
{
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
if (!bd->pd3dDevice)
return false;
if (bd->pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
// If you would like to use this DX11 sample code but remove this dependency you can:
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
// Create the vertex shader
{
static const char* vertexShader =
"cbuffer vertexBuffer : register(b0) \
{\
float4x4 ProjectionMatrix; \
};\
struct VS_INPUT\
{\
float2 pos : POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
PS_INPUT main(VS_INPUT input)\
{\
PS_INPUT output;\
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
output.col = input.col;\
output.uv = input.uv;\
return output;\
}";
ID3DBlob* vertexShaderBlob;
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &bd->pVertexShader) != S_OK)
{
vertexShaderBlob->Release();
return false;
}
// Create the input layout
D3D11_INPUT_ELEMENT_DESC local_layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
{
vertexShaderBlob->Release();
return false;
}
vertexShaderBlob->Release();
// Create the constant buffer
{
D3D11_BUFFER_DESC desc;
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX11);
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVertexConstantBuffer);
}
}
// Create the pixel shader
{
static const char* pixelShader =
"struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
sampler sampler0;\
Texture2D texture0;\
\
float4 main(PS_INPUT input) : SV_Target\
{\
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
return out_col; \
}";
ID3DBlob* pixelShaderBlob;
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &bd->pPixelShader) != S_OK)
{
pixelShaderBlob->Release();
return false;
}
pixelShaderBlob->Release();
}
// Create the blending setup
{
D3D11_BLEND_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.AlphaToCoverageEnable = false;
desc.RenderTarget[0].BlendEnable = true;
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState);
}
// Create the rasterizer state
{
D3D11_RASTERIZER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.FillMode = D3D11_FILL_SOLID;
desc.CullMode = D3D11_CULL_NONE;
desc.ScissorEnable = true;
desc.DepthClipEnable = true;
bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState);
}
// Create depth-stencil State
{
D3D11_DEPTH_STENCIL_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.DepthEnable = false;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
desc.StencilEnable = false;
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
desc.BackFace = desc.FrontFace;
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
}
ImGui_ImplDX11_CreateFontsTexture();
return true;
}
void ImGui_ImplDX11_InvalidateDeviceObjects()
{
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
if (!bd->pd3dDevice)
return;
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = nullptr; }
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = nullptr; }
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = nullptr; }
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = nullptr; }
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = nullptr; }
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = nullptr; }
}
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags
ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)();
io.BackendRendererUserData = (void*)bd;
io.BackendRendererName = "imgui_impl_dx11";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
// Get factory from device
IDXGIDevice* pDXGIDevice = nullptr;
IDXGIAdapter* pDXGIAdapter = nullptr;
IDXGIFactory* pFactory = nullptr;
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
{
bd->pd3dDevice = device;
bd->pd3dDeviceContext = device_context;
bd->pFactory = pFactory;
}
if (pDXGIDevice) pDXGIDevice->Release();
if (pDXGIAdapter) pDXGIAdapter->Release();
bd->pd3dDevice->AddRef();
bd->pd3dDeviceContext->AddRef();
return true;
}
void ImGui_ImplDX11_Shutdown()
{
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplDX11_InvalidateDeviceObjects();
if (bd->pFactory) { bd->pFactory->Release(); }
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
io.BackendRendererName = nullptr;
io.BackendRendererUserData = nullptr;
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
IM_DELETE(bd);
}
void ImGui_ImplDX11_NewFrame()
{
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX11_Init()?");
if (!bd->pFontSampler)
ImGui_ImplDX11_CreateDeviceObjects();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -0,0 +1,32 @@
// dear imgui: Renderer Backend for DirectX11
// This needs to be used along with a Platform Backend (e.g. Win32)
// Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ID3D11Device;
struct ID3D11DeviceContext;
IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -0,0 +1,761 @@
// dear imgui: Renderer Backend for DirectX12
// This needs to be used along with a Platform Backend (e.g. Win32)
// Implemented features:
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
// To build this on 32-bit systems:
// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer.
// 2021-01-11: DirectX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically.
// 2020-09-16: DirectX12: Avoid rendering calls with zero-sized scissor rectangle since it generates a validation layer warning.
// 2020-09-08: DirectX12: Clarified support for building on 32-bit systems by redefining ImTextureID.
// 2019-10-18: DirectX12: *BREAKING CHANGE* Added extra ID3D12DescriptorHeap parameter to ImGui_ImplDX12_Init() function.
// 2019-05-29: DirectX12: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: DirectX12: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2019-03-29: Misc: Various minor tidying up.
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-06-12: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData().
// 2018-06-08: Misc: Extracted imgui_impl_dx12.cpp/.h away from the old combined DX12+Win32 example.
// 2018-06-08: DirectX12: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle (to ease support for future multi-viewport).
// 2018-02-22: Merged into master with all Win32 code synchronized to other examples.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx12.h"
// DirectX
#include <d3d12.h>
#include <dxgi1_4.h>
#include <d3dcompiler.h>
#ifdef _MSC_VER
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
#endif
// DirectX data
struct ImGui_ImplDX12_RenderBuffers;
struct ImGui_ImplDX12_Data
{
ID3D12Device* pd3dDevice;
ID3D12RootSignature* pRootSignature;
ID3D12PipelineState* pPipelineState;
DXGI_FORMAT RTVFormat;
ID3D12Resource* pFontTextureResource;
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
ID3D12DescriptorHeap* pd3dSrvDescHeap;
UINT numFramesInFlight;
ImGui_ImplDX12_RenderBuffers* pFrameResources;
UINT frameIndex;
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); frameIndex = UINT_MAX; }
};
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData()
{
return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
// Buffers used during the rendering of a frame
struct ImGui_ImplDX12_RenderBuffers
{
ID3D12Resource* IndexBuffer;
ID3D12Resource* VertexBuffer;
int IndexBufferSize;
int VertexBufferSize;
};
struct VERTEX_CONSTANT_BUFFER_DX12
{
float mvp[4][4];
};
// Functions
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr)
{
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
// Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
VERTEX_CONSTANT_BUFFER_DX12 vertex_constant_buffer;
{
float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
float mvp[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
};
memcpy(&vertex_constant_buffer.mvp, mvp, sizeof(mvp));
}
// Setup viewport
D3D12_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D12_VIEWPORT));
vp.Width = draw_data->DisplaySize.x;
vp.Height = draw_data->DisplaySize.y;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0.0f;
ctx->RSSetViewports(1, &vp);
// Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0;
D3D12_VERTEX_BUFFER_VIEW vbv;
memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW));
vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset;
vbv.SizeInBytes = fr->VertexBufferSize * stride;
vbv.StrideInBytes = stride;
ctx->IASetVertexBuffers(0, 1, &vbv);
D3D12_INDEX_BUFFER_VIEW ibv;
memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW));
ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress();
ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx);
ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
ctx->IASetIndexBuffer(&ibv);
ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->SetPipelineState(bd->pPipelineState);
ctx->SetGraphicsRootSignature(bd->pRootSignature);
ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
// Setup blend factor
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendFactor(blend_factor);
}
template<typename T>
static inline void SafeRelease(T*& res)
{
if (res)
res->Release();
res = nullptr;
}
// Render function
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx)
{
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
// FIXME: I'm assuming that this only gets called once per frame!
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
bd->frameIndex = bd->frameIndex + 1;
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[bd->frameIndex % bd->numFramesInFlight];
// Create and grow vertex/index buffers if needed
if (fr->VertexBuffer == nullptr || fr->VertexBufferSize < draw_data->TotalVtxCount)
{
SafeRelease(fr->VertexBuffer);
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
D3D12_HEAP_PROPERTIES props;
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
props.Type = D3D12_HEAP_TYPE_UPLOAD;
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
D3D12_RESOURCE_DESC desc;
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert);
desc.Height = 1;
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.SampleDesc.Count = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&fr->VertexBuffer)) < 0)
return;
}
if (fr->IndexBuffer == nullptr || fr->IndexBufferSize < draw_data->TotalIdxCount)
{
SafeRelease(fr->IndexBuffer);
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D12_HEAP_PROPERTIES props;
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
props.Type = D3D12_HEAP_TYPE_UPLOAD;
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
D3D12_RESOURCE_DESC desc;
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx);
desc.Height = 1;
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.SampleDesc.Count = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&fr->IndexBuffer)) < 0)
return;
}
// Upload vertex/index data into a single contiguous GPU buffer
void* vtx_resource, *idx_resource;
D3D12_RANGE range;
memset(&range, 0, sizeof(D3D12_RANGE));
if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK)
return;
if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK)
return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size;
}
fr->VertexBuffer->Unmap(0, &range);
fr->IndexBuffer->Unmap(0, &range);
// Setup desired DX state
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
// Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them)
int global_vtx_offset = 0;
int global_idx_offset = 0;
ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != nullptr)
{
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
else
pcmd->UserCallback(cmd_list, pcmd);
}
else
{
// Project scissor/clipping rectangles into framebuffer space
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue;
// Apply Scissor/clipping rectangle, Bind texture, Draw
const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
texture_handle.ptr = (UINT64)pcmd->GetTexID();
ctx->SetGraphicsRootDescriptorTable(1, texture_handle);
ctx->RSSetScissorRects(1, &r);
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
}
}
global_idx_offset += cmd_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size;
}
}
static void ImGui_ImplDX12_CreateFontsTexture()
{
// Build texture atlas
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
// Upload texture to graphics system
{
D3D12_HEAP_PROPERTIES props;
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
props.Type = D3D12_HEAP_TYPE_DEFAULT;
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
D3D12_RESOURCE_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
desc.Alignment = 0;
desc.Width = width;
desc.Height = height;
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
ID3D12Resource* pTexture = nullptr;
bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&pTexture));
UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
UINT uploadSize = height * uploadPitch;
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Alignment = 0;
desc.Width = uploadSize;
desc.Height = 1;
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
props.Type = D3D12_HEAP_TYPE_UPLOAD;
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
ID3D12Resource* uploadBuffer = nullptr;
HRESULT hr = bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&uploadBuffer));
IM_ASSERT(SUCCEEDED(hr));
void* mapped = nullptr;
D3D12_RANGE range = { 0, uploadSize };
hr = uploadBuffer->Map(0, &range, &mapped);
IM_ASSERT(SUCCEEDED(hr));
for (int y = 0; y < height; y++)
memcpy((void*) ((uintptr_t) mapped + y * uploadPitch), pixels + y * width * 4, width * 4);
uploadBuffer->Unmap(0, &range);
D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
srcLocation.pResource = uploadBuffer;
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srcLocation.PlacedFootprint.Footprint.Width = width;
srcLocation.PlacedFootprint.Footprint.Height = height;
srcLocation.PlacedFootprint.Footprint.Depth = 1;
srcLocation.PlacedFootprint.Footprint.RowPitch = uploadPitch;
D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
dstLocation.pResource = pTexture;
dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
dstLocation.SubresourceIndex = 0;
D3D12_RESOURCE_BARRIER barrier = {};
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier.Transition.pResource = pTexture;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
ID3D12Fence* fence = nullptr;
hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
IM_ASSERT(SUCCEEDED(hr));
HANDLE event = CreateEvent(0, 0, 0, 0);
IM_ASSERT(event != nullptr);
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.NodeMask = 1;
ID3D12CommandQueue* cmdQueue = nullptr;
hr = bd->pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue));
IM_ASSERT(SUCCEEDED(hr));
ID3D12CommandAllocator* cmdAlloc = nullptr;
hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
IM_ASSERT(SUCCEEDED(hr));
ID3D12GraphicsCommandList* cmdList = nullptr;
hr = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr, IID_PPV_ARGS(&cmdList));
IM_ASSERT(SUCCEEDED(hr));
cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, nullptr);
cmdList->ResourceBarrier(1, &barrier);
hr = cmdList->Close();
IM_ASSERT(SUCCEEDED(hr));
cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmdList);
hr = cmdQueue->Signal(fence, 1);
IM_ASSERT(SUCCEEDED(hr));
fence->SetEventOnCompletion(1, event);
WaitForSingleObject(event, INFINITE);
cmdList->Release();
cmdAlloc->Release();
cmdQueue->Release();
CloseHandle(event);
fence->Release();
uploadBuffer->Release();
// Create texture view
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, bd->hFontSrvCpuDescHandle);
SafeRelease(bd->pFontTextureResource);
bd->pFontTextureResource = pTexture;
}
// Store our identifier
// READ THIS IF THE STATIC_ASSERT() TRIGGERS:
// - Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
// - This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
// [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
// [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
// [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
// [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
static_assert(sizeof(ImTextureID) >= sizeof(bd->hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr);
}
bool ImGui_ImplDX12_CreateDeviceObjects()
{
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
if (!bd || !bd->pd3dDevice)
return false;
if (bd->pPipelineState)
ImGui_ImplDX12_InvalidateDeviceObjects();
// Create the root signature
{
D3D12_DESCRIPTOR_RANGE descRange = {};
descRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
descRange.NumDescriptors = 1;
descRange.BaseShaderRegister = 0;
descRange.RegisterSpace = 0;
descRange.OffsetInDescriptorsFromTableStart = 0;
D3D12_ROOT_PARAMETER param[2] = {};
param[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
param[0].Constants.ShaderRegister = 0;
param[0].Constants.RegisterSpace = 0;
param[0].Constants.Num32BitValues = 16;
param[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
param[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
param[1].DescriptorTable.NumDescriptorRanges = 1;
param[1].DescriptorTable.pDescriptorRanges = &descRange;
param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
D3D12_STATIC_SAMPLER_DESC staticSampler = {};
staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
staticSampler.MipLODBias = 0.f;
staticSampler.MaxAnisotropy = 0;
staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
staticSampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
staticSampler.MinLOD = 0.f;
staticSampler.MaxLOD = 0.f;
staticSampler.ShaderRegister = 0;
staticSampler.RegisterSpace = 0;
staticSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
D3D12_ROOT_SIGNATURE_DESC desc = {};
desc.NumParameters = _countof(param);
desc.pParameters = param;
desc.NumStaticSamplers = 1;
desc.pStaticSamplers = &staticSampler;
desc.Flags =
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS;
// Load d3d12.dll and D3D12SerializeRootSignature() function address dynamically to facilitate using with D3D12On7.
// See if any version of d3d12.dll is already loaded in the process. If so, give preference to that.
static HINSTANCE d3d12_dll = ::GetModuleHandleA("d3d12.dll");
if (d3d12_dll == nullptr)
{
// Attempt to load d3d12.dll from local directories. This will only succeed if
// (1) the current OS is Windows 7, and
// (2) there exists a version of d3d12.dll for Windows 7 (D3D12On7) in one of the following directories.
// See https://github.com/ocornut/imgui/pull/3696 for details.
const char* localD3d12Paths[] = { ".\\d3d12.dll", ".\\d3d12on7\\d3d12.dll", ".\\12on7\\d3d12.dll" }; // A. current directory, B. used by some games, C. used in Microsoft D3D12On7 sample
for (int i = 0; i < IM_ARRAYSIZE(localD3d12Paths); i++)
if ((d3d12_dll = ::LoadLibraryA(localD3d12Paths[i])) != nullptr)
break;
// If failed, we are on Windows >= 10.
if (d3d12_dll == nullptr)
d3d12_dll = ::LoadLibraryA("d3d12.dll");
if (d3d12_dll == nullptr)
return false;
}
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignatureFn = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)::GetProcAddress(d3d12_dll, "D3D12SerializeRootSignature");
if (D3D12SerializeRootSignatureFn == nullptr)
return false;
ID3DBlob* blob = nullptr;
if (D3D12SerializeRootSignatureFn(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, nullptr) != S_OK)
return false;
bd->pd3dDevice->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(&bd->pRootSignature));
blob->Release();
}
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
// If you would like to use this DX12 sample code but remove this dependency you can:
// 1) compile once, save the compiled shader blobs into a file or source code and assign them to psoDesc.VS/PS [preferred solution]
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;
memset(&psoDesc, 0, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
psoDesc.NodeMask = 1;
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
psoDesc.pRootSignature = bd->pRootSignature;
psoDesc.SampleMask = UINT_MAX;
psoDesc.NumRenderTargets = 1;
psoDesc.RTVFormats[0] = bd->RTVFormat;
psoDesc.SampleDesc.Count = 1;
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
ID3DBlob* vertexShaderBlob;
ID3DBlob* pixelShaderBlob;
// Create the vertex shader
{
static const char* vertexShader =
"cbuffer vertexBuffer : register(b0) \
{\
float4x4 ProjectionMatrix; \
};\
struct VS_INPUT\
{\
float2 pos : POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
PS_INPUT main(VS_INPUT input)\
{\
PS_INPUT output;\
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
output.col = input.col;\
output.uv = input.uv;\
return output;\
}";
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_5_0", 0, 0, &vertexShaderBlob, nullptr)))
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
psoDesc.VS = { vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize() };
// Create the input layout
static D3D12_INPUT_ELEMENT_DESC local_layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
};
psoDesc.InputLayout = { local_layout, 3 };
}
// Create the pixel shader
{
static const char* pixelShader =
"struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
SamplerState sampler0 : register(s0);\
Texture2D texture0 : register(t0);\
\
float4 main(PS_INPUT input) : SV_Target\
{\
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
return out_col; \
}";
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_5_0", 0, 0, &pixelShaderBlob, nullptr)))
{
vertexShaderBlob->Release();
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
}
psoDesc.PS = { pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize() };
}
// Create the blending setup
{
D3D12_BLEND_DESC& desc = psoDesc.BlendState;
desc.AlphaToCoverageEnable = false;
desc.RenderTarget[0].BlendEnable = true;
desc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
}
// Create the rasterizer state
{
D3D12_RASTERIZER_DESC& desc = psoDesc.RasterizerState;
desc.FillMode = D3D12_FILL_MODE_SOLID;
desc.CullMode = D3D12_CULL_MODE_NONE;
desc.FrontCounterClockwise = FALSE;
desc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
desc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
desc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
desc.DepthClipEnable = true;
desc.MultisampleEnable = FALSE;
desc.AntialiasedLineEnable = FALSE;
desc.ForcedSampleCount = 0;
desc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
}
// Create depth-stencil State
{
D3D12_DEPTH_STENCIL_DESC& desc = psoDesc.DepthStencilState;
desc.DepthEnable = false;
desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
desc.StencilEnable = false;
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
desc.BackFace = desc.FrontFace;
}
HRESULT result_pipeline_state = bd->pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&bd->pPipelineState));
vertexShaderBlob->Release();
pixelShaderBlob->Release();
if (result_pipeline_state != S_OK)
return false;
ImGui_ImplDX12_CreateFontsTexture();
return true;
}
void ImGui_ImplDX12_InvalidateDeviceObjects()
{
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
if (!bd || !bd->pd3dDevice)
return;
ImGuiIO& io = ImGui::GetIO();
SafeRelease(bd->pRootSignature);
SafeRelease(bd->pPipelineState);
SafeRelease(bd->pFontTextureResource);
io.Fonts->SetTexID(0); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
for (UINT i = 0; i < bd->numFramesInFlight; i++)
{
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
SafeRelease(fr->IndexBuffer);
SafeRelease(fr->VertexBuffer);
}
}
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags
ImGui_ImplDX12_Data* bd = IM_NEW(ImGui_ImplDX12_Data)();
io.BackendRendererUserData = (void*)bd;
io.BackendRendererName = "imgui_impl_dx12";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
bd->pd3dDevice = device;
bd->RTVFormat = rtv_format;
bd->hFontSrvCpuDescHandle = font_srv_cpu_desc_handle;
bd->hFontSrvGpuDescHandle = font_srv_gpu_desc_handle;
bd->pFrameResources = new ImGui_ImplDX12_RenderBuffers[num_frames_in_flight];
bd->numFramesInFlight = num_frames_in_flight;
bd->pd3dSrvDescHeap = cbv_srv_heap;
bd->frameIndex = UINT_MAX;
// Create buffers with a default size (they will later be grown as needed)
for (int i = 0; i < num_frames_in_flight; i++)
{
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
fr->IndexBuffer = nullptr;
fr->VertexBuffer = nullptr;
fr->IndexBufferSize = 10000;
fr->VertexBufferSize = 5000;
}
return true;
}
void ImGui_ImplDX12_Shutdown()
{
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO();
// Clean up windows and device objects
ImGui_ImplDX12_InvalidateDeviceObjects();
delete[] bd->pFrameResources;
io.BackendRendererName = nullptr;
io.BackendRendererUserData = nullptr;
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
IM_DELETE(bd);
}
void ImGui_ImplDX12_NewFrame()
{
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX12_Init()?");
if (!bd->pPipelineState)
ImGui_ImplDX12_CreateDeviceObjects();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -0,0 +1,44 @@
// dear imgui: Renderer Backend for DirectX12
// This needs to be used along with a Platform Backend (e.g. Win32)
// Implemented features:
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
// See imgui_impl_dx12.cpp file for details.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
#include <dxgiformat.h> // DXGI_FORMAT
struct ID3D12Device;
struct ID3D12DescriptorHeap;
struct ID3D12GraphicsCommandList;
struct D3D12_CPU_DESCRIPTOR_HANDLE;
struct D3D12_GPU_DESCRIPTOR_HANDLE;
// cmd_list is the command list that the implementation will use to render imgui draw lists.
// Before calling the render function, caller must prepare cmd_list by resetting it and setting the appropriate
// render target and descriptor heap that contains font_srv_cpu_desc_handle/font_srv_gpu_desc_handle.
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture.
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle);
IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown();
IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame();
IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list);
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

Some files were not shown because too many files have changed in this diff Show More