1
0
Fork 0

Compare commits

..

No commits in common. "master" and "v0.0.1" have entirely different histories.

471 changed files with 9318 additions and 132353 deletions

77
.bam/functions.lua Normal file
View file

@ -0,0 +1,77 @@
local _systems = {
"Win32",
-- "Linux"
}
-- Returns a string of all supported systems
function supported_systems()
return table.concat(_systems, ', ')
end
-- Detect what system we currently are on.
function system()
local win = os.getenv('OS')
if win:lower():match('windows') then
return _systems[1]
end
return nil
end
-- Defines a module
-- path: base path to source files.
-- src: table of source files.
function Module(path, src)
local r = {}
for k, v in pairs(src) do
r[k] = path .. "/" .. v
end
return r
end
-- Copy a directory src to dst
-- src = "path/to/a", dest = "path/to/b" -> the whole content
-- of "a" will be copied to "path/to/b"
function CopyDir(dst, src)
local r = {}
local base = PathDir(src)
local files = CollectRecursive(Path(src) .. "/*")
for k, v in pairs(files) do
local rdir = PathDir(v:sub(base:len() + 1))
r[k] = CopyToDirectory(PathJoin(dst, rdir), v)
end
return r
end
-- Build example binary.
-- This function Imports "examples/<name>/bam.lua"
-- that file must define a table "src" that contains the source files.
function BuildExample(settings, name, dependencies)
Import("examples/" .. name .. "/bam.lua")
exe = Link(settings, "examples/" .. name, Compile(settings, src))
if dependencies ~= nil and #dependencies > 0 then
AddDependency(exe, dependencies)
end
return exe
end
-- Build examples binaries.
-- Just a wrapper for BuildExample. taking a table of names instead.
function BuildExamples(settings, names, dependencies)
local r = {}
for i = 1, #names do
r[i] = BuildExample(settings, names[i], dependencies)
end
return r
end

View file

@ -1,6 +0,0 @@
BasedOnStyle: LLVM
UseTab: Always
TabWidth: 8
IndentWidth: 8
BreakBeforeBraces: Linux

4
.gitattributes vendored
View file

@ -5,12 +5,8 @@
*.sh text eol=lf
*.ini text eol=lf
*.xml text eol=lf
*.h eol=lf
*.hpp eol=lf
*.hxx eol=lf
*.c text eol=lf
*.cpp text eol=lf
*.cxx text eol=lf
*.htext eol=lf
*.txt text eol=lf
*.glsl text eol=lf

13
.gitignore vendored
View file

@ -1,10 +1,7 @@
# Build system related files
build/
# LSP related files
.ccls-cache/
compile_commands.json
.bam/*
!.bam/*.lua
# Thumbnail databases (Windows)
Thumbs.db
@ -28,12 +25,6 @@ Thumbs.db
!vsproj/*
# Visual Studio Code
.vscode/
# Debug files
*.pdb
# Compiled Object files
*.slo
*.lo

View file

@ -1,42 +0,0 @@
# ------------------------------------------------------------
#
# Spectre main Cmake config
#
# ------------------------------------------------------------
cmake_minimum_required(VERSION 3.15)
cmake_policy(SET CMP0091 NEW)
# set the project name
project(Spectre
VERSION 0.0.1
DESCRIPTION ""
HOMEPAGE_URL "")
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake" )
include(GNUInstallDirs)
# Compiler
# -------------------------------
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS OFF)
if (MSVC)
add_definitions("/EHsc -D_CRT_SECURE_NO_WARNINGS")
# Staticly link with MSVCR
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif (MSVC)
# Variables
# -------------------------------
# Include engine
include(engine.cmake)
# Include examples
add_subdirectory(examples)

View file

@ -1,41 +1,3 @@
# Spectre 2D Engine
A simple 2D Game engine from scratch!
## Compiling
This project uses [cmake](https://cmake.org) build system
(Version 3.15 or greater) to compile the engine.
### Linux with make.
```sh
$ mkdir build
$ cd build
$ cmake .. -G "Unix Makefiles"
$ make
```
### Windows using NMake
```sh
$ mkdir build
$ cd build
$ cmake .. -G "NMake Makefiles"
$ nmake
```
### Or the best way (in my opinion)
install [Ninja](https://ninja-build.org) and run
```sh
$ mkdir build
$ cd build
$ cmake .. -G Ninja
$ ninja
```
The build will produce `spectre.lib` in the `build` directory that
should be used when linking.
## Author
Henrik Hautakoski - [henrik.hautakoski@gmail.com](mailto:henrik.hautakoski@gmail.com)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

248
bam.lua Normal file
View file

@ -0,0 +1,248 @@
--------------------------------
-- --
-- Spectre build config --
-- --
--------------------------------
Import(".bam/functions.lua")
CheckVersion("0.5")
--------------------------------
-- --
-- Environment Setup --
-- --
--------------------------------
-- OS Detection
TARGET_OS = system()
if TARGET_OS == nil then
print ("System not supported" )
print ("Supported systems are: " .. supported_systems() )
return 1
end
-- paths used when building.
paths = {
build = "build",
object = "obj",
examples = "examples"
}
--------------------------------
-- --
-- Global Build Settings --
-- --
--------------------------------
global_settings = NewSettings();
-- Build type
--------------------------------
global_settings.debug = 1
global_settings.optimize = 0
if ScriptArgs.type ~= nil and ScriptArgs.type:match("^release") then
global_settings.debug = 0
if ScriptArgs.type == "release-fast" then
global_settings.optimize = 1
end
end
-- Output configuration
--------------------------------
global_settings.lib.prefix = Path(paths.build) .. "/"
global_settings.link.Output = function(settings, input)
return Path(PathJoin(paths.build, input))
end
global_settings.cc.Output = function(settings, input)
return Path(PathJoin(PathJoin(paths.build, paths.object), PathBase(input)))
end
-- Compiler configuration
--------------------------------
-- MSVC complains about exception handler without this flag.
if global_settings.cc.exe_cxx == "cl" then
global_settings.cc.flags:Add('/EHsc')
end
--------------------------------
-- --
-- Engine configuration --
-- --
--------------------------------
local settings = global_settings
settings.cc.includes:Add("include/")
settings.cc.includes:Add("source/")
-- FreeType2
if TARGET_OS == "Win32" then
settings.cc.includes:Add("vendor/FreeType2/include")
else
settings.cc.includes:Add("/usr/include/freetype2")
end
-- STB
settings.cc.includes:Add("vendor/stb/include")
-- Source files
--------------------------------
local system_module = Module("source/System", {
"File.cpp",
"MessageHandler.cpp",
"MessageQueue.cpp",
"SystemEvent.cpp",
"Log.cpp"
})
local platform_common_module = Module("source/Platform", {
"PlatformDisplay.cpp"
})
-- if TARGET_OS == "Win32" then -- Needed later for unix.
platform_spec_module = Module("source/Platform/Win32", {
"Win32Application.cpp",
"Win32Display.cpp",
"Win32GLContext.cpp",
"Win32Input.cpp",
"Win32Internal.cpp",
"Win32Keyboard.cpp",
"Win32Misc.cpp",
"Win32Mouse.cpp",
"Win32MsgBuffer.cpp",
"Win32System.cpp",
"glad_wgl.c"
})
--end
local input_module = Module("source/Input", {
"InputDevice.cpp",
"InputEvent.cpp",
"InputListener.cpp",
"InputModule.cpp",
"Keyboard.cpp",
"Mouse.cpp"
})
local display_module = Module("source/Display", {
"Display.cpp",
"DisplayDescription.cpp",
"DisplayMode.cpp",
"GLContext.cpp"
})
local graphics_module = Module("source/Graphics", {
-- Primitives
"Vertex2D.cpp",
"Transformable.cpp",
"Sprite.cpp",
-- Rendering
"BatchRenderer2D.cpp",
"DefaultRenderer2D.cpp",
"Renderable2D.cpp",
"Renderer2D.cpp",
"RenderState.cpp",
"Shader.cpp",
"ShaderProgram.cpp",
"Texture.cpp",
-- Text
"Font/FontDriver.cpp",
"Font/FreeTypeDriver.cpp",
"Font/FreeTypeError.cpp",
"Font.cpp",
"Text.cpp",
-- Image
"Image.cpp",
"ImageLoader.cpp",
"OpenGL.cpp",
"GL/glad.c",
"GL/CheckError.cpp",
})
local core_module = Module("source/Core", {
"String.cpp"
})
local math_module = Module("source/Math", {
"Color.cpp",
"Logarithm.cpp",
"Math.cpp",
"Transform.cpp"
})
local game_module = Module("source", {
"Game/FPSCounter.cpp",
"Game/GameTime.cpp",
"Game.cpp",
})
local scene_module = Module("source/Scene", {
"Camera2D.cpp"
})
-- Build target
--------------------------------
local obj = Compile(settings, {
system_module,
platform_common_module,
platform_spec_module,
input_module,
display_module,
graphics_module,
core_module,
math_module,
game_module,
scene_module
})
local libspectre = StaticLibrary(settings,
"spectre",
obj
)
--------------------------------
-- --
-- Examples --
-- --
--------------------------------
local example_settings = global_settings
-- Include spectre headers.
example_settings.cc.includes:Add("include/")
-- Link with spectre.
example_settings.link.extrafiles:Add(libspectre)
if TARGET_OS == "Win32" then
-- Windows needs to link against these.
example_settings.link.libs:Add("opengl32", "gdi32", "user32")
-- Staticly link freetype on windows.
example_settings.link.libpath:Add("vendor/FreeType2/lib/x86")
if example_settings.debug > 0 then
example_settings.link.libs:Add("freetype-d-s")
else
example_settings.link.libs:Add("freetype-s")
end
end
-- For now, to get examples working
-- we copy the whole assets directory.
assets = CopyDir(PathJoin(paths.build, paths.examples), "assets")
BuildExamples(example_settings, {
"text"
}, assets)

View file

@ -1,7 +0,0 @@
function(spectre_example NAME)
add_executable(example_${NAME} ${ARGN})
target_link_libraries(example_${NAME} PRIVATE Spectre)
set_target_properties(example_${NAME} PROPERTIES VS_GLOBAL_IgnoreImportLibrary "true")
#set_target_properties(${NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
endfunction()

View file

@ -1,31 +0,0 @@
# This script provides the spectre as an import target
# ----------------------------------------------------------
#
# Use find_package() so cmake will find spectre:
#
# find_package(spectre) # No specific version
# find_package(spectre REQUIRED) # No specific version, but the library must be found.
# find_package(spectre 0.1) # any 0.1.x, but the library is optional.
# find_package(spectre 0.1.0) # 0.1.0 or greater, but the library is optional.
#
# Then you just link your target with spectre:
#
# target_link_libraries( ${PROGRAM_EXE} PUBLIC spectre )
#
# if you do not specify REQUIRED. you must check the variable spectre_FOUND
# and and only link to it if it's defined:
#
# if (spectre_FOUND)
# ...
# target_link_libraries( ${PROGRAM_EXE} PUBLIC spectre )
# ..
# endif()
@PACKAGE_INIT@
find_package(OpenGL)
set_and_check( SPECTRE_ASSETS "@PACKAGE_ASSETS_DIR@" )
include("${CMAKE_CURRENT_LIST_DIR}/SpectreTargets.cmake")
check_required_components(Spectre)

View file

@ -1,240 +0,0 @@
# ------------------------------------------------------------
#
# Engine library build config
#
# ------------------------------------------------------------
# Source
# ------------------------------------------------------------
set( ENGINE_SRC
# Core
source/Core/String.cpp
# System
source/System/ByteOrder.cpp
source/System/Event.cpp
source/System/EventListener.cpp
source/System/File.cpp
source/System/Log.cpp
source/System/MessageHandler.cpp
source/System/MessageQueue.cpp
source/System/Path.cpp
source/System/Stopwatch.cpp
source/System/Log/FileWriter.cpp
# Platform
source/Platform/PlatformApplication.cpp
source/Platform/PlatformWindow.cpp
# Math
source/Math/Color.cpp
source/Math/Logarithm.cpp
source/Math/Time.cpp
source/Math/Transform.cpp
source/Math/Math.cpp
# Input
source/Input/InputDevice.cpp
source/Input/InputModule.cpp
source/Input/Keyboard.cpp
source/Input/Mouse.cpp
# Window
source/Window/Window.cpp
source/Window/WindowDescription.cpp
source/Window/DisplayMode.cpp
source/Window/GLWindow.cpp
source/Window/GLContext.cpp
# GfxDriver
source/GfxDriver/ShaderProgram.cpp
# Graphics
source/Graphics/BatchRenderer2D.cpp
source/Graphics/DefaultRenderer2D.cpp
source/Graphics/Renderable2D.cpp
source/Graphics/Renderer2D.cpp
source/Graphics/RenderState.cpp
source/Graphics/Sprite.cpp
source/Graphics/Text.cpp
source/Graphics/Texture.cpp
source/Graphics/Transformable.cpp
source/Graphics/Vertex2D.cpp
source/Graphics/Graphics.cpp
# Graphics - Font
source/Graphics/Font/Engine/FreeTypeEngine.cpp
source/Graphics/Font/Engine/FreeTypeError.cpp
source/Graphics/Font/Engine/FreeTypeLib.cpp
source/Graphics/Font/FontDescription.cpp
source/Graphics/Font.cpp
# Graphics - Image
source/Graphics/Image/IcoFormat.cpp
source/Graphics/ImageLoader.cpp
source/Graphics/PixelFormat.cpp
source/Graphics/Image.cpp
# Graphics - GL
source/Graphics/GL/glad.c
source/Graphics/GL/CheckError.cpp
# Scene
source/Scene/Camera2D.cpp
# Game
source/Game/FPSCounter.cpp
source/Game/GameTime.cpp
source/Game.cpp
)
set(ENGINE_GFXDRIVER_OPENGL_SRC
source/GfxDriver/OpenGL/OpenGLDrv.cpp
source/GfxDriver/OpenGL/OpenGLShaderProgram.cpp
)
set(ENGINE_PLATFORM_WIN32_SRC
source/Platform/Win32/Win32Application.cpp
source/Platform/Win32/Win32Window.cpp
source/Platform/Win32/Win32GLContext.cpp
source/Platform/Win32/Win32Input.cpp
source/Platform/Win32/Win32Internal.cpp
source/Platform/Win32/Win32Keyboard.cpp
source/Platform/Win32/Win32Misc.cpp
source/Platform/Win32/Win32Mouse.cpp
source/Platform/Win32/Win32EventQueue.cpp
source/Platform/Win32/Win32System.cpp
source/Platform/Win32/glad_wgl.c
)
set(ENGINE_PLATFORM_UNIX_SRC
source/Platform/Unix/UnixApplication.cpp
source/Platform/Unix/UnixSystem.cpp
source/Platform/Unix/UnixMisc.cpp
# GLContext
source/Platform/Unix/GLXContext.cpp
source/Platform/Unix/glad_glx.c
# X11
source/Platform/Unix/Xlib.cpp
source/Platform/Unix/Xrandr.cpp
source/Platform/Unix/X11Window.cpp
source/Platform/Unix/X11Input.cpp
source/Platform/Unix/X11Keyboard.cpp
source/Platform/Unix/X11Mouse.cpp
source/Platform/Unix/X11EventQueue.cpp
source/Platform/Unix/X11WindowEventHandler.cpp
)
# Library
# ------------------------------------------------------------
add_library( Spectre STATIC ${ENGINE_SRC} )
target_include_directories(Spectre
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/source
)
if (WIN32)
target_compile_options(Spectre PRIVATE "-DSPECTRE_PLATFORM_WIN=1")
else()
target_compile_options(Spectre PRIVATE "-DSPECTRE_PLATFORM_UNIX=1")
endif()
# Dependancies
# ------------------------------------------------------------
# Platform specific
if (WIN32)
target_sources(Spectre PRIVATE ${ENGINE_PLATFORM_WIN32_SRC})
else()
target_sources(Spectre PRIVATE ${ENGINE_PLATFORM_UNIX_SRC})
# Unix needs to link against X11
find_package(X11 REQUIRED COMPONENTS Xrandr)
target_link_libraries(Spectre PRIVATE X11::X11 X11::Xrandr)
endif (WIN32)
# Select graphics API
# Only OpenGL Driver for now
target_sources(Spectre PRIVATE ${ENGINE_GFXDRIVER_OPENGL_SRC})
if (WIN32)
find_package(OpenGL REQUIRED COMPONENTS OpenGL)
target_link_libraries(Spectre PRIVATE OpenGL::GL)
else()
find_package(OpenGL REQUIRED COMPONENTS OpenGL GLX)
target_link_libraries(Spectre PRIVATE OpenGL::OpenGL OpenGL::GLX)
endif()
# FreeType
add_subdirectory(vendor/FreeType2)
target_sources(Spectre PRIVATE $<TARGET_OBJECTS:freetype>)
target_include_directories(Spectre PRIVATE $<TARGET_PROPERTY:freetype,INTERFACE_INCLUDE_DIRECTORIES>)
# STB
target_include_directories(Spectre PRIVATE ${CMAKE_CURRENT_LIST_DIR}/vendor/stb/include)
# Install
# ------------------------------------------------------------
# Includes
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/Spectre TYPE INCLUDE)
# Assets
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/assets DESTINATION ${CMAKE_INSTALL_DATADIR})
# Install - CMake targets
# ------------------------------------------------------------
install(TARGETS Spectre
EXPORT SpectreTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(EXPORT SpectreTargets
FILE SpectreTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Spectre
)
# Build directory target
export(EXPORT SpectreTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/SpectreTargets.cmake"
)
# CMake config
# ------------------------------------------------------------
# Version
include(CMakePackageConfigHelpers)
write_basic_package_version_file(SpectreConfigVersion.cmake COMPATIBILITY SameMajorVersion)
set (ASSETS_DIR ${CMAKE_INSTALL_DATADIR}/assets)
configure_package_config_file(cmake/SpectreConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake/SpectreConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Spectre
PATH_VARS ASSETS_DIR)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/SpectreConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/SpectreConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Spectre)
# CMake config - build directory
# ------------------------------------------------------------
set (ASSETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/assets)
configure_package_config_file(cmake/SpectreConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/SpectreConfig.cmake
INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}
PATH_VARS ASSETS_DIR)

View file

@ -1,7 +0,0 @@
include("Macros")
add_subdirectory(window)
add_subdirectory(events)
add_subdirectory(input)
add_subdirectory(text)

View file

@ -1,7 +0,0 @@
#find_package(Spectre REQUIRED)
spectre_example(events
main.cpp
EventsExample.cpp
)

View file

@ -1,34 +0,0 @@
#include <Spectre/System/MessageHandler.h>
#include <Spectre/System/Log.h>
#include "EventsExample.h"
void EventsExample::init()
{
getMessageHandler()->registerListener(this);
}
void EventsExample::onEvent(const sp::Event& event)
{
if (event.type == sp::Event::Key) {
std::string name = event.key.getKeyName();
const char* pressed = event.key.pressed ? "pressed" : "released";
sp::Log::info("Key: %s %s", name.c_str(), pressed);
}
if (event.type == sp::Event::MouseButton) {
std::string name = event.mouseButton.getName();
const char* pressed = event.mouseButton.pressed ? "pressed" : "released";
sp::Log::info("MouseButton: %s %s", name.c_str(), pressed);
}
}
void EventsExample::update(double dt)
{
// Nothing to do
}
void EventsExample::render()
{
// Nothing to do
}

View file

@ -1,22 +0,0 @@
#ifndef EVENTS_EXAMPLE_H
#define EVENTS_EXAMPLE_H
#include <Spectre/Game.h>
#include <Spectre/System/EventListener.h>
class EventsExample : public sp::Game, sp::EventListener
{
public :
void onEvent(const sp::Event& event);
protected :
void init();
void update(double dt);
void render();
};
#endif /* EVENTS_EXAMPLE_H */

