Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw pixels in SDL 2.0?

Tags:

c++

c

sdl

sdl-2

How does one draw with pixels in SDL2.0?

I'm trying to get familiar with C++, but this is very difficult to do without pretty pictures, so I'm trying to get a very basic graphics display thing running. All I really want it to do is give me a window, let me draw rgbα pixels on it, and access information about those pixels. There may be other things I want that I'm not aware of, but that's all that's on my list right now. My research on this has lead me to try using SDL, the current version being 2.0.

Almost all my graphics experience comes from using JavaScript on a <canvas>. Most of the other bit comes from my calculator, which has this really awesome Pxl-On() command, so easy.

I'm using MinGW for my C++, if it matters. Also, if there's something better** out there than SDL2.0 for what I need, advice welcome.


** "better" means "contains what functionality I need, but less total functionality than SDL2.0, and/or has a more intuitive/less complex*** API than SDL2.0."

*** Less lines of code to accomplish the same task.

like image 295
Jordan Avatar asked Dec 14 '13 04:12

Jordan


People also ask

How do you draw pixels in SDL?

For example: SDL_Window *window; SDL_Renderer *renderer; SDL_CreateWindowAndRenderer(800, 600, 0, &window, &renderer); //Probably on a loop SDL_RenderDrawPoint(renderer, 400, 300); //Renders on middle of screen. SDL_RenderPresent(renderer); This should draw a pixel on the middle of screen.

How do you draw a line in SDL?

SDL_RenderDrawLine() draws the line to include both end points. If you want to draw multiple, connecting lines use SDL_RenderDrawLines() instead.

What is an SDL surface?

An SDL surface is just an image data type that contains the pixels of an image along with all data needed to render it. SDL surfaces use software rendering which means it uses the CPU to render. It is possible to render hardware images but it's a bit more difficult so we're going to learn it the easy way first.


3 Answers

Runnable example

Draws a diagonal red line pixel by pixel on the screen using SDL_RenderDrawPoint.

enter image description here

main.c

#include <stdlib.h>

#include <SDL2/SDL.h>

#define WINDOW_WIDTH 600

int main(void) {
    SDL_Event event;
    SDL_Renderer *renderer;
    SDL_Window *window;
    int i;

    SDL_Init(SDL_INIT_VIDEO);
    SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_WIDTH, 0, &window, &renderer);
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
    SDL_RenderClear(renderer);
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
    for (i = 0; i < WINDOW_WIDTH; ++i)
        SDL_RenderDrawPoint(renderer, i, i);
    SDL_RenderPresent(renderer);
    while (1) {
        if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
            break;
    }
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return EXIT_SUCCESS;
}

GitHub upstream.

Compile and run:

gcc -std=c89 -Wextra -pedantic-errors -o main.out main.c -lSDL2
./main.out

If you want to set a large rectangle of pixels at once, e.g. the entire screen or a sprite, use SDL_Texture + SDL_RenderCopy and possibly SDL_TEXTUREACCESS_STREAMING, as that will be much faster. Examples at:

  • What is a Blit in SDL?
  • Rendering pixels from array of RGB values in SDL 1.2?

Tested on libsdl 2.0.2, Ubuntu 15.10.


I don't know how your code is structured. Assuming you have a SDL_Window and a SDL_Renderer, you just have to call SDL_RenderDrawPoint(renderer, x, y).

If you don't have a renderer nor window, you can create both with SDL_CreateWindowAndRenderer(). For example:

SDL_Window *window;
SDL_Renderer *renderer;
SDL_CreateWindowAndRenderer(800, 600, 0, &window, &renderer);

//Probably on a loop
  SDL_RenderDrawPoint(renderer, 400, 300); //Renders on middle of screen.
  SDL_RenderPresent(renderer);

This should draw a pixel on the middle of screen. To read a pixel is a little more complicated. You can use SDL_RenderReadPixels(), it is made for read an area, but you can always specify an area of 1x1. Read the wiki page if you really need it.

If you are having much trouble with SDL2 a recommend you to read the Lazy Foo tutorials. The SDL2 section still a work in progress, but there is enough material to begin learning.

like image 33
TalesM Avatar answered Oct 17 '22 12:10

TalesM


I find Python + PySDL2 more easy to prototype with. Debug is also funny, because it is veeeery slooow for pixel graphics. =) Here is the complete code:

"""
The code is placed into public domain
by anatoly techtonik <[email protected]>
"""

import sdl2
import sdl2.ext

sdl2.ext.init()

window = sdl2.ext.Window('', size=(300, 100))
window.show()

renderer = sdl2.ext.Renderer(window)
renderer.draw_point([10,10], sdl2.ext.Color(255,255,255))
renderer.present()

running = True
while running:
  for e in sdl2.ext.get_events():
    if e.type == sdl2.SDL_QUIT:
      running = False
      break
    if e.type == sdl2.SDL_KEYDOWN:
      if e.key.keysym.sym == sdl2.SDLK_ESCAPE:
        running = False
        break
like image 3
anatoly techtonik Avatar answered Oct 17 '22 11:10

anatoly techtonik