Giter Club home page Giter Club logo

oryol's Introduction

Please note that Oryol is currently not actively maintained and hasn't been for a long time, my focus is currently on the Sokol headers and (from time to time) on the Chips emulator stuff.

Oryol

A small, portable and extensible 3D coding framework written in C++:

  • simple Orthodox C++ coding style and APIs
  • extensible through external code modules living in git repositories
  • runs on OSX, Linux (incl RaspberryPi), Windows, iOS, Android, emscripten, from the same C++ source
  • renders through GL, GLES2, WebGL, Metal, D3D11 from same shader source
  • produces small executables (e.g. emscripten WebGL demos starting at around 100 Kbytes)
  • async data loading from web or disc

Build Status:

Platform Build Status
OSX + Linux (OpenGL) Build Status
Windows (OpenGL + D3D11) Build status

Live Demos:

How to Build (Quick'n'Dirty):

You need: cmake, python and your platform's default C/C++ development environment.

> mkdir projects
> cd projects
> git clone --depth 5 https://github.com/floooh/oryol
> cd oryol
> ./fips build
> ./fips run Triangle

In case of problems or for more detailed build info (e.g. how to work with IDEs) see here: How to Build

Getting Started:

Useful Blog Posts:

Extension Modules:

See the Oryol Extension Sample webpage for more interesting 3rd-party library integrations.

Tools etc.:

Standalone App Demo:

A simple standalone app using Oryol: https://github.com/floooh/oryol-test-app

Videos

Please note that these videos use older versions of the Gfx module, details have changed (and will continue to change at least until the Vulkan and DX12 renderer backends have been implemented).

Enjoy!

oryol's People

Contributors

anthraxx avatar attilaz avatar code-disaster avatar ejkoy avatar floooh avatar funcman avatar fungos avatar hb3p8 avatar joeld42 avatar kimkulling avatar kkimdev avatar mgerhardy avatar nfd avatar oldes avatar pboyer avatar pixelpicosean avatar pol-zzz-ygoniq avatar roddiekieley avatar russpowers avatar severtsev avatar smalllixin avatar thejinchao avatar waywardmonkeys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oryol's Issues

Implement HTTP module

  • HttpFileSystem -> sits on top of HttpClient
  • HttpClient
  • HttpServer (only a simple server for serving debug pages and remote-controlling the app)
  • HttpRequest, HttpResponse
  • support for JSON, XML, JSON-RPC, XML-RPC stuff
  • prefer platform-specific HTTP APIs or use CURL as fallback

Sample Gallery App for publishing on Google Play Store

Publishing on Play Store would simplify installation for users and for crash-report reporting. For this a single Sample Gallery App is needed though which would have to be created during the build process (similar to the sample web page).

Can Android's modular Activities help with this? I.e. can each sample be its own Activity bundled into the app, with a single "launcher activity" on top (could be as simple as a list view).

Initial emscripten support.

Set emscripten frame-function in Core::AppBase, create new emscDisplayMgr in Render. Test if the atomic stuff needs workarounds in the latest fastcomp emscripten, if yes, create a new Atomic wrapper class under Core/Threads

Make Samples run. Some unittests won't work though since they block for threads.

-Wformat support

I added -Wformat support and ran into a couple of things:

  • Do you want this?
  • This uses __attribute__. Where is a good place to add the equivalent of:
#ifndef __GNUC__
#define __attribute__(x)
#endif
  • This adds a couple of new warnings:
code/Modules/Core/UnitTests/CreationTest.cc:121:63: warning:
    format specifies type 'int' but the argument has type 'std::__1::__thread_id' [-Wformat]
    Log::Info("create_multithreaded: thread '%d' entered!\n", this_thread::get_id());
                                             ~~               ^~~~~~~~~~~~~~~~~~~~~
code/Modules/Core/UnitTests/CreationTest.cc:132:62: warning:
    format specifies type 'int' but the argument has type 'std::__1::__thread_id' [-Wformat]
    Log::Info("CreateMultiThreaded: thread '%d' leaving!\n", this_thread::get_id());
                                            ~~               ^~~~~~~~~~~~~~~~~~~~~
code/Modules/Messaging/UnitTests/ThreadedQueueTest.cc:74:76: warning:
    format specifies type 'double' but the argument has type 'duration<double>' [-Wformat]
    Log::Info("ThreadedQueue: 1000000 msgs created and handled: %f sec\n", dur);
                                                                ~~         ^~~

I suspect the ThreadedQueueTest should be using dur.count(). The thread ID stuff can just cast to int, but that isn't portable in theory, afaik.

Thoughts?

Better async IO

It should be possible to provide a success and failed callback with the asynchronous load file function. When the IO request has been handled, the functions should be called with the IO request.