View file

@ -1,11 +0,0 @@
#include "EventsExample.h"
int main(int argc, char **argv) {
EventsExample game;
game.run();
return 0;
}

View file

@ -1,7 +0,0 @@
#find_package(Spectre REQUIRED)
spectre_example(input
main.cpp
InputExample.cpp
)

View file

@ -1,99 +0,0 @@
#include <Spectre/Input/InputModule.h>
#include <Spectre/Input/Keyboard.h>
#include <Spectre/Input/Mouse.h>
#include <Spectre/System/MessageHandler.h>
#include <Spectre/System/Log.h>
#include <Spectre/Graphics/BatchRenderer2D.h>
#include <Spectre/System/Log.h>
#include "InputExample.h"
void InputExample::init()
{
m_renderer = new sp::BatchRenderer2D();
getMessageHandler()->registerListener(this);
m_tux_texture.create("assets/textures/tux.png");
m_kb_sprite.setTexture(m_tux_texture);
m_kb_sprite.setColor(sp::Color::Green);
m_kb_sprite.setSize(sp::vec2f(100, 100));
m_mouse_sprite.setTexture(m_tux_texture);
m_mouse_sprite.setColor(sp::Color::Red);
m_mouse_sprite.setSize(sp::vec2f(100, 100));
m_mouse_sprite.setPosition(sp::vec2f(50, 50));
m_mouse_event_sprite.setTexture(m_tux_texture);
m_mouse_event_sprite.setColor(sp::Color::Blue);
m_mouse_event_sprite.setSize(sp::vec2f(100, 100));
m_mouse_event_sprite.setPosition(sp::vec2f(50, 50));
m_right_mouse_down = false;
m_renderer->setCamera(m_camera);
}
void InputExample::update(double dt)
{
sp::Keyboard* keyboard = getInput()->getKeyboard();
sp::Mouse* mouse = getInput()->getMouse();
double delta = 0.3 * dt;
// Handle keyboard input.
if (keyboard->isKeyDown(sp::Keyboard::Left)) {
m_kb_sprite.move(sp::vec2f(-delta, 0));
} else if (keyboard->isKeyDown(sp::Keyboard::Right)) {
m_kb_sprite.move(sp::vec2f( delta, 0));
}
if (keyboard->isKeyDown(sp::Keyboard::Up)) {
m_kb_sprite.move(sp::vec2f(0, -delta));
} else if (keyboard->isKeyDown(sp::Keyboard::Down)) {
m_kb_sprite.move(sp::vec2f(0, delta));
}
// Handle mouse input.
if (mouse->isButtonDown(sp::Mouse::Left)) {
m_mouse_sprite.setPosition(mouse->getPosition());
}
}
void InputExample::onSizeChanged(sp::Window* Window, int width, int height)
{
}
void InputExample::onEvent(const sp::Event& event)
{
if (event.type == event.Key && !event.key.pressed) {
if (event.key.code == sp::Keyboard::G) {
getGraphics()->getWindow()->grabCursor(true);
sp::Log::info("Mouse Grabbed");
} else if (event.key.code == sp::Keyboard::U) {
getGraphics()->getWindow()->grabCursor(false);
sp::Log::info("Mouse Released");
}
} else if (event.type == event.MouseButton && event.mouseButton.button == sp::Mouse::Right) {
m_right_mouse_down = event.mouseButton.pressed;
} else if (event.type == event.MouseMove && m_right_mouse_down) {
m_mouse_event_sprite.setPosition(event.mouseMove.x, event.mouseMove.y);
}
}
void InputExample::render()
{
sp::Graphics* g = getGraphics();
g->clearBuffer();
m_renderer->begin();
m_renderer->submit(m_mouse_sprite);
m_renderer->submit(m_mouse_event_sprite);
m_renderer->submit(m_kb_sprite);
m_renderer->render();
g->swapBuffers();
}

View file

@ -1,42 +0,0 @@
#ifndef INPUT_EXAMPLE_H
#define INPUT_EXAMPLE_H
#include <Spectre/Scene/Camera2D.h>
#include <Spectre/Graphics/Texture.h>
#include <Spectre/Graphics/Sprite.h>
#include <Spectre/System/EventListener.h>
#include <Spectre/Game.h>
namespace sp {
class Renderer2D;
}
class InputExample : public sp::Game, sp::EventListener
{
protected :
void init();
void update(double dt);
void render();
void onSizeChanged(sp::Window* display, int width, int height);
void onEvent(const sp::Event& event);
private :
sp::Camera2D m_camera;
sp::Renderer2D *m_renderer;
sp::Sprite m_kb_sprite;
sp::Sprite m_mouse_sprite;
sp::Sprite m_mouse_event_sprite;
bool m_right_mouse_down;
sp::Texture m_tux_texture;
};
#endif /* INPUT_EXAMPLE_H*/

View file

@ -1,11 +0,0 @@
#include "InputExample.h"
int main(int argc, char **argv) {
InputExample game;
game.run();
return 0;
}

View file

@ -1,7 +0,0 @@
#find_package(Spectre REQUIRED)
spectre_example(text
main.cpp
Game.cpp
)

View file

@ -2,9 +2,11 @@
#ifndef TEXT_GAME_H
#define TEXT_GAME_H
#include <Spectre/Math/Vector2.h>
#include <Spectre/Input/InputListener.h>
#include <Spectre/Game.h>
class TextExample : public sp::Game
class TextExample : public sp::Game, public sp::InputListener
{
protected :
@ -15,4 +17,4 @@ protected :
void render();
};
#endif /* TEXT_GAME_H*/
#endif /* TEXT_GAME_H*/

