summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZoRo <dos21h@gmail.com>2020-10-21 21:24:36 +0100
committerZoRo <dos21h@gmail.com>2020-10-21 21:24:36 +0100
commit50756d266af3dd94d55a9b0d3b6e7e4f953ac627 (patch)
tree83dbc53a659454c0ff1c17448b9c4235b0236059
parenta73c7a57888f0f44f298ec425fc5abd3cfcffd62 (diff)
downloadwasm_fractal-50756d266af3dd94d55a9b0d3b6e7e4f953ac627.tar.gz
wasm_fractal-50756d266af3dd94d55a9b0d3b6e7e4f953ac627.zip
Working fractal drawing
-rw-r--r--Makefile18
-rw-r--r--fractal.c411
2 files changed, 419 insertions, 10 deletions
diff --git a/Makefile b/Makefile
index 7f8696f..9e99e53 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,21 @@
-
+#source "/home/fam/downloads/source/wasm/emsdk/emsdk_env.sh"
+#EMCC=/usr/lib/emscripten/emcc
+#ENV=LLVM=/usr/bin NODE_JS=node EMSCRIPTEN_ROOT=/usr/lib/emscripten
+EMCC=emcc
CC=gcc
+LDFLAGS=-lSDL2 -lSDL2_ttf -lGLESv2 -lGL
+EM_LDFALGS=-s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png"]' -s USE_SDL_TTF=2 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s LLD_REPORT_UNDEFINED -s USE_GLFW=3
make:
$(CC) -c koh.c
$(CC) -c fractal.c
- $(CC) koh.o fractal.o -o fractal -lSDL2 \ No newline at end of file
+ $(CC) -c fractal2.c
+ $(CC) koh.o fractal.o -o fractal $(LDFLAGS)
+ $(CC) koh.o fractal2.o -o fractal2 $(LDFLAGS)
+
+emcc:
+ $(EMCC) fractal.c koh.c -s WASM=1 -O3 -o index.js $(EM_LDFALGS) -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
+ #$(EMCC) fractal2.c koh.c -s WASM=1 -O3 -o index.js $(EM_LDFALGS) -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
+
+web:
+ darkhttpd ./ --port 12345 \ No newline at end of file
diff --git a/fractal.c b/fractal.c
index 98410d9..2f01a7f 100644
--- a/fractal.c
+++ b/fractal.c
@@ -6,18 +6,38 @@
#include <stdint.h>
#include <time.h>
+#if __EMSCRIPTEN__
+#include <emscripten/emscripten.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+#include <GLES2/gl2.h>
+#else
#include <SDL2/SDL.h>
+#include <SDL2/SDL_ttf.h>
+#include <GLES2/gl2.h>
+#endif
+
+
+//#include <GL/glu.h>
#include "koh.h"
//#include "queue.h"
-#define SCREEN_WIDTH 160
-#define SCREEN_HEIGHT 160
+#define SCREEN_WIDTH 320
+#define SCREEN_WIDTH2 (SCREEN_WIDTH/2)
+#define SCREEN_HEIGHT 320
+#define SCREEN_HEIGHT2 (SCREEN_HEIGHT/2)
+#define MAX_GENERATION 5
static int quit=0;
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
+typedef struct rgba32_t
+{
+ double r,g,b,a;
+} rgba32_t;
+
#define MAX_LEVEL 7
#define QUEUE_SIZE (1+MAX_LEVEL*MAX_LEVEL*MAX_LEVEL*MAX_LEVEL)
@@ -40,8 +60,16 @@ void queue_init()
void queue_add(koh_node kn)
{
+ if (queue_index > QUEUE_SIZE)
+ {
+ printf("Cannot add to queue\n");
+ //return -1;
+ return ;
+ }
koh_queue[queue_index] = kn;
queue_index += 1;
+ return;
+ //return 0;
}
@@ -59,16 +87,358 @@ koh_node queue_get(int idx)
return kn;
}
+rgba32_t color_gen_shade(rgba32_t original, int gen, int max_gen)
+{
+ rgba32_t c = {0,0,0,0};
+
+ c.r = (1.0*original.r/max_gen)*gen;
+ c.g = (1.0*original.g/max_gen)*gen;
+ c.b = (1.0*original.b/max_gen)*gen;
+ c.a = original.a;
+
+ return c;
+}
+rgba32_t color_gen_shade_inv(rgba32_t original, int gen, int max_gen)
+{
+ rgba32_t c = {0,0,0,0};
+
+ c.r = original.r-(1.0*original.r/max_gen)*gen;
+ c.g = original.g-(1.0*original.g/max_gen)*gen;
+ c.b = original.b-(1.0*original.b/max_gen)*gen;
+ c.a = original.a;
+
+ return c;
+}
+
+rgba32_t color_gen_mainlv(rgba32_t original, int gen, int max_gen)
+{
+ double color_r = 10.0/255;
+ double color_g = 20.0/255;
+ double color_b = 14.0/255;
+ rgba32_t c = {color_r, color_g, color_b,0};
+
+ /*
+ c.r = 1.0*180/255 + (gen-max_gen)*color_r;
+ c.g = 1.0*100/255 + (gen-max_gen)*color_g;
+ c.b = 1.0*50/255 + (gen-max_gen)*color_b;
+ */
+ c.r = 1.0*180/255 - (max_gen-gen)*color_r;
+ c.g = 1.0*100/255 - (max_gen-gen)*color_g;
+ c.b = 1.0*50/255 - (max_gen-gen)*color_b;
+ c.a = original.a;
+
+ return c;
+}
+
+void generate_koh(int gener, double size, int posx, int posy, double k)
+{
+ int i;
+ koh_node kn = {-1,-1,-1,-1};
+
+ printf("%f %f\n",size,k);
+ double t_size = size*k;
+
+ if (gener<0)
+ {
+ //return 0;
+ return;
+ }
+
+ kn.generaton = gener;
+ kn.size = size;
+ kn.x = posx;
+ kn.y = posy;
+
+
+ printf("Gener %d posx %d posy %d size %f=>%f\n",gener,posx,posy,size,t_size);
+ queue_add(kn);
+
+ generate_koh(gener-1, t_size, posx-t_size/2, posy-t_size/2, k);
+ generate_koh(gener-1, t_size, posx-t_size/2, posy+size-t_size/2, k);
+ generate_koh(gener-1, t_size, posx+size-t_size/2, posy+size-t_size/2, k);
+ generate_koh(gener-1, t_size, posx+size-t_size/2, posy-t_size/2, k);
+}
+
+void Rect( GLfloat w, GLfloat h )
+{
+ /*
+ glBegin( GL_QUADS );
+ glVertex3f( -w, h, 0.0f );
+ glVertex3f( w, h, 0.0f );
+ glVertex3f( w, -h, 0.0f );
+ glVertex3f( -w, -h, 0.0f );
+ glEnd();
+ */
+}
+
+void Triangle( int x, int y, int w, int h)
+{
+ // An array of 3 vectors which represents 3 vertices
+ static const GLfloat g_vertex_buffer_data[] = {
+ -1.0f, -1.0f, 0.0f,
+ 1.0f, -1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ };
+
+ // This will identify our vertex buffer
+ GLuint vertexbuffer;
+ // Generate 1 buffer, put the resulting identifier in vertexbuffer
+ glGenBuffers(1, &vertexbuffer);
+ // The following commands will talk about our 'vertexbuffer' buffer
+ glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
+ // Give our vertices to OpenGL.
+ glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
+ glVertexAttribPointer(
+ 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
+ 3, // size
+ GL_FLOAT, // type
+ GL_FALSE, // normalized?
+ 0, // stride
+ (void*)0 // array buffer offset
+ );
+ // Draw the triangle !
+ glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
+ glDisableVertexAttribArray(0);
+
+}
+
+
+// Shader sources
+const GLchar* vertexSource =
+ "attribute vec4 position; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = vec4(position.xyz, 1.0); \n"
+ "} \n";
+const GLchar* fragmentSource =
+ "precision mediump float;\n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = vec4 (1.0, 1.0, 1.0, 1.0 );\n"
+ "} \n";
+
+
+GLuint vertexShader;
+GLuint fragmentShader;
+GLuint shaderProgram;
+GLint posAttrib;
+
+
+void RectPX( int x, int y,int w, int h )
+{
+ GLfloat x1 = (1.0f*x-SCREEN_WIDTH2)/SCREEN_WIDTH2;
+ GLfloat y1 = (1.0f*y-SCREEN_HEIGHT2)/SCREEN_HEIGHT2;
+ GLfloat x2 = (1.0f*(x+w)-SCREEN_WIDTH2)/SCREEN_WIDTH2;
+ GLfloat y2 = (1.0f*(y+h)-SCREEN_HEIGHT2)/SCREEN_HEIGHT2;
+ GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f,
+ -0.5f, -0.5f, 0.0f,
+ 0.5f, -0.5f, 0.0f };
+ GLuint vertexPosObject;
+ glGenBuffers(1, &vertexPosObject);
+ glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
+ glBufferData(GL_ARRAY_BUFFER, 9*4, vVertices, GL_STATIC_DRAW);
+ //glClear ( GL_COLOR_BUFFER_BIT );
+ glEnableVertexAttribArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
+ glVertexAttribPointer(0 /* ? */, 3, GL_FLOAT, GL_FALSE, 0, 0);
+
+ glDrawArrays ( GL_TRIANGLES, 0, 3 );
+
+
+
+ /*
+ glBegin( GL_QUADS );
+ glVertex3f( x1, y2, 0.0f );
+ glVertex3f( x2, y2, 0.0f );
+ glVertex3f( x2, y1, 0.0f );
+ glVertex3f( x1, y1, 0.0f );
+ glEnd();
+ */
+
+}
+
+
+void RectPX2( int x, int y,int w, int h )
+{
+ GLfloat x1 = (1.0f*x-SCREEN_WIDTH2)/SCREEN_WIDTH2;
+ GLfloat y1 = (1.0f*y-SCREEN_HEIGHT2)/SCREEN_HEIGHT2;
+ GLfloat x2 = (1.0f*(x+w)-SCREEN_WIDTH2)/SCREEN_WIDTH2;
+ GLfloat y2 = (1.0f*(y+h)-SCREEN_HEIGHT2)/SCREEN_HEIGHT2;
+ GLfloat vVertices[] = { x1, y2, 0.0f,
+ x2, y2, 0.0f,
+ x2, y1, 0.0f,
+ x1, y1, 0.0f };
+ GLuint vertexPosObject;
+
+ printf("x1 %f y1 %f x2 %f y2 %f\n",x1,y1,x2,y2);
+
+ glGenBuffers(1, &vertexPosObject);
+ glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), vVertices, GL_STATIC_DRAW);
+ //glClear ( GL_COLOR_BUFFER_BIT );
+ glEnableVertexAttribArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
+ glVertexAttribPointer(0 /* ? */, 3, GL_FLOAT, GL_FALSE, 0, 0);
+
+ glDrawArrays ( GL_TRIANGLE_FAN, 0, 4 );
+
+}
+
+rgba32_t start_col = {1.0,1.0,1.0,0.0};
+
+#if __EMSCRIPTEN__
+void main_tick() {
+#else
+int main_tick() {
+#endif
+ int i,j;
+ SDL_Event event;
+ SDL_StartTextInput();
+ //while (quit == 0)
+ //{
+ while (SDL_PollEvent(&event))
+ {
+
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ {
+ quit = 1;
+ break;
+ }
+ //case SDL_KE
+ }
+
+ //sleep(1);
+ }
+
+
+ //SDL_SetRenderDrawColor(renderer, 0, 100, 0, 0);
+ //SDL_RenderClear(renderer);
+ //SDL_RenderPresent(renderer);
+
+ glClear( GL_COLOR_BUFFER_BIT );
+ //glLoadIdentity();
+
+ for (i=0;i<=MAX_GENERATION;i++)
+ {
+ //rgba32_t c = color_gen_shade(start_col, i, MAX_GENERATION);
+ rgba32_t c = color_gen_mainlv(start_col, i, MAX_GENERATION);
+ //glColor3f( c.r , c.g , c.b );
+ //static int once=0
+ for (j=0;j<queue_index;j++)
+ {
+
+
+ if (koh_queue[j].generaton == i)
+ {
+ koh_node kn = queue_get(j);
+ printf("j:%d %d %d %d\n",j,kn.x, kn.y, kn.size);
+ //RectPX(kn.x, kn.y, kn.size, kn.size);
+ RectPX2(kn.x, kn.y, kn.size, kn.size);
+ //Triangle(kn.x, kn.y, kn.size, kn.size);
+ }
+ }
+ }
+ SDL_GL_SwapWindow( window );
+ //SDL_UpdateWindowSurface(window);
+ SDL_Delay( 1 );
+ //}
+
+#if !__EMSCRIPTEN__
+ return 0;
+#endif
+}
+
+void main_loop()
+{
+
+#if __EMSCRIPTEN__
+ emscripten_set_main_loop(main_tick, -1, 1);
+#else
+ while (0 == quit)
+ {
+
+ main_tick();
+ printf("One tick\n");
+ //sleep(1);
+ }
+#endif
+}
+
int main()
{
+ int i,j;
SDL_Event event;
+ GLenum error = GL_NO_ERROR;
printf("Max queue size %d\n", QUEUE_SIZE);
SDL_Init(SDL_INIT_VIDEO);
- window = SDL_CreateWindow("KOH", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL);
+ //Use OpenGL 2.1
+ SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
+ SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
+ window = SDL_CreateWindow("KOH", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
- SDL_SetRenderDrawColor(renderer, 0xff, 0x99, 0x99, 0x99);
+ SDL_SetRenderDrawColor(renderer, 0xff, 0xaa, 0xaa, 0xaa);
+ SDL_GLContext gl_context = SDL_GL_CreateContext(window);
+ SDL_GL_SetSwapInterval( 1 );
+
+ //init OpenGL
+ //glMatrixMode( GL_PROJECTION );
+ //glLoadIdentity();
+ error = glGetError();
+ if( error != GL_NO_ERROR )
+ {
+ printf( "Error initializing OpenGL! \n");
+ }
+ //glMatrixMode( GL_MODELVIEW );
+ //glLoadIdentity();
+ error = glGetError();
+ if( error != GL_NO_ERROR )
+ {
+ printf( "Error initializing OpenGL! \n");
+ }
+ glClearColor( 0.f, 0.f, 1.f, 1.f );
+ error = glGetError();
+ if( error != GL_NO_ERROR )
+ {
+ printf( "Error initializing OpenGL!\n" );
+ }
+
+ const int frac_size=100;
+ generate_koh(MAX_GENERATION, frac_size, SCREEN_WIDTH2-frac_size/2, SCREEN_HEIGHT2-frac_size/2, 0.5);
+
+ //prepare shaders
+ vertexShader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vertexShader, 1, &vertexSource, NULL);
+ glCompileShader(vertexShader);
+ // Create and compile the fragment shader
+ fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
+ glCompileShader(fragmentShader);
+
+ // Link the vertex and fragment shader into a shader program
+ shaderProgram = glCreateProgram();
+ glAttachShader(shaderProgram, vertexShader);
+ glAttachShader(shaderProgram, fragmentShader);
+ // glBindFragDataLocation(shaderProgram, 0, "outColor");
+ glLinkProgram(shaderProgram);
+ glUseProgram(shaderProgram);
+
+ posAttrib = glGetAttribLocation(shaderProgram, "position");
+ glEnableVertexAttribArray(posAttrib);
+ //changed from 2 to 3
+ glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
+
+ main_loop();
+ /*
+ //Enable text input
+ SDL_StartTextInput();
while (quit == 0)
{
while (SDL_PollEvent(&event))
@@ -87,17 +457,42 @@ int main()
//sleep(1);
}
- SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
- SDL_RenderClear(renderer);
- SDL_RenderPresent(renderer);
+
+ //SDL_SetRenderDrawColor(renderer, 0, 100, 0, 0);
+ //SDL_RenderClear(renderer);
+ //SDL_RenderPresent(renderer);
+
+ glClear( GL_COLOR_BUFFER_BIT );
+ //glLoadIdentity();
+
+ for (i=0;i<=MAX_GENERATION;i++)
+ {
+ //rgba32_t c = color_gen_shade(start_col, i, MAX_GENERATION);
+ rgba32_t c = color_gen_mainlv(start_col, i, MAX_GENERATION);
+ //glColor3f( c.r , c.g , c.b );
+ for (j=0;j<queue_index;j++)
+ {
+ if (koh_queue[j].generaton == i)
+ {
+ koh_node kn = queue_get(j);
+ //printf("%d %d %d\n",kn.x, kn.y, kn.size);
+ RectPX(kn.x, kn.y, kn.size, kn.size);
+ }
+ }
+ }
+ SDL_GL_SwapWindow( window );
+ SDL_Delay( 1 );
}
+ */
+ //SDL_StopTextInput();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
-
return 0;
}
+
+