Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/heysokam/glfb
gl*FB | Tiny Framebuffer with OpenGL
https://github.com/heysokam/glfb
framebuffer opengl
Last synced: 8 days ago
JSON representation
gl*FB | Tiny Framebuffer with OpenGL
- Host: GitHub
- URL: https://github.com/heysokam/glfb
- Owner: heysokam
- License: mit
- Created: 2023-08-14T02:00:34.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2024-06-27T06:27:56.000Z (5 months ago)
- Last Synced: 2024-06-27T07:32:54.279Z (5 months ago)
- Topics: framebuffer, opengl
- Language: Nim
- Homepage:
- Size: 55.7 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- License: license.md
Awesome Lists containing this project
README
> **Warning**:
> _This library is in **Low Maintainance** mode._
> _See the [relevant section](#low-maintainance-mode) for an explanation of what that means._# gl*FB | Tiny Framebuffer with OpenGL
This library provides a simple way to draw a pixel buffer into the screen.
A framebuffer is a memory buffer containing data representing all the pixels in a complete video frame.
The user of the library is fully responsible for how the contents of the pixel buffer are generated.## HowTo
Add this repository to your nimble file with `requires "https://github.com/heysokam/glFB#head"`
Then, in your code file:
```nim
import glFB
# ... your code here ...
```
### API Examples
#### Simple API
```nim
var scr = Screen.new(960,540) # Initialize the Screen object
while not scr.close(): # Run while the Screen has not been marked for closing
for pix in scr.pixels: pix = myPixel # Generate the pixels on the CPU
scr.update() # Update the screen contents in the GPU
scr.term() # Terminate everything after
```Pixel access ergonomics:
```nim
# Individual pixels
let pix = scr[10,10] # Returns a copy of the pixel at coordinates [X,Y]
for pixel in scr.pixels: # Access all pixels individually one by one
pixel = rgbx(0,0,0,0) # Each item is modifiable, like mitems
scr[10,10] = rgbx(0,0,0,0) # Directly modify a single pixel at [X,Y]# All pixels at once
let data = scr.data # Alias for accessing the entire Screen's pixel data
scr.data = SomeSeqOfColorRGBX # Alias for pixel buffer data asignation all at once (size must match)# Note: Coordinate (0,0) is at topleft of the screen
```#### Advanced Usage
Screen construction:
```nim
# Constructor function options:
# 1. Creates pixel buffer with all values set to (0,0,0,0)
var scr = Screen.new( Width, Height )
# 2. Creates a pixel buffer with the contents and size of the input pixie.Image
var scr = Screen.new( SomePixieImageObject )
# 3. Creates the required pixie image internally, using the given separate pixel buffer inputs
var scr = Screen.new( Width, Height, SomeSeqOfColorRGBX )# Implicit Defaults during Screen Creation with `Screen.new( ... )`:
title : string = "glFB | Window"; # Title of the window
resizable : bool = false; # Whether the window is allowed to be resized or not
resize : glfw.FrameBufferSizeFun = w.resize; # GLFW framebuffer resize callback. aka: glFB/window proc resize() ...
key : glfw.KeyFun = i.key; # GLFW Input Keyboard callback. aka: glFB/input proc key() ...
mousePos : glfw.CursorPosFun = nil; # GLFW Input Mouse Position callback.
mouseBtn : glfw.MouseButtonFun = nil; # GLFW Input Mouse Button callback.
mouseScroll : glfw.ScrollFun = nil; # GLFW Input Mouse ScrollWheel callback.
mouseCapture : bool = false; # Whether to capture the mouse on window launch or not
error : glfw.ErrorFun = nil; # GLFW Error callback
vsync : bool = false; # Whether vsync is active or not
```Post-Processing shader example (Simple API):
```nim
var scr = Screen.new(960,540) # Initialize the Screen
scr.addPost(DbgFrag) # Add the Debug Post-Processing effect to the list
while not scr.close(): # Run while the Screen has not been marked for closing
for pix in scr.pixels: pix = rgbx(255,255,255,255) # Generate the pixels on the CPU
scr.update() # Draw the contents (also applies all Post-Processing shaders)
scr.term() # Terminate everything after
```Post-Processing shader removal:
```nim
var shd = scr.addPost( SomeShaderCodeString ) # Returns the (implicitly discarded) handle of the shader
scr.rmvPost( shd ) # Remove the shader from the list with its handle id
```Fully verbose example:
```nim
import glFB#_______________________________________
# Our dummy CPU renderer
from chroma import rgbx
proc renderPixels(scr :var Screen) :void=
for pix in scr.pixels: pix = rgbx(255,255,255,255)
#_______________________________________#_______________________________________
# Our verbose glFB Framebuffer application
#_____________________________
# Input functions for GLFW
from nglfw as glfw import nil
proc myResizeFunction (window :glfw.Window; width, height :cint) {.cdecl.} = discard
proc myKeyboardFunction (window :glfw.Window; key, scancode, action, modifiers :cint) {.cdecl.} = discard
proc myMousePositionFunction (window :glfw.Window; x, y :cdouble) {.cdecl.} = discard
proc myMouseButtonFunction (window :glfw.Window; button, action, modifiers :cint) {.cdecl.} = discard
proc myMouseScrollFunction (window :glfw.Window; xoffset, yoffset :cdouble) {.cdecl.} = discard# Create the Screen object
var scr = Screen.new( # Initialize the Screen object, using the (W,H) variant
W = 960, # (must be explicit) Window and pixelbuffer initial width
H = 540, # (must be explicit) Window and pixelbuffer initial height
title = "glFB | Window",
resizable = true, # Change window to resizable (default false)
resize = myResizeFunction,
key = myKeyboardFunction,
mousePos = myMousePositionFunction,
mouseBtn = myMouseButtonFunction,
mouseScroll = myMouseScrollFunction,
mouseCapture = true, # Change default to capture the mouse (default false)
error = myErrorCallback,
) # << Screen.new( ... )# Generate a custom Post-Processing shader
var shd = scr.addPost( SomeShaderCodeString ) # Store the handle. Will be removed later in the example, using a condition# Do something explicit with glfw on the window
# Could be anything supported by glfw, you have full access to the window context
glfw.setWindowShouldClose(scr.win.ct, true)# Update loop
while not scr.close(): # Run while the Screen has not been marked for closing
scr.renderPixels() # Generate the pixels on the CPU, with the verbose example custom function
if myCondition: scr.rmvPost( shd ) # Remove the post-process effect. Drawing will no longer trigger it
scr.update() # Update the screen contents in the GPU# Terminate after we are done
scr.term() # Terminate everything after
```## Notes:
### No acceleration
The GPU is exclusively used for accessing the data, and transfering it into the screen.
The only GPU-based processing this library does is applying the list of (optional) Post-Processing effects.
This library applies no GPU acceleration anywhere else, which makes it suitable for purely CPU-driven renderers.
### Coordinates
Coordinate (0,0) is topleft of the screen.
OpenGL wants 0,0 to be bottomleft, but glFB changes this in the FST vertex shader, so that the buffer is drawn correctly.## TODO
- [ ] Window size Uniform access
- [ ] Texture size Uniform access
- [ ] Time Uniform access## Low Maintainance mode
This library is in low maintainance mode.New updates are unlikely to be implemented, unless:
- They are randomnly needed for some casual side project _(eg: a gamejam or similar)_
- They are submitted through a PR> Note: Proposals and PRs are very welcomed, and are very likely to be accepted right away.