lab5 add
92
cw 5/Zadania 5.md
Normal 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)
|
BIN
cw 5/assimp-vc141-mt.dll
Normal file
BIN
cw 5/assimp-vc141-mtd.dll
Normal file
BIN
cw 5/freeglut.dll
Normal file
BIN
cw 5/glew32.dll
Normal file
122
cw 5/grk-cw5.vcxproj
Normal file
@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Box.cpp" />
|
||||
<ClCompile Include="src\Camera.cpp" />
|
||||
<ClCompile Include="src\main.cpp" />
|
||||
<ClCompile Include="src\Render_Utils.cpp" />
|
||||
<ClCompile Include="src\Shader_Loader.cpp" />
|
||||
<ClCompile Include="src\SOIL\image_DXT.c" />
|
||||
<ClCompile Include="src\SOIL\image_helper.c" />
|
||||
<ClCompile Include="src\SOIL\SOIL.c" />
|
||||
<ClCompile Include="src\SOIL\stb_image_aug.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\Camera.h" />
|
||||
<ClInclude Include="src\ex_5_1.hpp" />
|
||||
<ClInclude Include="src\objload.h" />
|
||||
<ClInclude Include="src\Render_Utils.h" />
|
||||
<ClInclude Include="src\Shader_Loader.h" />
|
||||
<ClInclude Include="src\SOIL\image_DXT.h" />
|
||||
<ClInclude Include="src\SOIL\image_helper.h" />
|
||||
<ClInclude Include="src\SOIL\SOIL.h" />
|
||||
<ClInclude Include="src\SOIL\stbi_DDS_aug.h" />
|
||||
<ClInclude Include="src\SOIL\stbi_DDS_aug_c.h" />
|
||||
<ClInclude Include="src\SOIL\stb_image_aug.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="shaders\shader_5_1.frag" />
|
||||
<None Include="shaders\shader_5_1.vert" />
|
||||
<None Include="shaders\shader_5_sun.frag" />
|
||||
<None Include="shaders\shader_5_sun.vert" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{7B84D06D-946D-4DCB-BD1A-B5635B0F83F0}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>grk-cw5</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>grk-cw5</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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<LibraryPath>$(SolutionDir)dependencies\freeglut\lib;$(SolutionDir)dependencies\glew-2.0.0\lib\Release\Win32;$(SolutionDir)dependencies\glfw-3.3.8.bin.WIN32\lib-vc2019;$(SolutionDir)dependencies\assimp;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>$(SolutionDir)dependencies\freeglut\include\GL;$(SolutionDir)dependencies\glew-2.0.0\include\GL;$(SolutionDir)dependencies\glm;$(SolutionDir)dependencies\glfw-3.3.8.bin.WIN32\include;$(SolutionDir)dependencies\assimp\include;$(IncludePath)</IncludePath>
|
||||
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<LibraryPath>$(SolutionDir)dependencies\freeglut\lib;$(SolutionDir)dependencies\glew-2.0.0\lib\Release\Win32;$(SolutionDir)dependencies\glfw-3.3.8.bin.WIN32\lib-vc2019;$(SolutionDir)dependencies\assimp;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>$(SolutionDir)dependencies\freeglut\include\GL;$(SolutionDir)dependencies\glew-2.0.0\include\GL;$(SolutionDir)dependencies\glm;$(SolutionDir)dependencies\glfw-3.3.8.bin.WIN32\include;$(SolutionDir)dependencies\assimp\include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opengl32.lib;freeglut.lib;glew32.lib;$(SolutionDir)\dependencies\glfw-3.3.8.bin.WIN32\lib-vc2019\glfw3.lib;$(SolutionDir)\dependencies\glfw-3.3.8.bin.WIN32\lib-vc2019\glfw3dll.lib;zlibd.lib;assimp-vc141-mtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)dependencies\glfw-3.3.8.bin.WIN32\lib-vc2019;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>opengl32.lib;freeglut.lib;glew32.lib;$(SolutionDir)\dependencies\glfw-3.3.8.bin.WIN32\lib-vc2019\glfw3.lib;$(SolutionDir)\dependencies\glfw-3.3.8.bin.WIN32\lib-vc2019\glfw3dll.lib;zlibd.lib;assimp-vc141-mtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)dependencies\glfw-3.3.8.bin.WIN32\lib-vc2019;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
107
cw 5/grk-cw5.vcxproj.filters
Normal file
@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Shader Files">
|
||||
<UniqueIdentifier>{0a247bb8-2e8e-4a90-b0ef-17415b0941ba}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\SOIL">
|
||||
<UniqueIdentifier>{fd2042cb-5cbc-4508-9e27-cb1e07254eb9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Render_Utils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<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>
|
||||
<ClCompile Include="src\main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Texture.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SOIL\image_DXT.c">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SOIL\image_helper.c">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SOIL\SOIL.c">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SOIL\stb_image_aug.c">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\objload.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Render_Utils.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Shader_Loader.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Camera.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ex_5_1.hpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Texture.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\SOIL\image_DXT.h">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\SOIL\image_helper.h">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\SOIL\SOIL.h">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\SOIL\stb_image_aug.h">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\SOIL\stbi_DDS_aug.h">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\SOIL\stbi_DDS_aug_c.h">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="shaders\shader_5_1.vert">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_5_sun.frag">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_5_sun.vert">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_5_1.frag">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
BIN
cw 5/img/2.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
cw 5/img/3.webp
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
cw 5/img/384px-PerlinNoiseDotProducts.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
cw 5/img/384px-PerlinNoiseInterpolated.png
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
cw 5/img/4.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
cw 5/img/5.webp
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
cw 5/img/6.webp
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
cw 5/img/7.webp
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
cw 5/img/8.webp
Normal file
After Width: | Height: | Size: 34 KiB |
1254
cw 5/img/Figure_1.eps
Normal file
BIN
cw 5/img/PerlinNoiseDotProducts.png
Normal file
After Width: | Height: | Size: 178 KiB |
BIN
cw 5/img/PerlinNoiseGradientGrid.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
cw 5/img/PerlinNoiseInterpolated.png
Normal file
After Width: | Height: | Size: 144 KiB |
BIN
cw 5/img/blending1.webp
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
cw 5/img/camera.jpg
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
cw 5/img/capture.webm
Normal file
BIN
cw 5/img/coordinate_systems.jpg
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
cw 5/img/cubemaps_sampling.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
cw 5/img/gamma_correction_brightness.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
cw 5/img/lighting_result.png
Normal file
After Width: | Height: | Size: 190 KiB |
BIN
cw 5/img/noise_examples.jpg
Normal file
After Width: | Height: | Size: 329 KiB |
BIN
cw 5/img/shadow_mapping_projection.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
cw 5/img/shadows1.bmp
Normal file
After Width: | Height: | Size: 978 KiB |
BIN
cw 5/img/spotlight.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
cw 5/img/stride_offest.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
cw 5/img/stride_offest_2_2.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
cw 5/img/struktura.jpg
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
cw 5/img/sun.png
Normal file
After Width: | Height: | Size: 2.0 MiB |
BIN
cw 5/img/textures.png
Normal file
After Width: | Height: | Size: 260 KiB |
BIN
cw 5/img/z_depth_graph.jpg
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
cw 5/img/z_depth_graph2.jpg
Normal file
After Width: | Height: | Size: 72 KiB |
38
cw 5/shaders/shader_5_1.frag
Normal file
@ -0,0 +1,38 @@
|
||||
#version 430 core
|
||||
|
||||
uniform vec3 color;
|
||||
out vec4 outColor;
|
||||
|
||||
uniform vec3 lightColor;
|
||||
uniform vec3 cameraPos;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
in vec3 FragNormal;
|
||||
in vec4 vertexPosWorld;
|
||||
|
||||
uniform float exposition;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 viewDir = normalize(cameraPos - vertexPosWorld.xyz);
|
||||
vec3 normalizedNormal = normalize(FragNormal);
|
||||
|
||||
vec3 lightDir = normalize(lightPos - vertexPosWorld.xyz);
|
||||
|
||||
float diffuse = max(dot(normalizedNormal, lightDir), 0.0);
|
||||
|
||||
|
||||
vec3 normalizedViewDir = normalize(viewDir);
|
||||
vec3 reflectDir = reflect(-normalize(lightDir), normalizedNormal);
|
||||
float specular = pow(max(dot(normalizedViewDir, reflectDir), 0.0), 8.0);
|
||||
|
||||
//zad_6
|
||||
float distance = length(lightPos - vertexPosWorld.xyz);
|
||||
vec3 newLightColor = lightColor / distance;
|
||||
vec3 finalColor = newLightColor * (color * diffuse+specular);
|
||||
|
||||
finalColor = 1.0 - exp(-finalColor * exposition);
|
||||
|
||||
outColor = vec4(finalColor, 1.0);
|
||||
|
||||
}
|
27
cw 5/shaders/shader_5_1.vert
Normal file
@ -0,0 +1,27 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
out vec3 FragNormal;
|
||||
uniform mat4 modelMatrix;
|
||||
uniform vec3 cameraPos;
|
||||
|
||||
out vec3 viewDir;
|
||||
out vec4 vertexPosWorld;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
|
||||
vec4 transformedNormal = modelMatrix * vec4(vertexNormal, 0.0);
|
||||
FragNormal = normalize(transformedNormal.xyz);
|
||||
|
||||
vertexPosWorld = modelMatrix * vec4(vertexPosition, 1.0);
|
||||
|
||||
|
||||
|
||||
}
|
24
cw 5/shaders/shader_5_sun.frag
Normal file
@ -0,0 +1,24 @@
|
||||
#version 430 core
|
||||
|
||||
uniform vec3 color;
|
||||
|
||||
in vec3 interpNormal;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
float rimIntensity = 0.5; // intensywnoϾ
|
||||
vec3 rimColor = vec3(1.0, 0.0, 0.0); // kolor rim
|
||||
float rim = dot(normalize(interpNormal), normalize(vec3(0.0, 0.0, 1.0))); // wektor (0, 0, 1) ¿eby na krawêdziach
|
||||
rim = 1 - pow(rim, 2); // jak szeroki jest ten rim
|
||||
|
||||
vec3 finalColor = color;
|
||||
|
||||
finalColor = mix(color, rimColor, rimIntensity * rim);
|
||||
|
||||
|
||||
out_color = vec4(finalColor, 1.0);
|
||||
|
||||
}
|
15
cw 5/shaders/shader_5_sun.vert
Normal file
@ -0,0 +1,15 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
|
||||
uniform mat4 transformation;
|
||||
out vec3 interpNormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
interpNormal = normalize(transformation * vec4(vertexNormal, 0.0)).xyz;
|
||||
}
|
55
cw 5/src/Box.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
|
||||
// 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,
|
||||
};
|
||||
|
31
cw 5/src/Camera.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "Camera.h"
|
||||
|
||||
glm::mat4 Core::createPerspectiveMatrix(float zNear, float zFar, float frustumScale)
|
||||
{
|
||||
glm::mat4 perspective;
|
||||
perspective[0][0] = 1.f;
|
||||
perspective[1][1] = frustumScale;
|
||||
perspective[2][2] = (zFar + zNear) / (zNear - zFar);
|
||||
perspective[3][2] = (2 * zFar * zNear) / (zNear - zFar);
|
||||
perspective[2][3] = -1;
|
||||
perspective[3][3] = 0;
|
||||
|
||||
return perspective;
|
||||
}
|
||||
|
||||
glm::mat4 Core::createViewMatrix( glm::vec3 position, glm::vec3 forward, glm::vec3 up )
|
||||
{
|
||||
glm::vec3 side = glm::cross(forward, up);
|
||||
|
||||
// Trzeba pamietac o minusie przy ustawianiu osi Z kamery.
|
||||
// Wynika to z tego, ze standardowa macierz perspektywiczna zaklada, ze "z przodu" jest ujemna (a nie dodatnia) czesc osi Z.
|
||||
glm::mat4 cameraRotation;
|
||||
cameraRotation[0][0] = side.x; cameraRotation[1][0] = side.y; cameraRotation[2][0] = side.z;
|
||||
cameraRotation[0][1] = up.x; cameraRotation[1][1] = up.y; cameraRotation[2][1] = up.z;
|
||||
cameraRotation[0][2] = -forward.x; cameraRotation[1][2] = -forward.y; cameraRotation[2][2] = -forward.z;
|
||||
|
||||
glm::mat4 cameraTranslation;
|
||||
cameraTranslation[3] = glm::vec4(-position, 1.0f);
|
||||
|
||||
return cameraRotation * cameraTranslation;
|
||||
}
|
14
cw 5/src/Camera.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "glm.hpp"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
glm::mat4 createPerspectiveMatrix(float zNear = 0.1f, float zFar = 100.0f, float frustumScale = 1.f);
|
||||
|
||||
// position - pozycja kamery
|
||||
// forward - wektor "do przodu" kamery (jednostkowy)
|
||||
// up - wektor "w gore" kamery (jednostkowy)
|
||||
// up i forward musza byc ortogonalne!
|
||||
glm::mat4 createViewMatrix(glm::vec3 position, glm::vec3 forward, glm::vec3 up);
|
||||
}
|
128
cw 5/src/Render_Utils.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "Render_Utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
|
||||
|
||||
void Core::RenderContext::initFromAssimpMesh(aiMesh* mesh) {
|
||||
vertexArray = 0;
|
||||
vertexBuffer = 0;
|
||||
vertexIndexBuffer = 0;
|
||||
|
||||
std::vector<float> textureCoord;
|
||||
std::vector<unsigned int> indices;
|
||||
//tex coord must be converted to 2d vecs
|
||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
if (mesh->mTextureCoords[0] != nullptr) {
|
||||
textureCoord.push_back(mesh->mTextureCoords[0][i].x);
|
||||
textureCoord.push_back(mesh->mTextureCoords[0][i].y);
|
||||
}
|
||||
else {
|
||||
textureCoord.push_back(0.0f);
|
||||
textureCoord.push_back(0.0f);
|
||||
}
|
||||
}
|
||||
if (mesh->mTextureCoords[0] == nullptr) {
|
||||
std::cout << "no uv coords\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||
{
|
||||
aiFace face = mesh->mFaces[i];
|
||||
// retrieve all indices of the face and store them in the indices vector
|
||||
for (unsigned int j = 0; j < face.mNumIndices; j++)
|
||||
indices.push_back(face.mIndices[j]);
|
||||
}
|
||||
|
||||
unsigned int vertexDataBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexNormalBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexTexBufferSize = sizeof(float) * mesh->mNumVertices * 2;
|
||||
unsigned int vertexTangentBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexBiTangentBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
|
||||
unsigned int vertexElementBufferSize = sizeof(unsigned int) * indices.size();
|
||||
size = indices.size();
|
||||
|
||||
glGenVertexArrays(1, &vertexArray);
|
||||
glBindVertexArray(vertexArray);
|
||||
|
||||
|
||||
glGenBuffers(1, &vertexIndexBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexElementBufferSize, &indices[0], GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &vertexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
//std::cout << vertexBuffer;
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize + vertexTangentBufferSize + vertexBiTangentBufferSize, NULL, GL_STATIC_DRAW);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexDataBufferSize, mesh->mVertices);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize, vertexNormalBufferSize, mesh->mNormals);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize, vertexTexBufferSize, &textureCoord[0]);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize, vertexTangentBufferSize, mesh->mTangents);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize + vertexTangentBufferSize, vertexBiTangentBufferSize, mesh->mBitangents);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0));
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertexDataBufferSize));
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)(vertexNormalBufferSize + vertexDataBufferSize));
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize));
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize + vertexTangentBufferSize));
|
||||
|
||||
}
|
||||
|
||||
void Core::DrawVertexArray(const float * vertexArray, int numVertices, int elementSize )
|
||||
{
|
||||
glVertexAttribPointer(0, elementSize, GL_FLOAT, false, 0, vertexArray);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, numVertices);
|
||||
}
|
||||
|
||||
void Core::DrawVertexArrayIndexed( const float * vertexArray, const int * indexArray, int numIndexes, int elementSize )
|
||||
{
|
||||
glVertexAttribPointer(0, elementSize, GL_FLOAT, false, 0, vertexArray);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexArray);
|
||||
}
|
||||
|
||||
|
||||
void Core::DrawVertexArray( const VertexData & data )
|
||||
{
|
||||
int numAttribs = std::min(VertexData::MAX_ATTRIBS, data.NumActiveAttribs);
|
||||
for(int i = 0; i < numAttribs; i++)
|
||||
{
|
||||
glVertexAttribPointer(i, data.Attribs[i].Size, GL_FLOAT, false, 0, data.Attribs[i].Pointer);
|
||||
glEnableVertexAttribArray(i);
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLES, 0, data.NumVertices);
|
||||
}
|
||||
|
||||
void Core::DrawContext(Core::RenderContext& context)
|
||||
{
|
||||
|
||||
glBindVertexArray(context.vertexArray);
|
||||
glDrawElements(
|
||||
GL_TRIANGLES, // mode
|
||||
context.size, // count
|
||||
GL_UNSIGNED_INT, // type
|
||||
(void*)0 // element array buffer offset
|
||||
);
|
||||
glBindVertexArray(0);
|
||||
}
|
72
cw 5/src/Render_Utils.h
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
#include "glm.hpp"
|
||||
#include "glew.h"
|
||||
#include "objload.h"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||
|
||||
namespace Core
|
||||
{
|
||||
struct RenderContext
|
||||
{
|
||||
GLuint vertexArray;
|
||||
GLuint vertexBuffer;
|
||||
GLuint vertexIndexBuffer;
|
||||
int size = 0;
|
||||
|
||||
void initFromOBJ(obj::Model& model);
|
||||
|
||||
void initFromAssimpMesh(aiMesh* mesh);
|
||||
};
|
||||
|
||||
// vertexArray - jednowymiarowa tablica zawierajaca wartosci opisujace pozycje kolejnych wierzcholkow w jednym ciagu (x1, y1, z1, w1, x2, y2, z2, w2, ...)
|
||||
// numVertices - liczba wierzcholkow do narysowania
|
||||
// elementSize - liczba wartosci opisujacych pojedynczy wierzcholek (np. 3 gdy wierzcholek opisany jest trojka (x, y, z))
|
||||
void DrawVertexArray(const float * vertexArray, int numVertices, int elementSize);
|
||||
|
||||
// indexArray - jednowymiarowa tablica zawierajaca indeksy wierzcholkow kolejnych trojkatow w jednym ciagu (t1_i1, t1_i2, t1_i3, t2_i1, t2_i2, t2_i3, ...)
|
||||
// numIndexes - liczba indeksow w tablicy indexArray
|
||||
void DrawVertexArrayIndexed(const float * vertexArray, const int * indexArray, int numIndexes, int elementSize);
|
||||
|
||||
|
||||
struct VertexAttribute
|
||||
{
|
||||
const void * Pointer;
|
||||
int Size;
|
||||
};
|
||||
|
||||
struct VertexData
|
||||
{
|
||||
static const int MAX_ATTRIBS = 8;
|
||||
VertexAttribute Attribs[MAX_ATTRIBS];
|
||||
int NumActiveAttribs;
|
||||
int NumVertices;
|
||||
};
|
||||
|
||||
// Ta funkcja sluzy do rysowania trojkatow, ktorych wierzcholki moga byc opisane wiecej niz jednym atrybutem.
|
||||
// Funkcja przyjmuje jako parametr strukture, w ktorej nalezy zawrzec wszystkie potrzebne dane.
|
||||
//
|
||||
// Przykladowe wywolanie funkcji - narysowanie trojkata jak na pierwszych zajeciach:
|
||||
/*
|
||||
|
||||
const float vertices[] = {
|
||||
0.25f, 0.25f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
Core::VertexData vertexData;
|
||||
vertexData.NumActiveAttribs = 1; // Liczba uzywanych atrybutow wierzcholka
|
||||
vertexData.Attribs[0].Pointer = vertices; // Wskaznik na dane zerowego atrybutu
|
||||
vertexData.Attribs[0].Size = 4; // Wielkosc zerowego atrybutu (ilosc liczb opisujacych ten atrybut w pojedynczym wierzcholku)
|
||||
vertexData.NumVertices = 3; // Liczba wierzcholkow do narysowania
|
||||
Core::DrawVertexArray(vertexData);
|
||||
|
||||
*/
|
||||
void DrawVertexArray(const VertexData & data);
|
||||
|
||||
void DrawContext(RenderContext& context);
|
||||
}
|
2024
cw 5/src/SOIL/SOIL.c
Normal file
433
cw 5/src/SOIL/SOIL.h
Normal file
@ -0,0 +1,433 @@
|
||||
/**
|
||||
@mainpage SOIL
|
||||
|
||||
Jonathan Dummer
|
||||
2007-07-26-10.36
|
||||
|
||||
Simple OpenGL Image Library
|
||||
|
||||
A tiny c library for uploading images as
|
||||
textures into OpenGL. Also saving and
|
||||
loading of images is supported.
|
||||
|
||||
I'm using Sean's Tool Box image loader as a base:
|
||||
http://www.nothings.org/
|
||||
|
||||
I'm upgrading it to load TGA and DDS files, and a direct
|
||||
path for loading DDS files straight into OpenGL textures,
|
||||
when applicable.
|
||||
|
||||
Image Formats:
|
||||
- BMP load & save
|
||||
- TGA load & save
|
||||
- DDS load & save
|
||||
- PNG load
|
||||
- JPG load
|
||||
|
||||
OpenGL Texture Features:
|
||||
- resample to power-of-two sizes
|
||||
- MIPmap generation
|
||||
- compressed texture S3TC formats (if supported)
|
||||
- can pre-multiply alpha for you, for better compositing
|
||||
- can flip image about the y-axis (except pre-compressed DDS files)
|
||||
|
||||
Thanks to:
|
||||
* Sean Barret - for the awesome stb_image
|
||||
* Dan Venkitachalam - for finding some non-compliant DDS files, and patching some explicit casts
|
||||
* everybody at gamedev.net
|
||||
**/
|
||||
|
||||
#ifndef HEADER_SIMPLE_OPENGL_IMAGE_LIBRARY
|
||||
#define HEADER_SIMPLE_OPENGL_IMAGE_LIBRARY
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
The format of images that may be loaded (force_channels).
|
||||
SOIL_LOAD_AUTO leaves the image in whatever format it was found.
|
||||
SOIL_LOAD_L forces the image to load as Luminous (greyscale)
|
||||
SOIL_LOAD_LA forces the image to load as Luminous with Alpha
|
||||
SOIL_LOAD_RGB forces the image to load as Red Green Blue
|
||||
SOIL_LOAD_RGBA forces the image to load as Red Green Blue Alpha
|
||||
**/
|
||||
enum
|
||||
{
|
||||
SOIL_LOAD_AUTO = 0,
|
||||
SOIL_LOAD_L = 1,
|
||||
SOIL_LOAD_LA = 2,
|
||||
SOIL_LOAD_RGB = 3,
|
||||
SOIL_LOAD_RGBA = 4
|
||||
};
|
||||
|
||||
/**
|
||||
Passed in as reuse_texture_ID, will cause SOIL to
|
||||
register a new texture ID using glGenTextures().
|
||||
If the value passed into reuse_texture_ID > 0 then
|
||||
SOIL will just re-use that texture ID (great for
|
||||
reloading image assets in-game!)
|
||||
**/
|
||||
enum
|
||||
{
|
||||
SOIL_CREATE_NEW_ID = 0
|
||||
};
|
||||
|
||||
/**
|
||||
flags you can pass into SOIL_load_OGL_texture()
|
||||
and SOIL_create_OGL_texture().
|
||||
(note that if SOIL_FLAG_DDS_LOAD_DIRECT is used
|
||||
the rest of the flags with the exception of
|
||||
SOIL_FLAG_TEXTURE_REPEATS will be ignored while
|
||||
loading already-compressed DDS files.)
|
||||
|
||||
SOIL_FLAG_POWER_OF_TWO: force the image to be POT
|
||||
SOIL_FLAG_MIPMAPS: generate mipmaps for the texture
|
||||
SOIL_FLAG_TEXTURE_REPEATS: otherwise will clamp
|
||||
SOIL_FLAG_MULTIPLY_ALPHA: for using (GL_ONE,GL_ONE_MINUS_SRC_ALPHA) blending
|
||||
SOIL_FLAG_INVERT_Y: flip the image vertically
|
||||
SOIL_FLAG_COMPRESS_TO_DXT: if the card can display them, will convert RGB to DXT1, RGBA to DXT5
|
||||
SOIL_FLAG_DDS_LOAD_DIRECT: will load DDS files directly without _ANY_ additional processing
|
||||
SOIL_FLAG_NTSC_SAFE_RGB: clamps RGB components to the range [16,235]
|
||||
SOIL_FLAG_CoCg_Y: Google YCoCg; RGB=>CoYCg, RGBA=>CoCgAY
|
||||
SOIL_FLAG_TEXTURE_RECTANGE: uses ARB_texture_rectangle ; pixel indexed & no repeat or MIPmaps or cubemaps
|
||||
**/
|
||||
enum
|
||||
{
|
||||
SOIL_FLAG_POWER_OF_TWO = 1,
|
||||
SOIL_FLAG_MIPMAPS = 2,
|
||||
SOIL_FLAG_TEXTURE_REPEATS = 4,
|
||||
SOIL_FLAG_MULTIPLY_ALPHA = 8,
|
||||
SOIL_FLAG_INVERT_Y = 16,
|
||||
SOIL_FLAG_COMPRESS_TO_DXT = 32,
|
||||
SOIL_FLAG_DDS_LOAD_DIRECT = 64,
|
||||
SOIL_FLAG_NTSC_SAFE_RGB = 128,
|
||||
SOIL_FLAG_CoCg_Y = 256,
|
||||
SOIL_FLAG_TEXTURE_RECTANGLE = 512
|
||||
};
|
||||
|
||||
/**
|
||||
The types of images that may be saved.
|
||||
(TGA supports uncompressed RGB / RGBA)
|
||||
(BMP supports uncompressed RGB)
|
||||
(DDS supports DXT1 and DXT5)
|
||||
**/
|
||||
enum
|
||||
{
|
||||
SOIL_SAVE_TYPE_TGA = 0,
|
||||
SOIL_SAVE_TYPE_BMP = 1,
|
||||
SOIL_SAVE_TYPE_DDS = 2
|
||||
};
|
||||
|
||||
/**
|
||||
Defines the order of faces in a DDS cubemap.
|
||||
I recommend that you use the same order in single
|
||||
image cubemap files, so they will be interchangeable
|
||||
with DDS cubemaps when using SOIL.
|
||||
**/
|
||||
#define SOIL_DDS_CUBEMAP_FACE_ORDER "EWUDNS"
|
||||
|
||||
/**
|
||||
The types of internal fake HDR representations
|
||||
|
||||
SOIL_HDR_RGBE: RGB * pow( 2.0, A - 128.0 )
|
||||
SOIL_HDR_RGBdivA: RGB / A
|
||||
SOIL_HDR_RGBdivA2: RGB / (A*A)
|
||||
**/
|
||||
enum
|
||||
{
|
||||
SOIL_HDR_RGBE = 0,
|
||||
SOIL_HDR_RGBdivA = 1,
|
||||
SOIL_HDR_RGBdivA2 = 2
|
||||
};
|
||||
|
||||
/**
|
||||
Loads an image from disk into an OpenGL texture.
|
||||
\param filename the name of the file to upload as a texture
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_texture
|
||||
(
|
||||
const char *filename,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads 6 images from disk into an OpenGL cubemap texture.
|
||||
\param x_pos_file the name of the file to upload as the +x cube face
|
||||
\param x_neg_file the name of the file to upload as the -x cube face
|
||||
\param y_pos_file the name of the file to upload as the +y cube face
|
||||
\param y_neg_file the name of the file to upload as the -y cube face
|
||||
\param z_pos_file the name of the file to upload as the +z cube face
|
||||
\param z_neg_file the name of the file to upload as the -z cube face
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_cubemap
|
||||
(
|
||||
const char *x_pos_file,
|
||||
const char *x_neg_file,
|
||||
const char *y_pos_file,
|
||||
const char *y_neg_file,
|
||||
const char *z_pos_file,
|
||||
const char *z_neg_file,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads 1 image from disk and splits it into an OpenGL cubemap texture.
|
||||
\param filename the name of the file to upload as a texture
|
||||
\param face_order the order of the faces in the file, any combination of NSWEUD, for North, South, Up, etc.
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_single_cubemap
|
||||
(
|
||||
const char *filename,
|
||||
const char face_order[6],
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads an HDR image from disk into an OpenGL texture.
|
||||
\param filename the name of the file to upload as a texture
|
||||
\param fake_HDR_format SOIL_HDR_RGBE, SOIL_HDR_RGBdivA, SOIL_HDR_RGBdivA2
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_HDR_texture
|
||||
(
|
||||
const char *filename,
|
||||
int fake_HDR_format,
|
||||
int rescale_to_max,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads an image from RAM into an OpenGL texture.
|
||||
\param buffer the image data in RAM just as if it were still in a file
|
||||
\param buffer_length the size of the buffer in bytes
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_texture_from_memory
|
||||
(
|
||||
const unsigned char *const buffer,
|
||||
int buffer_length,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads 6 images from memory into an OpenGL cubemap texture.
|
||||
\param x_pos_buffer the image data in RAM to upload as the +x cube face
|
||||
\param x_pos_buffer_length the size of the above buffer
|
||||
\param x_neg_buffer the image data in RAM to upload as the +x cube face
|
||||
\param x_neg_buffer_length the size of the above buffer
|
||||
\param y_pos_buffer the image data in RAM to upload as the +x cube face
|
||||
\param y_pos_buffer_length the size of the above buffer
|
||||
\param y_neg_buffer the image data in RAM to upload as the +x cube face
|
||||
\param y_neg_buffer_length the size of the above buffer
|
||||
\param z_pos_buffer the image data in RAM to upload as the +x cube face
|
||||
\param z_pos_buffer_length the size of the above buffer
|
||||
\param z_neg_buffer the image data in RAM to upload as the +x cube face
|
||||
\param z_neg_buffer_length the size of the above buffer
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_cubemap_from_memory
|
||||
(
|
||||
const unsigned char *const x_pos_buffer,
|
||||
int x_pos_buffer_length,
|
||||
const unsigned char *const x_neg_buffer,
|
||||
int x_neg_buffer_length,
|
||||
const unsigned char *const y_pos_buffer,
|
||||
int y_pos_buffer_length,
|
||||
const unsigned char *const y_neg_buffer,
|
||||
int y_neg_buffer_length,
|
||||
const unsigned char *const z_pos_buffer,
|
||||
int z_pos_buffer_length,
|
||||
const unsigned char *const z_neg_buffer,
|
||||
int z_neg_buffer_length,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads 1 image from RAM and splits it into an OpenGL cubemap texture.
|
||||
\param buffer the image data in RAM just as if it were still in a file
|
||||
\param buffer_length the size of the buffer in bytes
|
||||
\param face_order the order of the faces in the file, any combination of NSWEUD, for North, South, Up, etc.
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_single_cubemap_from_memory
|
||||
(
|
||||
const unsigned char *const buffer,
|
||||
int buffer_length,
|
||||
const char face_order[6],
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a 2D OpenGL texture from raw image data. Note that the raw data is
|
||||
_NOT_ freed after the upload (so the user can load various versions).
|
||||
\param data the raw data to be uploaded as an OpenGL texture
|
||||
\param width the width of the image in pixels
|
||||
\param height the height of the image in pixels
|
||||
\param channels the number of channels: 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_create_OGL_texture
|
||||
(
|
||||
const unsigned char *const data,
|
||||
int width, int height, int channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Creates an OpenGL cubemap texture by splitting up 1 image into 6 parts.
|
||||
\param data the raw data to be uploaded as an OpenGL texture
|
||||
\param width the width of the image in pixels
|
||||
\param height the height of the image in pixels
|
||||
\param channels the number of channels: 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param face_order the order of the faces in the file, and combination of NSWEUD, for North, South, Up, etc.
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_create_OGL_single_cubemap
|
||||
(
|
||||
const unsigned char *const data,
|
||||
int width, int height, int channels,
|
||||
const char face_order[6],
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Captures the OpenGL window (RGB) and saves it to disk
|
||||
\return 0 if it failed, otherwise returns 1
|
||||
**/
|
||||
int
|
||||
SOIL_save_screenshot
|
||||
(
|
||||
const char *filename,
|
||||
int image_type,
|
||||
int x, int y,
|
||||
int width, int height
|
||||
);
|
||||
|
||||
/**
|
||||
Loads an image from disk into an array of unsigned chars.
|
||||
Note that *channels return the original channel count of the
|
||||
image. If force_channels was other than SOIL_LOAD_AUTO,
|
||||
the resulting image has force_channels, but *channels may be
|
||||
different (if the original image had a different channel
|
||||
count).
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
unsigned char*
|
||||
SOIL_load_image
|
||||
(
|
||||
const char *filename,
|
||||
int *width, int *height, int *channels,
|
||||
int force_channels
|
||||
);
|
||||
|
||||
/**
|
||||
Loads an image from memory into an array of unsigned chars.
|
||||
Note that *channels return the original channel count of the
|
||||
image. If force_channels was other than SOIL_LOAD_AUTO,
|
||||
the resulting image has force_channels, but *channels may be
|
||||
different (if the original image had a different channel
|
||||
count).
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
unsigned char*
|
||||
SOIL_load_image_from_memory
|
||||
(
|
||||
const unsigned char *const buffer,
|
||||
int buffer_length,
|
||||
int *width, int *height, int *channels,
|
||||
int force_channels
|
||||
);
|
||||
|
||||
/**
|
||||
Saves an image from an array of unsigned chars (RGBA) to disk
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
int
|
||||
SOIL_save_image
|
||||
(
|
||||
const char *filename,
|
||||
int image_type,
|
||||
int width, int height, int channels,
|
||||
const unsigned char *const data
|
||||
);
|
||||
|
||||
/**
|
||||
Frees the image data (note, this is just C's "free()"...this function is
|
||||
present mostly so C++ programmers don't forget to use "free()" and call
|
||||
"delete []" instead [8^)
|
||||
**/
|
||||
void
|
||||
SOIL_free_image_data
|
||||
(
|
||||
unsigned char *img_data
|
||||
);
|
||||
|
||||
/**
|
||||
This function resturn a pointer to a string describing the last thing
|
||||
that happened inside SOIL. It can be used to determine why an image
|
||||
failed to load.
|
||||
**/
|
||||
const char*
|
||||
SOIL_last_result
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_SIMPLE_OPENGL_IMAGE_LIBRARY */
|
632
cw 5/src/SOIL/image_DXT.c
Normal file
@ -0,0 +1,632 @@
|
||||
/*
|
||||
Jonathan Dummer
|
||||
2007-07-31-10.32
|
||||
|
||||
simple DXT compression / decompression code
|
||||
|
||||
public domain
|
||||
*/
|
||||
|
||||
#include "image_DXT.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* set this =1 if you want to use the covarince matrix method...
|
||||
which is better than my method of using standard deviations
|
||||
overall, except on the infintesimal chance that the power
|
||||
method fails for finding the largest eigenvector */
|
||||
#define USE_COV_MAT 1
|
||||
|
||||
/********* Function Prototypes *********/
|
||||
/*
|
||||
Takes a 4x4 block of pixels and compresses it into 8 bytes
|
||||
in DXT1 format (color only, no alpha). Speed is valued
|
||||
over prettyness, at least for now.
|
||||
*/
|
||||
void compress_DDS_color_block(
|
||||
int channels,
|
||||
const unsigned char *const uncompressed,
|
||||
unsigned char compressed[8] );
|
||||
/*
|
||||
Takes a 4x4 block of pixels and compresses the alpha
|
||||
component it into 8 bytes for use in DXT5 DDS files.
|
||||
Speed is valued over prettyness, at least for now.
|
||||
*/
|
||||
void compress_DDS_alpha_block(
|
||||
const unsigned char *const uncompressed,
|
||||
unsigned char compressed[8] );
|
||||
|
||||
/********* Actual Exposed Functions *********/
|
||||
int
|
||||
save_image_as_DDS
|
||||
(
|
||||
const char *filename,
|
||||
int width, int height, int channels,
|
||||
const unsigned char *const data
|
||||
)
|
||||
{
|
||||
/* variables */
|
||||
FILE *fout;
|
||||
unsigned char *DDS_data;
|
||||
DDS_header header;
|
||||
int DDS_size;
|
||||
/* error check */
|
||||
if( (NULL == filename) ||
|
||||
(width < 1) || (height < 1) ||
|
||||
(channels < 1) || (channels > 4) ||
|
||||
(data == NULL ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* Convert the image */
|
||||
if( (channels & 1) == 1 )
|
||||
{
|
||||
/* no alpha, just use DXT1 */
|
||||
DDS_data = convert_image_to_DXT1( data, width, height, channels, &DDS_size );
|
||||
} else
|
||||
{
|
||||
/* has alpha, so use DXT5 */
|
||||
DDS_data = convert_image_to_DXT5( data, width, height, channels, &DDS_size );
|
||||
}
|
||||
/* save it */
|
||||
memset( &header, 0, sizeof( DDS_header ) );
|
||||
header.dwMagic = ('D' << 0) | ('D' << 8) | ('S' << 16) | (' ' << 24);
|
||||
header.dwSize = 124;
|
||||
header.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_LINEARSIZE;
|
||||
header.dwWidth = width;
|
||||
header.dwHeight = height;
|
||||
header.dwPitchOrLinearSize = DDS_size;
|
||||
header.sPixelFormat.dwSize = 32;
|
||||
header.sPixelFormat.dwFlags = DDPF_FOURCC;
|
||||
if( (channels & 1) == 1 )
|
||||
{
|
||||
header.sPixelFormat.dwFourCC = ('D' << 0) | ('X' << 8) | ('T' << 16) | ('1' << 24);
|
||||
} else
|
||||
{
|
||||
header.sPixelFormat.dwFourCC = ('D' << 0) | ('X' << 8) | ('T' << 16) | ('5' << 24);
|
||||
}
|
||||
header.sCaps.dwCaps1 = DDSCAPS_TEXTURE;
|
||||
/* write it out */
|
||||
fout = fopen( filename, "wb");
|
||||
fwrite( &header, sizeof( DDS_header ), 1, fout );
|
||||
fwrite( DDS_data, 1, DDS_size, fout );
|
||||
fclose( fout );
|
||||
/* done */
|
||||
free( DDS_data );
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char* convert_image_to_DXT1(
|
||||
const unsigned char *const uncompressed,
|
||||
int width, int height, int channels,
|
||||
int *out_size )
|
||||
{
|
||||
unsigned char *compressed;
|
||||
int i, j, x, y;
|
||||
unsigned char ublock[16*3];
|
||||
unsigned char cblock[8];
|
||||
int index = 0, chan_step = 1;
|
||||
int block_count = 0;
|
||||
/* error check */
|
||||
*out_size = 0;
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(NULL == uncompressed) ||
|
||||
(channels < 1) || (channels > 4) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/* for channels == 1 or 2, I do not step forward for R,G,B values */
|
||||
if( channels < 3 )
|
||||
{
|
||||
chan_step = 0;
|
||||
}
|
||||
/* get the RAM for the compressed image
|
||||
(8 bytes per 4x4 pixel block) */
|
||||
*out_size = ((width+3) >> 2) * ((height+3) >> 2) * 8;
|
||||
compressed = (unsigned char*)malloc( *out_size );
|
||||
/* go through each block */
|
||||
for( j = 0; j < height; j += 4 )
|
||||
{
|
||||
for( i = 0; i < width; i += 4 )
|
||||
{
|
||||
/* copy this block into a new one */
|
||||
int idx = 0;
|
||||
int mx = 4, my = 4;
|
||||
if( j+4 >= height )
|
||||
{
|
||||
my = height - j;
|
||||
}
|
||||
if( i+4 >= width )
|
||||
{
|
||||
mx = width - i;
|
||||
}
|
||||
for( y = 0; y < my; ++y )
|
||||
{
|
||||
for( x = 0; x < mx; ++x )
|
||||
{
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels];
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels+chan_step];
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels+chan_step+chan_step];
|
||||
}
|
||||
for( x = mx; x < 4; ++x )
|
||||
{
|
||||
ublock[idx++] = ublock[0];
|
||||
ublock[idx++] = ublock[1];
|
||||
ublock[idx++] = ublock[2];
|
||||
}
|
||||
}
|
||||
for( y = my; y < 4; ++y )
|
||||
{
|
||||
for( x = 0; x < 4; ++x )
|
||||
{
|
||||
ublock[idx++] = ublock[0];
|
||||
ublock[idx++] = ublock[1];
|
||||
ublock[idx++] = ublock[2];
|
||||
}
|
||||
}
|
||||
/* compress the block */
|
||||
++block_count;
|
||||
compress_DDS_color_block( 3, ublock, cblock );
|
||||
/* copy the data from the block into the main block */
|
||||
for( x = 0; x < 8; ++x )
|
||||
{
|
||||
compressed[index++] = cblock[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
return compressed;
|
||||
}
|
||||
|
||||
unsigned char* convert_image_to_DXT5(
|
||||
const unsigned char *const uncompressed,
|
||||
int width, int height, int channels,
|
||||
int *out_size )
|
||||
{
|
||||
unsigned char *compressed;
|
||||
int i, j, x, y;
|
||||
unsigned char ublock[16*4];
|
||||
unsigned char cblock[8];
|
||||
int index = 0, chan_step = 1;
|
||||
int block_count = 0, has_alpha;
|
||||
/* error check */
|
||||
*out_size = 0;
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(NULL == uncompressed) ||
|
||||
(channels < 1) || ( channels > 4) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/* for channels == 1 or 2, I do not step forward for R,G,B vales */
|
||||
if( channels < 3 )
|
||||
{
|
||||
chan_step = 0;
|
||||
}
|
||||
/* # channels = 1 or 3 have no alpha, 2 & 4 do have alpha */
|
||||
has_alpha = 1 - (channels & 1);
|
||||
/* get the RAM for the compressed image
|
||||
(16 bytes per 4x4 pixel block) */
|
||||
*out_size = ((width+3) >> 2) * ((height+3) >> 2) * 16;
|
||||
compressed = (unsigned char*)malloc( *out_size );
|
||||
/* go through each block */
|
||||
for( j = 0; j < height; j += 4 )
|
||||
{
|
||||
for( i = 0; i < width; i += 4 )
|
||||
{
|
||||
/* local variables, and my block counter */
|
||||
int idx = 0;
|
||||
int mx = 4, my = 4;
|
||||
if( j+4 >= height )
|
||||
{
|
||||
my = height - j;
|
||||
}
|
||||
if( i+4 >= width )
|
||||
{
|
||||
mx = width - i;
|
||||
}
|
||||
for( y = 0; y < my; ++y )
|
||||
{
|
||||
for( x = 0; x < mx; ++x )
|
||||
{
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels];
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels+chan_step];
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels+chan_step+chan_step];
|
||||
ublock[idx++] =
|
||||
has_alpha * uncompressed[(j+y)*width*channels+(i+x)*channels+channels-1]
|
||||
+ (1-has_alpha)*255;
|
||||
}
|
||||
for( x = mx; x < 4; ++x )
|
||||
{
|
||||
ublock[idx++] = ublock[0];
|
||||
ublock[idx++] = ublock[1];
|
||||
ublock[idx++] = ublock[2];
|
||||
ublock[idx++] = ublock[3];
|
||||
}
|
||||
}
|
||||
for( y = my; y < 4; ++y )
|
||||
{
|
||||
for( x = 0; x < 4; ++x )
|
||||
{
|
||||
ublock[idx++] = ublock[0];
|
||||
ublock[idx++] = ublock[1];
|
||||
ublock[idx++] = ublock[2];
|
||||
ublock[idx++] = ublock[3];
|
||||
}
|
||||
}
|
||||
/* now compress the alpha block */
|
||||
compress_DDS_alpha_block( ublock, cblock );
|
||||
/* copy the data from the compressed alpha block into the main buffer */
|
||||
for( x = 0; x < 8; ++x )
|
||||
{
|
||||
compressed[index++] = cblock[x];
|
||||
}
|
||||
/* then compress the color block */
|
||||
++block_count;
|
||||
compress_DDS_color_block( 4, ublock, cblock );
|
||||
/* copy the data from the compressed color block into the main buffer */
|
||||
for( x = 0; x < 8; ++x )
|
||||
{
|
||||
compressed[index++] = cblock[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
return compressed;
|
||||
}
|
||||
|
||||
/********* Helper Functions *********/
|
||||
int convert_bit_range( int c, int from_bits, int to_bits )
|
||||
{
|
||||
int b = (1 << (from_bits - 1)) + c * ((1 << to_bits) - 1);
|
||||
return (b + (b >> from_bits)) >> from_bits;
|
||||
}
|
||||
|
||||
int rgb_to_565( int r, int g, int b )
|
||||
{
|
||||
return
|
||||
(convert_bit_range( r, 8, 5 ) << 11) |
|
||||
(convert_bit_range( g, 8, 6 ) << 05) |
|
||||
(convert_bit_range( b, 8, 5 ) << 00);
|
||||
}
|
||||
|
||||
void rgb_888_from_565( unsigned int c, int *r, int *g, int *b )
|
||||
{
|
||||
*r = convert_bit_range( (c >> 11) & 31, 5, 8 );
|
||||
*g = convert_bit_range( (c >> 05) & 63, 6, 8 );
|
||||
*b = convert_bit_range( (c >> 00) & 31, 5, 8 );
|
||||
}
|
||||
|
||||
void compute_color_line_STDEV(
|
||||
const unsigned char *const uncompressed,
|
||||
int channels,
|
||||
float point[3], float direction[3] )
|
||||
{
|
||||
const float inv_16 = 1.0f / 16.0f;
|
||||
int i;
|
||||
float sum_r = 0.0f, sum_g = 0.0f, sum_b = 0.0f;
|
||||
float sum_rr = 0.0f, sum_gg = 0.0f, sum_bb = 0.0f;
|
||||
float sum_rg = 0.0f, sum_rb = 0.0f, sum_gb = 0.0f;
|
||||
/* calculate all data needed for the covariance matrix
|
||||
( to compare with _rygdxt code) */
|
||||
for( i = 0; i < 16*channels; i += channels )
|
||||
{
|
||||
sum_r += uncompressed[i+0];
|
||||
sum_rr += uncompressed[i+0] * uncompressed[i+0];
|
||||
sum_g += uncompressed[i+1];
|
||||
sum_gg += uncompressed[i+1] * uncompressed[i+1];
|
||||
sum_b += uncompressed[i+2];
|
||||
sum_bb += uncompressed[i+2] * uncompressed[i+2];
|
||||
sum_rg += uncompressed[i+0] * uncompressed[i+1];
|
||||
sum_rb += uncompressed[i+0] * uncompressed[i+2];
|
||||
sum_gb += uncompressed[i+1] * uncompressed[i+2];
|
||||
}
|
||||
/* convert the sums to averages */
|
||||
sum_r *= inv_16;
|
||||
sum_g *= inv_16;
|
||||
sum_b *= inv_16;
|
||||
/* and convert the squares to the squares of the value - avg_value */
|
||||
sum_rr -= 16.0f * sum_r * sum_r;
|
||||
sum_gg -= 16.0f * sum_g * sum_g;
|
||||
sum_bb -= 16.0f * sum_b * sum_b;
|
||||
sum_rg -= 16.0f * sum_r * sum_g;
|
||||
sum_rb -= 16.0f * sum_r * sum_b;
|
||||
sum_gb -= 16.0f * sum_g * sum_b;
|
||||
/* the point on the color line is the average */
|
||||
point[0] = sum_r;
|
||||
point[1] = sum_g;
|
||||
point[2] = sum_b;
|
||||
#if USE_COV_MAT
|
||||
/*
|
||||
The following idea was from ryg.
|
||||
(https://mollyrocket.com/forums/viewtopic.php?t=392)
|
||||
The method worked great (less RMSE than mine) most of
|
||||
the time, but had some issues handling some simple
|
||||
boundary cases, like full green next to full red,
|
||||
which would generate a covariance matrix like this:
|
||||
|
||||
| 1 -1 0 |
|
||||
| -1 1 0 |
|
||||
| 0 0 0 |
|
||||
|
||||
For a given starting vector, the power method can
|
||||
generate all zeros! So no starting with {1,1,1}
|
||||
as I was doing! This kind of error is still a
|
||||
slight posibillity, but will be very rare.
|
||||
*/
|
||||
/* use the covariance matrix directly
|
||||
(1st iteration, don't use all 1.0 values!) */
|
||||
sum_r = 1.0f;
|
||||
sum_g = 2.718281828f;
|
||||
sum_b = 3.141592654f;
|
||||
direction[0] = sum_r*sum_rr + sum_g*sum_rg + sum_b*sum_rb;
|
||||
direction[1] = sum_r*sum_rg + sum_g*sum_gg + sum_b*sum_gb;
|
||||
direction[2] = sum_r*sum_rb + sum_g*sum_gb + sum_b*sum_bb;
|
||||
/* 2nd iteration, use results from the 1st guy */
|
||||
sum_r = direction[0];
|
||||
sum_g = direction[1];
|
||||
sum_b = direction[2];
|
||||
direction[0] = sum_r*sum_rr + sum_g*sum_rg + sum_b*sum_rb;
|
||||
direction[1] = sum_r*sum_rg + sum_g*sum_gg + sum_b*sum_gb;
|
||||
direction[2] = sum_r*sum_rb + sum_g*sum_gb + sum_b*sum_bb;
|
||||
/* 3rd iteration, use results from the 2nd guy */
|
||||
sum_r = direction[0];
|
||||
sum_g = direction[1];
|
||||
sum_b = direction[2];
|
||||
direction[0] = sum_r*sum_rr + sum_g*sum_rg + sum_b*sum_rb;
|
||||
direction[1] = sum_r*sum_rg + sum_g*sum_gg + sum_b*sum_gb;
|
||||
direction[2] = sum_r*sum_rb + sum_g*sum_gb + sum_b*sum_bb;
|
||||
#else
|
||||
/* use my standard deviation method
|
||||
(very robust, a tiny bit slower and less accurate) */
|
||||
direction[0] = sqrt( sum_rr );
|
||||
direction[1] = sqrt( sum_gg );
|
||||
direction[2] = sqrt( sum_bb );
|
||||
/* which has a greater component */
|
||||
if( sum_gg > sum_rr )
|
||||
{
|
||||
/* green has greater component, so base the other signs off of green */
|
||||
if( sum_rg < 0.0f )
|
||||
{
|
||||
direction[0] = -direction[0];
|
||||
}
|
||||
if( sum_gb < 0.0f )
|
||||
{
|
||||
direction[2] = -direction[2];
|
||||
}
|
||||
} else
|
||||
{
|
||||
/* red has a greater component */
|
||||
if( sum_rg < 0.0f )
|
||||
{
|
||||
direction[1] = -direction[1];
|
||||
}
|
||||
if( sum_rb < 0.0f )
|
||||
{
|
||||
direction[2] = -direction[2];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LSE_master_colors_max_min(
|
||||
int *cmax, int *cmin,
|
||||
int channels,
|
||||
const unsigned char *const uncompressed )
|
||||
{
|
||||
int i, j;
|
||||
/* the master colors */
|
||||
int c0[3], c1[3];
|
||||
/* used for fitting the line */
|
||||
float sum_x[] = { 0.0f, 0.0f, 0.0f };
|
||||
float sum_x2[] = { 0.0f, 0.0f, 0.0f };
|
||||
float dot_max = 1.0f, dot_min = -1.0f;
|
||||
float vec_len2 = 0.0f;
|
||||
float dot;
|
||||
/* error check */
|
||||
if( (channels < 3) || (channels > 4) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
compute_color_line_STDEV( uncompressed, channels, sum_x, sum_x2 );
|
||||
vec_len2 = 1.0f / ( 0.00001f +
|
||||
sum_x2[0]*sum_x2[0] + sum_x2[1]*sum_x2[1] + sum_x2[2]*sum_x2[2] );
|
||||
/* finding the max and min vector values */
|
||||
dot_max =
|
||||
(
|
||||
sum_x2[0] * uncompressed[0] +
|
||||
sum_x2[1] * uncompressed[1] +
|
||||
sum_x2[2] * uncompressed[2]
|
||||
);
|
||||
dot_min = dot_max;
|
||||
for( i = 1; i < 16; ++i )
|
||||
{
|
||||
dot =
|
||||
(
|
||||
sum_x2[0] * uncompressed[i*channels+0] +
|
||||
sum_x2[1] * uncompressed[i*channels+1] +
|
||||
sum_x2[2] * uncompressed[i*channels+2]
|
||||
);
|
||||
if( dot < dot_min )
|
||||
{
|
||||
dot_min = dot;
|
||||
} else if( dot > dot_max )
|
||||
{
|
||||
dot_max = dot;
|
||||
}
|
||||
}
|
||||
/* and the offset (from the average location) */
|
||||
dot = sum_x2[0]*sum_x[0] + sum_x2[1]*sum_x[1] + sum_x2[2]*sum_x[2];
|
||||
dot_min -= dot;
|
||||
dot_max -= dot;
|
||||
/* post multiply by the scaling factor */
|
||||
dot_min *= vec_len2;
|
||||
dot_max *= vec_len2;
|
||||
/* OK, build the master colors */
|
||||
for( i = 0; i < 3; ++i )
|
||||
{
|
||||
/* color 0 */
|
||||
c0[i] = (int)(0.5f + sum_x[i] + dot_max * sum_x2[i]);
|
||||
if( c0[i] < 0 )
|
||||
{
|
||||
c0[i] = 0;
|
||||
} else if( c0[i] > 255 )
|
||||
{
|
||||
c0[i] = 255;
|
||||
}
|
||||
/* color 1 */
|
||||
c1[i] = (int)(0.5f + sum_x[i] + dot_min * sum_x2[i]);
|
||||
if( c1[i] < 0 )
|
||||
{
|
||||
c1[i] = 0;
|
||||
} else if( c1[i] > 255 )
|
||||
{
|
||||
c1[i] = 255;
|
||||
}
|
||||
}
|
||||
/* down_sample (with rounding?) */
|
||||
i = rgb_to_565( c0[0], c0[1], c0[2] );
|
||||
j = rgb_to_565( c1[0], c1[1], c1[2] );
|
||||
if( i > j )
|
||||
{
|
||||
*cmax = i;
|
||||
*cmin = j;
|
||||
} else
|
||||
{
|
||||
*cmax = j;
|
||||
*cmin = i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
compress_DDS_color_block
|
||||
(
|
||||
int channels,
|
||||
const unsigned char *const uncompressed,
|
||||
unsigned char compressed[8]
|
||||
)
|
||||
{
|
||||
/* variables */
|
||||
int i;
|
||||
int next_bit;
|
||||
int enc_c0, enc_c1;
|
||||
int c0[4], c1[4];
|
||||
float color_line[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
float vec_len2 = 0.0f, dot_offset = 0.0f;
|
||||
/* stupid order */
|
||||
int swizzle4[] = { 0, 2, 3, 1 };
|
||||
/* get the master colors */
|
||||
LSE_master_colors_max_min( &enc_c0, &enc_c1, channels, uncompressed );
|
||||
/* store the 565 color 0 and color 1 */
|
||||
compressed[0] = (enc_c0 >> 0) & 255;
|
||||
compressed[1] = (enc_c0 >> 8) & 255;
|
||||
compressed[2] = (enc_c1 >> 0) & 255;
|
||||
compressed[3] = (enc_c1 >> 8) & 255;
|
||||
/* zero out the compressed data */
|
||||
compressed[4] = 0;
|
||||
compressed[5] = 0;
|
||||
compressed[6] = 0;
|
||||
compressed[7] = 0;
|
||||
/* reconstitute the master color vectors */
|
||||
rgb_888_from_565( enc_c0, &c0[0], &c0[1], &c0[2] );
|
||||
rgb_888_from_565( enc_c1, &c1[0], &c1[1], &c1[2] );
|
||||
/* the new vector */
|
||||
vec_len2 = 0.0f;
|
||||
for( i = 0; i < 3; ++i )
|
||||
{
|
||||
color_line[i] = (float)(c1[i] - c0[i]);
|
||||
vec_len2 += color_line[i] * color_line[i];
|
||||
}
|
||||
if( vec_len2 > 0.0f )
|
||||
{
|
||||
vec_len2 = 1.0f / vec_len2;
|
||||
}
|
||||
/* pre-proform the scaling */
|
||||
color_line[0] *= vec_len2;
|
||||
color_line[1] *= vec_len2;
|
||||
color_line[2] *= vec_len2;
|
||||
/* compute the offset (constant) portion of the dot product */
|
||||
dot_offset = color_line[0]*c0[0] + color_line[1]*c0[1] + color_line[2]*c0[2];
|
||||
/* store the rest of the bits */
|
||||
next_bit = 8*4;
|
||||
for( i = 0; i < 16; ++i )
|
||||
{
|
||||
/* find the dot product of this color, to place it on the line
|
||||
(should be [-1,1]) */
|
||||
int next_value = 0;
|
||||
float dot_product =
|
||||
color_line[0] * uncompressed[i*channels+0] +
|
||||
color_line[1] * uncompressed[i*channels+1] +
|
||||
color_line[2] * uncompressed[i*channels+2] -
|
||||
dot_offset;
|
||||
/* map to [0,3] */
|
||||
next_value = (int)( dot_product * 3.0f + 0.5f );
|
||||
if( next_value > 3 )
|
||||
{
|
||||
next_value = 3;
|
||||
} else if( next_value < 0 )
|
||||
{
|
||||
next_value = 0;
|
||||
}
|
||||
/* OK, store this value */
|
||||
compressed[next_bit >> 3] |= swizzle4[ next_value ] << (next_bit & 7);
|
||||
next_bit += 2;
|
||||
}
|
||||
/* done compressing to DXT1 */
|
||||
}
|
||||
|
||||
void
|
||||
compress_DDS_alpha_block
|
||||
(
|
||||
const unsigned char *const uncompressed,
|
||||
unsigned char compressed[8]
|
||||
)
|
||||
{
|
||||
/* variables */
|
||||
int i;
|
||||
int next_bit;
|
||||
int a0, a1;
|
||||
float scale_me;
|
||||
/* stupid order */
|
||||
int swizzle8[] = { 1, 7, 6, 5, 4, 3, 2, 0 };
|
||||
/* get the alpha limits (a0 > a1) */
|
||||
a0 = a1 = uncompressed[3];
|
||||
for( i = 4+3; i < 16*4; i += 4 )
|
||||
{
|
||||
if( uncompressed[i] > a0 )
|
||||
{
|
||||
a0 = uncompressed[i];
|
||||
} else if( uncompressed[i] < a1 )
|
||||
{
|
||||
a1 = uncompressed[i];
|
||||
}
|
||||
}
|
||||
/* store those limits, and zero the rest of the compressed dataset */
|
||||
compressed[0] = a0;
|
||||
compressed[1] = a1;
|
||||
/* zero out the compressed data */
|
||||
compressed[2] = 0;
|
||||
compressed[3] = 0;
|
||||
compressed[4] = 0;
|
||||
compressed[5] = 0;
|
||||
compressed[6] = 0;
|
||||
compressed[7] = 0;
|
||||
/* store the all of the alpha values */
|
||||
next_bit = 8*2;
|
||||
scale_me = 7.9999f / (a0 - a1);
|
||||
for( i = 3; i < 16*4; i += 4 )
|
||||
{
|
||||
/* convert this alpha value to a 3 bit number */
|
||||
int svalue;
|
||||
int value = (int)((uncompressed[i] - a1) * scale_me);
|
||||
svalue = swizzle8[ value&7 ];
|
||||
/* OK, store this value, start with the 1st byte */
|
||||
compressed[next_bit >> 3] |= svalue << (next_bit & 7);
|
||||
if( (next_bit & 7) > 5 )
|
||||
{
|
||||
/* spans 2 bytes, fill in the start of the 2nd byte */
|
||||
compressed[1 + (next_bit >> 3)] |= svalue >> (8 - (next_bit & 7) );
|
||||
}
|
||||
next_bit += 3;
|
||||
}
|
||||
/* done compressing to DXT1 */
|
||||
}
|
123
cw 5/src/SOIL/image_DXT.h
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
Jonathan Dummer
|
||||
2007-07-31-10.32
|
||||
|
||||
simple DXT compression / decompression code
|
||||
|
||||
public domain
|
||||
*/
|
||||
|
||||
#ifndef HEADER_IMAGE_DXT
|
||||
#define HEADER_IMAGE_DXT
|
||||
|
||||
/**
|
||||
Converts an image from an array of unsigned chars (RGB or RGBA) to
|
||||
DXT1 or DXT5, then saves the converted image to disk.
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
int
|
||||
save_image_as_DDS
|
||||
(
|
||||
const char *filename,
|
||||
int width, int height, int channels,
|
||||
const unsigned char *const data
|
||||
);
|
||||
|
||||
/**
|
||||
take an image and convert it to DXT1 (no alpha)
|
||||
**/
|
||||
unsigned char*
|
||||
convert_image_to_DXT1
|
||||
(
|
||||
const unsigned char *const uncompressed,
|
||||
int width, int height, int channels,
|
||||
int *out_size
|
||||
);
|
||||
|
||||
/**
|
||||
take an image and convert it to DXT5 (with alpha)
|
||||
**/
|
||||
unsigned char*
|
||||
convert_image_to_DXT5
|
||||
(
|
||||
const unsigned char *const uncompressed,
|
||||
int width, int height, int channels,
|
||||
int *out_size
|
||||
);
|
||||
|
||||
/** A bunch of DirectDraw Surface structures and flags **/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int dwMagic;
|
||||
unsigned int dwSize;
|
||||
unsigned int dwFlags;
|
||||
unsigned int dwHeight;
|
||||
unsigned int dwWidth;
|
||||
unsigned int dwPitchOrLinearSize;
|
||||
unsigned int dwDepth;
|
||||
unsigned int dwMipMapCount;
|
||||
unsigned int dwReserved1[ 11 ];
|
||||
|
||||
/* DDPIXELFORMAT */
|
||||
struct
|
||||
{
|
||||
unsigned int dwSize;
|
||||
unsigned int dwFlags;
|
||||
unsigned int dwFourCC;
|
||||
unsigned int dwRGBBitCount;
|
||||
unsigned int dwRBitMask;
|
||||
unsigned int dwGBitMask;
|
||||
unsigned int dwBBitMask;
|
||||
unsigned int dwAlphaBitMask;
|
||||
}
|
||||
sPixelFormat;
|
||||
|
||||
/* DDCAPS2 */
|
||||
struct
|
||||
{
|
||||
unsigned int dwCaps1;
|
||||
unsigned int dwCaps2;
|
||||
unsigned int dwDDSX;
|
||||
unsigned int dwReserved;
|
||||
}
|
||||
sCaps;
|
||||
unsigned int dwReserved2;
|
||||
}
|
||||
DDS_header ;
|
||||
|
||||
/* the following constants were copied directly off the MSDN website */
|
||||
|
||||
/* The dwFlags member of the original DDSURFACEDESC2 structure
|
||||
can be set to one or more of the following values. */
|
||||
#define DDSD_CAPS 0x00000001
|
||||
#define DDSD_HEIGHT 0x00000002
|
||||
#define DDSD_WIDTH 0x00000004
|
||||
#define DDSD_PITCH 0x00000008
|
||||
#define DDSD_PIXELFORMAT 0x00001000
|
||||
#define DDSD_MIPMAPCOUNT 0x00020000
|
||||
#define DDSD_LINEARSIZE 0x00080000
|
||||
#define DDSD_DEPTH 0x00800000
|
||||
|
||||
/* DirectDraw Pixel Format */
|
||||
#define DDPF_ALPHAPIXELS 0x00000001
|
||||
#define DDPF_FOURCC 0x00000004
|
||||
#define DDPF_RGB 0x00000040
|
||||
|
||||
/* The dwCaps1 member of the DDSCAPS2 structure can be
|
||||
set to one or more of the following values. */
|
||||
#define DDSCAPS_COMPLEX 0x00000008
|
||||
#define DDSCAPS_TEXTURE 0x00001000
|
||||
#define DDSCAPS_MIPMAP 0x00400000
|
||||
|
||||
/* The dwCaps2 member of the DDSCAPS2 structure can be
|
||||
set to one or more of the following values. */
|
||||
#define DDSCAPS2_CUBEMAP 0x00000200
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
|
||||
#define DDSCAPS2_VOLUME 0x00200000
|
||||
|
||||
#endif /* HEADER_IMAGE_DXT */
|
435
cw 5/src/SOIL/image_helper.c
Normal file
@ -0,0 +1,435 @@
|
||||
/*
|
||||
Jonathan Dummer
|
||||
|
||||
image helper functions
|
||||
|
||||
MIT license
|
||||
*/
|
||||
|
||||
#include "image_helper.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Upscaling the image uses simple bilinear interpolation */
|
||||
int
|
||||
up_scale_image
|
||||
(
|
||||
const unsigned char* const orig,
|
||||
int width, int height, int channels,
|
||||
unsigned char* resampled,
|
||||
int resampled_width, int resampled_height
|
||||
)
|
||||
{
|
||||
float dx, dy;
|
||||
int x, y, c;
|
||||
|
||||
/* error(s) check */
|
||||
if ( (width < 1) || (height < 1) ||
|
||||
(resampled_width < 2) || (resampled_height < 2) ||
|
||||
(channels < 1) ||
|
||||
(NULL == orig) || (NULL == resampled) )
|
||||
{
|
||||
/* signify badness */
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
for each given pixel in the new map, find the exact location
|
||||
from the original map which would contribute to this guy
|
||||
*/
|
||||
dx = (width - 1.0f) / (resampled_width - 1.0f);
|
||||
dy = (height - 1.0f) / (resampled_height - 1.0f);
|
||||
for ( y = 0; y < resampled_height; ++y )
|
||||
{
|
||||
/* find the base y index and fractional offset from that */
|
||||
float sampley = y * dy;
|
||||
int inty = (int)sampley;
|
||||
/* if( inty < 0 ) { inty = 0; } else */
|
||||
if( inty > height - 2 ) { inty = height - 2; }
|
||||
sampley -= inty;
|
||||
for ( x = 0; x < resampled_width; ++x )
|
||||
{
|
||||
float samplex = x * dx;
|
||||
int intx = (int)samplex;
|
||||
int base_index;
|
||||
/* find the base x index and fractional offset from that */
|
||||
/* if( intx < 0 ) { intx = 0; } else */
|
||||
if( intx > width - 2 ) { intx = width - 2; }
|
||||
samplex -= intx;
|
||||
/* base index into the original image */
|
||||
base_index = (inty * width + intx) * channels;
|
||||
for ( c = 0; c < channels; ++c )
|
||||
{
|
||||
/* do the sampling */
|
||||
float value = 0.5f;
|
||||
value += orig[base_index]
|
||||
*(1.0f-samplex)*(1.0f-sampley);
|
||||
value += orig[base_index+channels]
|
||||
*(samplex)*(1.0f-sampley);
|
||||
value += orig[base_index+width*channels]
|
||||
*(1.0f-samplex)*(sampley);
|
||||
value += orig[base_index+width*channels+channels]
|
||||
*(samplex)*(sampley);
|
||||
/* move to the next channel */
|
||||
++base_index;
|
||||
/* save the new value */
|
||||
resampled[y*resampled_width*channels+x*channels+c] =
|
||||
(unsigned char)(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* done */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
mipmap_image
|
||||
(
|
||||
const unsigned char* const orig,
|
||||
int width, int height, int channels,
|
||||
unsigned char* resampled,
|
||||
int block_size_x, int block_size_y
|
||||
)
|
||||
{
|
||||
int mip_width, mip_height;
|
||||
int i, j, c;
|
||||
|
||||
/* error check */
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(channels < 1) || (orig == NULL) ||
|
||||
(resampled == NULL) ||
|
||||
(block_size_x < 1) || (block_size_y < 1) )
|
||||
{
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
}
|
||||
mip_width = width / block_size_x;
|
||||
mip_height = height / block_size_y;
|
||||
if( mip_width < 1 )
|
||||
{
|
||||
mip_width = 1;
|
||||
}
|
||||
if( mip_height < 1 )
|
||||
{
|
||||
mip_height = 1;
|
||||
}
|
||||
for( j = 0; j < mip_height; ++j )
|
||||
{
|
||||
for( i = 0; i < mip_width; ++i )
|
||||
{
|
||||
for( c = 0; c < channels; ++c )
|
||||
{
|
||||
const int index = (j*block_size_y)*width*channels + (i*block_size_x)*channels + c;
|
||||
int sum_value;
|
||||
int u,v;
|
||||
int u_block = block_size_x;
|
||||
int v_block = block_size_y;
|
||||
int block_area;
|
||||
/* do a bit of checking so we don't over-run the boundaries
|
||||
(necessary for non-square textures!) */
|
||||
if( block_size_x * (i+1) > width )
|
||||
{
|
||||
u_block = width - i*block_size_y;
|
||||
}
|
||||
if( block_size_y * (j+1) > height )
|
||||
{
|
||||
v_block = height - j*block_size_y;
|
||||
}
|
||||
block_area = u_block*v_block;
|
||||
/* for this pixel, see what the average
|
||||
of all the values in the block are.
|
||||
note: start the sum at the rounding value, not at 0 */
|
||||
sum_value = block_area >> 1;
|
||||
for( v = 0; v < v_block; ++v )
|
||||
for( u = 0; u < u_block; ++u )
|
||||
{
|
||||
sum_value += orig[index + v*width*channels + u*channels];
|
||||
}
|
||||
resampled[j*mip_width*channels + i*channels + c] = sum_value / block_area;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
scale_image_RGB_to_NTSC_safe
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
)
|
||||
{
|
||||
const float scale_lo = 16.0f - 0.499f;
|
||||
const float scale_hi = 235.0f + 0.499f;
|
||||
int i, j;
|
||||
int nc = channels;
|
||||
unsigned char scale_LUT[256];
|
||||
/* error check */
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(channels < 1) || (orig == NULL) )
|
||||
{
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
}
|
||||
/* set up the scaling Look Up Table */
|
||||
for( i = 0; i < 256; ++i )
|
||||
{
|
||||
scale_LUT[i] = (unsigned char)((scale_hi - scale_lo) * i / 255.0f + scale_lo);
|
||||
}
|
||||
/* for channels = 2 or 4, ignore the alpha component */
|
||||
nc -= 1 - (channels & 1);
|
||||
/* OK, go through the image and scale any non-alpha components */
|
||||
for( i = 0; i < width*height*channels; i += channels )
|
||||
{
|
||||
for( j = 0; j < nc; ++j )
|
||||
{
|
||||
orig[i+j] = scale_LUT[orig[i+j]];
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char clamp_byte( int x ) { return ( (x) < 0 ? (0) : ( (x) > 255 ? 255 : (x) ) ); }
|
||||
|
||||
/*
|
||||
This function takes the RGB components of the image
|
||||
and converts them into YCoCg. 3 components will be
|
||||
re-ordered to CoYCg (for optimum DXT1 compression),
|
||||
while 4 components will be ordered CoCgAY (for DXT5
|
||||
compression).
|
||||
*/
|
||||
int
|
||||
convert_RGB_to_YCoCg
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
)
|
||||
{
|
||||
int i;
|
||||
/* error check */
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(channels < 3) || (channels > 4) ||
|
||||
(orig == NULL) )
|
||||
{
|
||||
/* nothing to do */
|
||||
return -1;
|
||||
}
|
||||
/* do the conversion */
|
||||
if( channels == 3 )
|
||||
{
|
||||
for( i = 0; i < width*height*3; i += 3 )
|
||||
{
|
||||
int r = orig[i+0];
|
||||
int g = (orig[i+1] + 1) >> 1;
|
||||
int b = orig[i+2];
|
||||
int tmp = (2 + r + b) >> 2;
|
||||
/* Co */
|
||||
orig[i+0] = clamp_byte( 128 + ((r - b + 1) >> 1) );
|
||||
/* Y */
|
||||
orig[i+1] = clamp_byte( g + tmp );
|
||||
/* Cg */
|
||||
orig[i+2] = clamp_byte( 128 + g - tmp );
|
||||
}
|
||||
} else
|
||||
{
|
||||
for( i = 0; i < width*height*4; i += 4 )
|
||||
{
|
||||
int r = orig[i+0];
|
||||
int g = (orig[i+1] + 1) >> 1;
|
||||
int b = orig[i+2];
|
||||
unsigned char a = orig[i+3];
|
||||
int tmp = (2 + r + b) >> 2;
|
||||
/* Co */
|
||||
orig[i+0] = clamp_byte( 128 + ((r - b + 1) >> 1) );
|
||||
/* Cg */
|
||||
orig[i+1] = clamp_byte( 128 + g - tmp );
|
||||
/* Alpha */
|
||||
orig[i+2] = a;
|
||||
/* Y */
|
||||
orig[i+3] = clamp_byte( g + tmp );
|
||||
}
|
||||
}
|
||||
/* done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
This function takes the YCoCg components of the image
|
||||
and converts them into RGB. See above.
|
||||
*/
|
||||
int
|
||||
convert_YCoCg_to_RGB
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
)
|
||||
{
|
||||
int i;
|
||||
/* error check */
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(channels < 3) || (channels > 4) ||
|
||||
(orig == NULL) )
|
||||
{
|
||||
/* nothing to do */
|
||||
return -1;
|
||||
}
|
||||
/* do the conversion */
|
||||
if( channels == 3 )
|
||||
{
|
||||
for( i = 0; i < width*height*3; i += 3 )
|
||||
{
|
||||
int co = orig[i+0] - 128;
|
||||
int y = orig[i+1];
|
||||
int cg = orig[i+2] - 128;
|
||||
/* R */
|
||||
orig[i+0] = clamp_byte( y + co - cg );
|
||||
/* G */
|
||||
orig[i+1] = clamp_byte( y + cg );
|
||||
/* B */
|
||||
orig[i+2] = clamp_byte( y - co - cg );
|
||||
}
|
||||
} else
|
||||
{
|
||||
for( i = 0; i < width*height*4; i += 4 )
|
||||
{
|
||||
int co = orig[i+0] - 128;
|
||||
int cg = orig[i+1] - 128;
|
||||
unsigned char a = orig[i+2];
|
||||
int y = orig[i+3];
|
||||
/* R */
|
||||
orig[i+0] = clamp_byte( y + co - cg );
|
||||
/* G */
|
||||
orig[i+1] = clamp_byte( y + cg );
|
||||
/* B */
|
||||
orig[i+2] = clamp_byte( y - co - cg );
|
||||
/* A */
|
||||
orig[i+3] = a;
|
||||
}
|
||||
}
|
||||
/* done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
float
|
||||
find_max_RGBE
|
||||
(
|
||||
unsigned char *image,
|
||||
int width, int height
|
||||
)
|
||||
{
|
||||
float max_val = 0.0f;
|
||||
unsigned char *img = image;
|
||||
int i, j;
|
||||
for( i = width * height; i > 0; --i )
|
||||
{
|
||||
/* float scale = powf( 2.0f, img[3] - 128.0f ) / 255.0f; */
|
||||
float scale = ldexp( 1.0f / 255.0f, (int)(img[3]) - 128 );
|
||||
for( j = 0; j < 3; ++j )
|
||||
{
|
||||
if( img[j] * scale > max_val )
|
||||
{
|
||||
max_val = img[j] * scale;
|
||||
}
|
||||
}
|
||||
/* next pixel */
|
||||
img += 4;
|
||||
}
|
||||
return max_val;
|
||||
}
|
||||
|
||||
int
|
||||
RGBE_to_RGBdivA
|
||||
(
|
||||
unsigned char *image,
|
||||
int width, int height,
|
||||
int rescale_to_max
|
||||
)
|
||||
{
|
||||
/* local variables */
|
||||
int i, iv;
|
||||
unsigned char *img = image;
|
||||
float scale = 1.0f;
|
||||
/* error check */
|
||||
if( (!image) || (width < 1) || (height < 1) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* convert (note: no negative numbers, but 0.0 is possible) */
|
||||
if( rescale_to_max )
|
||||
{
|
||||
scale = 255.0f / find_max_RGBE( image, width, height );
|
||||
}
|
||||
for( i = width * height; i > 0; --i )
|
||||
{
|
||||
/* decode this pixel, and find the max */
|
||||
float r,g,b,e, m;
|
||||
/* e = scale * powf( 2.0f, img[3] - 128.0f ) / 255.0f; */
|
||||
e = scale * ldexp( 1.0f / 255.0f, (int)(img[3]) - 128 );
|
||||
r = e * img[0];
|
||||
g = e * img[1];
|
||||
b = e * img[2];
|
||||
m = (r > g) ? r : g;
|
||||
m = (b > m) ? b : m;
|
||||
/* and encode it into RGBdivA */
|
||||
iv = (m != 0.0f) ? (int)(255.0f / m) : 1.0f;
|
||||
iv = (iv < 1) ? 1 : iv;
|
||||
img[3] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * r + 0.5f);
|
||||
img[0] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * g + 0.5f);
|
||||
img[1] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * b + 0.5f);
|
||||
img[2] = (iv > 255) ? 255 : iv;
|
||||
/* and on to the next pixel */
|
||||
img += 4;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
RGBE_to_RGBdivA2
|
||||
(
|
||||
unsigned char *image,
|
||||
int width, int height,
|
||||
int rescale_to_max
|
||||
)
|
||||
{
|
||||
/* local variables */
|
||||
int i, iv;
|
||||
unsigned char *img = image;
|
||||
float scale = 1.0f;
|
||||
/* error check */
|
||||
if( (!image) || (width < 1) || (height < 1) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* convert (note: no negative numbers, but 0.0 is possible) */
|
||||
if( rescale_to_max )
|
||||
{
|
||||
scale = 255.0f * 255.0f / find_max_RGBE( image, width, height );
|
||||
}
|
||||
for( i = width * height; i > 0; --i )
|
||||
{
|
||||
/* decode this pixel, and find the max */
|
||||
float r,g,b,e, m;
|
||||
/* e = scale * powf( 2.0f, img[3] - 128.0f ) / 255.0f; */
|
||||
e = scale * ldexp( 1.0f / 255.0f, (int)(img[3]) - 128 );
|
||||
r = e * img[0];
|
||||
g = e * img[1];
|
||||
b = e * img[2];
|
||||
m = (r > g) ? r : g;
|
||||
m = (b > m) ? b : m;
|
||||
/* and encode it into RGBdivA */
|
||||
iv = (m != 0.0f) ? (int)sqrtf( 255.0f * 255.0f / m ) : 1.0f;
|
||||
iv = (iv < 1) ? 1 : iv;
|
||||
img[3] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * img[3] * r / 255.0f + 0.5f);
|
||||
img[0] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * img[3] * g / 255.0f + 0.5f);
|
||||
img[1] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * img[3] * b / 255.0f + 0.5f);
|
||||
img[2] = (iv > 255) ? 255 : iv;
|
||||
/* and on to the next pixel */
|
||||
img += 4;
|
||||
}
|
||||
return 1;
|
||||
}
|
115
cw 5/src/SOIL/image_helper.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
Jonathan Dummer
|
||||
|
||||
Image helper functions
|
||||
|
||||
MIT license
|
||||
*/
|
||||
|
||||
#ifndef HEADER_IMAGE_HELPER
|
||||
#define HEADER_IMAGE_HELPER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
This function upscales an image.
|
||||
Not to be used to create MIPmaps,
|
||||
but to make it square,
|
||||
or to make it a power-of-two sized.
|
||||
**/
|
||||
int
|
||||
up_scale_image
|
||||
(
|
||||
const unsigned char* const orig,
|
||||
int width, int height, int channels,
|
||||
unsigned char* resampled,
|
||||
int resampled_width, int resampled_height
|
||||
);
|
||||
|
||||
/**
|
||||
This function downscales an image.
|
||||
Used for creating MIPmaps,
|
||||
the incoming image should be a
|
||||
power-of-two sized.
|
||||
**/
|
||||
int
|
||||
mipmap_image
|
||||
(
|
||||
const unsigned char* const orig,
|
||||
int width, int height, int channels,
|
||||
unsigned char* resampled,
|
||||
int block_size_x, int block_size_y
|
||||
);
|
||||
|
||||
/**
|
||||
This function takes the RGB components of the image
|
||||
and scales each channel from [0,255] to [16,235].
|
||||
This makes the colors "Safe" for display on NTSC
|
||||
displays. Note that this is _NOT_ a good idea for
|
||||
loading images like normal- or height-maps!
|
||||
**/
|
||||
int
|
||||
scale_image_RGB_to_NTSC_safe
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
);
|
||||
|
||||
/**
|
||||
This function takes the RGB components of the image
|
||||
and converts them into YCoCg. 3 components will be
|
||||
re-ordered to CoYCg (for optimum DXT1 compression),
|
||||
while 4 components will be ordered CoCgAY (for DXT5
|
||||
compression).
|
||||
**/
|
||||
int
|
||||
convert_RGB_to_YCoCg
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
);
|
||||
|
||||
/**
|
||||
This function takes the YCoCg components of the image
|
||||
and converts them into RGB. See above.
|
||||
**/
|
||||
int
|
||||
convert_YCoCg_to_RGB
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
);
|
||||
|
||||
/**
|
||||
Converts an HDR image from an array
|
||||
of unsigned chars (RGBE) to RGBdivA
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
int
|
||||
RGBE_to_RGBdivA
|
||||
(
|
||||
unsigned char *image,
|
||||
int width, int height,
|
||||
int rescale_to_max
|
||||
);
|
||||
|
||||
/**
|
||||
Converts an HDR image from an array
|
||||
of unsigned chars (RGBE) to RGBdivA2
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
int
|
||||
RGBE_to_RGBdivA2
|
||||
(
|
||||
unsigned char *image,
|
||||
int width, int height,
|
||||
int rescale_to_max
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_IMAGE_HELPER */
|
3682
cw 5/src/SOIL/stb_image_aug.c
Normal file
354
cw 5/src/SOIL/stb_image_aug.h
Normal file
@ -0,0 +1,354 @@
|
||||
/* stbi-1.16 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
|
||||
when you control the images you're loading
|
||||
|
||||
QUICK NOTES:
|
||||
Primarily of interest to game developers and other people who can
|
||||
avoid problematic images and only need the trivial interface
|
||||
|
||||
JPEG baseline (no JPEG progressive, no oddball channel decimations)
|
||||
PNG non-interlaced
|
||||
BMP non-1bpp, non-RLE
|
||||
TGA (not sure what subset, if a subset)
|
||||
PSD (composited view only, no extra channels)
|
||||
HDR (radiance rgbE format)
|
||||
writes BMP,TGA (define STBI_NO_WRITE to remove code)
|
||||
decoded from memory or through stdio FILE (define STBI_NO_STDIO to remove code)
|
||||
supports installable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
|
||||
|
||||
TODO:
|
||||
stbi_info_*
|
||||
|
||||
history:
|
||||
1.16 major bugfix - convert_format converted one too many pixels
|
||||
1.15 initialize some fields for thread safety
|
||||
1.14 fix threadsafe conversion bug; header-file-only version (#define STBI_HEADER_FILE_ONLY before including)
|
||||
1.13 threadsafe
|
||||
1.12 const qualifiers in the API
|
||||
1.11 Support installable IDCT, colorspace conversion routines
|
||||
1.10 Fixes for 64-bit (don't use "unsigned long")
|
||||
optimized upsampling by Fabian "ryg" Giesen
|
||||
1.09 Fix format-conversion for PSD code (bad global variables!)
|
||||
1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz
|
||||
1.07 attempt to fix C++ warning/errors again
|
||||
1.06 attempt to fix C++ warning/errors again
|
||||
1.05 fix TGA loading to return correct *comp and use good luminance calc
|
||||
1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free
|
||||
1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR
|
||||
1.02 support for (subset of) HDR files, float interface for preferred access to them
|
||||
1.01 fix bug: possible bug in handling right-side up bmps... not sure
|
||||
fix bug: the stbi_bmp_load() and stbi_tga_load() functions didn't work at all
|
||||
1.00 interface to zlib that skips zlib header
|
||||
0.99 correct handling of alpha in palette
|
||||
0.98 TGA loader by lonesock; dynamically add loaders (untested)
|
||||
0.97 jpeg errors on too large a file; also catch another malloc failure
|
||||
0.96 fix detection of invalid v value - particleman@mollyrocket forum
|
||||
0.95 during header scan, seek to markers in case of padding
|
||||
0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same
|
||||
0.93 handle jpegtran output; verbose errors
|
||||
0.92 read 4,8,16,24,32-bit BMP files of several formats
|
||||
0.91 output 24-bit Windows 3.0 BMP files
|
||||
0.90 fix a few more warnings; bump version number to approach 1.0
|
||||
0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd
|
||||
0.60 fix compiling as c++
|
||||
0.59 fix warnings: merge Dave Moore's -Wall fixes
|
||||
0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian
|
||||
0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less
|
||||
than 16 available
|
||||
0.56 fix bug: zlib uncompressed mode len vs. nlen
|
||||
0.55 fix bug: restart_interval not initialized to 0
|
||||
0.54 allow NULL for 'int *comp'
|
||||
0.53 fix bug in png 3->4; speedup png decoding
|
||||
0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments
|
||||
0.51 obey req_comp requests, 1-component jpegs return as 1-component,
|
||||
on 'test' only check type, not whether we support this variant
|
||||
*/
|
||||
|
||||
#ifndef HEADER_STB_IMAGE_AUGMENTED
|
||||
#define HEADER_STB_IMAGE_AUGMENTED
|
||||
|
||||
//// begin header file ////////////////////////////////////////////////////
|
||||
//
|
||||
// Limitations:
|
||||
// - no progressive/interlaced support (jpeg, png)
|
||||
// - 8-bit samples only (jpeg, png)
|
||||
// - not threadsafe
|
||||
// - channel subsampling of at most 2 in each dimension (jpeg)
|
||||
// - no delayed line count (jpeg) -- IJG doesn't support either
|
||||
//
|
||||
// Basic usage (see HDR discussion below):
|
||||
// int x,y,n;
|
||||
// unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
|
||||
// // ... process data if not NULL ...
|
||||
// // ... x = width, y = height, n = # 8-bit components per pixel ...
|
||||
// // ... replace '0' with '1'..'4' to force that many components per pixel
|
||||
// stbi_image_free(data)
|
||||
//
|
||||
// Standard parameters:
|
||||
// int *x -- outputs image width in pixels
|
||||
// int *y -- outputs image height in pixels
|
||||
// int *comp -- outputs # of image components in image file
|
||||
// int req_comp -- if non-zero, # of image components requested in result
|
||||
//
|
||||
// The return value from an image loader is an 'unsigned char *' which points
|
||||
// to the pixel data. The pixel data consists of *y scanlines of *x pixels,
|
||||
// with each pixel consisting of N interleaved 8-bit components; the first
|
||||
// pixel pointed to is top-left-most in the image. There is no padding between
|
||||
// image scanlines or between pixels, regardless of format. The number of
|
||||
// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise.
|
||||
// If req_comp is non-zero, *comp has the number of components that _would_
|
||||
// have been output otherwise. E.g. if you set req_comp to 4, you will always
|
||||
// get RGBA output, but you can check *comp to easily see if it's opaque.
|
||||
//
|
||||
// An output image with N components has the following components interleaved
|
||||
// in this order in each pixel:
|
||||
//
|
||||
// N=#comp components
|
||||
// 1 grey
|
||||
// 2 grey, alpha
|
||||
// 3 red, green, blue
|
||||
// 4 red, green, blue, alpha
|
||||
//
|
||||
// If image loading fails for any reason, the return value will be NULL,
|
||||
// and *x, *y, *comp will be unchanged. The function stbi_failure_reason()
|
||||
// can be queried for an extremely brief, end-user unfriendly explanation
|
||||
// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid
|
||||
// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
|
||||
// more user-friendly ones.
|
||||
//
|
||||
// Paletted PNG and BMP images are automatically depalettized.
|
||||
//
|
||||
//
|
||||
// ===========================================================================
|
||||
//
|
||||
// HDR image support (disable by defining STBI_NO_HDR)
|
||||
//
|
||||
// stb_image now supports loading HDR images in general, and currently
|
||||
// the Radiance .HDR file format, although the support is provided
|
||||
// generically. You can still load any file through the existing interface;
|
||||
// if you attempt to load an HDR file, it will be automatically remapped to
|
||||
// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
|
||||
// both of these constants can be reconfigured through this interface:
|
||||
//
|
||||
// stbi_hdr_to_ldr_gamma(2.2f);
|
||||
// stbi_hdr_to_ldr_scale(1.0f);
|
||||
//
|
||||
// (note, do not use _inverse_ constants; stbi_image will invert them
|
||||
// appropriately).
|
||||
//
|
||||
// Additionally, there is a new, parallel interface for loading files as
|
||||
// (linear) floats to preserve the full dynamic range:
|
||||
//
|
||||
// float *data = stbi_loadf(filename, &x, &y, &n, 0);
|
||||
//
|
||||
// If you load LDR images through this interface, those images will
|
||||
// be promoted to floating point values, run through the inverse of
|
||||
// constants corresponding to the above:
|
||||
//
|
||||
// stbi_ldr_to_hdr_scale(1.0f);
|
||||
// stbi_ldr_to_hdr_gamma(2.2f);
|
||||
//
|
||||
// Finally, given a filename (or an open file or memory block--see header
|
||||
// file for details) containing image data, you can query for the "most
|
||||
// appropriate" interface to use (that is, whether the image is HDR or
|
||||
// not), using:
|
||||
//
|
||||
// stbi_is_hdr(char *filename);
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define STBI_VERSION 1
|
||||
|
||||
enum
|
||||
{
|
||||
STBI_default = 0, // only used for req_comp
|
||||
|
||||
STBI_grey = 1,
|
||||
STBI_grey_alpha = 2,
|
||||
STBI_rgb = 3,
|
||||
STBI_rgb_alpha = 4,
|
||||
};
|
||||
|
||||
typedef unsigned char stbi_uc;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// WRITING API
|
||||
|
||||
#if !defined(STBI_NO_WRITE) && !defined(STBI_NO_STDIO)
|
||||
// write a BMP/TGA file given tightly packed 'comp' channels (no padding, nor bmp-stride-padding)
|
||||
// (you must include the appropriate extension in the filename).
|
||||
// returns TRUE on success, FALSE if couldn't open file, error writing file
|
||||
extern int stbi_write_bmp (char const *filename, int x, int y, int comp, void *data);
|
||||
extern int stbi_write_tga (char const *filename, int x, int y, int comp, void *data);
|
||||
#endif
|
||||
|
||||
// PRIMARY API - works on images of any type
|
||||
|
||||
// load image by filename, open file, or memory buffer
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp);
|
||||
#endif
|
||||
extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
// for stbi_load_from_file, file pointer is left pointing immediately after image
|
||||
|
||||
#ifndef STBI_NO_HDR
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
|
||||
extern void stbi_hdr_to_ldr_gamma(float gamma);
|
||||
extern void stbi_hdr_to_ldr_scale(float scale);
|
||||
|
||||
extern void stbi_ldr_to_hdr_gamma(float gamma);
|
||||
extern void stbi_ldr_to_hdr_scale(float scale);
|
||||
|
||||
#endif // STBI_NO_HDR
|
||||
|
||||
// get a VERY brief reason for failure
|
||||
// NOT THREADSAFE
|
||||
extern char *stbi_failure_reason (void);
|
||||
|
||||
// free the loaded image -- this is just free()
|
||||
extern void stbi_image_free (void *retval_from_stbi_load);
|
||||
|
||||
// get image dimensions & components without fully decoding
|
||||
extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
|
||||
extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_info (char const *filename, int *x, int *y, int *comp);
|
||||
extern int stbi_is_hdr (char const *filename);
|
||||
extern int stbi_is_hdr_from_file(FILE *f);
|
||||
#endif
|
||||
|
||||
// ZLIB client - used by PNG, available for other purposes
|
||||
|
||||
extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
|
||||
extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen);
|
||||
extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
|
||||
|
||||
extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen);
|
||||
extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
|
||||
|
||||
// TYPE-SPECIFIC ACCESS
|
||||
|
||||
// is it a jpeg?
|
||||
extern int stbi_jpeg_test_memory (stbi_uc const *buffer, int len);
|
||||
extern stbi_uc *stbi_jpeg_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_jpeg_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern stbi_uc *stbi_jpeg_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_jpeg_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_jpeg_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
|
||||
extern int stbi_jpeg_info (char const *filename, int *x, int *y, int *comp);
|
||||
extern int stbi_jpeg_info_from_file (FILE *f, int *x, int *y, int *comp);
|
||||
#endif
|
||||
|
||||
// is it a png?
|
||||
extern int stbi_png_test_memory (stbi_uc const *buffer, int len);
|
||||
extern stbi_uc *stbi_png_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_png_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern stbi_uc *stbi_png_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_png_info (char const *filename, int *x, int *y, int *comp);
|
||||
extern int stbi_png_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_png_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_png_info_from_file (FILE *f, int *x, int *y, int *comp);
|
||||
#endif
|
||||
|
||||
// is it a bmp?
|
||||
extern int stbi_bmp_test_memory (stbi_uc const *buffer, int len);
|
||||
|
||||
extern stbi_uc *stbi_bmp_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_bmp_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_bmp_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
// is it a tga?
|
||||
extern int stbi_tga_test_memory (stbi_uc const *buffer, int len);
|
||||
|
||||
extern stbi_uc *stbi_tga_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_tga_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_tga_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_tga_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
// is it a psd?
|
||||
extern int stbi_psd_test_memory (stbi_uc const *buffer, int len);
|
||||
|
||||
extern stbi_uc *stbi_psd_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_psd_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_psd_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
// is it an hdr?
|
||||
extern int stbi_hdr_test_memory (stbi_uc const *buffer, int len);
|
||||
|
||||
extern float * stbi_hdr_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern float * stbi_hdr_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_hdr_load_rgbe (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern float * stbi_hdr_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_hdr_test_file (FILE *f);
|
||||
extern float * stbi_hdr_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_hdr_load_rgbe_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
// define new loaders
|
||||
typedef struct
|
||||
{
|
||||
int (*test_memory)(stbi_uc const *buffer, int len);
|
||||
stbi_uc * (*load_from_memory)(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
int (*test_file)(FILE *f);
|
||||
stbi_uc * (*load_from_file)(FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
} stbi_loader;
|
||||
|
||||
// register a loader by filling out the above structure (you must defined ALL functions)
|
||||
// returns 1 if added or already added, 0 if not added (too many loaders)
|
||||
// NOT THREADSAFE
|
||||
extern int stbi_register_loader(stbi_loader *loader);
|
||||
|
||||
// define faster low-level operations (typically SIMD support)
|
||||
#if STBI_SIMD
|
||||
typedef void (*stbi_idct_8x8)(uint8 *out, int out_stride, short data[64], unsigned short *dequantize);
|
||||
// compute an integer IDCT on "input"
|
||||
// input[x] = data[x] * dequantize[x]
|
||||
// write results to 'out': 64 samples, each run of 8 spaced by 'out_stride'
|
||||
// CLAMP results to 0..255
|
||||
typedef void (*stbi_YCbCr_to_RGB_run)(uint8 *output, uint8 const *y, uint8 const *cb, uint8 const *cr, int count, int step);
|
||||
// compute a conversion from YCbCr to RGB
|
||||
// 'count' pixels
|
||||
// write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B
|
||||
// y: Y input channel
|
||||
// cb: Cb input channel; scale/biased to be 0..255
|
||||
// cr: Cr input channel; scale/biased to be 0..255
|
||||
|
||||
extern void stbi_install_idct(stbi_idct_8x8 func);
|
||||
extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func);
|
||||
#endif // STBI_SIMD
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
//
|
||||
//// end header file /////////////////////////////////////////////////////
|
||||
#endif // STBI_INCLUDE_STB_IMAGE_H
|
21
cw 5/src/SOIL/stbi_DDS_aug.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
adding DDS loading support to stbi
|
||||
*/
|
||||
|
||||
#ifndef HEADER_STB_IMAGE_DDS_AUGMENTATION
|
||||
#define HEADER_STB_IMAGE_DDS_AUGMENTATION
|
||||
|
||||
// is it a DDS file?
|
||||
extern int stbi_dds_test_memory (stbi_uc const *buffer, int len);
|
||||
|
||||
extern stbi_uc *stbi_dds_load (char *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_dds_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_dds_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_dds_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
//
|
||||
//
|
||||
//// end header file /////////////////////////////////////////////////////
|
||||
#endif // HEADER_STB_IMAGE_DDS_AUGMENTATION
|
511
cw 5/src/SOIL/stbi_DDS_aug_c.h
Normal file
@ -0,0 +1,511 @@
|
||||
|
||||
/// DDS file support, does decoding, _not_ direct uploading
|
||||
/// (use SOIL for that ;-)
|
||||
|
||||
/// A bunch of DirectDraw Surface structures and flags
|
||||
typedef struct {
|
||||
unsigned int dwMagic;
|
||||
unsigned int dwSize;
|
||||
unsigned int dwFlags;
|
||||
unsigned int dwHeight;
|
||||
unsigned int dwWidth;
|
||||
unsigned int dwPitchOrLinearSize;
|
||||
unsigned int dwDepth;
|
||||
unsigned int dwMipMapCount;
|
||||
unsigned int dwReserved1[ 11 ];
|
||||
|
||||
// DDPIXELFORMAT
|
||||
struct {
|
||||
unsigned int dwSize;
|
||||
unsigned int dwFlags;
|
||||
unsigned int dwFourCC;
|
||||
unsigned int dwRGBBitCount;
|
||||
unsigned int dwRBitMask;
|
||||
unsigned int dwGBitMask;
|
||||
unsigned int dwBBitMask;
|
||||
unsigned int dwAlphaBitMask;
|
||||
} sPixelFormat;
|
||||
|
||||
// DDCAPS2
|
||||
struct {
|
||||
unsigned int dwCaps1;
|
||||
unsigned int dwCaps2;
|
||||
unsigned int dwDDSX;
|
||||
unsigned int dwReserved;
|
||||
} sCaps;
|
||||
unsigned int dwReserved2;
|
||||
} DDS_header ;
|
||||
|
||||
// the following constants were copied directly off the MSDN website
|
||||
|
||||
// The dwFlags member of the original DDSURFACEDESC2 structure
|
||||
// can be set to one or more of the following values.
|
||||
#define DDSD_CAPS 0x00000001
|
||||
#define DDSD_HEIGHT 0x00000002
|
||||
#define DDSD_WIDTH 0x00000004
|
||||
#define DDSD_PITCH 0x00000008
|
||||
#define DDSD_PIXELFORMAT 0x00001000
|
||||
#define DDSD_MIPMAPCOUNT 0x00020000
|
||||
#define DDSD_LINEARSIZE 0x00080000
|
||||
#define DDSD_DEPTH 0x00800000
|
||||
|
||||
// DirectDraw Pixel Format
|
||||
#define DDPF_ALPHAPIXELS 0x00000001
|
||||
#define DDPF_FOURCC 0x00000004
|
||||
#define DDPF_RGB 0x00000040
|
||||
|
||||
// The dwCaps1 member of the DDSCAPS2 structure can be
|
||||
// set to one or more of the following values.
|
||||
#define DDSCAPS_COMPLEX 0x00000008
|
||||
#define DDSCAPS_TEXTURE 0x00001000
|
||||
#define DDSCAPS_MIPMAP 0x00400000
|
||||
|
||||
// The dwCaps2 member of the DDSCAPS2 structure can be
|
||||
// set to one or more of the following values.
|
||||
#define DDSCAPS2_CUBEMAP 0x00000200
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
|
||||
#define DDSCAPS2_VOLUME 0x00200000
|
||||
|
||||
static int dds_test(stbi *s)
|
||||
{
|
||||
// check the magic number
|
||||
if (get8(s) != 'D') return 0;
|
||||
if (get8(s) != 'D') return 0;
|
||||
if (get8(s) != 'S') return 0;
|
||||
if (get8(s) != ' ') return 0;
|
||||
// check header size
|
||||
if (get32le(s) != 124) return 0;
|
||||
return 1;
|
||||
}
|
||||
#ifndef STBI_NO_STDIO
|
||||
int stbi_dds_test_file (FILE *f)
|
||||
{
|
||||
stbi s;
|
||||
int r,n = ftell(f);
|
||||
start_file(&s,f);
|
||||
r = dds_test(&s);
|
||||
fseek(f,n,SEEK_SET);
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
int stbi_dds_test_memory (stbi_uc const *buffer, int len)
|
||||
{
|
||||
stbi s;
|
||||
start_mem(&s,buffer, len);
|
||||
return dds_test(&s);
|
||||
}
|
||||
|
||||
// helper functions
|
||||
int stbi_convert_bit_range( int c, int from_bits, int to_bits )
|
||||
{
|
||||
int b = (1 << (from_bits - 1)) + c * ((1 << to_bits) - 1);
|
||||
return (b + (b >> from_bits)) >> from_bits;
|
||||
}
|
||||
void stbi_rgb_888_from_565( unsigned int c, int *r, int *g, int *b )
|
||||
{
|
||||
*r = stbi_convert_bit_range( (c >> 11) & 31, 5, 8 );
|
||||
*g = stbi_convert_bit_range( (c >> 05) & 63, 6, 8 );
|
||||
*b = stbi_convert_bit_range( (c >> 00) & 31, 5, 8 );
|
||||
}
|
||||
void stbi_decode_DXT1_block(
|
||||
unsigned char uncompressed[16*4],
|
||||
unsigned char compressed[8] )
|
||||
{
|
||||
int next_bit = 4*8;
|
||||
int i, r, g, b;
|
||||
int c0, c1;
|
||||
unsigned char decode_colors[4*4];
|
||||
// find the 2 primary colors
|
||||
c0 = compressed[0] + (compressed[1] << 8);
|
||||
c1 = compressed[2] + (compressed[3] << 8);
|
||||
stbi_rgb_888_from_565( c0, &r, &g, &b );
|
||||
decode_colors[0] = r;
|
||||
decode_colors[1] = g;
|
||||
decode_colors[2] = b;
|
||||
decode_colors[3] = 255;
|
||||
stbi_rgb_888_from_565( c1, &r, &g, &b );
|
||||
decode_colors[4] = r;
|
||||
decode_colors[5] = g;
|
||||
decode_colors[6] = b;
|
||||
decode_colors[7] = 255;
|
||||
if( c0 > c1 )
|
||||
{
|
||||
// no alpha, 2 interpolated colors
|
||||
decode_colors[8] = (2*decode_colors[0] + decode_colors[4]) / 3;
|
||||
decode_colors[9] = (2*decode_colors[1] + decode_colors[5]) / 3;
|
||||
decode_colors[10] = (2*decode_colors[2] + decode_colors[6]) / 3;
|
||||
decode_colors[11] = 255;
|
||||
decode_colors[12] = (decode_colors[0] + 2*decode_colors[4]) / 3;
|
||||
decode_colors[13] = (decode_colors[1] + 2*decode_colors[5]) / 3;
|
||||
decode_colors[14] = (decode_colors[2] + 2*decode_colors[6]) / 3;
|
||||
decode_colors[15] = 255;
|
||||
} else
|
||||
{
|
||||
// 1 interpolated color, alpha
|
||||
decode_colors[8] = (decode_colors[0] + decode_colors[4]) / 2;
|
||||
decode_colors[9] = (decode_colors[1] + decode_colors[5]) / 2;
|
||||
decode_colors[10] = (decode_colors[2] + decode_colors[6]) / 2;
|
||||
decode_colors[11] = 255;
|
||||
decode_colors[12] = 0;
|
||||
decode_colors[13] = 0;
|
||||
decode_colors[14] = 0;
|
||||
decode_colors[15] = 0;
|
||||
}
|
||||
// decode the block
|
||||
for( i = 0; i < 16*4; i += 4 )
|
||||
{
|
||||
int idx = ((compressed[next_bit>>3] >> (next_bit & 7)) & 3) * 4;
|
||||
next_bit += 2;
|
||||
uncompressed[i+0] = decode_colors[idx+0];
|
||||
uncompressed[i+1] = decode_colors[idx+1];
|
||||
uncompressed[i+2] = decode_colors[idx+2];
|
||||
uncompressed[i+3] = decode_colors[idx+3];
|
||||
}
|
||||
// done
|
||||
}
|
||||
void stbi_decode_DXT23_alpha_block(
|
||||
unsigned char uncompressed[16*4],
|
||||
unsigned char compressed[8] )
|
||||
{
|
||||
int i, next_bit = 0;
|
||||
// each alpha value gets 4 bits
|
||||
for( i = 3; i < 16*4; i += 4 )
|
||||
{
|
||||
uncompressed[i] = stbi_convert_bit_range(
|
||||
(compressed[next_bit>>3] >> (next_bit&7)) & 15,
|
||||
4, 8 );
|
||||
next_bit += 4;
|
||||
}
|
||||
}
|
||||
void stbi_decode_DXT45_alpha_block(
|
||||
unsigned char uncompressed[16*4],
|
||||
unsigned char compressed[8] )
|
||||
{
|
||||
int i, next_bit = 8*2;
|
||||
unsigned char decode_alpha[8];
|
||||
// each alpha value gets 3 bits, and the 1st 2 bytes are the range
|
||||
decode_alpha[0] = compressed[0];
|
||||
decode_alpha[1] = compressed[1];
|
||||
if( decode_alpha[0] > decode_alpha[1] )
|
||||
{
|
||||
// 6 step intermediate
|
||||
decode_alpha[2] = (6*decode_alpha[0] + 1*decode_alpha[1]) / 7;
|
||||
decode_alpha[3] = (5*decode_alpha[0] + 2*decode_alpha[1]) / 7;
|
||||
decode_alpha[4] = (4*decode_alpha[0] + 3*decode_alpha[1]) / 7;
|
||||
decode_alpha[5] = (3*decode_alpha[0] + 4*decode_alpha[1]) / 7;
|
||||
decode_alpha[6] = (2*decode_alpha[0] + 5*decode_alpha[1]) / 7;
|
||||
decode_alpha[7] = (1*decode_alpha[0] + 6*decode_alpha[1]) / 7;
|
||||
} else
|
||||
{
|
||||
// 4 step intermediate, pluss full and none
|
||||
decode_alpha[2] = (4*decode_alpha[0] + 1*decode_alpha[1]) / 5;
|
||||
decode_alpha[3] = (3*decode_alpha[0] + 2*decode_alpha[1]) / 5;
|
||||
decode_alpha[4] = (2*decode_alpha[0] + 3*decode_alpha[1]) / 5;
|
||||
decode_alpha[5] = (1*decode_alpha[0] + 4*decode_alpha[1]) / 5;
|
||||
decode_alpha[6] = 0;
|
||||
decode_alpha[7] = 255;
|
||||
}
|
||||
for( i = 3; i < 16*4; i += 4 )
|
||||
{
|
||||
int idx = 0, bit;
|
||||
bit = (compressed[next_bit>>3] >> (next_bit&7)) & 1;
|
||||
idx += bit << 0;
|
||||
++next_bit;
|
||||
bit = (compressed[next_bit>>3] >> (next_bit&7)) & 1;
|
||||
idx += bit << 1;
|
||||
++next_bit;
|
||||
bit = (compressed[next_bit>>3] >> (next_bit&7)) & 1;
|
||||
idx += bit << 2;
|
||||
++next_bit;
|
||||
uncompressed[i] = decode_alpha[idx & 7];
|
||||
}
|
||||
// done
|
||||
}
|
||||
void stbi_decode_DXT_color_block(
|
||||
unsigned char uncompressed[16*4],
|
||||
unsigned char compressed[8] )
|
||||
{
|
||||
int next_bit = 4*8;
|
||||
int i, r, g, b;
|
||||
int c0, c1;
|
||||
unsigned char decode_colors[4*3];
|
||||
// find the 2 primary colors
|
||||
c0 = compressed[0] + (compressed[1] << 8);
|
||||
c1 = compressed[2] + (compressed[3] << 8);
|
||||
stbi_rgb_888_from_565( c0, &r, &g, &b );
|
||||
decode_colors[0] = r;
|
||||
decode_colors[1] = g;
|
||||
decode_colors[2] = b;
|
||||
stbi_rgb_888_from_565( c1, &r, &g, &b );
|
||||
decode_colors[3] = r;
|
||||
decode_colors[4] = g;
|
||||
decode_colors[5] = b;
|
||||
// Like DXT1, but no choicees:
|
||||
// no alpha, 2 interpolated colors
|
||||
decode_colors[6] = (2*decode_colors[0] + decode_colors[3]) / 3;
|
||||
decode_colors[7] = (2*decode_colors[1] + decode_colors[4]) / 3;
|
||||
decode_colors[8] = (2*decode_colors[2] + decode_colors[5]) / 3;
|
||||
decode_colors[9] = (decode_colors[0] + 2*decode_colors[3]) / 3;
|
||||
decode_colors[10] = (decode_colors[1] + 2*decode_colors[4]) / 3;
|
||||
decode_colors[11] = (decode_colors[2] + 2*decode_colors[5]) / 3;
|
||||
// decode the block
|
||||
for( i = 0; i < 16*4; i += 4 )
|
||||
{
|
||||
int idx = ((compressed[next_bit>>3] >> (next_bit & 7)) & 3) * 3;
|
||||
next_bit += 2;
|
||||
uncompressed[i+0] = decode_colors[idx+0];
|
||||
uncompressed[i+1] = decode_colors[idx+1];
|
||||
uncompressed[i+2] = decode_colors[idx+2];
|
||||
}
|
||||
// done
|
||||
}
|
||||
static stbi_uc *dds_load(stbi *s, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
// all variables go up front
|
||||
stbi_uc *dds_data = NULL;
|
||||
stbi_uc block[16*4];
|
||||
stbi_uc compressed[8];
|
||||
int flags, DXT_family;
|
||||
int has_alpha, has_mipmap;
|
||||
int is_compressed, cubemap_faces;
|
||||
int block_pitch, num_blocks;
|
||||
DDS_header header;
|
||||
int i, sz, cf;
|
||||
// load the header
|
||||
if( sizeof( DDS_header ) != 128 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
getn( s, (stbi_uc*)(&header), 128 );
|
||||
// and do some checking
|
||||
if( header.dwMagic != (('D' << 0) | ('D' << 8) | ('S' << 16) | (' ' << 24)) ) return NULL;
|
||||
if( header.dwSize != 124 ) return NULL;
|
||||
flags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
|
||||
if( (header.dwFlags & flags) != flags ) return NULL;
|
||||
/* According to the MSDN spec, the dwFlags should contain
|
||||
DDSD_LINEARSIZE if it's compressed, or DDSD_PITCH if
|
||||
uncompressed. Some DDS writers do not conform to the
|
||||
spec, so I need to make my reader more tolerant */
|
||||
if( header.sPixelFormat.dwSize != 32 ) return NULL;
|
||||
flags = DDPF_FOURCC | DDPF_RGB;
|
||||
if( (header.sPixelFormat.dwFlags & flags) == 0 ) return NULL;
|
||||
if( (header.sCaps.dwCaps1 & DDSCAPS_TEXTURE) == 0 ) return NULL;
|
||||
// get the image data
|
||||
s->img_x = header.dwWidth;
|
||||
s->img_y = header.dwHeight;
|
||||
s->img_n = 4;
|
||||
is_compressed = (header.sPixelFormat.dwFlags & DDPF_FOURCC) / DDPF_FOURCC;
|
||||
has_alpha = (header.sPixelFormat.dwFlags & DDPF_ALPHAPIXELS) / DDPF_ALPHAPIXELS;
|
||||
has_mipmap = (header.sCaps.dwCaps1 & DDSCAPS_MIPMAP) && (header.dwMipMapCount > 1);
|
||||
cubemap_faces = (header.sCaps.dwCaps2 & DDSCAPS2_CUBEMAP) / DDSCAPS2_CUBEMAP;
|
||||
/* I need cubemaps to have square faces */
|
||||
cubemap_faces &= (s->img_x == s->img_y);
|
||||
cubemap_faces *= 5;
|
||||
cubemap_faces += 1;
|
||||
block_pitch = (s->img_x+3) >> 2;
|
||||
num_blocks = block_pitch * ((s->img_y+3) >> 2);
|
||||
/* let the user know what's going on */
|
||||
*x = s->img_x;
|
||||
*y = s->img_y;
|
||||
*comp = s->img_n;
|
||||
/* is this uncompressed? */
|
||||
if( is_compressed )
|
||||
{
|
||||
/* compressed */
|
||||
// note: header.sPixelFormat.dwFourCC is something like (('D'<<0)|('X'<<8)|('T'<<16)|('1'<<24))
|
||||
DXT_family = 1 + (header.sPixelFormat.dwFourCC >> 24) - '1';
|
||||
if( (DXT_family < 1) || (DXT_family > 5) ) return NULL;
|
||||
/* check the expected size...oops, nevermind...
|
||||
those non-compliant writers leave
|
||||
dwPitchOrLinearSize == 0 */
|
||||
// passed all the tests, get the RAM for decoding
|
||||
sz = (s->img_x)*(s->img_y)*4*cubemap_faces;
|
||||
dds_data = (unsigned char*)malloc( sz );
|
||||
/* do this once for each face */
|
||||
for( cf = 0; cf < cubemap_faces; ++ cf )
|
||||
{
|
||||
// now read and decode all the blocks
|
||||
for( i = 0; i < num_blocks; ++i )
|
||||
{
|
||||
// where are we?
|
||||
int bx, by, bw=4, bh=4;
|
||||
int ref_x = 4 * (i % block_pitch);
|
||||
int ref_y = 4 * (i / block_pitch);
|
||||
// get the next block's worth of compressed data, and decompress it
|
||||
if( DXT_family == 1 )
|
||||
{
|
||||
// DXT1
|
||||
getn( s, compressed, 8 );
|
||||
stbi_decode_DXT1_block( block, compressed );
|
||||
} else if( DXT_family < 4 )
|
||||
{
|
||||
// DXT2/3
|
||||
getn( s, compressed, 8 );
|
||||
stbi_decode_DXT23_alpha_block ( block, compressed );
|
||||
getn( s, compressed, 8 );
|
||||
stbi_decode_DXT_color_block ( block, compressed );
|
||||
} else
|
||||
{
|
||||
// DXT4/5
|
||||
getn( s, compressed, 8 );
|
||||
stbi_decode_DXT45_alpha_block ( block, compressed );
|
||||
getn( s, compressed, 8 );
|
||||
stbi_decode_DXT_color_block ( block, compressed );
|
||||
}
|
||||
// is this a partial block?
|
||||
if( ref_x + 4 > s->img_x )
|
||||
{
|
||||
bw = s->img_x - ref_x;
|
||||
}
|
||||
if( ref_y + 4 > s->img_y )
|
||||
{
|
||||
bh = s->img_y - ref_y;
|
||||
}
|
||||
// now drop our decompressed data into the buffer
|
||||
for( by = 0; by < bh; ++by )
|
||||
{
|
||||
int idx = 4*((ref_y+by+cf*s->img_x)*s->img_x + ref_x);
|
||||
for( bx = 0; bx < bw*4; ++bx )
|
||||
{
|
||||
|
||||
dds_data[idx+bx] = block[by*16+bx];
|
||||
}
|
||||
}
|
||||
}
|
||||
/* done reading and decoding the main image...
|
||||
skip MIPmaps if present */
|
||||
if( has_mipmap )
|
||||
{
|
||||
int block_size = 16;
|
||||
if( DXT_family == 1 )
|
||||
{
|
||||
block_size = 8;
|
||||
}
|
||||
for( i = 1; i < header.dwMipMapCount; ++i )
|
||||
{
|
||||
int mx = s->img_x >> (i + 2);
|
||||
int my = s->img_y >> (i + 2);
|
||||
if( mx < 1 )
|
||||
{
|
||||
mx = 1;
|
||||
}
|
||||
if( my < 1 )
|
||||
{
|
||||
my = 1;
|
||||
}
|
||||
skip( s, mx*my*block_size );
|
||||
}
|
||||
}
|
||||
}/* per cubemap face */
|
||||
} else
|
||||
{
|
||||
/* uncompressed */
|
||||
DXT_family = 0;
|
||||
s->img_n = 3;
|
||||
if( has_alpha )
|
||||
{
|
||||
s->img_n = 4;
|
||||
}
|
||||
*comp = s->img_n;
|
||||
sz = s->img_x*s->img_y*s->img_n*cubemap_faces;
|
||||
dds_data = (unsigned char*)malloc( sz );
|
||||
/* do this once for each face */
|
||||
for( cf = 0; cf < cubemap_faces; ++ cf )
|
||||
{
|
||||
/* read the main image for this face */
|
||||
getn( s, &dds_data[cf*s->img_x*s->img_y*s->img_n], s->img_x*s->img_y*s->img_n );
|
||||
/* done reading and decoding the main image...
|
||||
skip MIPmaps if present */
|
||||
if( has_mipmap )
|
||||
{
|
||||
for( i = 1; i < header.dwMipMapCount; ++i )
|
||||
{
|
||||
int mx = s->img_x >> i;
|
||||
int my = s->img_y >> i;
|
||||
if( mx < 1 )
|
||||
{
|
||||
mx = 1;
|
||||
}
|
||||
if( my < 1 )
|
||||
{
|
||||
my = 1;
|
||||
}
|
||||
skip( s, mx*my*s->img_n );
|
||||
}
|
||||
}
|
||||
}
|
||||
/* data was BGR, I need it RGB */
|
||||
for( i = 0; i < sz; i += s->img_n )
|
||||
{
|
||||
unsigned char temp = dds_data[i];
|
||||
dds_data[i] = dds_data[i+2];
|
||||
dds_data[i+2] = temp;
|
||||
}
|
||||
}
|
||||
/* finished decompressing into RGBA,
|
||||
adjust the y size if we have a cubemap
|
||||
note: sz is already up to date */
|
||||
s->img_y *= cubemap_faces;
|
||||
*y = s->img_y;
|
||||
// did the user want something else, or
|
||||
// see if all the alpha values are 255 (i.e. no transparency)
|
||||
has_alpha = 0;
|
||||
if( s->img_n == 4)
|
||||
{
|
||||
for( i = 3; (i < sz) && (has_alpha == 0); i += 4 )
|
||||
{
|
||||
has_alpha |= (dds_data[i] < 255);
|
||||
}
|
||||
}
|
||||
if( (req_comp <= 4) && (req_comp >= 1) )
|
||||
{
|
||||
// user has some requirements, meet them
|
||||
if( req_comp != s->img_n )
|
||||
{
|
||||
dds_data = convert_format( dds_data, s->img_n, req_comp, s->img_x, s->img_y );
|
||||
*comp = s->img_n;
|
||||
}
|
||||
} else
|
||||
{
|
||||
// user had no requirements, only drop to RGB is no alpha
|
||||
if( (has_alpha == 0) && (s->img_n == 4) )
|
||||
{
|
||||
dds_data = convert_format( dds_data, 4, 3, s->img_x, s->img_y );
|
||||
*comp = 3;
|
||||
}
|
||||
}
|
||||
// OK, done
|
||||
return dds_data;
|
||||
}
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
stbi_uc *stbi_dds_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
stbi s;
|
||||
start_file(&s,f);
|
||||
return dds_load(&s,x,y,comp,req_comp);
|
||||
}
|
||||
|
||||
stbi_uc *stbi_dds_load (char *filename, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
stbi_uc *data;
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if (!f) return NULL;
|
||||
data = stbi_dds_load_from_file(f,x,y,comp,req_comp);
|
||||
fclose(f);
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
stbi_uc *stbi_dds_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
stbi s;
|
||||
start_mem(&s,buffer, len);
|
||||
return dds_load(&s,x,y,comp,req_comp);
|
||||
}
|
102
cw 5/src/Shader_Loader.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "Shader_Loader.h"
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<vector>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
Shader_Loader::Shader_Loader(void){}
|
||||
Shader_Loader::~Shader_Loader(void){}
|
||||
|
||||
std::string Shader_Loader::ReadShader(char *filename)
|
||||
{
|
||||
|
||||
std::string shaderCode;
|
||||
std::ifstream file(filename, std::ios::in);
|
||||
|
||||
if (!file.good())
|
||||
{
|
||||
std::cout << "Can't read file " << filename << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
shaderCode.resize((unsigned int)file.tellg());
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read(&shaderCode[0], shaderCode.size());
|
||||
file.close();
|
||||
return shaderCode;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateShader(GLenum shaderType, std::string
|
||||
source, char* shaderName)
|
||||
{
|
||||
|
||||
int compile_result = 0;
|
||||
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
const char *shader_code_ptr = source.c_str();
|
||||
const int shader_code_size = source.size();
|
||||
|
||||
glShaderSource(shader, 1, &shader_code_ptr, &shader_code_size);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_result);
|
||||
|
||||
//sprawdz bledy
|
||||
if (compile_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> shader_log(info_log_length);
|
||||
glGetShaderInfoLog(shader, info_log_length, NULL, &shader_log[0]);
|
||||
std::cout << "ERROR compiling shader: " << shaderName << std::endl << &shader_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateProgram(char* vertexShaderFilename,
|
||||
char* fragmentShaderFilename)
|
||||
{
|
||||
|
||||
//wczytaj shadery
|
||||
std::string vertex_shader_code = ReadShader(vertexShaderFilename);
|
||||
std::string fragment_shader_code = ReadShader(fragmentShaderFilename);
|
||||
|
||||
GLuint vertex_shader = CreateShader(GL_VERTEX_SHADER, vertex_shader_code, "vertex shader");
|
||||
GLuint fragment_shader = CreateShader(GL_FRAGMENT_SHADER, fragment_shader_code, "fragment shader");
|
||||
|
||||
int link_result = 0;
|
||||
//stworz shader
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &link_result);
|
||||
//sprawdz bledy w linkerze
|
||||
if (link_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> program_log(info_log_length);
|
||||
glGetProgramInfoLog(program, info_log_length, NULL, &program_log[0]);
|
||||
std::cout << "Shader Loader : LINK ERROR" << std::endl << &program_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glDetachShader(program, vertex_shader);
|
||||
glDetachShader(program, fragment_shader);
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void Shader_Loader::DeleteProgram( GLuint program )
|
||||
{
|
||||
glDeleteProgram(program);
|
||||
}
|
29
cw 5/src/Shader_Loader.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
||||
class Shader_Loader
|
||||
{
|
||||
private:
|
||||
|
||||
std::string ReadShader(char *filename);
|
||||
GLuint CreateShader(GLenum shaderType,
|
||||
std::string source,
|
||||
char* shaderName);
|
||||
|
||||
public:
|
||||
|
||||
Shader_Loader(void);
|
||||
~Shader_Loader(void);
|
||||
GLuint CreateProgram(char* VertexShaderFilename,
|
||||
char* FragmentShaderFilename);
|
||||
|
||||
void DeleteProgram(GLuint program);
|
||||
|
||||
};
|
||||
}
|
267
cw 5/src/ex_5_1.hpp
Normal file
@ -0,0 +1,267 @@
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
#include "Camera.h"
|
||||
|
||||
#include "Box.cpp"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
GLuint program;
|
||||
|
||||
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
Core::RenderContext shipContext;
|
||||
Core::RenderContext sphereContext;
|
||||
|
||||
glm::vec3 cameraPos = glm::vec3(-4.f, 0, 0);
|
||||
glm::vec3 cameraDir = glm::vec3(1.f, 0.f, 0.f);
|
||||
glm::vec3 lightColor = glm::vec3(1.f, 1.f, 1.f);
|
||||
glm::vec3 lightDir = glm::vec3(0.5, 0.5, 0.5);
|
||||
|
||||
glm::vec3 spaceshipPos = glm::vec3(-4.f, 0, 0);
|
||||
glm::vec3 spaceshipDir = glm::vec3(1.f, 0.f, 0.f);
|
||||
GLuint VAO,VBO;
|
||||
|
||||
float aspectRatio = 1.f;
|
||||
|
||||
float lastTime = -1.f;
|
||||
float deltaTime = 0.f;
|
||||
|
||||
float exposition = 5.0f;
|
||||
|
||||
GLuint programSun;
|
||||
|
||||
void updateDeltaTime(float time) {
|
||||
if (lastTime < 0) {
|
||||
lastTime = time;
|
||||
return;
|
||||
}
|
||||
|
||||
deltaTime = time - lastTime;
|
||||
if (deltaTime > 0.1) deltaTime = 0.1;
|
||||
lastTime = time;
|
||||
}
|
||||
|
||||
glm::mat4 createCameraMatrix()
|
||||
{
|
||||
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 cameraRotrationMatrix = glm::mat4({
|
||||
cameraSide.x,cameraSide.y,cameraSide.z,0,
|
||||
cameraUp.x,cameraUp.y,cameraUp.z ,0,
|
||||
-cameraDir.x,-cameraDir.y,-cameraDir.z,0,
|
||||
0.,0.,0.,1.,
|
||||
});
|
||||
cameraRotrationMatrix = glm::transpose(cameraRotrationMatrix);
|
||||
glm::mat4 cameraMatrix = cameraRotrationMatrix * glm::translate(-cameraPos);
|
||||
|
||||
return cameraMatrix;
|
||||
}
|
||||
|
||||
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);
|
||||
perspectiveMatrix = glm::mat4({
|
||||
1,0.,0.,0.,
|
||||
0.,aspectRatio,0.,0.,
|
||||
0.,0.,(f+n) / (n - f),2*f * n / (n - f),
|
||||
0.,0.,-1.,0.,
|
||||
});
|
||||
|
||||
|
||||
perspectiveMatrix=glm::transpose(perspectiveMatrix);
|
||||
|
||||
return perspectiveMatrix;
|
||||
}
|
||||
|
||||
void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color, GLuint program) {
|
||||
glUseProgram(program);
|
||||
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
||||
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
glUniform3f(glGetUniformLocation(program, "color"), color.x,color.y,color.z);
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
||||
|
||||
glm::vec3 lightDir = glm::normalize(glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
glm::vec3 lightColor = glm::vec3(0.0f, 1.0f, 1.0f);
|
||||
|
||||
glUniform3fv(glGetUniformLocation(program, "lightDir"), 1, glm::value_ptr(lightDir));
|
||||
glUniform3fv(glGetUniformLocation(program, "lightColor"), 1, glm::value_ptr(lightColor));
|
||||
|
||||
glUniform3fv(glGetUniformLocation(program, "cameraPos"), 1, glm::value_ptr(cameraPos));
|
||||
|
||||
glUniform1f(glGetUniformLocation(program, "exposition"), exposition);
|
||||
|
||||
Core::DrawContext(context);
|
||||
glUseProgram(0);
|
||||
|
||||
}
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glm::mat4 transformation;
|
||||
float time = glfwGetTime();
|
||||
updateDeltaTime(time);
|
||||
|
||||
|
||||
//Uniform3fv(glGetUniformLocation(program, "lightDir"), 1, glm::value_ptr(lightDir));
|
||||
//glUniform3fv(glGetUniformLocation(program, "lightColor"), 1, glm::value_ptr(lightColor));
|
||||
|
||||
|
||||
|
||||
glm::vec3 sunPosition = glm::vec3(0.0, 0.0, 0.0);
|
||||
glm::mat4 sunModelMatrix = glm::translate(glm::vec3(1.0f, 1.0f, 0.3f));
|
||||
drawObjectColor(sphereContext, sunModelMatrix, glm::vec3(1.0, 1.0, 0.3), programSun);
|
||||
|
||||
glUniform3fv(glGetUniformLocation(program, "lightPos"), 1, glm::value_ptr(sunPosition));
|
||||
|
||||
drawObjectColor(sphereContext, glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::scale(glm::vec3(0.3f)), glm::vec3(0.2, 0.7, 0.3), program);
|
||||
|
||||
drawObjectColor(sphereContext,
|
||||
glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)),
|
||||
glm::vec3(0.5, 0.5, 0.5), program);
|
||||
|
||||
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
|
||||
glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir));
|
||||
glm::mat4 specshipCameraRotrationMatrix = glm::mat4({
|
||||
spaceshipSide.x,spaceshipSide.y,spaceshipSide.z,0,
|
||||
spaceshipUp.x,spaceshipUp.y,spaceshipUp.z ,0,
|
||||
-spaceshipDir.x,-spaceshipDir.y,-spaceshipDir.z,0,
|
||||
0.,0.,0.,1.,
|
||||
});
|
||||
|
||||
|
||||
//drawObjectColor(shipContext,
|
||||
// glm::translate(cameraPos + 1.5 * cameraDir + cameraUp * -0.5f) * inveseCameraRotrationMatrix * glm::eulerAngleY(glm::pi<float>()),
|
||||
// glm::vec3(0.3, 0.3, 0.5)
|
||||
// );
|
||||
drawObjectColor(shipContext,
|
||||
glm::translate(spaceshipPos) * specshipCameraRotrationMatrix * glm::eulerAngleY(glm::pi<float>()) * glm::scale(glm::vec3(0.2f)),
|
||||
glm::vec3(0.3, 0.3, 0.5),
|
||||
program
|
||||
);
|
||||
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
aspectRatio = width / float(height);
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
void loadModelToContext(std::string path, Core::RenderContext& context)
|
||||
{
|
||||
Assimp::Importer import;
|
||||
const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_CalcTangentSpace);
|
||||
|
||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
{
|
||||
std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << std::endl;
|
||||
return;
|
||||
}
|
||||
context.initFromAssimpMesh(scene->mMeshes[0]);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
programSun = shaderLoader.CreateProgram("shaders/shader_5_sun.vert", "shaders/shader_5_sun.frag");
|
||||
|
||||
loadModelToContext("./models/sphere.obj", sphereContext);
|
||||
loadModelToContext("./models/spaceship.obj", shipContext);
|
||||
|
||||
|
||||
// Ustaw wartości dla lightDir i lightColor potem prześlij do shadera
|
||||
//glm::vec3 lightDir = glm::normalize(glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
//glm::vec3 lightColor = glm::vec3(0.0f, 1.0f, 1.0f);
|
||||
|
||||
//glUseProgram(program);
|
||||
//glUniform3fv(glGetUniformLocation(program, "lightDir"), 1, glm::value_ptr(lightDir));
|
||||
//glUniform3fv(glGetUniformLocation(program, "lightColor"), 1, glm::value_ptr(lightColor));
|
||||
//glUseProgram(0);
|
||||
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
|
||||
glm::vec3 spaceshipUp = glm::vec3(0.f, 1.f, 0.f);
|
||||
float angleSpeed = 0.05f * deltaTime * 60;
|
||||
float moveSpeed = 0.05f * deltaTime * 60;
|
||||
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
|
||||
angleSpeed *= 3;
|
||||
moveSpeed *= 3;
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
spaceshipPos += spaceshipDir * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||
spaceshipPos -= spaceshipDir * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS)
|
||||
spaceshipPos += spaceshipSide * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS)
|
||||
spaceshipPos -= spaceshipSide * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
|
||||
spaceshipPos += spaceshipUp * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
|
||||
spaceshipPos -= spaceshipUp * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||
spaceshipDir = glm::vec3(glm::eulerAngleY(angleSpeed) * glm::vec4(spaceshipDir, 0));
|
||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
spaceshipDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(spaceshipDir, 0));
|
||||
|
||||
if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS)
|
||||
exposition += 0.1;
|
||||
if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS)
|
||||
exposition -= 0.1;
|
||||
|
||||
|
||||
cameraPos = spaceshipPos - 0.3f * spaceshipDir + glm::vec3(0, 1, 0) * 0.1f;
|
||||
cameraDir = spaceshipDir;
|
||||
|
||||
//cameraDir = glm::normalize(-cameraPos);
|
||||
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
47
cw 5/src/main.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "glew.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "ex_5_1.hpp"
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// inicjalizacja glfw
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
#endif
|
||||
|
||||
// tworzenie okna za pomoca glfw
|
||||
GLFWwindow* window = glfwCreateWindow(500, 500, "FirstWindow", NULL, NULL);
|
||||
if (window == NULL)
|
||||
{
|
||||
std::cout << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
// ladowanie OpenGL za pomoca glew
|
||||
glewInit();
|
||||
glViewport(0, 0, 500, 500);
|
||||
|
||||
init(window);
|
||||
|
||||
// uruchomienie glownej petli
|
||||
renderLoop(window);
|
||||
|
||||
shutdown(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
291
cw 5/src/objload.h
Normal file
@ -0,0 +1,291 @@
|
||||
/* Copyright (c) 2012, Gerhard Reitmayr
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#ifndef OBJLOAD_H_
|
||||
#define OBJLOAD_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace obj {
|
||||
|
||||
struct Model {
|
||||
std::vector<float> vertex; //< 3 * N entries
|
||||
std::vector<float> texCoord; //< 2 * N entries
|
||||
std::vector<float> normal; //< 3 * N entries
|
||||
|
||||
std::map<std::string, std::vector<unsigned short> > faces; //< assume triangels and uniform indexing
|
||||
};
|
||||
|
||||
struct ObjModel {
|
||||
struct FaceVertex {
|
||||
FaceVertex() : v(-1), t(-1), n(-1) {}
|
||||
int v, t, n;
|
||||
|
||||
bool operator<( const FaceVertex & other ) const;
|
||||
bool operator==( const FaceVertex & other ) const;
|
||||
};
|
||||
|
||||
typedef std::pair<std::vector<FaceVertex>, std::vector<unsigned> > FaceList;
|
||||
|
||||
std::vector<float> vertex; //< 3 * N entries
|
||||
std::vector<float> texCoord; //< 2 * N entries
|
||||
std::vector<float> normal; //< 3 * N entries
|
||||
|
||||
std::map<std::string, FaceList > faces;
|
||||
};
|
||||
|
||||
inline ObjModel parseObjModel( std::istream & in);
|
||||
inline void tesselateObjModel( ObjModel & obj);
|
||||
inline ObjModel tesselateObjModel( const ObjModel & obj );
|
||||
inline Model convertToModel( const ObjModel & obj );
|
||||
|
||||
inline Model loadModel( std::istream & in );
|
||||
inline Model loadModelFromString( const std::string & in );
|
||||
inline Model loadModelFromFile( const std::string & in );
|
||||
|
||||
inline std::ostream & operator<<( std::ostream & out, const Model & m );
|
||||
inline std::ostream & operator<<( std::ostream & out, const ObjModel::FaceVertex & f);
|
||||
|
||||
// ---------------------------- Implementation starts here -----------------------
|
||||
|
||||
inline bool ObjModel::FaceVertex::operator<( const ObjModel::FaceVertex & other ) const {
|
||||
return (v < other.v) || (v == other.v && t < other.t ) || (v == other.v && t == other.t && n < other.n);
|
||||
}
|
||||
|
||||
inline bool ObjModel::FaceVertex::operator==( const ObjModel::FaceVertex & other ) const {
|
||||
return (v == other.v && t == other.t && n == other.n);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::istream & operator>>(std::istream & in, std::vector<T> & vec ){
|
||||
T temp;
|
||||
if(in >> temp)
|
||||
vec.push_back(temp);
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::istream & operator>>(std::istream & in, std::set<T> & vec ){
|
||||
T temp;
|
||||
if(in >> temp)
|
||||
vec.insert(temp);
|
||||
return in;
|
||||
}
|
||||
|
||||
inline std::istream & operator>>( std::istream & in, ObjModel::FaceVertex & f){
|
||||
if(in >> f.v){
|
||||
if(in.peek() == '/'){
|
||||
in.get();
|
||||
in >> f.t;
|
||||
in.clear();
|
||||
if(in.peek() == '/'){
|
||||
in.get();
|
||||
in >> f.n;
|
||||
in.clear();
|
||||
}
|
||||
}
|
||||
in.clear();
|
||||
--f.v;
|
||||
--f.t;
|
||||
--f.n;
|
||||
}
|
||||
// std::cout << f << std::endl;
|
||||
return in;
|
||||
}
|
||||
|
||||
ObjModel parseObjModel( std::istream & in ){
|
||||
char line[1024];
|
||||
std::string op;
|
||||
std::istringstream line_in;
|
||||
std::set<std::string> groups;
|
||||
groups.insert("default");
|
||||
|
||||
ObjModel data;
|
||||
|
||||
while(in.good()){
|
||||
in.getline(line, 1023);
|
||||
line_in.clear();
|
||||
line_in.str(line);
|
||||
|
||||
if(!(line_in >> op))
|
||||
continue;
|
||||
if(op == "v")
|
||||
line_in >> data.vertex >> data.vertex >> data.vertex;
|
||||
else if(op == "vt")
|
||||
line_in >> data.texCoord >> data.texCoord >> data.texCoord;
|
||||
else if(op == "vn")
|
||||
line_in >> data.normal >> data.normal >> data.normal;
|
||||
else if(op == "g"){
|
||||
groups.clear();
|
||||
while(line_in >> groups) ;
|
||||
groups.insert("default");
|
||||
}
|
||||
else if(op == "f") {
|
||||
std::vector<ObjModel::FaceVertex> list;
|
||||
while(line_in >> list) ;
|
||||
|
||||
for(std::set<std::string>::const_iterator g = groups.begin(); g != groups.end(); ++g){
|
||||
ObjModel::FaceList & fl = data.faces[*g];
|
||||
fl.second.push_back(fl.first.size());
|
||||
fl.first.insert(fl.first.end(), list.begin(), list.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
for(std::map<std::string, ObjModel::FaceList>::iterator g = data.faces.begin(); g != data.faces.end(); ++g){
|
||||
ObjModel::FaceList & fl = g->second;
|
||||
fl.second.push_back(fl.first.size());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
inline void tesselateObjModel( std::vector<ObjModel::FaceVertex> & input, std::vector<unsigned> & input_start){
|
||||
std::vector<ObjModel::FaceVertex> output;
|
||||
std::vector<unsigned> output_start;
|
||||
output.reserve(input.size());
|
||||
output_start.reserve(input_start.size());
|
||||
|
||||
for(std::vector<unsigned>::const_iterator s = input_start.begin(); s != input_start.end() - 1; ++s){
|
||||
const unsigned size = *(s+1) - *s;
|
||||
if(size > 3){
|
||||
const ObjModel::FaceVertex & start_vertex = input[*s];
|
||||
for( int i = 1; i < (int)size-1; ++i){
|
||||
output_start.push_back(output.size());
|
||||
output.push_back(start_vertex);
|
||||
output.push_back(input[*s+i]);
|
||||
output.push_back(input[*s+i+1]);
|
||||
}
|
||||
} else {
|
||||
output_start.push_back(output.size());
|
||||
output.insert(output.end(), input.begin() + *s, input.begin() + *(s+1));
|
||||
}
|
||||
}
|
||||
output_start.push_back(output.size());
|
||||
input.swap(output);
|
||||
input_start.swap(output_start);
|
||||
}
|
||||
|
||||
void tesselateObjModel( ObjModel & obj){
|
||||
for(std::map<std::string, ObjModel::FaceList>::iterator g = obj.faces.begin(); g != obj.faces.end(); ++g){
|
||||
ObjModel::FaceList & fl = g->second;
|
||||
tesselateObjModel(fl.first, fl.second);
|
||||
}
|
||||
}
|
||||
|
||||
Model convertToModel( const ObjModel & obj ) {
|
||||
// insert all face vertices into a vector and make unique
|
||||
std::vector<ObjModel::FaceVertex> unique(obj.faces.find("default")->second.first);
|
||||
std::sort(unique.begin(), unique.end());
|
||||
unique.erase( std::unique(unique.begin(), unique.end()), unique.end());
|
||||
|
||||
// build a new model with repeated vertices/texcoords/normals to have single indexing
|
||||
Model model;
|
||||
for(std::vector<ObjModel::FaceVertex>::const_iterator f = unique.begin(); f != unique.end(); ++f){
|
||||
model.vertex.insert(model.vertex.end(), obj.vertex.begin() + 3*f->v, obj.vertex.begin() + 3*f->v + 3);
|
||||
if(!obj.texCoord.empty()){
|
||||
const int index = (f->t > -1) ? f->t : f->v;
|
||||
model.texCoord.insert(model.texCoord.end(), obj.texCoord.begin() + 2*index, obj.texCoord.begin() + 2*index + 2);
|
||||
}
|
||||
if(!obj.normal.empty()){
|
||||
const int index = (f->n > -1) ? f->n : f->v;
|
||||
model.normal.insert(model.normal.end(), obj.normal.begin() + 3*index, obj.normal.begin() + 3*index + 3);
|
||||
}
|
||||
}
|
||||
// look up unique index and transform face descriptions
|
||||
for(std::map<std::string, ObjModel::FaceList>::const_iterator g = obj.faces.begin(); g != obj.faces.end(); ++g){
|
||||
const std::string & name = g->first;
|
||||
const ObjModel::FaceList & fl = g->second;
|
||||
std::vector<unsigned short> & v = model.faces[g->first];
|
||||
v.reserve(fl.first.size());
|
||||
for(std::vector<ObjModel::FaceVertex>::const_iterator f = fl.first.begin(); f != fl.first.end(); ++f){
|
||||
const unsigned short index = std::distance(unique.begin(), std::lower_bound(unique.begin(), unique.end(), *f));
|
||||
v.push_back(index);
|
||||
}
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
ObjModel tesselateObjModel( const ObjModel & obj ){
|
||||
ObjModel result = obj;
|
||||
tesselateObjModel(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Model loadModel( std::istream & in ){
|
||||
ObjModel model = parseObjModel(in);
|
||||
tesselateObjModel(model);
|
||||
return convertToModel(model);
|
||||
}
|
||||
|
||||
Model loadModelFromString( const std::string & str ){
|
||||
std::istringstream in(str);
|
||||
return loadModel(in);
|
||||
}
|
||||
|
||||
Model loadModelFromFile( const std::string & str) {
|
||||
std::ifstream in(str.c_str());
|
||||
return loadModel(in);
|
||||
}
|
||||
|
||||
inline std::ostream & operator<<( std::ostream & out, const ObjModel::FaceVertex & f){
|
||||
out << f.v << "\t" << f.t << "\t" << f.n;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream & operator<<( std::ostream & out, const Model & m ){
|
||||
if(!m.vertex.empty()){
|
||||
out << "vertex\n";
|
||||
for(int i = 0; i < (int)m.vertex.size(); ++i)
|
||||
out << m.vertex[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
if(!m.texCoord.empty()){
|
||||
out << "texCoord\n";
|
||||
for(int i = 0; i < (int)m.texCoord.size(); ++i)
|
||||
out << m.texCoord[i] << (((i % 2) == 1)?"\n":"\t");
|
||||
}
|
||||
if(!m.normal.empty()){
|
||||
out << "normal\n";
|
||||
for(int i = 0; i < (int)m.normal.size(); ++i)
|
||||
out << m.normal[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
if(!m.faces.empty()){
|
||||
out << "faces\t";
|
||||
for(std::map<std::string, std::vector<unsigned short> >::const_iterator g = m.faces.begin(); g != m.faces.end(); ++g){
|
||||
out << g->first << " ";
|
||||
}
|
||||
out << "\n";
|
||||
// for(int i = 0; i < m.face.size(); ++i)
|
||||
// out << m.face[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace obj
|
||||
|
||||
#endif // OBJLOAD_H_
|
107
cw 5/style.css
Normal file
@ -0,0 +1,107 @@
|
||||
html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
|
||||
|
||||
body{
|
||||
color:#444;
|
||||
font-family:Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif;
|
||||
font-size:12px;
|
||||
line-height:1.5em;
|
||||
padding:1em;
|
||||
margin:auto;
|
||||
max-width:42em;
|
||||
background:#fefefe;
|
||||
}
|
||||
|
||||
a{ color: #0645ad; text-decoration:none;}
|
||||
a:visited{ color: #0b0080; }
|
||||
a:hover{ color: #06e; }
|
||||
a:active{ color:#faa700; }
|
||||
a:focus{ outline: thin dotted; }
|
||||
a:hover, a:active{ outline: 0; }
|
||||
|
||||
::-moz-selection{background:rgba(255,255,0,0.3);color:#000}
|
||||
::selection{background:rgba(255,255,0,0.3);color:#000}
|
||||
|
||||
a::-moz-selection{background:rgba(255,255,0,0.3);color:#0645ad}
|
||||
a::selection{background:rgba(255,255,0,0.3);color:#0645ad}
|
||||
|
||||
p{
|
||||
margin:1em 0;
|
||||
}
|
||||
|
||||
img{
|
||||
max-width:100%;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6{
|
||||
font-weight:normal;
|
||||
color:#111;
|
||||
line-height:1em;
|
||||
}
|
||||
h4,h5,h6{ font-weight: bold; }
|
||||
h1{ font-size:2.5em; }
|
||||
h2{ font-size:2em; }
|
||||
h3{ font-size:1.5em; }
|
||||
h4{ font-size:1.2em; }
|
||||
h5{ font-size:1em; }
|
||||
h6{ font-size:0.9em; }
|
||||
|
||||
blockquote{
|
||||
color:#666666;
|
||||
margin:0;
|
||||
padding-left: 3em;
|
||||
border-left: 0.5em #EEE solid;
|
||||
}
|
||||
hr { display: block; height: 2px; border: 0; border-top: 1px solid #aaa;border-bottom: 1px solid #eee; margin: 1em 0; padding: 0; }
|
||||
pre, code, kbd, samp { color: #000; font-family: monospace, monospace; _font-family: 'courier new', monospace; font-size: 0.98em; }
|
||||
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
|
||||
|
||||
b, strong { font-weight: bold; }
|
||||
|
||||
dfn { font-style: italic; }
|
||||
|
||||
ins { background: #ff9; color: #000; text-decoration: none; }
|
||||
|
||||
mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
|
||||
|
||||
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
|
||||
sup { top: -0.5em; }
|
||||
sub { bottom: -0.25em; }
|
||||
|
||||
ul, ol { margin: 1em 0; padding: 0 0 0 2em; }
|
||||
li p:last-child { margin:0 }
|
||||
dd { margin: 0 0 0 2em; }
|
||||
|
||||
img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
}
|
||||
th { border-bottom: 1px solid black; }
|
||||
td { vertical-align: top; }
|
||||
|
||||
@media only screen and (min-width: 480px) {
|
||||
body{font-size:14px;}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
body{font-size:16px;}
|
||||
}
|
||||
|
||||
@media print {
|
||||
* { background: transparent !important; color: black !important; filter:none !important; -ms-filter: none !important; }
|
||||
body{font-size:12pt; max-width:100%;}
|
||||
a, a:visited { text-decoration: underline; }
|
||||
hr { height: 1px; border:0; border-bottom:1px solid black; }
|
||||
a[href]:after { content: " (" attr(href) ")"; }
|
||||
abbr[title]:after { content: " (" attr(title) ")"; }
|
||||
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
|
||||
pre, blockquote { border: 1px solid #999; padding-right: 1em; page-break-inside: avoid; }
|
||||
tr, img { page-break-inside: avoid; }
|
||||
img { max-width: 100% !important; }
|
||||
@page :left { margin: 15mm 20mm 15mm 10mm; }
|
||||
@page :right { margin: 15mm 10mm 15mm 20mm; }
|
||||
p, h2, h3 { orphans: 3; widows: 3; }
|
||||
h2, h3 { page-break-after: avoid; }
|
||||
}
|
116
cw 5/zadania 5.html
Normal file
@ -0,0 +1,116 @@
|
||||
<!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 5</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>
|
||||
<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="oświetlenie-phonga">Oświetlenie Phonga</h2>
|
||||
<p>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 <code>ex_5_1.hpp</code> kod z poprzednich zajęć. W przeciwnym wypadku wykorzystaj ten, który jest zaimplementowany w <code>ex_5_1.hpp</code>. W zadaniu będzie nam potrzebny statek latający przed kamerą, jak nie ma tego w Twojej scenie to skopiuj to z <code>ex_5_1.hpp</code>.</p>
|
||||
<h2 id="zadanie---diffuse">Zadanie - <em>diffuse</em></h2>
|
||||
<p>Oblicz we fragment shaderze oświetlenie obiektu przy użyciu modelu Phonga dla odbicia rozproszonego (*diffuse)</p>
|
||||
<p> 1. Przekaż źródło światła. Na razie przyjmiemy kierunkowy model oświetlenia, dlatego źródło będzie opisane jako wektor kierunkowy:</p>
|
||||
<ul>
|
||||
<li><p>Prześlij do shadera fragmentów zmienna typu <code>uniform vec3</code> (nazwij ją np. <code>lightDir</code>), w której będzie się znajdować wektor kierunkowy.</p></li>
|
||||
<li><p>Należy to zrobić podobnie do tego, jak przesyłany jest kolor.</p></li>
|
||||
<li><p>Jako kierunek światła wybierz dowolny wektor jednostkowy. (Możesz wziąć dowolny niezerowy wektor następnie go znormalizować).</p></li>
|
||||
<li><p>Dodatkowo prześlij drugą zmienną <code>uniform vec3 lightColor</code>, w której umieścimy kolor światła. Prześlij tam wartości ze zmiennej <code>glm::vec3 lightColor</code>.</p></li>
|
||||
</ul>
|
||||
<ol start="2" type="1">
|
||||
<li>Oblicz natężenie w shaderze fragmentów:</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li><p>prześlij normalne z shadera fragmentów do shadera wierzchołków</p></li>
|
||||
<li><p>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).</p></li>
|
||||
<li><p>Natężenie to iloczyn skalarny wektora normalnego powierzchni i odwrotnego wektora kierunku padania światła. Skorzystaj z funkcji <code>dot</code>.</p></li>
|
||||
<li><p>Natężenie nie może być ujemne. Przytnij natężenie do zera przy użyciu: <code>x = max(x, 0.0)</code></p></li>
|
||||
</ul>
|
||||
<ol start="3" type="1">
|
||||
<li>Zastosuj obliczone natężenie, aby zmodyfikować kolor obiektu:</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li>Przemnóż kolor RGB fragmentu przez obliczone natężenie i przez kolor światła z <code>lightColor</code>.</li>
|
||||
</ul>
|
||||
<h2 id="zadanie---obsługa-obrotów">Zadanie - obsługa obrotów</h2>
|
||||
<p>Dlaczego oświetlenie statku nie zmienia się podczas jego obracania?</p>
|
||||
<p>(Wektory normalne są w układzie lokalnym modelu, a wektor padania światła w układzie świata)</p>
|
||||
<p>Należy wykonać transformacje wektorów normalnych do przestrzeni świata: - Prześlij macierz modelu rysowanego obiektu (<em>model Matrix</em>) jako osobna zmienna do vertex shadera (<code>uniform mat4</code>).<br />
|
||||
- Przemnóż przez te macierz wektor normalny wierzchołka przed przesłaniem go do shadera fragmentów. - Współrzędna <strong>w</strong> 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.</p>
|
||||
<h2 id="zadanie---specular">Zadanie - <em>specular</em></h2>
|
||||
<p>Uzupełnił model o czynnik odbicia zwierciadlanego (<em>specular</em>). W tym celu:</p>
|
||||
<ol type="1">
|
||||
<li>Potrzebny będzie wektor od rysowanego fragmentu do pozycji kamery:</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li>Wyślij pozycje kamery (<code>cameraPos</code>) jako kolejna zmienna do fragment shadera.<br />
|
||||
</li>
|
||||
<li>Podobnie jak wektory normalne prześlij z vertex do fragment shadera pozycje wierzchołków (<code>vertexPosition</code>) w przestrzeni świata (czyli pomnożone przez macierz <strong>modelMatrix</strong>). Pamiętaj, że tym razem wektory reprezentują punkty, a nie kierunki - współrzędna <strong>w</strong> przed mnożeniem musi być ustawiona na 1. W wyniku rasteryzacji otrzymamy w shaderze fragmentu jego pozycję (nazywaną pozycją fragmentu)</li>
|
||||
<li>Oblicz wektor <strong>V</strong> (<em>view direction</em>) jako znormalizowaną różnice pozycji kamery i pozycji fragmentu.</li>
|
||||
</ul>
|
||||
<ol start="2" type="1">
|
||||
<li>Oblicz natężenie światła odbitego we <em>fragment shaderze</em>:</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li>Oblicz wektor kierunku odbicia światła <strong>R</strong> przy użyciu funkcji <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/reflect.xhtml"><code>reflect</code></a>. Pamiętaj, żeby przesłać do funkcji odwrócony wektor kierunku światła.</li>
|
||||
<li>Oblicz natężenie: iloczyn skalarny <strong>V</strong> i <strong>R</strong>, przycięty do zera ( <code>max(...,0.0)</code> ), a następnie podniesiony do wysokiej potęgi (np. 8, 50, 1000), która jest miara połyskliwości powierzchni.</li>
|
||||
</ul>
|
||||
<ol start="3" type="1">
|
||||
<li>Ustal ostateczny kolor piksela na <code>objectColor * diffuse + lightColor * specular</code>. Oznacza to najprostszy przypadek, gdy kolor światła odbitego jest biały.</li>
|
||||
</ol>
|
||||
<h2 id="zadanie---oświetlenie-punktowe">Zadanie - oświetlenie punktowe</h2>
|
||||
<p>W układzie planetarnym obiektem oświetlającym powinno być słońce, dlatego zamień oświetlenie kierunkowe na punktowe:</p>
|
||||
<ul>
|
||||
<li>Zamiast przesyłać (w <code>lightDir</code>) 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 <code>lightPos</code>).</li>
|
||||
<li>Oblicz kierunek światła odejmując od pozycji światła pozycję fragmentu, znormalizuj wynik. Zapisz wynik w zmiennej <code>lightDir</code>.<br />
|
||||
</li>
|
||||
<li>Słońce będzie czarne, nie martw się tym, tylko spójrz na punkt następny.</li>
|
||||
</ul>
|
||||
<h2 id="zadanie---shader-słońca">Zadanie - shader słońca</h2>
|
||||
<p>Ź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.</p>
|
||||
<p>Celem tego zadania jest stworzenie shadera (<strong>shader_5_sun.vert</strong>_ i <strong>shader_5_sun.frag</strong>), który będzie odpowiadał wyłącznie za rysowanie słońca. Poprzednie shadery (<strong>shader_4_1.vert</strong>_ i <strong>shader_5_1.frag</strong>) nadal mają rysować pozostałe obiekty. a) zainicjalizuj <em>program</em> (shadery): - Pliki <strong>shader_5_sun.vert</strong> i <strong>shader_5_sun.frag</strong> są identyczne z 5_1** przed zmianami, będą punktem wyjścia dla <em>shadera</em> słońca.</p>
|
||||
<ol type="1">
|
||||
<li><p>Utwórz zmienną globalną <code>GLuint programSun</code> na adres shadera słońca. Stwórz <em>program</em> za pomocą <code>shaderLoader.CreateProgram</code> analogicznie jak tworzy się <code>program</code> z <strong>shader_5_1.vert</strong> i <strong>shader_5_1.frag</strong> (parametry wejściowe to ścieżka do shadera wierzchołków i fragmentów <strong>shader_5_sun.vert</strong> i <strong>shader_5_sun.frag</strong>).</p></li>
|
||||
<li><p>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 <em>program</em> (shadery) do rysowania słońca:</p></li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li>funkcja <code>drawObject</code> korzysta z globalnej zmiennej <code>program</code>, żeby wskazywać shadery do rysowania. Dodaj argument do funkcji, który będziesz przekazywać adres <em>programu</em>, który ma być wykorzystany do rysowania.</li>
|
||||
<li>dodaj odpowiedni <em>program</em> w wywołaniach <code>drawObject</code>.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="zadanie---osłabienie-światła-attenuation"> Zadanie - Zmień shader słońca na bardziej realistyczny </h2>
|
||||
|
||||
<p>Na poniższym obrazku jest zdjęcie słońca. Jest ono ciemniejsze na brzegach spróbuj uzyskać podobny efekt. Przydadzą się wektory normalnych i wektor <strong>V</strong> jak i funkcja mix.</p>
|
||||
<p><img src="./img/sun.png" /></p>
|
||||
|
||||
<h2 id="osłabienie-światła-tone-mapping">Osłabienie światła, tone mapping</h2>
|
||||
<h3 id="zadanie---osłabienie-światła-attenuation">Zadanie - Osłabienie światła (attenuation)</h3>
|
||||
<p>Ś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. Przed kwadratowaniem przemnoz diystans przez 10.0.</p>
|
||||
|
||||
<h4 id="tone-mapping">Tone mapping</h4>
|
||||
<p>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 <span class="math inline">\([0,1]\)</span> (obsługą wyższych wartości nazywamy HDR). Rozwiązaniem jest pracowanie na wartościach powyżej 1 wykorzystanie <em>tone mappingu</em> do przeniesienia ich w zakres <span class="math inline">\([0,1]\)</span>. Istnieje wiele wzorów, które są wykorzystywane do tego, jeden z nich to:</p>
|
||||
<p><span class="math display">\[C_{mapped} = 1-e^{-C * E},\]</span> gdzie C to kolor sceny a E to parametr ekspozycji (z zakresu <span class="math inline">\((0,\infty)\)</span>, który może być dostosowany w zależności od jasności.
|
||||
|
||||
<h3 id="zadanie">Zadanie - Tone mapping</h3>
|
||||
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.</p>
|
||||
<h3 id="zadanie">Zadanie*</h3>
|
||||
<p>Dodaj drugie źródło oświetlenia w postaci reflektora statku. Reflektor świeci tylko w określonym stożku,dlatego oprócz pozycji <code>spotPos</code> posiada również kierunek <code>spotDir</code> i kąt świecenia <span class="math inline">\(\phi\)</span>. Po obliczeniu dla niego <code>lightDir</code> należy sprawdzić, czy iloczyn skalarny pomiędzy <code>lightDir</code> a <code>spodDir</code> jest większy niż <span class="math inline">\(\cos\phi\)</span> . 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.</p>
|
||||
Zwróć uwagę, że SpotDir to co innego niż light Dir w poprzednich zadaniach.
|
||||
<p><img src="./img/spotlight.png" /> </p>
|
||||
</body>
|
||||
</html>
|
BIN
cw 5/zlib.dll
Normal file
BIN
cw 5/zlibd.dll
Normal file
BIN
dependencies/assimp/IrrXMLd.lib
vendored
Normal file
BIN
dependencies/assimp/assimp-vc141-mtd.dll
vendored
Normal file
BIN
dependencies/assimp/assimp-vc141-mtd.exp
vendored
Normal file
BIN
dependencies/assimp/assimp-vc141-mtd.lib
vendored
Normal file
BIN
dependencies/assimp/assimp_viewerd.exe
vendored
Normal file
BIN
dependencies/assimp/assimpd.exe
vendored
Normal file
8
dependencies/assimp/include/assimp/.editorconfig
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# See <http://EditorConfig.org> for details
|
||||
|
||||
[*.{h,hpp,inl}]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
indent_size = 4
|
||||
indent_style = space
|
418
dependencies/assimp/include/assimp/BaseImporter.h
vendored
Normal file
@ -0,0 +1,418 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Definition of the base class for all importer worker classes. */
|
||||
#ifndef INCLUDED_AI_BASEIMPORTER_H
|
||||
#define INCLUDED_AI_BASEIMPORTER_H
|
||||
|
||||
#include "Exceptional.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <assimp/types.h>
|
||||
#include <assimp/ProgressHandler.hpp>
|
||||
#include <assimp/ai_assert.h>
|
||||
|
||||
struct aiScene;
|
||||
struct aiImporterDesc;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
class Importer;
|
||||
class IOSystem;
|
||||
class BaseProcess;
|
||||
class SharedPostProcessInfo;
|
||||
class IOStream;
|
||||
|
||||
// utility to do char4 to uint32 in a portable manner
|
||||
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
|
||||
(string[1] << 16) + (string[2] << 8) + string[3]))
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface
|
||||
* for all importer worker classes.
|
||||
*
|
||||
* The interface defines two functions: CanRead() is used to check if the
|
||||
* importer can handle the format of the given file. If an implementation of
|
||||
* this function returns true, the importer then calls ReadFile() which
|
||||
* imports the given file. ReadFile is not overridable, it just calls
|
||||
* InternReadFile() and catches any ImportErrorException that might occur.
|
||||
*/
|
||||
class ASSIMP_API BaseImporter {
|
||||
friend class Importer;
|
||||
|
||||
private:
|
||||
/* Pushes state into importer for the importer scale */
|
||||
virtual void UpdateImporterScale( Importer* pImp );
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor to be privately used by #Importer */
|
||||
BaseImporter() AI_NO_EXCEPT;
|
||||
|
||||
/** Destructor, private as well */
|
||||
virtual ~BaseImporter();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the class can handle the format of the given file.
|
||||
*
|
||||
* The implementation should be as quick as possible. A check for
|
||||
* the file extension is enough. If no suitable loader is found with
|
||||
* this strategy, CanRead() is called again, the 'checkSig' parameter
|
||||
* set to true this time. Now the implementation is expected to
|
||||
* perform a full check of the file structure, possibly searching the
|
||||
* first bytes of the file for magic identifiers or keywords.
|
||||
*
|
||||
* @param pFile Path and file name of the file to be examined.
|
||||
* @param pIOHandler The IO handler to use for accessing any file.
|
||||
* @param checkSig Set to true if this method is called a second time.
|
||||
* This time, the implementation may take more time to examine the
|
||||
* contents of the file to be loaded for magic bytes, keywords, etc
|
||||
* to be able to load files with unknown/not existent file extensions.
|
||||
* @return true if the class can read this file, false if not.
|
||||
*/
|
||||
virtual bool CanRead(
|
||||
const std::string& pFile,
|
||||
IOSystem* pIOHandler,
|
||||
bool checkSig
|
||||
) const = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Imports the given file and returns the imported data.
|
||||
* If the import succeeds, ownership of the data is transferred to
|
||||
* the caller. If the import fails, NULL is returned. The function
|
||||
* takes care that any partially constructed data is destroyed
|
||||
* beforehand.
|
||||
*
|
||||
* @param pImp #Importer object hosting this loader.
|
||||
* @param pFile Path of the file to be imported.
|
||||
* @param pIOHandler IO-Handler used to open this and possible other files.
|
||||
* @return The imported data or NULL if failed. If it failed a
|
||||
* human-readable error description can be retrieved by calling
|
||||
* GetErrorText()
|
||||
*
|
||||
* @note This function is not intended to be overridden. Implement
|
||||
* InternReadFile() to do the import. If an exception is thrown somewhere
|
||||
* in InternReadFile(), this function will catch it and transform it into
|
||||
* a suitable response to the caller.
|
||||
*/
|
||||
aiScene* ReadFile(
|
||||
Importer* pImp,
|
||||
const std::string& pFile,
|
||||
IOSystem* pIOHandler
|
||||
);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns the error description of the last error that occurred.
|
||||
* @return A description of the last error that occurred. An empty
|
||||
* string if there was no error.
|
||||
*/
|
||||
const std::string& GetErrorText() const {
|
||||
return m_ErrorText;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Called prior to ReadFile().
|
||||
* The function is a request to the importer to update its configuration
|
||||
* basing on the Importer's configuration property list.
|
||||
* @param pImp Importer instance
|
||||
*/
|
||||
virtual void SetupProperties(
|
||||
const Importer* pImp
|
||||
);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Called by #Importer::GetImporterInfo to get a description of
|
||||
* some loader features. Importers must provide this information. */
|
||||
virtual const aiImporterDesc* GetInfo() const = 0;
|
||||
|
||||
/**
|
||||
* Will be called only by scale process when scaling is requested.
|
||||
*/
|
||||
virtual void SetFileScale(double scale)
|
||||
{
|
||||
fileScale = scale;
|
||||
}
|
||||
|
||||
virtual double GetFileScale() const
|
||||
{
|
||||
return fileScale;
|
||||
}
|
||||
|
||||
enum ImporterUnits {
|
||||
M,
|
||||
MM,
|
||||
CM,
|
||||
INCHES,
|
||||
FEET
|
||||
};
|
||||
|
||||
/**
|
||||
* Assimp Importer
|
||||
* unit conversions available
|
||||
* if you need another measurment unit add it below.
|
||||
* it's currently defined in assimp that we prefer meters.
|
||||
* */
|
||||
std::map<ImporterUnits, double> importerUnits = {
|
||||
{ImporterUnits::M, 1},
|
||||
{ImporterUnits::CM, 0.01},
|
||||
{ImporterUnits::MM, 0.001},
|
||||
{ImporterUnits::INCHES, 0.0254},
|
||||
{ImporterUnits::FEET, 0.3048}
|
||||
};
|
||||
|
||||
virtual void SetApplicationUnits( const ImporterUnits& unit )
|
||||
{
|
||||
importerScale = importerUnits[unit];
|
||||
applicationUnits = unit;
|
||||
}
|
||||
|
||||
virtual const ImporterUnits& GetApplicationUnits()
|
||||
{
|
||||
return applicationUnits;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Called by #Importer::GetExtensionList for each loaded importer.
|
||||
* Take the extension list contained in the structure returned by
|
||||
* #GetInfo and insert all file extensions into the given set.
|
||||
* @param extension set to collect file extensions in*/
|
||||
void GetExtensionList(std::set<std::string>& extensions);
|
||||
|
||||
protected:
|
||||
ImporterUnits applicationUnits = ImporterUnits::M;
|
||||
double importerScale = 1.0;
|
||||
double fileScale = 1.0;
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Imports the given file into the given scene structure. The
|
||||
* function is expected to throw an ImportErrorException if there is
|
||||
* an error. If it terminates normally, the data in aiScene is
|
||||
* expected to be correct. Override this function to implement the
|
||||
* actual importing.
|
||||
* <br>
|
||||
* The output scene must meet the following requirements:<br>
|
||||
* <ul>
|
||||
* <li>At least a root node must be there, even if its only purpose
|
||||
* is to reference one mesh.</li>
|
||||
* <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives
|
||||
* in the mesh are determined automatically in this case.</li>
|
||||
* <li>the vertex data is stored in a pseudo-indexed "verbose" format.
|
||||
* In fact this means that every vertex that is referenced by
|
||||
* a face is unique. Or the other way round: a vertex index may
|
||||
* not occur twice in a single aiMesh.</li>
|
||||
* <li>aiAnimation::mDuration may be -1. Assimp determines the length
|
||||
* of the animation automatically in this case as the length of
|
||||
* the longest animation channel.</li>
|
||||
* <li>aiMesh::mBitangents may be NULL if tangents and normals are
|
||||
* given. In this case bitangents are computed as the cross product
|
||||
* between normal and tangent.</li>
|
||||
* <li>There needn't be a material. If none is there a default material
|
||||
* is generated. However, it is recommended practice for loaders
|
||||
* to generate a default material for yourself that matches the
|
||||
* default material setting for the file format better than Assimp's
|
||||
* generic default material. Note that default materials *should*
|
||||
* be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded
|
||||
* or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy)
|
||||
* texture. </li>
|
||||
* </ul>
|
||||
* If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul>
|
||||
* <li> at least one mesh must be there</li>
|
||||
* <li> there may be no meshes with 0 vertices or faces</li>
|
||||
* </ul>
|
||||
* This won't be checked (except by the validation step): Assimp will
|
||||
* crash if one of the conditions is not met!
|
||||
*
|
||||
* @param pFile Path of the file to be imported.
|
||||
* @param pScene The scene object to hold the imported data.
|
||||
* NULL is not a valid parameter.
|
||||
* @param pIOHandler The IO handler to use for any file access.
|
||||
* NULL is not a valid parameter. */
|
||||
virtual void InternReadFile(
|
||||
const std::string& pFile,
|
||||
aiScene* pScene,
|
||||
IOSystem* pIOHandler
|
||||
) = 0;
|
||||
|
||||
public: // static utilities
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** A utility for CanRead().
|
||||
*
|
||||
* The function searches the header of a file for a specific token
|
||||
* and returns true if this token is found. This works for text
|
||||
* files only. There is a rudimentary handling of UNICODE files.
|
||||
* The comparison is case independent.
|
||||
*
|
||||
* @param pIOSystem IO System to work with
|
||||
* @param file File name of the file
|
||||
* @param tokens List of tokens to search for
|
||||
* @param numTokens Size of the token array
|
||||
* @param searchBytes Number of bytes to be searched for the tokens.
|
||||
*/
|
||||
static bool SearchFileHeaderForToken(
|
||||
IOSystem* pIOSystem,
|
||||
const std::string& file,
|
||||
const char** tokens,
|
||||
unsigned int numTokens,
|
||||
unsigned int searchBytes = 200,
|
||||
bool tokensSol = false,
|
||||
bool noAlphaBeforeTokens = false);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Check whether a file has a specific file extension
|
||||
* @param pFile Input file
|
||||
* @param ext0 Extension to check for. Lowercase characters only, no dot!
|
||||
* @param ext1 Optional second extension
|
||||
* @param ext2 Optional third extension
|
||||
* @note Case-insensitive
|
||||
*/
|
||||
static bool SimpleExtensionCheck (
|
||||
const std::string& pFile,
|
||||
const char* ext0,
|
||||
const char* ext1 = NULL,
|
||||
const char* ext2 = NULL);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Extract file extension from a string
|
||||
* @param pFile Input file
|
||||
* @return Extension without trailing dot, all lowercase
|
||||
*/
|
||||
static std::string GetExtension (
|
||||
const std::string& pFile);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Check whether a file starts with one or more magic tokens
|
||||
* @param pFile Input file
|
||||
* @param pIOHandler IO system to be used
|
||||
* @param magic n magic tokens
|
||||
* @params num Size of magic
|
||||
* @param offset Offset from file start where tokens are located
|
||||
* @param Size of one token, in bytes. Maximally 16 bytes.
|
||||
* @return true if one of the given tokens was found
|
||||
*
|
||||
* @note For convenience, the check is also performed for the
|
||||
* byte-swapped variant of all tokens (big endian). Only for
|
||||
* tokens of size 2,4.
|
||||
*/
|
||||
static bool CheckMagicToken(
|
||||
IOSystem* pIOHandler,
|
||||
const std::string& pFile,
|
||||
const void* magic,
|
||||
unsigned int num,
|
||||
unsigned int offset = 0,
|
||||
unsigned int size = 4);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** An utility for all text file loaders. It converts a file to our
|
||||
* UTF8 character set. Errors are reported, but ignored.
|
||||
*
|
||||
* @param data File buffer to be converted to UTF8 data. The buffer
|
||||
* is resized as appropriate. */
|
||||
static void ConvertToUTF8(
|
||||
std::vector<char>& data);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** An utility for all text file loaders. It converts a file from our
|
||||
* UTF8 character set back to ISO-8859-1. Errors are reported, but ignored.
|
||||
*
|
||||
* @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer
|
||||
* is resized as appropriate. */
|
||||
static void ConvertUTF8toISO8859_1(
|
||||
std::string& data);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/// @brief Enum to define, if empty files are ok or not.
|
||||
enum TextFileMode {
|
||||
ALLOW_EMPTY,
|
||||
FORBID_EMPTY
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Utility for text file loaders which copies the contents of the
|
||||
* file into a memory buffer and converts it to our UTF8
|
||||
* representation.
|
||||
* @param stream Stream to read from.
|
||||
* @param data Output buffer to be resized and filled with the
|
||||
* converted text file data. The buffer is terminated with
|
||||
* a binary 0.
|
||||
* @param mode Whether it is OK to load empty text files. */
|
||||
static void TextFileToBuffer(
|
||||
IOStream* stream,
|
||||
std::vector<char>& data,
|
||||
TextFileMode mode = FORBID_EMPTY);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Utility function to move a std::vector into a aiScene array
|
||||
* @param vec The vector to be moved
|
||||
* @param out The output pointer to the allocated array.
|
||||
* @param numOut The output count of elements copied. */
|
||||
template<typename T>
|
||||
AI_FORCE_INLINE
|
||||
static void CopyVector(
|
||||
std::vector<T>& vec,
|
||||
T*& out,
|
||||
unsigned int& outLength)
|
||||
{
|
||||
outLength = unsigned(vec.size());
|
||||
if (outLength) {
|
||||
out = new T[outLength];
|
||||
std::swap_ranges(vec.begin(), vec.end(), out);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Error description in case there was one.
|
||||
std::string m_ErrorText;
|
||||
/// Currently set progress handler.
|
||||
ProgressHandler* m_progress;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
#endif // AI_BASEIMPORTER_H_INC
|
125
dependencies/assimp/include/assimp/Bitmap.h
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Bitmap.h
|
||||
* @brief Defines bitmap format helper for textures
|
||||
*
|
||||
* Used for file formats which embed their textures into the model file.
|
||||
*/
|
||||
|
||||
#ifndef AI_BITMAP_H_INC
|
||||
#define AI_BITMAP_H_INC
|
||||
|
||||
#include "defs.h"
|
||||
#include <stdint.h>
|
||||
#include <cstddef>
|
||||
|
||||
struct aiTexture;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
class IOStream;
|
||||
|
||||
class ASSIMP_API Bitmap {
|
||||
protected:
|
||||
|
||||
struct Header {
|
||||
uint16_t type;
|
||||
uint32_t size;
|
||||
uint16_t reserved1;
|
||||
uint16_t reserved2;
|
||||
uint32_t offset;
|
||||
|
||||
// We define the struct size because sizeof(Header) might return a wrong result because of structure padding.
|
||||
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
|
||||
static const std::size_t header_size =
|
||||
sizeof(uint16_t) + // type
|
||||
sizeof(uint32_t) + // size
|
||||
sizeof(uint16_t) + // reserved1
|
||||
sizeof(uint16_t) + // reserved2
|
||||
sizeof(uint32_t); // offset
|
||||
};
|
||||
|
||||
struct DIB {
|
||||
uint32_t size;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
uint16_t planes;
|
||||
uint16_t bits_per_pixel;
|
||||
uint32_t compression;
|
||||
uint32_t image_size;
|
||||
int32_t x_resolution;
|
||||
int32_t y_resolution;
|
||||
uint32_t nb_colors;
|
||||
uint32_t nb_important_colors;
|
||||
|
||||
// We define the struct size because sizeof(DIB) might return a wrong result because of structure padding.
|
||||
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
|
||||
static const std::size_t dib_size =
|
||||
sizeof(uint32_t) + // size
|
||||
sizeof(int32_t) + // width
|
||||
sizeof(int32_t) + // height
|
||||
sizeof(uint16_t) + // planes
|
||||
sizeof(uint16_t) + // bits_per_pixel
|
||||
sizeof(uint32_t) + // compression
|
||||
sizeof(uint32_t) + // image_size
|
||||
sizeof(int32_t) + // x_resolution
|
||||
sizeof(int32_t) + // y_resolution
|
||||
sizeof(uint32_t) + // nb_colors
|
||||
sizeof(uint32_t); // nb_important_colors
|
||||
};
|
||||
|
||||
static const std::size_t mBytesPerPixel = 4;
|
||||
|
||||
public:
|
||||
static void Save(aiTexture* texture, IOStream* file);
|
||||
|
||||
protected:
|
||||
static void WriteHeader(Header& header, IOStream* file);
|
||||
static void WriteDIB(DIB& dib, IOStream* file);
|
||||
static void WriteData(aiTexture* texture, IOStream* file);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // AI_BITMAP_H_INC
|
338
dependencies/assimp/include/assimp/BlobIOSystem.h
vendored
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Provides cheat implementations for IOSystem and IOStream to
|
||||
* redirect exporter output to a blob chain.*/
|
||||
|
||||
#ifndef AI_BLOBIOSYSTEM_H_INCLUDED
|
||||
#define AI_BLOBIOSYSTEM_H_INCLUDED
|
||||
|
||||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/cexport.h>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <stdint.h>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace Assimp {
|
||||
class BlobIOSystem;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/** Redirect IOStream to a blob */
|
||||
// --------------------------------------------------------------------------------------------
|
||||
class BlobIOStream : public IOStream
|
||||
{
|
||||
public:
|
||||
|
||||
BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096)
|
||||
: buffer()
|
||||
, cur_size()
|
||||
, file_size()
|
||||
, cursor()
|
||||
, initial(initial)
|
||||
, file(file)
|
||||
, creator(creator)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual ~BlobIOStream();
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
aiExportDataBlob* GetBlob()
|
||||
{
|
||||
aiExportDataBlob* blob = new aiExportDataBlob();
|
||||
blob->size = file_size;
|
||||
blob->data = buffer;
|
||||
|
||||
buffer = NULL;
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
virtual size_t Read( void *,
|
||||
size_t,
|
||||
size_t )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
virtual size_t Write(const void* pvBuffer,
|
||||
size_t pSize,
|
||||
size_t pCount)
|
||||
{
|
||||
pSize *= pCount;
|
||||
if (cursor + pSize > cur_size) {
|
||||
Grow(cursor + pSize);
|
||||
}
|
||||
|
||||
memcpy(buffer+cursor, pvBuffer, pSize);
|
||||
cursor += pSize;
|
||||
|
||||
file_size = std::max(file_size,cursor);
|
||||
return pCount;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
virtual aiReturn Seek(size_t pOffset,
|
||||
aiOrigin pOrigin)
|
||||
{
|
||||
switch(pOrigin)
|
||||
{
|
||||
case aiOrigin_CUR:
|
||||
cursor += pOffset;
|
||||
break;
|
||||
|
||||
case aiOrigin_END:
|
||||
cursor = file_size - pOffset;
|
||||
break;
|
||||
|
||||
case aiOrigin_SET:
|
||||
cursor = pOffset;
|
||||
break;
|
||||
|
||||
default:
|
||||
return AI_FAILURE;
|
||||
}
|
||||
|
||||
if (cursor > file_size) {
|
||||
Grow(cursor);
|
||||
}
|
||||
|
||||
file_size = std::max(cursor,file_size);
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
virtual size_t Tell() const
|
||||
{
|
||||
return cursor;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
virtual size_t FileSize() const
|
||||
{
|
||||
return file_size;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
virtual void Flush()
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void Grow(size_t need = 0)
|
||||
{
|
||||
// 1.5 and phi are very heap-friendly growth factors (the first
|
||||
// allows for frequent re-use of heap blocks, the second
|
||||
// forms a fibonacci sequence with similar characteristics -
|
||||
// since this heavily depends on the heap implementation
|
||||
// and other factors as well, i'll just go with 1.5 since
|
||||
// it is quicker to compute).
|
||||
size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
|
||||
|
||||
const uint8_t* const old = buffer;
|
||||
buffer = new uint8_t[new_size];
|
||||
|
||||
if (old) {
|
||||
memcpy(buffer,old,cur_size);
|
||||
delete[] old;
|
||||
}
|
||||
|
||||
cur_size = new_size;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint8_t* buffer;
|
||||
size_t cur_size,file_size, cursor, initial;
|
||||
|
||||
const std::string file;
|
||||
BlobIOSystem* const creator;
|
||||
};
|
||||
|
||||
|
||||
#define AI_BLOBIO_MAGIC "$blobfile"
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/** Redirect IOSystem to a blob */
|
||||
// --------------------------------------------------------------------------------------------
|
||||
class BlobIOSystem : public IOSystem
|
||||
{
|
||||
|
||||
friend class BlobIOStream;
|
||||
typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
|
||||
|
||||
public:
|
||||
|
||||
BlobIOSystem()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~BlobIOSystem()
|
||||
{
|
||||
for(BlobEntry& blobby : blobs) {
|
||||
delete blobby.second;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
const char* GetMagicFileName() const
|
||||
{
|
||||
return AI_BLOBIO_MAGIC;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
aiExportDataBlob* GetBlobChain()
|
||||
{
|
||||
// one must be the master
|
||||
aiExportDataBlob* master = NULL, *cur;
|
||||
for(const BlobEntry& blobby : blobs) {
|
||||
if (blobby.first == AI_BLOBIO_MAGIC) {
|
||||
master = blobby.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!master) {
|
||||
ASSIMP_LOG_ERROR("BlobIOSystem: no data written or master file was not closed properly.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
master->name.Set("");
|
||||
|
||||
cur = master;
|
||||
for(const BlobEntry& blobby : blobs) {
|
||||
if (blobby.second == master) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cur->next = blobby.second;
|
||||
cur = cur->next;
|
||||
|
||||
// extract the file extension from the file written
|
||||
const std::string::size_type s = blobby.first.find_first_of('.');
|
||||
cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1));
|
||||
}
|
||||
|
||||
// give up blob ownership
|
||||
blobs.clear();
|
||||
return master;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
virtual bool Exists( const char* pFile) const {
|
||||
return created.find(std::string(pFile)) != created.end();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
virtual char getOsSeparator() const {
|
||||
return '/';
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
virtual IOStream* Open(const char* pFile,
|
||||
const char* pMode)
|
||||
{
|
||||
if (pMode[0] != 'w') {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
created.insert(std::string(pFile));
|
||||
return new BlobIOStream(this,std::string(pFile));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
virtual void Close( IOStream* pFile)
|
||||
{
|
||||
delete pFile;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void OnDestruct(const std::string& filename, BlobIOStream* child)
|
||||
{
|
||||
// we don't know in which the files are closed, so we
|
||||
// can't reliably say that the first must be the master
|
||||
// file ...
|
||||
blobs.push_back( BlobEntry(filename,child->GetBlob()) );
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<std::string> created;
|
||||
std::vector< BlobEntry > blobs;
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
BlobIOStream :: ~BlobIOStream()
|
||||
{
|
||||
creator->OnDestruct(file,this);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
|
||||
} // end Assimp
|
||||
|
||||
#endif
|
287
dependencies/assimp/include/assimp/ByteSwapper.h
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Helper class tp perform various byte oder swappings
|
||||
(e.g. little to big endian) */
|
||||
#ifndef AI_BYTESWAPPER_H_INC
|
||||
#define AI_BYTESWAPPER_H_INC
|
||||
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
namespace Assimp {
|
||||
// --------------------------------------------------------------------------------------
|
||||
/** Defines some useful byte order swap routines.
|
||||
*
|
||||
* This is required to read big-endian model formats on little-endian machines,
|
||||
* and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
|
||||
// --------------------------------------------------------------------------------------
|
||||
class ByteSwap {
|
||||
ByteSwap() AI_NO_EXCEPT {}
|
||||
|
||||
public:
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** Swap two bytes of data
|
||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||
static inline void Swap2(void* _szOut)
|
||||
{
|
||||
ai_assert(_szOut);
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
|
||||
*szOut = _byteswap_ushort(*szOut);
|
||||
#else
|
||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
||||
std::swap(szOut[0],szOut[1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** Swap four bytes of data
|
||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||
static inline void Swap4(void* _szOut)
|
||||
{
|
||||
ai_assert(_szOut);
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
|
||||
*szOut = _byteswap_ulong(*szOut);
|
||||
#else
|
||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
||||
std::swap(szOut[0],szOut[3]);
|
||||
std::swap(szOut[1],szOut[2]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** Swap eight bytes of data
|
||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||
static inline void Swap8(void* _szOut)
|
||||
{
|
||||
ai_assert(_szOut);
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
|
||||
*szOut = _byteswap_uint64(*szOut);
|
||||
#else
|
||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
||||
std::swap(szOut[0],szOut[7]);
|
||||
std::swap(szOut[1],szOut[6]);
|
||||
std::swap(szOut[2],szOut[5]);
|
||||
std::swap(szOut[3],szOut[4]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** ByteSwap a float. Not a joke.
|
||||
* @param[inout] fOut ehm. .. */
|
||||
static inline void Swap(float* fOut) {
|
||||
Swap4(fOut);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** ByteSwap a double. Not a joke.
|
||||
* @param[inout] fOut ehm. .. */
|
||||
static inline void Swap(double* fOut) {
|
||||
Swap8(fOut);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** ByteSwap an int16t. Not a joke.
|
||||
* @param[inout] fOut ehm. .. */
|
||||
static inline void Swap(int16_t* fOut) {
|
||||
Swap2(fOut);
|
||||
}
|
||||
|
||||
static inline void Swap(uint16_t* fOut) {
|
||||
Swap2(fOut);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** ByteSwap an int32t. Not a joke.
|
||||
* @param[inout] fOut ehm. .. */
|
||||
static inline void Swap(int32_t* fOut){
|
||||
Swap4(fOut);
|
||||
}
|
||||
|
||||
static inline void Swap(uint32_t* fOut){
|
||||
Swap4(fOut);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** ByteSwap an int64t. Not a joke.
|
||||
* @param[inout] fOut ehm. .. */
|
||||
static inline void Swap(int64_t* fOut) {
|
||||
Swap8(fOut);
|
||||
}
|
||||
|
||||
static inline void Swap(uint64_t* fOut) {
|
||||
Swap8(fOut);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//! Templatized ByteSwap
|
||||
//! \returns param tOut as swapped
|
||||
template<typename Type>
|
||||
static inline Type Swapped(Type tOut)
|
||||
{
|
||||
return _swapper<Type,sizeof(Type)>()(tOut);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <typename T, size_t size> struct _swapper;
|
||||
};
|
||||
|
||||
template <typename T> struct ByteSwap::_swapper<T,2> {
|
||||
T operator() (T tOut) {
|
||||
Swap2(&tOut);
|
||||
return tOut;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct ByteSwap::_swapper<T,4> {
|
||||
T operator() (T tOut) {
|
||||
Swap4(&tOut);
|
||||
return tOut;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct ByteSwap::_swapper<T,8> {
|
||||
T operator() (T tOut) {
|
||||
Swap8(&tOut);
|
||||
return tOut;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ByteSwap macros for BigEndian/LittleEndian support
|
||||
// --------------------------------------------------------------------------------------
|
||||
#if (defined AI_BUILD_BIG_ENDIAN)
|
||||
# define AI_LE(t) (t)
|
||||
# define AI_BE(t) ByteSwap::Swapped(t)
|
||||
# define AI_LSWAP2(p)
|
||||
# define AI_LSWAP4(p)
|
||||
# define AI_LSWAP8(p)
|
||||
# define AI_LSWAP2P(p)
|
||||
# define AI_LSWAP4P(p)
|
||||
# define AI_LSWAP8P(p)
|
||||
# define LE_NCONST const
|
||||
# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
|
||||
# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
|
||||
# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
|
||||
# define AI_SWAP2P(p) ByteSwap::Swap2((p))
|
||||
# define AI_SWAP4P(p) ByteSwap::Swap4((p))
|
||||
# define AI_SWAP8P(p) ByteSwap::Swap8((p))
|
||||
# define BE_NCONST
|
||||
#else
|
||||
# define AI_BE(t) (t)
|
||||
# define AI_LE(t) ByteSwap::Swapped(t)
|
||||
# define AI_SWAP2(p)
|
||||
# define AI_SWAP4(p)
|
||||
# define AI_SWAP8(p)
|
||||
# define AI_SWAP2P(p)
|
||||
# define AI_SWAP4P(p)
|
||||
# define AI_SWAP8P(p)
|
||||
# define BE_NCONST const
|
||||
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
|
||||
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
|
||||
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
|
||||
# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
|
||||
# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
|
||||
# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
|
||||
# define LE_NCONST
|
||||
#endif
|
||||
|
||||
|
||||
namespace Intern {
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
template <typename T, bool doit>
|
||||
struct ByteSwapper {
|
||||
void operator() (T* inout) {
|
||||
ByteSwap::Swap(inout);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ByteSwapper<T,false> {
|
||||
void operator() (T*) {
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
template <bool SwapEndianess, typename T, bool RuntimeSwitch>
|
||||
struct Getter {
|
||||
void operator() (T* inout, bool le) {
|
||||
#ifdef AI_BUILD_BIG_ENDIAN
|
||||
le = le;
|
||||
#else
|
||||
le = !le;
|
||||
#endif
|
||||
if (le) {
|
||||
ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
|
||||
}
|
||||
else ByteSwapper<T,false> () (inout);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool SwapEndianess, typename T>
|
||||
struct Getter<SwapEndianess,T,false> {
|
||||
|
||||
void operator() (T* inout, bool /*le*/) {
|
||||
// static branch
|
||||
ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
|
||||
}
|
||||
};
|
||||
} // end Intern
|
||||
} // end Assimp
|
||||
|
||||
#endif //!! AI_BYTESWAPPER_H_INC
|
22
dependencies/assimp/include/assimp/Compiler/poppack1.h
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
// ===============================================================================
|
||||
// May be included multiple times - resets structure packing to the defaults
|
||||
// for all supported compilers. Reverts the changes made by #include <pushpack1.h>
|
||||
//
|
||||
// Currently this works on the following compilers:
|
||||
// MSVC 7,8,9
|
||||
// GCC
|
||||
// BORLAND (complains about 'pack state changed but not reverted', but works)
|
||||
// ===============================================================================
|
||||
|
||||
#ifndef AI_PUSHPACK_IS_DEFINED
|
||||
# error pushpack1.h must be included after poppack1.h
|
||||
#endif
|
||||
|
||||
// reset packing to the original value
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
|
||||
# pragma pack( pop )
|
||||
#endif
|
||||
#undef PACK_STRUCT
|
||||
|
||||
#undef AI_PUSHPACK_IS_DEFINED
|
912
dependencies/assimp/include/assimp/Compiler/pstdint.h
vendored
Normal file
@ -0,0 +1,912 @@
|
||||
/* A portable stdint.h
|
||||
****************************************************************************
|
||||
* BSD License:
|
||||
****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2005-2016 Paul Hsieh
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Version 0.1.15.4
|
||||
*
|
||||
* The ANSI C standard committee, for the C99 standard, specified the
|
||||
* inclusion of a new standard include file called stdint.h. This is
|
||||
* a very useful and long desired include file which contains several
|
||||
* very precise definitions for integer scalar types that is
|
||||
* critically important for making portable several classes of
|
||||
* applications including cryptography, hashing, variable length
|
||||
* integer libraries and so on. But for most developers its likely
|
||||
* useful just for programming sanity.
|
||||
*
|
||||
* The problem is that some compiler vendors chose to ignore the C99
|
||||
* standard and some older compilers have no opportunity to be updated.
|
||||
* Because of this situation, simply including stdint.h in your code
|
||||
* makes it unportable.
|
||||
*
|
||||
* So that's what this file is all about. Its an attempt to build a
|
||||
* single universal include file that works on as many platforms as
|
||||
* possible to deliver what stdint.h is supposed to. Even compilers
|
||||
* that already come with stdint.h can use this file instead without
|
||||
* any loss of functionality. A few things that should be noted about
|
||||
* this file:
|
||||
*
|
||||
* 1) It is not guaranteed to be portable and/or present an identical
|
||||
* interface on all platforms. The extreme variability of the
|
||||
* ANSI C standard makes this an impossibility right from the
|
||||
* very get go. Its really only meant to be useful for the vast
|
||||
* majority of platforms that possess the capability of
|
||||
* implementing usefully and precisely defined, standard sized
|
||||
* integer scalars. Systems which are not intrinsically 2s
|
||||
* complement may produce invalid constants.
|
||||
*
|
||||
* 2) There is an unavoidable use of non-reserved symbols.
|
||||
*
|
||||
* 3) Other standard include files are invoked.
|
||||
*
|
||||
* 4) This file may come in conflict with future platforms that do
|
||||
* include stdint.h. The hope is that one or the other can be
|
||||
* used with no real difference.
|
||||
*
|
||||
* 5) In the current version, if your platform can't represent
|
||||
* int32_t, int16_t and int8_t, it just dumps out with a compiler
|
||||
* error.
|
||||
*
|
||||
* 6) 64 bit integers may or may not be defined. Test for their
|
||||
* presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
|
||||
* Note that this is different from the C99 specification which
|
||||
* requires the existence of 64 bit support in the compiler. If
|
||||
* this is not defined for your platform, yet it is capable of
|
||||
* dealing with 64 bits then it is because this file has not yet
|
||||
* been extended to cover all of your system's capabilities.
|
||||
*
|
||||
* 7) (u)intptr_t may or may not be defined. Test for its presence
|
||||
* with the test: #ifdef PTRDIFF_MAX. If this is not defined
|
||||
* for your platform, then it is because this file has not yet
|
||||
* been extended to cover all of your system's capabilities, not
|
||||
* because its optional.
|
||||
*
|
||||
* 8) The following might not been defined even if your platform is
|
||||
* capable of defining it:
|
||||
*
|
||||
* WCHAR_MIN
|
||||
* WCHAR_MAX
|
||||
* (u)int64_t
|
||||
* PTRDIFF_MIN
|
||||
* PTRDIFF_MAX
|
||||
* (u)intptr_t
|
||||
*
|
||||
* 9) The following have not been defined:
|
||||
*
|
||||
* WINT_MIN
|
||||
* WINT_MAX
|
||||
*
|
||||
* 10) The criteria for defining (u)int_least(*)_t isn't clear,
|
||||
* except for systems which don't have a type that precisely
|
||||
* defined 8, 16, or 32 bit types (which this include file does
|
||||
* not support anyways). Default definitions have been given.
|
||||
*
|
||||
* 11) The criteria for defining (u)int_fast(*)_t isn't something I
|
||||
* would trust to any particular compiler vendor or the ANSI C
|
||||
* committee. It is well known that "compatible systems" are
|
||||
* commonly created that have very different performance
|
||||
* characteristics from the systems they are compatible with,
|
||||
* especially those whose vendors make both the compiler and the
|
||||
* system. Default definitions have been given, but its strongly
|
||||
* recommended that users never use these definitions for any
|
||||
* reason (they do *NOT* deliver any serious guarantee of
|
||||
* improved performance -- not in this file, nor any vendor's
|
||||
* stdint.h).
|
||||
*
|
||||
* 12) The following macros:
|
||||
*
|
||||
* PRINTF_INTMAX_MODIFIER
|
||||
* PRINTF_INT64_MODIFIER
|
||||
* PRINTF_INT32_MODIFIER
|
||||
* PRINTF_INT16_MODIFIER
|
||||
* PRINTF_LEAST64_MODIFIER
|
||||
* PRINTF_LEAST32_MODIFIER
|
||||
* PRINTF_LEAST16_MODIFIER
|
||||
* PRINTF_INTPTR_MODIFIER
|
||||
*
|
||||
* are strings which have been defined as the modifiers required
|
||||
* for the "d", "u" and "x" printf formats to correctly output
|
||||
* (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
|
||||
* (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
|
||||
* PRINTF_INTPTR_MODIFIER is not defined for some systems which
|
||||
* provide their own stdint.h. PRINTF_INT64_MODIFIER is not
|
||||
* defined if INT64_MAX is not defined. These are an extension
|
||||
* beyond what C99 specifies must be in stdint.h.
|
||||
*
|
||||
* In addition, the following macros are defined:
|
||||
*
|
||||
* PRINTF_INTMAX_HEX_WIDTH
|
||||
* PRINTF_INT64_HEX_WIDTH
|
||||
* PRINTF_INT32_HEX_WIDTH
|
||||
* PRINTF_INT16_HEX_WIDTH
|
||||
* PRINTF_INT8_HEX_WIDTH
|
||||
* PRINTF_INTMAX_DEC_WIDTH
|
||||
* PRINTF_INT64_DEC_WIDTH
|
||||
* PRINTF_INT32_DEC_WIDTH
|
||||
* PRINTF_INT16_DEC_WIDTH
|
||||
* PRINTF_UINT8_DEC_WIDTH
|
||||
* PRINTF_UINTMAX_DEC_WIDTH
|
||||
* PRINTF_UINT64_DEC_WIDTH
|
||||
* PRINTF_UINT32_DEC_WIDTH
|
||||
* PRINTF_UINT16_DEC_WIDTH
|
||||
* PRINTF_UINT8_DEC_WIDTH
|
||||
*
|
||||
* Which specifies the maximum number of characters required to
|
||||
* print the number of that type in either hexadecimal or decimal.
|
||||
* These are an extension beyond what C99 specifies must be in
|
||||
* stdint.h.
|
||||
*
|
||||
* Compilers tested (all with 0 warnings at their highest respective
|
||||
* settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
|
||||
* bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
|
||||
* .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
|
||||
*
|
||||
* This file should be considered a work in progress. Suggestions for
|
||||
* improvements, especially those which increase coverage are strongly
|
||||
* encouraged.
|
||||
*
|
||||
* Acknowledgements
|
||||
*
|
||||
* The following people have made significant contributions to the
|
||||
* development and testing of this file:
|
||||
*
|
||||
* Chris Howie
|
||||
* John Steele Scott
|
||||
* Dave Thorup
|
||||
* John Dill
|
||||
* Florian Wobbe
|
||||
* Christopher Sean Morrison
|
||||
* Mikkel Fahnoe Jorgensen
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
|
||||
/*
|
||||
* For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
|
||||
* do nothing else. On the Mac OS X version of gcc this is _STDINT_H_.
|
||||
*/
|
||||
|
||||
#if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
|
||||
#include <stdint.h>
|
||||
#define _PSTDINT_H_INCLUDED
|
||||
# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__))
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "l"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# endif
|
||||
# else
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "ll"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# if (UINT_MAX == UINT32_MAX)
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# else
|
||||
# define PRINTF_INT32_MODIFIER "l"
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER "h"
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_MODIFIER
|
||||
# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
|
||||
# endif
|
||||
# ifndef PRINTF_INT64_HEX_WIDTH
|
||||
# define PRINTF_INT64_HEX_WIDTH "16"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT64_HEX_WIDTH
|
||||
# define PRINTF_UINT64_HEX_WIDTH "16"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_HEX_WIDTH
|
||||
# define PRINTF_INT32_HEX_WIDTH "8"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT32_HEX_WIDTH
|
||||
# define PRINTF_UINT32_HEX_WIDTH "8"
|
||||
# endif
|
||||
# ifndef PRINTF_INT16_HEX_WIDTH
|
||||
# define PRINTF_INT16_HEX_WIDTH "4"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT16_HEX_WIDTH
|
||||
# define PRINTF_UINT16_HEX_WIDTH "4"
|
||||
# endif
|
||||
# ifndef PRINTF_INT8_HEX_WIDTH
|
||||
# define PRINTF_INT8_HEX_WIDTH "2"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT8_HEX_WIDTH
|
||||
# define PRINTF_UINT8_HEX_WIDTH "2"
|
||||
# endif
|
||||
# ifndef PRINTF_INT64_DEC_WIDTH
|
||||
# define PRINTF_INT64_DEC_WIDTH "19"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT64_DEC_WIDTH
|
||||
# define PRINTF_UINT64_DEC_WIDTH "20"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_DEC_WIDTH
|
||||
# define PRINTF_INT32_DEC_WIDTH "10"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT32_DEC_WIDTH
|
||||
# define PRINTF_UINT32_DEC_WIDTH "10"
|
||||
# endif
|
||||
# ifndef PRINTF_INT16_DEC_WIDTH
|
||||
# define PRINTF_INT16_DEC_WIDTH "5"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT16_DEC_WIDTH
|
||||
# define PRINTF_UINT16_DEC_WIDTH "5"
|
||||
# endif
|
||||
# ifndef PRINTF_INT8_DEC_WIDTH
|
||||
# define PRINTF_INT8_DEC_WIDTH "3"
|
||||
# endif
|
||||
# ifndef PRINTF_UINT8_DEC_WIDTH
|
||||
# define PRINTF_UINT8_DEC_WIDTH "3"
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_HEX_WIDTH
|
||||
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_UINTMAX_HEX_WIDTH
|
||||
# define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_DEC_WIDTH
|
||||
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_UINTMAX_DEC_WIDTH
|
||||
# define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Something really weird is going on with Open Watcom. Just pull some of
|
||||
* these duplicated definitions from Open Watcom's stdint.h file for now.
|
||||
*/
|
||||
|
||||
# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
|
||||
# if !defined (INT64_C)
|
||||
# define INT64_C(x) (x + (INT64_MAX - INT64_MAX))
|
||||
# endif
|
||||
# if !defined (UINT64_C)
|
||||
# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
|
||||
# endif
|
||||
# if !defined (INT32_C)
|
||||
# define INT32_C(x) (x + (INT32_MAX - INT32_MAX))
|
||||
# endif
|
||||
# if !defined (UINT32_C)
|
||||
# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX))
|
||||
# endif
|
||||
# if !defined (INT16_C)
|
||||
# define INT16_C(x) (x)
|
||||
# endif
|
||||
# if !defined (UINT16_C)
|
||||
# define UINT16_C(x) (x)
|
||||
# endif
|
||||
# if !defined (INT8_C)
|
||||
# define INT8_C(x) (x)
|
||||
# endif
|
||||
# if !defined (UINT8_C)
|
||||
# define UINT8_C(x) (x)
|
||||
# endif
|
||||
# if !defined (UINT64_MAX)
|
||||
# define UINT64_MAX 18446744073709551615ULL
|
||||
# endif
|
||||
# if !defined (INT64_MAX)
|
||||
# define INT64_MAX 9223372036854775807LL
|
||||
# endif
|
||||
# if !defined (UINT32_MAX)
|
||||
# define UINT32_MAX 4294967295UL
|
||||
# endif
|
||||
# if !defined (INT32_MAX)
|
||||
# define INT32_MAX 2147483647L
|
||||
# endif
|
||||
# if !defined (INTMAX_MAX)
|
||||
# define INTMAX_MAX INT64_MAX
|
||||
# endif
|
||||
# if !defined (INTMAX_MIN)
|
||||
# define INTMAX_MIN INT64_MIN
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I have no idea what is the truly correct thing to do on older Solaris.
|
||||
* From some online discussions, this seems to be what is being
|
||||
* recommended. For people who actually are developing on older Solaris,
|
||||
* what I would like to know is, does this define all of the relevant
|
||||
* macros of a complete stdint.h? Remember, in pstdint.h 64 bit is
|
||||
* considered optional.
|
||||
*/
|
||||
|
||||
#if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED)
|
||||
#include <sys/inttypes.h>
|
||||
#define _PSTDINT_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#ifndef _PSTDINT_H_INCLUDED
|
||||
#define _PSTDINT_H_INCLUDED
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX (~(size_t)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Deduce the type assignments from limits.h under the assumption that
|
||||
* integer sizes in bits are powers of 2, and follow the ANSI
|
||||
* definitions.
|
||||
*/
|
||||
|
||||
#ifndef UINT8_MAX
|
||||
# define UINT8_MAX 0xff
|
||||
#endif
|
||||
#if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks)
|
||||
# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
|
||||
typedef unsigned char uint8_t;
|
||||
# define UINT8_C(v) ((uint8_t) v)
|
||||
# else
|
||||
# error "Platform not supported"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INT8_MAX
|
||||
# define INT8_MAX 0x7f
|
||||
#endif
|
||||
#ifndef INT8_MIN
|
||||
# define INT8_MIN INT8_C(0x80)
|
||||
#endif
|
||||
#if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks)
|
||||
# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
|
||||
typedef signed char int8_t;
|
||||
# define INT8_C(v) ((int8_t) v)
|
||||
# else
|
||||
# error "Platform not supported"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef UINT16_MAX
|
||||
# define UINT16_MAX 0xffff
|
||||
#endif
|
||||
#if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks)
|
||||
#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
|
||||
typedef unsigned int uint16_t;
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER ""
|
||||
# endif
|
||||
# define UINT16_C(v) ((uint16_t) (v))
|
||||
#elif (USHRT_MAX == UINT16_MAX)
|
||||
typedef unsigned short uint16_t;
|
||||
# define UINT16_C(v) ((uint16_t) (v))
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER "h"
|
||||
# endif
|
||||
#else
|
||||
#error "Platform not supported"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef INT16_MAX
|
||||
# define INT16_MAX 0x7fff
|
||||
#endif
|
||||
#ifndef INT16_MIN
|
||||
# define INT16_MIN INT16_C(0x8000)
|
||||
#endif
|
||||
#if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks)
|
||||
#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
|
||||
typedef signed int int16_t;
|
||||
# define INT16_C(v) ((int16_t) (v))
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER ""
|
||||
# endif
|
||||
#elif (SHRT_MAX == INT16_MAX)
|
||||
typedef signed short int16_t;
|
||||
# define INT16_C(v) ((int16_t) (v))
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER "h"
|
||||
# endif
|
||||
#else
|
||||
#error "Platform not supported"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_MAX
|
||||
# define UINT32_MAX (0xffffffffUL)
|
||||
#endif
|
||||
#if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks)
|
||||
#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
|
||||
typedef unsigned long uint32_t;
|
||||
# define UINT32_C(v) v ## UL
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER "l"
|
||||
# endif
|
||||
#elif (UINT_MAX == UINT32_MAX)
|
||||
typedef unsigned int uint32_t;
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# endif
|
||||
# define UINT32_C(v) v ## U
|
||||
#elif (USHRT_MAX == UINT32_MAX)
|
||||
typedef unsigned short uint32_t;
|
||||
# define UINT32_C(v) ((unsigned short) (v))
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# endif
|
||||
#else
|
||||
#error "Platform not supported"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef INT32_MAX
|
||||
# define INT32_MAX (0x7fffffffL)
|
||||
#endif
|
||||
#ifndef INT32_MIN
|
||||
# define INT32_MIN INT32_C(0x80000000)
|
||||
#endif
|
||||
#if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks)
|
||||
#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
|
||||
typedef signed long int32_t;
|
||||
# define INT32_C(v) v ## L
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER "l"
|
||||
# endif
|
||||
#elif (INT_MAX == INT32_MAX)
|
||||
typedef signed int int32_t;
|
||||
# define INT32_C(v) v
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# endif
|
||||
#elif (SHRT_MAX == INT32_MAX)
|
||||
typedef signed short int32_t;
|
||||
# define INT32_C(v) ((short) (v))
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# endif
|
||||
#else
|
||||
#error "Platform not supported"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The macro stdint_int64_defined is temporarily used to record
|
||||
* whether or not 64 integer support is available. It must be
|
||||
* defined for any 64 integer extensions for new platforms that are
|
||||
* added.
|
||||
*/
|
||||
|
||||
#undef stdint_int64_defined
|
||||
#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
|
||||
# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
|
||||
# define stdint_int64_defined
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
# define UINT64_C(v) v ## ULL
|
||||
# define INT64_C(v) v ## LL
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "ll"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined (stdint_int64_defined)
|
||||
# if defined(__GNUC__) && !defined(vxWorks)
|
||||
# define stdint_int64_defined
|
||||
__extension__ typedef long long int64_t;
|
||||
__extension__ typedef unsigned long long uint64_t;
|
||||
# define UINT64_C(v) v ## ULL
|
||||
# define INT64_C(v) v ## LL
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "ll"
|
||||
# endif
|
||||
# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
|
||||
# define stdint_int64_defined
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
# define UINT64_C(v) v ## ULL
|
||||
# define INT64_C(v) v ## LL
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "ll"
|
||||
# endif
|
||||
# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
|
||||
# define stdint_int64_defined
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# define UINT64_C(v) v ## UI64
|
||||
# define INT64_C(v) v ## I64
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "I64"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined (LONG_LONG_MAX) && defined (INT64_C)
|
||||
# define LONG_LONG_MAX INT64_C (9223372036854775807)
|
||||
#endif
|
||||
#ifndef ULONG_LONG_MAX
|
||||
# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
|
||||
#endif
|
||||
|
||||
#if !defined (INT64_MAX) && defined (INT64_C)
|
||||
# define INT64_MAX INT64_C (9223372036854775807)
|
||||
#endif
|
||||
#if !defined (INT64_MIN) && defined (INT64_C)
|
||||
# define INT64_MIN INT64_C (-9223372036854775808)
|
||||
#endif
|
||||
#if !defined (UINT64_MAX) && defined (INT64_C)
|
||||
# define UINT64_MAX UINT64_C (18446744073709551615)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Width of hexadecimal for number field.
|
||||
*/
|
||||
|
||||
#ifndef PRINTF_INT64_HEX_WIDTH
|
||||
# define PRINTF_INT64_HEX_WIDTH "16"
|
||||
#endif
|
||||
#ifndef PRINTF_INT32_HEX_WIDTH
|
||||
# define PRINTF_INT32_HEX_WIDTH "8"
|
||||
#endif
|
||||
#ifndef PRINTF_INT16_HEX_WIDTH
|
||||
# define PRINTF_INT16_HEX_WIDTH "4"
|
||||
#endif
|
||||
#ifndef PRINTF_INT8_HEX_WIDTH
|
||||
# define PRINTF_INT8_HEX_WIDTH "2"
|
||||
#endif
|
||||
#ifndef PRINTF_INT64_DEC_WIDTH
|
||||
# define PRINTF_INT64_DEC_WIDTH "19"
|
||||
#endif
|
||||
#ifndef PRINTF_INT32_DEC_WIDTH
|
||||
# define PRINTF_INT32_DEC_WIDTH "10"
|
||||
#endif
|
||||
#ifndef PRINTF_INT16_DEC_WIDTH
|
||||
# define PRINTF_INT16_DEC_WIDTH "5"
|
||||
#endif
|
||||
#ifndef PRINTF_INT8_DEC_WIDTH
|
||||
# define PRINTF_INT8_DEC_WIDTH "3"
|
||||
#endif
|
||||
#ifndef PRINTF_UINT64_DEC_WIDTH
|
||||
# define PRINTF_UINT64_DEC_WIDTH "20"
|
||||
#endif
|
||||
#ifndef PRINTF_UINT32_DEC_WIDTH
|
||||
# define PRINTF_UINT32_DEC_WIDTH "10"
|
||||
#endif
|
||||
#ifndef PRINTF_UINT16_DEC_WIDTH
|
||||
# define PRINTF_UINT16_DEC_WIDTH "5"
|
||||
#endif
|
||||
#ifndef PRINTF_UINT8_DEC_WIDTH
|
||||
# define PRINTF_UINT8_DEC_WIDTH "3"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ok, lets not worry about 128 bit integers for now. Moore's law says
|
||||
* we don't need to worry about that until about 2040 at which point
|
||||
* we'll have bigger things to worry about.
|
||||
*/
|
||||
|
||||
#ifdef stdint_int64_defined
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
# define INTMAX_MAX INT64_MAX
|
||||
# define INTMAX_MIN INT64_MIN
|
||||
# define UINTMAX_MAX UINT64_MAX
|
||||
# define UINTMAX_C(v) UINT64_C(v)
|
||||
# define INTMAX_C(v) INT64_C(v)
|
||||
# ifndef PRINTF_INTMAX_MODIFIER
|
||||
# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_HEX_WIDTH
|
||||
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_DEC_WIDTH
|
||||
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
|
||||
# endif
|
||||
#else
|
||||
typedef int32_t intmax_t;
|
||||
typedef uint32_t uintmax_t;
|
||||
# define INTMAX_MAX INT32_MAX
|
||||
# define UINTMAX_MAX UINT32_MAX
|
||||
# define UINTMAX_C(v) UINT32_C(v)
|
||||
# define INTMAX_C(v) INT32_C(v)
|
||||
# ifndef PRINTF_INTMAX_MODIFIER
|
||||
# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_HEX_WIDTH
|
||||
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_DEC_WIDTH
|
||||
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Because this file currently only supports platforms which have
|
||||
* precise powers of 2 as bit sizes for the default integers, the
|
||||
* least definitions are all trivial. Its possible that a future
|
||||
* version of this file could have different definitions.
|
||||
*/
|
||||
|
||||
#ifndef stdint_least_defined
|
||||
typedef int8_t int_least8_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
|
||||
# define UINT_LEAST8_MAX UINT8_MAX
|
||||
# define INT_LEAST8_MAX INT8_MAX
|
||||
# define UINT_LEAST16_MAX UINT16_MAX
|
||||
# define INT_LEAST16_MAX INT16_MAX
|
||||
# define UINT_LEAST32_MAX UINT32_MAX
|
||||
# define INT_LEAST32_MAX INT32_MAX
|
||||
# define INT_LEAST8_MIN INT8_MIN
|
||||
# define INT_LEAST16_MIN INT16_MIN
|
||||
# define INT_LEAST32_MIN INT32_MIN
|
||||
# ifdef stdint_int64_defined
|
||||
typedef int64_t int_least64_t;
|
||||
typedef uint64_t uint_least64_t;
|
||||
# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
|
||||
# define UINT_LEAST64_MAX UINT64_MAX
|
||||
# define INT_LEAST64_MAX INT64_MAX
|
||||
# define INT_LEAST64_MIN INT64_MIN
|
||||
# endif
|
||||
#endif
|
||||
#undef stdint_least_defined
|
||||
|
||||
/*
|
||||
* The ANSI C committee pretending to know or specify anything about
|
||||
* performance is the epitome of misguided arrogance. The mandate of
|
||||
* this file is to *ONLY* ever support that absolute minimum
|
||||
* definition of the fast integer types, for compatibility purposes.
|
||||
* No extensions, and no attempt to suggest what may or may not be a
|
||||
* faster integer type will ever be made in this file. Developers are
|
||||
* warned to stay away from these types when using this or any other
|
||||
* stdint.h.
|
||||
*/
|
||||
|
||||
typedef int_least8_t int_fast8_t;
|
||||
typedef uint_least8_t uint_fast8_t;
|
||||
typedef int_least16_t int_fast16_t;
|
||||
typedef uint_least16_t uint_fast16_t;
|
||||
typedef int_least32_t int_fast32_t;
|
||||
typedef uint_least32_t uint_fast32_t;
|
||||
#define UINT_FAST8_MAX UINT_LEAST8_MAX
|
||||
#define INT_FAST8_MAX INT_LEAST8_MAX
|
||||
#define UINT_FAST16_MAX UINT_LEAST16_MAX
|
||||
#define INT_FAST16_MAX INT_LEAST16_MAX
|
||||
#define UINT_FAST32_MAX UINT_LEAST32_MAX
|
||||
#define INT_FAST32_MAX INT_LEAST32_MAX
|
||||
#define INT_FAST8_MIN INT_LEAST8_MIN
|
||||
#define INT_FAST16_MIN INT_LEAST16_MIN
|
||||
#define INT_FAST32_MIN INT_LEAST32_MIN
|
||||
#ifdef stdint_int64_defined
|
||||
typedef int_least64_t int_fast64_t;
|
||||
typedef uint_least64_t uint_fast64_t;
|
||||
# define UINT_FAST64_MAX UINT_LEAST64_MAX
|
||||
# define INT_FAST64_MAX INT_LEAST64_MAX
|
||||
# define INT_FAST64_MIN INT_LEAST64_MIN
|
||||
#endif
|
||||
|
||||
#undef stdint_int64_defined
|
||||
|
||||
/*
|
||||
* Whatever piecemeal, per compiler thing we can do about the wchar_t
|
||||
* type limits.
|
||||
*/
|
||||
|
||||
#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks)
|
||||
# include <wchar.h>
|
||||
# ifndef WCHAR_MIN
|
||||
# define WCHAR_MIN 0
|
||||
# endif
|
||||
# ifndef WCHAR_MAX
|
||||
# define WCHAR_MAX ((wchar_t)-1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Whatever piecemeal, per compiler/platform thing we can do about the
|
||||
* (u)intptr_t types and limits.
|
||||
*/
|
||||
|
||||
#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T)
|
||||
# define STDINT_H_UINTPTR_T_DEFINED
|
||||
#endif
|
||||
|
||||
#ifndef STDINT_H_UINTPTR_T_DEFINED
|
||||
# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__)
|
||||
# define stdint_intptr_bits 64
|
||||
# elif defined (__WATCOMC__) || defined (__TURBOC__)
|
||||
# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
|
||||
# define stdint_intptr_bits 16
|
||||
# else
|
||||
# define stdint_intptr_bits 32
|
||||
# endif
|
||||
# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__)
|
||||
# define stdint_intptr_bits 32
|
||||
# elif defined (__INTEL_COMPILER)
|
||||
/* TODO -- what did Intel do about x86-64? */
|
||||
# else
|
||||
/* #error "This platform might not be supported yet" */
|
||||
# endif
|
||||
|
||||
# ifdef stdint_intptr_bits
|
||||
# define stdint_intptr_glue3_i(a,b,c) a##b##c
|
||||
# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c)
|
||||
# ifndef PRINTF_INTPTR_MODIFIER
|
||||
# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
|
||||
# endif
|
||||
# ifndef PTRDIFF_MAX
|
||||
# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
|
||||
# endif
|
||||
# ifndef PTRDIFF_MIN
|
||||
# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
|
||||
# endif
|
||||
# ifndef UINTPTR_MAX
|
||||
# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
|
||||
# endif
|
||||
# ifndef INTPTR_MAX
|
||||
# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
|
||||
# endif
|
||||
# ifndef INTPTR_MIN
|
||||
# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
|
||||
# endif
|
||||
# ifndef INTPTR_C
|
||||
# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
|
||||
# endif
|
||||
# ifndef UINTPTR_C
|
||||
# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
|
||||
# endif
|
||||
typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
|
||||
typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t;
|
||||
# else
|
||||
/* TODO -- This following is likely wrong for some platforms, and does
|
||||
nothing for the definition of uintptr_t. */
|
||||
typedef ptrdiff_t intptr_t;
|
||||
# endif
|
||||
# define STDINT_H_UINTPTR_T_DEFINED
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assumes sig_atomic_t is signed and we have a 2s complement machine.
|
||||
*/
|
||||
|
||||
#ifndef SIG_ATOMIC_MAX
|
||||
# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)
|
||||
|
||||
/*
|
||||
* Please compile with the maximum warning settings to make sure macros are
|
||||
* not defined more than once.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define glue3_aux(x,y,z) x ## y ## z
|
||||
#define glue3(x,y,z) glue3_aux(x,y,z)
|
||||
|
||||
#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0);
|
||||
#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0);
|
||||
|
||||
#define DECL(us,bits) glue3(DECL,us,) (bits)
|
||||
|
||||
#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits)
|
||||
|
||||
#define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; }
|
||||
|
||||
int main () {
|
||||
int err_n = 0;
|
||||
int err_first = 0;
|
||||
DECL(I,8)
|
||||
DECL(U,8)
|
||||
DECL(I,16)
|
||||
DECL(U,16)
|
||||
DECL(I,32)
|
||||
DECL(U,32)
|
||||
#ifdef INT64_MAX
|
||||
DECL(I,64)
|
||||
DECL(U,64)
|
||||
#endif
|
||||
intmax_t imax = INTMAX_C(0);
|
||||
uintmax_t umax = UINTMAX_C(0);
|
||||
char str0[256], str1[256];
|
||||
|
||||
sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647));
|
||||
if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
|
||||
if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH));
|
||||
sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295));
|
||||
if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
|
||||
if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH));
|
||||
#ifdef INT64_MAX
|
||||
sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807));
|
||||
if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
|
||||
if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1)));
|
||||
sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591));
|
||||
if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
|
||||
if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1)));
|
||||
#endif
|
||||
|
||||
sprintf (str0, "%d %x\n", 0, ~0);
|
||||
|
||||
sprintf (str1, "%d %x\n", i8, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1));
|
||||
sprintf (str1, "%u %x\n", u8, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1));
|
||||
sprintf (str1, "%d %x\n", i16, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1));
|
||||
sprintf (str1, "%u %x\n", u16, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1));
|
||||
sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1));
|
||||
sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1));
|
||||
#ifdef INT64_MAX
|
||||
sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1));
|
||||
#endif
|
||||
sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1));
|
||||
sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0);
|
||||
if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1));
|
||||
|
||||
TESTUMAX(8);
|
||||
TESTUMAX(16);
|
||||
TESTUMAX(32);
|
||||
#ifdef INT64_MAX
|
||||
TESTUMAX(64);
|
||||
#endif
|
||||
|
||||
#define STR(v) #v
|
||||
#define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v));
|
||||
if (err_n) {
|
||||
printf ("pstdint.h is not correct. Please use sizes below to correct it:\n");
|
||||
}
|
||||
|
||||
Q(int)
|
||||
Q(unsigned)
|
||||
Q(long int)
|
||||
Q(short int)
|
||||
Q(int8_t)
|
||||
Q(int16_t)
|
||||
Q(int32_t)
|
||||
#ifdef INT64_MAX
|
||||
Q(int64_t)
|
||||
#endif
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
43
dependencies/assimp/include/assimp/Compiler/pushpack1.h
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
|
||||
// ===============================================================================
|
||||
// May be included multiple times - sets structure packing to 1
|
||||
// for all supported compilers. #include <poppack1.h> reverts the changes.
|
||||
//
|
||||
// Currently this works on the following compilers:
|
||||
// MSVC 7,8,9
|
||||
// GCC
|
||||
// BORLAND (complains about 'pack state changed but not reverted', but works)
|
||||
// Clang
|
||||
//
|
||||
//
|
||||
// USAGE:
|
||||
//
|
||||
// struct StructToBePacked {
|
||||
// } PACK_STRUCT;
|
||||
//
|
||||
// ===============================================================================
|
||||
|
||||
#ifdef AI_PUSHPACK_IS_DEFINED
|
||||
# error poppack1.h must be included after pushpack1.h
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
|
||||
# pragma pack(push,1)
|
||||
# define PACK_STRUCT
|
||||
#elif defined( __GNUC__ ) || defined(__clang__)
|
||||
# if !defined(HOST_MINGW)
|
||||
# define PACK_STRUCT __attribute__((__packed__))
|
||||
# else
|
||||
# define PACK_STRUCT __attribute__((gcc_struct, __packed__))
|
||||
# endif
|
||||
#else
|
||||
# error Compiler not supported
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// C4103: Packing was changed after the inclusion of the header, probably missing #pragma pop
|
||||
# pragma warning (disable : 4103)
|
||||
#endif
|
||||
|
||||
#define AI_PUSHPACK_IS_DEFINED
|
58
dependencies/assimp/include/assimp/CreateAnimMesh.h
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file CreateAnimMesh.h
|
||||
* Create AnimMesh from Mesh
|
||||
*/
|
||||
#ifndef INCLUDED_AI_CREATE_ANIM_MESH_H
|
||||
#define INCLUDED_AI_CREATE_ANIM_MESH_H
|
||||
|
||||
#include <assimp/mesh.h>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
/** Create aiAnimMesh from aiMesh. */
|
||||
ASSIMP_API aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh);
|
||||
|
||||
} // end of namespace Assimp
|
||||
#endif // INCLUDED_AI_CREATE_ANIM_MESH_H
|
||||
|
140
dependencies/assimp/include/assimp/DefaultIOStream.h
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Default file I/O using fXXX()-family of functions */
|
||||
#ifndef AI_DEFAULTIOSTREAM_H_INC
|
||||
#define AI_DEFAULTIOSTREAM_H_INC
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/importerdesc.h>
|
||||
#include <assimp/Defines.h>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
//! @class DefaultIOStream
|
||||
//! @brief Default IO implementation, use standard IO operations
|
||||
//! @note An instance of this class can exist without a valid file handle
|
||||
//! attached to it. All calls fail, but the instance can nevertheless be
|
||||
//! used with no restrictions.
|
||||
class ASSIMP_API DefaultIOStream : public IOStream
|
||||
{
|
||||
friend class DefaultIOSystem;
|
||||
#if __ANDROID__
|
||||
# if __ANDROID_API__ > 9
|
||||
# if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
||||
friend class AndroidJNIIOSystem;
|
||||
# endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
||||
# endif // __ANDROID_API__ > 9
|
||||
#endif // __ANDROID__
|
||||
|
||||
protected:
|
||||
DefaultIOStream() AI_NO_EXCEPT;
|
||||
DefaultIOStream(FILE* pFile, const std::string &strFilename);
|
||||
|
||||
public:
|
||||
/** Destructor public to allow simple deletion to close the file. */
|
||||
~DefaultIOStream ();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/// Read from stream
|
||||
size_t Read(void* pvBuffer,
|
||||
size_t pSize,
|
||||
size_t pCount);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/// Write to stream
|
||||
size_t Write(const void* pvBuffer,
|
||||
size_t pSize,
|
||||
size_t pCount);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/// Seek specific position
|
||||
aiReturn Seek(size_t pOffset,
|
||||
aiOrigin pOrigin);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/// Get current seek position
|
||||
size_t Tell() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/// Get size of file
|
||||
size_t FileSize() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/// Flush file contents
|
||||
void Flush();
|
||||
|
||||
private:
|
||||
// File data-structure, using clib
|
||||
FILE* mFile;
|
||||
// Filename
|
||||
std::string mFilename;
|
||||
// Cached file size
|
||||
mutable size_t mCachedSize;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline
|
||||
DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
|
||||
: mFile(nullptr)
|
||||
, mFilename("")
|
||||
, mCachedSize(SIZE_MAX) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline
|
||||
DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
|
||||
: mFile(pFile)
|
||||
, mFilename(strFilename)
|
||||
, mCachedSize(SIZE_MAX) {
|
||||
// empty
|
||||
}
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
} // ns assimp
|
||||
|
||||
#endif //!!AI_DEFAULTIOSTREAM_H_INC
|
||||
|
93
dependencies/assimp/include/assimp/DefaultIOSystem.h
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Default implementation of IOSystem using the standard C file functions */
|
||||
#ifndef AI_DEFAULTIOSYSTEM_H_INC
|
||||
#define AI_DEFAULTIOSYSTEM_H_INC
|
||||
|
||||
#include <assimp/IOSystem.hpp>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Default implementation of IOSystem using the standard C file functions */
|
||||
class ASSIMP_API DefaultIOSystem : public IOSystem {
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** Tests for the existence of a file at the given path. */
|
||||
bool Exists( const char* pFile) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns the directory separator. */
|
||||
char getOsSeparator() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Open a new file with a given path. */
|
||||
IOStream* Open( const char* pFile, const char* pMode = "rb");
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Closes the given file and releases all resources associated with it. */
|
||||
void Close( IOStream* pFile);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Compare two paths */
|
||||
bool ComparePaths (const char* one, const char* second) const;
|
||||
|
||||
/** @brief get the file name of a full filepath
|
||||
* example: /tmp/archive.tar.gz -> archive.tar.gz
|
||||
*/
|
||||
static std::string fileName( const std::string &path );
|
||||
|
||||
/** @brief get the complete base name of a full filepath
|
||||
* example: /tmp/archive.tar.gz -> archive.tar
|
||||
*/
|
||||
static std::string completeBaseName( const std::string &path);
|
||||
|
||||
/** @brief get the path of a full filepath
|
||||
* example: /tmp/archive.tar.gz -> /tmp/
|
||||
*/
|
||||
static std::string absolutePath( const std::string &path);
|
||||
};
|
||||
|
||||
} //!ns Assimp
|
||||
|
||||
#endif //AI_DEFAULTIOSYSTEM_H_INC
|
188
dependencies/assimp/include/assimp/DefaultLogger.hpp
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
/** @file DefaultLogger.hpp
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_AI_DEFAULTLOGGER
|
||||
#define INCLUDED_AI_DEFAULTLOGGER
|
||||
|
||||
#include "Logger.hpp"
|
||||
#include "LogStream.hpp"
|
||||
#include "NullLogger.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace Assimp {
|
||||
// ------------------------------------------------------------------------------------
|
||||
class IOStream;
|
||||
struct LogStreamInfo;
|
||||
|
||||
/** default name of logfile */
|
||||
#define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt"
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
/** @brief CPP-API: Primary logging facility of Assimp.
|
||||
*
|
||||
* The library stores its primary #Logger as a static member of this class.
|
||||
* #get() returns this primary logger. By default the underlying implementation is
|
||||
* just a #NullLogger which rejects all log messages. By calling #create(), logging
|
||||
* is turned on. To capture the log output multiple log streams (#LogStream) can be
|
||||
* attach to the logger. Some default streams for common streaming locations (such as
|
||||
* a file, std::cout, OutputDebugString()) are also provided.
|
||||
*
|
||||
* If you wish to customize the logging at an even deeper level supply your own
|
||||
* implementation of #Logger to #set().
|
||||
* @note The whole logging stuff causes a small extra overhead for all imports. */
|
||||
class ASSIMP_API DefaultLogger :
|
||||
public Logger {
|
||||
|
||||
public:
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Creates a logging instance.
|
||||
* @param name Name for log file. Only valid in combination
|
||||
* with the aiDefaultLogStream_FILE flag.
|
||||
* @param severity Log severity, VERBOSE turns on debug messages
|
||||
* @param defStreams Default log streams to be attached. Any bitwise
|
||||
* combination of the aiDefaultLogStream enumerated values.
|
||||
* If #aiDefaultLogStream_FILE is specified but an empty string is
|
||||
* passed for 'name', no log file is created at all.
|
||||
* @param io IOSystem to be used to open external files (such as the
|
||||
* log file). Pass NULL to rely on the default implementation.
|
||||
* This replaces the default #NullLogger with a #DefaultLogger instance. */
|
||||
static Logger *create(const char* name = ASSIMP_DEFAULT_LOG_NAME,
|
||||
LogSeverity severity = NORMAL,
|
||||
unsigned int defStreams = aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE,
|
||||
IOSystem* io = NULL);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Setup a custom #Logger implementation.
|
||||
*
|
||||
* Use this if the provided #DefaultLogger class doesn't fit into
|
||||
* your needs. If the provided message formatting is OK for you,
|
||||
* it's much easier to use #create() and to attach your own custom
|
||||
* output streams to it.
|
||||
* @param logger Pass NULL to setup a default NullLogger*/
|
||||
static void set (Logger *logger);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Getter for singleton instance
|
||||
* @return Only instance. This is never null, but it could be a
|
||||
* NullLogger. Use isNullLogger to check this.*/
|
||||
static Logger *get();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Return whether a #NullLogger is currently active
|
||||
* @return true if the current logger is a #NullLogger.
|
||||
* Use create() or set() to setup a logger that does actually do
|
||||
* something else than just rejecting all log messages. */
|
||||
static bool isNullLogger();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Kills the current singleton logger and replaces it with a
|
||||
* #NullLogger instance. */
|
||||
static void kill();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @copydoc Logger::attachStream */
|
||||
bool attachStream(LogStream *pStream,
|
||||
unsigned int severity);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @copydoc Logger::detatchStream */
|
||||
bool detatchStream(LogStream *pStream,
|
||||
unsigned int severity);
|
||||
|
||||
private:
|
||||
// ----------------------------------------------------------------------
|
||||
/** @briefPrivate construction for internal use by create().
|
||||
* @param severity Logging granularity */
|
||||
explicit DefaultLogger(LogSeverity severity);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @briefDestructor */
|
||||
~DefaultLogger();
|
||||
|
||||
/** @brief Logs debug infos, only been written when severity level VERBOSE is set */
|
||||
void OnDebug(const char* message);
|
||||
|
||||
/** @brief Logs an info message */
|
||||
void OnInfo(const char* message);
|
||||
|
||||
/** @brief Logs a warning message */
|
||||
void OnWarn(const char* message);
|
||||
|
||||
/** @brief Logs an error message */
|
||||
void OnError(const char* message);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Writes a message to all streams */
|
||||
void WriteToStreams(const char* message, ErrorSeverity ErrorSev );
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Returns the thread id.
|
||||
* @note This is an OS specific feature, if not supported, a
|
||||
* zero will be returned.
|
||||
*/
|
||||
unsigned int GetThreadID();
|
||||
|
||||
private:
|
||||
// Aliases for stream container
|
||||
typedef std::vector<LogStreamInfo*> StreamArray;
|
||||
typedef std::vector<LogStreamInfo*>::iterator StreamIt;
|
||||
typedef std::vector<LogStreamInfo*>::const_iterator ConstStreamIt;
|
||||
|
||||
//! only logging instance
|
||||
static Logger *m_pLogger;
|
||||
static NullLogger s_pNullLogger;
|
||||
|
||||
//! Attached streams
|
||||
StreamArray m_StreamArray;
|
||||
|
||||
bool noRepeatMsg;
|
||||
char lastMsg[MAX_LOG_MESSAGE_LENGTH*2];
|
||||
size_t lastLen;
|
||||
};
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // !! INCLUDED_AI_DEFAULTLOGGER
|
49
dependencies/assimp/include/assimp/Defines.h
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2012, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// We need those constants, workaround for any platforms where nobody defined them yet
|
||||
#if (!defined SIZE_MAX)
|
||||
# define SIZE_MAX (~((size_t)0))
|
||||
#endif
|
||||
|
||||
#if (!defined UINT_MAX)
|
||||
# define UINT_MAX (~((unsigned int)0))
|
||||
#endif
|
||||
|
125
dependencies/assimp/include/assimp/Exceptional.h
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_EXCEPTIONAL_H
|
||||
#define INCLUDED_EXCEPTIONAL_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include <assimp/DefaultIOStream.h>
|
||||
using std::runtime_error;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable : 4275)
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an
|
||||
* unrecoverable error occurs while importing. Loading APIs return
|
||||
* NULL instead of a valid aiScene then. */
|
||||
class DeadlyImportError
|
||||
: public runtime_error
|
||||
{
|
||||
public:
|
||||
/** Constructor with arguments */
|
||||
explicit DeadlyImportError( const std::string& errorText)
|
||||
: runtime_error(errorText)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
typedef DeadlyImportError DeadlyExportError;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(default : 4275)
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct ExceptionSwallower {
|
||||
T operator ()() const {
|
||||
return T();
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct ExceptionSwallower<T*> {
|
||||
T* operator ()() const {
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template <>
|
||||
struct ExceptionSwallower<aiReturn> {
|
||||
aiReturn operator ()() const {
|
||||
try {
|
||||
throw;
|
||||
}
|
||||
catch (std::bad_alloc&) {
|
||||
return aiReturn_OUTOFMEMORY;
|
||||
}
|
||||
catch (...) {
|
||||
return aiReturn_FAILURE;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template <>
|
||||
struct ExceptionSwallower<void> {
|
||||
void operator ()() const {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
#define ASSIMP_BEGIN_EXCEPTION_REGION()\
|
||||
{\
|
||||
try {
|
||||
|
||||
#define ASSIMP_END_EXCEPTION_REGION(type)\
|
||||
} catch(...) {\
|
||||
return ExceptionSwallower<type>()();\
|
||||
}\
|
||||
}
|
||||
|
||||
#endif // INCLUDED_EXCEPTIONAL_H
|
505
dependencies/assimp/include/assimp/Exporter.hpp
vendored
Normal file
@ -0,0 +1,505 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Exporter.hpp
|
||||
* @brief Defines the CPP-API for the Assimp export interface
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef AI_EXPORT_HPP_INC
|
||||
#define AI_EXPORT_HPP_INC
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
|
||||
#include "cexport.h"
|
||||
#include <map>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
class ExporterPimpl;
|
||||
class IOSystem;
|
||||
class ProgressHandler;
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
/** CPP-API: The Exporter class forms an C++ interface to the export functionality
|
||||
* of the Open Asset Import Library. Note that the export interface is available
|
||||
* only if Assimp has been built with ASSIMP_BUILD_NO_EXPORT not defined.
|
||||
*
|
||||
* The interface is modeled after the importer interface and mostly
|
||||
* symmetric. The same rules for threading etc. apply.
|
||||
*
|
||||
* In a nutshell, there are two export interfaces: #Export, which writes the
|
||||
* output file(s) either to the regular file system or to a user-supplied
|
||||
* #IOSystem, and #ExportToBlob which returns a linked list of memory
|
||||
* buffers (blob), each referring to one output file (in most cases
|
||||
* there will be only one output file of course, but this extra complexity is
|
||||
* needed since Assimp aims at supporting a wide range of file formats).
|
||||
*
|
||||
* #ExportToBlob is especially useful if you intend to work
|
||||
* with the data in-memory.
|
||||
*/
|
||||
class ASSIMP_API ExportProperties;
|
||||
|
||||
class ASSIMP_API Exporter {
|
||||
public:
|
||||
/** Function pointer type of a Export worker function */
|
||||
typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
|
||||
/** Internal description of an Assimp export format option */
|
||||
struct ExportFormatEntry {
|
||||
/// Public description structure to be returned by aiGetExportFormatDescription()
|
||||
aiExportFormatDesc mDescription;
|
||||
|
||||
// Worker function to do the actual exporting
|
||||
fpExportFunc mExportFunction;
|
||||
|
||||
// Post-processing steps to be executed PRIOR to invoking mExportFunction
|
||||
unsigned int mEnforcePP;
|
||||
|
||||
// Constructor to fill all entries
|
||||
ExportFormatEntry( const char* pId, const char* pDesc, const char* pExtension, fpExportFunc pFunction, unsigned int pEnforcePP = 0u)
|
||||
{
|
||||
mDescription.id = pId;
|
||||
mDescription.description = pDesc;
|
||||
mDescription.fileExtension = pExtension;
|
||||
mExportFunction = pFunction;
|
||||
mEnforcePP = pEnforcePP;
|
||||
}
|
||||
|
||||
ExportFormatEntry() :
|
||||
mExportFunction()
|
||||
, mEnforcePP()
|
||||
{
|
||||
mDescription.id = NULL;
|
||||
mDescription.description = NULL;
|
||||
mDescription.fileExtension = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The class constructor.
|
||||
*/
|
||||
Exporter();
|
||||
|
||||
/**
|
||||
* @brief The class destructor.
|
||||
*/
|
||||
~Exporter();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Supplies a custom IO handler to the exporter to use to open and
|
||||
* access files.
|
||||
*
|
||||
* If you need #Export to use custom IO logic to access the files,
|
||||
* you need to supply a custom implementation of IOSystem and
|
||||
* IOFile to the exporter.
|
||||
*
|
||||
* #Exporter takes ownership of the object and will destroy it
|
||||
* afterwards. The previously assigned handler will be deleted.
|
||||
* Pass NULL to take again ownership of your IOSystem and reset Assimp
|
||||
* to use its default implementation, which uses plain file IO.
|
||||
*
|
||||
* @param pIOHandler The IO handler to be used in all file accesses
|
||||
* of the Importer. */
|
||||
void SetIOHandler( IOSystem* pIOHandler);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Retrieves the IO handler that is currently set.
|
||||
* You can use #IsDefaultIOHandler() to check whether the returned
|
||||
* interface is the default IO handler provided by ASSIMP. The default
|
||||
* handler is active as long the application doesn't supply its own
|
||||
* custom IO handler via #SetIOHandler().
|
||||
* @return A valid IOSystem interface, never NULL. */
|
||||
IOSystem* GetIOHandler() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Checks whether a default IO handler is active
|
||||
* A default handler is active as long the application doesn't
|
||||
* supply its own custom IO handler via #SetIOHandler().
|
||||
* @return true by default */
|
||||
bool IsDefaultIOHandler() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Supplies a custom progress handler to the exporter. This
|
||||
* interface exposes an #Update() callback, which is called
|
||||
* more or less periodically (please don't sue us if it
|
||||
* isn't as periodically as you'd like it to have ...).
|
||||
* This can be used to implement progress bars and loading
|
||||
* timeouts.
|
||||
* @param pHandler Progress callback interface. Pass nullptr to
|
||||
* disable progress reporting.
|
||||
* @note Progress handlers can be used to abort the loading
|
||||
* at almost any time.*/
|
||||
void SetProgressHandler(ProgressHandler* pHandler);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Exports the given scene to a chosen file format. Returns the exported
|
||||
* data as a binary blob which you can write into a file or something.
|
||||
* When you're done with the data, simply let the #Exporter instance go
|
||||
* out of scope to have it released automatically.
|
||||
* @param pScene The scene to export. Stays in possession of the caller,
|
||||
* is not changed by the function.
|
||||
* @param pFormatId ID string to specify to which format you want to
|
||||
* export to. Use
|
||||
* #GetExportFormatCount / #GetExportFormatDescription to learn which
|
||||
* export formats are available.
|
||||
* @param pPreprocessing See the documentation for #Export
|
||||
* @return the exported data or NULL in case of error.
|
||||
* @note If the Exporter instance did already hold a blob from
|
||||
* a previous call to #ExportToBlob, it will be disposed.
|
||||
* Any IO handlers set via #SetIOHandler are ignored here.
|
||||
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||
* imported scene. */
|
||||
const aiExportDataBlob* ExportToBlob(const aiScene* pScene, const char* pFormatId,
|
||||
unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
|
||||
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId,
|
||||
unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Convenience function to export directly to a file. Use
|
||||
* #SetIOSystem to supply a custom IOSystem to gain fine-grained control
|
||||
* about the output data flow of the export process.
|
||||
* @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL.
|
||||
* @param pPath Full target file name. Target must be accessible.
|
||||
* @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated
|
||||
* flags, but in reality only a subset of them makes sense here. Specifying
|
||||
* 'preprocessing' flags is useful if the input scene does not conform to
|
||||
* Assimp's default conventions as specified in the @link data Data Structures Page @endlink.
|
||||
* In short, this means the geometry data should use a right-handed coordinate systems, face
|
||||
* winding should be counter-clockwise and the UV coordinate origin is assumed to be in
|
||||
* the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
|
||||
* #aiProcess_FlipWindingOrder flags are used in the import side to allow users
|
||||
* to have those defaults automatically adapted to their conventions. Specifying those flags
|
||||
* for exporting has the opposite effect, respectively. Some other of the
|
||||
* #aiPostProcessSteps enumerated values may be useful as well, but you'll need
|
||||
* to try out what their effect on the exported file is. Many formats impose
|
||||
* their own restrictions on the structure of the geometry stored therein,
|
||||
* so some preprocessing may have little or no effect at all, or may be
|
||||
* redundant as exporters would apply them anyhow. A good example
|
||||
* is triangulation - whilst you can enforce it by specifying
|
||||
* the #aiProcess_Triangulate flag, most export formats support only
|
||||
* triangulate data so they would run the step even if it wasn't requested.
|
||||
*
|
||||
* If assimp detects that the input scene was directly taken from the importer side of
|
||||
* the library (i.e. not copied using aiCopyScene and potentially modified afterwards),
|
||||
* any post-processing steps already applied to the scene will not be applied again, unless
|
||||
* they show non-idempotent behavior (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
|
||||
* #aiProcess_FlipWindingOrder).
|
||||
* @return AI_SUCCESS if everything was fine.
|
||||
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||
* imported scene.*/
|
||||
aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
|
||||
unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
|
||||
aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath,
|
||||
unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns an error description of an error that occurred in #Export
|
||||
* or #ExportToBlob
|
||||
*
|
||||
* Returns an empty string if no error occurred.
|
||||
* @return A description of the last error, an empty string if no
|
||||
* error occurred. The string is never NULL.
|
||||
*
|
||||
* @note The returned function remains valid until one of the
|
||||
* following methods is called: #Export, #ExportToBlob, #FreeBlob */
|
||||
const char* GetErrorString() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Return the blob obtained from the last call to #ExportToBlob */
|
||||
const aiExportDataBlob* GetBlob() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Orphan the blob from the last call to #ExportToBlob. This means
|
||||
* the caller takes ownership and is thus responsible for calling
|
||||
* the C API function #aiReleaseExportBlob to release it. */
|
||||
const aiExportDataBlob* GetOrphanedBlob() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Frees the current blob.
|
||||
*
|
||||
* The function does nothing if no blob has previously been
|
||||
* previously produced via #ExportToBlob. #FreeBlob is called
|
||||
* automatically by the destructor. The only reason to call
|
||||
* it manually would be to reclaim as much storage as possible
|
||||
* without giving up the #Exporter instance yet. */
|
||||
void FreeBlob( );
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns the number of export file formats available in the current
|
||||
* Assimp build. Use #Exporter::GetExportFormatDescription to
|
||||
* retrieve infos of a specific export format.
|
||||
*
|
||||
* This includes built-in exporters as well as exporters registered
|
||||
* using #RegisterExporter.
|
||||
**/
|
||||
size_t GetExportFormatCount() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns a description of the nth export file format. Use #
|
||||
* #Exporter::GetExportFormatCount to learn how many export
|
||||
* formats are supported.
|
||||
*
|
||||
* The returned pointer is of static storage duration if the
|
||||
* pIndex pertains to a built-in exporter (i.e. one not registered
|
||||
* via #RegistrerExporter). It is restricted to the life-time of the
|
||||
* #Exporter instance otherwise.
|
||||
*
|
||||
* @param pIndex Index of the export format to retrieve information
|
||||
* for. Valid range is 0 to #Exporter::GetExportFormatCount
|
||||
* @return A description of that specific export format.
|
||||
* NULL if pIndex is out of range. */
|
||||
const aiExportFormatDesc* GetExportFormatDescription( size_t pIndex ) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Register a custom exporter. Custom export formats are limited to
|
||||
* to the current #Exporter instance and do not affect the
|
||||
* library globally. The indexes under which the format's
|
||||
* export format description can be queried are assigned
|
||||
* monotonously.
|
||||
* @param desc Exporter description.
|
||||
* @return aiReturn_SUCCESS if the export format was successfully
|
||||
* registered. A common cause that would prevent an exporter
|
||||
* from being registered is that its format id is already
|
||||
* occupied by another format. */
|
||||
aiReturn RegisterExporter(const ExportFormatEntry& desc);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Remove an export format previously registered with #RegisterExporter
|
||||
* from the #Exporter instance (this can also be used to drop
|
||||
* built-in exporters because those are implicitly registered
|
||||
* using #RegisterExporter).
|
||||
* @param id Format id to be unregistered, this refers to the
|
||||
* 'id' field of #aiExportFormatDesc.
|
||||
* @note Calling this method on a format description not yet registered
|
||||
* has no effect.*/
|
||||
void UnregisterExporter(const char* id);
|
||||
|
||||
protected:
|
||||
// Just because we don't want you to know how we're hacking around.
|
||||
ExporterPimpl* pimpl;
|
||||
};
|
||||
|
||||
class ASSIMP_API ExportProperties {
|
||||
public:
|
||||
// Data type to store the key hash
|
||||
typedef unsigned int KeyType;
|
||||
|
||||
// typedefs for our four configuration maps.
|
||||
// We don't need more, so there is no need for a generic solution
|
||||
typedef std::map<KeyType, int> IntPropertyMap;
|
||||
typedef std::map<KeyType, ai_real> FloatPropertyMap;
|
||||
typedef std::map<KeyType, std::string> StringPropertyMap;
|
||||
typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
|
||||
|
||||
public:
|
||||
/** Standard constructor
|
||||
* @see ExportProperties()
|
||||
*/
|
||||
ExportProperties();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Copy constructor.
|
||||
*
|
||||
* This copies the configuration properties of another ExportProperties.
|
||||
* @see ExportProperties(const ExportProperties& other)
|
||||
*/
|
||||
ExportProperties(const ExportProperties& other);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Set an integer configuration property.
|
||||
* @param szName Name of the property. All supported properties
|
||||
* are defined in the aiConfig.g header (all constants share the
|
||||
* prefix AI_CONFIG_XXX and are simple strings).
|
||||
* @param iValue New value of the property
|
||||
* @return true if the property was set before. The new value replaces
|
||||
* the previous value in this case.
|
||||
* @note Property of different types (float, int, string ..) are kept
|
||||
* on different stacks, so calling SetPropertyInteger() for a
|
||||
* floating-point property has no effect - the loader will call
|
||||
* GetPropertyFloat() to read the property, but it won't be there.
|
||||
*/
|
||||
bool SetPropertyInteger(const char* szName, int iValue);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Set a boolean configuration property. Boolean properties
|
||||
* are stored on the integer stack internally so it's possible
|
||||
* to set them via #SetPropertyBool and query them with
|
||||
* #GetPropertyBool and vice versa.
|
||||
* @see SetPropertyInteger()
|
||||
*/
|
||||
bool SetPropertyBool(const char* szName, bool value) {
|
||||
return SetPropertyInteger(szName,value);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Set a floating-point configuration property.
|
||||
* @see SetPropertyInteger()
|
||||
*/
|
||||
bool SetPropertyFloat(const char* szName, ai_real fValue);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Set a string configuration property.
|
||||
* @see SetPropertyInteger()
|
||||
*/
|
||||
bool SetPropertyString(const char* szName, const std::string& sValue);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Set a matrix configuration property.
|
||||
* @see SetPropertyInteger()
|
||||
*/
|
||||
bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a configuration property.
|
||||
* @param szName Name of the property. All supported properties
|
||||
* are defined in the aiConfig.g header (all constants share the
|
||||
* prefix AI_CONFIG_XXX).
|
||||
* @param iErrorReturn Value that is returned if the property
|
||||
* is not found.
|
||||
* @return Current value of the property
|
||||
* @note Property of different types (float, int, string ..) are kept
|
||||
* on different lists, so calling SetPropertyInteger() for a
|
||||
* floating-point property has no effect - the loader will call
|
||||
* GetPropertyFloat() to read the property, but it won't be there.
|
||||
*/
|
||||
int GetPropertyInteger(const char* szName,
|
||||
int iErrorReturn = 0xffffffff) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a boolean configuration property. Boolean properties
|
||||
* are stored on the integer stack internally so it's possible
|
||||
* to set them via #SetPropertyBool and query them with
|
||||
* #GetPropertyBool and vice versa.
|
||||
* @see GetPropertyInteger()
|
||||
*/
|
||||
bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
|
||||
return GetPropertyInteger(szName,bErrorReturn)!=0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a floating-point configuration property
|
||||
* @see GetPropertyInteger()
|
||||
*/
|
||||
ai_real GetPropertyFloat(const char* szName,
|
||||
ai_real fErrorReturn = 10e10f) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a string configuration property
|
||||
*
|
||||
* The return value remains valid until the property is modified.
|
||||
* @see GetPropertyInteger()
|
||||
*/
|
||||
const std::string GetPropertyString(const char* szName,
|
||||
const std::string& sErrorReturn = "") const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a matrix configuration property
|
||||
*
|
||||
* The return value remains valid until the property is modified.
|
||||
* @see GetPropertyInteger()
|
||||
*/
|
||||
const aiMatrix4x4 GetPropertyMatrix(const char* szName,
|
||||
const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Determine a integer configuration property has been set.
|
||||
* @see HasPropertyInteger()
|
||||
*/
|
||||
bool HasPropertyInteger(const char* szName) const;
|
||||
|
||||
/** Determine a boolean configuration property has been set.
|
||||
* @see HasPropertyBool()
|
||||
*/
|
||||
bool HasPropertyBool(const char* szName) const;
|
||||
|
||||
/** Determine a boolean configuration property has been set.
|
||||
* @see HasPropertyFloat()
|
||||
*/
|
||||
bool HasPropertyFloat(const char* szName) const;
|
||||
|
||||
/** Determine a String configuration property has been set.
|
||||
* @see HasPropertyString()
|
||||
*/
|
||||
bool HasPropertyString(const char* szName) const;
|
||||
|
||||
/** Determine a Matrix configuration property has been set.
|
||||
* @see HasPropertyMatrix()
|
||||
*/
|
||||
bool HasPropertyMatrix(const char* szName) const;
|
||||
|
||||
protected:
|
||||
|
||||
/** List of integer properties */
|
||||
IntPropertyMap mIntProperties;
|
||||
|
||||
/** List of floating-point properties */
|
||||
FloatPropertyMap mFloatProperties;
|
||||
|
||||
/** List of string properties */
|
||||
StringPropertyMap mStringProperties;
|
||||
|
||||
/** List of Matrix properties */
|
||||
MatrixPropertyMap mMatrixProperties;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline
|
||||
const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const std::string& pFormatId,
|
||||
unsigned int pPreprocessing, const ExportProperties* pProperties)
|
||||
{
|
||||
return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing, pProperties);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline
|
||||
aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId,
|
||||
const std::string& pPath, unsigned int pPreprocessing,
|
||||
const ExportProperties* pProperties)
|
||||
{
|
||||
return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing, pProperties);
|
||||
}
|
||||
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||
#endif // AI_EXPORT_HPP_INC
|
133
dependencies/assimp/include/assimp/GenericProperty.h
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef AI_GENERIC_PROPERTY_H_INCLUDED
|
||||
#define AI_GENERIC_PROPERTY_H_INCLUDED
|
||||
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/ai_assert.h>
|
||||
#include "Hash.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline
|
||||
bool SetGenericProperty(std::map< unsigned int, T >& list,
|
||||
const char* szName, const T& value) {
|
||||
ai_assert(nullptr != szName);
|
||||
const uint32_t hash = SuperFastHash(szName);
|
||||
|
||||
typename std::map<unsigned int, T>::iterator it = list.find(hash);
|
||||
if (it == list.end()) {
|
||||
list.insert(std::pair<unsigned int, T>( hash, value ));
|
||||
return false;
|
||||
}
|
||||
(*it).second = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline
|
||||
const T& GetGenericProperty(const std::map< unsigned int, T >& list,
|
||||
const char* szName, const T& errorReturn) {
|
||||
ai_assert(nullptr != szName);
|
||||
const uint32_t hash = SuperFastHash(szName);
|
||||
|
||||
typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
|
||||
if (it == list.end()) {
|
||||
return errorReturn;
|
||||
}
|
||||
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Special version for pointer types - they will be deleted when replaced with another value
|
||||
// passing NULL removes the whole property
|
||||
template <class T>
|
||||
inline
|
||||
void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
|
||||
const char* szName, T* value, bool* bWasExisting = nullptr ) {
|
||||
ai_assert(nullptr != szName);
|
||||
const uint32_t hash = SuperFastHash(szName);
|
||||
|
||||
typename std::map<unsigned int, T*>::iterator it = list.find(hash);
|
||||
if (it == list.end()) {
|
||||
if (bWasExisting) {
|
||||
*bWasExisting = false;
|
||||
}
|
||||
|
||||
list.insert(std::pair<unsigned int,T*>( hash, value ));
|
||||
return;
|
||||
}
|
||||
if ((*it).second != value) {
|
||||
delete (*it).second;
|
||||
(*it).second = value;
|
||||
}
|
||||
if (!value) {
|
||||
list.erase(it);
|
||||
}
|
||||
if (bWasExisting) {
|
||||
*bWasExisting = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline
|
||||
bool HasGenericProperty(const std::map< unsigned int, T >& list,
|
||||
const char* szName) {
|
||||
ai_assert(nullptr != szName);
|
||||
const uint32_t hash = SuperFastHash(szName);
|
||||
|
||||
typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
|
||||
if (it == list.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED
|
118
dependencies/assimp/include/assimp/Hash.h
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef AI_HASH_H_INCLUDED
|
||||
#define AI_HASH_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Hashing function taken from
|
||||
// http://www.azillionmonkeys.com/qed/hash.html
|
||||
// (incremental version)
|
||||
//
|
||||
// This code is Copyright 2004-2008 by Paul Hsieh. It is used here in the belief that
|
||||
// Assimp's license is considered compatible with Pauls's derivative license as specified
|
||||
// on his web page.
|
||||
//
|
||||
// (stdint.h should have been been included here)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#undef get16bits
|
||||
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
||||
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
||||
#define get16bits(d) (*((const uint16_t *) (d)))
|
||||
#endif
|
||||
|
||||
#if !defined (get16bits)
|
||||
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
|
||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) {
|
||||
uint32_t tmp;
|
||||
int rem;
|
||||
|
||||
if (!data) return 0;
|
||||
if (!len)len = (uint32_t)::strlen(data);
|
||||
|
||||
rem = len & 3;
|
||||
len >>= 2;
|
||||
|
||||
/* Main loop */
|
||||
for (;len > 0; len--) {
|
||||
hash += get16bits (data);
|
||||
tmp = (get16bits (data+2) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2*sizeof (uint16_t);
|
||||
hash += hash >> 11;
|
||||
}
|
||||
|
||||
/* Handle end cases */
|
||||
switch (rem) {
|
||||
case 3: hash += get16bits (data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= data[sizeof (uint16_t)] << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2: hash += get16bits (data);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
break;
|
||||
case 1: hash += *data;
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
||||
/* Force "avalanching" of final 127 bits */
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
#endif // !! AI_HASH_H_INCLUDED
|
142
dependencies/assimp/include/assimp/IOStream.hpp
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
/** @file IOStream.hpp
|
||||
* @brief File I/O wrappers for C++.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef AI_IOSTREAM_H_INC
|
||||
#define AI_IOSTREAM_H_INC
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This header requires C++ to be used. aiFileIO.h is the \
|
||||
corresponding C interface.
|
||||
#endif
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
/** @brief CPP-API: Class to handle file I/O for C++
|
||||
*
|
||||
* Derive an own implementation from this interface to provide custom IO handling
|
||||
* to the Importer. If you implement this interface, be sure to also provide an
|
||||
* implementation for IOSystem that creates instances of your custom IO class.
|
||||
*/
|
||||
class ASSIMP_API IOStream
|
||||
#ifndef SWIG
|
||||
: public Intern::AllocateFromAssimpHeap
|
||||
#endif
|
||||
{
|
||||
protected:
|
||||
/** Constructor protected, use IOSystem::Open() to create an instance. */
|
||||
IOStream() AI_NO_EXCEPT;
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Destructor. Deleting the object closes the underlying file,
|
||||
* alternatively you may use IOSystem::Close() to release the file.
|
||||
*/
|
||||
virtual ~IOStream();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Read from the file
|
||||
*
|
||||
* See fread() for more details
|
||||
* This fails for write-only files */
|
||||
virtual size_t Read(void* pvBuffer,
|
||||
size_t pSize,
|
||||
size_t pCount) = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Write to the file
|
||||
*
|
||||
* See fwrite() for more details
|
||||
* This fails for read-only files */
|
||||
virtual size_t Write(const void* pvBuffer,
|
||||
size_t pSize,
|
||||
size_t pCount) = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Set the read/write cursor of the file
|
||||
*
|
||||
* Note that the offset is _negative_ for aiOrigin_END.
|
||||
* See fseek() for more details */
|
||||
virtual aiReturn Seek(size_t pOffset,
|
||||
aiOrigin pOrigin) = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Get the current position of the read/write cursor
|
||||
*
|
||||
* See ftell() for more details */
|
||||
virtual size_t Tell() const = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Returns filesize
|
||||
* Returns the filesize. */
|
||||
virtual size_t FileSize() const = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Flush the contents of the file buffer (for writers)
|
||||
* See fflush() for more details.
|
||||
*/
|
||||
virtual void Flush() = 0;
|
||||
}; //! class IOStream
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline
|
||||
IOStream::IOStream() AI_NO_EXCEPT {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline
|
||||
IOStream::~IOStream() {
|
||||
// empty
|
||||
}
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
} //!namespace Assimp
|
||||
|
||||
#endif //!!AI_IOSTREAM_H_INC
|
355
dependencies/assimp/include/assimp/IOStreamBuffer.h
vendored
Normal file
@ -0,0 +1,355 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <assimp/types.h>
|
||||
#include <assimp/IOStream.hpp>
|
||||
|
||||
#include "ParsingUtils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* Implementation of a cached stream buffer.
|
||||
*/
|
||||
template<class T>
|
||||
class IOStreamBuffer {
|
||||
public:
|
||||
/// @brief The class constructor.
|
||||
IOStreamBuffer( size_t cache = 4096 * 4096 );
|
||||
|
||||
/// @brief The class destructor.
|
||||
~IOStreamBuffer();
|
||||
|
||||
/// @brief Will open the cached access for a given stream.
|
||||
/// @param stream The stream to cache.
|
||||
/// @return true if successful.
|
||||
bool open( IOStream *stream );
|
||||
|
||||
/// @brief Will close the cached access.
|
||||
/// @return true if successful.
|
||||
bool close();
|
||||
|
||||
/// @brief Returns the file-size.
|
||||
/// @return The file-size.
|
||||
size_t size() const;
|
||||
|
||||
/// @brief Returns the cache size.
|
||||
/// @return The cache size.
|
||||
size_t cacheSize() const;
|
||||
|
||||
/// @brief Will read the next block.
|
||||
/// @return true if successful.
|
||||
bool readNextBlock();
|
||||
|
||||
/// @brief Returns the number of blocks to read.
|
||||
/// @return The number of blocks.
|
||||
size_t getNumBlocks() const;
|
||||
|
||||
/// @brief Returns the current block index.
|
||||
/// @return The current block index.
|
||||
size_t getCurrentBlockIndex() const;
|
||||
|
||||
/// @brief Returns the current file pos.
|
||||
/// @return The current file pos.
|
||||
size_t getFilePos() const;
|
||||
|
||||
/// @brief Will read the next line.
|
||||
/// @param buffer The buffer for the next line.
|
||||
/// @return true if successful.
|
||||
bool getNextDataLine( std::vector<T> &buffer, T continuationToken );
|
||||
|
||||
/// @brief Will read the next line ascii or binary end line char.
|
||||
/// @param buffer The buffer for the next line.
|
||||
/// @return true if successful.
|
||||
bool getNextLine(std::vector<T> &buffer);
|
||||
|
||||
/// @brief Will read the next block.
|
||||
/// @param buffer The buffer for the next block.
|
||||
/// @return true if successful.
|
||||
bool getNextBlock( std::vector<T> &buffer );
|
||||
|
||||
private:
|
||||
IOStream *m_stream;
|
||||
size_t m_filesize;
|
||||
size_t m_cacheSize;
|
||||
size_t m_numBlocks;
|
||||
size_t m_blockIdx;
|
||||
std::vector<T> m_cache;
|
||||
size_t m_cachePos;
|
||||
size_t m_filePos;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
|
||||
: m_stream( nullptr )
|
||||
, m_filesize( 0 )
|
||||
, m_cacheSize( cache )
|
||||
, m_numBlocks( 0 )
|
||||
, m_blockIdx( 0 )
|
||||
, m_cachePos( 0 )
|
||||
, m_filePos( 0 ) {
|
||||
m_cache.resize( cache );
|
||||
std::fill( m_cache.begin(), m_cache.end(), '\n' );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
IOStreamBuffer<T>::~IOStreamBuffer() {
|
||||
// empty
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool IOStreamBuffer<T>::open( IOStream *stream ) {
|
||||
// file still opened!
|
||||
if ( nullptr != m_stream ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Invalid stream pointer
|
||||
if ( nullptr == stream ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_stream = stream;
|
||||
m_filesize = m_stream->FileSize();
|
||||
if ( m_filesize == 0 ) {
|
||||
return false;
|
||||
}
|
||||
if ( m_filesize < m_cacheSize ) {
|
||||
m_cacheSize = m_filesize;
|
||||
}
|
||||
|
||||
m_numBlocks = m_filesize / m_cacheSize;
|
||||
if ( ( m_filesize % m_cacheSize ) > 0 ) {
|
||||
m_numBlocks++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool IOStreamBuffer<T>::close() {
|
||||
if ( nullptr == m_stream ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// init counters and state vars
|
||||
m_stream = nullptr;
|
||||
m_filesize = 0;
|
||||
m_numBlocks = 0;
|
||||
m_blockIdx = 0;
|
||||
m_cachePos = 0;
|
||||
m_filePos = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
size_t IOStreamBuffer<T>::size() const {
|
||||
return m_filesize;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
size_t IOStreamBuffer<T>::cacheSize() const {
|
||||
return m_cacheSize;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool IOStreamBuffer<T>::readNextBlock() {
|
||||
m_stream->Seek( m_filePos, aiOrigin_SET );
|
||||
size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize );
|
||||
if ( readLen == 0 ) {
|
||||
return false;
|
||||
}
|
||||
if ( readLen < m_cacheSize ) {
|
||||
m_cacheSize = readLen;
|
||||
}
|
||||
m_filePos += m_cacheSize;
|
||||
m_cachePos = 0;
|
||||
m_blockIdx++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
size_t IOStreamBuffer<T>::getNumBlocks() const {
|
||||
return m_numBlocks;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
size_t IOStreamBuffer<T>::getCurrentBlockIndex() const {
|
||||
return m_blockIdx;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
size_t IOStreamBuffer<T>::getFilePos() const {
|
||||
return m_filePos;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
|
||||
buffer.resize( m_cacheSize );
|
||||
if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) {
|
||||
if ( !readNextBlock() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool continuationFound( false );
|
||||
size_t i = 0;
|
||||
for( ;; ) {
|
||||
if ( continuationToken == m_cache[ m_cachePos ] ) {
|
||||
continuationFound = true;
|
||||
++m_cachePos;
|
||||
}
|
||||
if ( IsLineEnd( m_cache[ m_cachePos ] ) ) {
|
||||
if ( !continuationFound ) {
|
||||
// the end of the data line
|
||||
break;
|
||||
} else {
|
||||
// skip line end
|
||||
while ( m_cache[m_cachePos] != '\n') {
|
||||
++m_cachePos;
|
||||
}
|
||||
++m_cachePos;
|
||||
continuationFound = false;
|
||||
}
|
||||
}
|
||||
|
||||
buffer[ i ] = m_cache[ m_cachePos ];
|
||||
++m_cachePos;
|
||||
++i;
|
||||
if (m_cachePos >= size()) {
|
||||
break;
|
||||
}
|
||||
if ( m_cachePos >= m_cacheSize ) {
|
||||
if ( !readNextBlock() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer[ i ] = '\n';
|
||||
++m_cachePos;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool isEndOfCache( size_t pos, size_t cacheSize ) {
|
||||
return ( pos == cacheSize );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
|
||||
buffer.resize(m_cacheSize);
|
||||
if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) {
|
||||
if (!readNextBlock()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsLineEnd(m_cache[m_cachePos])) {
|
||||
// skip line end
|
||||
while (m_cache[m_cachePos] != '\n') {
|
||||
++m_cachePos;
|
||||
}
|
||||
++m_cachePos;
|
||||
if ( isEndOfCache( m_cachePos, m_cacheSize ) ) {
|
||||
if ( !readNextBlock() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t i( 0 );
|
||||
while (!IsLineEnd(m_cache[ m_cachePos ])) {
|
||||
buffer[i] = m_cache[ m_cachePos ];
|
||||
++m_cachePos;
|
||||
++i;
|
||||
if (m_cachePos >= m_cacheSize) {
|
||||
if (!readNextBlock()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer[i] = '\n';
|
||||
++m_cachePos;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
|
||||
// Return the last block-value if getNextLine was used before
|
||||
if ( 0 != m_cachePos ) {
|
||||
buffer = std::vector<T>( m_cache.begin() + m_cachePos, m_cache.end() );
|
||||
m_cachePos = 0;
|
||||
} else {
|
||||
if ( !readNextBlock() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer = std::vector<T>(m_cache.begin(), m_cache.end());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // !ns Assimp
|
357
dependencies/assimp/include/assimp/IOSystem.hpp
vendored
Normal file
@ -0,0 +1,357 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file IOSystem.hpp
|
||||
* @brief File system wrapper for C++. Inherit this class to supply
|
||||
* custom file handling logic to the Import library.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef AI_IOSYSTEM_H_INC
|
||||
#define AI_IOSYSTEM_H_INC
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This header requires C++ to be used. aiFileIO.h is the \
|
||||
corresponding C interface.
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <direct.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
#else
|
||||
# include <sys/stat.h>
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
class IOStream;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief CPP-API: Interface to the file system.
|
||||
*
|
||||
* Derive an own implementation from this interface to supply custom file handling
|
||||
* to the importer library. If you implement this interface, you also want to
|
||||
* supply a custom implementation for IOStream.
|
||||
*
|
||||
* @see Importer::SetIOHandler()
|
||||
*/
|
||||
class ASSIMP_API IOSystem
|
||||
#ifndef SWIG
|
||||
: public Intern::AllocateFromAssimpHeap
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Default constructor.
|
||||
*
|
||||
* Create an instance of your derived class and assign it to an
|
||||
* #Assimp::Importer instance by calling Importer::SetIOHandler().
|
||||
*/
|
||||
IOSystem() AI_NO_EXCEPT;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Virtual destructor.
|
||||
*
|
||||
* It is safe to be called from within DLL Assimp, we're constructed
|
||||
* on Assimp's heap.
|
||||
*/
|
||||
virtual ~IOSystem();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief For backward compatibility
|
||||
* @see Exists(const char*)
|
||||
*/
|
||||
AI_FORCE_INLINE bool Exists( const std::string& pFile) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Tests for the existence of a file at the given path.
|
||||
*
|
||||
* @param pFile Path to the file
|
||||
* @return true if there is a file with this path, else false.
|
||||
*/
|
||||
virtual bool Exists( const char* pFile) const = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Returns the system specific directory separator
|
||||
* @return System specific directory separator
|
||||
*/
|
||||
virtual char getOsSeparator() const = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Open a new file with a given path.
|
||||
*
|
||||
* When the access to the file is finished, call Close() to release
|
||||
* all associated resources (or the virtual dtor of the IOStream).
|
||||
*
|
||||
* @param pFile Path to the file
|
||||
* @param pMode Desired file I/O mode. Required are: "wb", "w", "wt",
|
||||
* "rb", "r", "rt".
|
||||
*
|
||||
* @return New IOStream interface allowing the lib to access
|
||||
* the underlying file.
|
||||
* @note When implementing this class to provide custom IO handling,
|
||||
* you probably have to supply an own implementation of IOStream as well.
|
||||
*/
|
||||
virtual IOStream* Open(const char* pFile,
|
||||
const char* pMode = "rb") = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief For backward compatibility
|
||||
* @see Open(const char*, const char*)
|
||||
*/
|
||||
inline IOStream* Open(const std::string& pFile,
|
||||
const std::string& pMode = std::string("rb"));
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Closes the given file and releases all resources
|
||||
* associated with it.
|
||||
* @param pFile The file instance previously created by Open().
|
||||
*/
|
||||
virtual void Close( IOStream* pFile) = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Compares two paths and check whether the point to
|
||||
* identical files.
|
||||
*
|
||||
* The dummy implementation of this virtual member performs a
|
||||
* case-insensitive comparison of the given strings. The default IO
|
||||
* system implementation uses OS mechanisms to convert relative into
|
||||
* absolute paths, so the result can be trusted.
|
||||
* @param one First file
|
||||
* @param second Second file
|
||||
* @return true if the paths point to the same file. The file needn't
|
||||
* be existing, however.
|
||||
*/
|
||||
virtual bool ComparePaths (const char* one,
|
||||
const char* second) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief For backward compatibility
|
||||
* @see ComparePaths(const char*, const char*)
|
||||
*/
|
||||
inline bool ComparePaths (const std::string& one,
|
||||
const std::string& second) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Pushes a new directory onto the directory stack.
|
||||
* @param path Path to push onto the stack.
|
||||
* @return True, when push was successful, false if path is empty.
|
||||
*/
|
||||
virtual bool PushDirectory( const std::string &path );
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Returns the top directory from the stack.
|
||||
* @return The directory on the top of the stack.
|
||||
* Returns empty when no directory was pushed to the stack.
|
||||
*/
|
||||
virtual const std::string &CurrentDirectory() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Returns the number of directories stored on the stack.
|
||||
* @return The number of directories of the stack.
|
||||
*/
|
||||
virtual size_t StackSize() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Pops the top directory from the stack.
|
||||
* @return True, when a directory was on the stack. False if no
|
||||
* directory was on the stack.
|
||||
*/
|
||||
virtual bool PopDirectory();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief CReates an new directory at the given path.
|
||||
* @param path [in] The path to create.
|
||||
* @return True, when a directory was created. False if the directory
|
||||
* cannot be created.
|
||||
*/
|
||||
virtual bool CreateDirectory( const std::string &path );
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Will change the current directory to the given path.
|
||||
* @param path [in] The path to change to.
|
||||
* @return True, when the directory has changed successfully.
|
||||
*/
|
||||
virtual bool ChangeDirectory( const std::string &path );
|
||||
|
||||
virtual bool DeleteFile( const std::string &file );
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_pathStack;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
IOSystem::IOSystem() AI_NO_EXCEPT
|
||||
: m_pathStack() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
IOSystem::~IOSystem() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// For compatibility, the interface of some functions taking a std::string was
|
||||
// changed to const char* to avoid crashes between binary incompatible STL
|
||||
// versions. This code her is inlined, so it shouldn't cause any problems.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
IOStream* IOSystem::Open(const std::string& pFile, const std::string& pMode) {
|
||||
// NOTE:
|
||||
// For compatibility, interface was changed to const char* to
|
||||
// avoid crashes between binary incompatible STL versions
|
||||
return Open(pFile.c_str(),pMode.c_str());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
bool IOSystem::Exists( const std::string& pFile) const {
|
||||
// NOTE:
|
||||
// For compatibility, interface was changed to const char* to
|
||||
// avoid crashes between binary incompatible STL versions
|
||||
return Exists(pFile.c_str());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
bool IOSystem::ComparePaths (const std::string& one, const std::string& second) const {
|
||||
// NOTE:
|
||||
// For compatibility, interface was changed to const char* to
|
||||
// avoid crashes between binary incompatible STL versions
|
||||
return ComparePaths(one.c_str(),second.c_str());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
bool IOSystem::PushDirectory( const std::string &path ) {
|
||||
if ( path.empty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pathStack.push_back( path );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
const std::string &IOSystem::CurrentDirectory() const {
|
||||
if ( m_pathStack.empty() ) {
|
||||
static const std::string Dummy("");
|
||||
return Dummy;
|
||||
}
|
||||
return m_pathStack[ m_pathStack.size()-1 ];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
size_t IOSystem::StackSize() const {
|
||||
return m_pathStack.size();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
bool IOSystem::PopDirectory() {
|
||||
if ( m_pathStack.empty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pathStack.pop_back();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
bool IOSystem::CreateDirectory( const std::string &path ) {
|
||||
if ( path.empty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
return 0 != ::_mkdir( path.c_str() );
|
||||
#else
|
||||
return 0 != ::mkdir( path.c_str(), 0777 );
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
bool IOSystem::ChangeDirectory( const std::string &path ) {
|
||||
if ( path.empty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
return 0 != ::_chdir( path.c_str() );
|
||||
#else
|
||||
return 0 != ::chdir( path.c_str() );
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
bool IOSystem::DeleteFile( const std::string &file ) {
|
||||
if ( file.empty() ) {
|
||||
return false;
|
||||
}
|
||||
const int retCode( ::remove( file.c_str() ) );
|
||||
return ( 0 == retCode );
|
||||
}
|
||||
} //!ns Assimp
|
||||
|
||||
#endif //AI_IOSYSTEM_H_INC
|
659
dependencies/assimp/include/assimp/Importer.hpp
vendored
Normal file
@ -0,0 +1,659 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Importer.hpp
|
||||
* @brief Defines the C++-API to the Open Asset Import Library.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef AI_ASSIMP_HPP_INC
|
||||
#define AI_ASSIMP_HPP_INC
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This header requires C++ to be used. Use assimp.h for plain C.
|
||||
#endif // __cplusplus
|
||||
|
||||
// Public ASSIMP data structures
|
||||
#include <assimp/types.h>
|
||||
|
||||
namespace Assimp {
|
||||
// =======================================================================
|
||||
// Public interface to Assimp
|
||||
class Importer;
|
||||
class IOStream;
|
||||
class IOSystem;
|
||||
class ProgressHandler;
|
||||
|
||||
// =======================================================================
|
||||
// Plugin development
|
||||
//
|
||||
// Include the following headers for the declarations:
|
||||
// BaseImporter.h
|
||||
// BaseProcess.h
|
||||
class BaseImporter;
|
||||
class BaseProcess;
|
||||
class SharedPostProcessInfo;
|
||||
class BatchLoader;
|
||||
|
||||
// =======================================================================
|
||||
// Holy stuff, only for members of the high council of the Jedi.
|
||||
class ImporterPimpl;
|
||||
} //! namespace Assimp
|
||||
|
||||
#define AI_PROPERTY_WAS_NOT_EXISTING 0xffffffff
|
||||
|
||||
struct aiScene;
|
||||
|
||||
// importerdesc.h
|
||||
struct aiImporterDesc;
|
||||
|
||||
/** @namespace Assimp Assimp's CPP-API and all internal APIs */
|
||||
namespace Assimp {
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
/** CPP-API: The Importer class forms an C++ interface to the functionality of the
|
||||
* Open Asset Import Library.
|
||||
*
|
||||
* Create an object of this class and call ReadFile() to import a file.
|
||||
* If the import succeeds, the function returns a pointer to the imported data.
|
||||
* The data remains property of the object, it is intended to be accessed
|
||||
* read-only. The imported data will be destroyed along with the Importer
|
||||
* object. If the import fails, ReadFile() returns a NULL pointer. In this
|
||||
* case you can retrieve a human-readable error description be calling
|
||||
* GetErrorString(). You can call ReadFile() multiple times with a single Importer
|
||||
* instance. Actually, constructing Importer objects involves quite many
|
||||
* allocations and may take some time, so it's better to reuse them as often as
|
||||
* possible.
|
||||
*
|
||||
* If you need the Importer to do custom file handling to access the files,
|
||||
* implement IOSystem and IOStream and supply an instance of your custom
|
||||
* IOSystem implementation by calling SetIOHandler() before calling ReadFile().
|
||||
* If you do not assign a custion IO handler, a default handler using the
|
||||
* standard C++ IO logic will be used.
|
||||
*
|
||||
* @note One Importer instance is not thread-safe. If you use multiple
|
||||
* threads for loading, each thread should maintain its own Importer instance.
|
||||
*/
|
||||
class ASSIMP_API Importer {
|
||||
public:
|
||||
/**
|
||||
* @brief The upper limit for hints.
|
||||
*/
|
||||
static const unsigned int MaxLenHint = 200;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Constructor. Creates an empty importer object.
|
||||
*
|
||||
* Call ReadFile() to start the import process. The configuration
|
||||
* property table is initially empty.
|
||||
*/
|
||||
Importer();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Copy constructor.
|
||||
*
|
||||
* This copies the configuration properties of another Importer.
|
||||
* If this Importer owns a scene it won't be copied.
|
||||
* Call ReadFile() to start the import process.
|
||||
*/
|
||||
Importer(const Importer& other)=delete;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Assignment operator has been deleted
|
||||
*/
|
||||
Importer &operator=(const Importer &) = delete;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Destructor. The object kept ownership of the imported data,
|
||||
* which now will be destroyed along with the object.
|
||||
*/
|
||||
~Importer();
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Registers a new loader.
|
||||
*
|
||||
* @param pImp Importer to be added. The Importer instance takes
|
||||
* ownership of the pointer, so it will be automatically deleted
|
||||
* with the Importer instance.
|
||||
* @return AI_SUCCESS if the loader has been added. The registration
|
||||
* fails if there is already a loader for a specific file extension.
|
||||
*/
|
||||
aiReturn RegisterLoader(BaseImporter* pImp);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Unregisters a loader.
|
||||
*
|
||||
* @param pImp Importer to be unregistered.
|
||||
* @return AI_SUCCESS if the loader has been removed. The function
|
||||
* fails if the loader is currently in use (this could happen
|
||||
* if the #Importer instance is used by more than one thread) or
|
||||
* if it has not yet been registered.
|
||||
*/
|
||||
aiReturn UnregisterLoader(BaseImporter* pImp);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Registers a new post-process step.
|
||||
*
|
||||
* At the moment, there's a small limitation: new post processing
|
||||
* steps are added to end of the list, or in other words, executed
|
||||
* last, after all built-in steps.
|
||||
* @param pImp Post-process step to be added. The Importer instance
|
||||
* takes ownership of the pointer, so it will be automatically
|
||||
* deleted with the Importer instance.
|
||||
* @return AI_SUCCESS if the step has been added correctly.
|
||||
*/
|
||||
aiReturn RegisterPPStep(BaseProcess* pImp);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Unregisters a post-process step.
|
||||
*
|
||||
* @param pImp Step to be unregistered.
|
||||
* @return AI_SUCCESS if the step has been removed. The function
|
||||
* fails if the step is currently in use (this could happen
|
||||
* if the #Importer instance is used by more than one thread) or
|
||||
* if it has not yet been registered.
|
||||
*/
|
||||
aiReturn UnregisterPPStep(BaseProcess* pImp);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Set an integer configuration property.
|
||||
* @param szName Name of the property. All supported properties
|
||||
* are defined in the aiConfig.g header (all constants share the
|
||||
* prefix AI_CONFIG_XXX and are simple strings).
|
||||
* @param iValue New value of the property
|
||||
* @return true if the property was set before. The new value replaces
|
||||
* the previous value in this case.
|
||||
* @note Property of different types (float, int, string ..) are kept
|
||||
* on different stacks, so calling SetPropertyInteger() for a
|
||||
* floating-point property has no effect - the loader will call
|
||||
* GetPropertyFloat() to read the property, but it won't be there.
|
||||
*/
|
||||
bool SetPropertyInteger(const char* szName, int iValue);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Set a boolean configuration property. Boolean properties
|
||||
* are stored on the integer stack internally so it's possible
|
||||
* to set them via #SetPropertyBool and query them with
|
||||
* #GetPropertyBool and vice versa.
|
||||
* @see SetPropertyInteger()
|
||||
*/
|
||||
bool SetPropertyBool(const char* szName, bool value) {
|
||||
return SetPropertyInteger(szName,value);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Set a floating-point configuration property.
|
||||
* @see SetPropertyInteger()
|
||||
*/
|
||||
bool SetPropertyFloat(const char* szName, ai_real fValue);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Set a string configuration property.
|
||||
* @see SetPropertyInteger()
|
||||
*/
|
||||
bool SetPropertyString(const char* szName, const std::string& sValue);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Set a matrix configuration property.
|
||||
* @see SetPropertyInteger()
|
||||
*/
|
||||
bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a configuration property.
|
||||
* @param szName Name of the property. All supported properties
|
||||
* are defined in the aiConfig.g header (all constants share the
|
||||
* prefix AI_CONFIG_XXX).
|
||||
* @param iErrorReturn Value that is returned if the property
|
||||
* is not found.
|
||||
* @return Current value of the property
|
||||
* @note Property of different types (float, int, string ..) are kept
|
||||
* on different lists, so calling SetPropertyInteger() for a
|
||||
* floating-point property has no effect - the loader will call
|
||||
* GetPropertyFloat() to read the property, but it won't be there.
|
||||
*/
|
||||
int GetPropertyInteger(const char* szName,
|
||||
int iErrorReturn = 0xffffffff) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a boolean configuration property. Boolean properties
|
||||
* are stored on the integer stack internally so it's possible
|
||||
* to set them via #SetPropertyBool and query them with
|
||||
* #GetPropertyBool and vice versa.
|
||||
* @see GetPropertyInteger()
|
||||
*/
|
||||
bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
|
||||
return GetPropertyInteger(szName,bErrorReturn)!=0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a floating-point configuration property
|
||||
* @see GetPropertyInteger()
|
||||
*/
|
||||
ai_real GetPropertyFloat(const char* szName,
|
||||
ai_real fErrorReturn = 10e10) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a string configuration property
|
||||
*
|
||||
* The return value remains valid until the property is modified.
|
||||
* @see GetPropertyInteger()
|
||||
*/
|
||||
const std::string GetPropertyString(const char* szName,
|
||||
const std::string& sErrorReturn = "") const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a matrix configuration property
|
||||
*
|
||||
* The return value remains valid until the property is modified.
|
||||
* @see GetPropertyInteger()
|
||||
*/
|
||||
const aiMatrix4x4 GetPropertyMatrix(const char* szName,
|
||||
const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Supplies a custom IO handler to the importer to use to open and
|
||||
* access files. If you need the importer to use custom IO logic to
|
||||
* access the files, you need to provide a custom implementation of
|
||||
* IOSystem and IOFile to the importer. Then create an instance of
|
||||
* your custom IOSystem implementation and supply it by this function.
|
||||
*
|
||||
* The Importer takes ownership of the object and will destroy it
|
||||
* afterwards. The previously assigned handler will be deleted.
|
||||
* Pass NULL to take again ownership of your IOSystem and reset Assimp
|
||||
* to use its default implementation.
|
||||
*
|
||||
* @param pIOHandler The IO handler to be used in all file accesses
|
||||
* of the Importer.
|
||||
*/
|
||||
void SetIOHandler( IOSystem* pIOHandler);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Retrieves the IO handler that is currently set.
|
||||
* You can use #IsDefaultIOHandler() to check whether the returned
|
||||
* interface is the default IO handler provided by ASSIMP. The default
|
||||
* handler is active as long the application doesn't supply its own
|
||||
* custom IO handler via #SetIOHandler().
|
||||
* @return A valid IOSystem interface, never NULL.
|
||||
*/
|
||||
IOSystem* GetIOHandler() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Checks whether a default IO handler is active
|
||||
* A default handler is active as long the application doesn't
|
||||
* supply its own custom IO handler via #SetIOHandler().
|
||||
* @return true by default
|
||||
*/
|
||||
bool IsDefaultIOHandler() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Supplies a custom progress handler to the importer. This
|
||||
* interface exposes an #Update() callback, which is called
|
||||
* more or less periodically (please don't sue us if it
|
||||
* isn't as periodically as you'd like it to have ...).
|
||||
* This can be used to implement progress bars and loading
|
||||
* timeouts.
|
||||
* @param pHandler Progress callback interface. Pass NULL to
|
||||
* disable progress reporting.
|
||||
* @note Progress handlers can be used to abort the loading
|
||||
* at almost any time.*/
|
||||
void SetProgressHandler ( ProgressHandler* pHandler );
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Retrieves the progress handler that is currently set.
|
||||
* You can use #IsDefaultProgressHandler() to check whether the returned
|
||||
* interface is the default handler provided by ASSIMP. The default
|
||||
* handler is active as long the application doesn't supply its own
|
||||
* custom handler via #SetProgressHandler().
|
||||
* @return A valid ProgressHandler interface, never NULL.
|
||||
*/
|
||||
ProgressHandler* GetProgressHandler() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Checks whether a default progress handler is active
|
||||
* A default handler is active as long the application doesn't
|
||||
* supply its own custom progress handler via #SetProgressHandler().
|
||||
* @return true by default
|
||||
*/
|
||||
bool IsDefaultProgressHandler() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Check whether a given set of post-processing flags
|
||||
* is supported.
|
||||
*
|
||||
* Some flags are mutually exclusive, others are probably
|
||||
* not available because your excluded them from your
|
||||
* Assimp builds. Calling this function is recommended if
|
||||
* you're unsure.
|
||||
*
|
||||
* @param pFlags Bitwise combination of the aiPostProcess flags.
|
||||
* @return true if this flag combination is fine.
|
||||
*/
|
||||
bool ValidateFlags(unsigned int pFlags) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Reads the given file and returns its contents if successful.
|
||||
*
|
||||
* If the call succeeds, the contents of the file are returned as a
|
||||
* pointer to an aiScene object. The returned data is intended to be
|
||||
* read-only, the importer object keeps ownership of the data and will
|
||||
* destroy it upon destruction. If the import fails, NULL is returned.
|
||||
* A human-readable error description can be retrieved by calling
|
||||
* GetErrorString(). The previous scene will be deleted during this call.
|
||||
* @param pFile Path and filename to the file to be imported.
|
||||
* @param pFlags Optional post processing steps to be executed after
|
||||
* a successful import. Provide a bitwise combination of the
|
||||
* #aiPostProcessSteps flags. If you wish to inspect the imported
|
||||
* scene first in order to fine-tune your post-processing setup,
|
||||
* consider to use #ApplyPostProcessing().
|
||||
* @return A pointer to the imported data, NULL if the import failed.
|
||||
* The pointer to the scene remains in possession of the Importer
|
||||
* instance. Use GetOrphanedScene() to take ownership of it.
|
||||
*
|
||||
* @note Assimp is able to determine the file format of a file
|
||||
* automatically.
|
||||
*/
|
||||
const aiScene* ReadFile(
|
||||
const char* pFile,
|
||||
unsigned int pFlags);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Reads the given file from a memory buffer and returns its
|
||||
* contents if successful.
|
||||
*
|
||||
* If the call succeeds, the contents of the file are returned as a
|
||||
* pointer to an aiScene object. The returned data is intended to be
|
||||
* read-only, the importer object keeps ownership of the data and will
|
||||
* destroy it upon destruction. If the import fails, NULL is returned.
|
||||
* A human-readable error description can be retrieved by calling
|
||||
* GetErrorString(). The previous scene will be deleted during this call.
|
||||
* Calling this method doesn't affect the active IOSystem.
|
||||
* @param pBuffer Pointer to the file data
|
||||
* @param pLength Length of pBuffer, in bytes
|
||||
* @param pFlags Optional post processing steps to be executed after
|
||||
* a successful import. Provide a bitwise combination of the
|
||||
* #aiPostProcessSteps flags. If you wish to inspect the imported
|
||||
* scene first in order to fine-tune your post-processing setup,
|
||||
* consider to use #ApplyPostProcessing().
|
||||
* @param pHint An additional hint to the library. If this is a non
|
||||
* empty string, the library looks for a loader to support
|
||||
* the file extension specified by pHint and passes the file to
|
||||
* the first matching loader. If this loader is unable to completely
|
||||
* the request, the library continues and tries to determine the
|
||||
* file format on its own, a task that may or may not be successful.
|
||||
* Check the return value, and you'll know ...
|
||||
* @return A pointer to the imported data, NULL if the import failed.
|
||||
* The pointer to the scene remains in possession of the Importer
|
||||
* instance. Use GetOrphanedScene() to take ownership of it.
|
||||
*
|
||||
* @note This is a straightforward way to decode models from memory
|
||||
* buffers, but it doesn't handle model formats that spread their
|
||||
* data across multiple files or even directories. Examples include
|
||||
* OBJ or MD3, which outsource parts of their material info into
|
||||
* external scripts. If you need full functionality, provide
|
||||
* a custom IOSystem to make Assimp find these files and use
|
||||
* the regular ReadFile() API.
|
||||
*/
|
||||
const aiScene* ReadFileFromMemory(
|
||||
const void* pBuffer,
|
||||
size_t pLength,
|
||||
unsigned int pFlags,
|
||||
const char* pHint = "");
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Apply post-processing to an already-imported scene.
|
||||
*
|
||||
* This is strictly equivalent to calling #ReadFile() with the same
|
||||
* flags. However, you can use this separate function to inspect
|
||||
* the imported scene first to fine-tune your post-processing setup.
|
||||
* @param pFlags Provide a bitwise combination of the
|
||||
* #aiPostProcessSteps flags.
|
||||
* @return A pointer to the post-processed data. This is still the
|
||||
* same as the pointer returned by #ReadFile(). However, if
|
||||
* post-processing fails, the scene could now be NULL.
|
||||
* That's quite a rare case, post processing steps are not really
|
||||
* designed to 'fail'. To be exact, the #aiProcess_ValidateDS
|
||||
* flag is currently the only post processing step which can actually
|
||||
* cause the scene to be reset to NULL.
|
||||
*
|
||||
* @note The method does nothing if no scene is currently bound
|
||||
* to the #Importer instance. */
|
||||
const aiScene* ApplyPostProcessing(unsigned int pFlags);
|
||||
|
||||
const aiScene* ApplyCustomizedPostProcessing( BaseProcess *rootProcess, bool requestValidation );
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Reads the given file and returns its contents if successful.
|
||||
*
|
||||
* This function is provided for backward compatibility.
|
||||
* See the const char* version for detailed docs.
|
||||
* @see ReadFile(const char*, pFlags) */
|
||||
const aiScene* ReadFile(
|
||||
const std::string& pFile,
|
||||
unsigned int pFlags);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Frees the current scene.
|
||||
*
|
||||
* The function does nothing if no scene has previously been
|
||||
* read via ReadFile(). FreeScene() is called automatically by the
|
||||
* destructor and ReadFile() itself. */
|
||||
void FreeScene( );
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns an error description of an error that occurred in ReadFile().
|
||||
*
|
||||
* Returns an empty string if no error occurred.
|
||||
* @return A description of the last error, an empty string if no
|
||||
* error occurred. The string is never NULL.
|
||||
*
|
||||
* @note The returned function remains valid until one of the
|
||||
* following methods is called: #ReadFile(), #FreeScene(). */
|
||||
const char* GetErrorString() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns the scene loaded by the last successful call to ReadFile()
|
||||
*
|
||||
* @return Current scene or NULL if there is currently no scene loaded */
|
||||
const aiScene* GetScene() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns the scene loaded by the last successful call to ReadFile()
|
||||
* and releases the scene from the ownership of the Importer
|
||||
* instance. The application is now responsible for deleting the
|
||||
* scene. Any further calls to GetScene() or GetOrphanedScene()
|
||||
* will return NULL - until a new scene has been loaded via ReadFile().
|
||||
*
|
||||
* @return Current scene or NULL if there is currently no scene loaded
|
||||
* @note Use this method with maximal caution, and only if you have to.
|
||||
* By design, aiScene's are exclusively maintained, allocated and
|
||||
* deallocated by Assimp and no one else. The reasoning behind this
|
||||
* is the golden rule that deallocations should always be done
|
||||
* by the module that did the original allocation because heaps
|
||||
* are not necessarily shared. GetOrphanedScene() enforces you
|
||||
* to delete the returned scene by yourself, but this will only
|
||||
* be fine if and only if you're using the same heap as assimp.
|
||||
* On Windows, it's typically fine provided everything is linked
|
||||
* against the multithreaded-dll version of the runtime library.
|
||||
* It will work as well for static linkage with Assimp.*/
|
||||
aiScene* GetOrphanedScene();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether a given file extension is supported by ASSIMP.
|
||||
*
|
||||
* @param szExtension Extension to be checked.
|
||||
* Must include a trailing dot '.'. Example: ".3ds", ".md3".
|
||||
* Cases-insensitive.
|
||||
* @return true if the extension is supported, false otherwise */
|
||||
bool IsExtensionSupported(const char* szExtension) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Returns whether a given file extension is supported by ASSIMP.
|
||||
*
|
||||
* This function is provided for backward compatibility.
|
||||
* See the const char* version for detailed and up-to-date docs.
|
||||
* @see IsExtensionSupported(const char*) */
|
||||
inline bool IsExtensionSupported(const std::string& szExtension) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get a full list of all file extensions supported by ASSIMP.
|
||||
*
|
||||
* If a file extension is contained in the list this does of course not
|
||||
* mean that ASSIMP is able to load all files with this extension ---
|
||||
* it simply means there is an importer loaded which claims to handle
|
||||
* files with this file extension.
|
||||
* @param szOut String to receive the extension list.
|
||||
* Format of the list: "*.3ds;*.obj;*.dae". This is useful for
|
||||
* use with the WinAPI call GetOpenFileName(Ex). */
|
||||
void GetExtensionList(aiString& szOut) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Get a full list of all file extensions supported by ASSIMP.
|
||||
*
|
||||
* This function is provided for backward compatibility.
|
||||
* See the aiString version for detailed and up-to-date docs.
|
||||
* @see GetExtensionList(aiString&)*/
|
||||
inline void GetExtensionList(std::string& szOut) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get the number of importers currently registered with Assimp. */
|
||||
size_t GetImporterCount() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Get meta data for the importer corresponding to a specific index..
|
||||
*
|
||||
* For the declaration of #aiImporterDesc, include <assimp/importerdesc.h>.
|
||||
* @param index Index to query, must be within [0,GetImporterCount())
|
||||
* @return Importer meta data structure, NULL if the index does not
|
||||
* exist or if the importer doesn't offer meta information (
|
||||
* importers may do this at the cost of being hated by their peers).*/
|
||||
const aiImporterDesc* GetImporterInfo(size_t index) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Find the importer corresponding to a specific index.
|
||||
*
|
||||
* @param index Index to query, must be within [0,GetImporterCount())
|
||||
* @return Importer instance. NULL if the index does not
|
||||
* exist. */
|
||||
BaseImporter* GetImporter(size_t index) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Find the importer corresponding to a specific file extension.
|
||||
*
|
||||
* This is quite similar to #IsExtensionSupported except a
|
||||
* BaseImporter instance is returned.
|
||||
* @param szExtension Extension to check for. The following formats
|
||||
* are recognized (BAH being the file extension): "BAH" (comparison
|
||||
* is case-insensitive), ".bah", "*.bah" (wild card and dot
|
||||
* characters at the beginning of the extension are skipped).
|
||||
* @return NULL if no importer is found*/
|
||||
BaseImporter* GetImporter (const char* szExtension) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Find the importer index corresponding to a specific file extension.
|
||||
*
|
||||
* @param szExtension Extension to check for. The following formats
|
||||
* are recognized (BAH being the file extension): "BAH" (comparison
|
||||
* is case-insensitive), ".bah", "*.bah" (wild card and dot
|
||||
* characters at the beginning of the extension are skipped).
|
||||
* @return (size_t)-1 if no importer is found */
|
||||
size_t GetImporterIndex (const char* szExtension) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns the storage allocated by ASSIMP to hold the scene data
|
||||
* in memory.
|
||||
*
|
||||
* This refers to the currently loaded file, see #ReadFile().
|
||||
* @param in Data structure to be filled.
|
||||
* @note The returned memory statistics refer to the actual
|
||||
* size of the use data of the aiScene. Heap-related overhead
|
||||
* is (naturally) not included.*/
|
||||
void GetMemoryRequirements(aiMemoryInfo& in) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Enables "extra verbose" mode.
|
||||
*
|
||||
* 'Extra verbose' means the data structure is validated after *every*
|
||||
* single post processing step to make sure everyone modifies the data
|
||||
* structure in a well-defined manner. This is a debug feature and not
|
||||
* intended for use in production environments. */
|
||||
void SetExtraVerbose(bool bDo);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Private, do not use. */
|
||||
ImporterPimpl* Pimpl() { return pimpl; }
|
||||
const ImporterPimpl* Pimpl() const { return pimpl; }
|
||||
|
||||
protected:
|
||||
|
||||
// Just because we don't want you to know how we're hacking around.
|
||||
ImporterPimpl* pimpl;
|
||||
}; //! class Importer
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// For compatibility, the interface of some functions taking a std::string was
|
||||
// changed to const char* to avoid crashes between binary incompatible STL
|
||||
// versions. This code her is inlined, so it shouldn't cause any problems.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE const aiScene* Importer::ReadFile( const std::string& pFile,unsigned int pFlags){
|
||||
return ReadFile(pFile.c_str(),pFlags);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE void Importer::GetExtensionList(std::string& szOut) const {
|
||||
aiString s;
|
||||
GetExtensionList(s);
|
||||
szOut = s.data;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE bool Importer::IsExtensionSupported(const std::string& szExtension) const {
|
||||
return IsExtensionSupported(szExtension.c_str());
|
||||
}
|
||||
|
||||
} // !namespace Assimp
|
||||
|
||||
#endif // AI_ASSIMP_HPP_INC
|
285
dependencies/assimp/include/assimp/LineSplitter.h
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file LineSplitter.h
|
||||
* @brief LineSplitter, a helper class to iterate through all lines
|
||||
* of a file easily. Works with StreamReader.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef INCLUDED_LINE_SPLITTER_H
|
||||
#define INCLUDED_LINE_SPLITTER_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include "StreamReader.h"
|
||||
#include "ParsingUtils.h"
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** Usage:
|
||||
@code
|
||||
for(LineSplitter splitter(stream);splitter;++splitter) {
|
||||
|
||||
if (*splitter == "hi!") {
|
||||
...
|
||||
}
|
||||
else if (splitter->substr(0,5) == "hello") {
|
||||
...
|
||||
// access the third token in the line (tokens are space-separated)
|
||||
if (strtol(splitter[2]) > 5) { .. }
|
||||
}
|
||||
|
||||
std::cout << "Current line is: " << splitter.get_index() << std::endl;
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class LineSplitter {
|
||||
public:
|
||||
typedef size_t line_idx;
|
||||
|
||||
// -----------------------------------------
|
||||
/** construct from existing stream reader
|
||||
note: trim is *always* assumed true if skyp_empty_lines==true
|
||||
*/
|
||||
LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true);
|
||||
|
||||
~LineSplitter();
|
||||
|
||||
// -----------------------------------------
|
||||
/** pseudo-iterator increment */
|
||||
LineSplitter& operator++();
|
||||
|
||||
// -----------------------------------------
|
||||
LineSplitter& operator++(int);
|
||||
|
||||
// -----------------------------------------
|
||||
/** get a pointer to the beginning of a particular token */
|
||||
const char* operator[] (size_t idx) const;
|
||||
|
||||
// -----------------------------------------
|
||||
/** extract the start positions of N tokens from the current line*/
|
||||
template <size_t N>
|
||||
void get_tokens(const char* (&tokens)[N]) const;
|
||||
|
||||
// -----------------------------------------
|
||||
/** member access */
|
||||
const std::string* operator -> () const;
|
||||
|
||||
std::string operator* () const;
|
||||
|
||||
// -----------------------------------------
|
||||
/** boolean context */
|
||||
operator bool() const;
|
||||
|
||||
// -----------------------------------------
|
||||
/** line indices are zero-based, empty lines are included */
|
||||
operator line_idx() const;
|
||||
|
||||
line_idx get_index() const;
|
||||
|
||||
// -----------------------------------------
|
||||
/** access the underlying stream object */
|
||||
StreamReaderLE& get_stream();
|
||||
|
||||
// -----------------------------------------
|
||||
/** !strcmp((*this)->substr(0,strlen(check)),check) */
|
||||
bool match_start(const char* check);
|
||||
|
||||
// -----------------------------------------
|
||||
/** swallow the next call to ++, return the previous value. */
|
||||
void swallow_next_increment();
|
||||
|
||||
LineSplitter( const LineSplitter & ) = delete;
|
||||
LineSplitter(LineSplitter &&) = delete;
|
||||
LineSplitter &operator = ( const LineSplitter & ) = delete;
|
||||
|
||||
private:
|
||||
line_idx mIdx;
|
||||
std::string mCur;
|
||||
StreamReaderLE& mStream;
|
||||
bool mSwallow, mSkip_empty_lines, mTrim;
|
||||
};
|
||||
|
||||
inline
|
||||
LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim )
|
||||
: mIdx(0)
|
||||
, mCur()
|
||||
, mStream(stream)
|
||||
, mSwallow()
|
||||
, mSkip_empty_lines(skip_empty_lines)
|
||||
, mTrim(trim) {
|
||||
mCur.reserve(1024);
|
||||
operator++();
|
||||
mIdx = 0;
|
||||
}
|
||||
|
||||
inline
|
||||
LineSplitter::~LineSplitter() {
|
||||
// empty
|
||||
}
|
||||
|
||||
inline
|
||||
LineSplitter& LineSplitter::operator++() {
|
||||
if (mSwallow) {
|
||||
mSwallow = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (!*this) {
|
||||
throw std::logic_error("End of file, no more lines to be retrieved.");
|
||||
}
|
||||
|
||||
char s;
|
||||
mCur.clear();
|
||||
while (mStream.GetRemainingSize() && (s = mStream.GetI1(), 1)) {
|
||||
if (s == '\n' || s == '\r') {
|
||||
if (mSkip_empty_lines) {
|
||||
while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\r' || s == '\n'));
|
||||
if (mStream.GetRemainingSize()) {
|
||||
mStream.IncPtr(-1);
|
||||
}
|
||||
} else {
|
||||
// skip both potential line terminators but don't read past this line.
|
||||
if (mStream.GetRemainingSize() && (s == '\r' && mStream.GetI1() != '\n')) {
|
||||
mStream.IncPtr(-1);
|
||||
}
|
||||
if (mTrim) {
|
||||
while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\t'));
|
||||
if (mStream.GetRemainingSize()) {
|
||||
mStream.IncPtr(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
mCur += s;
|
||||
}
|
||||
++mIdx;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
LineSplitter &LineSplitter::operator++(int) {
|
||||
return ++(*this);
|
||||
}
|
||||
|
||||
inline
|
||||
const char *LineSplitter::operator[] (size_t idx) const {
|
||||
const char* s = operator->()->c_str();
|
||||
|
||||
SkipSpaces(&s);
|
||||
for (size_t i = 0; i < idx; ++i) {
|
||||
|
||||
for (; !IsSpace(*s); ++s) {
|
||||
if (IsLineEnd(*s)) {
|
||||
throw std::range_error("Token index out of range, EOL reached");
|
||||
}
|
||||
}
|
||||
SkipSpaces(&s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
inline
|
||||
void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
|
||||
const char* s = operator->()->c_str();
|
||||
|
||||
SkipSpaces(&s);
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (IsLineEnd(*s)) {
|
||||
throw std::range_error("Token count out of range, EOL reached");
|
||||
}
|
||||
tokens[i] = s;
|
||||
|
||||
for (; *s && !IsSpace(*s); ++s);
|
||||
SkipSpaces(&s);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
const std::string* LineSplitter::operator -> () const {
|
||||
return &mCur;
|
||||
}
|
||||
|
||||
inline
|
||||
std::string LineSplitter::operator* () const {
|
||||
return mCur;
|
||||
}
|
||||
|
||||
inline
|
||||
LineSplitter::operator bool() const {
|
||||
return mStream.GetRemainingSize() > 0;
|
||||
}
|
||||
|
||||
inline
|
||||
LineSplitter::operator line_idx() const {
|
||||
return mIdx;
|
||||
}
|
||||
|
||||
inline
|
||||
LineSplitter::line_idx LineSplitter::get_index() const {
|
||||
return mIdx;
|
||||
}
|
||||
|
||||
inline
|
||||
StreamReaderLE &LineSplitter::get_stream() {
|
||||
return mStream;
|
||||
}
|
||||
|
||||
inline
|
||||
bool LineSplitter::match_start(const char* check) {
|
||||
const size_t len = ::strlen(check);
|
||||
|
||||
return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
|
||||
}
|
||||
|
||||
inline
|
||||
void LineSplitter::swallow_next_increment() {
|
||||
mSwallow = true;
|
||||
}
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // INCLUDED_LINE_SPLITTER_H
|
131
dependencies/assimp/include/assimp/LogAux.h
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file LogAux.h
|
||||
* @brief Common logging usage patterns for importer implementations
|
||||
*/
|
||||
#ifndef INCLUDED_AI_LOGAUX_H
|
||||
#define INCLUDED_AI_LOGAUX_H
|
||||
|
||||
#include <assimp/TinyFormatter.h>
|
||||
#include <assimp/Exceptional.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
template<class TDeriving>
|
||||
class LogFunctions {
|
||||
public:
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void ThrowException(const std::string& msg)
|
||||
{
|
||||
throw DeadlyImportError(Prefix()+msg);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogWarn(const Formatter::format& message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
ASSIMP_LOG_WARN(Prefix()+(std::string)message);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogError(const Formatter::format& message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
ASSIMP_LOG_ERROR(Prefix()+(std::string)message);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogInfo(const Formatter::format& message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
ASSIMP_LOG_INFO(Prefix()+(std::string)message);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogDebug(const Formatter::format& message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
ASSIMP_LOG_DEBUG(Prefix()+(std::string)message);
|
||||
}
|
||||
}
|
||||
|
||||
// https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462
|
||||
#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogWarn (const char* message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
LogWarn(Formatter::format(message));
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogError (const char* message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
LogError(Formatter::format(message));
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogInfo (const char* message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
LogInfo(Formatter::format(message));
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogDebug (const char* message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
LogDebug(Formatter::format(message));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
static const char* Prefix();
|
||||
|
||||
};
|
||||
} // ! Assimp
|
||||
|
||||
#endif
|
111
dependencies/assimp/include/assimp/LogStream.hpp
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file LogStream.hpp
|
||||
* @brief Abstract base class 'LogStream', representing an output log stream.
|
||||
*/
|
||||
#ifndef INCLUDED_AI_LOGSTREAM_H
|
||||
#define INCLUDED_AI_LOGSTREAM_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
class IOSystem;
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
/** @brief CPP-API: Abstract interface for log stream implementations.
|
||||
*
|
||||
* Several default implementations are provided, see #aiDefaultLogStream for more
|
||||
* details. Writing your own implementation of LogStream is just necessary if these
|
||||
* are not enough for your purpose. */
|
||||
class ASSIMP_API LogStream
|
||||
#ifndef SWIG
|
||||
: public Intern::AllocateFromAssimpHeap
|
||||
#endif
|
||||
{
|
||||
protected:
|
||||
/** @brief Default constructor */
|
||||
LogStream() AI_NO_EXCEPT;
|
||||
|
||||
public:
|
||||
/** @brief Virtual destructor */
|
||||
virtual ~LogStream();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Overwrite this for your own output methods
|
||||
*
|
||||
* Log messages *may* consist of multiple lines and you shouldn't
|
||||
* expect a consistent formatting. If you want custom formatting
|
||||
* (e.g. generate HTML), supply a custom instance of Logger to
|
||||
* #DefaultLogger:set(). Usually you can *expect* that a log message
|
||||
* is exactly one line and terminated with a single \n character.
|
||||
* @param message Message to be written */
|
||||
virtual void write(const char* message) = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Creates a default log stream
|
||||
* @param streams Type of the default stream
|
||||
* @param name For aiDefaultLogStream_FILE: name of the output file
|
||||
* @param io For aiDefaultLogStream_FILE: IOSystem to be used to open the output
|
||||
* file. Pass NULL for the default implementation.
|
||||
* @return New LogStream instance. */
|
||||
static LogStream* createDefaultStream(aiDefaultLogStream stream,
|
||||
const char* name = "AssimpLog.txt",
|
||||
IOSystem* io = nullptr );
|
||||
|
||||
}; // !class LogStream
|
||||
|
||||
inline
|
||||
LogStream::LogStream() AI_NO_EXCEPT {
|
||||
// empty
|
||||
}
|
||||
|
||||
inline
|
||||
LogStream::~LogStream() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif
|
305
dependencies/assimp/include/assimp/Logger.hpp
vendored
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Logger.hpp
|
||||
* @brief Abstract base class 'Logger', base of the logging system.
|
||||
*/
|
||||
#ifndef INCLUDED_AI_LOGGER_H
|
||||
#define INCLUDED_AI_LOGGER_H
|
||||
|
||||
#include <assimp/types.h>
|
||||
#include <assimp/TinyFormatter.h>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
class LogStream;
|
||||
|
||||
// Maximum length of a log message. Longer messages are rejected.
|
||||
#define MAX_LOG_MESSAGE_LENGTH 1024u
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
/** @brief CPP-API: Abstract interface for logger implementations.
|
||||
* Assimp provides a default implementation and uses it for almost all
|
||||
* logging stuff ('DefaultLogger'). This class defines just basic logging
|
||||
* behavior and is not of interest for you. Instead, take a look at #DefaultLogger. */
|
||||
class ASSIMP_API Logger
|
||||
#ifndef SWIG
|
||||
: public Intern::AllocateFromAssimpHeap
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @enum LogSeverity
|
||||
* @brief Log severity to describe the granularity of logging.
|
||||
*/
|
||||
enum LogSeverity {
|
||||
NORMAL, //!< Normal granularity of logging
|
||||
VERBOSE //!< Debug infos will be logged, too
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @enum ErrorSeverity
|
||||
* @brief Description for severity of a log message.
|
||||
*
|
||||
* Every LogStream has a bitwise combination of these flags.
|
||||
* A LogStream doesn't receive any messages of a specific type
|
||||
* if it doesn't specify the corresponding ErrorSeverity flag.
|
||||
*/
|
||||
enum ErrorSeverity {
|
||||
Debugging = 1, //!< Debug log message
|
||||
Info = 2, //!< Info log message
|
||||
Warn = 4, //!< Warn log message
|
||||
Err = 8 //!< Error log message
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/** @brief Virtual destructor */
|
||||
virtual ~Logger();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Writes a debug message
|
||||
* @param message Debug message*/
|
||||
void debug(const char* message);
|
||||
void debug(const std::string &message);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Writes a info message
|
||||
* @param message Info message*/
|
||||
void info(const char* message);
|
||||
void info(const std::string &message);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Writes a warning message
|
||||
* @param message Warn message*/
|
||||
void warn(const char* message);
|
||||
void warn(const std::string &message);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Writes an error message
|
||||
* @param message Error message*/
|
||||
void error(const char* message);
|
||||
void error(const std::string &message);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Set a new log severity.
|
||||
* @param log_severity New severity for logging*/
|
||||
void setLogSeverity(LogSeverity log_severity);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Get the current log severity*/
|
||||
LogSeverity getLogSeverity() const;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Attach a new log-stream
|
||||
*
|
||||
* The logger takes ownership of the stream and is responsible
|
||||
* for its destruction (which is done using ::delete when the logger
|
||||
* itself is destroyed). Call detachStream to detach a stream and to
|
||||
* gain ownership of it again.
|
||||
* @param pStream Log-stream to attach
|
||||
* @param severity Message filter, specified which types of log
|
||||
* messages are dispatched to the stream. Provide a bitwise
|
||||
* combination of the ErrorSeverity flags.
|
||||
* @return true if the stream has been attached, false otherwise.*/
|
||||
virtual bool attachStream(LogStream *pStream,
|
||||
unsigned int severity = Debugging | Err | Warn | Info) = 0;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** @brief Detach a still attached stream from the logger (or
|
||||
* modify the filter flags bits)
|
||||
* @param pStream Log-stream instance for detaching
|
||||
* @param severity Provide a bitwise combination of the ErrorSeverity
|
||||
* flags. This value is &~ed with the current flags of the stream,
|
||||
* if the result is 0 the stream is detached from the Logger and
|
||||
* the caller retakes the possession of the stream.
|
||||
* @return true if the stream has been detached, false otherwise.*/
|
||||
virtual bool detatchStream(LogStream *pStream,
|
||||
unsigned int severity = Debugging | Err | Warn | Info) = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
Logger() AI_NO_EXCEPT;
|
||||
|
||||
/**
|
||||
* Construction with a given log severity
|
||||
*/
|
||||
explicit Logger(LogSeverity severity);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Called as a request to write a specific debug message
|
||||
* @param message Debug message. Never longer than
|
||||
* MAX_LOG_MESSAGE_LENGTH characters (excluding the '0').
|
||||
* @note The message string is only valid until the scope of
|
||||
* the function is left.
|
||||
*/
|
||||
virtual void OnDebug(const char* message)= 0;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Called as a request to write a specific info message
|
||||
* @param message Info message. Never longer than
|
||||
* MAX_LOG_MESSAGE_LENGTH characters (ecxluding the '0').
|
||||
* @note The message string is only valid until the scope of
|
||||
* the function is left.
|
||||
*/
|
||||
virtual void OnInfo(const char* message) = 0;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Called as a request to write a specific warn message
|
||||
* @param message Warn message. Never longer than
|
||||
* MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
|
||||
* @note The message string is only valid until the scope of
|
||||
* the function is left.
|
||||
*/
|
||||
virtual void OnWarn(const char* essage) = 0;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Called as a request to write a specific error message
|
||||
* @param message Error message. Never longer than
|
||||
* MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
|
||||
* @note The message string is only valid until the scope of
|
||||
* the function is left.
|
||||
*/
|
||||
virtual void OnError(const char* message) = 0;
|
||||
|
||||
protected:
|
||||
LogSeverity m_Severity;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// Default constructor
|
||||
inline
|
||||
Logger::Logger() AI_NO_EXCEPT
|
||||
: m_Severity(NORMAL) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// Virtual destructor
|
||||
inline
|
||||
Logger::~Logger() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// Construction with given logging severity
|
||||
inline
|
||||
Logger::Logger(LogSeverity severity)
|
||||
: m_Severity(severity) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// Log severity setter
|
||||
inline
|
||||
void Logger::setLogSeverity(LogSeverity log_severity){
|
||||
m_Severity = log_severity;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// Log severity getter
|
||||
inline
|
||||
Logger::LogSeverity Logger::getLogSeverity() const {
|
||||
return m_Severity;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline
|
||||
void Logger::debug(const std::string &message) {
|
||||
return debug(message.c_str());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline
|
||||
void Logger::error(const std::string &message) {
|
||||
return error(message.c_str());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline
|
||||
void Logger::warn(const std::string &message) {
|
||||
return warn(message.c_str());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
inline
|
||||
void Logger::info(const std::string &message) {
|
||||
return info(message.c_str());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#define ASSIMP_LOG_WARN_F(string,...)\
|
||||
DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
|
||||
|
||||
#define ASSIMP_LOG_ERROR_F(string,...)\
|
||||
DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
|
||||
|
||||
#define ASSIMP_LOG_DEBUG_F(string,...)\
|
||||
DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
|
||||
|
||||
#define ASSIMP_LOG_INFO_F(string,...)\
|
||||
DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
|
||||
|
||||
|
||||
#define ASSIMP_LOG_WARN(string)\
|
||||
DefaultLogger::get()->warn(string)
|
||||
|
||||
#define ASSIMP_LOG_ERROR(string)\
|
||||
DefaultLogger::get()->error(string)
|
||||
|
||||
#define ASSIMP_LOG_DEBUG(string)\
|
||||
DefaultLogger::get()->debug(string)
|
||||
|
||||
#define ASSIMP_LOG_INFO(string)\
|
||||
DefaultLogger::get()->info(string)
|
||||
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // !! INCLUDED_AI_LOGGER_H
|
49
dependencies/assimp/include/assimp/Macros.h
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Helper macro to set a pointer to NULL in debug builds
|
||||
*/
|
||||
#if (defined ASSIMP_BUILD_DEBUG)
|
||||
# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
|
||||
#else
|
||||
# define AI_DEBUG_INVALIDATE_PTR(x)
|
||||
#endif
|
||||
|
86
dependencies/assimp/include/assimp/MathFunctions.h
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/** @file MathFunctions.h
|
||||
* @brief Implementation of math utility functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace Assimp {
|
||||
namespace Math {
|
||||
|
||||
// TODO: use binary GCD for unsigned integers ....
|
||||
template < typename IntegerType >
|
||||
inline
|
||||
IntegerType gcd( IntegerType a, IntegerType b ) {
|
||||
const IntegerType zero = (IntegerType)0;
|
||||
while ( true ) {
|
||||
if ( a == zero )
|
||||
return b;
|
||||
b %= a;
|
||||
|
||||
if ( b == zero )
|
||||
return a;
|
||||
a %= b;
|
||||
}
|
||||
}
|
||||
|
||||
template < typename IntegerType >
|
||||
inline
|
||||
IntegerType lcm( IntegerType a, IntegerType b ) {
|
||||
const IntegerType t = gcd (a,b);
|
||||
if (!t)
|
||||
return t;
|
||||
return a / t * b;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
T getEpsilon() {
|
||||
return std::numeric_limits<T>::epsilon();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
244
dependencies/assimp/include/assimp/MemoryIOWrapper.h
vendored
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file MemoryIOWrapper.h
|
||||
* Handy IOStream/IOSystem implemetation to read directly from a memory buffer */
|
||||
#ifndef AI_MEMORYIOSTREAM_H_INC
|
||||
#define AI_MEMORYIOSTREAM_H_INC
|
||||
|
||||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
#define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$"
|
||||
#define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
/** Implementation of IOStream to read directly from a memory buffer */
|
||||
// ----------------------------------------------------------------------------------
|
||||
class MemoryIOStream : public IOStream {
|
||||
public:
|
||||
MemoryIOStream (const uint8_t* buff, size_t len, bool own = false)
|
||||
: buffer (buff)
|
||||
, length(len)
|
||||
, pos((size_t)0)
|
||||
, own(own) {
|
||||
// empty
|
||||
}
|
||||
|
||||
~MemoryIOStream () {
|
||||
if(own) {
|
||||
delete[] buffer;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Read from stream
|
||||
size_t Read(void* pvBuffer, size_t pSize, size_t pCount) {
|
||||
ai_assert(nullptr != pvBuffer);
|
||||
ai_assert(0 != pSize);
|
||||
|
||||
const size_t cnt = std::min( pCount, (length-pos) / pSize);
|
||||
const size_t ofs = pSize * cnt;
|
||||
|
||||
::memcpy(pvBuffer,buffer+pos,ofs);
|
||||
pos += ofs;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Write to stream
|
||||
size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/,size_t /*pCount*/) {
|
||||
ai_assert(false); // won't be needed
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Seek specific position
|
||||
aiReturn Seek(size_t pOffset, aiOrigin pOrigin) {
|
||||
if (aiOrigin_SET == pOrigin) {
|
||||
if (pOffset > length) {
|
||||
return AI_FAILURE;
|
||||
}
|
||||
pos = pOffset;
|
||||
} else if (aiOrigin_END == pOrigin) {
|
||||
if (pOffset > length) {
|
||||
return AI_FAILURE;
|
||||
}
|
||||
pos = length-pOffset;
|
||||
} else {
|
||||
if (pOffset+pos > length) {
|
||||
return AI_FAILURE;
|
||||
}
|
||||
pos += pOffset;
|
||||
}
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Get current seek position
|
||||
size_t Tell() const {
|
||||
return pos;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Get size of file
|
||||
size_t FileSize() const {
|
||||
return length;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Flush file contents
|
||||
void Flush() {
|
||||
ai_assert(false); // won't be needed
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t* buffer;
|
||||
size_t length,pos;
|
||||
bool own;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Dummy IO system to read from a memory buffer */
|
||||
class MemoryIOSystem : public IOSystem {
|
||||
public:
|
||||
/** Constructor. */
|
||||
MemoryIOSystem(const uint8_t* buff, size_t len, IOSystem* io)
|
||||
: buffer(buff)
|
||||
, length(len)
|
||||
, existing_io(io)
|
||||
, created_streams() {
|
||||
// empty
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
~MemoryIOSystem() {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Tests for the existence of a file at the given path. */
|
||||
bool Exists(const char* pFile) const override {
|
||||
if (0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) {
|
||||
return true;
|
||||
}
|
||||
return existing_io ? existing_io->Exists(pFile) : false;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns the directory separator. */
|
||||
char getOsSeparator() const override {
|
||||
return existing_io ? existing_io->getOsSeparator()
|
||||
: '/'; // why not? it doesn't care
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Open a new file with a given path. */
|
||||
IOStream* Open(const char* pFile, const char* pMode = "rb") override {
|
||||
if ( 0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) {
|
||||
created_streams.emplace_back(new MemoryIOStream(buffer, length));
|
||||
return created_streams.back();
|
||||
}
|
||||
return existing_io ? existing_io->Open(pFile, pMode) : NULL;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Closes the given file and releases all resources associated with it. */
|
||||
void Close( IOStream* pFile) override {
|
||||
auto it = std::find(created_streams.begin(), created_streams.end(), pFile);
|
||||
if (it != created_streams.end()) {
|
||||
delete pFile;
|
||||
created_streams.erase(it);
|
||||
} else if (existing_io) {
|
||||
existing_io->Close(pFile);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Compare two paths */
|
||||
bool ComparePaths(const char* one, const char* second) const override {
|
||||
return existing_io ? existing_io->ComparePaths(one, second) : false;
|
||||
}
|
||||
|
||||
bool PushDirectory( const std::string &path ) override {
|
||||
return existing_io ? existing_io->PushDirectory(path) : false;
|
||||
}
|
||||
|
||||
const std::string &CurrentDirectory() const override {
|
||||
static std::string empty;
|
||||
return existing_io ? existing_io->CurrentDirectory() : empty;
|
||||
}
|
||||
|
||||
size_t StackSize() const override {
|
||||
return existing_io ? existing_io->StackSize() : 0;
|
||||
}
|
||||
|
||||
bool PopDirectory() override {
|
||||
return existing_io ? existing_io->PopDirectory() : false;
|
||||
}
|
||||
|
||||
bool CreateDirectory( const std::string &path ) override {
|
||||
return existing_io ? existing_io->CreateDirectory(path) : false;
|
||||
}
|
||||
|
||||
bool ChangeDirectory( const std::string &path ) override {
|
||||
return existing_io ? existing_io->ChangeDirectory(path) : false;
|
||||
}
|
||||
|
||||
bool DeleteFile( const std::string &file ) override {
|
||||
return existing_io ? existing_io->DeleteFile(file) : false;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t* buffer;
|
||||
size_t length;
|
||||
IOSystem* existing_io;
|
||||
std::vector<IOStream*> created_streams;
|
||||
};
|
||||
|
||||
} // end namespace Assimp
|
||||
|
||||
#endif
|