Git Product home page Git Product logo

sasluca / rayfork Goto Github PK

View Code? Open in Web Editor NEW
328.0 15.0 19.0 65.93 MB

C99 Game Library. XNA-like. Platform Independent. Allocator Aware.

License: The Unlicense

CMake 0.68% C 74.27% Batchfile 0.01% C++ 18.66% GLSL 0.16% Kotlin 0.02% Objective-C 2.93% Makefile 0.11% HTML 0.02% Shell 1.23% M4 0.87% Java 0.68% PowerShell 0.05% Roff 0.02% Perl 0.08% Python 0.01% Metal 0.01% Assembly 0.12% JavaScript 0.07%
raylib games-library game-engine c platform-independent cross-platform

rayfork's Introduction

C99 • Single Source • Platform Independent • XNA-like • Allocator-Aware • Game Dev Library



Forked from the awesome raylib game framework: https://www.raylib.com/

NOTICE: rayfork is still under very early development and it is not recommended that you use it professionally at the moment.

How to build

rayfork only has one .c file and only depends on libc, which means it can be easily compiled as a library from the command line.

# -c compiles the code as a library
# -EHsc disables exceptions on msvc

gcc -c rayfork.c
clang -c rayfork.c
cl -c -EHsc rayfork.c

Principles

1. Provide platform-independent code

rayfork does not provide a platform layer, that means it won't create a window, load OpenGL, or capture input for you.

This is by design, so that you can easily use rayfork on multiple platforms (including game consoles) by using the method that works best for you. There are templates for using rayfork with GLFW, SDL, sokol-app and custom platform layers.

The renderer currently has OpenGL33 and OpenGL-ES3 backends (with more to be added) that are implemented in a portable way which allows rayfork to be compiled on any platform, with the only dependency being libc. OpenGL procs are passed explicitly to rayfork and there is a simple macro to aid with this.

Because of this you can easily compile rayfork for any platform be it PC, Mobile or Consoles.

2. Provide full control over IO and memory

Functions that do IO are often optional and explicitly ask for IO callbacks. A simple wrapper for the libc IO functions is provided as rf_default_io.

Functions that allocate explicitly ask for an allocator and sometimes also for a temporary memory allocator (memory that is freed inside the function). A simple wrapper for libc's malloc/free is provided as rf_default_allocator.

All dependencies are also used with custom allocators in mind, the library will never allocate without you knowing.

Every function that requires an allocator or io callbacks has an _ez version which wraps the original function and calls it with rf_default_allocator and/or rf_default_io, this is useful for testing code quickly.

3. Easy to build

The library is only one header and source file and can be customized at compile time using preprocessor definitions. No additional compile flags are needed, depending on the graphics backend you might need to link against certain libraries.

Rationale

raylib was created initially for educational purposes and has matured over time into a very useful games library, similar to XNA.

However, due to its nature, several design choices in raylib make it hard to use for professional game developers:

  • Hard to use a custom platform layer (eg: using with a custom platform layer on Android with Android Studio)

  • Hard to port on other platforms (eg: iOS, consoles)

  • Little control over memory allocations and io.

rayfork is designed to address those issues and make it easy to develop professional games using the API from raylib.

I started this project because I love raylib and C99 and I really wanted to develop my game using them.

Many libraries however do not follow the principles that I look for in a library (see this article) which makes using them in games hard/annoying which is why I want to create a library that indie developers can confidently and easily use to develop their projects without sacrificing control, portability or quality.

Help needed

If you want to be able to develop games easily with libraries that respect the principles mentioned above, please consider contributing to rayfork.

You can check the issues tab and find a lot of things you can do to contribute.

I am also looking for help in developing things outside my expertise:

  • Improving the rendering API
  • More graphics backends (sokol-gfx, vulkan, custom console backends)
  • A particle system
  • Physics
  • Networking

