├── Source ├── Runtime │ ├── Engine │ │ ├── ThirdParty │ │ │ ├── lodepng.txt │ │ │ └── lodepng.h │ │ ├── Precompiled.cpp │ │ ├── Private │ │ │ ├── 3D │ │ │ │ ├── Bone.cpp │ │ │ │ ├── GameEngine.cpp │ │ │ │ ├── TransformComponent.cpp │ │ │ │ ├── GameObject.cpp │ │ │ │ ├── Mesh.cpp │ │ │ │ └── CameraObject.cpp │ │ │ ├── 2D │ │ │ │ ├── CameraObject.cpp │ │ │ │ ├── TransformComponent.cpp │ │ │ │ ├── GameEngine.cpp │ │ │ │ ├── GameObject.cpp │ │ │ │ └── Mesh.cpp │ │ │ ├── Texture.cpp │ │ │ └── InputManager.cpp │ │ ├── Precompiled.h │ │ ├── Public │ │ │ ├── 2D │ │ │ │ ├── Mesh.h │ │ │ │ ├── GameEngine.h │ │ │ │ ├── GameObject.h │ │ │ │ ├── CameraObject.h │ │ │ │ └── TransformComponent.h │ │ │ ├── 3D │ │ │ │ ├── Bone.h │ │ │ │ ├── Mesh.h │ │ │ │ ├── Resources.h │ │ │ │ ├── GameEngine.h │ │ │ │ ├── GameObject.h │ │ │ │ ├── CameraObject.h │ │ │ │ └── TransformComponent.h │ │ │ ├── EngineInterface.h │ │ │ ├── EngineHeaders.h │ │ │ ├── Texture.h │ │ │ └── InputManager.h │ │ └── CMakeLists.txt │ ├── Math │ │ ├── Precompiled.cpp │ │ ├── Precompiled.h │ │ ├── Public │ │ │ ├── Windows │ │ │ │ └── WindowsPlatform.h │ │ │ ├── Plane.h │ │ │ ├── Frustum.h │ │ │ ├── MathUtil.h │ │ │ ├── Matrix2x2.h │ │ │ ├── Matrix3x3.h │ │ │ ├── Matrix4x4.h │ │ │ ├── Transform.h │ │ │ ├── Vector2.h │ │ │ ├── Vector3.h │ │ │ ├── Vector4.h │ │ │ ├── Quaternion.h │ │ │ ├── ScreenPoint.h │ │ │ ├── CoreDefinition.h │ │ │ ├── Platform.h │ │ │ ├── MathHeaders.h │ │ │ ├── Sphere.h │ │ │ ├── Circle.h │ │ │ ├── HSVColor.h │ │ │ ├── Rotator.h │ │ │ ├── Color32.h │ │ │ ├── Rectangle.h │ │ │ ├── Box.h │ │ │ └── LinearColor.h │ │ ├── Private │ │ │ ├── Frustum.cpp │ │ │ ├── Transform.cpp │ │ │ ├── Color32.cpp │ │ │ ├── Box.cpp │ │ │ ├── Rectangle.cpp │ │ │ ├── Quaternion.cpp │ │ │ ├── Rotator.cpp │ │ │ ├── Math.cpp │ │ │ ├── Matrix2x2.cpp │ │ │ ├── Matrix3x3.cpp │ │ │ ├── Circle.cpp │ │ │ ├── Sphere.cpp │ │ │ ├── Matrix4x4.cpp │ │ │ ├── Vector2.cpp │ │ │ ├── Plane.cpp │ │ │ ├── Vector3.cpp │ │ │ ├── Vector4.cpp │ │ │ └── LinearColor.cpp │ │ └── CMakeLists.txt │ └── Renderer │ │ ├── Precompiled.cpp │ │ ├── Private │ │ ├── 2D │ │ │ ├── Shader.cpp │ │ │ └── Vertex.cpp │ │ ├── 3D │ │ │ ├── Shader.cpp │ │ │ ├── Vertex.cpp │ │ │ └── PerspectiveTest.cpp │ │ └── Windows │ │ │ ├── WindowsGDI.cpp │ │ │ └── WindowsRSI.cpp │ │ ├── Precompiled.h │ │ ├── Public │ │ ├── 2D │ │ │ ├── Shader.h │ │ │ └── Vertex.h │ │ ├── 3D │ │ │ ├── Shader.h │ │ │ ├── PerspectiveTest.h │ │ │ └── Vertex.h │ │ ├── RendererHeaders.h │ │ ├── RendererInterface.h │ │ └── Windows │ │ │ ├── WindowsRSI.h │ │ │ └── WindowsGDI.h │ │ └── CMakeLists.txt └── Player │ ├── Precompiled.cpp │ ├── SoftRenderer.h │ ├── SoftRenderer.cpp │ ├── SoftRenderer2D.cpp │ ├── SoftRenderer3D.cpp │ ├── Private │ ├── Windows │ │ ├── Res │ │ │ ├── player.rc │ │ │ ├── player.ico │ │ │ ├── player_small.ico │ │ │ └── resource.h │ │ ├── WindowsApp.cpp │ │ ├── WindowsPlayer.h │ │ └── WindowsUtil.h │ └── SystemInputManager.cpp │ ├── Precompiled.h │ ├── SystemInputManager.h │ └── CMakeLists.txt ├── .gitignore ├── Document ├── Depth.png ├── Normal.png ├── Wireframe1.png └── Wireframe2.png ├── Resource └── Steve.png ├── CMake-VS-16-2019.bat ├── LICENSE ├── README.md └── CMakeLists.txt /Source/Runtime/Engine/ThirdParty/lodepng.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Source/Player/Precompiled.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /Source/Player/Res/*.aps 2 | /Project 3 | /Output 4 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Precompiled.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Precompiled.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Precompiled.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Precompiled.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MathHeaders.h" 4 | -------------------------------------------------------------------------------- /Document/Depth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Document/Depth.png -------------------------------------------------------------------------------- /Resource/Steve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Resource/Steve.png -------------------------------------------------------------------------------- /Document/Normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Document/Normal.png -------------------------------------------------------------------------------- /Document/Wireframe1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Document/Wireframe1.png -------------------------------------------------------------------------------- /Document/Wireframe2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Document/Wireframe2.png -------------------------------------------------------------------------------- /Source/Player/SoftRenderer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Player/SoftRenderer.h -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/3D/Bone.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DDD; 4 | 5 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Private/2D/Shader.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DD; 4 | 5 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Private/2D/Vertex.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DD; 4 | 5 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Private/3D/Shader.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DDD; 4 | 5 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Private/3D/Vertex.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DDD; 4 | 5 | -------------------------------------------------------------------------------- /Source/Player/SoftRenderer.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Player/SoftRenderer.cpp -------------------------------------------------------------------------------- /Source/Runtime/Engine/Precompiled.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MathHeaders.h" 4 | #include "EngineHeaders.h" 5 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/2D/CameraObject.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DD; 4 | 5 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/2D/TransformComponent.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DD; 4 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Windows/WindowsPlatform.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #define FORCEINLINE __forceinline 5 | -------------------------------------------------------------------------------- /Source/Player/SoftRenderer2D.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Player/SoftRenderer2D.cpp -------------------------------------------------------------------------------- /Source/Player/SoftRenderer3D.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Player/SoftRenderer3D.cpp -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Frustum.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Private/3D/PerspectiveTest.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DDD; 4 | 5 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Plane.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/Plane.h -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Precompiled.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MathHeaders.h" 4 | #include "RendererHeaders.h" 5 | 6 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/2D/Mesh.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/2D/Mesh.h -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/3D/Bone.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/3D/Bone.h -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/3D/Mesh.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/3D/Mesh.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Frustum.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/Frustum.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/MathUtil.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/MathUtil.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Matrix2x2.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/Matrix2x2.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Matrix3x3.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/Matrix3x3.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Matrix4x4.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/Matrix4x4.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Transform.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/Transform.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Vector2.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/Vector2.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Vector3.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/Vector3.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Vector4.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/Vector4.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Quaternion.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/Quaternion.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/ScreenPoint.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/ScreenPoint.h -------------------------------------------------------------------------------- /Source/Player/Private/Windows/Res/player.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Player/Private/Windows/Res/player.rc -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/3D/Resources.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/3D/Resources.h -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Transform.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Private/Transform.cpp -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/CoreDefinition.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Math/Public/CoreDefinition.h -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Public/2D/Shader.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Renderer/Public/2D/Shader.h -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Public/3D/Shader.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Renderer/Public/3D/Shader.h -------------------------------------------------------------------------------- /Source/Player/Private/Windows/Res/player.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Player/Private/Windows/Res/player.ico -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/2D/GameEngine.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/2D/GameEngine.h -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/2D/GameObject.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/2D/GameObject.h -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/3D/GameEngine.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/3D/GameEngine.h -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/3D/GameObject.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/3D/GameObject.h -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/2D/GameEngine.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Private/2D/GameEngine.cpp -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/3D/GameEngine.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Private/3D/GameEngine.cpp -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/2D/CameraObject.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/2D/CameraObject.h -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/3D/CameraObject.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/3D/CameraObject.h -------------------------------------------------------------------------------- /Source/Player/Private/Windows/Res/player_small.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Player/Private/Windows/Res/player_small.ico -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Color32.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | const Color32 Color32::Error(255, 0, 255, 255); 6 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/2D/TransformComponent.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/2D/TransformComponent.h -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/3D/TransformComponent.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Public/3D/TransformComponent.h -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Public/3D/PerspectiveTest.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Renderer/Public/3D/PerspectiveTest.h -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/3D/TransformComponent.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideugu/CKSoftRenderer/HEAD/Source/Runtime/Engine/Private/3D/TransformComponent.cpp -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/2D/GameObject.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DD; 4 | 5 | GameObject GameObject::Invalid(Math::InvalidHashName); 6 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/3D/GameObject.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DDD; 4 | 5 | GameObject GameObject::Invalid(Math::InvalidHashName); 6 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/3D/Mesh.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DDD; 4 | 5 | void Mesh::CalculateBounds() 6 | { 7 | _SphereBound = Sphere(_Vertices); 8 | _BoxBound = Box(_Vertices); 9 | } 10 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/2D/Mesh.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DD; 4 | 5 | void Mesh::CalculateBounds() 6 | { 7 | _CircleBound = Circle(_Vertices); 8 | _RectBound = Rectangle(_Vertices); 9 | } 10 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Box.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | Box::Box(const std::vector InVertices) 6 | { 7 | for (const auto& v : InVertices) 8 | { 9 | *this += v; 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Rectangle.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | Rectangle::Rectangle(const std::vector InVertices) 6 | { 7 | for(const auto& v : InVertices) 8 | { 9 | *this += v; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Quaternion.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | const Quaternion Quaternion::Identity(0.f, 0.f, 0.f, 1.f); 6 | 7 | std::string Quaternion::ToString() const 8 | { 9 | return ToRotator().ToString(); 10 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Platform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreDefinition.h" 4 | 5 | #if defined(PLATFORM_WINDOWS) 6 | #include "Windows/WindowsPlatform.h" 7 | #endif 8 | 9 | #if !defined(FORCEINLINE) 10 | #define FORCEINLINE inline 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Rotator.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | const Rotator Rotator::Identity(0.f, 0.f, 0.f); 6 | 7 | std::string Rotator::ToString() const 8 | { 9 | char result[64]; 10 | std::snprintf(result, sizeof(result), "(Y : %.1f, R: %.1f, P : %.1f)", Yaw, Roll, Pitch); 11 | return result; 12 | } -------------------------------------------------------------------------------- /Source/Player/Precompiled.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(PLATFORM_WINDOWS) 4 | 5 | #define WIN32_LEAN_AND_MEAN 6 | #include 7 | #include 8 | #include "Res/resource.h" 9 | 10 | #endif 11 | 12 | #include "MathHeaders.h" 13 | #include "EngineHeaders.h" 14 | #include "RendererHeaders.h" 15 | #include "SystemInputManager.h" 16 | 17 | using namespace CK; 18 | 19 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Public/RendererHeaders.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "2D/Vertex.h" 6 | #include "2D/Shader.h" 7 | #include "3D/Vertex.h" 8 | #include "3D/Shader.h" 9 | #include "3D/PerspectiveTest.h" 10 | 11 | #include "RendererInterface.h" 12 | 13 | #if defined(PLATFORM_WINDOWS) 14 | #include 15 | #include "Windows/WindowsGDI.h" 16 | #include "Windows/WindowsRSI.h" 17 | #endif 18 | 19 | using namespace CK; 20 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/3D/CameraObject.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK::DDD; 4 | 5 | void CameraObject::SetLookAtRotation(const GameObject& InGameObject, const Vector3& InUp) 6 | { 7 | SetLookAtRotation(InGameObject.GetTransform().GetWorldPosition(), InUp); 8 | } 9 | 10 | 11 | void CameraObject::SetLookAtRotation(const Vector3& InTargetPosition, const Vector3& InUp) 12 | { 13 | _Transform.SetWorldRotation(Quaternion(InTargetPosition - _Transform.GetWorldPosition())); 14 | } 15 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/EngineInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | enum class GameObjectType : UINT32 7 | { 8 | Normal = 0, 9 | Gizmo 10 | }; 11 | 12 | enum class MeshType : UINT32 13 | { 14 | Normal = 0, 15 | Skinned 16 | }; 17 | 18 | class EngineInterface 19 | { 20 | public: 21 | virtual bool Init() = 0; 22 | virtual bool IsInitialized() = 0; 23 | virtual void OnScreenResize(const ScreenPoint& InScreenSize) = 0; 24 | virtual InputManager& GetInputManager() = 0; 25 | }; 26 | 27 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Math.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | //const float Math::PI = 3.14159265358979323846f; 6 | //const float Math::TwoPI = 2.f * PI; 7 | //const float Math::HalfPI = 1.57079632679f; 8 | //const float Math::InvPI = 0.31830988618f; 9 | //const int Math::IntMin = (-2147483647 - 1); 10 | //const int Math::IntMax = 2147483647; 11 | // 12 | //const std::string Math::InvalidHashName("!@CK_INVALIDHASH#$"); 13 | const std::size_t Math::InvalidHash = std::hash()(InvalidHashName); 14 | 15 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Matrix2x2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | const Matrix2x2 Matrix2x2::Identity(Vector2(1.f, 0.f), Vector2(0.f, 1.f)); 6 | 7 | std::vector Matrix2x2::ToStrings() const 8 | { 9 | std::vector result; 10 | 11 | Matrix2x2 trMatrix = this->Tranpose(); 12 | for (BYTE i = 0; i < Rank; ++i) 13 | { 14 | char row[64]; 15 | std::snprintf(row, sizeof(row), "| %.3f , %.3f |", trMatrix.Cols[i].X, trMatrix.Cols[i].Y); 16 | result.emplace_back(row); 17 | } 18 | return result; 19 | } -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/EngineHeaders.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "InputManager.h" 6 | #include "Texture.h" 7 | 8 | #include "EngineInterface.h" 9 | 10 | #include "2D/Mesh.h" 11 | #include "2D/TransformComponent.h" 12 | #include "2D/GameObject.h" 13 | #include "2D/CameraObject.h" 14 | #include "2D/GameEngine.h" 15 | 16 | #include "3D/Resources.h" 17 | #include "3D/TransformComponent.h" 18 | #include "3D/Bone.h" 19 | #include "3D/Mesh.h" 20 | #include "3D/GameObject.h" 21 | #include "3D/CameraObject.h" 22 | #include "3D/GameEngine.h" 23 | 24 | using namespace CK; 25 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Matrix3x3.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | const Matrix3x3 Matrix3x3::Identity(Vector3(1.f, 0.f, 0.f), Vector3(0.f, 1.f, 0.f), Vector3(0.f, 0.f, 1.f)); 6 | 7 | std::vector Matrix3x3::ToStrings() const 8 | { 9 | std::vector result; 10 | 11 | Matrix3x3 trMatrix = this->Tranpose(); 12 | for (BYTE i = 0; i < Rank; ++i) 13 | { 14 | char row[64]; 15 | std::snprintf(row, sizeof(row), "| %.3f , %.3f , %.3f |", trMatrix.Cols[i].X, trMatrix.Cols[i].Y, trMatrix.Cols[i].Z); 16 | result.emplace_back(row); 17 | } 18 | return result; 19 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Circle.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | Circle::Circle(const std::vector InVertices) 6 | { 7 | size_t cnt = InVertices.size(); 8 | if (cnt == 0) 9 | { 10 | return; 11 | } 12 | 13 | Vector2 sum; 14 | for (const auto& v : InVertices) 15 | { 16 | sum += v; 17 | } 18 | 19 | Center = sum / (float)cnt; 20 | float distanceSquared = 0.f; 21 | Radius = (*std::max_element(InVertices.begin(), InVertices.end(), 22 | [&](Vector2 const& lhs, Vector2 const& rhs) 23 | { 24 | return (Center - lhs).SizeSquared() < (Center - rhs).SizeSquared(); 25 | })).Size(); 26 | } 27 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Sphere.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | Sphere::Sphere(const std::vector& InVertices) 6 | { 7 | size_t cnt = InVertices.size(); 8 | if (cnt == 0) 9 | { 10 | return; 11 | } 12 | 13 | Vector3 sum; 14 | for (const auto& v : InVertices) 15 | { 16 | sum += v; 17 | } 18 | 19 | Center = sum / (float)cnt; 20 | float distanceSquared = 0.f; 21 | Radius = (*std::max_element(InVertices.begin(), InVertices.end(), 22 | [&](Vector3 const& lhs, Vector3 const& rhs) 23 | { 24 | return (Center - lhs).SizeSquared() < (Center - rhs).SizeSquared(); 25 | })).Size(); 26 | } 27 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/Texture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | class Texture 7 | { 8 | public: 9 | Texture() = default; 10 | Texture(std::string InFileName); 11 | ~Texture() {} 12 | 13 | public: 14 | void LoadPNG(std::string InFileName); 15 | void Release(); 16 | bool IsIntialized() const { return (_Buffer.size() > 0); } 17 | UINT32 GetWidth() const { return _Width; } 18 | UINT32 GetHeight() const { return _Height; } 19 | UINT32 GetSize() const { return _Width * _Height; } 20 | LinearColor GetSample(Vector2 InUV) const; 21 | 22 | private: 23 | std::vector _Buffer; 24 | UINT32 _Width = 0; 25 | UINT32 _Height = 0; 26 | }; 27 | 28 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Matrix4x4.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | const Matrix4x4 Matrix4x4::Identity(Vector4(1.f, 0.f, 0.f, 0.f), Vector4(0.f, 1.f, 0.f, 0.f), Vector4(0.f, 0.f, 1.f, 0.f), Vector4(0.f, 0.f, 0.f, 1.f)); 6 | 7 | std::vector Matrix4x4::ToStrings() const 8 | { 9 | std::vector result; 10 | 11 | Matrix4x4 trMatrix = this->Tranpose(); 12 | for (BYTE i = 0; i < Rank; ++i) 13 | { 14 | char row[64]; 15 | std::snprintf(row, sizeof(row), "| %.3f , %.3f , %.3f, %.3f |", trMatrix.Cols[i].X, trMatrix.Cols[i].Y, trMatrix.Cols[i].Z, trMatrix.Cols[i].W); 16 | result.emplace_back(row); 17 | } 18 | return result; 19 | } 20 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Vector2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | const Vector2 Vector2::UnitX(1.f, 0.f); 6 | const Vector2 Vector2::UnitY(0.f, 1.f); 7 | const Vector2 Vector2::Zero(0.f, 0.f); 8 | const Vector2 Vector2::One(1.f, 1.f); 9 | 10 | std::string Vector2::ToString() const 11 | { 12 | char result[64]; 13 | std::snprintf(result, sizeof(result), "(%.3f, %.3f)", X, Y); 14 | return result; 15 | } 16 | 17 | Vector2 Vector2::Normalize() const 18 | { 19 | float squareSum = SizeSquared(); 20 | if (squareSum == 1.f) 21 | { 22 | return *this; 23 | } 24 | else if (squareSum == 0.f) 25 | { 26 | return Vector2::Zero; 27 | } 28 | 29 | float invLength = Math::InvSqrt(squareSum); 30 | return Vector2(X, Y) * invLength; 31 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Plane.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | Plane::Plane(const Vector3& InPoint1, const Vector3& InPoint2, const Vector3& InPoint3) 6 | { 7 | Vector3 v1 = InPoint2 - InPoint1; 8 | Vector3 v2 = InPoint3 - InPoint1; 9 | 10 | Normal = v1.Cross(v2).Normalize(); 11 | D = -Normal.Dot(InPoint1); 12 | } 13 | 14 | Plane::Plane(const Vector4& InVector4) 15 | { 16 | Normal = InVector4.ToVector3(); 17 | D = InVector4.W; 18 | Normalize(); 19 | } 20 | 21 | void Plane::Normalize() 22 | { 23 | float squaredSize = Normal.SizeSquared(); 24 | if (Math::EqualsInTolerance(squaredSize, 1.f)) 25 | { 26 | return; 27 | } 28 | 29 | float invLength = Math::InvSqrt(squaredSize); 30 | Normal *= invLength; 31 | D *= invLength; 32 | } 33 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Vector3.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | const Vector3 Vector3::UnitX(1.f, 0.f, 0.f); 6 | const Vector3 Vector3::UnitY(0.f, 1.f, 0.f); 7 | const Vector3 Vector3::UnitZ(0.f, 0.f, 1.f); 8 | const Vector3 Vector3::Zero(0.f, 0.f, 0.f); 9 | const Vector3 Vector3::One(1.f, 1.f, 1.f); 10 | 11 | std::string Vector3::ToString() const 12 | { 13 | char result[64]; 14 | std::snprintf(result, sizeof(result), "(%.3f, %.3f, %.3f)", X, Y, Z); 15 | return result; 16 | } 17 | 18 | Vector3 Vector3::Normalize() const 19 | { 20 | float squareSum = SizeSquared(); 21 | if (squareSum == 1.f) 22 | { 23 | return *this; 24 | } 25 | else if (squareSum == 0.f) 26 | { 27 | return Vector3::Zero; 28 | } 29 | 30 | float invLength = Math::InvSqrt(squareSum); 31 | return Vector3(X * invLength, Y * invLength, Z * invLength); 32 | } -------------------------------------------------------------------------------- /CMake-VS-16-2019.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | @echo: 4 | @echo [SoftRenderer Project Generator] 5 | @echo ------------------------------------------------- 6 | PUSHD %~dp0 7 | @echo Removing previous project folder. 8 | IF EXIST "Project" rd "Project" /s /q 9 | @echo: 10 | @echo Done! 11 | @echo: 12 | @echo ------------------------------------------------- 13 | IF NOT EXIST "Project" @echo Creating a new project folder. 14 | IF NOT EXIST "Project" md Project 15 | IF NOT EXIST "Project" @echo: 16 | cd Project 17 | @echo: 18 | @echo Done! 19 | @echo: 20 | @echo ------------------------------------------------- 21 | @echo Running CMAKE script. 22 | @echo: 23 | 24 | cmake -G "Visual Studio 16 2019" ..\ 25 | 26 | @echo: 27 | @echo Done! 28 | @echo: 29 | @echo ------------------------------------------------- 30 | @echo A new solution file is generated in %~dp0Project 31 | @echo: 32 | POPD 33 | PAUSE 34 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/MathHeaders.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | #include "Platform.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "MathUtil.h" 17 | #include "Vector2.h" 18 | #include "Vector3.h" 19 | #include "Vector4.h" 20 | 21 | #include "Matrix2x2.h" 22 | #include "Matrix3x3.h" 23 | #include "Matrix4x4.h" 24 | 25 | #include "ScreenPoint.h" 26 | 27 | #include "Color32.h" 28 | #include "LinearColor.h" 29 | #include "HSVColor.h" 30 | 31 | #include "Rotator.h" 32 | 33 | #include "Quaternion.h" 34 | 35 | #include "Transform.h" 36 | 37 | #include "Plane.h" 38 | 39 | #include "Circle.h" 40 | #include "Rectangle.h" 41 | #include "Sphere.h" 42 | #include "Box.h" 43 | 44 | #include "Frustum.h" 45 | 46 | using namespace CK; 47 | -------------------------------------------------------------------------------- /Source/Player/SystemInputManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | enum class SystemInputButton : UINT32 7 | { 8 | F1 = 0, 9 | F2, 10 | F3, 11 | F4, 12 | F5, 13 | F6, 14 | F7, 15 | F8, 16 | F9, 17 | F10, 18 | LastButton 19 | }; 20 | 21 | class SystemInputManager 22 | { 23 | public: 24 | bool IsPressed(SystemInputButton InSystemInputButton) const; 25 | bool IsPressing(SystemInputButton InSystemInputButton) const; 26 | bool IsReleased(SystemInputButton InSystemInputButton) const; 27 | bool IsInputReady() const; 28 | void SetSystemInputButton(SystemInputButton InSystemInputButton, std::function InPressedFn); 29 | void UpdateSystemInput(); 30 | 31 | private: 32 | std::array, static_cast(SystemInputButton::LastButton)> PressedButtonMap = { 0 }; 33 | std::array(SystemInputButton::LastButton)> PrevButtonStatus = { 0 }; 34 | }; 35 | 36 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Sphere.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | struct Sphere 7 | { 8 | public: 9 | FORCEINLINE constexpr Sphere() = default; 10 | FORCEINLINE constexpr Sphere(const Circle& InCircle) : Center(InCircle.Center), Radius(InCircle.Radius) {}; 11 | Sphere(const std::vector& InVertices); 12 | 13 | FORCEINLINE constexpr bool IsInside(const Vector3& InVector) const; 14 | FORCEINLINE constexpr bool Intersect(const Sphere& InCircle) const; 15 | 16 | public: 17 | Vector3 Center = Vector3::Zero; 18 | float Radius = 0.f; 19 | }; 20 | 21 | FORCEINLINE constexpr bool Sphere::IsInside(const Vector3& InVector) const 22 | { 23 | return ((Center - InVector).SizeSquared() <= (Radius * Radius)); 24 | } 25 | 26 | FORCEINLINE constexpr bool Sphere::Intersect(const Sphere& InCircle) const 27 | { 28 | float radiusSum = Radius + InCircle.Radius; 29 | return (Center - InCircle.Center).SizeSquared() < (radiusSum * radiusSum); 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/Vector4.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | const Vector4 Vector4::UnitX(1.f, 0.f, 0.f, 0.f); 6 | const Vector4 Vector4::UnitY(0.f, 1.f, 0.f, 0.f); 7 | const Vector4 Vector4::UnitZ(0.f, 0.f, 1.f, 0.f); 8 | const Vector4 Vector4::UnitW(0.f, 0.f, 0.f, 1.f); 9 | const Vector4 Vector4::Zero(0.f, 0.f, 0.f, 0.f); 10 | const Vector4 Vector4::One(1.f, 1.f, 1.f, 1.f); 11 | 12 | std::string Vector4::ToString() const 13 | { 14 | char result[64]; 15 | std::snprintf(result, sizeof(result), "(%.3f, %.3f, %.3f, %.3f)", X, Y, Z, W); 16 | return result; 17 | } 18 | 19 | Vector4 Vector4::Normalize() const 20 | { 21 | float squareSum = SizeSquared(); 22 | if (squareSum == 1.f) 23 | { 24 | return *this; 25 | } 26 | else if (squareSum == 0.f) 27 | { 28 | return Vector4::Zero; 29 | } 30 | 31 | float invLength = Math::InvSqrt(squareSum); 32 | return Vector4(X * invLength, Y * invLength, Z * invLength, W * invLength); 33 | } 34 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Circle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | struct Circle 7 | { 8 | public: 9 | FORCEINLINE constexpr Circle() = default; 10 | FORCEINLINE constexpr Circle(const Circle& InCircle) : Center(InCircle.Center), Radius(InCircle.Radius) {}; 11 | Circle(const std::vector InVertices); 12 | 13 | FORCEINLINE constexpr bool IsInside(const Vector2& InVector) const; 14 | FORCEINLINE constexpr bool Intersect(const Circle& InCircle) const; 15 | 16 | public: 17 | Vector2 Center = Vector2::Zero; 18 | float Radius = 0.f; 19 | }; 20 | 21 | FORCEINLINE constexpr bool Circle::IsInside(const Vector2& InVector) const 22 | { 23 | return ((Center - InVector).SizeSquared() <= (Radius * Radius)); 24 | } 25 | 26 | FORCEINLINE constexpr bool Circle::Intersect(const Circle& InCircle) const 27 | { 28 | float twoRadiusSum = Radius + InCircle.Radius; 29 | return (Center - InCircle.Center).SizeSquared() < (twoRadiusSum * twoRadiusSum); 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Private/LinearColor.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | using namespace CK; 4 | 5 | const LinearColor LinearColor::Error(1.f, 0.f, 1.f, 1.f); 6 | const LinearColor LinearColor::White(1.f, 1.f, 1.f, 1.f); 7 | const LinearColor LinearColor::Black(0.f, 0.f, 0.f, 1.f); 8 | const LinearColor LinearColor::Gray(0.5f, 0.5f, 0.5f, 1.f); 9 | const LinearColor LinearColor::Silver(0.4f, 0.4f, 0.4f, 1.f); 10 | const LinearColor LinearColor::WhiteSmoke(0.96f, 0.96f, 0.96f, 1.f); 11 | const LinearColor LinearColor::LightGray(0.83f, 0.83f, 0.83f, 1.f); 12 | const LinearColor LinearColor::DimGray(0.41f, 0.41f, 0.41f, 1.f); 13 | const LinearColor LinearColor::Red(1.f, 0.f, 0.f, 1.f); 14 | const LinearColor LinearColor::Green(0.f, 1.f, 0.f, 1.f); 15 | const LinearColor LinearColor::Blue(0.f, 0.f, 1.f, 1.f); 16 | const LinearColor LinearColor::Yellow(1.f, 1.f, 0.f, 1.f); 17 | const LinearColor LinearColor::Cyan(0.f, 1.f, 1.f, 1.f); 18 | const LinearColor LinearColor::Magenta(1.f, 0.f, 1.f, 1.f); 19 | 20 | 21 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Public/2D/Vertex.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | namespace CK 5 | { 6 | namespace DD 7 | { 8 | 9 | struct Vertex2D 10 | { 11 | public: 12 | constexpr Vertex2D() = default; 13 | constexpr Vertex2D(const Vector2& InPosition) : Position(InPosition) { } 14 | constexpr Vertex2D(const Vector2& InPosition, const LinearColor& InColor) : Position(InPosition), Color(InColor) { } 15 | constexpr Vertex2D(const Vector2& InPosition, const LinearColor& InColor, const Vector2& InUV) : Position(InPosition), Color(InColor), UV(InUV) { } 16 | 17 | constexpr Vertex2D operator*(float InScalar) const 18 | { 19 | return Vertex2D( 20 | Position * InScalar, 21 | Color * InScalar, 22 | UV * InScalar 23 | ); 24 | } 25 | 26 | constexpr Vertex2D operator+(const Vertex2D& InVector) const 27 | { 28 | return Vertex2D( 29 | Position + InVector.Position, 30 | Color + InVector.Color, 31 | UV + InVector.UV 32 | ); 33 | } 34 | 35 | Vector2 Position; 36 | LinearColor Color; 37 | Vector2 UV; 38 | }; 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Public/3D/Vertex.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | namespace CK 5 | { 6 | namespace DDD 7 | { 8 | 9 | struct Vertex3D 10 | { 11 | public: 12 | constexpr Vertex3D() = default; 13 | constexpr Vertex3D(const Vector4& InPosition) : Position(InPosition) { } 14 | constexpr Vertex3D(const Vector4& InPosition, const LinearColor& InColor) : Position(InPosition), Color(InColor) { } 15 | constexpr Vertex3D(const Vector4& InPosition, const LinearColor& InColor, const Vector2& InUV) : Position(InPosition), Color(InColor), UV(InUV) { } 16 | 17 | constexpr Vertex3D operator*(float InScalar) const 18 | { 19 | return Vertex3D( 20 | Position * InScalar, 21 | Color * InScalar, 22 | UV * InScalar 23 | ); 24 | } 25 | 26 | constexpr Vertex3D operator+(const Vertex3D& InVector) const 27 | { 28 | return Vertex3D( 29 | Position + InVector.Position, 30 | Color + InVector.Color, 31 | UV + InVector.UV 32 | ); 33 | } 34 | 35 | Vector4 Position; 36 | LinearColor Color; 37 | Vector2 UV; 38 | }; 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/HSVColor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | struct HSVColor 7 | { 8 | public: 9 | FORCEINLINE constexpr HSVColor() = default; 10 | FORCEINLINE constexpr HSVColor(float InH, float InS, float InV) : H(InH), S(InS), V(InV) {} 11 | FORCEINLINE constexpr LinearColor ToLinearColor() const 12 | { 13 | float r = 0.f, g = 0.f, b = 0.f; 14 | 15 | int i = Math::FloorToInt(H * 6.f); 16 | float f = H * 6.f - i; 17 | float p = V * (1.f - S); 18 | float q = V * (1 - f * S); 19 | float t = V * (1 - (1 - f) * S); 20 | 21 | switch (i % 6) { 22 | case 0: r = V, g = t, b = p; break; 23 | case 1: r = q, g = V, b = p; break; 24 | case 2: r = p, g = V, b = t; break; 25 | case 3: r = p, g = q, b = V; break; 26 | case 4: r = t, g = p, b = V; break; 27 | case 5: r = V, g = p, b = q; break; 28 | } 29 | 30 | return LinearColor(r, g, b); 31 | } 32 | 33 | public: 34 | float H = 0.f; 35 | float S = 1.f; 36 | float V = 1.f; 37 | }; 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Public/InputManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | enum class InputAxis : UINT32 7 | { 8 | XAxis = 0, 9 | YAxis, 10 | ZAxis, 11 | WAxis, 12 | LastAxis 13 | }; 14 | 15 | enum class InputButton : UINT32 16 | { 17 | Space = 0, 18 | Z, 19 | X, 20 | LastButton 21 | }; 22 | 23 | class InputManager 24 | { 25 | public: 26 | float GetAxis(InputAxis InInputAxis) const; 27 | bool IsPressed(InputButton InInputButton) const; 28 | bool IsPressing(InputButton InInputButton) const; 29 | bool IsReleased(InputButton InInputButton) const; 30 | bool IsInputReady() const; 31 | void SetInputAxis(InputAxis InInputAxis, std::function InAxisFn); 32 | void SetInputButton(InputButton InInputButton, std::function InPressedFn); 33 | void UpdateInput(); 34 | 35 | private: 36 | std::array, static_cast(InputAxis::LastAxis)> AxisMap = { 0 }; 37 | std::array, static_cast(InputButton::LastButton)> PressedButtonMap = { 0 }; 38 | std::array(InputButton::LastButton)> PrevButtonStatus = { 0 }; 39 | }; 40 | 41 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Dustin Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Source/Player/Private/Windows/Res/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++에서 생성한 포함 파일입니다. 3 | // player.rc에서 사용되고 있습니다. 4 | // 5 | #define IDC_MYICON 2 6 | #define IDD_SOFTRENDERER_DIALOG 102 7 | #define IDS_APP_TITLE 103 8 | #define IDD_ABOUTBOX 103 9 | #define IDM_ABOUT 104 10 | #define IDS_AUTHOR 104 11 | #define IDS_DEVELOPER 104 12 | #define IDM_EXIT 105 13 | #define IDI_SOFTRENDERER 107 14 | #define IDI_SMALL 108 15 | #define IDC_SOFTRENDERER 109 16 | #define IDR_MAINFRAME 128 17 | #define IDM_2D 200 18 | #define IDM_3DPERSP 201 19 | #define IDM_3DORTHO 202 20 | #define IDC_STATIC -1 21 | 22 | // Next default values for new objects 23 | // 24 | #ifdef APSTUDIO_INVOKED 25 | #ifndef APSTUDIO_READONLY_SYMBOLS 26 | #define _APS_NO_MFC 1 27 | #define _APS_NEXT_RESOURCE_VALUE 129 28 | #define _APS_NEXT_COMMAND_VALUE 32774 29 | #define _APS_NEXT_CONTROL_VALUE 1000 30 | #define _APS_NEXT_SYMED_VALUE 110 31 | #endif 32 | #endif 33 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Public/RendererInterface.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | namespace CK 5 | { 6 | 7 | class RendererInterface 8 | { 9 | public: 10 | virtual bool Init(const ScreenPoint& InSize) = 0; 11 | virtual void Shutdown() = 0; 12 | virtual bool IsInitialized() const = 0; 13 | 14 | virtual void Clear(const LinearColor& InClearColor) = 0; 15 | virtual void BeginFrame() = 0; 16 | virtual void EndFrame() = 0; 17 | 18 | virtual void DrawPoint(const Vector2& InVectorPos, const LinearColor& InColor) = 0; 19 | virtual void DrawPoint(const ScreenPoint& InScreenPos, const LinearColor& InColor) = 0; 20 | virtual void DrawLine(const Vector2& InStartPos, const Vector2& InEndPos, const LinearColor& InColor) = 0; 21 | virtual void DrawLine(const Vector4& InStartPos, const Vector4& InEndPos, const LinearColor& InColor) = 0; 22 | 23 | virtual float GetDepthBufferValue(const ScreenPoint& InScreenPos) const = 0; 24 | virtual void SetDepthBufferValue(const ScreenPoint& InScreenPos, float InDepthValue) = 0; 25 | 26 | virtual void DrawFullVerticalLine(int InX, const LinearColor& InColor) = 0; 27 | virtual void DrawFullHorizontalLine(int InY, const LinearColor& InColor) = 0; 28 | 29 | virtual void PushStatisticText(std::string && InText) = 0; 30 | virtual void PushStatisticTexts(std::vector && InTexts) = 0; 31 | }; 32 | 33 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Rotator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | struct Rotator 7 | { 8 | public: 9 | FORCEINLINE constexpr Rotator() = default; 10 | FORCEINLINE constexpr Rotator(float InYaw, float InRoll, float InPitch) : Yaw(InYaw), Roll(InRoll), Pitch(InPitch) { } 11 | FORCEINLINE void Clamp() 12 | { 13 | Yaw = GetAxisClampedValue(Yaw); 14 | Roll = GetAxisClampedValue(Roll); 15 | Pitch = GetAxisClampedValue(Pitch); 16 | } 17 | 18 | FORCEINLINE float GetAxisClampedValue(float InRotatorValue) 19 | { 20 | float angle = Math::FMod(InRotatorValue, 360.f); 21 | if (angle < 0.f) 22 | { 23 | angle += 360.f; 24 | } 25 | 26 | return angle; 27 | } 28 | 29 | FORCEINLINE void GetLocalAxes(Vector3& OutRight, Vector3& OutUp, Vector3& OutForward) 30 | { 31 | float cy = 0.f, sy = 0.f, cp = 0.f, sp = 0.f, cr = 0.f, sr = 0.f; 32 | Math::GetSinCos(sy, cy, Yaw); 33 | Math::GetSinCos(sp, cp, Pitch); 34 | Math::GetSinCos(sr, cr, Roll); 35 | 36 | OutRight = Vector3(cy * cr + sy * sp * sr, cp * sr, -sy * cr + cy * sp * sr); 37 | OutUp = Vector3(-cy * sr + sy * sp * cr, cp * cr, sy * sr + cy * sp * cr); 38 | OutForward = Vector3(sy * cp, -sp, cy * cp); 39 | } 40 | 41 | std::string ToString() const; 42 | static const Rotator Identity; 43 | 44 | public: 45 | float Yaw = 0.f; 46 | float Roll = 0.f; 47 | float Pitch = 0.f; 48 | }; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/Texture.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | #include "lodepng.h" 4 | 5 | Texture::Texture(std::string InFileName) 6 | { 7 | LoadPNG(InFileName); 8 | } 9 | 10 | void Texture::LoadPNG(std::string InFileName) 11 | { 12 | std::vector image; 13 | unsigned w, h; 14 | unsigned int error = lodepng::decode(image, w, h, InFileName); 15 | if (error != NULL) 16 | { 17 | Release(); 18 | return; 19 | } 20 | 21 | _Width = static_cast(w); 22 | _Height = static_cast(h); 23 | 24 | size_t bufferLength = image.size() / 4; 25 | _Buffer.reserve(bufferLength); 26 | for (UINT32 j = 0; j < _Height; j++) 27 | { 28 | for (UINT32 i = 0; i < _Width; i++) 29 | { 30 | auto ix = (j * _Width + i) * 4; 31 | Color32 c(image[ix], image[ix + 1], image[ix + 2], image[ix + 3]); 32 | _Buffer.push_back(LinearColor(c)); 33 | } 34 | } 35 | } 36 | 37 | void Texture::Release() 38 | { 39 | _Width = 0; 40 | _Height = 0; 41 | _Buffer.clear(); 42 | } 43 | 44 | LinearColor Texture::GetSample(Vector2 InUV) const 45 | { 46 | if (!IsIntialized()) 47 | { 48 | return LinearColor::Error; 49 | } 50 | 51 | int x = Math::FloorToInt(InUV.X * _Width) % _Width; 52 | int y = Math::FloorToInt(InUV.Y * _Height) % _Height; 53 | size_t index = static_cast(_Width * (_Height - (1 + y)) + x); 54 | if (index >= _Buffer.size()) 55 | { 56 | return LinearColor::Error; 57 | } 58 | 59 | return _Buffer[index]; 60 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SoftRenderer 2 | 3 | 교육적 목적으로 고안된 프로젝트입니다. 4 | 브랜치를 사용해 단계별로 코드가 구현되어 있으니 수업에 참고하시기 바랍니다. 5 | 6 | ## 요구사항 7 | - 비주얼 스튜디오 2019 커뮤니티 버젼 이상 8 | - CMake 3.1버젼 이상 ( https://cmake.org/download/ ) 9 | 본 프로젝트는 멀티플랫폼으로 설계되어 있으나, 현재는 윈도우만 지원합니다. 10 | 11 | ## 컴파일 방법 12 | - 소스를 다운 받은 후에 CMake-VS-16-2019.bat 배치 파일을 실행합니다. 13 | - 배치 파일을 실행하면 소스를 푼 폴더에 Project폴더와 솔루션 파일이 생성됩니다. 14 | - 솔루션을 더블클릭해 비주얼 스튜디오를 열고 컴파일하고 실행합니다. 15 | 16 | ## 사용하는 키 17 | | 키 | 기능 | 18 | | ------------- |:-------------:| 19 | | F1 | 일반 모드 | 20 | | F2 | 와이어 프레임 모드 | 21 | | F3 | 깊이 버퍼 모드 ( 3D 전용 ) | 22 | | F10 | 2D 엔진과 3D 엔진의 변경 | 23 | | 왼쪽,오른쪽 화살표 키 | 캐릭터 좌우 회전 | 24 | | 위,아래 화살표 키 | 캐릭터 전후 이동 | 25 | | 페이지 업,다운 | 카메라 FOV 조절 | 26 | 27 | ## 일반 모드 28 | 텍스쳐를 매핑해 렌더링합니다. 29 | 기즈모는 표시되나 본은 표시되지 않습니다. 30 | 31 | ![일반 모드](https://github.com/ideugu/CKSoftRenderer/blob/main/Document/Normal.png "일반 모드") 32 | 33 | 34 | ## 와이어 프레임 모드 35 | 선을 사용해 외곽선만 렌더링합니다. 36 | 기즈모와 본을 모두 표시해줍니다. 37 | 38 | ![와이어프레임 모드](https://github.com/ideugu/CKSoftRenderer/blob/main/Document/Wireframe1.png "와이어프레임 모드") 39 | 40 | 가까이서 확대하는 경우 동차좌표계에서 삼각형이 분할되는 과정을 확인할 수 있습니다. 41 | 42 | ![와이어프레임 모드 2](https://github.com/ideugu/CKSoftRenderer/blob/main/Document/Wireframe2.png "와이어프레임 모드 2") 43 | 44 | ## 뎁스 버퍼 모드 45 | 투영 변환 후 뎁스 값을 시각화하여 보여줍니다. 46 | 뎁스 테스팅은 비선형 값으로 진행하지만, 이를 선형화시켜 보여줍니다. 47 | 48 | ![뎁스 버퍼 모드](https://github.com/ideugu/CKSoftRenderer/blob/main/Document/Depth.png "뎁스버퍼 모드") 49 | 50 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Color32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | struct Color32 7 | { 8 | public: 9 | FORCEINLINE constexpr Color32() : R(0), G(0), B(0), A(0) { } 10 | FORCEINLINE explicit constexpr Color32(BYTE InR, BYTE InG, BYTE InB, BYTE InA = 255) : B(InB), G(InG), R(InR), A(InA) { } 11 | FORCEINLINE explicit constexpr Color32(UINT32 InColor) : ColorValue(InColor) { } 12 | 13 | FORCEINLINE constexpr const UINT32& GetColorRef() const { return ColorValue; } 14 | FORCEINLINE constexpr UINT32& GetColorRef() { return ColorValue; } 15 | 16 | FORCEINLINE constexpr bool operator==(const Color32& InC) const; 17 | FORCEINLINE constexpr bool operator!=(const Color32& InC) const; 18 | FORCEINLINE constexpr void operator+=(const Color32& InC); 19 | 20 | static const Color32 Error; 21 | 22 | public: 23 | union 24 | { 25 | struct 26 | { 27 | BYTE B, G, R, A; 28 | }; 29 | 30 | UINT32 ColorValue; 31 | }; 32 | }; 33 | 34 | FORCEINLINE constexpr bool Color32::operator==(const Color32& InC) const 35 | { 36 | return GetColorRef() == InC.GetColorRef(); 37 | } 38 | 39 | FORCEINLINE constexpr bool Color32::operator!=(const Color32& InC) const 40 | { 41 | return GetColorRef() != InC.GetColorRef(); 42 | } 43 | 44 | FORCEINLINE constexpr void Color32::operator+=(const Color32& InC) 45 | { 46 | R = (BYTE)Math::Clamp((BYTE)R + (BYTE)InC.R, 0, 255); 47 | G = (BYTE)Math::Clamp((BYTE)G + (BYTE)InC.G, 0, 255); 48 | B = (BYTE)Math::Clamp((BYTE)B + (BYTE)InC.B, 0, 255); 49 | A = (BYTE)Math::Clamp((BYTE)A + (BYTE)InC.A, 0, 255); 50 | } 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Source/Player/Private/Windows/WindowsApp.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | #include "SoftRenderer.h" 4 | #include "WindowsUtil.h" 5 | #include "WindowsPlayer.h" 6 | 7 | int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) 8 | { 9 | ScreenPoint defScreenSize(800, 600); 10 | SoftRenderer instance(GameEngineType::DDD, new WindowsRSI()); 11 | WindowsPlayer::gOnResizeFunc = [&instance](const ScreenPoint& InNewScreenSize) { 12 | if (InNewScreenSize.HasZero()) { 13 | return; 14 | } 15 | instance.OnResize(InNewScreenSize); 16 | }; 17 | instance._PerformanceInitFunc = WindowsUtil::GetCyclesPerMilliSeconds; 18 | instance._PerformanceMeasureFunc = WindowsUtil::GetCurrentTimeStamp; 19 | instance._InputBindingFunc = WindowsUtil::BindInput; 20 | WindowsUtil::BindSystemInput(instance.GetSystemInput()); 21 | 22 | if (!WindowsPlayer::Create(hInstance, defScreenSize)) 23 | { 24 | return -1; 25 | } 26 | 27 | WindowsUtil::Show(WindowsPlayer::gHandle); 28 | WindowsUtil::CenterWindow(WindowsPlayer::gHandle); 29 | 30 | static float previousTimer = 0.f; 31 | static float updatePeriod = 500.f; 32 | while (WindowsPlayer::Tick()) 33 | { 34 | instance.OnTick(); 35 | 36 | float currentTime = instance.GetElapsedTime(); 37 | if (currentTime - previousTimer > updatePeriod) 38 | { 39 | float frameFPS = instance.GetFrameFPS(); 40 | WindowsPlayer::SetWindowsStatTitle(frameFPS); 41 | previousTimer = currentTime; 42 | } 43 | } 44 | 45 | instance.OnShutdown(); 46 | WindowsPlayer::Destroy(); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Source/Player/Private/SystemInputManager.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | 4 | bool SystemInputManager::IsPressed(SystemInputButton InSystemInputButton) const 5 | { 6 | assert(InSystemInputButton < SystemInputButton::LastButton); 7 | size_t targetIndex = static_cast(InSystemInputButton); 8 | return (!PrevButtonStatus[targetIndex] && PressedButtonMap[targetIndex]()); 9 | } 10 | 11 | bool SystemInputManager::IsPressing(SystemInputButton InSystemInputButton) const 12 | { 13 | assert(InSystemInputButton < SystemInputButton::LastButton); 14 | size_t targetIndex = static_cast(InSystemInputButton); 15 | return (PrevButtonStatus[targetIndex] && PressedButtonMap[targetIndex]()); 16 | } 17 | 18 | bool SystemInputManager::IsReleased(SystemInputButton InSystemInputButton) const 19 | { 20 | assert(InSystemInputButton < SystemInputButton::LastButton); 21 | size_t targetIndex = static_cast(InSystemInputButton); 22 | return (PrevButtonStatus[targetIndex] && !PressedButtonMap[targetIndex]()); 23 | } 24 | 25 | void SystemInputManager::SetSystemInputButton(SystemInputButton SystemInputButton, std::function InPressedFn) 26 | { 27 | assert(SystemInputButton < SystemInputButton::LastButton); 28 | PressedButtonMap[static_cast(SystemInputButton)] = InPressedFn; 29 | } 30 | 31 | void SystemInputManager::UpdateSystemInput() 32 | { 33 | size_t lastIndex = static_cast(SystemInputButton::LastButton); 34 | for (size_t bi = 0; bi < lastIndex; ++bi) 35 | { 36 | PrevButtonStatus[bi] = PressedButtonMap[bi](); 37 | } 38 | } 39 | 40 | bool SystemInputManager::IsInputReady() const 41 | { 42 | if (!PressedButtonMap[0]) 43 | { 44 | return false; 45 | } 46 | 47 | return true; 48 | } -------------------------------------------------------------------------------- /Source/Runtime/Engine/Private/InputManager.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | 4 | float InputManager::GetAxis(InputAxis InInputAxis) const 5 | { 6 | assert(InInputAxis < InputAxis::LastAxis); 7 | return AxisMap[static_cast(InInputAxis)](); 8 | } 9 | 10 | bool InputManager::IsPressed(InputButton InInputButton) const 11 | { 12 | assert(InInputButton < InputButton::LastButton); 13 | size_t targetIndex = static_cast(InInputButton); 14 | return (!PrevButtonStatus[targetIndex] && PressedButtonMap[targetIndex]()); 15 | } 16 | 17 | bool InputManager::IsPressing(InputButton InInputButton) const 18 | { 19 | assert(InInputButton < InputButton::LastButton); 20 | size_t targetIndex = static_cast(InInputButton); 21 | return (PrevButtonStatus[targetIndex] && PressedButtonMap[targetIndex]()); 22 | } 23 | 24 | bool InputManager::IsReleased(InputButton InInputButton) const 25 | { 26 | assert(InInputButton < InputButton::LastButton); 27 | size_t targetIndex = static_cast(InInputButton); 28 | return (PrevButtonStatus[targetIndex] && !PressedButtonMap[targetIndex]()); 29 | } 30 | 31 | bool InputManager::IsInputReady() const 32 | { 33 | if (!AxisMap[0]) 34 | { 35 | return false; 36 | } 37 | 38 | if (!PressedButtonMap[0]) 39 | { 40 | return false; 41 | } 42 | 43 | return true; 44 | } 45 | 46 | void InputManager::SetInputAxis(InputAxis InInputAxis, std::function InAxisFn) 47 | { 48 | assert(InInputAxis < InputAxis::LastAxis); 49 | AxisMap[static_cast(InInputAxis)] = InAxisFn; 50 | } 51 | 52 | void InputManager::SetInputButton(InputButton InInputButton, std::function InPressedFn) 53 | { 54 | assert(InInputButton < InputButton::LastButton); 55 | PressedButtonMap[static_cast(InInputButton)] = InPressedFn; 56 | } 57 | 58 | void InputManager::UpdateInput() 59 | { 60 | size_t lastIndex = static_cast(InputButton::LastButton); 61 | for (size_t bi = 0; bi < lastIndex; ++bi) 62 | { 63 | PrevButtonStatus[bi] = PressedButtonMap[bi](); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Public/Windows/WindowsRSI.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | namespace CK 5 | { 6 | 7 | class WindowsRSI : public WindowsGDI, public RendererInterface 8 | { 9 | public: 10 | WindowsRSI() = default; 11 | ~WindowsRSI(); 12 | 13 | public: 14 | virtual bool Init(const ScreenPoint& InScreenSize) override; 15 | virtual void Shutdown() override; 16 | virtual bool IsInitialized() const { return _GDIInitialized; } 17 | 18 | virtual void Clear(const LinearColor& InClearColor) override; 19 | virtual void BeginFrame() override; 20 | virtual void EndFrame() override; 21 | 22 | virtual void DrawPoint(const Vector2& InVectorPos, const LinearColor& InColor) override; 23 | virtual void DrawPoint(const ScreenPoint& InScreenPos, const LinearColor& InColor) override; 24 | virtual void DrawLine(const Vector2& InStartPos, const Vector2& InEndPos, const LinearColor& InColor) override; 25 | virtual void DrawLine(const Vector4& InStartPos, const Vector4& InEndPos, const LinearColor& InColor) override; 26 | 27 | virtual float GetDepthBufferValue(const ScreenPoint& InPos) const override; 28 | virtual void SetDepthBufferValue(const ScreenPoint& InPos, float InDepthValue) override; 29 | 30 | virtual void DrawFullVerticalLine(int InX, const LinearColor& InColor) override; 31 | virtual void DrawFullHorizontalLine(int InY, const LinearColor& InColor) override; 32 | 33 | virtual void PushStatisticText(std::string && InText) override; 34 | virtual void PushStatisticTexts(std::vector && InTexts) override; 35 | 36 | private: 37 | int TestRegion(const Vector2& InVectorPos, const Vector2& InMinPos, const Vector2& InMaxPos); 38 | bool CohenSutherlandLineClip(Vector2& InOutStartPos, Vector2& InOutEndPos, const Vector2& InMinPos, const Vector2& InMaxPos); 39 | 40 | FORCEINLINE void SetPixel(const ScreenPoint& InPos, const LinearColor& InColor); 41 | }; 42 | 43 | FORCEINLINE void WindowsRSI::SetPixel(const ScreenPoint& InPos, const LinearColor& InColor) 44 | { 45 | SetPixelOpaque(InPos, InColor); 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ########################################################## 2 | ## CMake Setting for SoftRenderer 3 | ########################################################## 4 | 5 | cmake_minimum_required(VERSION 3.1) 6 | 7 | set(CMAKE_CXX_STANDARD 17) 8 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 9 | 10 | include(CMakeDependentOption) 11 | set(MAIN_PROJECT_NAME SoftRenderer) 12 | 13 | project(${MAIN_PROJECT_NAME}) 14 | 15 | set(RUNTIME_MODULE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Source/Runtime) 16 | 17 | if(NOT WIN32) 18 | message(FATAL_ERROR "This project only supports windows environment currently.") 19 | endif() 20 | 21 | if(NOT MSVC) 22 | message(FATAL_ERROR "This project only supports MSVC project currently.") 23 | endif() 24 | 25 | set(PLATFORM_DEFINITION PLATFORM_GENERIC) 26 | set(PLATFORM_FOLDER Generic) 27 | 28 | option(TARGET_WINDOWS "Windows Option" ON) 29 | 30 | if(TARGET_WINDOWS) 31 | set(PLATFORM_DEFINITION PLATFORM_WINDOWS) 32 | set(PLATFORM_FOLDER Windows) 33 | endif() 34 | 35 | ################################################################################ 36 | # Sub projects 37 | ################################################################################ 38 | 39 | add_subdirectory(Source/Runtime/Math) 40 | add_subdirectory(Source/Runtime/Renderer) 41 | add_subdirectory(Source/Runtime/Engine) 42 | add_subdirectory(Source/Player) 43 | 44 | ################################################################################ 45 | # Definitions 46 | ################################################################################ 47 | target_compile_definitions(SoftRendererPlayer PUBLIC ${PLATFORM_DEFINITION} ${PLATFORM_FOLDER}) 48 | target_compile_definitions(EngineModule PUBLIC ${PLATFORM_DEFINITION} ${PLATFORM_FOLDER}) 49 | target_compile_definitions(RendererModule PUBLIC ${PLATFORM_DEFINITION} ${PLATFORM_FOLDER}) 50 | target_compile_definitions(MathModule PUBLIC ${PLATFORM_DEFINITION} ${PLATFORM_FOLDER}) 51 | 52 | ################################################################################ 53 | # Solution Setting 54 | ################################################################################ 55 | set(CMAKE_SUPPRESS_REGENERATION true) 56 | set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT SoftRendererPlayer) 57 | 58 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Public/Windows/WindowsGDI.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | namespace CK 5 | { 6 | 7 | class WindowsGDI 8 | { 9 | public: 10 | WindowsGDI() = default; 11 | ~WindowsGDI(); 12 | 13 | public: 14 | bool InitializeGDI(const ScreenPoint& InScreenSize); 15 | void ReleaseGDI(); 16 | 17 | void FillBuffer(Color32 InColor); 18 | 19 | FORCEINLINE LinearColor GetPixel(const ScreenPoint& InPos); 20 | FORCEINLINE void SetPixelOpaque(const ScreenPoint& InPos, const LinearColor& InColor); 21 | FORCEINLINE void SetPixelAlphaBlending(const ScreenPoint& InPos, const LinearColor& InColor); 22 | 23 | void CreateDepthBuffer(); 24 | void ClearDepthBuffer(); 25 | 26 | Color32* GetScreenBuffer() const; 27 | 28 | void DrawStatisticTexts(); 29 | 30 | void SwapBuffer(); 31 | 32 | protected: 33 | FORCEINLINE bool IsInScreen(const ScreenPoint& InPos) const; 34 | int GetScreenBufferIndex(const ScreenPoint& InPos) const; 35 | 36 | template 37 | T* CopyBuffer(T* InDst, T* InSrc, int InCount); 38 | 39 | protected: 40 | bool _GDIInitialized = false; 41 | 42 | HWND _Handle = 0; 43 | HDC _ScreenDC = 0, _MemoryDC = 0; 44 | HBITMAP _DefaultBitmap = 0, DIBitmap = 0; 45 | 46 | Color32* _ScreenBuffer = nullptr; 47 | float* _DepthBuffer = nullptr; 48 | 49 | ScreenPoint _ScreenSize; 50 | std::vector _StatisticTexts; 51 | }; 52 | 53 | FORCEINLINE void WindowsGDI::SetPixelOpaque(const ScreenPoint& InPos, const LinearColor& InColor) 54 | { 55 | if (!IsInScreen(InPos)) 56 | { 57 | return; 58 | } 59 | 60 | Color32* dest = _ScreenBuffer; 61 | *(dest + GetScreenBufferIndex(InPos)) = InColor.ToColor32(); 62 | return; 63 | } 64 | 65 | FORCEINLINE void WindowsGDI::SetPixelAlphaBlending(const ScreenPoint & InPos, const LinearColor & InColor) 66 | { 67 | LinearColor bufferColor = GetPixel(InPos); 68 | if (!IsInScreen(InPos)) 69 | { 70 | return; 71 | } 72 | 73 | Color32* dest = _ScreenBuffer; 74 | *(dest + GetScreenBufferIndex(InPos)) = (InColor * InColor.A + bufferColor * (1.f - InColor.A)).ToColor32(); 75 | } 76 | 77 | FORCEINLINE bool WindowsGDI::IsInScreen(const ScreenPoint& InPos) const 78 | { 79 | if ((InPos.X < 0 || InPos.X >= _ScreenSize.X) || (InPos.Y < 0 || InPos.Y >= _ScreenSize.Y)) 80 | { 81 | return false; 82 | } 83 | 84 | return true; 85 | } 86 | 87 | FORCEINLINE int WindowsGDI::GetScreenBufferIndex(const ScreenPoint& InPos) const 88 | { 89 | return InPos.Y * _ScreenSize.X + InPos.X; 90 | } 91 | 92 | FORCEINLINE LinearColor WindowsGDI::GetPixel(const ScreenPoint& InPos) 93 | { 94 | if (!IsInScreen(InPos)) 95 | { 96 | return LinearColor::Error; 97 | } 98 | 99 | Color32* dest = _ScreenBuffer; 100 | Color32 bufferColor = *(dest + GetScreenBufferIndex(InPos)); 101 | return LinearColor(bufferColor); 102 | } 103 | 104 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Rectangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | struct Rectangle 7 | { 8 | public: 9 | FORCEINLINE constexpr Rectangle() = default; 10 | FORCEINLINE constexpr Rectangle(const Rectangle& InRectangle) : Min(InRectangle.Min), Max(InRectangle.Max) { } 11 | FORCEINLINE constexpr Rectangle(const Vector2& InMinVector, const Vector2& InMaxVector) : Min(InMinVector), Max(InMaxVector) { } 12 | Rectangle(const std::vector InVertices); 13 | 14 | FORCEINLINE constexpr bool Intersect(const Rectangle& InRectangle) const; 15 | FORCEINLINE constexpr bool IsInside(const Rectangle& InRectangle) const; 16 | FORCEINLINE constexpr bool IsInside(const Vector2& InVector) const; 17 | 18 | FORCEINLINE constexpr Rectangle operator+=(const Vector2& InVector); 19 | FORCEINLINE constexpr Rectangle operator+=(const Rectangle& InRectangle); 20 | 21 | FORCEINLINE constexpr Vector2 GetSize() const; 22 | FORCEINLINE constexpr Vector2 GetExtent() const; 23 | FORCEINLINE constexpr void GetCenterAndExtent(Vector2& OutCenter, Vector2& OutExtent) const; 24 | 25 | public: 26 | Vector2 Min; 27 | Vector2 Max; 28 | }; 29 | 30 | FORCEINLINE constexpr bool Rectangle::Intersect(const Rectangle& InRectangle) const 31 | { 32 | if ((Min.X > InRectangle.Max.X) || (InRectangle.Min.X > Max.X)) 33 | { 34 | return false; 35 | } 36 | 37 | if ((Min.Y > InRectangle.Max.Y) || (InRectangle.Min.Y > Max.Y)) 38 | { 39 | return false; 40 | } 41 | 42 | return true; 43 | } 44 | 45 | FORCEINLINE constexpr bool Rectangle::IsInside(const Rectangle& InRectangle) const 46 | { 47 | return (IsInside(InRectangle.Min) && IsInside(InRectangle.Max)); 48 | } 49 | 50 | FORCEINLINE constexpr bool Rectangle::IsInside(const Vector2& InVector) const 51 | { 52 | return ((InVector.X >= Min.X) && (InVector.X <= Max.X) && (InVector.Y >= Min.Y) && (InVector.Y <= Max.Y)); 53 | } 54 | 55 | FORCEINLINE constexpr Rectangle Rectangle::operator+=(const Vector2& InVector) 56 | { 57 | Min.X = Math::Min(Min.X, InVector.X); 58 | Min.Y = Math::Min(Min.Y, InVector.Y); 59 | 60 | Max.X = Math::Max(Max.X, InVector.X); 61 | Max.Y = Math::Max(Max.Y, InVector.Y); 62 | return *this; 63 | } 64 | 65 | FORCEINLINE constexpr Rectangle Rectangle::operator+=(const Rectangle& InRectangle) 66 | { 67 | Min.X = Math::Min(Min.X, InRectangle.Min.X); 68 | Min.Y = Math::Min(Min.Y, InRectangle.Min.Y); 69 | 70 | Max.X = Math::Max(Max.X, InRectangle.Max.X); 71 | Max.Y = Math::Max(Max.Y, InRectangle.Max.Y); 72 | return *this; 73 | } 74 | 75 | FORCEINLINE constexpr Vector2 Rectangle::GetSize() const 76 | { 77 | return (Max - Min); 78 | } 79 | 80 | FORCEINLINE constexpr Vector2 Rectangle::GetExtent() const 81 | { 82 | return GetSize() * 0.5f; 83 | } 84 | 85 | FORCEINLINE constexpr void Rectangle::GetCenterAndExtent(Vector2 & OutCenter, Vector2 & OutExtent) const 86 | { 87 | OutExtent = GetExtent(); 88 | OutCenter = Min + OutExtent; 89 | } 90 | 91 | } -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/Box.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | struct Box 7 | { 8 | public: 9 | FORCEINLINE constexpr Box() = default; 10 | FORCEINLINE constexpr Box(const Box& InBox) : Min(InBox.Min), Max(InBox.Max) { } 11 | FORCEINLINE constexpr Box(const Vector3& InMinVector, const Vector3& InMaxVector) : Min(InMinVector), Max(InMaxVector) { } 12 | Box(const std::vector InVertices); 13 | 14 | FORCEINLINE constexpr bool Intersect(const Box& InBox) const; 15 | FORCEINLINE constexpr bool IsInside(const Box& InBox) const; 16 | FORCEINLINE constexpr bool IsInside(const Vector3& InVector) const; 17 | 18 | FORCEINLINE constexpr Box operator+=(const Vector3& InVector); 19 | FORCEINLINE constexpr Box operator+=(const Box& InBox); 20 | 21 | FORCEINLINE constexpr Vector3 GetSize() const; 22 | FORCEINLINE constexpr Vector3 GetExtent() const; 23 | FORCEINLINE constexpr void GetCenterAndExtent(Vector3& OutCenter, Vector3& OutExtent) const; 24 | 25 | public: 26 | Vector3 Min; 27 | Vector3 Max; 28 | }; 29 | 30 | FORCEINLINE constexpr bool Box::Intersect(const Box& InBox) const 31 | { 32 | if ((Min.X > InBox.Max.X) || (InBox.Min.X > Max.X)) 33 | { 34 | return false; 35 | } 36 | 37 | if ((Min.Y > InBox.Max.Y) || (InBox.Min.Y > Max.Y)) 38 | { 39 | return false; 40 | } 41 | 42 | if ((Min.Z > InBox.Max.Z) || (InBox.Min.Z > Max.Z)) 43 | { 44 | return false; 45 | } 46 | 47 | return true; 48 | } 49 | 50 | FORCEINLINE constexpr bool Box::IsInside(const Box& InBox) const 51 | { 52 | return (IsInside(InBox.Min) && IsInside(InBox.Max)); 53 | } 54 | 55 | FORCEINLINE constexpr bool Box::IsInside(const Vector3& InVector) const 56 | { 57 | return ((InVector.X >= Min.X) && (InVector.X <= Max.X) && (InVector.Y >= Min.Y) && (InVector.Y <= Max.Y) && (InVector.Z >= Min.Z) && (InVector.Z <= Max.Z)); 58 | } 59 | 60 | FORCEINLINE constexpr Box Box::operator+=(const Vector3& InVector) 61 | { 62 | Min.X = Math::Min(Min.X, InVector.X); 63 | Min.Y = Math::Min(Min.Y, InVector.Y); 64 | Min.Z = Math::Min(Min.Z, InVector.Z); 65 | 66 | Max.X = Math::Max(Max.X, InVector.X); 67 | Max.Y = Math::Max(Max.Y, InVector.Y); 68 | Max.Z = Math::Max(Max.Z, InVector.Z); 69 | 70 | return *this; 71 | } 72 | 73 | FORCEINLINE constexpr Box Box::operator+=(const Box& InBox) 74 | { 75 | Min.X = Math::Min(Min.X, InBox.Min.X); 76 | Min.Y = Math::Min(Min.Y, InBox.Min.Y); 77 | Min.Z = Math::Min(Min.Z, InBox.Min.Z); 78 | 79 | Max.X = Math::Max(Max.X, InBox.Max.X); 80 | Max.Y = Math::Max(Max.Y, InBox.Max.Y); 81 | Max.Z = Math::Max(Max.Z, InBox.Max.Z); 82 | return *this; 83 | } 84 | 85 | FORCEINLINE constexpr Vector3 Box::GetSize() const 86 | { 87 | return (Max - Min); 88 | } 89 | 90 | FORCEINLINE constexpr Vector3 Box::GetExtent() const 91 | { 92 | return GetSize() * 0.5f; 93 | } 94 | 95 | FORCEINLINE constexpr void Box::GetCenterAndExtent(Vector3 & OutCenter, Vector3 & OutExtent) const 96 | { 97 | OutExtent = GetExtent(); 98 | OutCenter = Min + OutExtent; 99 | } 100 | 101 | } 102 | 103 | 104 | -------------------------------------------------------------------------------- /Source/Runtime/Math/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(MathModule) 4 | 5 | ################################################################################ 6 | # Source files 7 | ################################################################################ 8 | file(GLOB COMMON_FILES 9 | ${PROJECT_SOURCE_DIR}/*.cpp 10 | ${PROJECT_SOURCE_DIR}/*.h) 11 | 12 | file(GLOB_RECURSE MODULE_FILES 13 | ${PROJECT_SOURCE_DIR}/Private/*.cpp 14 | ${PROJECT_SOURCE_DIR}/Public/*.h 15 | ) 16 | 17 | file(GLOB_RECURSE THIRDPARTY_FILES 18 | ${PROJECT_SOURCE_DIR}/ThirdParty/*.h 19 | ${PROJECT_SOURCE_DIR}/ThirdParty/*.cpp 20 | ) 21 | 22 | set(ALL_FILES 23 | ${COMMON_FILES} 24 | ${MODULE_FILES} 25 | ${THIRDPARTY_FILES} 26 | ) 27 | 28 | if(TARGET_WINDOWS) 29 | 30 | file(GLOB_RECURSE WINDOWS_FILES 31 | ${PROJECT_SOURCE_DIR}/Public/${PLATFORM_FOLDER}/*.h 32 | ) 33 | 34 | set(ALL_FILES 35 | ${ALL_FILES} 36 | ${WINDOWS_FILES} 37 | ) 38 | 39 | endif() 40 | 41 | foreach(FILE ${ALL_FILES}) 42 | # make rel path 43 | file(RELATIVE_PATH REL_PATH "${PROJECT_SOURCE_DIR}" "${FILE}") 44 | set(ALL_FILES_REL ${ALL_FILES_REL} ${REL_PATH}) 45 | endforeach() 46 | 47 | set_source_files_properties(${ALL_FILES_REL} PROPERTIES HEADER_FILE_ONLY FALSE) 48 | 49 | foreach(FILE ${ALL_FILES_REL}) 50 | # get the base path 51 | get_filename_component(BASE_PATH "${FILE}" PATH) 52 | 53 | # changes /'s to \\'s 54 | string(REPLACE "/" "\\" GROUP "${BASE_PATH}") 55 | 56 | source_group("${GROUP}" FILES "${FILE}") 57 | endforeach() 58 | 59 | 60 | ################################################################################ 61 | # Include directory 62 | ################################################################################ 63 | include_directories( 64 | ${PROJECT_SOURCE_DIR} 65 | ${PROJECT_SOURCE_DIR}/Public 66 | ${PROJECT_SOURCE_DIR}/ThirdParty 67 | ) 68 | 69 | 70 | ################################################################################ 71 | # Precompiled Headers 72 | ################################################################################ 73 | set(ARG_PCH_HEADER Precompiled.h) 74 | set(ARG_PCH_SOURCE Precompiled.cpp) 75 | foreach (FILE ${ALL_FILES_REL}) 76 | if (FILE MATCHES ".*\\.(c|cpp)$") 77 | if (FILE STREQUAL ${ARG_PCH_SOURCE}) 78 | set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS "/Yc\"${ARG_PCH_HEADER}\"") 79 | else() 80 | set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS "/Yu\"${ARG_PCH_HEADER}\"") 81 | endif() 82 | endif() 83 | endforeach(FILE) 84 | 85 | ################################################################################ 86 | # Library Output Setting 87 | ################################################################################ 88 | add_library(${PROJECT_NAME} STATIC ${ALL_FILES_REL}) 89 | 90 | set_target_properties(${PROJECT_NAME} PROPERTIES 91 | PREFIX "" 92 | OUTPUT_NAME ${PROJECT_NAME} 93 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Output/${PLATFORM_FOLDER}/Library) 94 | 95 | 96 | ################################################################################ 97 | # Import Library 98 | ################################################################################ 99 | #target_link_libraries(${PROJECT_NAME} ) 100 | 101 | 102 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(EngineModule) 4 | 5 | ################################################################################ 6 | # Source files 7 | ################################################################################ 8 | file(GLOB COMMON_FILES 9 | ${PROJECT_SOURCE_DIR}/*.cpp 10 | ${PROJECT_SOURCE_DIR}/*.h) 11 | 12 | file(GLOB_RECURSE MODULE_FILES 13 | ${PROJECT_SOURCE_DIR}/Private/*.cpp 14 | ${PROJECT_SOURCE_DIR}/Public/*.h 15 | ${PROJECT_SOURCE_DIR}/Private/2D/*.cpp 16 | ${PROJECT_SOURCE_DIR}/Public/2D/*.h 17 | ${PROJECT_SOURCE_DIR}/Private/3D/*.cpp 18 | ${PROJECT_SOURCE_DIR}/Public/3D/*.h 19 | ) 20 | 21 | file(GLOB_RECURSE THIRDPARTY_FILES 22 | ${PROJECT_SOURCE_DIR}/ThirdParty/*.h 23 | ${PROJECT_SOURCE_DIR}/ThirdParty/*.cpp 24 | ) 25 | 26 | set(ALL_FILES 27 | ${COMMON_FILES} 28 | ${MODULE_FILES} 29 | ${THIRDPARTY_FILES} 30 | ) 31 | 32 | foreach(FILE ${ALL_FILES}) 33 | # make rel path 34 | file(RELATIVE_PATH REL_PATH "${PROJECT_SOURCE_DIR}" "${FILE}") 35 | set(ALL_FILES_REL ${ALL_FILES_REL} ${REL_PATH}) 36 | endforeach() 37 | 38 | set_source_files_properties(${ALL_FILES_REL} PROPERTIES HEADER_FILE_ONLY FALSE) 39 | 40 | foreach(FILE ${ALL_FILES_REL}) 41 | # get the base path 42 | get_filename_component(BASE_PATH "${FILE}" PATH) 43 | 44 | # changes /'s to \\'s 45 | string(REPLACE "/" "\\" GROUP "${BASE_PATH}") 46 | 47 | source_group("${GROUP}" FILES "${FILE}") 48 | endforeach() 49 | 50 | 51 | ################################################################################ 52 | # Include directory 53 | ################################################################################ 54 | include_directories( 55 | ${PROJECT_SOURCE_DIR} 56 | ${PROJECT_SOURCE_DIR}/Public 57 | ${PROJECT_SOURCE_DIR}/Public/2D 58 | ${PROJECT_SOURCE_DIR}/Public/3D 59 | ${PROJECT_SOURCE_DIR}/ThirdParty 60 | ${RUNTIME_MODULE_DIR}/Math/Public 61 | ${RUNTIME_MODULE_DIR}/Renderer/Public 62 | ) 63 | 64 | 65 | ################################################################################ 66 | # Precompiled Headers 67 | ################################################################################ 68 | set(ARG_PCH_HEADER Precompiled.h) 69 | set(ARG_PCH_SOURCE Precompiled.cpp) 70 | foreach (FILE ${ALL_FILES_REL}) 71 | if (FILE MATCHES ".*\\.(c|cpp)$") 72 | if (FILE STREQUAL ${ARG_PCH_SOURCE}) 73 | set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS "/Yc\"${ARG_PCH_HEADER}\"") 74 | else() 75 | set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS "/Yu\"${ARG_PCH_HEADER}\"") 76 | endif() 77 | endif() 78 | endforeach(FILE) 79 | 80 | 81 | ################################################################################ 82 | # Library Output Setting 83 | ################################################################################ 84 | add_library(${PROJECT_NAME} STATIC ${ALL_FILES_REL}) 85 | 86 | set_target_properties(${PROJECT_NAME} PROPERTIES 87 | PREFIX "" 88 | OUTPUT_NAME ${PROJECT_NAME} 89 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Output/${PLATFORM_FOLDER}/Library) 90 | 91 | 92 | ################################################################################ 93 | # Import Library 94 | ################################################################################ 95 | target_link_libraries(${PROJECT_NAME} MathModule RendererModule) 96 | 97 | 98 | -------------------------------------------------------------------------------- /Source/Player/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(SoftRendererPlayer) 4 | 5 | ################################################################################ 6 | # Source files 7 | ################################################################################ 8 | file(GLOB COMMON_SOURCE_FILES 9 | ${PROJECT_SOURCE_DIR}/Private/*.cpp 10 | ${PROJECT_SOURCE_DIR}/*.cpp 11 | ${PROJECT_SOURCE_DIR}/*.h 12 | ) 13 | 14 | set(ALL_FILES 15 | ${COMMON_SOURCE_FILES} 16 | ) 17 | 18 | if(TARGET_WINDOWS) 19 | 20 | file(GLOB_RECURSE WINDOWS_FILES 21 | ${PROJECT_SOURCE_DIR}/Private/${PLATFORM_FOLDER}/*.cpp 22 | ${PROJECT_SOURCE_DIR}/Private/${PLATFORM_FOLDER}/*.h 23 | ) 24 | 25 | file(GLOB WINDOWS_RESOURCE_FILES 26 | ${PROJECT_SOURCE_DIR}/Private/${PLATFORM_FOLDER}/Res/*.h 27 | ${PROJECT_SOURCE_DIR}/Private/${PLATFORM_FOLDER}/Res/*.rc 28 | ${PROJECT_SOURCE_DIR}/Private/${PLATFORM_FOLDER}/Res/*.ico 29 | ) 30 | 31 | set(ALL_FILES 32 | ${ALL_FILES} 33 | ${WINDOWS_FILES} 34 | ${WINDOWS_RESOURCE_FILES} 35 | ) 36 | 37 | endif() 38 | 39 | 40 | 41 | foreach(FILE ${ALL_FILES}) 42 | # make rel path 43 | file(RELATIVE_PATH REL_PATH "${PROJECT_SOURCE_DIR}" "${FILE}") 44 | 45 | # get the base path 46 | get_filename_component(BASE_PATH "${REL_PATH}" PATH) 47 | 48 | # changes /'s to \\'s 49 | string(REPLACE "/" "\\" GROUP "${BASE_PATH}") 50 | 51 | source_group("${GROUP}" FILES "${FILE}") 52 | endforeach() 53 | 54 | 55 | ################################################################################ 56 | # Include directory 57 | ################################################################################ 58 | include_directories( 59 | ${PROJECT_SOURCE_DIR} 60 | ${PROJECT_SOURCE_DIR}/Private/${PLATFORM_FOLDER} 61 | ${RUNTIME_MODULE_DIR}/Math/Public 62 | ${RUNTIME_MODULE_DIR}/Engine/Public 63 | ${RUNTIME_MODULE_DIR}/Renderer/Public 64 | ${RUNTIME_MODULE_DIR}/Renderer/Public/${PLATFORM_FOLDER} 65 | ) 66 | 67 | 68 | ################################################################################ 69 | # Precompiled Headers 70 | ################################################################################ 71 | set(ARG_PCH_HEADER Precompiled.h) 72 | set(ARG_PCH_SOURCE Precompiled.cpp) 73 | foreach (FILE ${ALL_FILES}) 74 | file(RELATIVE_PATH REL_PATH "${PROJECT_SOURCE_DIR}" "${FILE}") 75 | if (REL_PATH MATCHES ".*\\.(c|cpp)$") 76 | if (REL_PATH STREQUAL ${ARG_PCH_SOURCE}) 77 | set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS "/Yc\"${ARG_PCH_HEADER}\"") 78 | else() 79 | set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS "/Yu\"${ARG_PCH_HEADER}\"") 80 | endif() 81 | endif() 82 | endforeach(FILE) 83 | 84 | ################################################################################ 85 | # Excutable Output Setting 86 | ################################################################################ 87 | add_executable(${PROJECT_NAME} WIN32 ${ALL_FILES}) 88 | 89 | set_target_properties(${PROJECT_NAME} PROPERTIES 90 | PREFIX "" 91 | OUTPUT_NAME ${PROJECT_NAME} 92 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Output/${PLATFORM_FOLDER}/Binary 93 | VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Resource 94 | ) 95 | 96 | ################################################################################ 97 | # Import Library 98 | ################################################################################ 99 | target_link_libraries(${PROJECT_NAME} MathModule RendererModule EngineModule) 100 | 101 | 102 | -------------------------------------------------------------------------------- /Source/Player/Private/Windows/WindowsPlayer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace WindowsPlayer 4 | { 5 | static HINSTANCE gInstance; 6 | static HWND gHandle; 7 | static std::function gOnResizeFunc; 8 | 9 | static const TCHAR *gClassName = _T("SOFTRENDERER_PLAYER"); 10 | static TCHAR gTitle[64]; 11 | static TCHAR gPlayTitle[128]; 12 | 13 | LRESULT CALLBACK WndProc(HWND hwnd, UINT32 msg, WPARAM wParam, LPARAM lParam) 14 | { 15 | switch (msg) 16 | { 17 | case WM_DISPLAYCHANGE: 18 | case WM_SIZE: 19 | { 20 | int newWidth = (lParam & 0xffff); 21 | int newHeight = ((lParam >> 16) & 0xffff); 22 | if (gOnResizeFunc) 23 | { 24 | gOnResizeFunc(ScreenPoint(newWidth, newHeight)); 25 | } 26 | break; 27 | } 28 | case WM_CLOSE: 29 | { 30 | DestroyWindow(hwnd); 31 | return 0; 32 | } 33 | case WM_DESTROY: 34 | { 35 | PostQuitMessage(0); 36 | break; 37 | } 38 | case WM_SYSCOMMAND: 39 | { 40 | if (wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER || wParam == SC_KEYMENU) 41 | { 42 | return 0; 43 | } 44 | break; 45 | } 46 | } 47 | 48 | return DefWindowProc(hwnd, msg, wParam, lParam); 49 | } 50 | 51 | bool Create(HINSTANCE InInstance, const ScreenPoint& InDefaultScreenSize) 52 | { 53 | gInstance = InInstance; 54 | 55 | #define SIZEOF(a) ((int)(sizeof(a) / sizeof((a)[0]))) 56 | ::LoadString(gInstance, IDS_APP_TITLE, gTitle, SIZEOF(gTitle)); 57 | 58 | WNDCLASSEX wcex; 59 | memset(&wcex, 0, sizeof(wcex)); 60 | wcex.cbSize = sizeof(WNDCLASSEX); 61 | wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 62 | wcex.lpfnWndProc = WndProc; 63 | wcex.hInstance = gInstance; 64 | wcex.hIcon = LoadIcon(gInstance, MAKEINTRESOURCE(IDI_SOFTRENDERER)); 65 | wcex.hIconSm = LoadIcon(gInstance, MAKEINTRESOURCE(IDI_SMALL)); 66 | wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 67 | wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 68 | wcex.lpszMenuName = NULL; 69 | wcex.lpszClassName = gClassName; 70 | 71 | if (!::RegisterClassEx(&wcex)) 72 | { 73 | ::MessageBox(nullptr, "Window registration failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); 74 | return false; 75 | } 76 | 77 | RECT rect; 78 | rect.left = 0; 79 | rect.top = 0; 80 | rect.right = InDefaultScreenSize.X - 1; 81 | rect.bottom = InDefaultScreenSize.Y - 1; 82 | ::AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, false); 83 | int WindowWidth = rect.right - rect.left + 1; 84 | int WindowHeight = rect.bottom - rect.top + 1; 85 | 86 | gHandle = ::CreateWindow(gClassName, gTitle, WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, 87 | (GetSystemMetrics(SM_CXFULLSCREEN) - WindowWidth) / 2, (GetSystemMetrics(SM_CYFULLSCREEN) - WindowHeight) / 2, WindowWidth, WindowHeight, 88 | NULL, NULL, gInstance, NULL); 89 | 90 | if (!gHandle) 91 | { 92 | ::MessageBox(nullptr, "Window creation failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); 93 | return false; 94 | } 95 | 96 | return true; 97 | } 98 | 99 | FORCEINLINE bool Tick() 100 | { 101 | MSG msg; 102 | ZeroMemory(&msg, sizeof(msg)); 103 | 104 | while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) 105 | { 106 | TranslateMessage(&msg); 107 | DispatchMessage(&msg); 108 | 109 | if (msg.message == WM_QUIT) 110 | return false; 111 | } 112 | 113 | return true; 114 | } 115 | 116 | void Destroy() 117 | { 118 | DestroyWindow(gHandle); 119 | } 120 | 121 | FORCEINLINE void SetWindowsStatTitle(float frameFPS) 122 | { 123 | _stprintf_s(gPlayTitle, "%s [%.2f fps]", gTitle, frameFPS); 124 | ::SetWindowText(gHandle, gPlayTitle); 125 | } 126 | } -------------------------------------------------------------------------------- /Source/Runtime/Renderer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(RendererModule) 4 | 5 | ################################################################################ 6 | # Source files 7 | ################################################################################ 8 | file(GLOB COMMON_FILES 9 | ${PROJECT_SOURCE_DIR}/*.cpp 10 | ${PROJECT_SOURCE_DIR}/*.h) 11 | 12 | file(GLOB_RECURSE MODULE_FILES 13 | ${PROJECT_SOURCE_DIR}/Public/*.h 14 | ${PROJECT_SOURCE_DIR}/Public/2D/*.h 15 | ${PROJECT_SOURCE_DIR}/Public/3D/*.h 16 | ${PROJECT_SOURCE_DIR}/Private/2D/*.cpp 17 | ${PROJECT_SOURCE_DIR}/Private/3D/*.cpp 18 | ) 19 | 20 | file(GLOB_RECURSE THIRDPARTY_FILES 21 | ${PROJECT_SOURCE_DIR}/ThirdParty/*.h 22 | ${PROJECT_SOURCE_DIR}/ThirdParty/*.cpp 23 | ) 24 | 25 | set(ALL_FILES 26 | ${COMMON_FILES} 27 | ${MODULE_FILES} 28 | ${THIRDPARTY_FILES} 29 | ) 30 | 31 | if(TARGET_WINDOWS) 32 | 33 | file(GLOB_RECURSE WINDOWS_FILES 34 | ${PROJECT_SOURCE_DIR}/Public/${PLATFORM_FOLDER}/*.h 35 | ${PROJECT_SOURCE_DIR}/Private/${PLATFORM_FOLDER}/*.h 36 | ${PROJECT_SOURCE_DIR}/Private/${PLATFORM_FOLDER}/*.cpp 37 | ) 38 | 39 | set(ALL_FILES 40 | ${ALL_FILES} 41 | ${WINDOWS_FILES} 42 | ) 43 | 44 | endif() 45 | 46 | foreach(FILE ${ALL_FILES}) 47 | # make rel path 48 | file(RELATIVE_PATH REL_PATH "${PROJECT_SOURCE_DIR}" "${FILE}") 49 | set(ALL_FILES_REL ${ALL_FILES_REL} ${REL_PATH}) 50 | endforeach() 51 | 52 | set_source_files_properties(${ALL_FILES_REL} PROPERTIES HEADER_FILE_ONLY FALSE) 53 | 54 | foreach(FILE ${ALL_FILES_REL}) 55 | # get the base path 56 | get_filename_component(BASE_PATH "${FILE}" PATH) 57 | 58 | # changes /'s to \\'s 59 | string(REPLACE "/" "\\" GROUP "${BASE_PATH}") 60 | 61 | source_group("${GROUP}" FILES "${FILE}") 62 | endforeach() 63 | 64 | 65 | ################################################################################ 66 | # Include directory 67 | ################################################################################ 68 | include_directories( 69 | ${PROJECT_SOURCE_DIR} 70 | ${PROJECT_SOURCE_DIR}/Public 71 | ${PROJECT_SOURCE_DIR}/ThirdParty 72 | ${RUNTIME_MODULE_DIR}/Math/Public 73 | ) 74 | 75 | 76 | ################################################################################ 77 | # Precompiled Headers 78 | ################################################################################ 79 | set(ARG_PCH_HEADER Precompiled.h) 80 | set(ARG_PCH_SOURCE Precompiled.cpp) 81 | foreach (FILE ${ALL_FILES_REL}) 82 | if (FILE MATCHES ".*\\.(c|cpp)$") 83 | if (FILE STREQUAL ${ARG_PCH_SOURCE}) 84 | set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS "/Yc\"${ARG_PCH_HEADER}\"") 85 | else() 86 | set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS "/Yu\"${ARG_PCH_HEADER}\"") 87 | endif() 88 | endif() 89 | endforeach(FILE) 90 | 91 | 92 | ################################################################################ 93 | # Library Output Setting 94 | ################################################################################ 95 | add_library(${PROJECT_NAME} STATIC ${ALL_FILES_REL}) 96 | 97 | set_target_properties(${PROJECT_NAME} PROPERTIES 98 | PREFIX "" 99 | OUTPUT_NAME ${PROJECT_NAME} 100 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Output/${PLATFORM_FOLDER}/Library) 101 | 102 | 103 | ################################################################################ 104 | # Import Library 105 | ################################################################################ 106 | target_link_libraries(${PROJECT_NAME} MathModule) 107 | 108 | 109 | -------------------------------------------------------------------------------- /Source/Player/Private/Windows/WindowsUtil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace WindowsUtil 4 | { 5 | void GetWindowSize(HWND handle, float* width, float* height) 6 | { 7 | RECT rect; 8 | ::GetClientRect(handle, &rect); 9 | *width = static_cast(rect.right - rect.left); 10 | *height = static_cast(rect.bottom - rect.top); 11 | } 12 | 13 | void Show(HWND handle) 14 | { 15 | ::ShowWindow(handle, SW_SHOW); 16 | ::SetForegroundWindow(handle); 17 | ::SetFocus(handle); 18 | } 19 | 20 | void CenterWindow(HWND handle) 21 | { 22 | // center on parent or screen 23 | RECT rc, rcOwner, rcWindow; 24 | HWND ownerHandle = GetDesktopWindow(); 25 | GetWindowRect(ownerHandle, &rcOwner); 26 | GetWindowRect(handle, &rcWindow); 27 | CopyRect(&rc, &rcOwner); 28 | 29 | OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top); 30 | OffsetRect(&rc, -rc.left, -rc.top); 31 | OffsetRect(&rc, -rcWindow.right, -rcWindow.bottom); 32 | 33 | ::SetWindowPos(handle, HWND_TOP, 34 | rcOwner.left + (rc.right / 2), 35 | rcOwner.top + (rc.bottom / 2), 36 | 0, 0, 37 | SWP_NOSIZE); 38 | } 39 | 40 | float GetCyclesPerMilliSeconds() 41 | { 42 | LARGE_INTEGER frequency; 43 | if (!QueryPerformanceFrequency(&frequency)) 44 | { 45 | return 0.f; 46 | } 47 | 48 | return (float)(frequency.QuadPart / 1000.f); 49 | } 50 | 51 | long long GetCurrentTimeStamp() 52 | { 53 | LARGE_INTEGER currentTime; 54 | QueryPerformanceCounter(¤tTime); 55 | return currentTime.QuadPart; 56 | } 57 | 58 | float GetXAxisInput() 59 | { 60 | bool isLeft = GetAsyncKeyState(VK_LEFT); 61 | bool isRight = GetAsyncKeyState(VK_RIGHT); 62 | if (isLeft ^ isRight) 63 | { 64 | return isLeft ? -1.f : 1.f; 65 | } 66 | return 0.f; 67 | } 68 | 69 | float GetYAxisInput() 70 | { 71 | bool isDown = GetAsyncKeyState(VK_DOWN); 72 | bool isUp = GetAsyncKeyState(VK_UP); 73 | if (isDown ^ isUp) 74 | { 75 | return isDown ? -1.f : 1.f; 76 | } 77 | return 0.f; 78 | } 79 | 80 | float GetZAxisInput() 81 | { 82 | bool isDown = GetAsyncKeyState(VK_NEXT); 83 | bool isUp = GetAsyncKeyState(VK_PRIOR); 84 | if (isDown ^ isUp) 85 | { 86 | return isDown ? -1.f : 1.f; 87 | } 88 | return 0.f; 89 | } 90 | 91 | float GetWAxisInput() 92 | { 93 | bool isDown = GetAsyncKeyState(VK_END); 94 | bool isUp = GetAsyncKeyState(VK_HOME); 95 | if (isDown ^ isUp) 96 | { 97 | return isDown ? -1.f : 1.f; 98 | } 99 | return 0.f; 100 | } 101 | 102 | #define ISPRESSED(KeyCode) return (::GetKeyState(KeyCode) & 0x8000) != 0 103 | 104 | void BindInput(InputManager& InInputManager) 105 | { 106 | InInputManager.SetInputAxis(InputAxis::XAxis, GetXAxisInput); 107 | InInputManager.SetInputAxis(InputAxis::YAxis, GetYAxisInput); 108 | InInputManager.SetInputAxis(InputAxis::ZAxis, GetZAxisInput); 109 | InInputManager.SetInputAxis(InputAxis::WAxis, GetWAxisInput); 110 | InInputManager.SetInputButton(InputButton::Space, []() { ISPRESSED(VK_SPACE); }); 111 | InInputManager.SetInputButton(InputButton::Z, []() { ISPRESSED(0x5A); }); 112 | InInputManager.SetInputButton(InputButton::X, []() { ISPRESSED(0x58); }); 113 | } 114 | 115 | void BindSystemInput(SystemInputManager& InSystemInputManager) 116 | { 117 | InSystemInputManager.SetSystemInputButton(SystemInputButton::F1, []() { ISPRESSED(VK_F1); }); 118 | InSystemInputManager.SetSystemInputButton(SystemInputButton::F2, []() { ISPRESSED(VK_F2); }); 119 | InSystemInputManager.SetSystemInputButton(SystemInputButton::F3, []() { ISPRESSED(VK_F3); }); 120 | InSystemInputManager.SetSystemInputButton(SystemInputButton::F4, []() { ISPRESSED(VK_F4); }); 121 | InSystemInputManager.SetSystemInputButton(SystemInputButton::F5, []() { ISPRESSED(VK_F5); }); 122 | InSystemInputManager.SetSystemInputButton(SystemInputButton::F6, []() { ISPRESSED(VK_F6); }); 123 | InSystemInputManager.SetSystemInputButton(SystemInputButton::F7, []() { ISPRESSED(VK_F7); }); 124 | InSystemInputManager.SetSystemInputButton(SystemInputButton::F8, []() { ISPRESSED(VK_F8); }); 125 | InSystemInputManager.SetSystemInputButton(SystemInputButton::F9, []() { ISPRESSED(VK_F9); }); 126 | InSystemInputManager.SetSystemInputButton(SystemInputButton::F10, []() { ISPRESSED(VK_F10); }); 127 | } 128 | } -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Private/Windows/WindowsGDI.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | 4 | WindowsGDI::~WindowsGDI() 5 | { 6 | } 7 | 8 | bool WindowsGDI::InitializeGDI(const ScreenPoint& InScreenSize) 9 | { 10 | ReleaseGDI(); 11 | 12 | if (_Handle == 0) 13 | { 14 | _Handle = ::GetActiveWindow(); 15 | if (_Handle == 0) 16 | { 17 | return false; 18 | } 19 | } 20 | 21 | if (_GDIInitialized) 22 | { 23 | DeleteObject(_DefaultBitmap); 24 | DeleteObject(DIBitmap); 25 | ReleaseDC(_Handle, _ScreenDC); 26 | ReleaseDC(_Handle, _MemoryDC); 27 | } 28 | 29 | _ScreenDC = GetDC(_Handle); 30 | if (_ScreenDC == NULL) 31 | { 32 | return false; 33 | } 34 | 35 | _MemoryDC = CreateCompatibleDC(_ScreenDC); 36 | if (_MemoryDC == NULL) 37 | { 38 | return false; 39 | } 40 | 41 | _ScreenSize = InScreenSize; 42 | 43 | // Color & Bitmap Setting 44 | BITMAPINFO bmi; 45 | memset(&bmi, 0, sizeof(BITMAPINFO)); 46 | bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 47 | bmi.bmiHeader.biWidth = _ScreenSize.X; 48 | bmi.bmiHeader.biHeight = -_ScreenSize.Y; 49 | bmi.bmiHeader.biPlanes = 1; 50 | bmi.bmiHeader.biBitCount = 32; 51 | bmi.bmiHeader.biCompression = BI_RGB; 52 | 53 | DIBitmap = CreateDIBSection(_MemoryDC, &bmi, DIB_RGB_COLORS, (void**)&_ScreenBuffer, NULL, 0); 54 | if (DIBitmap == NULL) 55 | { 56 | return false; 57 | } 58 | 59 | _DefaultBitmap = (HBITMAP)SelectObject(_MemoryDC, DIBitmap); 60 | if (_DefaultBitmap == NULL) 61 | { 62 | return false; 63 | } 64 | 65 | // Create Depth Buffer 66 | CreateDepthBuffer(); 67 | 68 | _GDIInitialized = true; 69 | return true; 70 | } 71 | 72 | void WindowsGDI::ReleaseGDI() 73 | { 74 | if (_GDIInitialized) 75 | { 76 | DeleteObject(_DefaultBitmap); 77 | DeleteObject(DIBitmap); 78 | ReleaseDC(_Handle, _ScreenDC); 79 | ReleaseDC(_Handle, _MemoryDC); 80 | } 81 | 82 | if (_DepthBuffer != nullptr) 83 | { 84 | delete[] _DepthBuffer; 85 | _DepthBuffer = nullptr; 86 | } 87 | 88 | _GDIInitialized = false; 89 | } 90 | 91 | 92 | void WindowsGDI::FillBuffer(Color32 InColor) 93 | { 94 | if (!_GDIInitialized || (_ScreenBuffer == NULL)) 95 | { 96 | return; 97 | } 98 | 99 | Color32* dest = _ScreenBuffer; 100 | UINT32 totalCount = _ScreenSize.X * _ScreenSize.Y; 101 | CopyBuffer(_ScreenBuffer, &InColor, totalCount); 102 | return; 103 | } 104 | 105 | template 106 | T* WindowsGDI::CopyBuffer(T* InDst, T* InSrc, int InCount) 107 | { 108 | if (InCount == 0) 109 | { 110 | return NULL; 111 | } 112 | 113 | if (InCount == 1) 114 | { 115 | memcpy(InDst, InSrc, sizeof(T)); 116 | } 117 | else 118 | { 119 | int half = Math::FloorToInt(InCount * 0.5f); 120 | CopyBuffer(InDst, InSrc, half); 121 | memcpy(InDst + half, InDst, half * sizeof(T)); 122 | 123 | if (InCount % 2) 124 | { 125 | memcpy(InDst + (InCount - 1), InSrc, sizeof(T)); 126 | } 127 | } 128 | 129 | return InDst; 130 | } 131 | 132 | Color32* WindowsGDI::GetScreenBuffer() const 133 | { 134 | return _ScreenBuffer; 135 | } 136 | 137 | void WindowsGDI::DrawStatisticTexts() 138 | { 139 | if (_StatisticTexts.size() == 0) 140 | { 141 | return; 142 | } 143 | 144 | HFONT hFont, hOldFont; 145 | hFont = (HFONT)GetStockObject(ANSI_VAR_FONT); 146 | if (hOldFont = (HFONT)SelectObject(_MemoryDC, hFont)) 147 | { 148 | static const int leftPosition = 600; 149 | static const int topPosition = 10; 150 | static const int rowHeight = 20; 151 | int currentPosition = topPosition; 152 | for (std::vector::const_iterator it = _StatisticTexts.begin(); it != _StatisticTexts.end(); ++it) 153 | { 154 | TextOut(_MemoryDC, leftPosition, currentPosition, (*it).c_str(), (int)((*it).length())); 155 | currentPosition += rowHeight; 156 | } 157 | 158 | SelectObject(_MemoryDC, hOldFont); 159 | } 160 | } 161 | 162 | void WindowsGDI::SwapBuffer() 163 | { 164 | if (!_GDIInitialized) 165 | { 166 | return; 167 | } 168 | 169 | DrawStatisticTexts(); 170 | BitBlt(_ScreenDC, 0, 0, _ScreenSize.X, _ScreenSize.Y, _MemoryDC, 0, 0, SRCCOPY); 171 | 172 | _StatisticTexts.clear(); 173 | } 174 | 175 | void WindowsGDI::CreateDepthBuffer() 176 | { 177 | _DepthBuffer = new float[_ScreenSize.X * _ScreenSize.Y]; 178 | } 179 | 180 | void WindowsGDI::ClearDepthBuffer() 181 | { 182 | if (_DepthBuffer != nullptr) 183 | { 184 | float* dest = _DepthBuffer; 185 | static float defValue = INFINITY; 186 | UINT32 totalCount = _ScreenSize.X * _ScreenSize.Y; 187 | CopyBuffer(_DepthBuffer, &defValue, totalCount); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /Source/Runtime/Math/Public/LinearColor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CK 4 | { 5 | 6 | struct LinearColor 7 | { 8 | public: 9 | FORCEINLINE constexpr LinearColor() = default; 10 | FORCEINLINE explicit constexpr LinearColor(float InR, float InG, float InB, float InA = 1.f) : R(InR), G(InG), B(InB), A(InA) {} 11 | FORCEINLINE explicit constexpr LinearColor(const Color32& InColor32) 12 | { 13 | R = float(InColor32.R) * OneOver255; 14 | G = float(InColor32.G) * OneOver255; 15 | B = float(InColor32.B) * OneOver255; 16 | A = float(InColor32.A) * OneOver255; 17 | } 18 | 19 | FORCEINLINE constexpr Color32 ToColor32(const bool bSRGB = false) const; 20 | 21 | FORCEINLINE constexpr LinearColor operator+(const LinearColor& InColor) const; 22 | FORCEINLINE constexpr LinearColor operator-(const LinearColor& InColor) const; 23 | FORCEINLINE constexpr LinearColor operator*(const LinearColor& InColor) const; 24 | FORCEINLINE constexpr LinearColor operator*(float InScalar) const; 25 | FORCEINLINE constexpr LinearColor& operator*=(float InScale); 26 | FORCEINLINE constexpr LinearColor& operator/=(float InScale); 27 | FORCEINLINE constexpr LinearColor& operator+=(const LinearColor& InColor); 28 | FORCEINLINE constexpr LinearColor& operator-=(const LinearColor& InColor); 29 | 30 | FORCEINLINE constexpr bool operator==(const LinearColor& InColor) const; 31 | FORCEINLINE constexpr bool operator!=(const LinearColor& InColor) const; 32 | 33 | FORCEINLINE constexpr bool EqualsInRange(const LinearColor& InColor, float InTolerance = SMALL_NUMBER) const; 34 | 35 | static constexpr float OneOver255 = { 1.f / 255.f }; 36 | static const LinearColor Error; 37 | static const LinearColor White; 38 | static const LinearColor Black; 39 | static const LinearColor Gray; 40 | static const LinearColor Silver; 41 | static const LinearColor WhiteSmoke; 42 | static const LinearColor LightGray; 43 | static const LinearColor DimGray; 44 | static const LinearColor Red; 45 | static const LinearColor Green; 46 | static const LinearColor Blue; 47 | static const LinearColor Yellow; 48 | static const LinearColor Cyan; 49 | static const LinearColor Magenta; 50 | 51 | public: 52 | float R = 0.f; 53 | float G = 0.f; 54 | float B = 0.f; 55 | float A = 1.f; 56 | }; 57 | 58 | FORCEINLINE constexpr Color32 LinearColor::ToColor32(const bool bSRGB) const 59 | { 60 | float FloatR = Math::Clamp(R, 0.f, 1.f); 61 | float FloatG = Math::Clamp(G, 0.f, 1.f); 62 | float FloatB = Math::Clamp(B, 0.f, 1.f); 63 | float FloatA = Math::Clamp(A, 0.f, 1.f); 64 | 65 | return Color32( 66 | (int)(FloatR * 255.999f), 67 | (int)(FloatG * 255.999f), 68 | (int)(FloatB * 255.999f), 69 | (int)(FloatA * 255.999f) 70 | ); 71 | } 72 | 73 | FORCEINLINE constexpr LinearColor LinearColor::operator+(const LinearColor& InColor) const 74 | { 75 | return LinearColor( 76 | R + InColor.R, 77 | G + InColor.G, 78 | B + InColor.B, 79 | A + InColor.A 80 | ); 81 | } 82 | 83 | FORCEINLINE constexpr LinearColor LinearColor::operator-(const LinearColor& InColor) const 84 | { 85 | return LinearColor( 86 | R - InColor.R, 87 | G - InColor.G, 88 | B - InColor.B, 89 | A - InColor.A 90 | ); 91 | } 92 | 93 | FORCEINLINE constexpr LinearColor LinearColor::operator*(const LinearColor& InColor) const 94 | { 95 | return LinearColor( 96 | R * InColor.R, 97 | G * InColor.G, 98 | B * InColor.B, 99 | A * InColor.A 100 | ); 101 | } 102 | 103 | FORCEINLINE constexpr LinearColor LinearColor::operator*(float InScalar) const 104 | { 105 | return LinearColor( 106 | R * InScalar, 107 | G * InScalar, 108 | B * InScalar, 109 | A * InScalar 110 | ); 111 | } 112 | 113 | FORCEINLINE constexpr LinearColor& LinearColor::operator*=(float InScale) 114 | { 115 | R *= InScale; 116 | G *= InScale; 117 | B *= InScale; 118 | A *= InScale; 119 | return *this; 120 | } 121 | 122 | FORCEINLINE constexpr LinearColor& LinearColor::operator/=(float InScale) 123 | { 124 | R /= InScale; 125 | G /= InScale; 126 | B /= InScale; 127 | A /= InScale; 128 | return *this; 129 | } 130 | 131 | FORCEINLINE constexpr LinearColor& LinearColor::operator+=(const LinearColor& InColor) 132 | { 133 | R += InColor.R; 134 | G += InColor.G; 135 | B += InColor.B; 136 | A += InColor.A; 137 | return *this; 138 | } 139 | 140 | FORCEINLINE constexpr LinearColor& LinearColor::operator-=(const LinearColor& InColor) 141 | { 142 | R -= InColor.R; 143 | G -= InColor.G; 144 | B -= InColor.B; 145 | A -= InColor.A; 146 | return *this; 147 | } 148 | 149 | FORCEINLINE constexpr bool LinearColor::operator==(const LinearColor& InColor) const 150 | { 151 | return this->R == InColor.R && this->G == InColor.G && this->B == InColor.B && this->A == InColor.A; 152 | } 153 | 154 | FORCEINLINE constexpr bool LinearColor::operator!=(const LinearColor& InColor) const 155 | { 156 | return this->R != InColor.R || this->G != InColor.G || this->B != InColor.B || this->A != InColor.A; 157 | } 158 | 159 | FORCEINLINE constexpr bool LinearColor::EqualsInRange(const LinearColor& InColor, float InTolerance) const 160 | { 161 | return (Math::Abs(this->R - InColor.R) < InTolerance) && 162 | (Math::Abs(this->G - InColor.G) < InTolerance) && 163 | (Math::Abs(this->B - InColor.B) < InTolerance) && 164 | (Math::Abs(this->A - InColor.A) < InTolerance); 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /Source/Runtime/Renderer/Private/Windows/WindowsRSI.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Precompiled.h" 3 | 4 | WindowsRSI::~WindowsRSI() 5 | { 6 | } 7 | 8 | bool WindowsRSI::Init(const ScreenPoint& InScreenSize) 9 | { 10 | return InitializeGDI(InScreenSize); 11 | } 12 | 13 | void WindowsRSI::Shutdown() 14 | { 15 | ReleaseGDI(); 16 | } 17 | 18 | void WindowsRSI::Clear(const LinearColor & InClearColor) 19 | { 20 | FillBuffer(InClearColor.ToColor32()); 21 | ClearDepthBuffer(); 22 | } 23 | 24 | void WindowsRSI::BeginFrame() 25 | { 26 | } 27 | 28 | void WindowsRSI::EndFrame() 29 | { 30 | SwapBuffer(); 31 | } 32 | 33 | void WindowsRSI::DrawFullVerticalLine(int InX, const LinearColor & InColor) 34 | { 35 | if (InX < 0 || InX >= _ScreenSize.X) 36 | { 37 | return; 38 | } 39 | 40 | for (int y = 0; y < _ScreenSize.Y; ++y) 41 | { 42 | SetPixel(ScreenPoint(InX, y), InColor); 43 | } 44 | } 45 | 46 | void WindowsRSI::DrawFullHorizontalLine(int InY, const LinearColor & InColor) 47 | { 48 | if (InY < 0 || InY >= _ScreenSize.Y) 49 | { 50 | return; 51 | } 52 | 53 | for (int x = 0; x < _ScreenSize.X; ++x) 54 | { 55 | SetPixel(ScreenPoint(x, InY), InColor); 56 | } 57 | } 58 | 59 | void WindowsRSI::DrawPoint(const Vector2& InVectorPos, const LinearColor& InColor) 60 | { 61 | SetPixel(ScreenPoint::ToScreenCoordinate(_ScreenSize, InVectorPos), InColor); 62 | } 63 | 64 | void WindowsRSI::DrawPoint(const ScreenPoint& InScreenPos, const LinearColor& InColor) 65 | { 66 | SetPixel(InScreenPos, InColor); 67 | } 68 | 69 | int WindowsRSI::TestRegion(const Vector2& InVectorPos, const Vector2& InMinPos, const Vector2& InMaxPos) 70 | { 71 | int result = 0; 72 | if (InVectorPos.X < InMinPos.X) 73 | { 74 | result = result | 0b0001; 75 | } 76 | else if (InVectorPos.X > InMaxPos.X) 77 | { 78 | result = result | 0b0010; 79 | } 80 | 81 | if (InVectorPos.Y < InMinPos.Y) 82 | { 83 | result = result | 0b0100; 84 | } 85 | else if (InVectorPos.Y > InMaxPos.Y) 86 | { 87 | result = result | 0b1000; 88 | } 89 | 90 | return result; 91 | } 92 | 93 | bool WindowsRSI::CohenSutherlandLineClip(Vector2& InOutStartPos, Vector2& InOutEndPos, const Vector2& InMinPos, const Vector2& InMaxPos) 94 | { 95 | int startTest = TestRegion(InOutStartPos, InMinPos, InMaxPos); 96 | int endTest = TestRegion(InOutEndPos, InMinPos, InMaxPos); 97 | 98 | float width = (InOutEndPos.X - InOutStartPos.X); 99 | float height = (InOutEndPos.Y - InOutStartPos.Y); 100 | 101 | while (true) 102 | { 103 | if ((startTest == 0) && (endTest == 0)) 104 | { 105 | return true; 106 | } 107 | else if (startTest & endTest) 108 | { 109 | return false; 110 | } 111 | else 112 | { 113 | Vector2 clippedPosition; 114 | bool isStartTest = (startTest != 0); 115 | int currentTest = isStartTest ? startTest : endTest; 116 | 117 | if (currentTest < 0b0100) 118 | { 119 | if (currentTest & 1) 120 | { 121 | clippedPosition.X = InMinPos.X; 122 | } 123 | else 124 | { 125 | clippedPosition.X = InMaxPos.X; 126 | } 127 | 128 | if (Math::EqualsInTolerance(height, 0.0f)) 129 | { 130 | clippedPosition.Y = InOutStartPos.Y; 131 | 132 | } 133 | else 134 | { 135 | clippedPosition.Y = InOutStartPos.Y + height * (clippedPosition.X - InOutStartPos.X) / width; 136 | } 137 | } 138 | else 139 | { 140 | if (currentTest & 0b0100) 141 | { 142 | clippedPosition.Y = InMinPos.Y; 143 | } 144 | else 145 | { 146 | clippedPosition.Y = InMaxPos.Y; 147 | } 148 | 149 | if (Math::EqualsInTolerance(width, 0.0f)) 150 | { 151 | clippedPosition.X = InOutStartPos.X; 152 | } 153 | else 154 | { 155 | clippedPosition.X = InOutStartPos.X + width * (clippedPosition.Y - InOutStartPos.Y) / height; 156 | } 157 | } 158 | 159 | if (isStartTest) 160 | { 161 | InOutStartPos = clippedPosition; 162 | startTest = TestRegion(InOutStartPos, InMinPos, InMaxPos); 163 | } 164 | else 165 | { 166 | InOutEndPos = clippedPosition; 167 | endTest = TestRegion(InOutEndPos, InMinPos, InMaxPos); 168 | } 169 | } 170 | } 171 | 172 | return true; 173 | } 174 | 175 | void WindowsRSI::DrawLine(const Vector4& InStartPos, const Vector4& InEndPos, const LinearColor& InColor) 176 | { 177 | DrawLine(InStartPos.ToVector2(), InEndPos.ToVector2(), InColor); 178 | } 179 | 180 | 181 | float WindowsRSI::GetDepthBufferValue(const ScreenPoint& InPos) const 182 | { 183 | if (_DepthBuffer == nullptr) 184 | { 185 | return INFINITY; 186 | } 187 | 188 | if (!IsInScreen(InPos)) 189 | { 190 | return INFINITY; 191 | } 192 | 193 | return *(_DepthBuffer + GetScreenBufferIndex(InPos)); 194 | } 195 | 196 | void WindowsRSI::SetDepthBufferValue(const ScreenPoint& InPos, float InDepthValue) 197 | { 198 | if (_DepthBuffer == nullptr) 199 | { 200 | return; 201 | } 202 | 203 | if (!IsInScreen(InPos)) 204 | { 205 | return; 206 | } 207 | 208 | *(_DepthBuffer + GetScreenBufferIndex(InPos)) = InDepthValue; 209 | } 210 | 211 | void WindowsRSI::DrawLine(const Vector2& InStartPos, const Vector2& InEndPos, const LinearColor& InColor) 212 | { 213 | Vector2 clippedStart = InStartPos; 214 | Vector2 clippedEnd = InEndPos; 215 | Vector2 screenExtend = Vector2(_ScreenSize.X, _ScreenSize.Y) * 0.5f; 216 | Vector2 minScreen = -screenExtend; 217 | Vector2 maxScreen = screenExtend; 218 | if (!CohenSutherlandLineClip(clippedStart, clippedEnd, minScreen, maxScreen)) 219 | { 220 | return; 221 | } 222 | 223 | ScreenPoint startPosition = ScreenPoint::ToScreenCoordinate(_ScreenSize, clippedStart); 224 | ScreenPoint endPosition = ScreenPoint::ToScreenCoordinate(_ScreenSize, clippedEnd); 225 | 226 | int width = endPosition.X - startPosition.X; 227 | int height = endPosition.Y - startPosition.Y; 228 | 229 | bool isGradualSlope = (Math::Abs(width) >= Math::Abs(height)); 230 | int dx = (width >= 0) ? 1 : -1; 231 | int dy = (height > 0) ? 1 : -1; 232 | int fw = dx * width; 233 | int fh = dy * height; 234 | 235 | int f = isGradualSlope ? fh * 2 - fw : 2 * fw - fh; 236 | int f1 = isGradualSlope ? 2 * fh : 2 * fw; 237 | int f2 = isGradualSlope ? 2 * (fh - fw) : 2 * (fw - fh); 238 | int x = startPosition.X; 239 | int y = startPosition.Y; 240 | 241 | if (isGradualSlope) 242 | { 243 | while (x != endPosition.X) 244 | { 245 | SetPixel(ScreenPoint(x, y), InColor); 246 | 247 | if (f < 0) 248 | { 249 | f += f1; 250 | } 251 | else 252 | { 253 | f += f2; 254 | y += dy; 255 | } 256 | 257 | x += dx; 258 | } 259 | } 260 | else 261 | { 262 | while (y != endPosition.Y) 263 | { 264 | SetPixel(ScreenPoint(x, y), InColor); 265 | 266 | if (f < 0) 267 | { 268 | f += f1; 269 | } 270 | else 271 | { 272 | f += f2; 273 | x += dx; 274 | } 275 | 276 | y += dy; 277 | } 278 | } 279 | } 280 | 281 | void WindowsRSI::PushStatisticText(std::string && InText) 282 | { 283 | _StatisticTexts.emplace_back(InText); 284 | } 285 | 286 | void WindowsRSI::PushStatisticTexts(std::vector && InTexts) 287 | { 288 | std::move(InTexts.begin(), InTexts.end(), std::back_inserter(_StatisticTexts)); 289 | } 290 | -------------------------------------------------------------------------------- /Source/Runtime/Engine/ThirdParty/lodepng.h: -------------------------------------------------------------------------------- 1 | /* 2 | LodePNG version 20120729 3 | 4 | Copyright (c) 2005-2012 Lode Vandevenne 5 | 6 | This software is provided 'as-is', without any express or implied 7 | warranty. In no event will the authors be held liable for any damages 8 | arising from the use of this software. 9 | 10 | Permission is granted to anyone to use this software for any purpose, 11 | including commercial applications, and to alter it and redistribute it 12 | freely, subject to the following restrictions: 13 | 14 | 1. The origin of this software must not be misrepresented; you must not 15 | claim that you wrote the original software. If you use this software 16 | in a product, an acknowledgment in the product documentation would be 17 | appreciated but is not required. 18 | 19 | 2. Altered source versions must be plainly marked as such, and must not be 20 | misrepresented as being the original software. 21 | 22 | 3. This notice may not be removed or altered from any source 23 | distribution. 24 | */ 25 | 26 | #ifndef LODEPNG_H 27 | #define LODEPNG_H 28 | 29 | #include /*for size_t*/ 30 | 31 | #ifdef __cplusplus 32 | #include 33 | #include 34 | #endif /*__cplusplus*/ 35 | 36 | /* 37 | The following #defines are used to create code sections. They can be disabled 38 | to disable code sections, which can give faster compile time and smaller binary. 39 | The "NO_COMPILE" defines are designed to be used to pass as defines to the 40 | compiler command to disable them without modifying this header, e.g. 41 | -DLODEPNG_NO_COMPILE_ZLIB for gcc. 42 | */ 43 | /*deflate&zlib. If disabled, you need to define two zlib functions, see documtation of LODEPNG_CUSTOM_ZLIB_... below*/ 44 | #ifndef LODEPNG_NO_COMPILE_ZLIB 45 | #define LODEPNG_COMPILE_ZLIB 46 | #endif 47 | /*png encoder and png decoder*/ 48 | #ifndef LODEPNG_NO_COMPILE_PNG 49 | #define LODEPNG_COMPILE_PNG 50 | #endif 51 | /*deflate&zlib decoder and png decoder*/ 52 | #ifndef LODEPNG_NO_COMPILE_DECODER 53 | #define LODEPNG_COMPILE_DECODER 54 | #endif 55 | /*deflate&zlib encoder and png encoder*/ 56 | #ifndef LODEPNG_NO_COMPILE_ENCODER 57 | #define LODEPNG_COMPILE_ENCODER 58 | #endif 59 | /*the optional built in harddisk file loading and saving functions*/ 60 | #ifndef LODEPNG_NO_COMPILE_DISK 61 | #define LODEPNG_COMPILE_DISK 62 | #endif 63 | /*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ 64 | #ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 65 | #define LODEPNG_COMPILE_ANCILLARY_CHUNKS 66 | #endif 67 | /*ability to convert error numerical codes to English text string*/ 68 | #ifndef LODEPNG_NO_COMPILE_ERROR_TEXT 69 | #define LODEPNG_COMPILE_ERROR_TEXT 70 | #endif 71 | /*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/ 72 | #ifdef __cplusplus 73 | #ifndef LODEPNG_NO_COMPILE_CPP 74 | #define LODEPNG_COMPILE_CPP 75 | #endif 76 | #endif 77 | 78 | /* 79 | custom zlib decoder (if LODEPNG_COMPILE_ZLIB is disabled, this is ignored, always treated as "1"): 80 | 0: not custom, use LodePNG's zlib decoder 81 | 1: allow using custom zlib decoder with a setting 82 | --> you must then provide following function in your source files that LodePNG will link to: 83 | unsigned lodepng_custom_inflate(unsigned char**, size_t*, const unsigned char*, size_t, 84 | const LodePNGDecompressSettings*) 85 | 2: allow using custom deflate decoder with a setting 86 | --> you must then provide following function in your source files that LodePNG will link to: 87 | unsigned lodepng_custom_zlib_decompress(unsigned char**, size_t*, const unsigned char*, size_t, 88 | const LodePNGDecompressSettings*) 89 | */ 90 | #ifndef LODEPNG_OVERRIDE_CUSTOM_ZLIB_DECODER 91 | #define LODEPNG_CUSTOM_ZLIB_DECODER 0 92 | #else 93 | #define LODEPNG_CUSTOM_ZLIB_DECODER LODEPNG_OVERRIDE_CUSTOM_ZLIB_DECODER 94 | #endif 95 | 96 | /* 97 | custom zlib encoder (if LODEPNG_COMPILE_ZLIB is disabled, this is ignored, always treated as "1"): 98 | 0: not custom, use LodePNG's zlib encoder 99 | 1: allow using custom zlib encoder with a setting 100 | --> you must then provide following function in your source files that LodePNG will link to: 101 | unsigned lodepng_custom_deflate(unsigned char**, size_t*, const unsigned char*, size_t, 102 | const LodePNGCompressSettings*) 103 | 2: allow using custom deflate encoder with a setting 104 | --> you must then provide following function in your source files that LodePNG will link to: 105 | unsigned lodepng_custom_zlib_compress(unsigned char**, size_t*, const unsigned char*, size_t, 106 | const LodePNGCompressSettings*) 107 | */ 108 | #ifndef LODEPNG_OVERRIDE_CUSTOM_ZLIB_ENCODER 109 | #define LODEPNG_CUSTOM_ZLIB_ENCODER 0 110 | #else 111 | #define LODEPNG_CUSTOM_ZLIB_ENCODER LODEPNG_OVERRIDE_CUSTOM_ZLIB_ENCODER 112 | #endif 113 | 114 | #ifdef LODEPNG_COMPILE_PNG 115 | /*The PNG color types (also used for raw).*/ 116 | typedef enum LodePNGColorType 117 | { 118 | LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/ 119 | LCT_RGB = 2, /*RGB: 8,16 bit*/ 120 | LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ 121 | LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/ 122 | LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/ 123 | } LodePNGColorType; 124 | 125 | #ifdef LODEPNG_COMPILE_DECODER 126 | /* 127 | Converts PNG data in memory to raw pixel data. 128 | out: Output parameter. Pointer to buffer that will contain the raw pixel data. 129 | After decoding, its size is w * h * (bytes per pixel) bytes larger than 130 | initially. Bytes per pixel depends on colortype and bitdepth. 131 | Must be freed after usage with free(*out). 132 | w: Output parameter. Pointer to width of pixel data. 133 | h: Output parameter. Pointer to height of pixel data. 134 | in: Memory buffer with the PNG file. 135 | insize: size of the in buffer. 136 | colortype: the desired color type for the raw output image. See explanation on PNG color types. 137 | bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types. 138 | Return value: LodePNG error code (0 means no error). 139 | */ 140 | unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, 141 | const unsigned char* in, size_t insize, 142 | LodePNGColorType colortype, unsigned bitdepth); 143 | 144 | /*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/ 145 | unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, 146 | const unsigned char* in, size_t insize); 147 | 148 | /*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/ 149 | unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, 150 | const unsigned char* in, size_t insize); 151 | 152 | #ifdef LODEPNG_COMPILE_DISK 153 | /* 154 | Load PNG from disk, from file with given name. 155 | Same as the other decode functions, but instead takes a filename as input. 156 | */ 157 | unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, 158 | const char* filename, 159 | LodePNGColorType colortype, unsigned bitdepth); 160 | 161 | /*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/ 162 | unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, 163 | const char* filename); 164 | 165 | /*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/ 166 | unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, 167 | const char* filename); 168 | #endif /*LODEPNG_COMPILE_DISK*/ 169 | #endif /*LODEPNG_COMPILE_DECODER*/ 170 | 171 | 172 | #ifdef LODEPNG_COMPILE_ENCODER 173 | /* 174 | Converts raw pixel data into a PNG image in memory. The colortype and bitdepth 175 | of the output PNG image cannot be chosen, they are automatically determined 176 | by the colortype, bitdepth and content of the input pixel data. 177 | out: Output parameter. Pointer to buffer that will contain the raw pixel data. 178 | Must be freed after usage with free(*out). 179 | outsize: Output parameter. Pointer to the size in bytes of the out buffer. 180 | image: The raw pixel data to encode. The size of this buffer should be 181 | w * h * (bytes per pixel), bytes per pixel depends on colortype and bitdepth. 182 | w: width of the raw pixel data in pixels. 183 | h: height of the raw pixel data in pixels. 184 | colortype: the color type of the raw input image. See explanation on PNG color types. 185 | bitdepth: the bit depth of the raw input image. See explanation on PNG color types. 186 | Return value: LodePNG error code (0 means no error). 187 | */ 188 | unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, 189 | const unsigned char* image, unsigned w, unsigned h, 190 | LodePNGColorType colortype, unsigned bitdepth); 191 | 192 | /*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/ 193 | unsigned lodepng_encode32(unsigned char** out, size_t* outsize, 194 | const unsigned char* image, unsigned w, unsigned h); 195 | 196 | /*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/ 197 | unsigned lodepng_encode24(unsigned char** out, size_t* outsize, 198 | const unsigned char* image, unsigned w, unsigned h); 199 | 200 | #ifdef LODEPNG_COMPILE_DISK 201 | /* 202 | Converts raw pixel data into a PNG file on disk. 203 | Same as the other encode functions, but instead takes a filename as output. 204 | NOTE: This overwrites existing files without warning! 205 | */ 206 | unsigned lodepng_encode_file(const char* filename, 207 | const unsigned char* image, unsigned w, unsigned h, 208 | LodePNGColorType colortype, unsigned bitdepth); 209 | 210 | /*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/ 211 | unsigned lodepng_encode32_file(const char* filename, 212 | const unsigned char* image, unsigned w, unsigned h); 213 | 214 | /*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/ 215 | unsigned lodepng_encode24_file(const char* filename, 216 | const unsigned char* image, unsigned w, unsigned h); 217 | #endif /*LODEPNG_COMPILE_DISK*/ 218 | #endif /*LODEPNG_COMPILE_ENCODER*/ 219 | 220 | 221 | #ifdef LODEPNG_COMPILE_CPP 222 | namespace lodepng 223 | { 224 | #ifdef LODEPNG_COMPILE_DECODER 225 | /*Same as lodepng_decode_memory, but decodes to an std::vector.*/ 226 | unsigned decode(std::vector& out, unsigned& w, unsigned& h, 227 | const unsigned char* in, size_t insize, 228 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 229 | unsigned decode(std::vector& out, unsigned& w, unsigned& h, 230 | const std::vector& in, 231 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 232 | #ifdef LODEPNG_COMPILE_DISK 233 | /* 234 | Converts PNG file from disk to raw pixel data in memory. 235 | Same as the other decode functions, but instead takes a filename as input. 236 | */ 237 | unsigned decode(std::vector& out, unsigned& w, unsigned& h, 238 | const std::string& filename, 239 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 240 | #endif //LODEPNG_COMPILE_DISK 241 | #endif //LODEPNG_COMPILE_DECODER 242 | 243 | #ifdef LODEPNG_COMPILE_ENCODER 244 | /*Same as lodepng_encode_memory, but encodes to an std::vector.*/ 245 | unsigned encode(std::vector& out, 246 | const unsigned char* in, unsigned w, unsigned h, 247 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 248 | unsigned encode(std::vector& out, 249 | const std::vector& in, unsigned w, unsigned h, 250 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 251 | #ifdef LODEPNG_COMPILE_DISK 252 | /* 253 | Converts 32-bit RGBA raw pixel data into a PNG file on disk. 254 | Same as the other encode functions, but instead takes a filename as output. 255 | NOTE: This overwrites existing files without warning! 256 | */ 257 | unsigned encode(const std::string& filename, 258 | const unsigned char* in, unsigned w, unsigned h, 259 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 260 | unsigned encode(const std::string& filename, 261 | const std::vector& in, unsigned w, unsigned h, 262 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 263 | #endif //LODEPNG_COMPILE_DISK 264 | #endif //LODEPNG_COMPILE_ENCODER 265 | } //namespace lodepng 266 | #endif /*LODEPNG_COMPILE_CPP*/ 267 | #endif /*LODEPNG_COMPILE_PNG*/ 268 | 269 | #ifdef LODEPNG_COMPILE_ERROR_TEXT 270 | /*Returns an English description of the numerical error code.*/ 271 | const char* lodepng_error_text(unsigned code); 272 | #endif /*LODEPNG_COMPILE_ERROR_TEXT*/ 273 | 274 | #ifdef LODEPNG_COMPILE_DECODER 275 | /*Settings for zlib decompression*/ 276 | typedef struct LodePNGDecompressSettings 277 | { 278 | unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ 279 | unsigned custom_decoder; /*use custom decoder if LODEPNG_CUSTOM_ZLIB_DECODER and LODEPNG_COMPILE_ZLIB are enabled*/ 280 | } LodePNGDecompressSettings; 281 | 282 | extern const LodePNGDecompressSettings lodepng_default_decompress_settings; 283 | void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings); 284 | #endif /*LODEPNG_COMPILE_DECODER*/ 285 | 286 | #ifdef LODEPNG_COMPILE_ENCODER 287 | /* 288 | Settings for zlib compression. Tweaking these settings tweaks the balance 289 | between speed and compression ratio. 290 | */ 291 | typedef struct LodePNGCompressSettings /*deflate = compress*/ 292 | { 293 | /*LZ77 related settings*/ 294 | unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ 295 | unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ 296 | unsigned windowsize; /*the maximum is 32768, higher gives more compression but is slower. Typical value: 2048.*/ 297 | unsigned custom_encoder; /*use custom encoder if LODEPNG_CUSTOM_ZLIB_DECODER and LODEPNG_COMPILE_ZLIB are enabled*/ 298 | } LodePNGCompressSettings; 299 | 300 | extern const LodePNGCompressSettings lodepng_default_compress_settings; 301 | void lodepng_compress_settings_init(LodePNGCompressSettings* settings); 302 | #endif /*LODEPNG_COMPILE_ENCODER*/ 303 | 304 | #ifdef LODEPNG_COMPILE_PNG 305 | /* 306 | Color mode of an image. Contains all information required to decode the pixel 307 | bits to RGBA colors. This information is the same as used in the PNG file 308 | format, and is used both for PNG and raw image data in LodePNG. 309 | */ 310 | typedef struct LodePNGColorMode 311 | { 312 | /*header (IHDR)*/ 313 | LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ 314 | unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ 315 | 316 | /* 317 | palette (PLTE and tRNS) 318 | 319 | Dynamically allocated with the colors of the palette, including alpha. 320 | When encoding a PNG, to store your colors in the palette of the LodePNGColorMode, first use 321 | lodepng_palette_clear, then for each color use lodepng_palette_add. 322 | If you encode an image without alpha with palette, don't forget to put value 255 in each A byte of the palette. 323 | 324 | When decoding, by default you can ignore this palette, since LodePNG already 325 | fills the palette colors in the pixels of the raw RGBA output. 326 | 327 | The palette is only supported for color type 3. 328 | */ 329 | unsigned char* palette; /*palette in RGBARGBA... order*/ 330 | size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/ 331 | 332 | /* 333 | transparent color key (tRNS) 334 | 335 | This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. 336 | For greyscale PNGs, r, g and b will all 3 be set to the same. 337 | 338 | When decoding, by default you can ignore this information, since LodePNG sets 339 | pixels with this key to transparent already in the raw RGBA output. 340 | 341 | The color key is only supported for color types 0 and 2. 342 | */ 343 | unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ 344 | unsigned key_r; /*red/greyscale component of color key*/ 345 | unsigned key_g; /*green component of color key*/ 346 | unsigned key_b; /*blue component of color key*/ 347 | } LodePNGColorMode; 348 | 349 | /*init, cleanup and copy functions to use with this struct*/ 350 | void lodepng_color_mode_init(LodePNGColorMode* info); 351 | void lodepng_color_mode_cleanup(LodePNGColorMode* info); 352 | /*return value is error code (0 means no error)*/ 353 | unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source); 354 | 355 | void lodepng_palette_clear(LodePNGColorMode* info); 356 | /*add 1 color to the palette*/ 357 | unsigned lodepng_palette_add(LodePNGColorMode* info, 358 | unsigned char r, unsigned char g, unsigned char b, unsigned char a); 359 | 360 | /*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/ 361 | unsigned lodepng_get_bpp(const LodePNGColorMode* info); 362 | /*get the amount of color channels used, based on colortype in the struct. 363 | If a palette is used, it counts as 1 channel.*/ 364 | unsigned lodepng_get_channels(const LodePNGColorMode* info); 365 | /*is it a greyscale type? (only colortype 0 or 4)*/ 366 | unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info); 367 | /*has it got an alpha channel? (only colortype 2 or 6)*/ 368 | unsigned lodepng_is_alpha_type(const LodePNGColorMode* info); 369 | /*has it got a palette? (only colortype 3)*/ 370 | unsigned lodepng_is_palette_type(const LodePNGColorMode* info); 371 | /*only returns true if there is a palette and there is a value in the palette with alpha < 255. 372 | Loops through the palette to check this.*/ 373 | unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info); 374 | /* 375 | Check if the given color info indicates the possibility of having non-opaque pixels in the PNG image. 376 | Returns true if the image can have translucent or invisible pixels (it still be opaque if it doesn't use such pixels). 377 | Returns false if the image can only have opaque pixels. 378 | In detail, it returns true only if it's a color type with alpha, or has a palette with non-opaque values, 379 | or if "key_defined" is true. 380 | */ 381 | unsigned lodepng_can_have_alpha(const LodePNGColorMode* info); 382 | /*Returns the byte size of a raw image buffer with given width, height and color mode*/ 383 | size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color); 384 | 385 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 386 | /*The information of a Time chunk in PNG.*/ 387 | typedef struct LodePNGTime 388 | { 389 | unsigned year; /*2 bytes used (0-65535)*/ 390 | unsigned month; /*1-12*/ 391 | unsigned day; /*1-31*/ 392 | unsigned hour; /*0-23*/ 393 | unsigned minute; /*0-59*/ 394 | unsigned second; /*0-60 (to allow for leap seconds)*/ 395 | } LodePNGTime; 396 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ 397 | 398 | /*Information about the PNG image, except pixels, width and height.*/ 399 | typedef struct LodePNGInfo 400 | { 401 | /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ 402 | unsigned compression_method;/*compression method of the original file. Always 0.*/ 403 | unsigned filter_method; /*filter method of the original file*/ 404 | unsigned interlace_method; /*interlace method of the original file*/ 405 | LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ 406 | 407 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 408 | /* 409 | suggested background color chunk (bKGD) 410 | This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit. 411 | 412 | For greyscale PNGs, r, g and b will all 3 be set to the same. When encoding 413 | the encoder writes the red one. For palette PNGs: When decoding, the RGB value 414 | will be stored, not a palette index. But when encoding, specify the index of 415 | the palette in background_r, the other two are then ignored. 416 | 417 | The decoder does not use this background color to edit the color of pixels. 418 | */ 419 | unsigned background_defined; /*is a suggested background color given?*/ 420 | unsigned background_r; /*red component of suggested background color*/ 421 | unsigned background_g; /*green component of suggested background color*/ 422 | unsigned background_b; /*blue component of suggested background color*/ 423 | 424 | /* 425 | non-international text chunks (tEXt and zTXt) 426 | 427 | The char** arrays each contain num strings. The actual messages are in 428 | text_strings, while text_keys are keywords that give a short description what 429 | the actual text represents, e.g. Title, Author, Description, or anything else. 430 | 431 | A keyword is minimum 1 character and maximum 79 characters long. It's 432 | discouraged to use a single line length longer than 79 characters for texts. 433 | 434 | Don't allocate these text buffers yourself. Use the init/cleanup functions 435 | correctly and use lodepng_add_text and lodepng_clear_text. 436 | */ 437 | size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ 438 | char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ 439 | char** text_strings; /*the actual text*/ 440 | 441 | /* 442 | international text chunks (iTXt) 443 | Similar to the non-international text chunks, but with additional strings 444 | "langtags" and "transkeys". 445 | */ 446 | size_t itext_num; /*the amount of international texts in this PNG*/ 447 | char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ 448 | char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ 449 | char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ 450 | char** itext_strings; /*the actual international text - UTF-8 string*/ 451 | 452 | /*time chunk (tIME)*/ 453 | unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ 454 | LodePNGTime time; 455 | 456 | /*phys chunk (pHYs)*/ 457 | unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ 458 | unsigned phys_x; /*pixels per unit in x direction*/ 459 | unsigned phys_y; /*pixels per unit in y direction*/ 460 | unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ 461 | 462 | /* 463 | unknown chunks 464 | There are 3 buffers, one for each position in the PNG where unknown chunks can appear 465 | each buffer contains all unknown chunks for that position consecutively 466 | The 3 buffers are the unknown chunks between certain critical chunks: 467 | 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND 468 | Do not allocate or traverse this data yourself. Use the chunk traversing functions declared 469 | later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct. 470 | */ 471 | unsigned char* unknown_chunks_data[3]; 472 | size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ 473 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ 474 | } LodePNGInfo; 475 | 476 | /*init, cleanup and copy functions to use with this struct*/ 477 | void lodepng_info_init(LodePNGInfo* info); 478 | void lodepng_info_cleanup(LodePNGInfo* info); 479 | /*return value is error code (0 means no error)*/ 480 | unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source); 481 | 482 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 483 | void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ 484 | unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/ 485 | 486 | void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/ 487 | unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, 488 | const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/ 489 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ 490 | 491 | /* 492 | Converts raw buffer from one color type to another color type, based on 493 | LodePNGColorMode structs to describe the input and output color type. 494 | See the reference manual at the end of this header file to see which color conversions are supported. 495 | return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported) 496 | The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel 497 | of the output color type (lodepng_get_bpp) 498 | */ 499 | unsigned lodepng_convert(unsigned char* out, const unsigned char* in, 500 | LodePNGColorMode* mode_out, LodePNGColorMode* mode_in, 501 | unsigned w, unsigned h); 502 | 503 | 504 | #ifdef LODEPNG_COMPILE_DECODER 505 | /* 506 | Settings for the decoder. This contains settings for the PNG and the Zlib 507 | decoder, but not the Info settings from the Info structs. 508 | */ 509 | typedef struct LodePNGDecoderSettings 510 | { 511 | LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ 512 | 513 | unsigned ignore_crc; /*ignore CRC checksums*/ 514 | unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ 515 | 516 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 517 | unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ 518 | /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ 519 | unsigned remember_unknown_chunks; 520 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ 521 | } LodePNGDecoderSettings; 522 | 523 | void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings); 524 | #endif /*LODEPNG_COMPILE_DECODER*/ 525 | 526 | #ifdef LODEPNG_COMPILE_ENCODER 527 | /*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/ 528 | typedef enum LodePNGFilterStrategy 529 | { 530 | LFS_HEURISTIC, /*official PNG heuristic*/ 531 | LFS_ZERO, /*every filter at zero*/ 532 | LFS_MINSUM, /*like the official PNG heuristic, but use minimal sum always, including palette and low bitdepth images*/ 533 | /* 534 | Brute-force-search PNG filters by compressing each filter for each scanline. 535 | This gives better compression, at the cost of being super slow. Experimental! 536 | If you enable this, also set zlibsettings.windowsize to 32768 and choose an 537 | optimal color mode for the PNG image for best compression. Default: 0 (false). 538 | */ 539 | LFS_BRUTE_FORCE, 540 | LFS_PREDEFINED /*use predefined_filters buffer: you specify the filter type for each scanline*/ 541 | } LodePNGFilterStrategy; 542 | 543 | /*automatically use color type with less bits per pixel if losslessly possible. Default: LAC_AUTO*/ 544 | typedef enum LodePNGAutoConvert 545 | { 546 | LAC_NO, /*use color type user requested*/ 547 | LAC_ALPHA, /*use color type user requested, but if only opaque pixels and RGBA or grey+alpha, use RGB or grey*/ 548 | LAC_AUTO, /*use PNG color type that can losslessly represent the uncompressed image the smallest possible*/ 549 | /* 550 | like AUTO, but do not choose 1, 2 or 4 bit per pixel types. 551 | sometimes a PNG image compresses worse if less than 8 bits per pixels. 552 | */ 553 | LAC_AUTO_NO_NIBBLES 554 | } LodePNGAutoConvert; 555 | 556 | 557 | /*Settings for the encoder.*/ 558 | typedef struct LodePNGEncoderSettings 559 | { 560 | LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ 561 | 562 | LodePNGAutoConvert auto_convert; /*how to automatically choose output PNG color type, if at all*/ 563 | 564 | LodePNGFilterStrategy filter_strategy; 565 | 566 | /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with 567 | the same length as the amount of scanlines in the image, and each value must <= 5. You 568 | have to cleanup this buffer, LodePNG will never free it.*/ 569 | unsigned char* predefined_filters; 570 | 571 | /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). 572 | If colortype is 3, PLTE is _always_ created.*/ 573 | unsigned force_palette; 574 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 575 | /*add LodePNG identifier and version as a text chunk, for debugging*/ 576 | unsigned add_id; 577 | /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ 578 | unsigned text_compression; 579 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ 580 | } LodePNGEncoderSettings; 581 | 582 | void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings); 583 | #endif /*LODEPNG_COMPILE_ENCODER*/ 584 | 585 | 586 | #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) 587 | /*The settings, state and information for extended encoding and decoding.*/ 588 | typedef struct LodePNGState 589 | { 590 | #ifdef LODEPNG_COMPILE_DECODER 591 | LodePNGDecoderSettings decoder; /*the decoding settings*/ 592 | #endif /*LODEPNG_COMPILE_DECODER*/ 593 | #ifdef LODEPNG_COMPILE_ENCODER 594 | LodePNGEncoderSettings encoder; /*the encoding settings*/ 595 | #endif /*LODEPNG_COMPILE_ENCODER*/ 596 | LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ 597 | LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ 598 | unsigned error; 599 | #ifdef LODEPNG_COMPILE_CPP 600 | //For the lodepng::State subclass. 601 | virtual ~LodePNGState(){} 602 | #endif 603 | } LodePNGState; 604 | 605 | /*init, cleanup and copy functions to use with this struct*/ 606 | void lodepng_state_init(LodePNGState* state); 607 | void lodepng_state_cleanup(LodePNGState* state); 608 | void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source); 609 | #endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ 610 | 611 | #ifdef LODEPNG_COMPILE_DECODER 612 | /* 613 | Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings and 614 | getting much more information about the PNG image and color mode. 615 | */ 616 | unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, 617 | LodePNGState* state, 618 | const unsigned char* in, size_t insize); 619 | 620 | /* 621 | Read the PNG header, but not the actual data. This returns only the information 622 | that is in the header chunk of the PNG, such as width, height and color type. The 623 | information is placed in the info_png field of the LodePNGState. 624 | */ 625 | unsigned lodepng_inspect(unsigned* w, unsigned* h, 626 | LodePNGState* state, 627 | const unsigned char* in, size_t insize); 628 | #endif /*LODEPNG_COMPILE_DECODER*/ 629 | 630 | 631 | #ifdef LODEPNG_COMPILE_ENCODER 632 | /*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/ 633 | unsigned lodepng_encode(unsigned char** out, size_t* outsize, 634 | const unsigned char* image, unsigned w, unsigned h, 635 | LodePNGState* state); 636 | #endif /*LODEPNG_COMPILE_ENCODER*/ 637 | 638 | /* 639 | The lodepng_chunk functions are normally not needed, except to traverse the 640 | unknown chunks stored in the LodePNGInfo struct, or add new ones to it. 641 | It also allows traversing the chunks of an encoded PNG file yourself. 642 | 643 | PNG standard chunk naming conventions: 644 | First byte: uppercase = critical, lowercase = ancillary 645 | Second byte: uppercase = public, lowercase = private 646 | Third byte: must be uppercase 647 | Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy 648 | */ 649 | 650 | /*get the length of the data of the chunk. Total chunk length has 12 bytes more.*/ 651 | unsigned lodepng_chunk_length(const unsigned char* chunk); 652 | 653 | /*puts the 4-byte type in null terminated string*/ 654 | void lodepng_chunk_type(char type[5], const unsigned char* chunk); 655 | 656 | /*check if the type is the given type*/ 657 | unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type); 658 | 659 | /*0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard)*/ 660 | unsigned char lodepng_chunk_ancillary(const unsigned char* chunk); 661 | 662 | /*0: public, 1: private (see PNG standard)*/ 663 | unsigned char lodepng_chunk_private(const unsigned char* chunk); 664 | 665 | /*0: the chunk is unsafe to copy, 1: the chunk is safe to copy (see PNG standard)*/ 666 | unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk); 667 | 668 | /*get pointer to the data of the chunk, where the input points to the header of the chunk*/ 669 | unsigned char* lodepng_chunk_data(unsigned char* chunk); 670 | const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk); 671 | 672 | /*returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!)*/ 673 | unsigned lodepng_chunk_check_crc(const unsigned char* chunk); 674 | 675 | /*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ 676 | void lodepng_chunk_generate_crc(unsigned char* chunk); 677 | 678 | /*iterate to next chunks. don't use on IEND chunk, as there is no next chunk then*/ 679 | unsigned char* lodepng_chunk_next(unsigned char* chunk); 680 | const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk); 681 | 682 | /* 683 | Appends chunk to the data in out. The given chunk should already have its chunk header. 684 | The out variable and outlength are updated to reflect the new reallocated buffer. 685 | Returns error code (0 if it went ok) 686 | */ 687 | unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk); 688 | 689 | /* 690 | Appends new chunk to out. The chunk to append is given by giving its length, type 691 | and data separately. The type is a 4-letter string. 692 | The out variable and outlength are updated to reflect the new reallocated buffer. 693 | Returne error code (0 if it went ok) 694 | */ 695 | unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, 696 | const char* type, const unsigned char* data); 697 | 698 | 699 | /*Calculate CRC32 of buffer*/ 700 | unsigned lodepng_crc32(const unsigned char* buf, size_t len); 701 | #endif /*LODEPNG_COMPILE_PNG*/ 702 | 703 | 704 | #ifdef LODEPNG_COMPILE_ZLIB 705 | /* 706 | This zlib part can be used independently to zlib compress and decompress a 707 | buffer. It cannot be used to create gzip files however, and it only supports the 708 | part of zlib that is required for PNG, it does not support dictionaries. 709 | */ 710 | 711 | #ifdef LODEPNG_COMPILE_DECODER 712 | /*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/ 713 | unsigned lodepng_inflate(unsigned char** out, size_t* outsize, 714 | const unsigned char* in, size_t insize, 715 | const LodePNGDecompressSettings* settings); 716 | 717 | /* 718 | Decompresses Zlib data. Reallocates the out buffer and appends the data. The 719 | data must be according to the zlib specification. 720 | Either, *out must be NULL and *outsize must be 0, or, *out must be a valid 721 | buffer and *outsize its size in bytes. out must be freed by user after usage. 722 | */ 723 | unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, 724 | const unsigned char* in, size_t insize, 725 | const LodePNGDecompressSettings* settings); 726 | #endif /*LODEPNG_COMPILE_DECODER*/ 727 | 728 | #ifdef LODEPNG_COMPILE_ENCODER 729 | /* 730 | Compresses data with Zlib. Reallocates the out buffer and appends the data. 731 | Zlib adds a small header and trailer around the deflate data. 732 | The data is output in the format of the zlib specification. 733 | Either, *out must be NULL and *outsize must be 0, or, *out must be a valid 734 | buffer and *outsize its size in bytes. out must be freed by user after usage. 735 | */ 736 | unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, 737 | const unsigned char* in, size_t insize, 738 | const LodePNGCompressSettings* settings); 739 | 740 | /* 741 | Find length-limited Huffman code for given frequencies. This function is in the 742 | public interface only for tests, it's used internally by lodepng_deflate. 743 | */ 744 | unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, 745 | size_t numcodes, unsigned maxbitlen); 746 | 747 | /*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/ 748 | unsigned lodepng_deflate(unsigned char** out, size_t* outsize, 749 | const unsigned char* in, size_t insize, 750 | const LodePNGCompressSettings* settings); 751 | 752 | #endif /*LODEPNG_COMPILE_ENCODER*/ 753 | #endif /*LODEPNG_COMPILE_ZLIB*/ 754 | 755 | #ifdef LODEPNG_COMPILE_DISK 756 | /* 757 | Load a file from disk into buffer. The function allocates the out buffer, and 758 | after usage you should free it. 759 | out: output parameter, contains pointer to loaded buffer. 760 | outsize: output parameter, size of the allocated out buffer 761 | filename: the path to the file to load 762 | return value: error code (0 means ok) 763 | */ 764 | unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename); 765 | 766 | /* 767 | Save a file from buffer to disk. Warning, if it exists, this function overwrites 768 | the file without warning! 769 | buffer: the buffer to write 770 | buffersize: size of the buffer to write 771 | filename: the path to the file to save to 772 | return value: error code (0 means ok) 773 | */ 774 | unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename); 775 | #endif /*LODEPNG_COMPILE_DISK*/ 776 | 777 | #ifdef LODEPNG_COMPILE_CPP 778 | //The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. 779 | namespace lodepng 780 | { 781 | #ifdef LODEPNG_COMPILE_PNG 782 | class State : public LodePNGState 783 | { 784 | public: 785 | State(); 786 | State(const State& other); 787 | virtual ~State(); 788 | State& operator=(const State& other); 789 | }; 790 | 791 | #ifdef LODEPNG_COMPILE_DECODER 792 | //Same as other lodepng::decode, but using a State for more settings and information. 793 | unsigned decode(std::vector& out, unsigned& w, unsigned& h, 794 | State& state, 795 | const unsigned char* in, size_t insize); 796 | unsigned decode(std::vector& out, unsigned& w, unsigned& h, 797 | State& state, 798 | const std::vector& in); 799 | #endif /*LODEPNG_COMPILE_DECODER*/ 800 | 801 | #ifdef LODEPNG_COMPILE_ENCODER 802 | //Same as other lodepng::encode, but using a State for more settings and information. 803 | unsigned encode(std::vector& out, 804 | const unsigned char* in, unsigned w, unsigned h, 805 | State& state); 806 | unsigned encode(std::vector& out, 807 | const std::vector& in, unsigned w, unsigned h, 808 | State& state); 809 | #endif /*LODEPNG_COMPILE_ENCODER*/ 810 | 811 | 812 | #ifdef LODEPNG_COMPILE_DISK 813 | /* 814 | Load a file from disk into an std::vector. If the vector is empty, then either 815 | the file doesn't exist or is an empty file. 816 | */ 817 | void load_file(std::vector& buffer, const std::string& filename); 818 | 819 | /* 820 | Save the binary data in an std::vector to a file on disk. The file is overwritten 821 | without warning. 822 | */ 823 | void save_file(const std::vector& buffer, const std::string& filename); 824 | #endif //LODEPNG_COMPILE_DISK 825 | #endif //LODEPNG_COMPILE_PNG 826 | 827 | #ifdef LODEPNG_COMPILE_ZLIB 828 | #ifdef LODEPNG_COMPILE_DECODER 829 | //Zlib-decompress an unsigned char buffer 830 | unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, 831 | const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); 832 | 833 | //Zlib-decompress an std::vector 834 | unsigned decompress(std::vector& out, const std::vector& in, 835 | const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); 836 | #endif //LODEPNG_COMPILE_DECODER 837 | 838 | #ifdef LODEPNG_COMPILE_ENCODER 839 | //Zlib-compress an unsigned char buffer 840 | unsigned compress(std::vector& out, const unsigned char* in, size_t insize, 841 | const LodePNGCompressSettings& settings = lodepng_default_compress_settings); 842 | 843 | //Zlib-compress an std::vector 844 | unsigned compress(std::vector& out, const std::vector& in, 845 | const LodePNGCompressSettings& settings = lodepng_default_compress_settings); 846 | #endif //LODEPNG_COMPILE_ENCODER 847 | #endif //LODEPNG_COMPILE_ZLIB 848 | } //namespace lodepng 849 | #endif /*LODEPNG_COMPILE_CPP*/ 850 | 851 | /* 852 | TODO: 853 | [.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often 854 | [.] check compatibility with vareous compilers - done but needs to be redone for every newer version 855 | [X] converting color to 16-bit per channel types 856 | [ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values) 857 | [ ] make sure encoder generates no chunks with size > (2^31)-1 858 | [ ] partial decoding (stream processing) 859 | [X] let the "isFullyOpaque" function check color keys and transparent palettes too 860 | [X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" 861 | [ ] don't stop decoding on errors like 69, 57, 58 (make warnings) 862 | [ ] make option to choose if the raw image with non multiple of 8 bits per scanline should have padding bits or not 863 | [ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes 864 | */ 865 | 866 | #endif /*LODEPNG_H inclusion guard*/ 867 | 868 | /* 869 | LodePNG Documentation 870 | --------------------- 871 | 872 | 0. table of contents 873 | -------------------- 874 | 875 | 1. about 876 | 1.1. supported features 877 | 1.2. features not supported 878 | 2. C and C++ version 879 | 3. security 880 | 4. decoding 881 | 5. encoding 882 | 6. color conversions 883 | 6.1. PNG color types 884 | 6.2. color conversions 885 | 6.3. padding bits 886 | 7. error values 887 | 8. chunks and PNG editing 888 | 9. compiler support 889 | 10. examples 890 | 10.1. decoder C++ example 891 | 10.2. decoder C example 892 | 11. changes 893 | 12. contact information 894 | 895 | 896 | 1. about 897 | -------- 898 | 899 | PNG is a file format to store raster images losslessly with good compression, 900 | supporting different color types and alpha channel. 901 | 902 | LodePNG is a PNG codec according to the Portable Network Graphics (PNG) 903 | Specification (Second Edition) - W3C Recommendation 10 November 2003. 904 | 905 | The specifications used are: 906 | 907 | *) Portable Network Graphics (PNG) Specification (Second Edition): 908 | http://www.w3.org/TR/2003/REC-PNG-20031110 909 | *) RFC 1950 ZLIB Compressed Data Format version 3.3: 910 | http://www.gzip.org/zlib/rfc-zlib.html 911 | *) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3: 912 | http://www.gzip.org/zlib/rfc-deflate.html 913 | 914 | The most recent version of LodePNG can currently be found at 915 | http://lodev.org/lodepng/ 916 | 917 | LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds 918 | extra functionality. 919 | 920 | LodePNG exists out of two files: 921 | -lodepng.h: the header file for both C and C++ 922 | -lodepng.c(pp): give it the name lodepng.c or lodepng.cpp (or .cc) depending on your usage 923 | 924 | If you want to start using LodePNG right away without reading this doc, get the 925 | examples from the LodePNG website to see how to use it in code, or check the 926 | smaller examples in chapter 13 here. 927 | 928 | LodePNG is simple but only supports the basic requirements. To achieve 929 | simplicity, the following design choices were made: There are no dependencies 930 | on any external library. There are functions to decode and encode a PNG with 931 | a single function call, and extended versions of these functions taking a 932 | LodePNGState struct allowing to specify or get more information. By default 933 | the colors of the raw image are always RGB or RGBA, no matter what color type 934 | the PNG file uses. To read and write files, there are simple functions to 935 | convert the files to/from buffers in memory. 936 | 937 | This all makes LodePNG suitable for loading textures in games, demos and small 938 | programs, ... It's less suitable for full fledged image editors, loading PNGs 939 | over network (it requires all the image data to be available before decoding can 940 | begin), life-critical systems, ... 941 | 942 | 1.1. supported features 943 | ----------------------- 944 | 945 | The following features are supported by the decoder: 946 | 947 | *) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image, 948 | or the same color type as the PNG 949 | *) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image 950 | *) Adam7 interlace and deinterlace for any color type 951 | *) loading the image from harddisk or decoding it from a buffer from other sources than harddisk 952 | *) support for alpha channels, including RGBA color model, translucent palettes and color keying 953 | *) zlib decompression (inflate) 954 | *) zlib compression (deflate) 955 | *) CRC32 and ADLER32 checksums 956 | *) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks. 957 | *) the following chunks are supported (generated/interpreted) by both encoder and decoder: 958 | IHDR: header information 959 | PLTE: color palette 960 | IDAT: pixel data 961 | IEND: the final chunk 962 | tRNS: transparency for palettized images 963 | tEXt: textual information 964 | zTXt: compressed textual information 965 | iTXt: international textual information 966 | bKGD: suggested background color 967 | pHYs: physical dimensions 968 | tIME: modification time 969 | 970 | 1.2. features not supported 971 | --------------------------- 972 | 973 | The following features are _not_ supported: 974 | 975 | *) some features needed to make a conformant PNG-Editor might be still missing. 976 | *) partial loading/stream processing. All data must be available and is processed in one call. 977 | *) The following public chunks are not supported but treated as unknown chunks by LodePNG 978 | cHRM, gAMA, iCCP, sRGB, sBIT, hIST, sPLT 979 | Some of these are not supported on purpose: LodePNG wants to provide the RGB values 980 | stored in the pixels, not values modified by system dependent gamma or color models. 981 | 982 | 983 | 2. C and C++ version 984 | -------------------- 985 | 986 | The C version uses buffers allocated with alloc that you need to free() 987 | yourself. You need to use init and cleanup functions for each struct whenever 988 | using a struct from the C version to avoid exploits and memory leaks. 989 | 990 | The C++ version has extra functions with std::vectors in the interface and the 991 | lodepng::State class which is a LodePNGState with constructor and destructor. 992 | 993 | These files work without modification for both C and C++ compilers because all 994 | the additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers 995 | ignore it, and the C code is made to compile both with strict ISO C90 and C++. 996 | 997 | To use the C++ version, you need to rename the source file to lodepng.cpp 998 | (instead of lodepng.c), and compile it with a C++ compiler. 999 | 1000 | To use the C version, you need to rename the source file to lodepng.c (instead 1001 | of lodepng.cpp), and compile it with a C compiler. 1002 | 1003 | 1004 | 3. Security 1005 | ----------- 1006 | 1007 | Even if carefully designed, it's always possible that LodePNG contains possible 1008 | exploits. If you discover one, please let me know, and it will be fixed. 1009 | 1010 | When using LodePNG, care has to be taken with the C version of LodePNG, as well 1011 | as the C-style structs when working with C++. The following conventions are used 1012 | for all C-style structs: 1013 | 1014 | -if a struct has a corresponding init function, always call the init function when making a new one 1015 | -if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks 1016 | -if a struct has a corresponding copy function, use the copy function instead of "=". 1017 | The destination must also be inited already. 1018 | 1019 | 1020 | 4. Decoding 1021 | ----------- 1022 | 1023 | Decoding converts a PNG compressed image to a raw pixel buffer. 1024 | 1025 | Most documentation on using the decoder is at its declarations in the header 1026 | above. For C, simple decoding can be done with functions such as 1027 | lodepng_decode32, and more advanced decoding can be done with the struct 1028 | LodePNGState and lodepng_decode. For C++, all decoding can be done with the 1029 | various lodepng::decode functions, and lodepng::State can be used for advanced 1030 | features. 1031 | 1032 | When using the LodePNGState, it uses the following fields for decoding: 1033 | *) LodePNGInfo info_png: it stores extra information about the PNG (the input) in here 1034 | *) LodePNGColorMode info_raw: here you can say what color mode of the raw image (the output) you want to get 1035 | *) LodePNGDecoderSettings decoder: you can specify a few extra settings for the decoder to use 1036 | 1037 | LodePNGInfo info_png 1038 | -------------------- 1039 | 1040 | After decoding, this contains extra information of the PNG image, except the actual 1041 | pixels, width and height because these are already gotten directly from the decoder 1042 | functions. 1043 | 1044 | It contains for example the original color type of the PNG image, text comments, 1045 | suggested background color, etc... More details about the LodePNGInfo struct are 1046 | at its declaration documentation. 1047 | 1048 | LodePNGColorMode info_raw 1049 | ------------------------- 1050 | 1051 | When decoding, here you can specify which color type you want 1052 | the resulting raw image to be. If this is different from the colortype of the 1053 | PNG, then the decoder will automatically convert the result. This conversion 1054 | always works, except if you want it to convert a color PNG to greyscale or to 1055 | a palette with missing colors. 1056 | 1057 | By default, 32-bit color is used for the result. 1058 | 1059 | LodePNGDecoderSettings decoder 1060 | ------------------------------ 1061 | 1062 | The settings can be used to ignore the errors created by invalid CRC and Adler32 1063 | chunks, and to disable the decoding of tEXt chunks. 1064 | 1065 | There's also a setting color_convert, true by default. If false, no conversion 1066 | is done, the resulting data will be as it was in the PNG (after decompression) 1067 | and you'll have to puzzle the colors of the pixels together yourself using the 1068 | color type information in the LodePNGInfo. 1069 | 1070 | 1071 | 5. Encoding 1072 | ----------- 1073 | 1074 | Encoding converts a raw pixel buffer to a PNG compressed image. 1075 | 1076 | Most documentation on using the encoder is at its declarations in the header 1077 | above. For C, simple encoding can be done with functions such as 1078 | lodepng_encode32, and more advanced decoding can be done with the struct 1079 | LodePNGState and lodepng_encode. For C++, all encoding can be done with the 1080 | various lodepng::encode functions, and lodepng::State can be used for advanced 1081 | features. 1082 | 1083 | Like the decoder, the encoder can also give errors. However it gives less errors 1084 | since the encoder input is trusted, the decoder input (a PNG image that could 1085 | be forged by anyone) is not trusted. 1086 | 1087 | When using the LodePNGState, it uses the following fields for encoding: 1088 | *) LodePNGInfo info_png: here you specify how you want the PNG (the output) to be. 1089 | *) LodePNGColorMode info_raw: here you say what color type of the raw image (the input) has 1090 | *) LodePNGEncoderSettings encoder: you can specify a few settings for the encoder to use 1091 | 1092 | LodePNGInfo info_png 1093 | -------------------- 1094 | 1095 | When encoding, you use this the opposite way as when decoding: for encoding, 1096 | you fill in the values you want the PNG to have before encoding. By default it's 1097 | not needed to specify a color type for the PNG since it's automatically chosen, 1098 | but it's possible to choose it yourself given the right settings. 1099 | 1100 | The encoder will not always exactly match the LodePNGInfo struct you give, 1101 | it tries as close as possible. Some things are ignored by the encoder. The 1102 | encoder uses, for example, the following settings from it when applicable: 1103 | colortype and bitdepth, text chunks, time chunk, the color key, the palette, the 1104 | background color, the interlace method, unknown chunks, ... 1105 | 1106 | When encoding to a PNG with colortype 3, the encoder will generate a PLTE chunk. 1107 | If the palette contains any colors for which the alpha channel is not 255 (so 1108 | there are translucent colors in the palette), it'll add a tRNS chunk. 1109 | 1110 | LodePNGColorMode info_raw 1111 | ------------------------- 1112 | 1113 | You specify the color type of the raw image that you give to the input here, 1114 | including a possible transparent color key and palette you happen to be using in 1115 | your raw image data. 1116 | 1117 | By default, 32-bit color is assumed, meaning your input has to be in RGBA 1118 | format with 4 bytes (unsigned chars) per pixel. 1119 | 1120 | LodePNGEncoderSettings encoder 1121 | ------------------------------ 1122 | 1123 | The following settings are supported (some are in sub-structs): 1124 | *) auto_convert: when this option is enabled, the encoder will 1125 | automatically choose the smallest possible color mode (including color key) that 1126 | can encode the colors of all pixels without information loss. 1127 | *) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree, 1128 | 2 = dynamic huffman tree (best compression). Should be 2 for proper 1129 | compression. 1130 | *) use_lz77: whether or not to use LZ77 for compressed block types. Should be 1131 | true for proper compression. 1132 | *) windowsize: the window size used by the LZ77 encoder (1 - 32768). Has value 1133 | 2048 by default, but can be set to 32768 for better, but slow, compression. 1134 | *) force_palette: if colortype is 2 or 6, you can make the encoder write a PLTE 1135 | chunk if force_palette is true. This can used as suggested palette to convert 1136 | to by viewers that don't support more than 256 colors (if those still exist) 1137 | *) add_id: add text chunk "Encoder: LodePNG " to the image. 1138 | *) text_compression: default 1. If 1, it'll store texts as zTXt instead of tEXt chunks. 1139 | zTXt chunks use zlib compression on the text. This gives a smaller result on 1140 | large texts but a larger result on small texts (such as a single program name). 1141 | It's all tEXt or all zTXt though, there's no separate setting per text yet. 1142 | 1143 | 1144 | 6. color conversions 1145 | -------------------- 1146 | 1147 | An important thing to note about LodePNG, is that the color type of the PNG, and 1148 | the color type of the raw image, are completely independent. By default, when 1149 | you decode a PNG, you get the result as a raw image in the color type you want, 1150 | no matter whether the PNG was encoded with a palette, greyscale or RGBA color. 1151 | And if you encode an image, by default LodePNG will automatically choose the PNG 1152 | color type that gives good compression based on the values of colors and amount 1153 | of colors in the image. It can be configured to let you control it instead as 1154 | well, though. 1155 | 1156 | To be able to do this, LodePNG does conversions from one color mode to another. 1157 | It can convert from almost any color type to any other color type, except the 1158 | following conversions: RGB to greyscale is not supported, and converting to a 1159 | palette when the palette doesn't have a required color is not supported. This is 1160 | not supported on purpose: this is information loss which requires a color 1161 | reduction algorithm that is beyong the scope of a PNG encoder (yes, RGB to grey 1162 | is easy, but there are multiple ways if you want to give some channels more 1163 | weight). 1164 | 1165 | By default, when decoding, you get the raw image in 32-bit RGBA or 24-bit RGB 1166 | color, no matter what color type the PNG has. And by default when encoding, 1167 | LodePNG automatically picks the best color model for the output PNG, and expects 1168 | the input image to be 32-bit RGBA or 24-bit RGB. So, unless you want to control 1169 | the color format of the images yourself, you can skip this chapter. 1170 | 1171 | 6.1. PNG color types 1172 | -------------------- 1173 | 1174 | A PNG image can have many color types, ranging from 1-bit color to 64-bit color, 1175 | as well as palettized color modes. After the zlib decompression and unfiltering 1176 | in the PNG image is done, the raw pixel data will have that color type and thus 1177 | a certain amount of bits per pixel. If you want the output raw image after 1178 | decoding to have another color type, a conversion is done by LodePNG. 1179 | 1180 | The PNG specification gives the following color types: 1181 | 1182 | 0: greyscale, bit depths 1, 2, 4, 8, 16 1183 | 2: RGB, bit depths 8 and 16 1184 | 3: palette, bit depths 1, 2, 4 and 8 1185 | 4: greyscale with alpha, bit depths 8 and 16 1186 | 6: RGBA, bit depths 8 and 16 1187 | 1188 | Bit depth is the amount of bits per pixel per color channel. So the total amount 1189 | of bits per pixel is: amount of channels * bitdepth. 1190 | 1191 | 6.2. color conversions 1192 | ---------------------- 1193 | 1194 | As explained in the sections about the encoder and decoder, you can specify 1195 | color types and bit depths in info_png and info_raw to change the default 1196 | behaviour. 1197 | 1198 | If, when decoding, you want the raw image to be something else than the default, 1199 | you need to set the color type and bit depth you want in the LodePNGColorMode, 1200 | or the parameters of the simple function of LodePNG you're using. 1201 | 1202 | If, when encoding, you use another color type than the default in the input 1203 | image, you need to specify its color type and bit depth in the LodePNGColorMode 1204 | of the raw image, or use the parameters of the simplefunction of LodePNG you're 1205 | using. 1206 | 1207 | If, when encoding, you don't want LodePNG to choose the output PNG color type 1208 | but control it yourself, you need to set auto_convert in the encoder settings 1209 | to LAC_NONE, and specify the color type you want in the LodePNGInfo of the 1210 | encoder. 1211 | 1212 | If you do any of the above, LodePNG may need to do a color conversion, which 1213 | follows the rules below, and may sometimes not be allowed. 1214 | 1215 | To avoid some confusion: 1216 | -the decoder converts from PNG to raw image 1217 | -the encoder converts from raw image to PNG 1218 | -the colortype and bitdepth in LodePNGColorMode info_raw, are those of the raw image 1219 | -the colortype and bitdepth in the color field of LodePNGInfo info_png, are those of the PNG 1220 | -when encoding, the color type in LodePNGInfo is ignored if auto_convert 1221 | is enabled, it is automatically generated instead 1222 | -when decoding, the color type in LodePNGInfo is set by the decoder to that of the original 1223 | PNG image, but it can be ignored since the raw image has the color type you requested instead 1224 | -if the color type of the LodePNGColorMode and PNG image aren't the same, a conversion 1225 | between the color types is done if the color types are supported. If it is not 1226 | supported, an error is returned. If the types are the same, no conversion is done. 1227 | -even though some conversions aren't supported, LodePNG supports loading PNGs from any 1228 | colortype and saving PNGs to any colortype, sometimes it just requires preparing 1229 | the raw image correctly before encoding. 1230 | -both encoder and decoder use the same color converter. 1231 | 1232 | Non supported color conversions: 1233 | -color to greyscale: no error is thrown, but the result will look ugly because 1234 | only the red channel is taken 1235 | -anything, to palette when that palette does not have that color in it: in this 1236 | case an error is thrown 1237 | 1238 | Supported color conversions: 1239 | -anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA 1240 | -any grey or grey+alpha, to grey or grey+alpha 1241 | -anything to a palette, as long as the palette has the requested colors in it 1242 | -removing alpha channel 1243 | -higher to smaller bitdepth, and vice versa 1244 | 1245 | If you want no color conversion to be done: 1246 | -In the encoder, you can make it save a PNG with any color type by giving the 1247 | raw color mode and LodePNGInfo the same color mode, and setting auto_convert to 1248 | LAC_NO. 1249 | -In the decoder, you can make it store the pixel data in the same color type 1250 | as the PNG has, by setting the color_convert setting to false. Settings in 1251 | info_raw are then ignored. 1252 | 1253 | The function lodepng_convert does the color conversion. It is available in the 1254 | interface but normally isn't needed since the encoder and decoder already call 1255 | it. 1256 | 1257 | 6.3. padding bits 1258 | ----------------- 1259 | 1260 | In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines 1261 | have a bit amount that isn't a multiple of 8, then padding bits are used so that each 1262 | scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output. 1263 | The raw input image you give to the encoder, and the raw output image you get from the decoder 1264 | will NOT have these padding bits, e.g. in the case of a 1-bit image with a width 1265 | of 7 pixels, the first pixel of the second scanline will the the 8th bit of the first byte, 1266 | not the first bit of a new byte. 1267 | 1268 | 1269 | 7. error values 1270 | --------------- 1271 | 1272 | All functions in LodePNG that return an error code, return 0 if everything went 1273 | OK, or a non-zero code if there was an error. 1274 | 1275 | The meaning of the LodePNG error values can be retrieved with the function 1276 | lodepng_error_text: given the numerical error code, it returns a description 1277 | of the error in English as a string. 1278 | 1279 | Check the implementation of lodepng_error_text to see the meaning of each code. 1280 | 1281 | 1282 | 8. chunks and PNG editing 1283 | ------------------------- 1284 | 1285 | If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG 1286 | editor that should follow the rules about handling of unknown chunks, or if your 1287 | program is able to read other types of chunks than the ones handled by LodePNG, 1288 | then that's possible with the chunk functions of LodePNG. 1289 | 1290 | A PNG chunk has the following layout: 1291 | 1292 | 4 bytes length 1293 | 4 bytes type name 1294 | length bytes data 1295 | 4 bytes CRC 1296 | 1297 | 8.1. iterating through chunks 1298 | ----------------------------- 1299 | 1300 | If you have a buffer containing the PNG image data, then the first chunk (the 1301 | IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the 1302 | signature of the PNG and are not part of a chunk. But if you start at byte 8 1303 | then you have a chunk, and can check the following things of it. 1304 | 1305 | NOTE: none of these functions check for memory buffer boundaries. To avoid 1306 | exploits, always make sure the buffer contains all the data of the chunks. 1307 | When using lodepng_chunk_next, make sure the returned value is within the 1308 | allocated memory. 1309 | 1310 | unsigned lodepng_chunk_length(const unsigned char* chunk): 1311 | 1312 | Get the length of the chunk's data. The total chunk length is this length + 12. 1313 | 1314 | void lodepng_chunk_type(char type[5], const unsigned char* chunk): 1315 | unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type): 1316 | 1317 | Get the type of the chunk or compare if it's a certain type 1318 | 1319 | unsigned char lodepng_chunk_critical(const unsigned char* chunk): 1320 | unsigned char lodepng_chunk_private(const unsigned char* chunk): 1321 | unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk): 1322 | 1323 | Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are). 1324 | Check if the chunk is private (public chunks are part of the standard, private ones not). 1325 | Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical 1326 | chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your 1327 | program doesn't handle that type of unknown chunk. 1328 | 1329 | unsigned char* lodepng_chunk_data(unsigned char* chunk): 1330 | const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk): 1331 | 1332 | Get a pointer to the start of the data of the chunk. 1333 | 1334 | unsigned lodepng_chunk_check_crc(const unsigned char* chunk): 1335 | void lodepng_chunk_generate_crc(unsigned char* chunk): 1336 | 1337 | Check if the crc is correct or generate a correct one. 1338 | 1339 | unsigned char* lodepng_chunk_next(unsigned char* chunk): 1340 | const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk): 1341 | 1342 | Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these 1343 | functions do no boundary checking of the allocated data whatsoever, so make sure there is enough 1344 | data available in the buffer to be able to go to the next chunk. 1345 | 1346 | unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk): 1347 | unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, 1348 | const char* type, const unsigned char* data): 1349 | 1350 | These functions are used to create new chunks that are appended to the data in *out that has 1351 | length *outlength. The append function appends an existing chunk to the new data. The create 1352 | function creates a new chunk with the given parameters and appends it. Type is the 4-letter 1353 | name of the chunk. 1354 | 1355 | 8.2. chunks in info_png 1356 | ----------------------- 1357 | 1358 | The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3 1359 | buffers (each with size) to contain 3 types of unknown chunks: 1360 | the ones that come before the PLTE chunk, the ones that come between the PLTE 1361 | and the IDAT chunks, and the ones that come after the IDAT chunks. 1362 | It's necessary to make the distionction between these 3 cases because the PNG 1363 | standard forces to keep the ordering of unknown chunks compared to the critical 1364 | chunks, but does not force any other ordering rules. 1365 | 1366 | info_png.unknown_chunks_data[0] is the chunks before PLTE 1367 | info_png.unknown_chunks_data[1] is the chunks after PLTE, before IDAT 1368 | info_png.unknown_chunks_data[2] is the chunks after IDAT 1369 | 1370 | The chunks in these 3 buffers can be iterated through and read by using the same 1371 | way described in the previous subchapter. 1372 | 1373 | When using the decoder to decode a PNG, you can make it store all unknown chunks 1374 | if you set the option settings.remember_unknown_chunks to 1. By default, this 1375 | option is off (0). 1376 | 1377 | The encoder will always encode unknown chunks that are stored in the info_png. 1378 | If you need it to add a particular chunk that isn't known by LodePNG, you can 1379 | use lodepng_chunk_append or lodepng_chunk_create to the chunk data in 1380 | info_png.unknown_chunks_data[x]. 1381 | 1382 | Chunks that are known by LodePNG should not be added in that way. E.g. to make 1383 | LodePNG add a bKGD chunk, set background_defined to true and add the correct 1384 | parameters there instead. 1385 | 1386 | 1387 | 9. compiler support 1388 | ------------------- 1389 | 1390 | No libraries other than the current standard C library are needed to compile 1391 | LodePNG. For the C++ version, only the standard C++ library is needed on top. 1392 | Add the files lodepng.c(pp) and lodepng.h to your project, include 1393 | lodepng.h where needed, and your program can read/write PNG files. 1394 | 1395 | If performance is important, use optimization when compiling! For both the 1396 | encoder and decoder, this makes a large difference. 1397 | 1398 | Make sure that LodePNG is compiled with the same compiler of the same version 1399 | and with the same settings as the rest of the program, or the interfaces with 1400 | std::vectors and std::strings in C++ can be incompatible. 1401 | 1402 | CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets. 1403 | 1404 | *) gcc and g++ 1405 | 1406 | LodePNG is developed in gcc so this compiler is natively supported. It gives no 1407 | warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++ 1408 | version 4.7.0 on Linux. 1409 | 1410 | *) Mingw 1411 | 1412 | The Mingw compiler (a port of gcc) for Windows is fully supported by LodePNG. 1413 | 1414 | *) Visual Studio 2005 and Visual C++ 2005 Express Edition 1415 | 1416 | Versions 20070604 up to 20080107 have been tested on VS2005 and work. Visual 1417 | studio may give warnings about 'fopen' being deprecated. A multiplatform library 1418 | can't support the proposed Visual Studio alternative however. 1419 | 1420 | If you're using LodePNG in VS2005 and don't want to see the deprecated warnings, 1421 | put this on top of lodepng.h before the inclusions: 1422 | #define _CRT_SECURE_NO_DEPRECATE 1423 | 1424 | Visual Studio may want "stdafx.h" files to be included in each source file. That 1425 | is not standard C++ and will not be added to the stock LodePNG. Try to find a 1426 | setting to disable it for this source file. 1427 | 1428 | *) Visual Studio 6.0 1429 | 1430 | LodePNG support for Visual Studio 6.0 is not guaranteed because VS6 doesn't 1431 | follow the C++ standard correctly. 1432 | 1433 | *) Comeau C/C++ 1434 | 1435 | Vesion 20070107 compiles without problems on the Comeau C/C++ Online Test Drive 1436 | at http://www.comeaucomputing.com/tryitout in both C90 and C++ mode. 1437 | 1438 | *) Compilers on Macintosh 1439 | 1440 | LodePNG has been reported to work both with the gcc and LLVM for Macintosh, both 1441 | for C and C++. 1442 | 1443 | *) Other Compilers 1444 | 1445 | If you encounter problems on other compilers, feel free to let me know and I may 1446 | try to fix it if the compiler is modern standards complient. 1447 | 1448 | 1449 | 10. examples 1450 | ------------ 1451 | 1452 | This decoder example shows the most basic usage of LodePNG. More complex 1453 | examples can be found on the LodePNG website. 1454 | 1455 | 10.1. decoder C++ example 1456 | ------------------------- 1457 | 1458 | #include "lodepng.h" 1459 | #include 1460 | 1461 | int main(int argc, char *argv[]) 1462 | { 1463 | const char* filename = argc > 1 ? argv[1] : "test.png"; 1464 | 1465 | //load and decode 1466 | std::vector image; 1467 | unsigned width, height; 1468 | unsigned error = lodepng::decode(image, width, height, filename); 1469 | 1470 | //if there's an error, display it 1471 | if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; 1472 | 1473 | //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... 1474 | } 1475 | 1476 | 10.2. decoder C example 1477 | ----------------------- 1478 | 1479 | #include "lodepng.h" 1480 | 1481 | int main(int argc, char *argv[]) 1482 | { 1483 | unsigned error; 1484 | unsigned char* image; 1485 | size_t width, height; 1486 | const char* filename = argc > 1 ? argv[1] : "test.png"; 1487 | 1488 | error = lodepng_decode32_file(&image, &width, &height, filename); 1489 | 1490 | if(error) printf("decoder error %u: %s\n", error, lodepng_error_text(error)); 1491 | 1492 | / * use image here * / 1493 | 1494 | free(image); 1495 | return 0; 1496 | } 1497 | 1498 | 1499 | 11. changes 1500 | ----------- 1501 | 1502 | The version number of LodePNG is the date of the change given in the format 1503 | yyyymmdd. 1504 | 1505 | Some changes aren't backwards compatible. Those are indicated with a (!) 1506 | symbol. 1507 | 1508 | *) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc 1509 | and free functions and toggle #defines from compiler flags. Small fixes. 1510 | *) 6 may 2012 (!): Made plugging in custom zlib/deflate functions more flexible. 1511 | *) 22 apr 2012 (!): Made interface more consistent, renaming a lot. Removed 1512 | redundant C++ codec classes. Reduced amount of structs. Everything changed, 1513 | but it is cleaner now imho and functionality remains the same. Also fixed 1514 | several bugs and shrinked the implementation code. Made new samples. 1515 | *) 6 nov 2011 (!): By default, the encoder now automatically chooses the best 1516 | PNG color model and bit depth, based on the amount and type of colors of the 1517 | raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color. 1518 | *) 9 okt 2011: simpler hash chain implementation for the encoder. 1519 | *) 8 sep 2011: lz77 encoder lazy matching instead of greedy matching. 1520 | *) 23 aug 2011: tweaked the zlib compression parameters after benchmarking. 1521 | A bug with the PNG filtertype heuristic was fixed, so that it chooses much 1522 | better ones (it's quite significant). A setting to do an experimental, slow, 1523 | brute force search for PNG filter types is added. 1524 | *) 17 aug 2011 (!): changed some C zlib related function names. 1525 | *) 16 aug 2011: made the code less wide (max 120 characters per line). 1526 | *) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors. 1527 | *) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled. 1528 | *) 11 dec 2010: encoding is made faster, based on suggestion by Peter Eastman 1529 | to optimize long sequences of zeros. 1530 | *) 13 nov 2010: added LodePNG_InfoColor_hasPaletteAlpha and 1531 | LodePNG_InfoColor_canHaveAlpha functions for convenience. 1532 | *) 7 nov 2010: added LodePNG_error_text function to get error code description. 1533 | *) 30 okt 2010: made decoding slightly faster 1534 | *) 26 okt 2010: (!) changed some C function and struct names (more consistent). 1535 | Reorganized the documentation and the declaration order in the header. 1536 | *) 08 aug 2010: only changed some comments and external samples. 1537 | *) 05 jul 2010: fixed bug thanks to warnings in the new gcc version. 1538 | *) 14 mar 2010: fixed bug where too much memory was allocated for char buffers. 1539 | *) 02 sep 2008: fixed bug where it could create empty tree that linux apps could 1540 | read by ignoring the problem but windows apps couldn't. 1541 | *) 06 jun 2008: added more error checks for out of memory cases. 1542 | *) 26 apr 2008: added a few more checks here and there to ensure more safety. 1543 | *) 06 mar 2008: crash with encoding of strings fixed 1544 | *) 02 feb 2008: support for international text chunks added (iTXt) 1545 | *) 23 jan 2008: small cleanups, and #defines to divide code in sections 1546 | *) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor. 1547 | *) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder. 1548 | *) 17 jan 2008: ability to encode and decode compressed zTXt chunks added 1549 | Also vareous fixes, such as in the deflate and the padding bits code. 1550 | *) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved 1551 | filtering code of encoder. 1552 | *) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A 1553 | C++ wrapper around this provides an interface almost identical to before. 1554 | Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code 1555 | are together in these files but it works both for C and C++ compilers. 1556 | *) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks 1557 | *) 30 aug 2007: bug fixed which makes this Borland C++ compatible 1558 | *) 09 aug 2007: some VS2005 warnings removed again 1559 | *) 21 jul 2007: deflate code placed in new namespace separate from zlib code 1560 | *) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images 1561 | *) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing 1562 | invalid std::vector element [0] fixed, and level 3 and 4 warnings removed 1563 | *) 02 jun 2007: made the encoder add a tag with version by default 1564 | *) 27 may 2007: zlib and png code separated (but still in the same file), 1565 | simple encoder/decoder functions added for more simple usage cases 1566 | *) 19 may 2007: minor fixes, some code cleaning, new error added (error 69), 1567 | moved some examples from here to lodepng_examples.cpp 1568 | *) 12 may 2007: palette decoding bug fixed 1569 | *) 24 apr 2007: changed the license from BSD to the zlib license 1570 | *) 11 mar 2007: very simple addition: ability to encode bKGD chunks. 1571 | *) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding 1572 | palettized PNG images. Plus little interface change with palette and texts. 1573 | *) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes. 1574 | Fixed a bug where the end code of a block had length 0 in the Huffman tree. 1575 | *) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented 1576 | and supported by the encoder, resulting in smaller PNGs at the output. 1577 | *) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone. 1578 | *) 24 jan 2007: gave encoder an error interface. Added color conversion from any 1579 | greyscale type to 8-bit greyscale with or without alpha. 1580 | *) 21 jan 2007: (!) Totally changed the interface. It allows more color types 1581 | to convert to and is more uniform. See the manual for how it works now. 1582 | *) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days: 1583 | encode/decode custom tEXt chunks, separate classes for zlib & deflate, and 1584 | at last made the decoder give errors for incorrect Adler32 or Crc. 1585 | *) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel. 1586 | *) 29 dec 2006: Added support for encoding images without alpha channel, and 1587 | cleaned out code as well as making certain parts faster. 1588 | *) 28 dec 2006: Added "Settings" to the encoder. 1589 | *) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now. 1590 | Removed some code duplication in the decoder. Fixed little bug in an example. 1591 | *) 09 dec 2006: (!) Placed output parameters of public functions as first parameter. 1592 | Fixed a bug of the decoder with 16-bit per color. 1593 | *) 15 okt 2006: Changed documentation structure 1594 | *) 09 okt 2006: Encoder class added. It encodes a valid PNG image from the 1595 | given image buffer, however for now it's not compressed. 1596 | *) 08 sep 2006: (!) Changed to interface with a Decoder class 1597 | *) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different 1598 | way. Renamed decodePNG to decodePNGGeneric. 1599 | *) 29 jul 2006: (!) Changed the interface: image info is now returned as a 1600 | struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy. 1601 | *) 28 jul 2006: Cleaned the code and added new error checks. 1602 | Corrected terminology "deflate" into "inflate". 1603 | *) 23 jun 2006: Added SDL example in the documentation in the header, this 1604 | example allows easy debugging by displaying the PNG and its transparency. 1605 | *) 22 jun 2006: (!) Changed way to obtain error value. Added 1606 | loadFile function for convenience. Made decodePNG32 faster. 1607 | *) 21 jun 2006: (!) Changed type of info vector to unsigned. 1608 | Changed position of palette in info vector. Fixed an important bug that 1609 | happened on PNGs with an uncompressed block. 1610 | *) 16 jun 2006: Internally changed unsigned into unsigned where 1611 | needed, and performed some optimizations. 1612 | *) 07 jun 2006: (!) Renamed functions to decodePNG and placed them 1613 | in LodePNG namespace. Changed the order of the parameters. Rewrote the 1614 | documentation in the header. Renamed files to lodepng.cpp and lodepng.h 1615 | *) 22 apr 2006: Optimized and improved some code 1616 | *) 07 sep 2005: (!) Changed to std::vector interface 1617 | *) 12 aug 2005: Initial release (C++, decoder only) 1618 | 1619 | 1620 | 12. contact information 1621 | ----------------------- 1622 | 1623 | Feel free to contact me with suggestions, problems, comments, ... concerning 1624 | LodePNG. If you encounter a PNG image that doesn't work properly with this 1625 | decoder, feel free to send it and I'll use it to find and fix the problem. 1626 | 1627 | My email address is (puzzle the account and domain together with an @ symbol): 1628 | Domain: gmail dot com. 1629 | Account: lode dot vandevenne. 1630 | 1631 | 1632 | Copyright (c) 2005-2012 Lode Vandevenne 1633 | */ --------------------------------------------------------------------------------