这是indexloc提供的服务,不要输入任何密码
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
ec56851
buildsystem: inotify package search name lowercased
TheJJ Apr 19, 2015
47023b7
buildsystem: implemented vulkan cmake module
TheJJ Apr 19, 2015
fa04522
buildsystem: integrated vulkan and opengl detection
TheJJ Apr 19, 2015
6c228e7
renderer: modular render window and context creation
TheJJ Apr 20, 2015
d1d59c0
renderer: legacy opengl square rendering
TheJJ Jun 25, 2015
6454fc8
renderer: initial generic texture implementation
TheJJ Jun 29, 2015
418838f
renderer: rendering quad with opengl 3.3
TheJJ Jun 29, 2015
8e170d7
renderer: texture and shader creation abstractions
TheJJ Aug 10, 2015
ed60e49
renderer: use the full framebuffer for the test quad
TheJJ Aug 11, 2015
0902c83
renderer: implemented loading shaders from file
TheJJ Aug 11, 2015
9509f1b
renderer: initially integrated into the engine
TheJJ Aug 12, 2015
fdb85f6
renderer: renamed pipeline Program to RawProgram
TheJJ Aug 13, 2015
629a86e
renderer: moved program api contents to separate files
TheJJ Aug 13, 2015
c53f4cd
renderer: initial pipeline variable abstraction
TheJJ Aug 25, 2015
594544f
renderer: demo id selection via cython
TheJJ Sep 15, 2015
3094067
renderer: first successful texture draw
TheJJ Sep 15, 2015
a16d989
renderer: basic uniform variable abstraction
TheJJ Sep 16, 2015
b1b62b4
renderer: implemented vertex attribute packing and uploading
TheJJ Sep 18, 2015
c903e31
renderer: drawing texture with pipeline abstraction
TheJJ Sep 20, 2015
6b4eaa7
renderer: made error checking context-dependent
TheJJ Oct 2, 2015
23f2f3f
renderer: only upload gpu buffer when changed.
TheJJ Oct 21, 2015
0c1ef26
renderer: towards render tasks by storing uniform state
TheJJ Nov 5, 2015
7170d60
renderer: opengl version checking
Vtec234 Nov 8, 2016
d48a9de
engine: adjust new upstream changes to renderer branch changes
Vtec234 Nov 8, 2016
4f7993b
renderer: resource loading refactor
Vtec234 Jan 14, 2017
a36d4d5
renderer: begin major refactor
Vtec234 Mar 12, 2017
9354698
engine: revert changes
Vtec234 Apr 10, 2017
77cb221
renderer: first working version
Vtec234 Apr 11, 2017
05b3991
renderer: documentation and progress
Vtec234 Apr 12, 2017
c2dc925
renderer: screenshots
Vtec234 Apr 13, 2017
e352ab5
renderer: fix glsl parsing
Vtec234 Apr 14, 2017
182065c
renderer: documentation and small interface changes
Vtec234 Apr 14, 2017
d920560
First work on pixel-perfect hitbox, minor changes
citron0xa9 Apr 17, 2017
bd6bcc5
Working optional id write also dependent on alpha value. A bit hacky
citron0xa9 Apr 18, 2017
0cd4208
renderer: add row alignment support for textures; add support for rea…
Vtec234 Apr 21, 2017
1085d12
Extracting id from pixel value improved, added missing glPixelStorei
citron0xa9 Apr 22, 2017
71a679e
Simplified id drawing, using 32 bit ids now
citron0xa9 Apr 22, 2017
f74561a
WIP: Using VBO's and VAO's for drawing, matrix transformations tests
citron0xa9 Apr 30, 2017
e43f521
Enabled depth testing (added depth texture to FBO)
citron0xa9 May 1, 2017
625476c
renderer: small shader fix to avoid invalid uniforms
Vtec234 May 11, 2017
9d9d156
renderer: add more uniform types
Vtec234 May 11, 2017
197c2b9
renderer: add MeshData, move quad geometry there; make classes final;…
Vtec234 May 12, 2017
113388d
renderer: misc fixes and removals
Vtec234 May 12, 2017
38bd3ee
renderer: add support for meshed geometry
Vtec234 May 15, 2017
1b178ac
renderer: delete old files
Vtec234 May 15, 2017
b0fa07f
renderer: shader improvements, uniform and attribute parsing
Vtec234 May 15, 2017
eabebbb
add self to mailmap
Vtec234 May 15, 2017
4037e62
renderer: fix IDs and add more textures support
Vtec234 May 15, 2017
5a9d6be
renderer: fix build
Vtec234 May 15, 2017
1593ff2
renderer: add headers without implementations to CMakeLists to make Q…
Vtec234 May 15, 2017
76ca26f
renderer: refactor
Vtec234 May 17, 2017
d52cc0b
renderer: fix compiler errors after rebase
Vtec234 May 19, 2017
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
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 @@ -54,6 +54,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 @@ -29,7 +29,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
**Humans** | Mixing together all of the above
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-2015 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)
50 changes: 50 additions & 0 deletions buildsystem/modules/FindVulkan.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright 2015-2015 the openage authors. See copying.md for legal info.
#
# (To distribute this file outside of openage, extend the above
# copyright line with an appropriate GPLv3 or later reference,
# as you probably don't have a our copying.md)