7
examples/text/bam.lua Normal file
View file

@ -0,0 +1,7 @@
local base = PathDir(ModuleFilename())
src ={
base .. "/main.cpp",
base .. "/Game.cpp"
}

View file

@ -1,7 +0,0 @@
#find_package(Spectre REQUIRED)
spectre_example(window
main.cpp
WindowExample.cpp
)

View file

@ -1,70 +0,0 @@
#include <Spectre/Window/Window.h>
#include <Spectre/Graphics/BatchRenderer2D.h>
#include <Spectre/System/MessageHandler.h>
#include <Spectre/System/Log.h>
#include "WindowExample.h"
void WindowExample::init()
{
m_renderer = new sp::BatchRenderer2D();
m_mode = sp::Window::WINDOWED;
getMessageHandler()->registerListener(this);
m_texture.create("assets/textures/tux.png");
m_sprite.setTexture(m_texture);
m_sprite.setPosition(sp::vec2f(50, 50));
m_sprite.setSize(sp::vec2f(100, 100));
m_renderer->setCamera(m_camera);
}
void WindowExample::onEvent(const sp::Event& event)
{
if (event.type == sp::Event::Key && event.key.pressed == false) {
if (event.key.code == sp::Keyboard::W) {
if (m_mode == sp::Window::WINDOWED) {
m_mode = sp::Window::WINDOWEDFULLSCREEN;
sp::Log::info("Windowed Fullscreen");
} else {
m_mode = sp::Window::WINDOWED;
sp::Log::info("Windowed");
}
getGraphics()->setWindowMode(m_mode);
} else if (event.key.code == sp::Keyboard::Space) {
if (m_mode == sp::Window::WINDOWED) {
m_mode = sp::Window::FULLSCREEN;
sp::Log::info("Fullscreen");
} else {
m_mode = sp::Window::WINDOWED;
sp::Log::info("Windowed");
}
getGraphics()->setWindowMode(m_mode);
}
}
}
void WindowExample::update(double dt)
{
// Nothing to do
}
void WindowExample::render()
{
sp::Graphics* g = getGraphics();
g->clearBuffer();
m_renderer->begin();
m_renderer->submit(m_sprite);
m_renderer->render();
g->swapBuffers();
}

View file

@ -1,34 +0,0 @@
#ifndef DISPLAY_EXAMPLE_H
#define DISPLAY_EXAMPLE_H
#include <Spectre/Scene/Camera2D.h>
#include <Spectre/Graphics/Texture.h>
#include <Spectre/Graphics/Sprite.h>
#include <Spectre/System/EventListener.h>
#include <Spectre/Game.h>
class WindowExample : public sp::Game, sp::EventListener
{
public :
void onEvent(const sp::Event& event);
protected :
void init();
void update(double dt);
void render();
protected :
sp::Window::Mode m_mode;
sp::Camera2D m_camera;
sp::Renderer2D *m_renderer;
sp::Texture m_texture;
sp::Sprite m_sprite;
};
#endif /* DISPLAY_EXAMPLE_H */

View file

@ -1,11 +0,0 @@
#include "WindowExample.h"
int main(int argc, char **argv) {
WindowExample game;
game.run();
return 0;
}

View file

@ -8,12 +8,13 @@ class NonCopyable
{
protected :
NonCopyable() = default;
virtual ~NonCopyable() = default;
NonCopyable() {}
// Delete Copy constructor and assignment.
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator =(const NonCopyable&) = delete;
private :
// Skip implementation to trigger compiler error.
NonCopyable(const NonCopyable&);
NonCopyable& operator =(const NonCopyable&);
};
} // namespace sp

View file

@ -10,8 +10,6 @@ namespace sp { namespace core
{
// Convertion functions from standard c/c++ types.
std::string to_string(int value);
std::string to_string(unsigned int value);
std::string to_string(float value);

View file

@ -0,0 +1,80 @@
#ifndef SPECTRE_DISPLAY_DISPLAY_H
#define SPECTRE_DISPLAY_DISPLAY_H
#include "DisplayMode.h"
#include "DisplayDescription.h"
#include <Spectre/Display/GLContext.h>
#include <Spectre/System/SystemEvent.h>
#include <string>
namespace sp {
class PlatformDisplay;
class GLContext;
class Display
{
friend class PlatformDisplay;
public :
enum Mode {
WINDOWED = 0,
FULLSCREEN = 1,
WINDOWEDFULLSCREEN = 2,
};
public :
Display();
virtual ~Display();
bool create(DisplayDescription decription);
void destroy();
void setSize(unsigned int width, unsigned int height);
void setCaption(const std::string& title);
const std::string& getCaption() const;
void setIcon(const std::string& filename);
void setDisplayMode(const DisplayMode& mode);
const DisplayMode& getDisplayMode() const;
void setVideoMode(Mode mode);
enum Mode getVideoMode() const;
void showCursor(bool value);
bool activate(bool value);
// Enable/Disable Vertical Sync.
bool enableVSync(bool value);
void swapBuffers();
protected :
void init();
void onReshape(int width, int height);
protected :
enum Mode m_fmode;
DisplayDescription m_description;
DisplayDescription m_cacheDesc;
std::string m_caption;
PlatformDisplay* m_impl;
GLContext* m_context;
};
} // namepsace sp
#endif /* SPECTRE_DISPLAY_DISPLAY_H */

View file

@ -0,0 +1,34 @@
#ifndef SPECTRE_DISPLAY_DISPLAYDESCRIPTION_H
#define SPECTRE_DISPLAY_DISPLAYDESCRIPTION_H
#include "DisplayMode.h"
namespace sp {
namespace DisplayDecorate {
enum Type {
None = 0,
Menu = 1 << 0,
Resize = 1 << 1,
Close = 1 << 2,
Default = Menu | Resize | Close,
};
};
struct DisplayDescription
{
public :
DisplayDescription();
DisplayDescription(DisplayMode mode, unsigned decoration = DisplayDecorate::Default);
public :
DisplayMode mode;
unsigned int decoration;
};
} // namespace sp
#endif /* SPECTRE_DISPLAY_DISPLAYDESCRIPTION_H */

View file

@ -16,15 +16,6 @@ public :
static DisplayMode getDesktopMode();
// Returns true if width hight and bpp are not set (eg. zero)
// useful to determine if a DisplayMode object is set or not.
// this is equal to:
// DisplayMode a;
// if (a == DisplayMode()) {
// // empty
// }
bool empty() const;
inline bool operator==(const DisplayMode& other)
{
return width == other.width

View file

@ -1,22 +1,24 @@
#ifndef SPECTRE_WINDOW_GLCONTEXT_H
#define SPECTRE_WINDOW_GLCONTEXT_H
#ifndef DISPLAY_GLCONTEXT_H
#define DISPLAY_GLCONTEXT_H
#include <Spectre/Math/Vector2.h>
namespace sp {
class PlatformWindow;
class PlatformDisplay;
// Platform independant interface for OpenGL Contexts.
class GLContext
{
public :
static GLContext* create();
virtual ~GLContext();
// Create a GLContext for this perticular window.
virtual bool create(const PlatformWindow* window) = 0;
// Create a GLContext for this perticular display.
virtual bool create(const PlatformDisplay* display) = 0;
virtual void destroy() = 0;
@ -36,10 +38,13 @@ public :
// This is usually refered to as enabling/disabling vertical synchronization.
virtual bool setSwapInterval(int interval) = 0;
// Set the size of the pixel buffer.
virtual void setSize(unsigned int width, unsigned int height) = 0;
// Swap front with back buffer and vice versa.
virtual void swapBuffers() = 0;
};
} // namespace sp
#endif /* SPECTRE_WINDOW_GLCONTEXT_H */
#endif /* DISPLAY_GLCONTEXT_H */

View file

@ -3,6 +3,7 @@
#define SPECTRE_GAME_H
#include <Spectre/Graphics.h>
#include <Spectre/Input/InputEvent.h>
#include <Spectre/Game/FPSCounter.h>
class InputModule;
@ -12,8 +13,6 @@ class PlatformApplication;
namespace sp {
namespace log { class Writer; }
class Game
{
public :
@ -38,10 +37,10 @@ protected :
FPSCounter& getFpsCounter();
MessageHandler* getMessageHandler() const;
private :
void setup();
void gameLoop();
void processEvents();
@ -56,10 +55,9 @@ private :
MessageHandler* m_messageHandler;
log::Writer* m_log_writer;
FPSCounter m_fpsCounter;
double m_timestep;
bool m_running;
};

View file

@ -2,8 +2,6 @@
#ifndef SPECTRE_FPS_COUNTER_H
#define SPECTRE_FPS_COUNTER_H
#include <Spectre/System/Stopwatch.h>
// Simple FPS counter.
namespace sp {
@ -17,11 +15,11 @@ public :
// Should be called whenever a frame has been rendered.
void addFrame();
double getFPS() const;
float getFPS() const;
// Set the update rate (in seconds).
// How often the FPS should be sampled and calculated.
void setUpdateRate(unsigned int rate);
void setUpdateRate(unsigned int seconds);
// Update the internal time measurment.
bool update();
@ -31,18 +29,17 @@ public :
private :
// Number of frames since last update.
// Frame counter.
unsigned int m_count;
// Last time we updated the counter.
//Time m_time;
Stopwatch m_watch;
// time (in ms)
unsigned int m_time;
// Update rate (at what interval should we update)
Time m_updateRate;
// Update rate (in ms)
unsigned int m_updateRate;
// Calculated Frames per second.
double m_fps;
// Calculated fps.
float m_fps;
};
} // namespace sp

View file

@ -2,9 +2,6 @@
#ifndef SPECTRE_GAME_TIME_H
#define SPECTRE_GAME_TIME_H
#include <Spectre/Math/Time.h>
#include <Spectre/System/Stopwatch.h>
namespace sp {
class GameTime
@ -16,12 +13,12 @@ public :
double getTimeStep() const;
Time getElapsed() const;
unsigned long getElapsed() const;
//bool shouldTick();
bool beginFrame();
bool shouldTick() const;
bool tick();
void reset();
@ -36,13 +33,15 @@ protected :
// TODO: min,max framerates
Stopwatch m_watch;
// Time(in ms) when the last update occured.
unsigned long m_current;
unsigned long m_lastUpdate;
double m_acc;
Time m_acc;
Time m_max_acc;
// timeslice in ms.
double m_slice;
// Timeslice.
Time m_slice;
bool m_inLoop;
};
} // namespace sp

View file

@ -1,49 +0,0 @@
#ifndef SPECTRE_GFXDRIVER_GFXDRIVER_H
#define SPECTRE_GFXDRIVER_GFXDRIVER_H
#include <string>
namespace sp {
class ShaderProgram;
class GfxDriver
{
public:
enum BufferFlags {
CLEAR_BUFFER_BIT,
};
public:
// Get the name of the driver.
virtual std::string getName() const = 0;
// Get the version of the driver
virtual std::string getVersion() const = 0;
virtual std::string getVendor() const = 0;
virtual std::string getCardName() const = 0;
virtual void setViewport(int x, int y, int width, int height) = 0;
virtual void setClearColor(float r, float g, float b, float a) = 0;
virtual void clearBuffer(BufferFlags flags) = 0;
virtual void clearColorBuffer() = 0;
// Resources.
virtual ShaderProgram* createShaderProgram() = 0;
// CreateIndexBuffer()
// CreateVertexBuffer()
// Draw calls
};
} // namespace sp
#endif /* SPECTRE_GFXDRIVER_GFXDRIVER_H */

View file

@ -1,77 +0,0 @@
#ifndef SPECTRE_GFXDRIVER_SHADERPROGRAM_H
#define SPECTRE_GFXDRIVER_SHADERPROGRAM_H
#include <Spectre/Math/Matrix4.h>
#include <Spectre/Math/Color.h>
namespace sp {
enum ShaderType {
Vertex,
Fragment
};
class ShaderProgram
{
public:
virtual ~ShaderProgram();
// Load a shader program from file.
virtual bool loadFromFile(const std::string& filename);
// Load a shader from file.
virtual bool loadFromFile(const std::string& filename, ShaderType type);
// Load a shader from memory.
virtual bool loadFromMemory(const std::string& source, ShaderType type) = 0;
// Link the program.
virtual bool link() = 0;
// Returns true if the program was linked successfully
virtual bool isLinked() const;
// Enable this shader
// All shader operations after this call will affect this shader.
virtual void enable() const = 0;
// Disable this shader
// Operations will no longer affect this shader after this call.
virtual void disable() const = 0;
// Get the last shader error.
virtual std::string getLastError() const;
// ---------------------
// Variables.
// ---------------------
// TODO: Move this to a ShaderParameter class
virtual bool setMVPMatrix(const Matrix4f& matrix) = 0;
// ---------------------
// General Variables.
// ---------------------
virtual bool setAttribute(const std::string& name, float value) const = 0;
virtual bool setAttribute(const std::string& name, const Matrix4f& matrix) const = 0;
virtual bool setUniform(const std::string& name, const Matrix4f& matrix) const = 0;
virtual bool setUniform(const std::string& name, const Color& color) const = 0;
protected:
std::string m_extension;
mutable std::string m_error;
bool m_linked;
};
} // namespace sp
#endif /* SECTRE_GRAPHICS_SHADERPROGRAM_H */

View file

@ -2,8 +2,7 @@
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include <Spectre/GfxDriver/GfxDriver.h>
#include <Spectre/Window/GLWindow.h>
#include <Spectre/Display/Display.h>
namespace sp {
@ -31,7 +30,7 @@ public :
std::string getVersion() const;
void setWindowMode(Window::Mode mode);
void setDisplayMode(Display::Mode mode);
void setSize(int width, int height);
@ -43,19 +42,12 @@ public :
void swapBuffers();
GfxDriver* getDriver();
GLWindow* getWindow();
protected :
int m_width;
int m_height;
GLWindow *m_window;
// Graphics Driver. OpenGL/Vulcan/DirectX etc.
GfxDriver *m_gfxdrv;
Display *m_display;
};
} // namespace sp

View file

@ -39,10 +39,10 @@ protected :
struct Batch
{
RenderType type;
const Texture* texture;
unsigned int count;
unsigned int offset;
RenderType type;
const Texture* texture;
unsigned int count;
unsigned int offset;
};
typedef std::vector<Batch> BatchQueue;
@ -67,8 +67,8 @@ protected :
unsigned short m_size;
ShaderProgram* m_textShader;
ShaderProgram* m_spriteShader;
ShaderProgram m_textShader;
ShaderProgram m_spriteShader;
};
} // namespace