Advice for contributors

  • Contact me on the raylib discord server in the #rayfork channel, I am @BananyaDev#0001, or on twitter @SasLuca.

  • Keep the naming convention to snake case, use rf_function_name for interface functions and _rf_function_name for private functions.

  • Prefix all functions with rf_public or RF_INTERNAL

  • Don't include additional headers in the interface, work towards minimizing includes in general.

  • Use #pragma region \ #pragma endregion for folding regions of code and consider using an editor with support for folding those regions to get an easier grasp of the code.

  • Try to apply the advice from this article in general. Some of the more important advice would be:

    • Don't allocate memory, ask the user for vertex_buffers/allocators.
    • Don't use non constant global variables.
    • Avoid os-dependent functions.

rayfork example running on iOS and Windows:

rayfork's People

Contributors

bicycleghost avatar blueghostalt avatar oskarnp avatar sasluca 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

rayfork's Issues

Add build scripts for Linux

Currently, there is a simple CMake file used to build the examples and a batch script that invokes the cl msvc compiler from the command line.

We need to add support for more compilers in the build scripts (eg: gcc and clang) and maybe support to build the examples with more build systems (eg: Make, premake, gradle).

Add size parameters for all buffer parameters.

All functions that ask for buffers from the user should also ask for the size.
This is particularly a problem with functions that take const char* since they usually rely on strlen to get the size.
We don't want that, so we need to check every function that has buffers as parameters and ensure it also asks for the size of the buffer.

Create C++ wrapper

It can be very useful to have a dedicated C++ wrapper that can also provide some utilities using C++ features like function overloading or default parameters (eg: allocator parameters can default to the heap allocator).

This wrapper can do the following:

  • Use namespaces for all the names instead of rf_.
  • Use constexpr for all the constants instead of macros.
  • Make rf_context into a class with methods.

What to avoid:

  • RAII (aka destructors)
  • Exceptions
  • RTII
  • Virtual Dispatch

Add build scripts for macos

Currently, the examples don't compile on macos because objective-c reference counting needs to be enabled.

Add a sokol-gfx backend

We should consider moving the renderer to something like sokol_gfx or sokol_gl in order to provide graphics backends for Metal and DirectX.

Particularly, providing a Metal backend is important because OpenGL is deprecated on iOS and MacOS.

This would be a big change however and add an extra dependency.

Maybe use another library for math instead of the Raylib math functions?

Currently, we have the same math functions from Raylib.
This, however, adds bloat to the API and the functions do not support SIMD (SEE and NEON).

Maybe it would be a good idea to move to another math library like Handmade Math since it is well maintained and has SEE support (though no NEON support apparently).

If anyone has better suggestions or ideas regarding this please mention them.

We could also just add SEE and NEON support to the math functions.

Make all IO optional

Functions that do IO can be kept for convenience, but we should always have versions that ask for buffers loaded by the user instead.

This might be particularly hard in certain functions that read multiple files or parse the filepath and then look for other files.

Remove allocations for extList in rf_context_init

In rf_context_init memory is allocated for extList using malloc in order to load all GL extension strings in memory which are read afterward.

I think that instead of loading all of them in memory and then reading them we can just get pointers to them from OpenGL one by one and never allocate.

Add optional platform layers.

Since rayfork aims to not provide any platform layers it can be very useful to provide optional ones or examples that developers can use.

Particularly on platforms like iOS and Android where it can be harder to find libraries that provide platform layer support.

Provie async loading for all asset types

For all asset loading function we need to provide alternatives that allow for async loading of the asset.

One example of this is rf_load_font.
rf_load_font loads a font on the GL thread.
rf_load_font_async is a font loading task that can be executed on a different thread.
rf_finish_load_font_async takes the result of rf_load_font_async and finishes the loading on the GL thread.

Look at the design of these 3 functions and try to follow that model in providing async loading for other asset types.
Also, consider separating the file IO from the actual loading in order to give the user more flexibility.

Fix OpenGL1 backend

The OpenGL1 backend doesn't seem to work at all, the program doesn't crash, but nothing renders.

Build issues on Linux