#=================================================================
# Locate Vulkan graphics library
#
# usage:
# find_package(Vulkan)
#
# This module sets the following variables:
# VULKAN_FOUND True, if the system has Vulkan.
# VULKAN_INCLUDE_DIR Path to the Vulkan include directory.
# VULKAN_LIBRARIES Paths to the Vulkan libraries.
#=================================================================

set(_Vulkan_REQUIRED_VARS "VULKAN_vk_LIBRARY" "VULKAN_INCLUDE_DIR")

find_path(VULKAN_INCLUDE_DIR
VK/vk.h
/opt/graphics/Vulkan/include
)

find_library(VULKAN_vk_LIBRARY
NAMES VK Vulkan
PATHS
/opt/graphics/Vulkan/lib
)

if(VULKAN_vk_LIBRARY)
set(VULKAN_LIBRARIES ${VULKAN_vk_LIBRARY})
endif()


include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
Vulkan
REQUIRED_VARS ${_Vulkan_REQUIRED_VARS}
FAIL_MESSAGE "Vulkan NOT found."
)

unset(_Vulkan_REQUIRED_VARS)

mark_as_advanced(
VULKAN_INCLUDE_DIR
VULKAN_vk_LIBRARY
)
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",
}
Expand All @@ -81,7 +83,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
143 changes: 143 additions & 0 deletions doc/renderer/doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# 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.

### Shaders

<NOTE: this is an unorganized braindump, i'll rewrite it later>

These are more involved than resources, since each shader also carries a set of uniforms.

A shader program takes in uniform values and vertex inputs and produces a number of bitmaps written into its render targets. Every shader program is then a function of the form $S:P\times\prod\limits^{n_u} U_i\times\left(\prod\limits^{n_a}V_j\right)^n\rightarrow\prod\limits^{n_t}B_k$, where $P$ is the primitive type, $\{U_i\}$, $\{V_j\}$, $\{B_k\}$ are indexed families of uniform, vertex attribute and bitmap types, respectively and the shader takes in $n_u$ uniforms, $n$ vertices with $n_a$ attributes per vertex and outputs to $n_t$ render targets.

All of these inputs are contained in the $Renderable$ type. There is a catch here, since shaders are stateful, arguments are preserved between calls.

Keep in mind that the output bitmap is not necessarily what the final output in a render target will be, since multiple draw calls get combined into a single bitmap and the initial value of the target also has an effect.

