Skip to content

Instantly share code, notes, and snippets.

@jaburns
Last active August 29, 2015 14:16
Show Gist options
  • Save jaburns/fd786f2a6c13e3f9dd53 to your computer and use it in GitHub Desktop.
Save jaburns/fd786f2a6c13e3f9dd53 to your computer and use it in GitHub Desktop.
SDL Pixel Pushing comparison
#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct Color {
Uint8 r, g, b;
};
struct Color getColor(Uint8 x, Uint8 y, Uint8 t) {
double fx = x, fy = y;
Uint8 dist = (Uint8)sqrt((double)(fx*fx + fy*fy));
return (struct Color){ dist, 3*y-0xFF-10*t, 7*t };
}
int main()
{
SDL_Surface *screen;
Uint32 *raw_pixels;
int x, y;
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
}
screen = SDL_SetVideoMode(320, 240, 32, SDL_DOUBLEBUF);
if (screen == NULL) {
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
SDL_WM_SetCaption("C","C");
int t = 0;
while (1) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) return 0;
}
t++;
SDL_LockSurface(screen);
raw_pixels = (Uint32 *) screen->pixels;
for (x = 0; x < 320; x++) {
for (y = 0; y < 240; y++) {
Uint32 pixel_color;
int offset;
struct Color hi = getColor(x, y, t);
pixel_color = SDL_MapRGB(screen->format, hi.r, hi.g, hi.b);
raw_pixels[ ( y * screen->w ) + x ] = pixel_color;
}
}
SDL_UnlockSurface(screen);
SDL_Flip(screen);
}
return 0;
}
module Main (
main
) where
import Control.Monad.State
import Control.Monad.Reader
import Data.Word
import Foreign
import Graphics.UI.SDL
screenWidth = 320
screenHeight = 240
screenBpp = 32
getPixel32 :: Int -> Int -> Surface -> IO Pixel
getPixel32 x y s = do
pixels <- castPtr `liftM` surfaceGetPixels s
Pixel `liftM` peekElemOff pixels ((y * surfaceGetWidth s) + x)
putPixel32 :: Int -> Int -> Pixel -> Surface -> IO ()
putPixel32 x y (Pixel pixel) s = do
pixels <- castPtr `liftM` surfaceGetPixels s
pokeElemOff pixels ((y * surfaceGetWidth s) + x) pixel
getColor :: Int -> Int -> Int -> (Word8,Word8,Word8)
getColor x y t = (dist, 3*wy-0xFF-10*wt, 7*wt)
where
dist = truncate . sqrt . fromIntegral $ x*x + y*y
wx = fromIntegral x
wy = fromIntegral y
wt = fromIntegral t
colorSurface :: Surface -> Int -> IO ()
colorSurface s t = do
let format = surfaceGetPixelFormat s
lockSurface s
forM_ [(x,y) | x <- [0..(screenWidth-1)], y <- [0..(screenHeight-1)]] $ \(x,y) -> do
let (r,g,b) = getColor x y t
pixel <- mapRGB format r g b
putPixel32 x y pixel s
unlockSurface s
main = do
Graphics.UI.SDL.init [InitEverything]
setCaption "Haskell" "Haskell"
surface <- setVideoMode screenWidth screenHeight screenBpp [DoubleBuf]
mainLoop 0 surface
mainLoop :: Int -> Surface -> IO ()
mainLoop count surface = do
quit <- consumeEvents
unless quit $ do
colorSurface surface count
Graphics.UI.SDL.flip surface
mainLoop (count+1) surface
consumeEvents :: IO Bool
consumeEvents = do
event <- liftIO pollEvent
case event of
Quit -> return True
NoEvent -> return False
_ -> consumeEvents
extern crate sdl;
extern crate rand;
use sdl::video::{SurfaceFlag, VideoFlag};
use sdl::event::{Event};
use std::num::Float;
fn main() {
sdl::init(&[sdl::InitFlag::Video]);
sdl::wm::set_caption("Rust", "Rust");
let screen = match sdl::video::set_video_mode(320, 240, 32,
&[SurfaceFlag::HWSurface],
&[VideoFlag::DoubleBuf]) {
Ok(screen) => screen,
Err(err) => panic!("failed to set video mode: {}", err)
};
let mut t = 0;
'main : loop {
'event : loop {
match sdl::event::poll_event() {
Event::Quit => break 'main,
Event::None => break 'event,
_ => {}
}
}
screen.with_lock(|pixels| {
for x in 0..320 {
for y in 0..240 {
let fx = x as f32;
let fy = y as f32;
let dist = Float::sqrt(fx*fx + fy*fy) as u8;
let r = dist;
let g = 3*(y as u8)-0xFF-10*t;
let b = 7*t;
pixels[4*(320*y+x) + 0] = 0xFF;
pixels[4*(320*y+x) + 1] = r;
pixels[4*(320*y+x) + 2] = g;
pixels[4*(320*y+x) + 3] = b;
}
}
true
});
t = t + 1;
screen.flip();
}
sdl::quit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment