I'm using a shader to draw my tilemap onto a texure with the size of the camera (window) and im using a texure with the size of the tilemap (in tiles) to let the shader know what tile to draw.
Each pixel in the tilemap data texure represents 1 tile and im using the rgba channels as layers (r = floor, g = walls) to save the TileID.
But somehow it does not draw the correct tiles can you please take a look at my shader, because I'm trying to fix this for days but nothing works.
I am storing the TileIDs of the diffrent tile Types inside the color. for example: r = 0, g = 1. This corresponds to the 0th tile of my spritesheet as the ground layer, and 1th tile of my spritesheet is ontop of it. My Spritesheet starts with index 0.
Layer Info:
3: -> Top most Layer -> A
2: -> B
1: -> G
0: Bottom most Layer -> R
I only use R and G at the moment, my drawOrder is from 0 to 3 where 0 is the bottom most layer.
The TileMapData in the position of the tilemap (ONLY R & G is used, the rest is ignored), color values 0-255 represent the TileTypeID:
RGBA(0,1,0,255);RGBA(2,3,0,255);RGBA(1,2,0,255)
RGBA(0,1,0,255);RGBA(2,3,0,255);RGBA(1,2,0,255)
When I give the Shaderfunction "vec4 GetDrawColorFromSpritesheet(int tileType)" a TileTypeID manually it grabs the correct Tile from the tilesheet.
The error must be inside the Shaderfunction "int GetTileTypeFromMapData(int layerID)" or one of the helper functions getting the coordinates but I cannot figure out where it is.
I provide Images and Code to help you visualize it. I'm very sorry for the wall of code
.
Thank you for taking a look, it drives me mad.
My SpritesheetAir = 0
Wall = 1
StoneFloor = 2
Water = 3
How it Looks when executed and all the tileIDs in Console:It should look like this:My Shader:uniform vec2 cameraPos;
uniform sampler2D tileSheet;
uniform sampler2D tileMap;
uniform vec2 tileMapDimensions;
uniform vec2 renderSurfaceDimensions;
uniform vec2 tileSheetDimensions;
vec2 GetTileMapPixelCoord()
{
vec2 tileMapPixelCoord = vec2(cameraPos.x + gl_TexCoord[0].x * renderSurfaceDimensions.x, cameraPos.y + gl_TexCoord[0].y * renderSurfaceDimensions.y);
return tileMapPixelCoord;
}
vec2 GetTileMapTileCoord()
{
vec2 tileMapPixelCoord = GetTileMapPixelCoord();
vec2 tileMapTileCoord = vec2(floor(tileMapPixelCoord.x / 32.0), floor(tileMapPixelCoord.y / 32.0));
return tileMapTileCoord;
}
// 0 = floor, 1 = wall, 2 = ?, 3 = ?
int[4] GetTileTypeFromMapData()
{
vec2 tileMapTileCoord = GetTileMapTileCoord();
vec2 textureCoords = vec2(tileMapTileCoord.x - 1 / tileMapDimensions.x, tileMapTileCoord.y - 1 / tileMapDimensions.y);
vec4 tileMapTileIDColor = texture2D(tileMap, textureCoords);
int[4] retArray = {0, 0, 0, 0};
// L3
// L2
// L1 - wall
// L0 - floor
// Floor tile Type - layer 0
if (tileMapTileIDColor.r > 0.0)
{
float floorID = ceil(tileMapTileIDColor.r * 255.0);
retArray[0] = int(floorID);
}
// Wall tile Type - layer 1
if (tileMapTileIDColor.g > 0.0)
{
float wallID = ceil(tileMapTileIDColor.g * 255.0);
retArray[1] = int(wallID);
}
// layer 2
if (tileMapTileIDColor.b > 0.0)
{
float layer2 = ceil(tileMapTileIDColor.b * 255.0);
retArray[2] = int(layer2);
}
// layer 3
if (tileMapTileIDColor.a > 0.0)
{
float layer3 = ceil(tileMapTileIDColor.a * 255.0);
retArray[3] = int(layer3);
}
return retArray;
}
vec4 GetDrawColorFromSpritesheet(int tileType)
{
vec2 tileSheetDimensionsInTiles = vec2(tileSheetDimensions.x / 32, tileSheetDimensions.y / 32);
vec2 tileToGet = vec2(mod(tileType, tileSheetDimensionsInTiles.x), floor(tileType / tileSheetDimensionsInTiles.x));
vec2 tileMapPixelCoord = GetTileMapPixelCoord();
vec2 tileSheetPixelCoord = vec2(tileToGet.x * 32 + mod(tileMapPixelCoord.x, 32), tileToGet.y * 32 + mod(tileMapPixelCoord.y, 32));
vec2 tileSheetTextureCoord = vec2(tileSheetPixelCoord.x / tileSheetDimensions.x, tileSheetPixelCoord.y / tileSheetDimensions.y);
return texture2D(tileSheet, tileSheetTextureCoord);
}
vec4 AlphaBlend(vec4 source, vec4 dest)
{
vec4 outPx = vec4(1.0, 1.0, 1.0, 1.0);
outPx.a = source.a + dest.a*(1.0 - source.a);
outPx.r = (source.r*source.a + dest.r*dest.a*(1.0-source.a)) / outPx.a;
outPx.g = (source.g*source.a + dest.g*dest.a*(1.0-source.a)) / outPx.a;
outPx.b = (source.b*source.a + dest.b*dest.a*(1.0-source.a)) / outPx.a;
return outPx;
}
vec4 GetFinalPixelColor()
{
vec2 tileMapPixelCoord = GetTileMapPixelCoord();
if (tileMapPixelCoord.x < 0 || tileMapPixelCoord.y < 0 || tileMapPixelCoord.x > tileMapDimensions.x * 32 || tileMapPixelCoord.y > tileMapDimensions.y * 32)
{
return vec4(0.0, 0.0, 0.0, 1.0);
}
int[4] tileTypes = GetTileTypeFromMapData();
vec4 floorColor = GetDrawColorFromSpritesheet(tileTypes[0]);
vec4 wallColor = GetDrawColorFromSpritesheet(tileTypes[1]);
vec4 layer2Color = GetDrawColorFromSpritesheet(tileTypes[2]);
vec4 layer3Color = GetDrawColorFromSpritesheet(tileTypes[3]);
// Alphablending
vec4 finalColor = AlphaBlend(wallColor, floorColor);
finalColor = AlphaBlend(layer2Color, finalColor);
finalColor = AlphaBlend(layer3Color, finalColor);
return finalColor;
}
void main()
{
gl_FragColor = GetFinalPixelColor();
}
My Main.cpp as reference:#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <sstream>
#include <cuda_runtime.h>
#include <array>
#include "Debugging\guicon.h"
#include <SFML\Graphics.hpp>
#include "ResourceManagement\TexturePool.h"
#include "TileMap\TileType.h"
#include "ResourceManagement\ShaderPool.h"
#include "resource.h"
#include "Rendering\Quad.h"
extern void execHelloWorldKernel(int blocks, int threads, int start, int* outVal);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
#ifdef _DEBUG
RedirectIOToConsole();
#endif
sf::RenderWindow window(sf::VideoMode(800, 600), "Space Exodus");
//sf::View view(sf::Vector2f(window.getSize().x / 2.0f, window.getSize().y / 2.0f), (sf::Vector2f)window.getSize());
//view.zoom(2.0f);
//window.setView(view);
const int mapSizeX = 3;
const int mapSizeY = 2;
TileTypes.LoadTileTypes("");
sf::Uint8 testMap[mapSizeX * mapSizeY * 4];
testMap[0] = 0;
testMap[1] = 1;
testMap[2] = 0;
testMap[3] = 0;
testMap[4] = 2;
testMap[5] = 3;
testMap[6] = 0;
testMap[7] = 0;
testMap[8] = 1;
testMap[9] = 2;
testMap[10] = 0;
testMap[11] = 0;
testMap[12] = 3;
testMap[13] = 1;
testMap[14] = 0;
testMap[15] = 0;
testMap[16] = 3;
testMap[17] = 2;
testMap[18] = 0;
testMap[19] = 0;
testMap[20] = 2;
testMap[21] = 0;
testMap[22] = 0;
testMap[23] = 0;
for (int idx = 0; idx < mapSizeX * mapSizeY * 4; idx++)
{
sf::Uint8 floorTileID = rand() % 4;
sf::Uint8 wallTileID = rand() % 4;
int idxMod = idx % 4;
if (idxMod == 0)
{
//testMap[idx] = floorTileID;
printf("RGBA(%d,", testMap[idx]);
}
else if (idxMod == 1)
{
//testMap[idx] = wallTileID;
printf("%d,", testMap[idx]);
}
else if (idxMod == 2)
{
//testMap[idx] = 0;
printf("%d,", testMap[idx]);
}
else
{
//testMap[idx] = 255;
printf("%d) (x=%d, y=%d)\n", testMap[idx], idx % mapSizeX, (int)floor(idx / 4 / mapSizeX));
}
}
sf::Texture renderMapSliceTexture;
sf::Image renderMapSliceImage;
renderMapSliceImage.create(mapSizeX, mapSizeY, testMap);
renderMapSliceTexture.loadFromImage(renderMapSliceImage);
RmTexturePool.LoadAndAddTextureFromFile("SpriteSheet", "SpriteSheet.png");
sf::Font font;
font.loadFromFile("arial.ttf");
int bla = 5;
//RmShaderPool.AddAndCreateShaderFromResource(IDR_OGS_TEST_FRAG, OPENGLSHADER, "testFrag", sf::Shader::Type::Fragment);
RmShaderPool.AddAndCreateShaderFromResource(IDR_OGS_TILEMAP_FRAG, OPENGLSHADER, "LayeredTileShader", sf::Shader::Type::Fragment, true);
execHelloWorldKernel(1, 1, bla, &bla);
printf("adsasd %d\n", bla);
//sf::Sprite spr(*RmTexturePool.GetTexture("TileAir"));
RmShaderPool.GetShader("LayeredTileShader")->setParameter("cameraPos", sf::Vector2f(0.0f, 0.0f));
RmShaderPool.GetShader("LayeredTileShader")->setParameter("tileSheet", *RmTexturePool.GetTexture("SpriteSheet"));
RmShaderPool.GetShader("LayeredTileShader")->setParameter("tileMap", renderMapSliceTexture);
RmShaderPool.GetShader("LayeredTileShader")->setParameter("tileMapDimensions", sf::Vector2f((float)mapSizeX, (float)mapSizeY));
RmShaderPool.GetShader("LayeredTileShader")->setParameter("renderSurfaceDimensions", sf::Vector2f((float)window.getSize().x, (float)window.getSize().y));
RmShaderPool.GetShader("LayeredTileShader")->setParameter("tileSheetDimensions", sf::Vector2f((float)RmTexturePool.GetTexture("SpriteSheet")->getSize().x, (float)RmTexturePool.GetTexture("SpriteSheet")->getSize().y));
Rendering::Quad merp(sf::Vector2f(0, 0), (sf::Vector2f)window.getSize());
sf::Texture renderViewTex;
renderViewTex.create(window.getSize().x, window.getSize().y);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
sf::RenderStates rs;
rs.shader = RmShaderPool.GetShader("LayeredTileShader");
rs.texture = &renderViewTex;
window.draw(merp, rs);
window.display();
}
return 0;
}
Its Still broken I just draw the tiles seperatly. Thanks anyway