-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
raylib includes a set of ImageDraw*() functions that rely only on CPU memory (no GPU required). Those functions can be used to implement a basic 2d software rendered. Actually, those functions have been improved a lot in performance lately.
Here there are some notes about how it can be implemented, still under consideration:
- New compilation flag:
USE_SOFTWARE_RENDERER-> Some modules are not required any more:rlgl.h,models.h,camera.h Texture2D(GPU) should fallback toImage(CPU)- Some modules require functions mapping:
core.c,textures.c,text.candshapes.c - Some functions won't be usable -> code should be commented or pre-processed
Here some design details:
/// core.c
void InitWindow(); -> Create Image framebuffers (back + front) and NO_CONTEXT window (just for inputs)
void ClearBackground(Color color); -> ImageClearBackground(Color color);
void BeginDrawing(void); -> Just timing
void EndDrawing(void); -> [rlglDraw(), SwapBuffers(), PollInputEvents(), Timming()]
void BeginMode2D(Camera2D camera); -> Setup Image transform (matrix/kernel?)
void EndMode2D(void); -> Apply Image transform
void BeginMode3D(Camera3D camera); -> no 3d
void EndMode3D(void); -> no 3d
void BeginTextureMode(RenderTexture2D target); -> Replace internal framebuffer Image by custom one
void EndTextureMode(void); -> Reset drawing to internal framebuffer
void BeginScissorMode(int x, int y, int width, int height); -> Define drawing rectangle (check before ImageDraw() on framebuffer)
void EndScissorMode(void); -> Reset drawing rectangle
static bool InitGraphicsDevice(int width, int height); -> Create Image framebuffer
static void SetupFramebuffer(int width, int height); -> Setup Image framebuffer? -> Probably not required
static void SetupViewport(int width, int height); -> Set Image drawing area?
static void SwapBuffers(void); -> Copy Image back buffer to front buffers -> ISSUE: SWAP to SCREEN!
/// textures.c
Texture2D LoadTexture(const char *fileName); -> LoadImage()
Texture2D LoadTextureFromImage(Image image); -> ImageCopy()
TextureCubemap LoadTextureCubemap(Image image, int layoutType); -> LoadImage()
RenderTexture2D LoadRenderTexture(int width, int height); -> LoadImage()
void UnloadTexture(Texture2D texture); -> UnloadImage()
void UnloadRenderTexture(RenderTexture2D target); -> UnloadImage()
void UpdateTexture(Texture2D texture, const void *pixels); -> ImageDraw()
void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); -> ImageDraw()
Image GetTextureData(Texture2D texture); -> ImageCopy()
Image GetScreenData(void); -> ImageCopy() (internal framebuffer)
void GenTextureMipmaps(Texture2D *texture); -> ImageMipmaps()
void SetTextureFilter(Texture2D texture, int filterMode); -> Set ImageResize() scale mode
void SetTextureWrap(Texture2D texture, int wrapMode); -> Set Image wrap mode -> out-of-scope?
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); -> ImageDraw()
void DrawTextureV(Texture2D texture, Vector2 position, Color tint); -> ImageDraw()
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); -> ImageDraw()
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); -> ImageDraw()
void DrawTextureQuad(Texture2D texture, Vector2 tiling, Vector2 offset, Rectangle quad, Color tint); -> ImageDraw()
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint); -> ImageDraw()
void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle destRec, Vector2 origin, float rotation, Color tint); -> ImageDraw()
/// text.c
void DrawFPS(int posX, int posY); -> ImageDrawText()
void DrawText(const char *text, int posX, int posY, int fontSize, Color color); -> ImageDrawText()
void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); -> ImageDrawTextEx()
void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); -> no
void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint,
int selectStart, int selectLength, Color selectTint, Color selectBackTint); -> no
void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float scale, Color tint); -> ImageDrawTextEx()
/// shapes.c
void DrawPixel(int posX, int posY, Color color); -> void ImageDrawPixel(Image *dst, int posX, int posY, Color color);
void DrawPixelV(Vector2 position, Color color); -> void ImageDrawPixelV(Image *dst, Vector2 position, Color color);
void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); -> void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color);
void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); -> void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color);
void DrawCircle(int centerX, int centerY, float radius, Color color); -> void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color);->
void DrawCircleV(Vector2 center, float radius, Color color); -> void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color);
void DrawRectangle(int posX, int posY, int width, int height, Color color); -> void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color);
void DrawRectangleV(Vector2 position, Vector2 size, Color color); -> void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color);
void DrawRectangleRec(Rectangle rec, Color color); -> void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color);
void DrawRectangleLines(int posX, int posY, int width, int height, Color color); -> void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color);
// Several shapes drawing functions not supported...There is one big issue and actually the main stopper for this implementation: How to do the screen buffer display of our Image framebuffer?
Every platform would require a custom mechanism to push a bunch of pixels to the screen. GLFW has a long-time open issue where some mechanism was proposed: glfw/glfw#589
Two main concerns: how to integrate this in raylib (in a simple non-intrusive way) and how useful is this feature. Some answers:
- Use preprocessor
USE_SOFTWARE_RENDERERto completely separate default functions from software based ones. Ontextures.c,text.candshapes.cseems feasible butcore.cwould require some careful tweaking and probably some functions reorganization or internal preprocessing. - Software renderer could be useful when targeting old devices (consoles), some low-end embedded devices or custom devices with a display attached (Arduino, FPGA-based...). But on those cases, maybe raylib is too high level and beter lower level options exist.
In any case, I opened the issue for reference and comments. Please, do not send a PR, it's still a feature under consideration.