It should be possible that the callbacks are defined through lambdas.

IO Decoding

Separate system from "raw data fetching"... take an input stream and transform it into an output stream, for instance for: decompressing, procedurally generating data, etc...

Decode-requests are normal messages, living in message protocols.

A central decoderRegistry/decoderFacility, whatever, runs a thread-pool, and accepts dispatcher objects setup for a specific (decoder) message protocol. This is how the extensibility works... higher-level-subsystems can setup their own decoder message protocols and message handlers (which perform the actual decoding)...

Q: how do emscripten worker threads know about the decoders? Dispatchers and their handler functions must be setup in the worker...

Q: can decoders be chained? first decompress, then generate data...?

Build oryol for emscripten has error

I build it on osx.

[ 57%] Building CXX object code/Modules/HTTP/CMakeFiles/HTTP.dir/emsc/emscURLLoader.cc.o
Linking CXX static library libHTTP.a
[ 57%] Built target HTTP
Scanning dependencies of target Render
[ 57%] Building CXX object code/Modules/Render/CMakeFiles/Render.dir/RenderProtocol.cc.o
[ 58%] Building CXX object code/Modules/Render/CMakeFiles/Render.dir/RenderFacade.cc.o
In file included from /Users/xxx/SDK/oryol/code/Modules/Render/RenderFacade.cc:5:
In file included from /Users/xxx/SDK/oryol/code/Modules/Render/RenderFacade.h:10:
In file included from /Users/xxx/SDK/oryol/code/Modules/Render/Core/displayMgr.h:18:
/Users/xxx/SDK/oryol/code/Modules/Render/emsc/emscDisplayMgr.h:34:5: error:
unknown type name 'EMSCRIPTEN_WEBGL_CONTEXT_HANDLE'
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx;
^
1 error generated.
ERROR root: compiler frontend failed to generate LLVM bitcode, halting
make[2]: *** [code/Modules/Render/CMakeFiles/Render.dir/RenderFacade.cc.o] Error 1
make[1]: *** [code/Modules/Render/CMakeFiles/Render.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
[ 58%] Built target hello
[ 58%] Built target CoreHello
make: *** [all] Error 2
ERROR: Build failed.

HTTP Support for Android

Tricky, since the C/C++ API doesn't seem to expose HTTP functions. Check whether this is possible by calling back into Java from JNI without writing actual Java code...

Memleak in triangle demo

Xcode shows growing memory usage while the Triangle demo runs, which is strange since there are no dynamic memory allocation in Oryol's code. GLFW?

Implement RunLoop in Core

One run-loop on the main thread and on each thread. Some rough pre-defined priorities (BeginFrame, EndFrame, ...) with a lot of space between them. High priorities run at the start of the frame. Callback method gets a FrameInfo object(?) -> current time, last frame-duration, frame index. Callback (method + object) is wrapped into a std::function.

Is this a thread-local singleton? Or generally wrap behind the module's facade?

Can't build it for ios on osx10.9

Core/Logger.cc -o /Users/xxx/SDK/oryol/build/ios-xcode-release/code/Modules/Core/oryol.build/Release-iphoneos/Core.build/Objects-normal/armv7/Logger.o

** BUILD FAILED **

The following build commands failed:
CompileC build/ios-xcode-release/code/Modules/Core/oryol.build/Release-iphoneos/Core.build/Objects-normal/armv7/App.o code/Modules/Core/App.cc normal armv7 c++ com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
ERROR: Build failed.

How to build it for ios simulator?

How to load local file?

I just want load file in the directory if I run it in osx, But I don't know how to do it, I think who don't want make a game must run a web server if not run the web.
Is there any way to read a load file? And IO can load local file?
char buf[128] = {0};
sprintf(buf, "./nanovg/image%d.jpg", 1);
//_data.images[i] = _nvg->CreateImage(_ctx, _io->LoadFile(buf)->GetStream(), 0); //must url path? T^T
/* Can it like this? */
_data.images[i] = _nvg->CreateImage(_ctx, buf, 0);

I think must add GetResource or GetAssert in oryol, Because binary file is special in the osx, Itself is a folder(.app) and resource put into it(xxx.app/Contents/Resources/), so.

FrameShader system ideas

Have a more direct description of the render-frame as code. Directly inline the required state in the frame-shader-description instead of having the state only "externally" in shaders.

Some ideas how it could look like, the following would execute as python and generate C++ source when executed during the build process:

if FrameShader(name='default'):
  RenderTarget(name='NormalDepthBuffer', relWidth=1.0, relHeight=1.0, format='RGBA8', depth='D24S8')
  RenderTarget(name='LightBuffer', relWidth=1.0, relHeight=1.0, format='RGBA8', sharedDepth='NormalDepthBuffer')

  if Pass(name='NormalDepthPass') :
    ApplyRenderTarget('NormalDepthBuffer')
    Clear(color=[1.0,1.0,1.0,1.0], depth=1.0, stencil=0)
    ColorMask(True, True, True, True)
    DepthMask(True)
    Enable(DepthTest)
    DepthFunc(LessEqual)
    Disable(Blend)
    DrawBatch(tag='Solid')
    DrawBatch(tag='AlphaTest')
  if Pass(name='LightPass') :
    ApplyRenderTarget('LightBuffer')
    DepthMask(False)
    DepthFunc(Equal)
    DrawGlobalLight()
    DepthFunc(Greater)
    DrawPointLights()
...

Reminder: VertexShader / FragmentShader resources

...need to make VS and FS separate resources, so they can freely combined/reused for linked shader programs. Create program directly from shader source still a convenience option, but creates VS/FS resource objects under the hood.

Shader Generators

Basic Idea

Generate GLSL and C++ source from 'annotated shader source snippets'.

One big C++ header for one shader library, a shader library contains all shaders for a specific renderer implementation (i.e. forward renderer vs pre-light-pass vs deferred, or just a number of simple shader for a small rendering demo).

Build GLSL shader code from small, reusable fragments (in its simplest form just a smarter '#include' on function level. Generate wrapper C++ header with final GLSL source code embedded, and C++ classes (or C-style functions?) which provide ProgramBundleSetup objects and shader uniform indices.

The 2 'extreme use cases' which should be made easy:

  • easily manage a manually written shader library with many shader variations
  • plug-in a data-flow shader editor (not high-priority in the beginning)

Cross-platform is only relevant in the beginning to span several GLSL versions (but not HLSL).

IDE integration

Uses the python generator feature which is also used for generating Message protocol C++ sources. One top-level XML file per shader library defines the directories where shader snippet files will be found. Python generator script gathers all shader sources, plugs them together and generates a single big C++ header. All file types show up in the IDE and are auto-generated during the build process using cmake build jobs.

Annotated Shader Source Snippet files

Snippet files are normal GLSL code, annotations are specially formatted comments:

//#key value[s]

Functions and Includes

This defines a simple function to be included somewhere else. Many functions can live in a single file:

//#type fn
//#name myFunc
vec4 myFunc(float x, float y) {
   // ...
}

To include this function in another file:

//#needs path/to/file:myFunc

'path/to/file:' is optional, it can be omitted if the function is in the same file.

A function can also depend on other functions:

//#type fn
//#name myOtherFunc
//#needs myFunc
float myOtherFunc() {
    return myFunc(1,2,3).x;
}

Vertex- and Fragment-Shaders

Vertex- and Fragment-Shaders must be named, and may live in the same file (but don't have to!). They must declare the uniforms and inputs/outputs they need. The source generator will use this information to generate C++ bindings. Uniforms must have a variable name (which is used in the GLSL code) and a semantic (which defines the C++ binding). Some semantics have a standard meaning (like ModelViewProjection)

//#type vs
//#name myVertexShader
//#needs myFunc
//#uniform mat4 mvp ModelViewProjection
//#uniform float time Time
//#in vec4 position
//#in vec4 normal
//#in vec4 color
//#out vec4 nrm
//#out vec4 clr
void main() {
    //...
    GL_POSITION = ... 
}

//#type fs
//#name myFragmentShader
//#uniform sampler2D color ColorTexture
//#in vec4 nrm
//#in vec4 clr
void main() {
    //...
    GL_COLOR = 
}

Advanced Stuff

Shader Types (better name needed)

More advanced shader types, these are relatively generic functions which will be "arranged" in the right way through shader templates (see below). Ideally we could use the same surface shaders for different render pipelines (like forward rendering vs. deferred shading)...

  • light shader: 'light interaction shaders' take light attributes and some surface attributes (e.g. point on surface, surface normal) as input, and produce a 'light color' ... blarglblargl... must be better defined. Look at something like Renderman?
  • surface shader: takes surface position, normal, ... plus material parameters and produces a surface color
  • morph shader(?): morphs vertex components into vertex shader outputs (e.g. for uv animation, skinning)
  • ... what else?

The accumulated result of several light shaders and a surface shader produce a lit surface pixel etc etc etc...

Shader Templates

These are template files with placeholder variables defining where the above 'shader type' fragments inserted (e.g. in a forward renderer, the light shaders must be merged with the surface shader into a single fragment shader, while in a pre-light-pass renderer the light shaders and surface shaders would remain separate).

...this feature needs more brainsss...

Shader Nodes

These are shader functions with typed input- and output-plugs, so that they can be plugged together in a data-flow shader editor. This is the lowest priority feature of the whole system.

Worker Module

...a module for parallel task processing which hides the differences between actual pthread-style threads, and emscripten-style webworkers. Based on the messaging module. The IO decoding stuff will be based on this.

Worker functions will be associated with messages. Handling a message means calling its worker function. Worker function will be an as-simple-as-possibel C-style function.

On emscripten, messages will have to be coded to/from POD.

Custom message protocols can "hook" into the worker system, so basically one has to provide a MessageProtocol and the associated worker functions, these will have to be wrapped into some sort of registration macros so that they can be setup either inside "classic" threads, or emscripten worker threads (might have to couple Dispatchers and Protocols closer together for this ----> code generation!...

or maybe we can put all this setup stuff automatically into the Protocol (including handler functions... and have this stuff generated optionally, so that the "user" only needs to provide handler-functions following a specific naming convention..., basically a static Protocol-method which sets up a complete Messaging::Dispatcher...(???)

Implement Virtual Filesystem Infastructure

  • wrap IO operations into pluggable modules
  • associate a "VFS" with a HTTP scheme (e.g. http -> HttpFileSystem)
  • only asynchronously reading whole files, and subranges from files for now
  • first implementation for HTTP

-> special: MemoryFileSystem, for preloading files into memory, where special-case synchronous file access is required (e.g. for third party libs)

Implement Message handling infrastructure

  • scenarios:
  • synchronous, non-threaded: just call handler callback directly
  • asynchronous, non-threaded: add to queue, handler decides when to handle message
  • asynchronous, multi-threaded: handler lives in thread
  • synchronous, multi-threaded: ??? really? probably not...
  • in-thread, in-process, out-of-process
  • message transfer:
  • should be "pluggable"
  • case 1: don't serialize message, but send Ptr<> to message
  • case 2: serialize to POD, send raw bytes
  • Message, subclasses generated through code generation
  • subscribe to message with a per-message-type callback function (std::function)?? and/or have more complex Handler objects?
  • several subscribers per message allowed, sorted by priority (similar to runloop)
  • optional message-handled callback (optional because it should also be possible to store and ask a message object whether it has been handled, but not in all scenarios)
  • Port: generic end-point for sending and receiving messages, has a Dispatcher (as template param??)
  • Dispatcher: knows how to transfer the message to the handler...
  • Handler: simple case: just a callback function...
    .... to be continued...

Initial PNaCl support

Same as #14 , don't put the main loop into its own thread like in N3, instead put everything on the main thread. Can decide later if we want this.

Some class interface cleanup re VertexLayout

Setting VertexLayout should be unified:

MeshSetup meshSetup(...);
meshSetup.VertexLayout().Add(VertexAttr::Position, VertexFormat::Float3);
meshSetup.VertexLayout().Add(VertexAttr::Normal, VertexFormat::Float3);

ShapeBuilder shapeBuilder;
shapeBuilder.VertexLayout().Add(VertexAttr::Position, VertexFormat::Float3);
...

Make samples compile and run on Linux

Currently 64-bit Linux only, need to split precompiled libraries into 32- and 64-bit versions before enabling transparent 32/64 bit support (do we even need 32 bit support any more?)

Android Compatibility

This issue tracks compatibility of the sample apps with Android devices. Please check whether your device is already in the list before adding a new one. Please provide at least:

  • the hardware model
  • the Android OS version
  • steps to reproduce the crash (unless all samples fail to start at all, which is most likely)

Build System Issues

https://gist.github.com/code-disaster/e22492b306706e25590f

Issues I encountered on Mac OSX on a relatively fresh system.

  • I first totally missed BUILD.md. I'm stupid! That's why I've seen './oryol setup emscripten' fail very late in the install + compile process because node.js wasn't found. Maybe it's worth to check for some dependencies (node.js, ant) and fail early if some are missing.
  • './oryol build' with selected config 'emscripten-make-debug' failed because something (cmake?) was trying to run 'python2', but my OSX system didn't have such a symlink in /usr/bin. I "fixed" this by creating one pointing to '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7'.
  • './oryol setup android' seems to miss some SDK dependencies. The Android build later complains about 'Android SDK Build Tools' not found - maybe that's a new module? To solve this I've just installed it manually via the Android SDK Manager.
  • './oryol webpage' failed to compile RenderEnumsTest.cc successfully with 'emscripten-make-unittest-debug'. It doesn't know GL_TEXTURE_3D.
  • At the end of './oryol webpage' (without unittests) I've got a couple of warnings about 'dyld: Library not loaded: /usr/local/lib/libtiff.5.dylib'.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.