SFML community forums

Help => Graphics => Topic started by: antares on April 04, 2018, 09:00:29 am

Title: Is it possible to manipulate each pixel of a texture?
Post by: antares on April 04, 2018, 09:00:29 am
I am trying to create a texture pixel by pixel, which I later on will be passing to a fragment shader. Is there any way to achieve this?
Title: Re: Is it possible to manipulate each pixel of a texture?
Post by: eXpl0it3r on April 04, 2018, 09:07:26 am
Why not use the fragment shader from the start?

You can update a texture from a pixel array or an sf::Image, you can't manipulate a texture directly, except by using a shader.
Title: Re: Is it possible to manipulate each pixel of a texture?
Post by: Martin Sand on April 05, 2018, 10:20:22 pm
I agree with eXpl0it3r. If you want to understand the technique to manipulate pixels in an image, here is a code example.
Please note that you need a background.png image

#include <iostream>
#include <SFML/Graphics.hpp>

sf::Color setPixelColor(sf::Texture& texture, int x, int y, sf::Color color){
  // Get texture image
  sf::Image image = texture.copyToImage();

  // Optional show case: read size of image (not used in this function)
  int width = image.getSize().x;
  int height = image.getSize().y;

  // Get color of specific position
  sf::Color imagecolor = image.getPixel(x, y);

  // Just an example: if alpha is above 128, make it green
  if (imagecolor.a > 128){
    imagecolor.g = 255;
  }

  // Set pixel to color
  image.setPixel(x, y, color);

  // Update texture
  texture.loadFromImage(image);
}

int main(){
  sf::RenderWindow screen(sf::VideoMode(900, 600), "window");

  sf::Sprite background;
  sf::Texture texture;

  if (!texture.loadFromFile("background.png")){
     std::cout << "Error loading texture" << std::endl;
  }
  background.setTexture(texture);

  while (screen.isOpen()){
    sf::Event event;
    while (screen.pollEvent(event)){
      if (sf::Event::Closed == event.type){
        screen.close();
        break;
      }
    }

    setPixelColor(texture, 10, 10, sf::Color::Green);

    screen.clear();
    screen.draw(background);
    screen.display();
  }
}