Help with gid and to figure out how to render from .tmx file

61 views
Skip to first unread message

SyntheticPrime GOW

unread,
Jun 11, 2014, 1:36:47 PM6/11/14
to mape...@googlegroups.com
Hello,

I have parsed the .tmx file, and now trying to render my map. I have the gid but not sure how to take that and convert it to texture coordinates that are usable from my tileset .png file.

I have a tileset image with 64x64 tiles thats 10x10 so 640x640 in size.

e.g. 
say I have gid = 3, how do I grab texcoords in the range of 0-1 so I can tell OpenGL how to render that part of the texture map?

glTexCoord2d(); needs the values somehow from and id of 3...

thanks!
Dave

Petr Viktorin

unread,
Jun 11, 2014, 2:39:09 PM6/11/14
to mape...@googlegroups.com
I put together a quick picture to explain:
https://dl.dropboxusercontent.com/u/47397632/tiled-texture-mapping.png
Hope it helps, I didn't test the code so there's probably a mistake
but the general idea is there.


Source SVG: https://dl.dropboxusercontent.com/u/47397632/tiled-texture-mapping.svg
> --
> --
> Tiled Map Editor mailing list
> mape...@googlegroups.com
> http://groups.google.com/group/mapeditor
>
> ---
> You received this message because you are subscribed to the Google Groups
> "Tiled Map Editor" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mapeditor+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

SyntheticPrime GOW

unread,
Jun 11, 2014, 7:34:21 PM6/11/14
to mape...@googlegroups.com
Oh wow thanks for the .png. I will look at it later tonight!!! Thanks!


You received this message because you are subscribed to a topic in the Google Groups "Tiled Map Editor" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mapeditor/y5LKCUS76Z0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mapeditor+...@googlegroups.com.

SyntheticPrime GOW

unread,
Jun 12, 2014, 3:56:12 AM6/12/14
to mape...@googlegroups.com
I got it working but I have an issue with the textures not matching the layout from the .tmx file? Basically the image looks flipped on Y axis? Say a brick should be at the top row 3 col over, its being rendered bottom row 3 col over?


On Wed, Jun 11, 2014 at 1:38 PM, Petr Viktorin <enc...@gmail.com> wrote:
You received this message because you are subscribed to a topic in the Google Groups "Tiled Map Editor" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mapeditor/y5LKCUS76Z0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mapeditor+...@googlegroups.com.

SyntheticPrime GOW

unread,
Jun 12, 2014, 3:58:31 AM6/12/14
to mape...@googlegroups.com
Here is my code I am using...

for(int y = 0; y < HEIGHT; ++y)
{
for(int x = 0; x < WIDTH; ++x)
{
//assuming firstgid = 1
//10 = map width assuming 10 here for now

float tile = static_cast<NX::ResourceTMX*>(NX::ResourceManager::GetResourceManager()->findResourcebyID(6))->getMap()->getGridData(x, y)->getGridId();
tile = tile - 1.0f;
float row = std::floor(tile/10.0f);
float col = std::fmodf(tile, 10.0f);
float y2 = 1 - (row/10.0f);
float y1 = y2 - (1/10.0f);
float x1 = col / 10.0f;
float x2 = x1 + (1/10.0f);

glBegin(GL_QUADS);
glTexCoord2f(x1, y1); glVertex3f(float(x*OFFSETWIDTH), float(y*OFFSETHEIGHT), 0.0f);
glTexCoord2f(x2, y1); glVertex3f(float(x*OFFSETWIDTH + OFFSETWIDTH), float(y*OFFSETHEIGHT), 0.0f);
glTexCoord2f(x2, y2); glVertex3f(float(x*OFFSETWIDTH + OFFSETWIDTH), float(y*OFFSETHEIGHT + OFFSETHEIGHT), 0.0f);
glTexCoord2f(x1, y2); glVertex3f(float(x*OFFSETWIDTH), float(y*OFFSETHEIGHT + OFFSETHEIGHT), 0.0f);
glEnd();
}
}

Thorbjørn Lindeijer

unread,
Jun 12, 2014, 5:17:52 AM6/12/14
to mape...@googlegroups.com
On Thu, Jun 12, 2014, at 12:56 AM, SyntheticPrime GOW wrote:
> I got it working but I have an issue with the textures not matching the
> layout from the .tmx file? Basically the image looks flipped on Y axis?
> Say a brick should be at the top row 3 col over, its being rendered bottom
> row 3 col over?

That is because in Tiled, the origin of the map is in the top-left. So
if you're drawing the first row (0), you should make sure it shows up at
the top of your map. In your case it seems that you got your origin at
the bottom-left, which is somewhat common when using OpenGL. Either you
would change your coordinate system to have the origin in the top-left
as well, or you need to subtract the vertex y coordinates from the total
map height, which flips the map to adjust for the change of origin.