First, rayfork refuses to compile with sokol because glad is imported after sokol, which includes it's own GL, which makes glad refusing to compile, as OpenGL is already imported.
To fix it, you need to include glad before sokol in `https://github.com/SasLuca/rayfork/blob/rayfork-0.9/tests/platform-independent-tests/platform-layers/sokol/sokol-main.c#L8

Another issue is missing symbols (as required by e.g sokol).

  • math stuff is missing (you mostly want it, doesn't affect musl targets) : libm needs to be imported target_link_libraries(m), this affect directly rayfork.h
  • Xorg stuff (only with X11 target) : target_link_libraries(X11 Xi Xcursor)
  • dlopen/dlclose/... : target_link_libraries(dl)
  • pthread (or crash at launch) : target_link_libraries(pthread)
    All of them gives target_link_libraries(m dl pthread X11 Xi Xcursor)

Remove stdarg.h

Currently, stdarg.h is included just for the logging callback.

We can remove it and have the users of the logging function create a string on the stack with the data formatted inside it and pass that to rf_trace_log.

Example:

rf_trace_log(rf_ctx, rf_log_info, "[TEX ID %i] Default font loaded successfully", rf_ctx->default_font.texture.id);

Would become this:

char log_buffer[1024]; //Or some smaller value
snprintf(log_buffer, 1024, "[TEX ID %i] Default font loaded successfully", rf_ctx->default_font.texture.id);
rf_trace_log(rf_ctx, rf_log_info, log_buffer);

Rationale

We want to minimise the amount of includes, especially in the interface region. If we can remove all includes in the interface region that would be even better.

Remove all uses of malloc/free

We need to remove all uses of malloc/free in order to give developers full control over memory.
Right now developers can override RL_MALLOC and RL_FREE but that only provides basic support for custom memory management.

All functions that allocate should ask for buffers from the user in which they can write or for allocators.

Fork rAudio

rAudio is very useful and is next in line to be added to rayfork.

better-org branch cleanup

Here is a running list of things that should be addressed in this branch:

  • reorg roadmap : maybe a doc outlining what tasks are on the road to better-org
  • missing #include "sal.h" ... presumably this is a personal local file or something generated
  • outdated dependencies in third party
  • recommendations on top development tools (VSCode in particular, CLion optionally), any configuration needed in .vscode for include paths, plugins required or recommended for vscode
  • misc posix porting preprocessor directives needed to fix includes in some cases
  • rf_utf8_stats undefined ... appears an entire chunk of utf8.h and chars.c needs to get pulled together

I will update this as I have time.

referencia a `rf_get_time' sin definir ????

Al intentar conpilar rayfork me muestra este error.

src/egdklib/src/core.o:core.c:(.text+0x5c2cd): referencia a `rf_get_time' sin definir
src/egdklib/src/core.o:core.c:(.text+0x5c2cd): reubicación truncada para ajustar: R_X86_64_PC32 contra el símbolo `rf_get_time' sin definir
src/egdklib/src/core.o:core.c:(.text+0x5c3c3): referencia a `rf_get_time' sin definir
src/egdklib/src/core.o:core.c:(.text+0x5c3c3): reubicación truncada para ajustar: R_X86_64_PC32 contra el símbolo `rf_get_time' sin definir
src/egdklib/src/core.o:core.c:(.text+0x5c4c4): referencia a `rf_wait' sin definir
src/egdklib/src/core.o:core.c:(.text+0x5c4c4): reubicación truncada para ajustar: R_X86_64_PC32 contra el símbolo `rf_wait' sin definir
src/egdklib/src/core.o:core.c:(.text+0x5c4d3): referencia a `rf_get_time' sin definir
src/egdklib/src/core.o:core.c:(.text+0x5c4d3): reubicación truncada para ajustar: R_X86_64_PC32 contra el símbolo `rf_get_time' sin definir
collect2: error: ld devolvió el estado de salida 1
make: *** [Makefile:18: bin/EGDKEd] Error 1

