Select Git revision
gfx.c 4.52 KiB
/// @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)
{
}
}