View file

@ -7,8 +7,6 @@
namespace sp {
class ShaderProgram;
class DefaultRenderer2D : public Renderer2D
{
public :
@ -23,7 +21,7 @@ protected :
std::vector<const Renderable2D*> m_queue;
ShaderProgram* m_shader;
ShaderProgram m_shader;
};
} // namespace

View file

@ -1,18 +1,18 @@
#ifndef SPECTRE_GRAPHICS_FONT_H
#define SPECTRE_GRAPHICS_FONT_H
#ifndef SPECTRE_GRAPHCIS_FONT_H
#define SPECTRE_GRAPHCIS_FONT_H
#include <map>
#include <vector>
#include <string>
#include <Spectre/Math/Vector4.h>
#include <Spectre/Math/Vector2.h>
#include <Spectre/Graphics/Texture.h>
#include <Spectre/Graphics/Font/Glyph.h>
namespace sp {
class FontEngine;
class FontDriver;
// TODO: Fixup this api :)
@ -24,6 +24,16 @@ public :
std::string name;
};
struct Glyph {
vec2b size; // Width, Height of bounding box.
vec2b offset; // Offset from cursor where the box begins.
unsigned char advance;
//vec4u tex_coords;
vec2u texture_origin;
const Texture* texture; // Texture atlas.
};
Font();
~Font();
@ -55,7 +65,7 @@ protected :
Texture texture;
};
FontEngine *m_engine;
FontDriver *m_driver;
mutable std::map<unsigned char, Glyph> m_charset;
@ -67,4 +77,4 @@ protected :
}
#endif /* SPECTRE_GRAPHICS_FONT_H */
#endif /* SPECTRE_GRAPHCIS_FONT_H */

View file

@ -1,22 +0,0 @@
#ifndef SPECTRE_GRAPHICS_FONT_FONTDESCRIPTION_H
#define SPECTRE_GRAPHICS_FONT_FONTDESCRIPTION_H
namespace sp {
class FontDescription
{
public :
void hinting(bool value = true);
bool isHintingEnabled() const;
protected :
// True if hinting is enabled. false otherwise.
bool m_hinting = true;
};
} // namespace sp
#endif /* SPECTRE_GRAPHICS_FONT_FONTDESCRIPTION_H */

View file

@ -1,21 +0,0 @@
#ifndef SPECTRE_GRAPHICS_FONT_GLYPH_H
#define SPECTRE_GRAPHICS_FONT_GLYPH_H
#include <Spectre/Math/Vector2.h>
#include <Spectre/Graphics/Texture.h>
namespace sp {
struct Glyph {
vec2b size; // Width, Height of bounding box.
vec2b offset; // Offset from cursor where the box begins.
unsigned char advance;
vec2u texture_origin;
const Texture* texture; // Texture atlas.
};
} // namespace sp
#endif // SPECTRE_GRAPHICS_FONT_GLYPH_H

View file