Regards,
Bjørn

SyntheticPrime GOW

unread,
Jun 12, 2014, 6:06:18 AM6/12/14
to mape...@googlegroups.com
That didn't work... You are correct I am using OpenGL.

glBegin(GL_QUADS);
glTexCoord2f(x1, y1); glVertex3f(float(x*OFFSETWIDTH),               float(640 - (y*OFFSETHEIGHT)), 0.0f);
glTexCoord2f(x2, y1); glVertex3f(float(x*OFFSETWIDTH + OFFSETWIDTH), float(640 - (y*OFFSETHEIGHT)), 0.0f);
glTexCoord2f(x2, y2); glVertex3f(float(x*OFFSETWIDTH + OFFSETWIDTH), float(640 - (y*OFFSETHEIGHT + OFFSETHEIGHT)), 0.0f);
glTexCoord2f(x1, y2); glVertex3f(float(x*OFFSETWIDTH),               float(640 - (y*OFFSETHEIGHT + OFFSETHEIGHT)), 0.0f);
glEnd();

the size is 10x10 with 64 width and height grids.




Thorbjørn Lindeijer

unread,
Jun 12, 2014, 8:47:17 AM6/12/14
to mape...@googlegroups.com
On Thu, Jun 12, 2014, at 03:06 AM, SyntheticPrime GOW wrote:
> That didn't work... You are correct I am using OpenGL.
>
> glBegin(GL_QUADS);
> glTexCoord2f(x1, y1); glVertex3f(float(x*OFFSETWIDTH),
> float(640 - (y*OFFSETHEIGHT)), 0.0f);
> glTexCoord2f(x2, y1); glVertex3f(float(x*OFFSETWIDTH + OFFSETWIDTH),
> float(640 - (y*OFFSETHEIGHT)), 0.0f);
> glTexCoord2f(x2, y2); glVertex3f(float(x*OFFSETWIDTH + OFFSETWIDTH),
> float(640 - (y*OFFSETHEIGHT + OFFSETHEIGHT)), 0.0f);
> glTexCoord2f(x1, y2); glVertex3f(float(x*OFFSETWIDTH),
> float(640 - (y*OFFSETHEIGHT + OFFSETHEIGHT)), 0.0f);
> glEnd();
>
> the size is 10x10 with 64 width and height grids.

What do you mean with "That didn't work"? You seem to have changed your
y vertex values so that they should flip around, but are you saying this
had no effect at all? Or did it change the rendered map in some
undesired way? Can you provide before/after screenshots that may be able
to give a clue about what is going wrong?

Regards,
Bjørn

SyntheticPrime GOW

