summaryrefslogtreecommitdiffstats
path: root/md/writeup/wasm_fractal.md
blob: 62ce8c8241f5dc2d9c855226ffc52b0aa2046d06 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
title:Wasm fractal
keywords:wasm,c,js,emscripten,gcc

# Wasm fractal

## Intro

Since 2000's I have had some tech-dream to use one language to write and its results are available to 
all people independent of platform. In 2020 when WebAssembly is available by default on all platforms
and all major languages are able to translate source code to WebAssembly this era is here ;].
There was time when java applets nad adobe flash where main technologies for interactive web demos, now 
everything could be done with javascript, but also old-style languages like C are able to 
run latest tech in browser woohoo.

## Insights

As demo works on linux and in browser there is some quirks to overcome to make code 
compatible for both technologies. It wasnt straight away to just compile and join app SDL+OpenGL
for wasm. 

### Main loop

Each C program have main entry point. And SDL programm usual structure include loop 
that get events and execute them. 

```c
//Usual SDL code
SDL_Event event;
	SDL_StartTextInput();
        while (SDL_PollEvent(&event) != 0)
        {
            switch (event.type)
                {
                    case SDL_QUIT:
                    {
                        quit = 1;
                        break;
                    }
                    case SDL_KEYDOWN:
                    {
                        switch (event.key.keysym.sym)
                        {
                        case SDLK_DOWN:
                        }
                    }
                }
        }
```

As wasm is running in browser as canvas, then graphics context rendering is controlled from ui thread
so this loop cannot run all the time, and need to return back to ui thread.

```c
void main_loop()
{

#if __EMSCRIPTEN__
    emscripten_set_main_loop(main_tick, 25, 1);
#else
	while (0 == quit)
	{
		main_tick();
	}
#endif
}
```
Main loop where moved to single function. And now its able to run in single cycle for wasm,
and behave as loop for other platforms.


### Static queue

Allocating space in wasm from C with malloc is not supported. There is possibility to write
wrapper that manages static allocated memory, and create wrapper to alloc/dealloc memory.
Or there is possible to create arrays from js and pass buffer to wasm binary. Easier is just
to allocate static buffer. Queue that saves data for fractal iterations is saved in static
allocated buffer.

### Color pallets



### Shaders

First versions of drawing loop didn't worked out of the box in browse. There was spent some time 
to find a way to run shader. Got errors in shader language in browser, while on linux evertyhing
was working. There is version difference between shader language supported between linux and
was platform. Main fix was to define earlier shader language version.

```c
    "#version 100 \n"
    "attribute vec4 position;    \n"
    "attribute vec4 colour;      \n"
    "varying vec4 interpolated_colour;\n"
    "void main()                  \n"
    "{                            \n"
    "   interpolated_colour = colour;\n"
    "   gl_Position = position;  \n"
    "   \n"
    "}  
```

### SDL+GL and compilation

On linux OpenGLES library where used while it have less features then full OpenGL,
for current purpose is have everything. To enable different versions of GL on
wasm need to search for available options inside emscripten sdk js-configuration file.


Compile on linux
```sh
-lSDL2 -lSDL2_ttf -lGLESv2 -lGL
```

Compile with emscripten
```sh
-s USE_SDL=2 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s LLD_REPORT_UNDEFINED -s USE_GLFW=3
```


## Demo page

Permanent residence of demo, with latest version available   
[Demo - http://wasm.main.lv/fractal](http://wasm.main.lv/fractal)  


## Thx

[developers.lv](https://developers.lv) - for first tryouts  [daGrevis](https://github.com/daGrevis),[Aleksejs](https://twitter.com/AleksejsIvanovs),[Tenjou](https://github.com/tenjou)

## Source

Source provided as is, no any attempt to make it easy to build is made.
[http://git.main.lv/cgit.cgi/wasm_fractal.git/](http://git.main.lv/cgit.cgi/wasm_fractal.git/)  


## Links

[01] [main.lv/writeup/web_assembly_sdl_example.md](/writeup/web_assembly_sdl_example.md)  
[02] [https://github.com/opengl-tutorials/ogl/blob/master/tutorial04_colored_cube/tutorial04.cpp](https://github.com/opengl-tutorials/ogl/blob/master/tutorial04_colored_cube/tutorial04.cpp)  
[03] [https://arm-software.github.io/opengl-es-sdk-for-android/introduction_to_shaders.html](https://arm-software.github.io/opengl-es-sdk-for-android/introduction_to_shaders.html)  
[04] [https://gist.github.com/SuperV1234/5c5ad838fe5fe1bf54f9](https://gist.github.com/SuperV1234/5c5ad838fe5fe1bf54f9)