/*************************************************************************** * Copyright (C) 2005 by Michal Turek - Woq * * WOQ (zavinac) seznam.cz * * * * Program vykresli tri ctverce a linku palety sedi primym pristupem * * do graficke pameti surface okna * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include <stdio.h> #include <SDL.h> /* * Symbolicke konstanty * Neni spatny napad nacitat nektere parametry ze souboru... */ #define SDL_SUBSYSTEMS SDL_INIT_VIDEO #define WIN_FLAGS SDL_RESIZABLE #define WIN_WIDTH 320 #define WIN_HEIGHT 240 #define WIN_BPP 0 #define WIN_TITLE "Primy pristup k pixelum surface" /* * Globalni promenne */ SDL_Surface *g_screen; // Surface okna /* * Funkcni prototypy */ bool Init(); // Inicializace void Destroy(); // Deinicializace void Draw(); // Vykresleni bool ProcessEvent(); // Osetruje udalosti int main(int argc, char *argv[]); // Vstup do programu // Zamyka/odemyka surface pro primy pristup k pixelum bool Lock(SDL_Surface *surface); void Unlock(SDL_Surface *surface); // Vykresli pixel void DrawPixel(SDL_Surface *surface, int x, int y, Uint8 r, Uint8 g, Uint8 b); // Vykresli obdelnik void DrawRect(SDL_Surface *surface, SDL_Rect *rect, Uint8 r, Uint8 g, Uint8 b); /* * Zamyka/odemyka surface */ bool Lock(SDL_Surface *surface) { if(SDL_MUSTLOCK(surface)) { if(SDL_LockSurface(surface) < 0) { return false; } } return true; } void Unlock(SDL_Surface *surface) { if(SDL_MUSTLOCK(surface)) { SDL_UnlockSurface(surface); } } /* * Vykresli pixel do surface (z vetsi casti prevzato ze SDL intro) * Funkce predpoklada, ze je uz surface zamknuty */ void DrawPixel(SDL_Surface *surface, int x, int y, Uint8 r, Uint8 g, Uint8 b) { // Presahuje rozmery surface, zapis do neplatne pameti if(x >= surface->w || y >= surface->h) return; Uint32 color = SDL_MapRGB(surface->format, r, g, b); switch(surface->format->BytesPerPixel) { case 1:/* Assuming 8-bpp */ { Uint8 *bufp; bufp = (Uint8 *)surface->pixels + y*surface->pitch + x; *bufp = color; } break; case 2:/* Probably 15-bpp or 16-bpp */ { Uint16 *bufp; bufp = (Uint16 *)surface->pixels + y*surface->pitch/2 + x; *bufp = color; } break; case 3:/* Slow 24-bpp mode, usually not used */ { Uint8 *bufp; bufp = (Uint8 *)surface->pixels + y*surface->pitch + x*surface->format->BytesPerPixel; *(bufp+surface->format->Rshift/8) = r; *(bufp+surface->format->Gshift/8) = g; *(bufp+surface->format->Bshift/8) = b; } break; case 4:/* Probably 32-bpp */ { Uint32 *bufp; bufp = (Uint32 *)surface->pixels + y*surface->pitch/4 + x; *bufp = color; } break; } // Lepsi aktualizovat celou scenu najednou // SDL_UpdateRect(surface, x, y, 1, 1); } void DrawRect(SDL_Surface *surface, SDL_Rect *rect, Uint8 r, Uint8 g, Uint8 b) { if(!Lock(surface)) return; int i; for(i = rect->x; i < rect->x+rect->w+1; i++)// Horizontalni linky { DrawPixel(surface, i, rect->y, r, g, b); DrawPixel(surface, i, rect->y + rect->h, r, g, b); } for(i = rect->y+1; i < rect->y+rect->h; i++)// Vertikalni linky { DrawPixel(surface, rect->x, i, r, g, b); DrawPixel(surface, rect->x + rect->w, i, r, g, b); } Unlock(surface); } /* * Inicializacni funkce */ bool Init() { // Inicializace SDL if(SDL_Init(SDL_SUBSYSTEMS) == -1) { fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); return false; } // Vytvori okno s definovanymi vlastnostmi g_screen = SDL_SetVideoMode(WIN_WIDTH, WIN_HEIGHT, WIN_BPP, WIN_FLAGS); if(g_screen == NULL) { fprintf(stderr, "Unable to set %dx%d video: %s\n", WIN_WIDTH, WIN_HEIGHT, SDL_GetError()); return false; } SDL_WM_SetCaption(WIN_TITLE, NULL); return true; } /* * Deinicializacni funkce */ void Destroy() { SDL_Quit(); } /* * Vykresleni sceny */ void Draw() { if(!Lock(g_screen)) return; for(int i = 0; i < 255; i++) { DrawPixel(g_screen, i, 215, i, i, i);// Paleta sedi } Unlock(g_screen); SDL_Rect rect; rect.x = 40; rect.y = 40; rect.w = 40; rect.h = 40; DrawRect(g_screen, &rect, 255, 0, 0); rect.x = 60; rect.y = 60; rect.w = 60; rect.h = 60; DrawRect(g_screen, &rect, 0, 255, 0); rect.x = 90; rect.y = 90; rect.w = 90; rect.h = 90; DrawRect(g_screen, &rect, 0, 0, 255); SDL_Flip(g_screen); } /* * Osetreni udalosti * V tomto pripade ceka se na klavesu ESC, ktera ukonci program a reaguje * na zmenu velikosti okna */ bool ProcessEvent() { SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { // Klavesnice case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_ESCAPE: return false; break; default: break; } break; // Zmena velikosti okna case SDL_VIDEORESIZE: g_screen = SDL_SetVideoMode(event.resize.w, event.resize.h, WIN_BPP, WIN_FLAGS); if(g_screen == NULL) { fprintf(stderr, "Unable to resize window: %s\n", SDL_GetError()); return false; } break; // Pozadavek na ukonceni case SDL_QUIT: return false; break; default: break; } } return true; } /* * Vstup do programu */ int main(int argc, char *argv[]) { printf(WIN_TITLE); printf("\nPress ESC key to quit.\n"); // Inicializace if(!Init()) { Destroy(); return 1; } // Hlavni smycka programu bool done = false; while(!done) { done = !ProcessEvent(); Draw(); } // Deinicializace a konec Destroy(); return 0; }