这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,7 @@ perf.data*

# macOS
.DS_Store

# copyrighted assets
/assets/converted/
/assets/terrain/
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ Henry Snoek <?> <snoek09@users.noreply.github.com>
coop shell (Michael Enßlin, Jonas Jelten, Andre Kupka) <coop@sft.mx>
Franz-Niclas Muschter <fm@stusta.net> <franz-niclas.muschter@stusta.net>
Niklas Fiekas <niklas.fiekas@backscattering.de> <niklas.fiekas@tu-clausthal.de>
Wojciech Nawrocki <wjnawrocki@protonmail.com> <wjnawrocki+gh@protonmail.com>
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ if(NOT DEFINED WANT_INOTIFY)
set(WANT_INOTIFY if_available)
endif()

if(NOT DEFINED WANT_OPENGL)
set(WANT_OPENGL if_available)
endif()

if(NOT DEFINED WANT_VULKAN)
set(WANT_VULKAN if_available)
endif()

if(NOT DEFINED WANT_GPERFTOOLS_PROFILER)
set(WANT_GPERFTOOLS_PROFILER if_available)
endif()
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Technology | Component
**Qt5** | Graphical user interface
**Cython** | Glue code
**CMake** | Build system
**OpenGL2.1** | Rendering, shaders
**OpenGL3.3** | Rendering, shaders
**SDL2** | Cross-platform Audio/Input/Window handling
**Opus** | Audio codec
[**nyan**](https://github.com/SFTtech/nyan) | Content Configuration and Modding
Expand Down
4 changes: 2 additions & 2 deletions buildsystem/modules/FindInotify.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2014-2014 the openage authors. See copying.md for legal info.
# Copyright 2014-2018 the openage authors. See copying.md for legal info.

# This module defines
#
Expand All @@ -8,6 +8,6 @@
find_path(INOTIFY_INCLUDE_DIR sys/inotify.h HINTS /usr/include/${CMAKE_LIBRARY_ARCHITECTURE})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(INOTIFY DEFAULT_MSG INOTIFY_INCLUDE_DIR)
find_package_handle_standard_args(inotify DEFAULT_MSG INOTIFY_INCLUDE_DIR)

mark_as_advanced(INOTIFY_INCLUDE_DIR)
3 changes: 2 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ def getenv_bool(varname):
OPTIONS = {
"backtrace": "if_available",
"inotify": "if_available",
"opengl": "if_available",
"vulkan": "if_available",
"gperftools-tcmalloc": False,
"gperftools-profiler": "if_available",
"ncurses": "if_available",
Expand All @@ -82,7 +84,6 @@ def features(args, parser):
the defaults below will be used.
"""


def sanitize_option_name(option):
""" Check if the given feature exists """
if option not in OPTIONS:
Expand Down
105 changes: 105 additions & 0 deletions doc/code/renderer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Openage graphics
The graphics subsystem is implemented in two levels. The first level is an abstraction over graphics APIs (OpenGL, Vulkan) and provides generic shader execution methods. The second level uses the first to draw openage-specific graphics, i.e. the actual world, units, etc.

### Namespaces:
`openage::renderer` - the level 1 renderer
`openage::renderer::opengl` - the OpenGL implementation
`openage::renderer::vulkan` - the Vulkan implementation
`openage::renderer::resources` - management of graphics assets

__TODO name__
`openage::graphics` - the level 2 system

Every namespace is an actual directory and all its classes are contained there.

## Level 1:
### Overview
First things first, we might want to support multiple APIs. For now just OpenGL, but maybe Vulkan or some others. We want to abstract over these, but this can't unfortunately be done at the level of graphics primitives like textures, buffers, etc. Well, it can, but it introduces unnecessary complexity and possible overhead. That is because the next-gen (Vulkan, Metal, DX12) APIs are vastly different from the old ones - most importantly, they're bindless, so something like a Vulkan context (GL notion) doesn't even make sense. We therefore choose to abstract on the higher level of things-to-draw.

It works similarly to the Unity engine. The user can submit resources to be uploaded to the GPU and receives a handle that identifies the uploaded resource. Resources can be added, updated and removed. Currently supported resource types: shader, texture.

### Thread-safety
This level might or might not be threadsafe depending on the concrete implementation. The OpenGL version is, in typical GL fashion, so not-threadsafe it's almost anti-threadsafe. All code must be executed sequentially on a dedicated window thread, the same one on which the window and renderer were initially created. The plan for the Vulkan version is to make it at least independent of thread-local storage and hopefully completely threadsafe.

### Usage
#### Renderer
All interaction with the renderer is done through the abstract `Renderer` class, initialized with a concrete implementation. For an OpenGL implementation, first create a window and then make a renderer for it:
```c++
opengl::GlWindow window("title", 1024, 768);
std::unique_ptr<Renderer> renderer = window.make_renderer();
```

The `opengl` namespace or any other implementation-specific namespace like `vulkan`` should not ever be used after initializing the window.

#### Resources
The `resources` namespace provides classes for initializing and loading meshes, textures, shaders, etc.
These objects can then be passed to the renderer to make them usable with graphics hardware, e.g.:
```c++
auto vshader_src = resources::ShaderSource(
resources::shader_lang_t::glsl,
resources::shader_stage_t::vertex,
"#version 330\nvoid main() {}"
);

auto fshader_src = resources::ShaderSource(
resources::shader_lang_t::glsl,
resources::shader_stage_t::fragment,
"#version 330\nvoid main() {}"
);

auto shader = renderer->add_shader( { vshader_src, fshader_src } );

auto tex = resources::Texture2dData(game_path / "/assets/gaben.png");
auto gpu_tex = renderer->add_texture(tex);
```

#### RenderPass and Renderable
Graphics operations are executed through submitting `RenderPass`es and `Renderable`s to the `Renderer` object. For details,
see `renderer.h`.

#### Sample usage:
Sample usage:

```c++
opengl::GlWindow window("title", 1024, 768');
std::unique_ptr<Renderer> renderer = window.make_renderer();

resources::TextureData tex_data(game_path / "/path.tex");
std::unique_ptr<Texture2d> tex = renderer->add_texture(tex_data);

resources::ShaderSource vsrc = resources::ShaderSource(
resources::shader_lang_t::glsl,
resources::shader_stage_t::vertex,
game_path / "path.vert"
);
resources::ShaderSource fsrc = resources::ShaderSource(resources::shader_t::glsl_fragment);
resources::shader_lang_t::glsl,
resources::shader_stage_t::fragment,
game_path / "path.frag"
);

std::unique_ptr<ShaderProgram> prog = renderer->add_shader( { vsrc, fsrc } );

std::unique_ptr<UniformInput> input = prog->new_uniform_input(
"color", { 0.0f, 1.0f, 0.0f },
"time", 0.0f,
"num", 1337
);

std::unique_ptr<Geometry> geom = renderer->add_bufferless_quad();

RenderPass pass {
{ {
input.get(),
geom.get(),
true,
true,
} },
renderer->get_framebuffer_target(),
};

renderer->render(pass);
```

## Level 2:
On top of the level 1 renderer, we build a level 2 graphics subsystem. It has an API that is actually specific to Openage, and is threadsafe. The level-2 renderer calls the level 1 renderer and updates it to match the game state. In some documentation this is also called the "presenter".
35 changes: 31 additions & 4 deletions libopenage/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ endif()
find_library(FONTCONFIG_LIB fontconfig)

find_package(Freetype REQUIRED)
find_package(OpenGL REQUIRED)
find_package(PNG REQUIRED)
find_package(SDL2 REQUIRED)
find_package(SDL2Image REQUIRED)
find_package(Opusfile REQUIRED)
find_package(Epoxy REQUIRED)
find_package(HarfBuzz 1.0.0 REQUIRED)
find_package(Eigen3 3.3 REQUIRED NO_MODULE)

set(QT_VERSION_REQ "5.5")
find_package(Qt5Core ${QT_VERSION_REQ} REQUIRED)
Expand Down Expand Up @@ -204,8 +204,35 @@ else()
have_config_option(ncurses NCURSES false)
endif()

# remember to add more options to config.{cpp,h}.in!
# opengl support
if(WANT_OPENGL)
find_package(OpenGL)
endif()

# vulkan support
if(WANT_VULKAN)
find_package(Vulkan)
endif()

if(WANT_OPENGL AND OPENGL_FOUND)
have_config_option(opengl OPENGL true)
include_directories(${OPENGL_INCLUDE_DIR})
target_link_libraries(libopenage PRIVATE ${OPENGL_LIBRARY})
else()
have_config_option(opengl OPENGL false)
endif()

if(WANT_VULKAN AND VULKAN_FOUND)
have_config_option(vulkan VULKAN true)
include_directories(${Vulkan_INCLUDE_DIRS})
target_link_libraries(libopenage PRIVATE ${Vulkan_LIBRARIES})
else()
have_config_option(vulkan VULKAN false)
endif()

if(NOT (OPENGL_FOUND OR VULKAN_FOUND))
message(FATAL_ERROR "One of OpenGL or Vulkan is required!")
endif()

##################################################
# build configuration generation
Expand All @@ -225,7 +252,6 @@ endif()
# directories for header inclusion
target_include_directories(libopenage
PRIVATE
${OPENGL_INCLUDE_DIR}
${FREETYPE_INCLUDE_DIRS}
${EPOXY_INCLUDE_DIRS}
${OPUS_INCLUDE_DIRS}
Expand All @@ -243,7 +269,9 @@ target_include_directories(libopenage
# to the public api of libopenage
target_link_libraries(libopenage
PUBLIC
pthread
nyan::nyan
Eigen3::Eigen
${PNG_LIBRARIES}
${OPUS_LIBRARIES}
${OGG_LIB}
Expand All @@ -253,7 +281,6 @@ target_link_libraries(libopenage
${FREETYPE_LIBRARIES}
${EPOXY_LIBRARIES}
${MATH_LIB}
${OPENGL_LIBRARY}
${SDL2IMAGE_LIBRARIES}
${SDL2_LIBRARY}
${UTIL_LIB}
Expand Down
2 changes: 2 additions & 0 deletions libopenage/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#define WITH_BACKTRACE ${WITH_BACKTRACE}
#define WITH_INOTIFY ${WITH_INOTIFY}
#define WITH_OPENGL ${WITH_OPENGL}
#define WITH_VULKAN ${WITH_VULKAN}
#define WITH_GPERFTOOLS_PROFILER ${WITH_GPERFTOOLS_PROFILER}
#define WITH_GPERFTOOLS_TCMALLOC ${WITH_GPERFTOOLS_TCMALLOC}
#define WITH_NCURSES ${WITH_NCURSES}
Expand Down
25 changes: 22 additions & 3 deletions libopenage/renderer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
add_sources(libopenage
color.cpp
text.cpp
color.cpp
geometry.cpp
sdl_global.cpp
tests.cpp
text.cpp
texture.cpp
texture_array.cpp
window.cpp
)

add_subdirectory(font)
pxdgen(
tests.h
)

add_subdirectory(font/)
add_subdirectory(resources/)

if(OPENGL_FOUND)
add_subdirectory(opengl/)
endif()

if(VULKAN_FOUND)
add_subdirectory(vulkan/)
endif()
20 changes: 20 additions & 0 deletions libopenage/renderer/geometry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2015-2018 the openage authors. See copying.md for legal info.

#include "geometry.h"


namespace openage {
namespace renderer {

Geometry::Geometry(geometry_t type)
: type(type) {}

geometry_t Geometry::get_type() const {
return this->type;
}

void Geometry::update_verts(const std::vector<uint8_t>& verts) {
this->update_verts_offset(verts, 0);
}

}} //openage::renderer
49 changes: 49 additions & 0 deletions libopenage/renderer/geometry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2015-2018 the openage authors. See copying.md for legal info.

#pragma once

#include <vector>
#include <cstdint>
#include <cstddef>


namespace openage {
namespace renderer {

/// The type of geometry.
enum class geometry_t {
/// This passes 4 vertices with undefined positions to the shader.
/// The shader has to set the positions itself (e.g. using gl_VertexID in OpenGL).
bufferless_quad,
/// This passes valid geometry defined by a mesh to the shader.
mesh,
};

/// A class representing geometry to be passed to a draw call.
class Geometry {
public:
virtual ~Geometry() = default;

/// Returns the type of this geometry.
geometry_t get_type() const;

/// In a meshed geometry, updates the vertex data. The size and type of the vertex data has to be the same as before.
/// If the mesh is indexed, indices will stay the same.
/// @throws if there is a size mismatch between the new and old vertex data
void update_verts(std::vector<uint8_t> const& verts);

/// In a meshed geometry, updates the vertex data starting from the offset-th vertex. The type of the vertex
/// data has to be the same as it was on initializing the geometry. The size plus the offset cannot exceed the
/// previous size of the vertex data. If the mesh is indexed, indices will stay the same.
/// @throws if there is a size mismatch between the new and old vertex data
virtual void update_verts_offset(std::vector<uint8_t> const& verts, size_t offset) = 0;

protected:
/// Initialize the geometry to a given type.
explicit Geometry(geometry_t type);

private:
geometry_t type;
};

}} // openage::renderer
15 changes: 15 additions & 0 deletions libopenage/renderer/opengl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
add_sources(libopenage
buffer.cpp
context.cpp
framebuffer.cpp
geometry.cpp
render_target.cpp
renderer.cpp
shader.cpp
shader_program.cpp
simple_object.cpp
texture.cpp
texture_array.cpp
vertex_array.cpp
window.cpp
)
Loading