@ -13,16 +13,13 @@ namespace sp {
class Image
{
public :
enum Channels {
Alpha,
RGB,
RGBA
};
Image();
void create(unsigned width, unsigned height, const Color& color = Color::Black, enum Channels comp = Channels::RGBA);
void create(unsigned width, unsigned height, const void* pixels, PixelFormat format = PixelFormat::PF_RGBA);
void create(unsigned width, unsigned height, const Color& color = Color::Black);
void create(unsigned width, unsigned height, const void* pixels);
void create(PixelFormat format, unsigned width, unsigned height, const Color& color = Color::Black);
void create(PixelFormat format, unsigned width, unsigned height, const void* pixels);
const Vector2u& getSize() const;
@ -30,7 +27,7 @@ public :
unsigned int getHeight() const;
unsigned int getNumChannels() const;
unsigned int getBpp() const;
unsigned int getStride() const;
@ -49,7 +46,7 @@ public :
Color getPixel(unsigned x, unsigned y) const;
void setPixels(const void* pixels, PixelFormat format = PixelFormat::PF_RGBA);
void setPixels(const void* pixels);
const unsigned char* getPixels() const;
@ -59,7 +56,7 @@ private :
Vector2u m_size;
enum Channels m_channels;
PixelFormat m_format;
std::vector<unsigned char> m_pixels;
};

View file

@ -0,0 +1,7 @@
#ifndef SPECTRE_OPENGL_H
#define SPECTRE_OPENGL_H
#include <Spectre/Graphics/GL/glad.h>
#endif /* SPECTRE_OPENGL_H */

View file

@ -1,49 +1,16 @@
#ifndef SPECTRE_GRAPHICS_PIXELFORMAT_H
#define SPECTRE_GRAPHICS_PIXELFORMAT_H
#include <cstdint>
namespace sp {
enum PixelFormat
{
PF_Unknown = 0,
PF_Alpha = 1, // 8 bit alpha channel.
// Byte-order formats.
// Pixels are always ordered with the first channel at the first byte, second channel at the second byte.
// ---------------------------
PF_RGB = 2, // Standard RGB: 24 bits per pixel, 8 bits are used for red, green, blue.
PF_RGBX = 3, // 32 bits per pixel, 8 bits are used for red, green, Last 8 bits are unused.
PF_RGBA = 4, // Standard RGBA: 32 bits per pixel, 8 bits are used for red, green, blue, alpha.
PF_BGR = 5, // 24 bits per pixel, 8 bits are used for blue, green, red.
PF_BGRX = 6, // 32 bits per pixel, 8 bits are used for blue, green, red. Last 8 bits are unused.
PF_BGRA = 7, // 32 bits per pixel, 8 bits are used for blue, green, red, alpha.
// Packed formats.
// ---------------------------
// 32-bit: Pixels are in ordered in 32-bit words. where the first channel is stored at the most significant byte (MSB).
// these formats are architecture dependant (litte/big-endian).
// (MSB) | byte 0 | byte 1 | byte 2 | byte 3 | (LSB)
PF_RGBX32 = 8, // | rrrr rrrr | gggg gggg | bbbb bbbb | xxxx xxxx |
PF_RGBA32 = 9, // | rrrr rrrr | gggg gggg | bbbb bbbb | aaaa aaaa |
PF_BGRX32 = 10, // | bbbb bbbb | gggg gggg | rrrr rrrr | xxxx xxxx |
PF_BGRA32 = 11, // | bbbb bbbb | gggg gggg | rrrr rrrr | aaaa aaaa |
// 24-bit (unsuppored for now)
//PF_RGB24 = 12, // | rrrr rrrr | gggg gggg | bbbb bbbb |
//PF_BGR24 = 13, // | bbbb bbbb | gggg gggg | rrrr rrrr |
// 16-bit (unsuppored for now)
//PF_RGB565 = 14, // | rrrr rggg | gggb bbbb |
//PF_RGBA5551 = 15 // | rrrr rggg | ggb bbbba |
//PF_RGBX5551 = 16 // | rrrr rggg | ggb bbbbx |
PF_Unknown = 0,
PF_RGB = 1,
PF_RGBA = 2,
PF_Alpha = 3, // 1 byte alpha channel.
};
uint8_t PF_getNumChannels(enum PixelFormat format);
} // namespace
#endif /* SPECTRE_GRAPHICS_PIXELFORMAT_H */

View file

@ -3,6 +3,7 @@
#define SPECTRE_GRAPHICS_RENDERER2D_H
#include <Spectre/Graphics/Renderable.h>
#include <Spectre/Graphics/ShaderProgram.h>
#include <Spectre/Scene/Camera2D.h>
namespace sp {

View file

@ -0,0 +1,58 @@
#ifndef SPECTRE_GRAPHICS_SHADER_H
#define SPECTRE_GRAPHICS_SHADER_H
#include <string>
namespace sp {
class Shader
{
public :
enum Type {
Vertex,
Fragment
};
Shader(Type type, const std::string& name = "");
~Shader();
unsigned int getHandle() const;
const std::string& getName() const;
// Load shader from file.
bool loadFromFile(const std::string& file);
// Load shader from memory
bool loadFromMemory(const std::string& source);
const std::string& getError() const;
// Is this shader compiled?
bool isCompiled() const;
protected :
// Compile the shader.
// Returns true if the shader compiled without errors. false otherwise.
bool compile();
std::string fetchErrorLog();
protected :
// Type of shader. Vertex, fragment, geometry etc.
Type m_type;
unsigned int m_handle; // Shader id.
// A name for the shader (usually the filename if loaded from file).
std::string m_name;
std::string m_error;
};
} // namespace sp
#endif /* SPECTRE_GRAPHICS_SHADER_H */

View file

@ -0,0 +1,90 @@
#ifndef SPECTRE_GRAPHICS_SHADER_PROGRAM_H
#define SPECTRE_GRAPHICS_SHADER_PROGRAM_H
#include <string>
#include <Spectre/Math/Matrix4.h>
#include "Shader.h"
namespace sp {
struct Color;
class ShaderProgram
{
public :
ShaderProgram();
~ShaderProgram();
void create();
void destroy();
void addShader(const Shader& shader);
// Load a shader program from file.
//
// The following naming conventions are supported:
// <name>.glsl - Virtual file, will load all real shader files with the same name.
// <name>.vert.glsl - Vertex shader.
// <name>.frag.glsl - Fragment shader.
bool loadFromFile(const std::string& filename);
// Load a shader from file.
bool loadFromFile(const std::string& filename, Shader::Type type);
// Load a shader from memory.
bool loadFromMemory(const std::string& source, Shader::Type type);
// Link the program.
bool link();
// Returns true if the program was linked successfully
bool isLinked() const;
// Enable this shader
// All shader operations after this call will affect this shader.
void enable() const;
// Disable this shader
// Operations will no longer affect this shader after this call.
void disable() const;
// Get the last shader error.
std::string getLastError() const;
// ---------------------
// Variables.
// ---------------------
bool setMVPMatrix(const Matrix4f& matrix);
// ---------------------
// General Variables.
// ---------------------
bool setAttribute(const std::string& name, float value) const;
bool setAttribute(const std::string& name, const Matrix4f& matrix) const;
bool setUniform(const std::string& name, const Matrix4f& matrix) const;
bool setUniform(const std::string& name, const Color& color) const;
protected :
bool getAttribLoc(const std::string& name, int& loc) const;
bool getUniformLoc(const std::string& name, int& loc) const;
std::string fetchErrorLog();
protected :
unsigned int m_id; // program id
mutable std::string m_error;
};
} // namespace sp
#endif /* SPECTRE_GRAPHICS_SHADER_PROGRAM_H */

View file

@ -16,19 +16,19 @@ class Texture : public NonCopyable
{
public:
enum Filter {
Nearest = 0x2600,
Linear = 0x2601,
Nearest = 0x2600,
Linear = 0x2601,
NearestMipmapNearest = 0x2700,
NearestMipmapLinear = 0x2702,
LinearMipmapNearest = 0x2701,
LinearMipmapLinear = 0x2703,
NearestMipmapLinear = 0x2702,
LinearMipmapNearest = 0x2701,
LinearMipmapLinear = 0x2703,
};
enum WrapMode {
Repeat = 0x2901,
RepeatMirror = 0x8370,
RepeatMirror = 0x8370,
ClampToEdge = 0x812F,
ClampToBorder = 0x812D,
ClampToBorder = 0x812D,
};
Texture();
@ -85,9 +85,9 @@ protected :
unsigned int m_id;
Vector2u m_size;
Vector2u m_size;
PixelFormat m_format;
PixelFormat m_format;
};
} // namespace sp

View file

@ -2,9 +2,9 @@
#ifndef SPECTRE_INTPUT_DEVICE_H
#define SPECTRE_INTPUT_DEVICE_H
namespace sp {
#include "InputModule.h"
class InputModule;
namespace sp {
class InputDevice
{

View file

@ -0,0 +1,157 @@
#ifndef SPECTRE_INPUT_EVENT_H
#define SPECTRE_INPUT_EVENT_H
#include <string>
#include <vector>
namespace sp {
namespace MouseButton {
enum Type {
Unknown,
Left,
Right,
Middle,
Button1,
Button2,
NUM_MBUTTONS,
};
};
namespace Key {
enum Type {
Unknown,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
One,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Zero,
Period,
Comma,
Enter,
Backspace,
Escape,
Space,
Capslock,
Up,
Down,
Left,
Right,
NUMPAD_1,
NUMPAD_2,
NUMPAD_3,
NUMPAD_4,
NUMPAD_5,
NUMPAD_6,
NUMPAD_7,
NUMPAD_8,
NUMPAD_9,
NUMPAD_0,
NUMPAD_Enter,
Home,
End,
Insert,
Delete,
PageUp,
PageDown,
Pause,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
Tab,
LShift,
RShift,
LCtrl,
RCtrl,
LAlt,
RAlt,
NUM_KEYS,
};
}
typedef struct InputEvent
{
enum Type
{
None,
Key,
MouseButton,
MousePosition
};
struct KeyEvent {
Key::Type code;
bool pressed; /* true if pressed, false if released. */
std::string getKeyName() const; /* Get the key name */
};
struct MouseButtonEvent {
MouseButton::Type button;
bool pressed; /* true if pressed, false if released. */
std::string getName() const;
};
struct MouseEvent {
unsigned int x;
unsigned int y;
};
Type type;
union {
struct KeyEvent key;
struct MouseEvent mouse;
struct MouseButtonEvent mouseButton;
};
InputEvent(Type type = None);
} InputEvent;
} // namespace sp
#endif /* SPECTRE_INPUT_EVENT_H */

View file

@ -0,0 +1,17 @@
#ifndef SPECTRE_INPUT_LISTENER_H
#define SPECTRE_INPUT_LISTENER_H
#include "InputEvent.h"
namespace sp {
class InputListener
{
public :
virtual void onInputEvent(const InputEvent& event);
};
} // namespace sp
#endif /* SPECTRE_INPUT_LISTENER_H */

View file

@ -5,6 +5,9 @@
#include <deque>
#include <vector>
#include "InputListener.h"
#include "InputEvent.h"
namespace sp {
class Mouse;
@ -25,6 +28,12 @@ public :
void addInputDevice(InputDevice *device);
void registerListener(InputListener* listener);
void removeListener(InputListener* listener);
void postInputEvent(const InputEvent& event);
// NOTE: Update devices here! (for winapi, process keyboard/mouse messages)
void update();
@ -39,6 +48,11 @@ protected :
Keyboard *m_keyboard;
// Buffered input queue.
std::deque<InputEvent> m_buffer;
std::vector<InputListener*> m_listeners;
PlatformInput *m_platform;
};

View file

@ -3,107 +3,19 @@
#define SPECTRE_INPUT_KEYBOARD_H
#include <string>
#include "InputEvent.h"
#include "InputDevice.h"
namespace sp {
class Keyboard : public InputDevice
{
public :
enum Key {
Unknown,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
One,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Zero,
Period,
Comma,
Enter,
Backspace,
Escape,
Space,
Capslock,
Up,
Down,
Left,
Right,
Numpad1,
Numpad2,
Numpad3,
Numpad4,
Numpad5,
Numpad6,
Numpad7,
Numpad8,
Numpad9,
Numpad0,
Home,
End,
Insert,
Delete,
PageUp,
PageDown,
Pause,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
Tab,
LShift,
RShift,
LCtrl,
RCtrl,
LAlt,
RAlt,
NUM_KEYS,
};
public :
virtual ~Keyboard() {};
virtual bool isKeyDown(Key key) = 0;
virtual bool isKeyDown(Key::Type key) = 0;
static std::string getKeyName(Key key);
static std::string getKeyName(Key::Type key);
};
} // namespace sp

View file

@ -4,39 +4,26 @@
#include <string>
#include <Spectre/Math/Vector2.h>
#include <Spectre/Input/InputDevice.h>
#include "InputEvent.h"
#include "InputDevice.h"
namespace sp {
class Mouse : public InputDevice
{
public :
enum Button {
Unknown,
Left,
Right,
Middle,
XButton1,
XButton2,
NUM_MBUTTONS
};
public :
virtual ~Mouse();
// Get the position in relative (focused window) coordinates.
// coordinates are relative to the window's top-left corner.
// Get mouse position
virtual Vector2f getPosition() const = 0;
// Get the position in absolute (screen) coordinates.
// 0,0 is located at the screen's top-left corner.
virtual Vector2f getAbsPosition() const = 0;
//virtual Vector2i getPositionAbs() const = 0;
virtual bool isButtonDown(Button button) const = 0;
virtual bool isButtonDown(MouseButton::Type button) const = 0;
static std::string getButtonName(Button button);
static std::string getButtonName(MouseButton::Type button);
};
}; // namespace sp
} // namespace sp
#endif /* SPECTRE_INPUT_MOUSE_H */

View file

@ -2,8 +2,6 @@
#ifndef SPECTRE_MATH_MATH_H
#define SPECTRE_MATH_MATH_H
#include "Transform.h"
#include "Vector4.h"
#include "Vector3.h"
#include "Vector2.h"
#include "Matrix4.h"
@ -34,17 +32,21 @@ namespace sp { namespace math
float bottom, float top,
float zNear = -1.0f, float zFar = 1.0f);
//
Vector2f Vector2UnProject(Vector2f point, Transform InverseMVP, Vector4u screen);
// Create a 2D rotation matrix. (rotation around Z-axis)
Matrix4f rotation(float theta);
// Create a 2D translation matrix.
Matrix4f translate(float x, float y);
Matrix4f translate(const Vector2f& v);
// Create a 2D scale matrix.
Matrix4f scale(float x, float y);
Matrix4f scale(const Vector2f& f);
// Get translation part of a matrix.
Vector3f getTranslate(const Matrix4f matrix);
Vector3f getUpVector(const Matrix4f matrix);
Vector3f getForwardVector(const Matrix4f matrix);
} } // namespace sp

View file

@ -58,16 +58,7 @@ struct Matrix3
inline Matrix3<T> operator*(const Matrix3<T>& mat) const;
inline Matrix3<T> operator*=(const Matrix3<T>& mat);
// -----------------
// Arithmetic: Scalar
// -----------------
inline Matrix3<T> operator/(T value) const;
inline Matrix3<T> operator/=(T value);
inline Matrix3<T> operator*(T value) const;
inline Matrix3<T> operator*=(T value);
// Need scalar, vector arithmetic?
// -----------------
// Named operations.
@ -78,9 +69,6 @@ struct Matrix3
// Transpose matrix.
Matrix3<T> transpose() const;
// Inverse
Matrix3<T> inverse() const;
};
template <typename T>

View file

@ -4,8 +4,8 @@
namespace sp {
template<typename T>
sp::Matrix3<T> sp::Matrix3<T>::Identity(
template <>
Matrix3f Matrix3f::Identity(
1, 0, 0,
0, 1, 0,
0, 0, 1
@ -87,39 +87,6 @@ inline Matrix3<T> Matrix3<T>::operator*=(const Matrix3<T>& mat)
return *this;
}
template<typename T>
inline Matrix3<T> Matrix3<T>::operator/(T value) const
{
return Matrix3<T>(
v[0] / value, v[1] / value, v[2] / value,
v[3] / value, v[4] / value, v[5] / value,
v[6] / value, v[7] / value, v[8] / value);
}
template<typename T>
inline Matrix3<T> Matrix3<T>::operator/=(T value)
{
*this = *this / value;
return *this;
}
template<typename T>
inline Matrix3<T> Matrix3<T>::operator*(T value) const
{
return Matrix3<T>(
v[0] * value, v[1] * value, v[2] * value,
v[3] * value, v[4] * value, v[5] * value,
v[6] * value, v[7] * value, v[8] * value);
}
template<typename T>
inline Matrix3<T> Matrix3<T>::operator*=(T value)
{
*this = *this * value;
return *this;
}
template<typename T>
float Matrix3<T>::det() const
{
@ -136,30 +103,6 @@ float Matrix3<T>::det() const
return det;
}
template<typename T>
Matrix3<T> Matrix3<T>::inverse() const
{
float d = det();
if (d != 0.0f) {
float a00 = (v[4] * v[8]) - (v[7] * v[5]);
float a01 = -((v[1] * v[8]) - (v[7] * v[2]));
float a02 = (v[1] * v[5]) - (v[4] * v[2]);
float a10 = -((v[3] * v[8]) - (v[6] * v[5]));
float a11 = (v[0] * v[8]) - (v[6] * v[2]);
float a12 = -((v[0] * v[5]) - (v[3] * v[2]));
float a20 = (v[3] * v[7]) - (v[6] * v[4]);
float a21 = -((v[0] * v[7]) - (v[6] * v[1]));
float a22 = (v[0] * v[4]) - (v[3] * v[1]);
return Matrix3<T>(a00, a01, a02, a10, a11, a12, a20, a21, a22) / d;
}
return Matrix3<T>::Identity;
}
template<typename T>
Matrix3<T> Matrix3<T>::transpose() const
{

View file

@ -1,50 +0,0 @@
#ifndef SPECTRE_MATH_TIME_H
#define SPECTRE_MATH_TIME_H
namespace sp {
class Time {
public :
Time(long value = 0);
double seconds() const;
int milliseconds() const;
long microseconds() const;
// ----------------------------
// Helper construct functions
// ----------------------------
static Time seconds(double value);
static Time milliseconds(int value);
static Time microseconds(long value);
private :
// Microseconds (us)
long m_us;
};
// ----------------------------
// Compare
// ----------------------------
bool operator ==(const Time& a, const Time& b);
bool operator !=(const Time& a, const Time& b);
bool operator <(const Time& a, const Time& b);
bool operator <=(const Time& a, const Time& b);
bool operator >(const Time& a, const Time& b);
bool operator >=(const Time& a, const Time& b);
// ----------------------------
// Arithmetic
// ----------------------------
Time operator +(const Time& a, const Time& b);
Time& operator +=(Time& a, const Time& b);
Time operator -(const Time& a, const Time& b);
Time& operator -=(Time& a, const Time& b);
}; // namespace sp
#endif /* SPECTRE_MATH_TIME_H */

View file

@ -53,11 +53,7 @@ public :
Transform& scale(Vector2f offset);
Transform& scale(float s);
// Inverse
Transform inverse();
Transform& combine(const Transform& other);
Transform& multiply(const Transform& other);
Vector2f transformPoint(float x, float y) const;

View file

@ -30,16 +30,16 @@ struct Vector2
// Named operations.
// -----------------
inline float len() const;
inline float length() const;
inline Vector2<T>& normal();
inline Vector2<T>& normalize();
// Dot product
inline T dot(const Vector2<T>& vec) const;
inline Vector2<T>& reflect(const Vector2<T>& n);
inline std::string toString() const;
std::string toString() const;
};
// ------------
@ -182,14 +182,14 @@ inline std::ostream& operator<<(std::ostream &s, const Vector2<T>& v);
// Common specialization types
// -----------------------------
typedef Vector2<float> Vector2f;
typedef Vector2<int> Vector2i;
typedef Vector2<unsigned> Vector2u;
typedef Vector2<float> Vector2f;
typedef Vector2<int> Vector2i;
typedef Vector2<unsigned> Vector2u;
typedef Vector2<unsigned char> Vector2b;
typedef Vector2<float> vec2f;
typedef Vector2<int> vec2i;
typedef Vector2<unsigned> vec2u;
typedef Vector2<float> vec2f;
typedef Vector2<int> vec2i;
typedef Vector2<unsigned> vec2u;
typedef Vector2<unsigned char> vec2b;
} // namespace sp

View file

@ -31,15 +31,15 @@ inline Vector2<T>::Vector2(const Vector2<U>& vec)
}
template <typename T>
inline float Vector2<T>::len() const
inline float Vector2<T>::length() const
{
return std::sqrt((x * x) + (y * y));
}
template <typename T>
inline Vector2<T>& Vector2<T>::normal()
inline Vector2<T>& Vector2<T>::normalize()
{
float il = 1.0f / len();
float il = 1.0f / length();
x *= il; y *= il;
return *this;
}
@ -58,7 +58,7 @@ inline Vector2<T>& Vector2<T>::reflect(const Vector2<T>& n)
}
template <typename T>
inline std::string Vector2<T>::toString() const
std::string Vector2<T>::toString() const
{
return core::to_string(x) + ", " + core::to_string(y);
}

