- Operating System: Windows 10 or later (64-bit)
- Processor: x86-64 CPU with SSE2 support
- Memory: 8 GB RAM minimum, 16 GB recommended
- Graphics: Graphics card supporting OpenGL 3.3 or later
- Storage: 2 GB available space
- Visual Studio 2022: Community Edition or higher
- C++ CMake tools for Visual Studio
- Windows 10/11 SDK
- CMake: Version 3.16.0 or later
- Git: For version control
- Visual Studio Code: With C++ and CMake extensions
- GitKraken: Git GUI client (optional)
- Notepad++: Advanced text editor (optional)
- Download Visual Studio 2022 Community from visualstudio.microsoft.com
- Run the installer and select the "Desktop development with C++" workload
- Ensure the following components are selected:
- MSVC v143 - VS 2022 C++ x64/x86 build tools
- Windows 10/11 SDK
- C++ CMake tools for Visual Studio
- Download CMake from cmake.org
- Run the installer and follow the setup wizard
- Ensure CMake is added to your system PATH
- Open Command Prompt or PowerShell
- Navigate to your desired development directory
- Clone the repository:
git clone https://github.com/yourusername/Pyramid.git
cd Pyramid- Open Visual Studio 2022
- Select "Open a local folder"
- Navigate to and select the Pyramid directory
- Visual Studio will automatically detect the CMakeLists.txt and configure the project
- Wait for CMake generation to complete
- In the toolbar, select the desired configuration (Debug, Release, RelWithDebInfo)
- Build the solution by pressing Ctrl+Shift+B or selecting Build → Build Solution
- Open Command Prompt or PowerShell
- Navigate to the Pyramid directory
- Generate build files:
cmake -B build -S . -G "Visual Studio 17 2022" -A x64- Build the engine:
cmake --build build --config Debug- Debug: Includes debug symbols, no optimizations, full logging
- Release: Optimized for performance, minimal logging
- RelWithDebInfo: Optimized with debug symbols, useful for profiling
After successful build, you will find:
- Static Library:
build/lib/PyramidEngine.lib - Dynamic Library:
build/bin/Debug/PyramidEngine.dll(Debug configuration) - Example Executables:
build/bin/Debug/Examples/BasicGame.exe
Create a new class inheriting from Pyramid::Game:
// MyGame.hpp
#pragma once
#include <Pyramid/Core/Game.hpp>
#include <Pyramid/Graphics/GraphicsDevice.hpp>
#include <Pyramid/Graphics/Camera.hpp>
#include <Pyramid/Math/Math.hpp>
class MyGame : public Pyramid::Game {
public:
MyGame();
~MyGame() = default;
protected:
void onCreate() override;
void onUpdate(float deltaTime) override;
void onRender() override;
private:
// Graphics resources
std::shared_ptr<Pyramid::IShader> m_shader;
std::shared_ptr<Pyramid::IVertexBuffer> m_vertexBuffer;
std::shared_ptr<Pyramid::IIndexBuffer> m_indexBuffer;
std::shared_ptr<Pyramid::IVertexArray> m_vertexArray;
// Camera
Pyramid::Camera m_camera;
// Timing
f32 m_time = 0.0f;
};// MyGame.cpp
#include "MyGame.hpp"
MyGame::MyGame() : Pyramid::Game() {
// Constructor - window properties are set automatically
}
void MyGame::onCreate() {
auto* device = GetGraphicsDevice();
// Create camera
m_camera = Pyramid::Camera(
Pyramid::Math::Radians(60.0f), // FOV
1280.0f / 720.0f, // Aspect ratio
0.1f, // Near plane
1000.0f // Far plane
);
m_camera.SetPosition(Pyramid::Math::Vec3(0.0f, 0.0f, 5.0f));
m_camera.LookAt(Pyramid::Math::Vec3::Zero);
// Create shader
m_shader = device->CreateShader();
const char* vertexSource = R"(
#version 330 core
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec3 a_Color;
uniform mat4 u_ViewProjection;
uniform mat4 u_WorldMatrix;
uniform float u_Time;
out vec3 v_Color;
void main() {
gl_Position = u_ViewProjection * u_WorldMatrix * vec4(a_Position, 1.0);
v_Color = a_Color;
}
)";
const char* fragmentSource = R"(
#version 330 core
in vec3 v_Color;
uniform float u_Time;
out vec4 o_Color;
void main() {
// Animate color based on time
vec3 animatedColor = v_Color * (0.5f + 0.5f * sin(u_Time));
o_Color = vec4(animatedColor, 1.0f);
}
)";
m_shader->setVertexSource(vertexSource);
m_shader->setFragmentSource(fragmentSource);
if (!m_shader->compile()) {
PYRAMID_LOG_ERROR("Shader compilation failed: ", m_shader->getErrorMessage());
return;
}
// Create vertex buffer
struct Vertex {
Pyramid::Math::Vec3 position;
Pyramid::Math::Vec3 color;
};
std::vector<Vertex> vertices = {
{{-0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}}, // Bottom-left - Red
{{ 0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}}, // Bottom-right - Green
{{ 0.0f, 0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}} // Top - Blue
};
m_vertexBuffer = device->CreateVertexBuffer();
m_vertexBuffer->setData(vertices.data(), vertices.size() * sizeof(Vertex));
// Set up vertex layout
Pyramid::BufferLayout layout = {
{Pyramid::ShaderDataType::Float3, "a_Position"},
{Pyramid::ShaderDataType::Float3, "a_Color"}
};
m_vertexBuffer->setLayout(layout);
// Create index buffer
std::vector<u32> indices = {0, 1, 2}; // Triangle indices
m_indexBuffer = device->CreateIndexBuffer();
m_indexBuffer->setData(indices.data(), indices.size() * sizeof(u32));
// Create vertex array
m_vertexArray = device->CreateVertexArray();
m_vertexArray->addVertexBuffer(m_vertexBuffer);
m_vertexArray->setIndexBuffer(m_indexBuffer);
PYRAMID_LOG_INFO("Game created successfully!");
}
void MyGame::onUpdate(float deltaTime) {
// Update timing
m_time += deltaTime;
// Rotate camera around the triangle
f32 radius = 5.0f;
f32 camX = sin(m_time * 0.5f) * radius;
f32 camZ = cos(m_time * 0.5f) * radius;
m_camera.SetPosition(Pyramid::Math::Vec3(camX, 0.0f, camZ));
m_camera.LookAt(Pyramid::Math::Vec3::Zero);
}
void MyGame::onRender() {
auto* device = GetGraphicsDevice();
// Clear the screen
device->Clear(Pyramid::Color(0.1f, 0.1f, 0.1f, 1.0f));
// Set up rendering state
device->EnableDepthTest(false);
// Bind shader and set uniforms
m_shader->bind();
m_shader->setUniform("u_ViewProjection", m_camera.GetViewProjectionMatrix());
m_shader->setUniform("u_WorldMatrix", Pyramid::Math::Mat4::Identity);
m_shader->setUniform("u_Time", m_time);
// Bind vertex array and draw
m_vertexArray->bind();
device->DrawIndexed(3);
}
// Main.cpp
#include <windows.h>
#include "MyGame.hpp"
int WINAPI WinMain(
[[maybe_unused]] HINSTANCE hInstance,
[[maybe_unused]] HINSTANCE hPrevInstance,
[[maybe_unused]] LPSTR lpCmdLine,
[[maybe_unused]] int nCmdShow)
{
try {
MyGame game;
game.run();
return 0;
}
catch (const std::exception& e) {
MessageBoxA(NULL, e.what(), "Error", MB_OK | MB_ICONERROR);
return 1;
}
}cmake_minimum_required(VERSION 3.16.0)
project(MyGame CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Find Pyramid Engine
find_package(PyramidEngine REQUIRED)
# Add executable
add_executable(MyGame WIN32
source/Main.cpp
source/MyGame.cpp
include/MyGame.hpp
)
# Link with Pyramid Engine
target_link_libraries(MyGame PRIVATE PyramidEngine)
# Include directories
target_include_directories(MyGame
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# Set output directory
set_target_properties(MyGame PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}"
)MyGame/
├── CMakeLists.txt
├── include/
│ └── MyGame.hpp
├── source/
│ ├── Main.cpp
│ └── MyGame.cpp
└── assets/
├── textures/
├── shaders/
└── models/
Here's a complete minimal example that renders a colored triangle:
#include <Pyramid/Core/Game.hpp>
#include <Pyramid/Graphics/GraphicsDevice.hpp>
#include <Pyramid/Math/Math.hpp>
class HelloTriangle : public Pyramid::Game {
public:
void onCreate() override {
auto* device = GetGraphicsDevice();
// Create simple shader
m_shader = device->CreateShader();
m_shader->setVertexSource(R"(
#version 330 core
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec3 a_Color;
uniform mat4 u_ViewProjection;
out vec3 v_Color;
void main() {
gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
v_Color = a_Color;
}
)");
m_shader->setFragmentSource(R"(
#version 330 core
in vec3 v_Color;
out vec4 o_Color;
void main() {
o_Color = vec4(v_Color, 1.0);
}
)");
m_shader->compile();
// Triangle vertices with colors
float vertices[] = {
// Position // Color
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom-left - Red
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom-right - Green
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // Top - Blue
};
m_vertexBuffer = device->CreateVertexBuffer();
m_vertexBuffer->setData(vertices, sizeof(vertices));
// Set up vertex layout
Pyramid::BufferLayout layout = {
{Pyramid::ShaderDataType::Float3, "a_Position"},
{Pyramid::ShaderDataType::Float3, "a_Color"}
};
m_vertexBuffer->setLayout(layout);
// Create vertex array
m_vertexArray = device->CreateVertexArray();
m_vertexArray->addVertexBuffer(m_vertexBuffer);
// Set up camera
m_camera = Pyramid::Camera(
Pyramid::Math::Radians(60.0f),
1280.0f / 720.0f, // Fixed aspect ratio - window size methods don't exist
0.1f, 100.0f
);
m_camera.SetPosition(Pyramid::Math::Vec3(0.0f, 0.0f, 3.0f));
}
void onRender() override {
auto* device = GetGraphicsDevice();
device->Clear(Pyramid::Color(0.2f, 0.2f, 0.2f, 1.0f));
m_shader->bind();
m_shader->setUniform("u_ViewProjection", m_camera.GetViewProjectionMatrix());
m_vertexArray->bind();
device->DrawArrays(3);
}
private:
std::shared_ptr<Pyramid::IShader> m_shader;
std::shared_ptr<Pyramid::IVertexBuffer> m_vertexBuffer;
std::shared_ptr<Pyramid::IVertexArray> m_vertexArray;
Pyramid::Camera m_camera;
};
int main() {
HelloTriangle game;
game.run();
return 0;
}- Create a new directory for your game project
- Copy the project structure shown above
- Add your game project to the Pyramid solution:
- Right-click the Solution in Solution Explorer
- Add → Existing Project
- Select your game's CMakeLists.txt
- Set your game as the startup project
- Build and run (F5)
- Navigate to your game directory
- Create a build directory:
mkdir build
cd build- Generate build files:
cmake .. -G "Visual Studio 17 2022" -A x64- Build:
cmake --build . --config Debug- Run:
./bin/Debug/MyGame.exeProblem: CMake cannot find Pyramid Engine
CMake Error at CMakeLists.txt:10 (find_package):
Could not find a configuration file for "PyramidEngine"
Solution: Ensure the Pyramid Engine is built and installed, or specify the path:
set(PyramidEngine_DIR "path/to/pyramid/build")Problem: Linker errors unresolved external symbols Solution: Ensure you're linking against the correct library configuration (Debug/Release) and that all dependencies are properly installed.
Problem: Window creation fails Solution: Ensure your graphics drivers are up to date and that your system supports OpenGL 3.3 or later.
Problem: Shader compilation fails Solution: Check the shader error messages in the log output. Common issues include:
- Unsupported GLSL version
- Syntax errors in shader code
- Missing uniforms or attributes
Problem: Low frame rate Solution:
- Use Release build configuration for better performance
- Enable VSync in present call
- Optimize shader code
- Reduce draw calls
- Explore Examples: Check the
Examples/directory for more comprehensive examples - Read API Documentation: Refer to the API Reference for detailed class documentation
- Experiment with Features: Try adding textures, lighting, and more complex geometry
- Join the Community: Participate in discussions and get help from other developers
- Architecture Overview - Detailed engine architecture
- API Reference - Complete API documentation
- Math Library - Math library reference
- Graphics System - Graphics system reference
Examples/BasicGame/- Basic game example with input handlingExamples/AdvancedRendering/- Advanced rendering techniquesExamples/SceneManagement/- Scene management and spatial partitioning
- GitHub: https://github.com/yourusername/Pyramid
- Issues: Report bugs and request features
- Discussions: Ask questions and share knowledge
- Discord: Real-time chat (coming soon)
If you encounter issues or have questions:
- Check the Documentation: Most common issues are covered in the documentation
- Search Existing Issues: Check GitHub Issues for similar problems
- Create a Minimal Example: Isolate the issue in a simple, reproducible example
- File an Issue: Provide detailed information about your problem:
- Operating system and version
- Graphics card and driver version
- Full error messages and stack traces
- Minimal code that reproduces the issue
Happy coding with Pyramid Engine!
- Create a new class inheriting from
Pyramid::Game:
#include <Pyramid/Core/Game.hpp>
class MyGame : public Pyramid::Game {
public:
MyGame() = default;
void onCreate() override {
// Initialize your game resources
}
void onUpdate(float deltaTime) override {
// Add your game logic here
}
};- Create the main entry point (Windows):
#include <windows.h>
int WINAPI WinMain(
[[maybe_unused]] HINSTANCE hInstance,
[[maybe_unused]] HINSTANCE hPrevInstance,
[[maybe_unused]] LPSTR lpCmdLine,
[[maybe_unused]] int nCmdShow)
{
try
{
MyGame game;
game.run();
return 0;
}
catch (const std::exception& e)
{
MessageBoxA(NULL, e.what(), "Error", MB_OK | MB_ICONERROR);
return 1;
}
}The engine provides a robust window management system:
// Window is automatically created and managed by Game
// Window customization is handled through the platform-specific window implementation
void onCreate() override {
// Initialize your game resources
// Window properties are set automatically during Game initialization
}// Handle window events in your game class
void onWindowEvent(const WindowEvent& event) override {
switch (event.type) {
case WindowEvent::Resize:
// Handle window resize
break;
case WindowEvent::Focus:
// Handle window focus change
break;
case WindowEvent::Close:
// Handle window close request
break;
}
}The engine provides a flexible graphics abstraction layer:
// Graphics device is automatically created and managed by Game
// You can access it in your game class:
void onCreate() override {
auto* device = GetGraphicsDevice();
// Create graphics resources
auto vertexBuffer = device->CreateVertexBuffer();
auto shader = device->CreateShader();
}// Create and use shaders
void onCreate() override {
auto* device = GetGraphicsDevice();
// Create shader
auto shader = device->CreateShader();
shader->setVertexSource(vertexShaderSource);
shader->setFragmentSource(fragmentShaderSource);
shader->compile();
// Use shader
shader->bind();
}// Create and use vertex buffers
void onCreate() override {
auto* device = GetGraphicsDevice();
// Create vertex buffer
auto vertexBuffer = device->CreateVertexBuffer();
vertexBuffer->setData(vertices, sizeof(vertices));
// Use vertex buffer
vertexBuffer->bind();
}The engine features a production-ready scene management system with spatial partitioning:
#include <Pyramid/Graphics/Scene/SceneManager.hpp>
void onCreate() override {
using namespace Pyramid::SceneManagement;
// Create scene manager
m_sceneManager = SceneUtils::CreateSceneManager();
// Create and set active scene
auto mainScene = m_sceneManager->CreateScene("MainLevel");
m_sceneManager->SetActiveScene(mainScene);
// Configure spatial partitioning
m_sceneManager->SetOctreeDepth(8); // 8 levels deep
m_sceneManager->SetOctreeSize(Math::Vec3(1000.0f, 1000.0f, 1000.0f));
}void onUpdate(float deltaTime) override {
// Find objects near player
Math::Vec3 playerPos = getPlayerPosition();
auto nearbyObjects = m_sceneManager->GetObjectsInRadius(playerPos, 10.0f);
// Find nearest interactive object
auto nearest = m_sceneManager->GetNearestObject(playerPos);
if (nearest) {
// Handle interaction
}
// Get visible objects for rendering
auto visibleObjects = m_sceneManager->GetVisibleObjects(camera);
// Update scene
m_sceneManager->Update(deltaTime);
}void logPerformanceStats() {
const auto& stats = m_sceneManager->GetStats();
PYRAMID_LOG_INFO("Scene Performance:");
PYRAMID_LOG_INFO(" Total Objects: ", stats.totalObjects);
PYRAMID_LOG_INFO(" Visible Objects: ", stats.visibleObjects);
PYRAMID_LOG_INFO(" Query Time: ", stats.lastQueryTime, " ms");
}A typical Pyramid game project structure looks like this:
MyGame/
├── include/
│ └── MyGame.hpp
├── source/
│ ├── MyGame.cpp
│ └── Main.cpp
└── CMakeLists.txt
Example CMakeLists.txt:
add_executable(MyGame WIN32
source/Main.cpp
source/MyGame.cpp
include/MyGame.hpp
)
target_link_libraries(MyGame PRIVATE PyramidEngine)
target_include_directories(MyGame
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
)- Check out the example projects in the
Examples/directory - Read the API documentation
- Join our community:
- GitHub Discussions
- Discord Server
- Forums
If you need help:
- Check the documentation
- Look at the example projects
- Ask in our community channels
- File an issue on GitHub