/// @file gfx.c /// @author Florent Gluck /// @date November 6, 2016 /// Helper routines to render pixels in fullscreen graphic mode. /// Uses the SDL2 library. #include "gfx.h" /// Create a fullscreen graphic window. /// @param title Title of the window. /// @param width Width of the window in pixels. /// @param height Height of the window in pixels. /// @return a pointer to the graphic context or NULL if it failed. struct gfx_context_t* gfx_create(char *title, uint width, uint height) { if (SDL_Init(SDL_INIT_VIDEO) != 0) goto error; SDL_Window *window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_RESIZABLE); SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0); SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height); uint32_t *pixels = malloc(width*height*sizeof(uint32_t)); struct gfx_context_t *ctxt = malloc(sizeof(struct gfx_context_t)); //printf("%d %d %d %d %d ",window,renderer,texture,pixels,ctxt); if (!window || !renderer || !texture || !pixels || !ctxt) goto error; ctxt->renderer = renderer; ctxt->texture = texture; ctxt->window = window; ctxt->width = width; ctxt->height = height; ctxt->pixels = pixels; SDL_ShowCursor(SDL_DISABLE); gfx_clear(ctxt, COLOR_BLACK); return ctxt; error: return NULL; } /// Draw a pixel in the specified graphic context. /// @param ctxt Graphic context where the pixel is to be drawn. /// @param x X coordinate of the pixel. /// @param y Y coordinate of the pixel. /// @param color Color of the pixel. void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y, uint32_t color) { if (x < ctxt->width && y < ctxt->height) ctxt->pixels[ctxt->width*y+x] = color; } /// Clear the specified graphic context. /// @param ctxt Graphic context to clear. /// @param color Color to use. void gfx_clear(struct gfx_context_t *ctxt, uint32_t color) { int n = ctxt->width*ctxt->height; while (n) ctxt->pixels[--n] = color; } /// Display the graphic context. /// @param ctxt Graphic context to clear. void gfx_present(struct gfx_context_t *ctxt) { SDL_UpdateTexture(ctxt->texture, NULL, ctxt->pixels, ctxt->width*sizeof(uint32_t)); SDL_RenderCopy(ctxt->renderer, ctxt->texture, NULL, NULL); SDL_RenderPresent(ctxt->renderer); } /// Destroy a graphic window. /// @param ctxt Graphic context of the window to close. void gfx_destroy(struct gfx_context_t *ctxt) { SDL_ShowCursor(SDL_ENABLE); SDL_DestroyTexture(ctxt->texture); SDL_DestroyRenderer(ctxt->renderer); SDL_DestroyWindow(ctxt->window); free(ctxt->pixels); ctxt->texture = NULL; ctxt->renderer = NULL; ctxt->window = NULL; ctxt->pixels = NULL; SDL_Quit(); free(ctxt); } /// If a key was pressed, returns its key code (non blocking call). /// List of key codes: https://wiki.libsdl.org/SDL_Keycode /// @return the key that was pressed or 0 if none was pressed. SDL_Keycode gfx_keypressed() { SDL_Event event; if (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) return event.key.keysym.sym; } return 0; } void drawCarrer(struct gfx_context_t *context,int posX,int posY,int carrer) { uint32_t color = MAKE_COLOR(255,0,0); for(int i=0;i<carrer;i++) { gfx_putpixel(context, posX+i, posY, color); gfx_putpixel(context, posX+i, posY-carrer, color); gfx_putpixel(context, posX, posY-i, color); gfx_putpixel(context, posX+carrer, posY-i, color); } } void drawGraph(struct gfx_context_t *context,int *tab,int size) { int posX = 50; int posY = 200; int carrer= 200/ size; uint32_t color = MAKE_COLOR(255,0,0); for (int i = 0; i < 400; i++) { gfx_putpixel(context, posX+i, posY, color); gfx_putpixel(context, posX, posY+1, color); } for(int j=0;j<size;j++) { for(int i =1;i<=tab[j];i++) { drawCarrer(context,posX+carrer*j,posY-carrer*i,carrer); } } } struct gfx_context_t *initWindow(int width,int height,char tab[]) { struct gfx_context_t *ctxt = gfx_create(tab, width, height); if (!ctxt) { fprintf(stderr, "Graphics initialization failed!\n"); } return ctxt; } void dessineTab2D(struct gfx_context_t *context ,uint32_t **tab,int width,int height,int lumMax) { int min = 0; uint16_t px; uint32_t intensity,color; for (int i = 0; i < width ; ++i) for (int j = 0; j < height; ++j) { px = tab[i][j]; intensity = (uint32_t)(( px - min)*255) / (255-min); //lumMax color = MAKE_COLOR(intensity,0,0); gfx_putpixel(context, i, j, color); } } void waitSpacePress() { while (gfx_keypressed() != SDLK_ESCAPE) { } }