View file

@ -35,9 +35,9 @@ struct Vector3
// Named operations.
// -----------------
inline float len() const;
inline float length() const;
inline Vector3<T>& normal();
inline Vector3<T>& normalize();
inline Vector2<T> toVec2();
};
@ -159,14 +159,14 @@ inline std::ostream& operator<<(std::ostream &s, const Vector3<T>& v);
// Common specialization types
// -----------------------------
typedef Vector3<float> Vector3f;
typedef Vector3<int> Vector3i;
typedef Vector3<unsigned> Vector3u;
typedef Vector3<float> Vector3f;
typedef Vector3<int> Vector3i;
typedef Vector3<unsigned> Vector3u;
typedef Vector3<unsigned char> Vector3b;
typedef Vector3<float> vec3f;
typedef Vector3<int> vec3i;
typedef Vector3<unsigned> vec3u;
typedef Vector3<float> vec3f;
typedef Vector3<int> vec3i;
typedef Vector3<unsigned> vec3u;
typedef Vector3<unsigned char> vec3b;
} // namespace sp

View file

@ -43,7 +43,7 @@ inline Vector3<T>::Vector3(const Vector2<U>& vec)
}
template <typename T>
inline float Vector3<T>::len() const
inline float Vector3<T>::length() const
{
return std::sqrt((x * x) + (y * y) + (z * z));
}
@ -55,9 +55,9 @@ Vector2<T> Vector3<T>::toVec2()
}
template <typename T>
inline Vector3<T>& Vector3<T>::normal()
inline Vector3<T>& Vector3<T>::normalize()
{
float il = 1.0f / len();
float il = 1.0f / length();
x *= il; y *= il; z *= il;
return *this;
}

View file

@ -29,9 +29,9 @@ struct Vector4
// Named operations
inline float len() const;
inline float length() const;
inline Vector4<T>& normal();
inline Vector4<T>& normalize();
};
// ---------
@ -145,14 +145,14 @@ inline bool operator>=(T s, const Vector4<T>& v);
template <typename T>
inline std::ostream& operator<<(std::ostream &s, const Vector4<T>& v);
typedef Vector4<float> Vector4f;
typedef Vector4<int> Vector4i;
typedef Vector4<unsigned> Vector4u;
typedef Vector4<float> Vector4f;
typedef Vector4<int> Vector4i;
typedef Vector4<unsigned> Vector4u;
typedef Vector4<unsigned char> Vector4b;
typedef Vector4<float> vec4f;
typedef Vector4<int> vec4i;
typedef Vector4<unsigned> vec4u;
typedef Vector4<float> vec4f;
typedef Vector4<int> vec4i;
typedef Vector4<unsigned> vec4u;
typedef Vector4<unsigned char> vec4b;
} // namespace sp

View file

@ -36,15 +36,15 @@ Vector4<T>::Vector4(const Vector4<U>& vec)
}
template <typename T>
float Vector4<T>::len() const
float Vector4<T>::length() const
{
return std::sqrt((x * x) + (y * y) + (z * z) + (w * w));
}
template <typename T>
Vector4<T>& Vector4<T>::normal()
Vector4<T>& Vector4<T>::normalize()
{
float il = 1.0f / len();
float il = 1.0f / length();
x *= il; y *= il; z *= il; w *= il;
return *this;
}

View file

@ -1,15 +0,0 @@
#ifndef SPECTRE_SYSTEM_BYTEORDER_H
#define SPECTRE_SYSTEM_BYTEORDER_H
#include <cstdint>
namespace sp { namespace system
{
uint16_t ltoh16(const uint8_t* bytes);
uint32_t ltoh32(const uint8_t* bytes);
} } // namespace sp::system
#endif /* SPECTRE_SYSTEM_BYTEORDER_H */

View file

@ -1,76 +0,0 @@
#ifndef SPECTRE_SYSTEM_EVENT_H
#define SPECTRE_SYSTEM_EVENT_H
#include <Spectre/Input/Mouse.h>
#include <Spectre/Input/Keyboard.h>
namespace sp {
class Window;
struct Event
{
public :
enum Type {
Unknown,
Quit,
Size,
Key,
MouseButton,
MouseMove
};
struct KeyEvent {
Keyboard::Key code;
bool pressed; /* true if pressed, false if released. */
std::string getKeyName() const; /* Get the key name */
};
struct MouseButtonEvent {
Mouse::Button button;
bool pressed; /* true if pressed, false if released. */
std::string getName() const;
};
struct MouseMoveEvent {
unsigned int x;
unsigned int y;
};
struct SizeEvent
{
Window *window;
int width;
int height;
};
Type type;
union {
struct SizeEvent size;
struct KeyEvent key;
struct MouseMoveEvent mouseMove;
struct MouseButtonEvent mouseButton;
};
Event(Type type = Unknown);
std::string toString() const;
// Helper methods
static Event createSize(Window *window, int width, int height);
static Event createKey(Keyboard::Key code, bool pressed);
static Event createMouseButton(Mouse::Button button, bool pressed);
static Event createMouseMove(unsigned int x, unsigned int y);
};
} // namespace sp
#endif /* SPECTRE_SYSTEM_EVENT_H */

View file

@ -1,23 +0,0 @@
#ifndef SYSTEM_EVENT_LISTENER_H
#define SYSTEM_EVENT_LISTENER_H
#include <Spectre/System/Event.h>
#include <Spectre/Input/Mouse.h>
#include <Spectre/Input/Keyboard.h>
namespace sp {
class Window;
class EventListener
{
public :
virtual void onSizeChanged(Window* window, int width, int height);
virtual void onEvent(const Event& event);
};
} // namespace sp
#endif /* SYSTEM_EVENT_LISTENER_H */

View file

@ -2,118 +2,18 @@
#ifndef SPECTRE_SYSTEM_FILE_H
#define SPECTRE_SYSTEM_FILE_H
#include <stdio.h>
#include <vector>
#include <string>
#include <system_error>
namespace sp {
class File
namespace sp { namespace file
{
public :
std::string getBasename(const std::string& path);
enum struct Access {
READ = 1 << 0,
WRITE = 1 << 1,
READ_WRITE = READ | WRITE,
};
std::string getExtension(const std::string& path);
// NOTE: These are ignored atm. as implementation uses stdio.h
enum OpenMode {
// Only open if file exists and
// in overwrite mode if write is enabled.
DEFAULT = 0,
// Create file if it does not exist (ignored in read-only mode)
CREATE = 1 << 0,
// If file exists any write calls will
// append to the file. (ignored in read-only mode)
APPEND = 1 << 1,
// If file exists it's content are discarded
// resulting in an empty file. (ignored in read-only mode)
TRUNCATE = 1 << 2
};
std::string getPathname(const std::string& path);
// Methods.
public :
File();
// see `open()`
File(const std::string& filename,
Access access = Access::READ,
unsigned int mode = DEFAULT);
~File();
// Opens a file (default in read-only)
bool open(const std::string& filename,
Access access = Access::READ,
unsigned int mode = DEFAULT);
// Returns true if the file is open, false otherwise.
bool isOpen() const;
// Close the file.
void close();
std::string getErrorMessage() const;
// Get the current position in the file.
size_t pos();
// Set the file stream position.
// if `from_end` is true. `offset` will be applied from the end of file, otherwise from beginning.
// Returns true if the position was updated, false otherwise.
bool set(long int pos = 0, bool from_end = false);
// Move the current file stream position with `offset` bytes.
// This is equivalent to calling set(pos() + offset)
// Returns true if the position was updated, false otherwise.
bool seek(long int offset);
// Get the size of the file (in bytes)
size_t size() const;
// Read `size` data from file at the current position.
// Content is stored in `ptr` and must be alteast `size` bytes.
// Returns -1 if an error occured. Otherwice the number of bytes read is returned.
size_t read(void *ptr, size_t size);
// Read all remaining data from file at the current position. Content is stored in `buffer`.
// Returns true if exactly all data could be read from file. false otherwise.
template <typename buffer_t>
inline bool read(buffer_t& buffer)
{
size_t s = size();
buffer.resize(s);
return read((void*) &buffer[0], s) == s;
}
// Read contents into str until null (\0)
size_t readString(std::string &str);
// Write data to file at the current position.
// Returns -1 if an error occured. Otherwice the number of bytes written is returned.
size_t write(const void *ptr, size_t size);
// Write data to file at the current position.
// Returns true if exactly all data could be written from `buffer`. false otherwise.
template <typename buffer_t>
inline bool write(const buffer_t& buffer)
{
return write((const void*) &buffer[0], buffer.size()) == buffer.size();
}
// Flush any buffered data to the file.
bool flush();
private :
FILE *m_handle;
// Error
mutable std::error_condition m_error;
};
} //namespace sp
std::vector<unsigned char> read(const std::string& path);
} }
#endif /* SPECTRE_SYSTEM_FILE_H */

View file

@ -7,8 +7,6 @@
namespace sp {
namespace log { class Writer; }
class Log
{
public :
@ -17,24 +15,17 @@ public :
T_WARNING = 1 << 0,
T_CRITICAL = 1 << 1,
T_ERROR = 1 << 2,
T_DEBUG = 1 << 3
};
static void setWriter(log::Writer* writer);
static void info(const char *message, ...);
static void info(const char *format, ...);
static void warn(const char *message, ...);
static void warn(const char *format, ...);
static int error(const char *format, ...);
static void debug(const char *format, ...);
static int error(const char *message, ...);
private :
static void writeln(Type type, const char *fmt, va_list args);
static log::Writer* _writer;
};
} // namespace sp

View file

@ -1,32 +0,0 @@
#ifndef SPECTRE_SYSTEM_LOG_FILEWRITER_H
#define SPECTRE_SYSTEM_LOG_FILEWRITER_H
#include <stdio.h>
#include <string>
#include <Spectre/System/Log/Writer.h>
namespace sp { namespace log {
class FileWriter : public Writer
{
public:
FileWriter(const std::string file = "");
~FileWriter();
bool open(const std::string file);
bool close();
size_t write(const void *data, size_t len);
virtual bool flush();
protected:
FILE *m_fd;
};
} } // sp::log
#endif /* SPECTRE_SYSTEM_LOG_FILEWRITER_H */

View file

@ -1,19 +0,0 @@
#ifndef SPECTRE_SYSTEM_LOG_WRITER_H
#define SPECTRE_SYSTEM_LOG_WRITER_H
namespace sp { namespace log {
class Writer
{
public:
virtual ~Writer() {}
virtual size_t write(const void *data, size_t len) = 0;
virtual bool flush() = 0;
};
} } // sp::log
#endif /* SPECTRE_SYSTEM_LOG_WRITER_H */

View file

@ -2,25 +2,16 @@
#ifndef SPECTRE_SYSTEM_MESSAGEHANDLER_H
#define SPECTRE_SYSTEM_MESSAGEHANDLER_H
#include <vector>
#include "EventListener.h"
#include "SystemEvent.h"
namespace sp {
class MessageHandler : public EventListener
class Display;
class MessageHandler
{
public :
void registerListener(EventListener *listener);
void unregisterListener(EventListener *listener);
virtual void onSizeChanged(Window* window, int width, int height);
virtual void onEvent(const Event& event);
protected :
std::vector<EventListener*> m_listeners;
virtual void onSizeChanged(Display* display, int width, int height);
};
} // namespace sp

View file

@ -2,29 +2,22 @@
#ifndef SPECTRE_MESSAGE_QUEUE_H
#define SPECTRE_MESSAGE_QUEUE_H
#include <Spectre/System/Event.h>
#include <Spectre/System/SystemEvent.h>
#include <queue>
namespace sp {
class PlatformEventQueue;
class MessageQueue
{
public :
MessageQueue();
~MessageQueue();
void postEvent(SysEvent event);
void postEvent(Event event);
bool pollEvent(Event& event);
bool pollEvent(SysEvent& event);
bool isEmpty() const;
protected :
std::deque<Event> m_queue;
PlatformEventQueue* m_impl;
std::deque<SysEvent> m_queue;
};
} // namespace sp

