first working, non optimized, version of the Shader (Julia set only)

This commit is contained in:
Sylvain PILLOT 2023-01-17 12:29:49 +01:00
commit f31f044d4e
16 changed files with 441 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
# Build files
/build-fx
/build-cg
/*.g1a
/*.g3a
# Python bytecode
__pycache__/
# Common IDE files
*.sublime-project
*.sublime-workspace
.vscode

35
CMakeLists.txt Normal file
View File

@ -0,0 +1,35 @@
# Configure with [fxsdk build-fx] or [fxsdk build-cg], which provide the
# toolchain file and module path of the fxSDK
cmake_minimum_required(VERSION 3.15)
project(Schmup VERSION 1.0 LANGUAGES CXX C ASM)
include(GenerateG3A)
include(Fxconv)
find_package(Azur 0.1 REQUIRED)
find_package(Gint 2.9 REQUIRED)
find_package(LibProf 2.4 REQUIRED)
set(SOURCES
src/main.cpp
src/mandelbrotshader.cpp
src/utilities.cpp
# ...
)
set(ASSETS_cg
assets-cg/font.png
# ...
)
fxconv_declare_assets(${ASSETS} ${ASSETS_fx} ${ASSETS_cg} WITH_METADATA)
add_executable(shmup ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}})
target_compile_options(shmup PRIVATE -Wall -Wextra -Os -std=c++20)
target_link_options(shmup PRIVATE -Wl,-Map=Build_Addin.map -Wl,--print-memory-usage -fpermissive)
target_link_libraries(shmup Azur::Azur -lnum LibProf::LibProf Gint::Gint -lstdc++)
if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
generate_g3a(TARGET shmup OUTPUT "MandAzur.g3a"
NAME " " ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
endif()

5
README.md Normal file
View File

@ -0,0 +1,5 @@
# A simple shader for AZUR aiming at computating the Mandelbrot or Julia set
Current data set is for Julia only (for evaluation).
This is a WIP, more cases to be implemented soon.

BIN
assets-cg/font.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,4 @@
*.png:
type: bopti-image
name_regex: (.*)\.png img_\1
profile: p8_rgb565a

BIN
assets-cg/icon-sel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
assets-cg/icon-uns.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

3
build Executable file
View File

@ -0,0 +1,3 @@
rm -r build-cg
rm *.g3a
fxsdk build-cg VERBOSE=1

1
capture Executable file
View File

@ -0,0 +1 @@
fxlink -iw -q

4
clean Executable file
View File

@ -0,0 +1,4 @@
rm -r build-cg/
rm -r build-fx
rm *.g3a
rm *.g1a

1
send Executable file
View File

@ -0,0 +1 @@
fxlink -sw *.g3a -u

169
src/main.cpp Normal file
View File

@ -0,0 +1,169 @@
#include <azur/azur.h>
#include <azur/gint/render.h>
#include <gint/drivers/r61524.h>
#include <gint/rtc.h>
#include <gint/keyboard.h>
#include <gint/kmalloc.h>
#include <libprof.h>
#include <gint/usb.h>
#include <gint/usb-ff-bulk.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fxlibc/printf.h>
#include <cstdint>
#include <num/num.h>
#include "utilities.h"
#include "mandelbrotshader.h"
bool screenshot = false;
bool record = false;
bool textoutput = false;
bool exitToOS = false;
#define SCALE_PIXEL 1
#define X_RESOL (DWIDTH / SCALE_PIXEL)
#define Y_RESOL (DHEIGHT / SCALE_PIXEL)
#define BIAS 1
#define NOBIAS (1-BIAS)
uint8_t texttodraw=1;
static void update( float dt )
{
}
static void get_inputs( void )
{
key_event_t ev;
while((ev = pollevent()).type != KEYEV_NONE)
{
}
if(keydown(KEY_SHIFT)) { }
if(keydown(KEY_EXIT)) {exitToOS = true; };
if(keydown(KEY_7)) {screenshot = true;};
if(keydown(KEY_8)) {record = !record; };
if(keydown(KEY_9)) {textoutput = true;};
if(keydown(KEY_F1)) {texttodraw=0;}
if(keydown(KEY_F2)) {texttodraw=1;}
if(keydown(KEY_F3)) {texttodraw=2;}
if(keydown(KEY_F4)) {texttodraw=3;}
}
int main(void)
{
exitToOS = false;
float elapsedTime = 0.0f;
kmalloc_arena_t *_uram = kmalloc_get_arena("_uram");
kmalloc_gint_stats_t *_uram_stats;
__printf_enable_fp();
__printf_enable_fixed();
azrp_config_scale(SCALE_PIXEL);
azrp_shader_clear_configure();
azrp_shader_image_rgb16_configure();
azrp_shader_image_p8_configure();
azrp_shader_image_p4_configure();
azrp_mandelbrot_init();
usb_interface_t const *interfaces[] = { &usb_ff_bulk, NULL };
usb_open(interfaces, GINT_CALL_NULL);
prof_init();
prof_t perf_update, perf_render;
uint32_t time_update=0, time_render=0;
do
{
perf_update = prof_make();
prof_enter(perf_update);
{
// read inputs from the player
get_inputs( );
// update as per the time spend to do the loop
update( elapsedTime );
// update the RAM consumption status
_uram_stats = kmalloc_get_gint_stats(_uram);
}
prof_leave(perf_update);
time_update = prof_time(perf_update);
perf_render = prof_make();
prof_enter(perf_render);
{
// all the stuff to be rendered should be put here
azrp_clear( C_BLACK );
azrp_mandelbrot();
if (texttodraw>=1) Azur_draw_text(1,01, " FPS = %.0f", (float) (1000000.0f / elapsedTime) );
if (texttodraw>=2) Azur_draw_text(1,31, "Update = %.0f mc secs", (float) time_update );
if (texttodraw>=2) Azur_draw_text(1,41, "Render = %.0f mc secs", (float) time_render );
if (texttodraw>=2) Azur_draw_text(1,51, ">Total = %.3f ml secs", (float) elapsedTime / 1000.0f );
if (texttodraw>=2) Azur_draw_text(1,61, ">Total = %.0f seconds", (float) elapsedTime );
if (texttodraw>=3) Azur_draw_text(1,81, "Mem Used : %d", _uram_stats->used_memory );
if (texttodraw>=3) Azur_draw_text(1,91, "Mem Free : %d", _uram_stats->free_memory );
if (texttodraw>=3) Azur_draw_text(1,101, "Mem Peak Used : %d", _uram_stats->peak_used_memory );
azrp_update();
}
prof_leave(perf_render);
time_render = prof_time(perf_render);
elapsedTime = ((float) (time_update+time_render));
if (screenshot && usb_is_open())
{
usb_fxlink_screenshot(false);
screenshot = false;
}
if(record && usb_is_open())
{
usb_fxlink_videocapture(false);
}
if (textoutput && usb_is_open())
{
azrp_mandelbrot_USBDEBUG( );
textoutput = false;
}
}
while (exitToOS==false);
azrp_mandelbrot_close( );
prof_quit();
usb_close();
return 1;
}

164
src/mandelbrotshader.cpp Normal file
View File

@ -0,0 +1,164 @@
#include <azur/gint/render.h>
#include "mandelbrotshader.h"
#include <cstdlib>
#include <cstdio>
#include <gint/rtc.h>
#include <gint/usb.h>
#include <gint/usb-ff-bulk.h>
#include <num/num.h>
uint8_t AZRP_SHADER_MANDELBROT = -1;
__attribute__((constructor))
static void register_shader(void)
{
extern azrp_shader_t azrp_shader_mandelbrot;
AZRP_SHADER_MANDELBROT = azrp_register_shader(azrp_shader_mandelbrot);
}
void azrp_shader_mandelbrot_configure(void)
{
azrp_set_uniforms(AZRP_SHADER_MANDELBROT, (void *)azrp_width);
}
void azrp_mandelbrot_USBDEBUG( void )
{
char texttosend[1024];
sprintf( texttosend, "data" );
usb_fxlink_text(texttosend, 0);
}
void azrp_mandelbrot_init( )
{
}
void azrp_mandelbrot_close( void )
{
}
struct command {
uint8_t shader_id;
uint8_t current_frag;
libnum::num xmin;
libnum::num xmax;
libnum::num ymin;
libnum::num ymax;
libnum::num xinc;
libnum::num yinc;
};
void azrp_mandelbrot( void )
{
prof_enter(azrp_perf_cmdgen);
struct command cmd;
cmd.shader_id = AZRP_SHADER_MANDELBROT;
cmd.current_frag = 0;
cmd.xmin = libnum::num(-1.98f);
cmd.xmax = libnum::num(1.98f);
cmd.ymin = libnum::num(-1.12f);
cmd.ymax = libnum::num(1.12f);
cmd.xinc = libnum::num((2*1.98f)/azrp_width);
cmd.yinc = libnum::num((2*1.12f)/azrp_height);
int fragmin = 0;
int fragcount = (azrp_height >> 4) + 1;
azrp_queue_command(&cmd, sizeof cmd, fragmin, fragcount);
prof_leave(azrp_perf_cmdgen);
}
void azrp_shader_mandelbrot( void *uniforms, void *comnd, void *fragment )
{
struct command *cmd = (struct command *) comnd;
uint16_t *frag = (uint16_t *) fragment;
int maxiter = 256;
libnum::num cr = libnum::num(-0.480f);
libnum::num ci = libnum::num(0.600f);
for( int j=0; j<16; j++)
{
int offset = azrp_width * j;
for( int i=0; i<azrp_width; i++ )
{
libnum::num zr = cmd->xmin + libnum::num(i)* cmd->xinc;
libnum::num zi = cmd->ymax - libnum::num(cmd->current_frag*16)*cmd->yinc - libnum::num(j)*cmd->yinc;
libnum::num zr2 = zr * zr;
libnum::num zi2 = zi * zi;
int u=0;
while((zr2+zi2)<4 && (u<maxiter))
{
libnum::num temp = zr;
zr2 = zr * zr;
zi2 = zi * zi;
zr = zr2 - zi2 + cr;
zi = 2*zi*temp + ci;
u++;
}
if(u==maxiter)
{
frag[offset + i] = 0x0000;
}
else
{
int CR, CG, CB;
if (u<maxiter/4)
{
CR = 0;
CG = u*4;
CB = 255;
}
else if (u<2*maxiter/4)
{
CR = 0;
CG = 255;
CB = 255-(u-maxiter)/4;
}
else if (u<3*maxiter/4)
{
CR = (u-2*maxiter)/4;
CG = 255;
CB = 0;
}
else if (u<4*maxiter/4)
{
CR = 255;
CG = 255-(u-3*maxiter)/4;
CB = 0;
}
frag[offset + i] = C_RGB(CR,CG,CB);
}
}
}
cmd->current_frag++;
}

9
src/mandelbrotshader.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef MANDELBROT_SHADER_H
#define MANDELBROT_SHADER_H
void azrp_mandelbrot( void );
void azrp_mandelbrot_init( void );
void azrp_mandelbrot_close( void );
void azrp_mandelbrot_USBDEBUG( void );
#endif //MYAZURSHADERS_H

27
src/utilities.cpp Normal file
View File

@ -0,0 +1,27 @@
#include <azur/azur.h>
#include <azur/gint/render.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fxlibc/printf.h>
/* Render text with Azur images - quite bad, but I don't have time lol. */
void Azur_draw_text(int x, int y, char const *fmt, ...)
{
char str[128];
va_list args;
va_start(args, fmt);
vsnprintf(str, 128, fmt, args);
va_end(args);
extern bopti_image_t img_font;
for(int i = 0; str[i]; i++) {
if(str[i] < 32 || str[i] >= 0x7f) continue;
int row = (str[i] - 32) >> 4;
int col = (str[i] - 32) & 15;
azrp_subimage(x + 5 * i, y, &img_font, 7 * col + 1, 9 * row + 1, 6, 8, DIMAGE_NONE);
}
}

6
src/utilities.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef UTILITIES_H
#define UTILITIES_H
void Azur_draw_text(int x, int y, char const *fmt, ...);
#endif