PDA

View Full Version : ClanLib 2.3.6 - How to set the color of a pixel?



somescripter
07-28-2013, 08:12 PM
I've noticed that CL_PixelBuffer contains get_pixel but no set_pixel.

I'd like to convert the following shader to my game (from the awesome indie game Atomic Creep Spawner):



package com.sparkedstudios.beyondthelight.graphics;

public class Shader
{
public int w, h;
public int scale;
public Sprite sb;
public double FACTOR = 0.7;

public Sprite addAlpha(Sprite s) {
Sprite result = new Sprite(s.width, s.height);

for (int i = 0; i < result.pixels.length; i++) {
result.pixels[i] = ((255 >> 24) & 0xff) | s.pixels[i];
}

return result;
}
public Sprite scale(Sprite s, int scale) {
Sprite result = new Sprite(s.width * scale, s.height * scale);

for (int x = 0; x < result.width; x++)
{
for (int y = 0; y < result.height; y++)
{
int col = s.pixels[(x / scale) + (y / scale) * s.width];
result.setPixel(x, y, col);
}
}

return result;
}

public Sprite mosaic(Sprite s, int scale) {
Sprite result = s;

for (int x = 0; x < s.width / scale; x++)
{
for (int y = 0; y < s.height / scale; y++)
{
int col = s.getPixel(x * scale, y * scale);
if (col > 0) continue;

int brighter = brighter(col);
int darker = darker(col);

for (int i = 0; i < scale - 1; i++)
{
result.setPixel((x * scale) + i, y * scale, brighter);
result.setPixel((x * scale), (y * scale) + i, brighter);
result.setPixel((x * scale) + scale - 1, (y * scale) + i, darker);
result.setPixel((x * scale) + i, (y * scale) + scale - 1, darker);
}
}
}
return result;
}

public int brighter(int col)
{
int r = getRed(col);
int g = getGreen(col);
int b = getBlue(col);
int alpha = getAlpha(col);
int i = (int) (1.0 / (1.0 - FACTOR));

if (r == 0 && g == 0 && b == 0)
{
return toInt(i, i, i, alpha);
}

if (r > 0 && r < i) r = i;
if (g > 0 && g < i) g = i;
if (b > 0 && b < i) b = i;

return toInt(Math.min((int) (r / FACTOR), 255), Math.min((int) (g / FACTOR), 255), Math.min((int) (b / FACTOR), 255), alpha);
}

public int darker(int col) {
return toInt(Math.max((int) (getRed(col) * FACTOR), 0), Math.max((int) (getGreen(col) * FACTOR), 0), Math.max((int) (getBlue(col) * FACTOR), 0), getAlpha(col));
}

public int toInt(int r, int g, int b, int a) {
return ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) << 0);
}

public int getRed(int col) {
return (col >> 16) & 0xFF;
}

public int getGreen(int col) {
return (col >> 8) & 0xFF;
}

public int getBlue(int col) {
return (col >> 0) & 0xFF;
}

public int getAlpha(int col) {
return (col >> 24) & 0xff;
}
}


The problem is I can't use GLSL because I need to be able to set neighbouring pixel colors. For this reason I'd like to be able to iterate through each pixel myself like in this code and set the colours.

Thank you!

rombust
07-28-2013, 09:00 PM
We do not have set_pixel because it would be too slow to do anything useful with it.

Instead, you use get_data() to retrieve the base pointer to the image.

In psuedo code:
pixel = get_data() + xpos + ypos * pitch

The datatype of get_data() depends on the datatype of the image (usually cl_rgb8 or cl_rgba8)

However, I would try to port the shader to GLSL, looking at it, it should be possible.

somescripter
07-28-2013, 10:19 PM
I've really tried to port the shader to GLSL but I'm really struggling. I can't seem to figure out how to set neighboring pixel colors/fragment colors. Oh well, thanks for your help :(