View file

@ -1,19 +0,0 @@
#ifndef SYSTEM_PATH_H
#define SYSTEM_PATH_H
#include <string>
namespace sp {
class Path
{
public :
static std::string getBasename(const std::string& path);
static std::string getExtension(const std::string& path);
};
} // namespace sp
#endif /* SYSTEM_PATH_H */

View file

@ -1,27 +0,0 @@
#ifndef SPECTRE_SYSTEM_STOPWATCH_H
#define SPECTRE_SYSTEM_STOPWATCH_H
#include <Spectre/Math/Time.h>
namespace sp {
class Stopwatch {
public :
Stopwatch();
// Restart the watch. also returns the elapsed time before
// the watch was restarted.
Time restart();
// Get the elapsed time since the watch was restarted.
Time elapsed() const;
private :
Time m_start;
};
} // namespace sp
#endif /* SPECTRE_SYSTEM_STOPWATCH_H */

View file

@ -0,0 +1,41 @@
#ifndef SYSTEM_EVENT_H
#define SYSTEM_EVENT_H
namespace sp {
class Display;
struct SysEvent
{
public :
enum Type {
None,
Quit,
Size,
};
Type type;
struct Size
{
Display *display;
int width;
int height;
};
union {
struct Size size;
};
SysEvent(Type type = None);
// Helper methods
static SysEvent sizeEvent(Display *display, int width, int height);
};
} // namespace sp
#endif /* SYSTEM_EVENT_H */

View file

@ -1,41 +0,0 @@
#ifndef SPECTRE_WINDOW_GLWINDOW_H
#define SPECTRE_WINDOW_GLWINDOW_H
#include <Spectre/Window/Window.h>
#include <Spectre/Window/GLContext.h>
namespace sp {
class GLContext;
// GLWindow represents a window that has an OpenGL context attached to it.
class GLWindow : public Window
{
public:
GLWindow();
virtual ~GLWindow();
virtual bool create(WindowDescription decription);
virtual void destroy();
bool activate(bool value);
// Enable/Disable Vertical Sync.
bool enableVSync(bool value);
void swapBuffers();
protected:
virtual void onReshape(int width, int height);
private:
GLContext* m_context;
};
} // namepsace sp
#endif /* SPECTRE_WINDOW_GLWINDOW_H */

View file

@ -1,83 +0,0 @@
#ifndef SPECTRE_WINDOW_WINDOW_H
#define SPECTRE_WINDOW_WINDOW_H
#include "DisplayMode.h"
#include "WindowDescription.h"
#include <Spectre/Math/Vector2.h>
#include <cstdint>
#include <string>
namespace sp {
class PlatformWindow;
class GLContext;
class Window
{
friend class PlatformWindow;
public :
enum Mode {
WINDOWED = 0,
FULLSCREEN = 1,
WINDOWEDFULLSCREEN = 2,
};
public :
Window();
virtual ~Window();
virtual bool create(WindowDescription decription);
virtual void destroy();
void setSize(unsigned int width, unsigned int height);
sp::Vector2u getSize() const;
void setCaption(const std::string& title);
const std::string& getCaption() const;
void setIcon(const std::string& filename);
void setIcon(unsigned int width, unsigned int height, const uint8_t *pixels);
void setDisplayMode(const DisplayMode& mode);
const DisplayMode& getDisplayMode() const;
void setVideoMode(Mode mode);
enum Mode getVideoMode() const;
void setVisible(bool visible);
void showCursor(bool value);
void grabCursor(bool value);
protected :
void init();
virtual void onReshape(int width, int height);
protected :
enum Mode m_fmode;
// Cache window position when entering fullscreen
// So it can be restored when returning to window mode.
Vector2u m_cachePos;
WindowDescription m_description;
WindowDescription m_cacheDesc;
std::string m_caption;
PlatformWindow* m_impl;
};
} // namepsace sp
#endif /* SPECTRE_WINDOW_WINDOW_H */

View file

@ -1,34 +0,0 @@
#ifndef SPECTRE_WINDOW_WINDOWDESCRIPTION_H
#define SPECTRE_WINDOW_WINDOWDESCRIPTION_H
#include "DisplayMode.h"
namespace sp {
namespace WindowDecorate {
enum Type {
Empty = 0,
Menu = 1 << 0,
Resize = 1 << 1,
Close = 1 << 2,
Default = Menu | Resize | Close,
};
};
struct WindowDescription
{
public :
WindowDescription();
WindowDescription(DisplayMode mode, unsigned decoration = WindowDecorate::Default);
public :
DisplayMode mode;
unsigned int decoration;
};
} // namespace sp
#endif /* SPECTRE_WINDOW_WINDOWDESCRIPTION_H */

View file

@ -4,13 +4,6 @@
namespace sp {
std::string core::to_string(int value)
{
char buf[32];
sprintf(buf, "%i", value);
return std::string(buf);
}
std::string core::to_string(unsigned int value)
{
char buf[32];

154
source/Display/Display.cpp Normal file
View file

@ -0,0 +1,154 @@
#include <iostream>
#include <Spectre/Display/Display.h>
#include <Spectre/Display/GLContext.h>
#include <Spectre/System/SystemEvent.h>
#include <Platform/PlatformDisplay.h>
namespace sp {
#define CAPTION_DEFAULT "Spectre"
#define ICON_DEFAULT "./assets/app.ico"
Display::Display()
{
m_caption = CAPTION_DEFAULT;
m_fmode = WINDOWED;
m_context = GLContext::create();
m_impl = PlatformDisplay::make(this);
}
Display::~Display()
{
delete m_context;
delete m_impl;
}
bool Display::create(DisplayDescription description)
{
destroy();
if (!m_impl->create(description)) {
return false;
}
if (!m_context->create(m_impl)) {
return false;
}
init();
m_description = description;
return true;
}
void Display::init()
{
m_impl->setCaption(m_caption);
setIcon(ICON_DEFAULT);
activate(true);
enableVSync(false);
showCursor(true);
}
void Display::destroy()
{
m_context->destroy();
m_impl->destroy();
}
void Display::setCaption(const std::string& caption)
{
m_caption = caption;
m_impl->setCaption(m_caption);
}
const std::string& Display::getCaption() const
{
return m_caption;
}
void Display::setIcon(const std::string& filename)
{
m_impl->setIcon(filename);
}
void Display::setSize(unsigned int width, unsigned int height)
{
m_description.mode.width = width;
m_description.mode.height = height;
m_impl->setSize(width, height);
}
void Display::setVideoMode(Mode mode)
{
DisplayDescription desc;
if (m_fmode == mode) {
return;
}
if (mode == FULLSCREEN || mode == WINDOWEDFULLSCREEN) {
// True fullscreen
if (mode == FULLSCREEN) {
desc.mode = m_description.mode;
} else {
desc.mode = DisplayMode::getDesktopMode();
m_cacheDesc = m_description;
}
desc.decoration = DisplayDecorate::None;
} else {
desc = m_cacheDesc;
}
create(desc);
m_fmode = mode;
}
enum Display::Mode Display::getVideoMode() const
{
return m_fmode;
}
void Display::showCursor(bool value)
{
m_impl->showCursor(value);
}
bool Display::activate(bool value)
{
if (value) {
return m_context->activate();
}
return m_context->deactivate();
}
bool Display::enableVSync(bool value)
{
return m_context->setSwapInterval(value ? 1 : 0);
}
void Display::swapBuffers()
{
if (activate(true)) {
m_context->swapBuffers();
}
}
void Display::onReshape(int width, int height)
{
// Resize context if the windows resizes.
m_context->setSize(width, height);
}
} // namespace sp

View file

@ -0,0 +1,18 @@
#include <Spectre/Display/DisplayDescription.h>
namespace sp {
DisplayDescription::DisplayDescription() :
mode (),
decoration (DisplayDecorate::Default)
{
}
DisplayDescription::DisplayDescription(DisplayMode mode, unsigned decoration) :
mode (mode),
decoration (decoration)
{
}
} // namespace sp

View file

@ -1,5 +1,5 @@
#include <Spectre/Window/DisplayMode.h>
#include <Spectre/Display/DisplayMode.h>
#include <Platform/PlatformMisc.h>
#include <algorithm>
@ -22,14 +22,14 @@ struct DisplayModeCmp
DisplayMode::DisplayMode() :
width (0),
height (0),
bpp (0)
bpp (32)
{
}
DisplayMode::DisplayMode(unsigned int width, unsigned int height, unsigned int bpp) :
width (width),
height (height),
bpp (bpp)
bpp (bpp)
{
}
@ -55,9 +55,4 @@ DisplayMode DisplayMode::getDesktopMode()
return PlatformMisc::GetDesktopMode();
}
bool DisplayMode::empty() const
{
return (width + height + bpp) == 0;
}
} // namespace sp

View file

@ -0,0 +1,23 @@
#include <Spectre/Display/GLContext.h>
#ifdef _WIN32
#include <Platform/Win32/Win32GLContext.h>
typedef sp::Win32GLContext ContextType;
#else
#error "No GLContext implementation exists"
#endif
namespace sp {
GLContext* GLContext::create()
{
return new ContextType();
}
GLContext::~GLContext()
{
// Nothing to do.
}
} // namespace sp

View file