unread,
Jun 12, 2014, 12:19:55 PM6/12/14
to mape...@googlegroups.com
changind the vertex Y  is what you wanted from a previous post? So I tried that no it didn't work. What works better is changing the texture coordinates but I need to get them working or is there some way to change OpenGL's texture coordinates to match DX then with a simple parameter call? I am rusty in all my coding been years and I am getting back into it so sorry. :( Please advise.



Regards,
Bjørn

Petr Viktorin

unread,
Jun 12, 2014, 12:23:53 PM6/12/14
to mape...@googlegroups.com
If your texture's Y coordinate is flipped, just flip it back -
calculate y1 & y2 the same way as x1 & x2.
> You received this message because you are subscribed to the Google Groups
> "Tiled Map Editor" group.
> To unsubscribe from this group and stop receiving emails from it, send an

Thorbjørn Lindeijer

unread,
Jun 12, 2014, 12:31:36 PM6/12/14
to mape...@googlegroups.com
On Thu, Jun 12, 2014, at 09:19 AM, SyntheticPrime GOW wrote:
> changind the vertex Y is what you wanted from a previous post? So I
> tried that no it didn't work. What works better is changing the texture
> coordinates but I need to get them working or is there some way to change
> OpenGL's texture coordinates to match DX then with a simple parameter
> call?

I don't really know the difference between OpenGL and DX, but it sounds
like you want to pass pixel coordinates instead of a value from 0-1 as
texture coordinate. In OpenGL, you can do that when using
GL_TEXTURE_RECTANGLE_ARB instead of GL_TEXTURE_2D as texture type, and
then you can use glVertex2i to pass pixel coordinates as integers. This
is an OpenGL extension though, so you may want to verify that it is
available on your target hardware / platform.

> I am rusty in all my coding been years and I am getting back into it so
> sorry. :( Please advise.

Well, I originally thought you had your map flipped. I now see that you
meant that just the texture graphic was flipped internally, so then you
should just exchange the y values of your texture coordinates
vertically.

Regards,
Bjørn

SyntheticPrime GOW

unread,
Jun 12, 2014, 12:47:46 PM6/12/14
to mape...@googlegroups.com
I got it!! thanks for all the help guys!!! Love Tiled keep up the great work!

I used this code for anyone else to use!!!

inline std::pair<float, float> dxTOglTexcoord(float u, float v)
{
return std::make_pair(u, 1.0f - v);
}

for(int y = 0; y < HEIGHT; ++y)
{
for(int x = 0; x < WIDTH; ++x)
{
//assuming firstgid = 1
//10 = map width assuming 10 here for now

float tile = static_cast<NX::ResourceTMX*>(NX::ResourceManager::GetResourceManager()->findResourcebyID(6))->getMap()->getGridData(x, y)->getGridId();
tile = tile - 1.0f;
float row = std::floorf(tile/10.0f);
float col = std::fmodf(tile, 10.0f);
float y2 = 1 - (row/10.0f);
float y1 = y2 - (1 / 10.0f);
float x1 = col / 10.0f;
float x2 = x1 + (1/10.0f);

std::pair<float, float> uv = NX::dxTOglTexcoord(x2, y2);
y2 = uv.second;
uv = NX::dxTOglTexcoord(x1, y1);
y1 = uv.second;

glBegin(GL_QUADS);
glTexCoord2f(x1, y1); glVertex3f(float(x*OFFSETWIDTH),               float(y*OFFSETHEIGHT), 0.0f);
glTexCoord2f(x2, y1); glVertex3f(float(x*OFFSETWIDTH + OFFSETWIDTH), float(y*OFFSETHEIGHT), 0.0f);
glTexCoord2f(x2, y2); glVertex3f(float(x*OFFSETWIDTH + OFFSETWIDTH), float(y*OFFSETHEIGHT + OFFSETHEIGHT), 0.0f);
glTexCoord2f(x1, y2); glVertex3f(float(x*OFFSETWIDTH),               float(y*OFFSETHEIGHT + OFFSETHEIGHT), 0.0f);
glEnd();
}
}

Regards,
Bjørn

Thorbjørn Lindeijer

unread,
Jun 12, 2014, 4:10:15 PM6/12/14
to mape...@googlegroups.com
On Thu, Jun 12, 2014, at 09:47 AM, SyntheticPrime GOW wrote:
> I got it!! thanks for all the help guys!!! Love Tiled keep up the great
> work!

That's great!

> I used this code for anyone else to use!!!

I've tried to improve the code a little:

const unsigned TILES_PER_ROW = 10;
const float TILES_PER_ROW_F = static_cast<float>(TILES_PER_ROW);
const float TILES_PER_COLUMN_F = TILES_PER_ROW_F;

auto *map =
static_cast<NX::ResourceTMX*>(NX::ResourceManager::GetResourceManager()->findResourcebyID(6))->getMap();

glBegin(GL_QUADS);
for (int y = 0; y < HEIGHT; ++y) {
for (int x = 0; x < WIDTH; ++x) {
//assuming firstgid = 1

unsigned tile = map->getGridData(x, y)->getGridId() - 1;
unsigned row = tile / TILES_PER_ROW;
unsigned col = tile % TILES_PER_ROW;

float x1 = col / TILES_PER_ROW_F;
float x2 = x1 + 1 / TILES_PER_ROW_F;
float y2 = row / TILES_PER_COLUMN_F;
float y1 = y2 + 1 / TILES_PER_COLUMN_F;

glTexCoord2f(x1, y1); glVertex3f(float(x*OFFSETWIDTH),
float(y*OFFSETHEIGHT), 0.0f);
glTexCoord2f(x2, y1); glVertex3f(float(x*OFFSETWIDTH +
OFFSETWIDTH), float(y*OFFSETHEIGHT), 0.0f);
glTexCoord2f(x2, y2); glVertex3f(float(x*OFFSETWIDTH +
OFFSETWIDTH), float(y*OFFSETHEIGHT + OFFSETHEIGHT), 0.0f);
glTexCoord2f(x1, y2); glVertex3f(float(x*OFFSETWIDTH),
float(y*OFFSETHEIGHT + OFFSETHEIGHT), 0.0f);
}
}
glEnd();

Changes I made:

* Retrieve the pointer to the map once and not for each tile.
* Calculate in integer the part that can be done with integers.
* Avoid the need for dxTOglTexcoord by calculating the right values
directly.
* Moved glBegin/glEnd out of the loop for performance reasons (though
for real performance gains one should not use this immediate rendering
mode but rather vertex arrays or FBOs).

Hopefully it still works because I haven't tested it!

For a more generic bit of code there's still quite a bit to improve of
course.

Regards,
Bjørn
Reply all
Reply to author
Forward
0 new messages