With this premise, we can create a renderer interface generic over low-level APIs and usage (although optimized for openage's purposes). The only renderables are sets of values to be passed to shader programs - they may or may not include geometry, textures, matrices, etc.

Our $ShaderInput$ class conceptually has almost the same member types as the types in the domain of the corresponding shader program function, with some small differences. For example, OpenGL shaders have implicit vertex attributes like $gl\_VertexID$ which we do not valuate manually.

For the most part, these types are not know statically, so $ShaderInput$ has to simulate them internally with dynamic dispatch while providing an external interface that acts as if its members are the same as the inputs to the shader.

OTOH, when it is the case that they are know statically, we can generate the appropriate headers from the shader code for better performance (in the future).

Figure out the interface for $ShaderInput$.

Parametrize $ShaderInput$ over a $Shader$ type. Have one $DynamicShader$ for all shaders loaded at runtime and some $StaticShaderForSpecificThing$ classes for shaders known beforehand. Make $DynamicShader$ compile for all operations and $StaticShader$.. only have operations it supports implemented, making it check them at compile-time.

```c++
template<typename S>
class ShaderInput {
template<unsigned int U, typename T>
void set_unif(T val) {
// always compiles for dynamic shader,
// only compiles for valid U and T for static shader
(instanceof S).set_unif<U, T>(val);
}
};

template<unsigned int N>
void func() {
static_assert(N != N, "Invalid shader uniform name.");
}

template<>
void func<COMPILE_TIME_CRC32_STR("val1")>() {
cout << "val1" << endl;
return;
}

template<>
void func<COMPILE_TIME_CRC32_STR("val2")>() {
cout << "val2" << endl;
return;
}
```

How to deal with drawing the scene?
We want stateless drawing, but pure stateless incurs some overhead. We can probably do with some mix of sharing scene between renderer and user. Keep a Scene object containing renderables (just shader valuations) and pass it to the render method.
What shoud Scene contain?
```c++
struct Scene {
std::vector<ObjectId>;
OR
std::vector<std::shared_ptr<Object>>;
SceneSettings...
alpha blending, ztest, all of that in Object
is there anything global?
From Unity3D:
far, near plane
default depth
projection type
occlusion culling method
HDR
AA styles
how to deal with unit picking? probably have to make it a separate render pass
that renders unit ids into a buffer. read it on CPU or GPU? GPU faster, but is it possible?
general render-pass related things; have objects for render passes?
};
```
alternatively call render_pass(..) for each pass rather than call render(OBJ) once where OBJ contains info about render passes. might be nicer since render pass info can be recovered. problem - have to sync CPU/GPU to wait for command buffer execution finish
QUESTION:
share ownership of scene data at all times or give views to the user that are only accessible when not rendering?

### Usage
Sample usage:

```c++
Window window("title");
auto renderer = opengl::GlRenderer(window.get_context());

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

resources::ShaderSource vsrc = resources::ShaderSource::read_from_file("/path.vert", resources::shader_t::glsl_vertex);
resources::ShaderSource fsrc = resources::ShaderSource::read_from_file("/path.frag", resources::shader_t::glsl_fragment);

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

auto input = prog->new_uniform_input(
"color", { 0.0f, 1.0f, 0.0f },
"time", 0.0f,
"num", 1337
);

RenderPass pass {
{ {
input,
new Geometry(geometry_t::quad),
true,
true,
true,
true,
} }, // list of renderables
renderer->get_framebuffer_target(),
1.0f,
8,
};

renderer->render(pass);
```

## Level 2:
On top of that 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.
32 changes: 30 additions & 2 deletions libopenage/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ add_subdirectory("gui")
add_subdirectory("error")
add_subdirectory("gamestate")
add_subdirectory("input")
add_subdirectory("log")
add_subdirectory("job")
add_subdirectory("log")
add_subdirectory("pathfinding")
add_subdirectory("pyinterface")
add_subdirectory("renderer")
Expand All @@ -49,7 +49,6 @@ add_subdirectory("testing")
add_subdirectory("unit")
add_subdirectory("util")


# run codegen, add files to executable
codegen_run()
add_sources(libopenage GENERATED ${CODEGEN_TARGET_TUS})
Expand Down Expand Up @@ -150,6 +149,35 @@ else()
have_config_option(inotify INOTIFY false)
endif()

# 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})
else()
have_config_option(opengl OPENGL false)
endif()

if(WANT_VULKAN AND VULKAN_FOUND)
have_config_option(vulkan VULKAN true)
include_directories(${VULKAN_INCLUDE_DIR})
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()


get_config_option_string()

configure_file(config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
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}

Expand Down
19 changes: 16 additions & 3 deletions libopenage/renderer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
add_sources(libopenage
color.cpp
text.cpp
color.cpp
geometry.cpp
renderer.h
shader_program.h
tests.cpp
text.cpp
texture.cpp
window.cpp
)

add_subdirectory(font)
pxdgen(
tests.h
)

add_subdirectory(font/)
add_subdirectory(opengl/)
add_subdirectory(resources/)
#add_subdirectory(shaders/)
7 changes: 3 additions & 4 deletions libopenage/renderer/color.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ Color::Color()
r{0},
g{0},
b{0},
a{255} {
// Empty
}
a{255} {}

Color::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
Color::Color(color_channel_t r, color_channel_t g,
color_channel_t b, color_channel_t a)
:
r{r},
g{g},
Expand Down
16 changes: 8 additions & 8 deletions libopenage/renderer/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ namespace openage {
namespace renderer {

class Color {
using color_channel_t = uint8_t;

public:
Color();

Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
Color(color_channel_t r, color_channel_t g, color_channel_t b, color_channel_t a);

bool operator==(const Color &other) const;

bool operator!=(const Color &other) const;

uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
bool operator !=(const Color &other) const;

color_channel_t r;
color_channel_t g;
color_channel_t b;
color_channel_t a;
};

}} // openage::renderer
Loading