@ -3,49 +3,45 @@
#include <Spectre/Game/GameTime.h>
#include <Spectre/Game/FPSCounter.h>
#include <Spectre/Input/InputModule.h>
#include <Spectre/System/Log.h>
#include <Spectre/System/Log/FileWriter.h>
#include <Spectre/System/MessageHandler.h>
#include <Spectre/System/MessageQueue.h>
#include <Spectre/Game.h>
#include <Platform/PlatformApplication.h>
#include <Platform/PlatformMisc.h>
#include <Platform/Win32/Win32Application.h>
#include <Spectre/Game.h>
namespace sp {
Game::Game() :
m_running(false)
Game::Game()
{
m_platform = PlatformApplication::get();
m_platform = new Win32Application();
m_running = false;
m_graphics = new Graphics(m_platform);
m_input = new InputModule(&m_platform->getInput());
m_messageHandler = new MessageHandler();
// Setup log
m_log_writer = new log::FileWriter("stdout");
Log::setWriter(m_log_writer);
m_messageHandler = new MessageHandler();
}
Game::~Game()
{
delete m_input;
delete m_graphics;
delete m_platform;
delete m_messageHandler;
}
// TODO: This is abit ugly tbh.
m_platform->shutdown();
void Game::setup()
{
m_graphics->init();
m_graphics->setClearColor(0.0f, 0.0f, 0.0f);
init();
}
void Game::run()
{
m_platform->init();
if (!m_graphics->init()) {
return;
}
init();
setup();
gameLoop();
}
@ -60,9 +56,6 @@ void Game::gameLoop()
processEvents();
// Update input.
getInput()->update();
if (time.beginFrame()) {
while(time.tick()) {
@ -78,22 +71,22 @@ void Game::gameLoop()
void Game::processEvents()
{
MessageQueue& queue = m_platform->getMessageQueue();
Event event;
SysEvent event;
m_platform->update();
while(queue.pollEvent(event)) {
if (event.type == Event::Quit) {
if (event.type == SysEvent::Quit) {
exit();
break;
}
// Call message handler.
if (event.type == Event::Size) {
m_messageHandler->onSizeChanged(event.size.window, event.size.width, event.size.height);
if (event.type == SysEvent::Size) {
m_messageHandler->onSizeChanged(event.size.display, event.size.width, event.size.height);
}
m_messageHandler->onEvent(event);
}
}
@ -117,9 +110,4 @@ FPSCounter& Game::getFpsCounter()
return m_fpsCounter;
}
MessageHandler* Game::getMessageHandler() const
{
return m_messageHandler;
}
} // namespace sp

View file

@ -5,9 +5,9 @@
namespace sp {
FPSCounter::FPSCounter() :
m_fps (60.0f)
m_fps (60.0f),
m_updateRate (2000)
{
m_updateRate = Time::seconds(2);
reset();
}
@ -16,19 +16,19 @@ void FPSCounter::addFrame()
m_count++;
}
double FPSCounter::getFPS() const
float FPSCounter::getFPS() const
{
return m_fps;
}
void FPSCounter::setUpdateRate(unsigned int rate)
void FPSCounter::setUpdateRate(unsigned int ups)
{
// Clamp to 1.
if (rate < 1) {
rate = 1;
if (ups < 1) {
ups = 1;
}
m_updateRate = Time::seconds(rate);
m_updateRate = ups * 1000;
// Must reset the counter.
reset();
@ -36,12 +36,15 @@ void FPSCounter::setUpdateRate(unsigned int rate)
bool FPSCounter::update()
{
Time elapsed = m_watch.elapsed();
unsigned int current = system::getMilliseconds();
unsigned int elapsed = current - m_time;
if (elapsed >= m_updateRate) {
m_fps = m_count / elapsed.seconds();
float fraction = m_count / ((float) elapsed);
m_fps = fraction * 1000.f;
reset();
m_time = current;
m_count = 0;
return true;
}
return false;
@ -49,7 +52,7 @@ bool FPSCounter::update()
void FPSCounter::reset()
{
m_watch.restart();
m_time = system::getMilliseconds();
m_count = 0;
}

View file

@ -7,44 +7,44 @@ namespace sp {
GameTime::GameTime(unsigned long updates_per_sec)
{
m_acc = 0;
m_current = system::getMilliseconds();
m_lastUpdate = m_current;
setTimeStep(updates_per_sec);
}
double GameTime::getTimeStep() const
{
return m_slice.milliseconds();
return m_slice;
}
void GameTime::setTimeStep(unsigned long updates_per_sec)
{
m_slice = Time::seconds(1.0f / ((double) updates_per_sec));
m_max_acc = Time::seconds(1.0f / m_slice.seconds());
m_slice = (1000.0f / ((double) updates_per_sec));
reset();
}
Time GameTime::getElapsed() const
unsigned long GameTime::getElapsed() const
{
return m_watch.elapsed();
return m_current - m_lastUpdate;
}
bool GameTime::beginFrame()
{
reset();
accumulateTime();
// Signal if we should tick
return shouldTick();
}
bool GameTime::shouldTick() const
{
// if acc is larger than one slice, we have atleast one tick.
return m_acc > m_slice;
if (m_acc > m_slice) {
m_inLoop = true;
}
return m_inLoop;
}
bool GameTime::tick()
{
if (shouldTick()) {
if (m_acc > m_slice) {
m_acc -= m_slice;
return true;
}
@ -53,14 +53,27 @@ bool GameTime::tick()
void GameTime::reset()
{
m_watch.restart();
m_lastUpdate = m_current;
m_inLoop = false;
}
void GameTime::accumulateTime()
{
m_acc += m_watch.restart();
if (m_acc > m_max_acc) {
m_acc = m_max_acc;
updateTime();
m_acc += (double) (m_current - m_lastUpdate);
if (m_acc > (1000.f / m_slice)) {
m_acc = 1000.f / m_slice;
}
}
void GameTime::updateTime()
{
m_current = system::getMilliseconds();
// Just to be safe. check so we don't get a negative interval.
if (m_current < m_lastUpdate) {
m_lastUpdate = m_current;
}
}

View file

@ -1,68 +0,0 @@
#include "OpenGLDrv.h"
#include <GfxDriver/OpenGL/OpenGLShaderProgram.h>
#include <Graphics/GL/gl.h>
namespace sp {
std::string OpenGLDrv::getName() const {
return "OpenGL";
}
std::string OpenGLDrv::getVersion() const {
char buf[512];
std::string prof = "Compability";
GLint flags;
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &flags);
if (flags & GL_CONTEXT_CORE_PROFILE_BIT) {
prof = "Core";
}
snprintf(buf, sizeof(buf), "%s %s", prof.c_str(), glGetString(GL_VERSION));
return std::string(buf);
}
std::string OpenGLDrv::getVendor() const
{
return std::string((char*)glGetString(GL_VENDOR));
}
std::string OpenGLDrv::getCardName() const
{
return std::string((char*)glGetString(GL_RENDERER));
}
void OpenGLDrv::setViewport(int x, int y, int width, int height)
{
glViewport(x, y, width, height);
}
void OpenGLDrv::setClearColor(float r, float g, float b, float a)
{
glClearColor(r, g, b, 1.0f);
}
void OpenGLDrv::clearBuffer(GfxDriver::BufferFlags flags)
{
int glFlags = 0;
if (flags == GfxDriver::CLEAR_BUFFER_BIT) {
glFlags |= GL_COLOR_BUFFER_BIT;
}
glClear(glFlags);
}
void OpenGLDrv::clearColorBuffer()
{
glClear(GL_COLOR_BUFFER_BIT);
}
ShaderProgram* OpenGLDrv::createShaderProgram() {
return new OpenGLShaderProgram();
}
} // namespace sp

View file

@ -1,35 +0,0 @@
#ifndef SPECTRE_GFXDRIVER_OPENGL_OPENGLDRV_H
#define SPECTRE_GFXDRIVER_OPENGL_OPENGLDRV_H
#include <Spectre/GfxDriver/GfxDriver.h>
namespace sp {
class ShaderProgram;
class OpenGLDrv : public GfxDriver
{
public:
virtual std::string getName() const;
virtual std::string getVersion() const;
virtual std::string getVendor() const;
virtual std::string getCardName() const;
virtual void setViewport(int x, int y, int width, int height);
virtual void setClearColor(float r, float g, float b, float a);
virtual void clearBuffer(GfxDriver::BufferFlags flags);
virtual void clearColorBuffer();
virtual ShaderProgram* createShaderProgram();
};
} // namespace sp
#endif /* SPECTRE_GFXDRIVER_GFXDRIVER_H */

View file

@ -1,185 +0,0 @@
#include "OpenGLShaderProgram.h"
namespace sp {
OpenGLShaderProgram::OpenGLShaderProgram()
{
m_extension = "glsl";
m_id = glCreateProgram();
}
OpenGLShaderProgram::~OpenGLShaderProgram()
{
if (m_id > 0) {
glDeleteProgram(m_id);
}
}
bool OpenGLShaderProgram::loadFromMemory(const std::string& source, ShaderType type)
{
const char *s = source.c_str();
GLuint shader_id = glCreateShader(type == ShaderType::Vertex
? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
glShaderSource(shader_id, 1, &s, NULL);
if (!compileShader(shader_id)) {
return false;
}
return attachShader(shader_id);
}
bool OpenGLShaderProgram::link()
{
GLint status;
glLinkProgram(m_id);
// Query OpenGL for link status.
glGetProgramiv(m_id, GL_LINK_STATUS, &status);
m_linked = status == GL_TRUE;
if (!m_linked) {
m_error = fetchErrorLog();
}
return m_linked;
}
// Enable this shader
// All shader operations after this call will affect this shader.
void OpenGLShaderProgram::enable() const
{
glUseProgram(m_id);
}
// Disable this shader
// Operations will no longer affect this shader after this call.
void OpenGLShaderProgram::disable() const
{
glUseProgram(0);
}
// ---------------------
// Variables.
// ---------------------
bool OpenGLShaderProgram::setMVPMatrix(const Matrix4f& matrix)
{
return setUniform("u_MVP", matrix);
}
// ---------------------
// General Variables.
// ---------------------
bool OpenGLShaderProgram::setAttribute(const std::string& name, float value) const
{
int loc;
if (getAttribLoc(name, loc)) {
glVertexAttrib1f(loc, value);
return true;
}
return false;
}
bool OpenGLShaderProgram::setAttribute(const std::string& name, const Matrix4f& matrix) const
{
int loc;
if (getAttribLoc(name, loc)) {
glVertexAttrib4fv(loc, matrix.e);
return true;
}
return false;
}
bool OpenGLShaderProgram::setUniform(const std::string& name, const Matrix4f& matrix) const
{
int loc;
if (getUniformLoc(name, loc)) {
glUniformMatrix4fv(loc, 1, GL_FALSE, matrix.e);
return true;
}
return false;
}
bool OpenGLShaderProgram::setUniform(const std::string& name, const Color& color) const
{
int loc;
if (getUniformLoc(name, loc)) {
Vector4f c = color.toRGBAf();
glUniform4f(loc, c.x, c.y, c.z, c.w);
return true;
}
return false;
}
bool OpenGLShaderProgram::getAttribLoc(const std::string& name, int& loc) const
{
loc = glGetAttribLocation(m_id, name.c_str());
if (loc < 0) {
m_error = "Attribute variable '" + name + "' was not found in shader.";
return false;
}
return true;
}
bool OpenGLShaderProgram::getUniformLoc(const std::string& name, int& loc) const
{
loc = glGetUniformLocation(m_id, name.c_str());
if (loc < 0) {
m_error = std::string("Uniform variable '" + name + "' was not found in shader.");
return false;
}
return true;
}
std::string OpenGLShaderProgram::fetchErrorLog() const
{
GLchar buf[4096] = { '\0' };
glGetProgramInfoLog(m_id, sizeof(buf), NULL, buf);
return std::string(buf);
}
bool OpenGLShaderProgram::compileShader(GLuint id)
{
glCompileShader(id);
// Query OpenGL for status.
GLint status;
glGetShaderiv(id, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLchar buf[4096] = { '\0' };
glGetShaderInfoLog(id, sizeof(buf), NULL, buf);
m_error = std::string(buf);
return false;
}
return true;
}
bool OpenGLShaderProgram::attachShader(GLuint id)
{
GLenum err;
glAttachShader(m_id, id);
err = glGetError();
if (err == GL_INVALID_VALUE) {
m_error = "Invalid Value";
return false;
} else if (err == GL_INVALID_OPERATION) {
m_error = "Invalid operation";
return false;
} else if (err != GL_NO_ERROR) {
m_error = "Unkown Error";
return false;
}
return true;
}
} // namespace sp

View file

@ -1,70 +0,0 @@
#ifndef SPECTRE_GFXDRIVER_OPENGL_OPENGLSHADERPROGRAM_H
#define SPECTRE_GFXDRIVER_OPENGL_OPENGLSHADERPROGRAM_H
#include <Graphics/GL/gl.h>
#include <Spectre/GfxDriver/ShaderProgram.h>
namespace sp {
class OpenGLShaderProgram : public ShaderProgram
{
public:
OpenGLShaderProgram();
virtual ~OpenGLShaderProgram();
// Load a shader from memory.
virtual bool loadFromMemory(const std::string& source, ShaderType type);
// Link the program.
virtual bool link();
// Enable this shader
// All shader operations after this call will affect this shader.
virtual void enable() const;
// Disable this shader
// Operations will no longer affect this shader after this call.
virtual void disable() const;
// ---------------------
// Variables.
// ---------------------
virtual bool setMVPMatrix(const Matrix4f& matrix);
// ---------------------
// General Variables.
// ---------------------
virtual bool setAttribute(const std::string& name, float value) const;
virtual bool setAttribute(const std::string& name, const Matrix4f& matrix) const;
virtual bool setUniform(const std::string& name, const Matrix4f& matrix) const;
virtual bool setUniform(const std::string& name, const Color& color) const;
protected :
// Compile a shader.
bool compileShader(GLuint id);
// Attach shader to program.
bool attachShader(GLuint id);
bool getAttribLoc(const std::string& name, int& loc) const;
bool getUniformLoc(const std::string& name, int& loc) const;
std::string fetchErrorLog() const;
protected :
// Program ID
GLuint m_id;
};
} // namespace sp
#endif /* SPECTRE_GFXDRIVER_OPENGL_OPENGLSHADERPROGRAM_H */

View file

@ -1,69 +0,0 @@
#include <Spectre/System/Path.h>
#include <Spectre/System/File.h>
#include <Spectre/GfxDriver/ShaderProgram.h>
#include <string>
namespace sp
{
ShaderProgram::~ShaderProgram()
{
}
bool ShaderProgram::loadFromFile(const std::string& filename)
{
std::string extension = Path::getExtension(filename);
// Meta file. load real shaders.
if (extension == "shader." + m_extension) {
// FIXME: This is ugly :)
std::string base_name = filename.substr(0, filename.length() - extension.length());
// vert and frag are not optional. they must exist.
return loadFromFile(base_name + "vert." + m_extension, ShaderType::Vertex) &&
loadFromFile(base_name + "frag." + m_extension, ShaderType::Fragment);
} else if (extension == "vert." + m_extension) {
return loadFromFile(filename, ShaderType::Vertex);
} else if (extension == "frag." + m_extension) {
return loadFromFile(filename, ShaderType::Fragment);
}
m_error = "Invalid file extension: " + extension;
return false;
}
bool ShaderProgram::loadFromFile(const std::string& filename, ShaderType type)
{
std::string src;
File file;
if (!file.open(filename)) {
m_error = "Can't open file: " + filename;
return false;
}
// Load file into memory.
if (!file.read(src)) {
m_error = "Could not read file: " + filename;
return false;
}
return loadFromMemory(src, type);
}
bool ShaderProgram::isLinked() const
{
return m_linked;
}
std::string ShaderProgram::getLastError() const
{
return m_error;
}
} // namespace sp

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