Compare commits
4 Commits
2b43c56ee6
...
96659f96a6
Author | SHA1 | Date |
---|---|---|
Sylvain PILLOT | 96659f96a6 | |
Sylvain PILLOT | d0100044fa | |
Sylvain PILLOT | e46df574d4 | |
Sylvain PILLOT | 18871a5964 |
|
@ -2,7 +2,7 @@
|
|||
# toolchain file and module path of the fxSDK
|
||||
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(Schmup VERSION 1.0 LANGUAGES CXX C ASM)
|
||||
project(MandAzur VERSION 1.0 LANGUAGES CXX C ASM)
|
||||
|
||||
include(GenerateG3A)
|
||||
include(Fxconv)
|
||||
|
@ -13,7 +13,9 @@ find_package(LibProf 2.4 REQUIRED)
|
|||
|
||||
set(SOURCES
|
||||
src/main.cpp
|
||||
src/mandelbrot.s
|
||||
src/mandelbrotshader.cpp
|
||||
src/juliashader.cpp
|
||||
src/utilities.cpp
|
||||
# ...
|
||||
)
|
||||
|
@ -24,12 +26,12 @@ set(ASSETS_cg
|
|||
|
||||
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++)
|
||||
add_executable(mandazur ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}})
|
||||
target_compile_options(mandazur PRIVATE -Wall -Wextra -Os -std=c++20)
|
||||
target_link_options(mandazur PRIVATE -Wl,-Map=Build_Addin.map -Wl,--print-memory-usage -fpermissive)
|
||||
target_link_libraries(mandazur Azur::Azur -lnum LibProf::LibProf Gint::Gint -lstdc++)
|
||||
|
||||
if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
|
||||
generate_g3a(TARGET shmup OUTPUT "MandAzur.g3a"
|
||||
generate_g3a(TARGET mandazur OUTPUT "MandAzur.g3a"
|
||||
NAME " " ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
|
||||
endif()
|
||||
|
|
|
@ -6,4 +6,9 @@ void azrp_mandelbrot_init( void );
|
|||
void azrp_mandelbrot_close( void );
|
||||
void azrp_mandelbrot_USBDEBUG( void );
|
||||
|
||||
void azrp_julia( void );
|
||||
void azrp_julia_init( void );
|
||||
void azrp_julia_close( void );
|
||||
void azrp_julia_USBDEBUG( void );
|
||||
|
||||
#endif //MYAZURSHADERS_H
|
|
@ -0,0 +1,174 @@
|
|||
#include <azur/gint/render.h>
|
||||
#include "fractalshaders.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_JULIA = -1;
|
||||
|
||||
|
||||
__attribute__((constructor))
|
||||
static void register_shader(void)
|
||||
{
|
||||
extern azrp_shader_t azrp_shader_julia;
|
||||
AZRP_SHADER_JULIA = azrp_register_shader(azrp_shader_julia);
|
||||
}
|
||||
|
||||
|
||||
void azrp_shader_julia_configure(void)
|
||||
{
|
||||
azrp_set_uniforms(AZRP_SHADER_JULIA, (void *)azrp_width);
|
||||
}
|
||||
|
||||
|
||||
void azrp_julia_USBDEBUG( void )
|
||||
{
|
||||
char texttosend[1024];
|
||||
|
||||
sprintf( texttosend, "data" );
|
||||
usb_fxlink_text(texttosend, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void azrp_julia_init( )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void azrp_julia_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_julia( void )
|
||||
{
|
||||
prof_enter(azrp_perf_cmdgen);
|
||||
|
||||
struct command cmd;
|
||||
|
||||
cmd.shader_id = AZRP_SHADER_JULIA;
|
||||
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_julia( void *uniforms, void *comnd, void *fragment )
|
||||
{
|
||||
struct command *cmd = (struct command *) comnd;
|
||||
uint16_t *frag = (uint16_t *) fragment;
|
||||
|
||||
int maxiter = 256;
|
||||
|
||||
libnum::num zr, zr2;
|
||||
libnum::num zi, zi2;
|
||||
|
||||
libnum::num cr = libnum::num(-0.480f);
|
||||
libnum::num ci = libnum::num(0.600f);
|
||||
|
||||
libnum::num zrsave = cmd->xmin;
|
||||
libnum::num zisave = cmd->ymax - libnum::num(cmd->current_frag*16)*cmd->yinc;
|
||||
|
||||
int offset = 0;
|
||||
|
||||
for( int j=0; j<16; j++)
|
||||
{
|
||||
for( int i=0; i<azrp_width; i++ )
|
||||
{
|
||||
zr = zrsave;
|
||||
zi = zisave;
|
||||
zr2 = zr * zr;
|
||||
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);
|
||||
}
|
||||
|
||||
zrsave += cmd->xinc;
|
||||
|
||||
}
|
||||
|
||||
zrsave = cmd->xmin;
|
||||
zisave -= cmd->yinc;
|
||||
|
||||
offset += azrp_width;
|
||||
|
||||
}
|
||||
|
||||
cmd->current_frag++;
|
||||
}
|
21
src/main.cpp
21
src/main.cpp
|
@ -19,7 +19,7 @@
|
|||
#include <num/num.h>
|
||||
|
||||
#include "utilities.h"
|
||||
#include "mandelbrotshader.h"
|
||||
#include "fractalshaders.h"
|
||||
|
||||
|
||||
bool screenshot = false;
|
||||
|
@ -36,8 +36,13 @@ bool exitToOS = false;
|
|||
|
||||
uint8_t texttodraw=2;
|
||||
|
||||
uint8_t Mandel_Julia_Switch = 1;
|
||||
|
||||
|
||||
void do_nothing( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void update( float dt )
|
||||
{
|
||||
|
@ -45,7 +50,6 @@ static void update( float dt )
|
|||
|
||||
}
|
||||
|
||||
|
||||
static void get_inputs( void )
|
||||
{
|
||||
key_event_t ev;
|
||||
|
@ -66,6 +70,8 @@ static void get_inputs( void )
|
|||
if(keydown(KEY_F2)) {texttodraw=1;}
|
||||
if(keydown(KEY_F3)) {texttodraw=2;}
|
||||
if(keydown(KEY_F4)) {texttodraw=3;}
|
||||
if(keydown(KEY_F5)) {Mandel_Julia_Switch=1;} // switch to Julia Set
|
||||
if(keydown(KEY_F6)) {Mandel_Julia_Switch=2;} // switch to Mandelbrot Set
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,6 +93,7 @@ int main(void)
|
|||
azrp_shader_image_p4_configure();
|
||||
|
||||
azrp_mandelbrot_init();
|
||||
azrp_julia_init();
|
||||
|
||||
usb_interface_t const *interfaces[] = { &usb_ff_bulk, NULL };
|
||||
usb_open(interfaces, GINT_CALL_NULL);
|
||||
|
@ -121,7 +128,9 @@ int main(void)
|
|||
// all the stuff to be rendered should be put here
|
||||
azrp_clear( C_BLACK );
|
||||
|
||||
azrp_mandelbrot();
|
||||
if (Mandel_Julia_Switch==1) azrp_mandelbrot();
|
||||
else if(Mandel_Julia_Switch==2) azrp_julia();
|
||||
else do_nothing();
|
||||
|
||||
if (texttodraw>=1) Azur_draw_text(1,01, " FPS = %.0f - Render = %.0f", (float) (1000000.0f / elapsedTime), (float) time_render / 1000.0f );
|
||||
if (texttodraw>=2) Azur_draw_text(1,31, "Update = %.0f mc secs", (float) time_update );
|
||||
|
@ -153,7 +162,10 @@ int main(void)
|
|||
|
||||
if (textoutput && usb_is_open())
|
||||
{
|
||||
azrp_mandelbrot_USBDEBUG( );
|
||||
if (Mandel_Julia_Switch==1) azrp_mandelbrot_USBDEBUG( );
|
||||
else if (Mandel_Julia_Switch==2) azrp_julia_USBDEBUG( );
|
||||
else do_nothing( );
|
||||
|
||||
textoutput = false;
|
||||
}
|
||||
}
|
||||
|
@ -161,6 +173,7 @@ int main(void)
|
|||
|
||||
|
||||
azrp_mandelbrot_close( );
|
||||
azrp_julia_close( );
|
||||
|
||||
prof_quit();
|
||||
usb_close();
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
/*
|
||||
int mandelbrot(int32_t cr, int32_t ci, uint32_t t_squared, int steps);
|
||||
(Pour moi : t_squared = (2 * 2) << 16, steps = 50)
|
||||
Si renvoie 0 -> dans la fractale
|
||||
Sinon renvoie un nombre entre 1...steps indiquant la "distance" (pour le dégradé)
|
||||
*/
|
||||
|
||||
.global _mandelbrot
|
||||
.text
|
||||
|
||||
/* Iteration of z = z²+c with threshold checks
|
||||
@r4 Real part of c, cr
|
||||
@r5 Imaginary part of c, ci
|
||||
@r6 Squared threshold t²
|
||||
@r7 Number of steps
|
||||
If c is in the set, returns 0. Otherwise, returns the remaining number of
|
||||
iterations to be checked before the process finised. */
|
||||
_mandelbrot:
|
||||
mov.l r8, @-r15
|
||||
mov.l r9, @-r15
|
||||
|
||||
/* Start with z=z²=0 (z=x+iy) */
|
||||
mov #0, r0
|
||||
mov #0, r1
|
||||
mov #0, r2
|
||||
mov #0, r3
|
||||
|
||||
.loop:
|
||||
/* Start xy */
|
||||
dmuls.l r0, r1
|
||||
|
||||
/* Update x = x²-y²+cr */
|
||||
mov r2, r0
|
||||
sub r3, r0
|
||||
add r4, r0
|
||||
|
||||
/* Get y = 2xy+ci while starting x²
|
||||
TODO: Hope there's no overflow in that [shll r1]. It might be
|
||||
TODO: provable because 2xy overflowing probably implies a lower
|
||||
TODO: bound on x²+y² at the previous iteration. */
|
||||
sts mach, r8
|
||||
sts macl, r1
|
||||
dmuls.l r0, r0
|
||||
xtrct r8, r1
|
||||
shll r1
|
||||
add r5, r1
|
||||
|
||||
/* Get x² and keep the integer part at full precision for ∥z∥²; at the
|
||||
same time, start y² */
|
||||
sts mach, r8
|
||||
sts macl, r2
|
||||
dmuls.l r1, r1
|
||||
xtrct r8, r2
|
||||
|
||||
/* Get y² and compute ∥z∥² = x²+y² in 32:0 format */
|
||||
sts mach, r9
|
||||
sts macl, r3
|
||||
add r9, r8
|
||||
xtrct r9, r3
|
||||
|
||||
/* Compare ∥z∥² to t², return if the threshold is reached */
|
||||
cmp/ge r6, r8
|
||||
bt .end
|
||||
|
||||
/* Continue looping */
|
||||
dt r7
|
||||
bf .loop
|
||||
|
||||
.end:
|
||||
mov.l @r15+, r9
|
||||
mov.l @r15+, r8
|
||||
rts
|
||||
mov r7, r0
|
|
@ -1,5 +1,5 @@
|
|||
#include <azur/gint/render.h>
|
||||
#include "mandelbrotshader.h"
|
||||
#include "fractalshaders.h"
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
|
@ -70,8 +70,8 @@ void azrp_mandelbrot( void )
|
|||
|
||||
cmd.shader_id = AZRP_SHADER_MANDELBROT;
|
||||
cmd.current_frag = 0;
|
||||
cmd.xmin = libnum::num(-1.98f);
|
||||
cmd.xmax = libnum::num(1.98f);
|
||||
cmd.xmin = libnum::num(-2.48f);
|
||||
cmd.xmax = libnum::num(1.48f);
|
||||
cmd.ymin = libnum::num(-1.12f);
|
||||
cmd.ymax = libnum::num(1.12f);
|
||||
cmd.xinc = libnum::num((2*1.98f)/azrp_width);
|
||||
|
@ -83,23 +83,24 @@ void azrp_mandelbrot( void )
|
|||
prof_leave(azrp_perf_cmdgen);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
extern int mandelbrot(int32_t cr, int32_t ci, uint32_t t_squared, int steps);
|
||||
}
|
||||
|
||||
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;
|
||||
int maxiter = 60;
|
||||
|
||||
libnum::num zr, zr2;
|
||||
libnum::num zi, zi2;
|
||||
|
||||
libnum::num cr = libnum::num(-0.480f);
|
||||
libnum::num ci = libnum::num(0.600f);
|
||||
libnum::num zr, zi;
|
||||
|
||||
libnum::num zrsave = cmd->xmin;
|
||||
libnum::num zisave = cmd->ymax - libnum::num(cmd->current_frag*16)*cmd->yinc;
|
||||
|
||||
int u;
|
||||
|
||||
int offset = 0;
|
||||
|
||||
for( int j=0; j<16; j++)
|
||||
|
@ -108,66 +109,19 @@ void azrp_shader_mandelbrot( void *uniforms, void *comnd, void *fragment )
|
|||
{
|
||||
zr = zrsave;
|
||||
zi = zisave;
|
||||
zr2 = zr * zr;
|
||||
zi2 = zi * zi;
|
||||
|
||||
int u=0;
|
||||
u = mandelbrot( zr.v, zi.v, (2*2)<<16, maxiter );
|
||||
|
||||
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);
|
||||
}
|
||||
if (u==0) frag[offset + i] = C_RGB(255,255,255);
|
||||
else frag[offset + i] = C_RGB(u*4,u*4,u*4);
|
||||
|
||||
zrsave += cmd->xinc;
|
||||
|
||||
}
|
||||
|
||||
zrsave = cmd->xmin;
|
||||
zisave -= cmd->yinc;
|
||||
|
||||
offset += azrp_width;
|
||||
|
||||
}
|
||||
|
||||
cmd->current_frag++;
|
||||
|
|
Loading…
Reference in New Issue