`

Allow the developers to choose their dependencies

Developers should have the option to not include a dependency and functions dependent on that dependency should just be #ifdef-ed out.

This should probably something like this:

#define RF_DONT_USE_X //Disables library X
#include "rayfork_renderer.h"

When a user defines RF_DONT_USE_X, library X should no longer be loaded and all functions that depend on it should be removed using #ifdef.

Minimize the use of logging

Logging is used heavily in Raylib and all the TraceLog calls were kept in Rayfork.
It might be useful to minimize their use and keep only the important logging bits.
We should also remove all instances where logging is used instead of error handling.

Fix OpenGL21 backend.

The OpenGL21 backend seems to have a problem with font rendering.
Everything else in the example seems to work fine with the OpenGL21 backend though.

frame_time is zero

Hi there,
I have some problems with frame_time in rf_context.

  1. rf_get_frame_time is not impl. (error: undefined reference to `rf_get_frame_time')
  2. rf_ctx.frame_time is zero

I used the basic_shapes example for testing.

void on_frame(void) {
  // error: undefined reference to `rf_get_frame_time'
  //printf("frame time %f\n", rf_get_frame_time());
  
  printf("frame time %f %f %f %f %f\n", rf_ctx.target_time, rf_ctx.current_time,
         rf_ctx.draw_time, rf_ctx.previous_time, rf_ctx.frame_time);
  printf("fps %d\n", rf_get_fps());
         
  rf_begin_drawing();
  //...
  rf_draw_fps(5, 5);

  rf_end_drawing();
}

Output:

frame time 0.016667 22425.000000 0.000000 22425.000000 0.000000
fps -2147483648
frame time 0.016667 22425.000000 0.000000 22425.000000 0.000000
fps -2147483648
frame time 0.016667 22426.000000 0.000000 22426.000000 1.000000
fps 1
frame time 0.016667 22426.000000 0.000000 22426.000000 0.000000
fps -2147483648
...
frame time 0.016667 22429.000000 0.000000 22429.000000 0.000000
fps -2147483648
  1. rf_draw_fps is also wrong
    image

Environment:

  • branch: master
  • Arch Linux (64-Bit) (4.19 kernel)
  • AMD CPU, GeForce GTX 970 Graphic
  • compiled with cmake 3.16, gcc 9.2.0

TCC (Tiny C Compiler) support?

I quite like your direction and philosophy with rayfork. I was wondering if you have any intention on supporting TCC in the future? In theory it should be possible, but I'm not as experienced with these sort of things.

Example script

I tried using this library today and I couldn't find any working examples. I looked into the tests directory and found this

int main() {
  // Init glfw and opengl
  glfwInit();
  GLFWwindow* window = glfwCreateWindow(800, 450, "rayfork simple glfw example", NULL, NULL);
  glfwMakeContextCurrent(window);
  glfwSwapInterval(1);
  gladLoadGL();

  // Init rayfork
  rf_context rf_ctx = {0};
  rf_default_render_batch rf_mem = {0};
  rf_init(&rf_ctx, &rf_mem, 800, 450, RF_DEFAULT_OPENGL_PROCS);

  // Load a texture with the default libc allocator and io callbacks.
  rf_texture2d texture = rf_load_texture_from_file_ez("bananya.png");

  // Main game loop
  while (!glfwWindowShouldClose(window))
  {
    // Render the image and clear the background to some nice shade of white
    rf_begin();
    rf_clear(RF_RAYWHITE);
    rf_draw_rectangle(0, 0, 100, 100, RF_RED);
    rf_draw_texture(texture, 0, 0, RF_WHITE);
    rf_end();

    glfwPollEvents();
    glfwSwapBuffers(window);
  }
}

But no function named rf_init is either in rayfork.h or rayfork.c and no macro RF_DEFAULT_OPENGL_PROCS was definied. So is there an API or tutorial somewhere how to create a valid context?

Project logo?

It would be nice to have a logo for the project, experience show me that projects with a representative logo become more popular. :)

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.