I'm making my first thing with libgdx. That's a tiled 2D game. Say I have two types of tiles: blue and green. Those are 32x32 pixel images that cover one cell on the game field. I want to be able to create a transition between tiles such as the one on the right of the image attached. Blue and green doesn't mean all pixels in a tile are the same color, that just defines what texture a pixel is from.
I'm not asking about an algorithm — I've already done it via canvas in JavaScript. I just need some directions on what classes/techniques/solutions to use specifically in libgdx.
So I need to take pixels from the blue texture and draw them above the green one. Is there a way to do this with a shader or maybe by directly taking pixel values from blue tile's texture?
Say I already have all my textures (with no transition sprites yet calculated) loaded in a TextureAtlas. What classes should go next to get the desired effect?
Update: Here is a rough example of what my code currently is. My gameScreen.render() method looks simply like this:
batch.begin();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
Sprite sprite = getFloorSpriteByCell(cells[x][y]);
batch.draw(sprite, x * 32, y * 32);
}
}
batch.end();
and in getFloorSpriteByCell() I choose between some of preloaded sprites, that's all, no fancy level editing in a fancy gui-thing.
I don't use tilemaps, I just need to draw some part of a texture above another texture during rendering.
Welp, I finished it, and here is how it looks:
Without diffusion:
With diffusion:
The code itself, I guess, is too large and project-specific to post it here. Here are the steps (actual classes from LibGDX are in bold starting with a capital letter):
Pick individual pixels of an image you are diffusing into and put
them into a Pixmap (if you have your textures in a
TextureAtlas as I have had them, use a PixmapTextureAtlas class from this question on GoogleCode to get Pixmaps).
Draw these Pixmaps to Textures
Then, as usual, draw all Textures to a SpriteBatch.
Hope this will be useful for someone. Contact me if you need the actual code.
Related
So, I am trying to create a Warcraft II RTS clone with SFML. I finished my menu now, a menu which should support 12 different player thus 12 different colors, however I have problems with colorizing the different sprites i downloaded from the internet, and probably making 12 different png files to load for each unit/building would be a huge waste of time and memory.
I saw many different suggestions on this topic but they seemed either unpractical or just really really hard to do.
These are some examples of the sprites I got
Also here is the link for the full project (this however doesn't include helpful information about these sprites, because only the menu is done):
https://github.com/lori2001/Warcraft-II---clone/tree/master
Any suggestions are welcome ! :)
The second picture you posted indicates the key: the characters are identical except for the four color shades indicated at the bottom.
Thus, you could preprocess your sprite sheets and separate them into the paletted bits and non-paletted bits.
What you do afterwards is up to you; the simplest is probably to generate one new sprite sheet per color and use the correct sprite sheet when rendering a unit for a given color. In OpenGL terms, I would think of a 3D texture where the first dimension is the color.
Alternatively, you could use an RGBA texture and mark the paletted bits using the alpha channel; rendering would then be something along the lines of
if (pixel.a == 1.0) {
outputColor = vec4(pixel.rgb, 1.0);
} else {
int idx = pixel.r / 0.25;
outputColor = vec4(palette[idx].rgb, 1.0);
}
where pixel is the pixel in your sprite sheet, and palette is a shader uniform containing four RGB values. An alpha value of 1 would keep the input pixel, while any of [0, 0.25, 0.50, 0.75] would use the corresponding palette index.
Im programming a Prototyp of an Tilebased Game to learn SDL.My map is just a 257x257 array of Tiles, each Tile is 1x1 to 60x60 pixels (different zoomings).The SDL Window has a resolution of 1024x768. So i can display 18x13 to 1024*768 Tiles.
Till now i tried 2 approches.
1st: Render from Tiles
//for (at worst) 1024*768 Tiles
SDL_Rect Tile;
SDL_SetRenderDrawColor(gRenderer, /*some color*/ , 255);
Tile = { Tile_size * x, Tile_size * y, Tile_size, Tile_size };
SDL_RenderFillRect(gRenderer, &(Tile));
con: it is way to time consuming and the game starts lagging if i try to move the map.
2nd create an texture before the Game starts
with: SDL_CreateRGBSurface, SDL_FillRect, SDL_CreateTextureFromSurface
con: the Texture would be (257x257)(Tiles)x(60x60)(pixel/Tile)x(32)(bit/pixel) ~ 951 MB. and with multiple Textures for different Zoom steps its way to huge to handle.
I'd appreciate any tips to improve the performance.
The first example just draws a single filled rectangle... That can't be slow, I'd have to see more to give a better answer.
In general you'll want to render only the tiles which are visible on the screen not the tiles on the map itself. With 60x60 tiles you can get away with just using SDL 2d drawing functions then. When you add different zoom levels I'm afraid you won't be able to just use 1x1 pixel tiles and use the same approach - you would try to call every pixel via a function call!
So once you add different zoom levels you'll have to figure out how to get that on screen - and what that's supposed to mean to the player anyway :)
I'm currently writing a simple program using SDL2 where you can drag some shapes (square, circle, triangle, etc) into a canvas and rotate them and move them around. Each shape is represented visually by a SDL texture that is created from a PNG file (using the IMG_LoadTexture function from the SDL_image library).
The thing is that I would like to know whether a certain pixel from the texture is transparent, so that when someone clicks on the image I could determine if I have to do some action (because the click is on the non transparent area) or not.
Because this is some school assignment I'm facing some restrictions, that is, only use SDL2 libraries and I can't have some map where I can look up if the pixel in question is transparent because the images are dinamically selected. Furthermore I thought about using a SDL surface for this task creating them from the original images but due to the fact that the shapes are being rotated through the texture that wouldn't work.
You can accomplish this by using Render Targets.
SDL_SetRenderTarget(renderer, target);
... render your textures rotated, flipped, translated using SDL_RenderCopyEx
SDL_RenderReadPixels(renderer, rect, format, pixels, pitch);
With the last step you read the pixels from the render target using SDL_RenderReadPixels and then you have to figure out if the alpha channel of the desired pixel is zero (transparent) or not. You can read just the one pixel you want from the render target, or the whole texture, which option you take depends on the number of hit tests you have to perform, how often the texture is rotated/moved around, etc.
You need to create your texture using the SDL_TEXTUREACCESS_STREAMING flag and lock your texture before being able to manipulate pixel data. To tell if a certain pixel is transparent in a texture make sure that you call
SDL_SetTextureBlendMode(t, SDL_BLENDMODE_BLEND);
this allows the texture to recognize an alpha channel.
Try something like this:
SDL_Texture *t;
int main()
{
// initialize SDL, window, renderer, texture
int pitch, w, h;
void *pixels;
SDL_SetTextureBlendMode(t, SDL_BLENDMODE_BLEND);
SDL_QueryTexture(t, NULL, &aw, &h);
SDL_LockTexture(t, NULL, &pixels, &pitch);
Uint32 *upixels = (Uint32*) pixels;
// you will need to know the color of the pixel even if it's transparent
Uint32 transparent = SDL_MapRGBA(SDL_GetWindowSurface(window)->format, r, g, b, 0x00);
// manipulate pixels
for (int i = 0; i < w * h; i++)
{
if (upixels[i] == transparent)
// do stuff
}
// replace the old pixels with the new ones
memcpy(pixels, upixels, (pitch / 4) * h);
SDL_UnlockTexture(t);
return 0;
}
If you have any questions please feel free to ask. Although I am no expert on this topic.
For further reading and tutorials, check out http://lazyfoo.net/tutorials/SDL/index.php. Tutorial 40 deals with pixel manipulation specifically.
I apologize if there are any errors in method names (I wrote this off the top of my head).
Hope this helped.
I am working on a 3D renderer, and as I was loading various test models, I noticed that everything looked OK, except for the fact the the textures were all flipped on the x-axis.
This is actually previewed as I'm blitting my GBuffer to the screen, so it can't be a FBO-rendering problem.
After I load each .obj file, I prepare its VBOs. Here's the snippet setting up the texture coordinates:
for(Face f : master.faces) {
for(int i = pointsPerFace - 1; i >= 0; i--) {
uv[0] = f.texCoords[i].x;
uv[1] = f.texCoords[i].y;
texcoords.append(uv);
}
}
Things like replacing a coordinate with 1 - coordinate don't really work, since that would flip the whole bitmap, not just the current triangle.
What could cause everything to be rendering x-flipped?
except for the fact the the textures were all flipped on the x-axis.
I think what's actually happening is, that the model's geometry is flipped on the Z axis. The usual transformation setup used with OpenGL uses a right handed coordinate system. If the object has been designed saved for left handed, one axis is swapped and this also affects the texture application of course.
Things like replacing a coordinate with 1 - coordinate don't really work
Yes it would, because…
since that would flip the whole bitmap, not just the current triangle.
… that's exactly what you'd require, if doing it this way. But first I'd check if the model geometry is loaded correctly, i.e. with the right handedness. If not, I'd simply flip the Z axis of the geometry.
I am pretty new to OpenGL and just want some quick advice. I want to draw a tiled background for a game. I guess this means drawing a whole bunch of sprite like objects to the screen. I have about 48 columns to 30 rows, therefore 1440 tiles (tiles change depending on the game, so I can't pre-render the entire grid).
Currently on start up I create 6 different FBO (using the ofFbo class from OpenFrameworks) that act as 6 different tiles. I then draw these buffers, up to a maximum of 1400 times, selecting one for each tile. So there are only ever 6 fbos, just being draw a lot of times. (The buffers are drawn to on start up, and are never changed once created).
for (int x=0; x<columns; x++) {
for (int y=0; y<rows; y++) {
// Get tile type and rotation from tile struct.
tileNum = tile.form
rotNum = tile.rot
// Draw image/texture/fbo that's stored in a std vector.
tileSet->draw(x*TILESIZE, y*TILESIZE, TILESIZE, TILESIZE);
}
}
I think I am going about this the wrong way, and was wondering if anyone new the best / optimal way to do this. Think something like an old school 8 bit video game background. Here is an image of my work in progress.
The structures in the background are the sprites i'm talking about, the different pieces are the inny corner, outty (concave) corner, square fill, and straight edge. Sorry for messing around with question.
I don't really understand your question. A texture is a (usually 2-dimensinal) image that can be applied to polygons, whereas an FBO (framebuffer object) is a kind of offscreen buffer that can be rendered into instead of the screen, usually used to render directly into textures. So I don't see where your question could be "textures vs FBOs" in any way, as they're quite orthogonal concepts and using FBOs doesn't make any sense in your example. Maybe you're messing up FBOs with VBOs (vertex buffer objects) or PBOs (pixel buffer objects)? But then your question is still quite ill-posed.
EDIT: If you're really using FBOs, and that only because you think they magically make the texture they reference to be stored in video memory, then rest assured that textures are always stored in video memory and using an FBO in your case is completely useless.
for what your doing I would recommend you just use a standard OpenGL texture.
I think I understand what your trying to do, but FBO's retain far more information than you need and will thus take much longer to render onto your destination (which is an FBO).