diff options
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | fractal.c | 411 |
2 files changed, 419 insertions, 10 deletions
@@ -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 @@ -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; } + + |