Java-Gaming.org
 Featured games (81) games approved by the League of Dukes Games in Showcase (497) Games in Android Showcase (114) games submitted by our members Games in WIP (563) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1] 2
 ignore  |  Print
 Dynamic tile map lighting.  (Read 12436 times) 0 Members and 1 Guest are viewing this topic.
SkyAphid
 « Posted 2012-04-24 03:34:50 »

So, I've been toying around with dynamic tilemap lighting, and it's going okay-ish, but I can't wrap my head around combining lights. As of now, each tilemap holds values of the lighting of each individual tile, from 0 - 255. 255 being completely black. So anyway, here's a screenshot of the problem:

Essentially the bottom-right image shows when a light below it collides with a light above it...the bottoms lights fade overrides the above lights brightness.

Here's the code, it's simple so I'll put it all up:

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20 `public void checkLighting(int x, int y){      if (mapTiles[3][x][y] < 255){ //Checks if the tile is lit up.            for (int c = 1; c < 10; c++){ //Diagnally ascending variable, breaking it into levels.                  for (int a = 0; a < (c*2)+1; a++){ // Takes each "level" and goes right and down                     try{//Sets lighting that of the original tile and makes it darker by 20*c. Same with the rest.                          mapTiles[3][x-c+a][y-c] = (mapTiles[3][x][y] + (20*c));                            mapTiles[3][x+c-a][y+c] = (mapTiles[3][x][y] + (20*c));                     }catch(Exception e){} //To prevent error from leaving bounds of tilemap.                  }                                    for (int b = 0; b < (c*2)+1; b++){ //Takes each "level" and goes left and up                     try{                        mapTiles[3][x-c][y-c+b] = (mapTiles[3][x][y] + (20*c));                                 mapTiles[3][x+c][y+c-b] = (mapTiles[3][x][y] + (20*c));                     }catch(Exception e){}                  }            }         }      }`

Any tips on fusing the lights? Help is greatly appreciated

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
UprightPath
 « Reply #1 - Posted 2012-04-24 04:37:37 »

When you add a new light source, you do something like: Math.max(oldValue, newValue) for each tile affected. Or if you want over laps to be a little brighter, do something like add them some how?

theagentd
 « Reply #2 - Posted 2012-04-24 10:45:31 »

When you add a new light source, you do something like: Math.max(oldValue, newValue) for each tile affected. Or if you want over laps to be a little brighter, do something like add them some how?
Light "stacks" additively. Put two lights on the same spot and it will be twice as bright (though that does not mean that the human eye sees it as twice as bright, but to handle that you need tone mapping and preferable HDR rendering).

It makes a lot more sense to set 100% darkness to 0 and 100% brightness to 255. That way, each tile contains how bright it is, instead of how dark it is which makes a lot of things easier. For exampe, you can just add together the light contribution from each light to determine the brightness of each tile. I don´t know how you render the tiles in the end, but if you use OpenGL you can just call glColor3f(brightness, brightness, brightness); (need to cast brightness to byte though) and the tile texture color will be multiplied by the brightness. If you use Java2D, I don´t know exactly how to do it, but to multiply a color by the intensity you convert the 0-255 brightness value to a 0.0-1.0 float value and multiply it with the color of each pixel.

Myomyomyo.
SkyAphid
 « Reply #3 - Posted 2012-04-24 12:16:15 »

When you add a new light source, you do something like: Math.max(oldValue, newValue) for each tile affected. Or if you want over laps to be a little brighter, do something like add them some how?
Light "stacks" additively. Put two lights on the same spot and it will be twice as bright (though that does not mean that the human eye sees it as twice as bright, but to handle that you need tone mapping and preferable HDR rendering).

It makes a lot more sense to set 100% darkness to 0 and 100% brightness to 255. That way, each tile contains how bright it is, instead of how dark it is which makes a lot of things easier. For exampe, you can just add together the light contribution from each light to determine the brightness of each tile. I don´t know how you render the tiles in the end, but if you use OpenGL you can just call glColor3f(brightness, brightness, brightness); (need to cast brightness to byte though) and the tile texture color will be multiplied by the brightness. If you use Java2D, I don´t know exactly how to do it, but to multiply a color by the intensity you convert the 0-255 brightness value to a 0.0-1.0 float value and multiply it with the color of each pixel.
I'm doing in this in the simplest way possible, seeing as it's not a major feature of the game. So, essentially, it's just aesthetic; the 0-255 thing is the transparency of the black blocks that overlap the tiles ;p lol.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
theagentd
 « Reply #4 - Posted 2012-04-24 16:36:12 »

Again, everything becomes simpler if you store the brightness instead of the transparency.

With brightness:
intensity = sum(light_contribution);
pixel color = color X (intensity / 255.0f);

With transparency:
transparency = 255 - sum(255 - light_contribution);
pixel color = color X ((255 - transparency) / 255.0f);

Which one makes more sense?

I did the exact same thing when I did 2D lighting. I imagined a "shroud" that had a transparency value that worked as an overlay over the game world, and I bumped into the same problem when lights started overlapping.

Myomyomyo.
SkyAphid
 « Reply #5 - Posted 2012-04-25 02:13:26 »

Again, everything becomes simpler if you store the brightness instead of the transparency.

With brightness:
intensity = sum(light_contribution);
pixel color = color X (intensity / 255.0f);

With transparency:
transparency = 255 - sum(255 - light_contribution);
pixel color = color X ((255 - transparency) / 255.0f);

Which one makes more sense?

I did the exact same thing when I did 2D lighting. I imagined a "shroud" that had a transparency value that worked as an overlay over the game world, and I bumped into the same problem when lights started overlapping.

So if I use the brightness thing, I could just change the color and leave the transparency alone, right?

I really want to make this as simple as possible, if possible.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
theagentd
 « Reply #6 - Posted 2012-04-25 03:31:30 »

The calculations just get simpler. What graphics library are you using?

Myomyomyo.
SkyAphid
 « Reply #7 - Posted 2012-04-26 12:17:01 »

The calculations just get simpler. What graphics library are you using?
Slick2d, sorry it took so long to get back to you..been a bit busy.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
theagentd
 « Reply #8 - Posted 2012-04-26 13:26:30 »

http://www.java-gaming.org/topics/rendering-tiles-fast-isometric-too/25292/view.html
That article changed my life. xD

Myomyomyo.
SkyAphid
 « Reply #9 - Posted 2012-04-27 14:56:49 »

It's helpful for isometrics, but I'm not sure on how I'm going to use this for what I need to do here lol

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
theagentd
 « Reply #10 - Posted 2012-04-27 17:44:19 »

Argh!!! Copy paste on an iPhone is going to kill me...

This is the article I meant... >_>

Myomyomyo.
SkyAphid
 « Reply #11 - Posted 2012-04-27 21:03:38 »

That article changed my life! lol

Can you fill me on how you achieved that isometric effect in the other article though? I originally planned to make my game's dungeons isometric, but couldn't draw the tiles, seeing as the whole game is essentially hand-drawn. Converting orthogonal tile-sets to look isometric would make my life awesome. lol

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
theagentd
 « Reply #12 - Posted 2012-04-28 04:00:08 »

That article changed my life! lol

Can you fill me on how you achieved that isometric effect in the other article though? I originally planned to make my game's dungeons isometric, but couldn't draw the tiles, seeing as the whole game is essentially hand-drawn. Converting orthogonal tile-sets to look isometric would make my life awesome. lol

Heh, that was a copy paste fail, but anyway...

Drawing isometric tiles is no different from drawing normal tiles. The best looking way is to have an isometric tileset since it produces the sharpest textures. Using a normal tileset makes the tiles look blurry, which you can see in the screenshot in that thread. The only thing I did was rotate the whole screen by 45 degrees and then flatten it a bit by scaling. It´s all there in the source code, so take a look there.

That one was meant for drawing extremely large maps. The map there was 2048x2048 tiles = 4 million quads = 16 million vertices, which to be fair can actually be handled by a decent GPU at over 60 FPS. If you have that large maps you obviously needs some form of culling to get rid of the tiles that are outside the screen, as simply drawing all those quads is going to eat more vertex power. It´s inefficient for both the CPU and the GPU. Instead my program just draws a single 2048x2048 sized quad and then a shader figures out which tile to read for each pixel on the screen. Since parts that are outside of the screen is automatically clipped by OpenGL, no culling is needed, an the only limiting factor is the texture size the GPU can handle, but simply streaming parts of the texture to the GPU as the player moves across the world allows you to have maps of any size. Again, the source is there, so take a look if you want to.

This is obviously overkill for most games and has pretty much no connection to isometric tiles. I just put that there since everyone was talking about isometric tiles when I created that thread. xD The rotate and scale trick works for drawing tiles in any way, so you can just "convert" normal tilesets to isometric that way even if you just use normal quads.

Ooooh, new idea: combine this with tesselation and I have a brand new 3D tile terrain renderer! =D

Myomyomyo.
SkyAphid
 « Reply #13 - Posted 2012-04-28 04:27:24 »

By the way, I kinda can't get soft shading to work in my engine lol. Problem is, being the noob I am, I don't really know where to start.

I was going to use OpenGL, but the thing is my engine wasn't built to use it, so I don't have access to an OpenGL drawable canvas, I'd imagine.

I'm using Slick2d, and using a GameContainer and the Graphics object to draw things, not sure if there's some magical connection I could use for access to OpenGL. Slick tends to have magical connections like these that I don't know about until I make an idiot of myself on here asking about them, because they generally aren't in plain sight on the tutorial pages ;p

Would you know? Assuming I can't use OpenGL, how should I approach simplistic lighting?

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
theagentd
 « Reply #14 - Posted 2012-04-28 04:31:09 »

The OpenGL classes are static. GL11. GL12, GL20, e.t.c.

Myomyomyo.
SkyAphid
 « Reply #15 - Posted 2012-04-28 05:32:09 »

The OpenGL classes are static. GL11. GL12, GL20, e.t.c.
So, in that case, I should be able to pull all the functions I need from where? I'm sorry if these are real obvious, but I haven't used OpenGL directly at all...ever. lol

EDIT:
I'm also a bit of a visual learner, so you know, keep that in mind Haha

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
sproingie

JGO Kernel

Medals: 202

 « Reply #16 - Posted 2012-04-28 16:11:04 »

theagentd is referring to LWJGL, implements the OpenGL API as static methods.  JOGL uses a GL graphics context object that gets passed in, similar to awt/swing, while GDX uses a global object.  Since Slick2D uses LWJGL under the covers, that's what you'd be using.  Anyway, the LWJGL wiki will get you started on that static method API.
theagentd
 « Reply #17 - Posted 2012-04-28 16:57:29 »

I'm sorry if these are real obvious, but I haven't used OpenGL directly at all...ever. lol
o_O Then this is a great opportunity to start! That article is what got me going with OpenGL. If you have no experience at all you should start out with doing some basic stuff; glBegin-glEnd, colors, texturing, e.t.c. The thing is that the lighting in that article is very easy to implement (at least only with hard shadows). The only things you need are FBOs, textures, very basic glBegin/glEnd geometry and blending pretty much. Even better, you´ll gain most of the basic knowledge needed to make games from just this.

Myomyomyo.
Orangy Tang

JGO Kernel

Medals: 56
Projects: 11

 « Reply #18 - Posted 2012-04-28 17:10:17 »

Argh!!! Copy paste on an iPhone is going to kill me...

This is the article I meant... >_>

Always nice seeing that reposted.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
deathpat
 « Reply #19 - Posted 2012-04-28 17:28:02 »

Always nice seeing that reposted.

I based my lighting system on this article as well for Daedalus ... in fact it is this article that motivated me to start to program my own game, and I saw a lot of other articles based on yours all over the internet ! It seems that you've inspired a lot of people with this ! Thanks !!

work in progress : D A E D A L U S
theagentd
 « Reply #20 - Posted 2012-04-28 17:35:00 »

OMG, was that you?! HAVE MY BABIES

Myomyomyo.
SkyAphid
 « Reply #21 - Posted 2012-04-28 21:09:10 »

I've been messing around, and I already have a few questions. :S

First of all, what's the difference in GL11-GL42?

Second of all, how do I even reference from a method like so:

 1  2  3  4  5  6  7  8 `public void render(GameContainer gc, Graphics g){      Input input = gc.getInput();      manageInput(input);      GL11 gl = ???            drawMap(gc, g);   }`

Thirdly, is there anything else I should know before I dive in?

Thanks for the help guys. I seem dumb when I start this stuff, but once I get the concept I'm pretty decent at programming this stuff.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Orangy Tang

JGO Kernel

Medals: 56
Projects: 11

 « Reply #22 - Posted 2012-04-28 23:03:33 »

First of all, what's the difference in GL11-GL42?

Lwjgl puts opengl functions in a class corresponding to the version (or extension) that the function belongs to. So GL11 contains all the functions defined by OpenGL v1.1 (ie. base opengl). All additional functions introduced in OpenGL v1.2 are in GL12, etc. Similarly any functions defined as an extension go in a class named after the extension (eg. ARBVertexBufferObject).

If a computer supports OpenGL, then it will always support GL11 functions. For anything above that you should check ContextCapabilities.

Often it's useful to choose a suitable base level (eg. GL20), check if that's available on start-up and then use whatever GL20 and lower functions you need afterwards.

Quote
Second of all, how do I even reference from a method like so:

You don't, you just call the functions directly since they're static.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
SkyAphid
 « Reply #23 - Posted 2012-04-29 01:05:19 »

Can someone explain this?

The code looks like this...

 1  2  3  4  5  6  7  8  9  10  11  12  13 `GL11.glViewport(0,0,GAME_WIDTH,GAME_HEIGHT);            GL11.glMatrixMode(GL11.GL_PROJECTION);            GL11.glLoadIdentity();            GLU.gluPerspective(45.0f, ((float)GAME_WIDTH/(float)GAME_HEIGHT),0.1f,100.0f);            GL11.glMatrixMode(GL11.GL_MODELVIEW);            GL11.glLoadIdentity();            GL11.glShadeModel(GL11.GL_SMOOTH);            GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);            GL11.glClearDepth(1.0f);            GL11.glEnable(GL11.GL_DEPTH_TEST);            GL11.glDepthFunc(GL11.GL_LEQUAL);            GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT,            GL11.GL_NICEST);`

Someone needs to find me a literal full explanation of how this thing works, I have no idea what I'm doing. Most of the tutorials I've found assume I know all of the terminology and what-not. It usually involves "conceptual code" as if I know how to convert to actual code. lol.

EDIT: For anyone who may read this, I found this. It's helping me a bit with terminology, but the above problem still persists at the moment :p
Here it is: http://www.arcsynthesis.org/gltut/

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
sproingie

JGO Kernel

Medals: 202

 « Reply #24 - Posted 2012-04-29 02:09:11 »

One thing you can probably get rid of is that last glHint, since it's meaningless in every modern driver I'm aware of.  The rest, you'll need to pick up an OpenGL tutorial to learn what everything does.  It's doing a lot, nothing that can be answered in a few forum posts.

SkyAphid
 « Reply #25 - Posted 2012-04-29 02:27:19 »

One thing you can probably get rid of is that last glHint, since it's meaningless in every modern driver I'm aware of.  The rest, you'll need to pick up an OpenGL tutorial to learn what everything does.  It's doing a lot, nothing that can be answered in a few forum posts.

That's the thing, all of the tutorials explain everything in the most complicated way possible with absolutely nothing visual for me to mentally grasp. Most of the time the shader tutorials don't have screenshots of what you're making either, so you have no idea on whether or not you're wasting your time or not.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
sproingie

JGO Kernel

Medals: 202

 « Reply #26 - Posted 2012-04-29 02:55:15 »

I wish I had comforting words there, but learning OpenGL from online tutorials really is a damned tricky thing, requiring you to go between lots of different ones to pick up basics.  Then there's learning it in Java, which have hardly any tutorials written using it.  While LWJGL clones the OpenGL C API almost perfectly in java, the various books still tend to assume C++, and porting things like matrix classes from them can be very tricky if you don't already have C++ experience.

I found the original Red Book, obsolete as it is, to be an immensely helpful resource, but it's no help for learning the programmable pipeline.  It could be that learning the fixed function pipeline then unlearning it for shaders is still the best way to ease into it.

SkyAphid
 « Reply #27 - Posted 2012-04-29 03:13:32 »

I wish I had comforting words there, but learning OpenGL from online tutorials really is a damned tricky thing, requiring you to go between lots of different ones to pick up basics.  Then there's learning it in Java, which have hardly any tutorials written using it.  While LWJGL clones the OpenGL C API almost perfectly in java, the various books still tend to assume C++, and porting things like matrix classes from them can be very tricky if you don't already have C++ experience.

I found the original Red Book, obsolete as it is, to be an immensely helpful resource, but it's no help for learning the programmable pipeline.  It could be that learning the fixed function pipeline then unlearning it for shaders is still the best way to ease into it.

Well, the lighting I want is really simple. I just want black if there's no light, and circles of light where there is. If you can just point out functions in the direction of doing this, I can just kind of bullcrap my way through.

I could do this the simple way, and make shading voxel style myself, but it'd look bad with the sketched graphics.

“Life is pretty simple: You do some stuff. Most fails. Some works. You do more of what works. If it works big, others quickly copy it. Then you do something else. The trick is the doing something else.” ~Leonardo da Vinci
Orangy Tang

JGO Kernel

Medals: 56
Projects: 11

 « Reply #28 - Posted 2012-04-29 10:20:19 »

Can someone explain this?
Yes, that looks like you have mismatched lwjgl jar + source setup in eclipse. The debug info from the .class file it's running says that the function is at line 2052, but when eclipse tries to find that in the source attachment you've given it it doesn't exist.

I'd suggest upgrading your lwjgl (jars + source + docs) to the latest so you know they're all the exact same version.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Orangy Tang

JGO Kernel

Medals: 56
Projects: 11

 « Reply #29 - Posted 2012-04-29 10:21:22 »

As for the actual null pointer error, I'd guess you're trying to issue GL commands before you've created a display?

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Pages: [1] 2
 ignore  |  Print

You cannot reply to this message, because it is very, very old.

 Add your game by posting it in the WIP section, or publish it in Showcase. The first screenshot will be displayed as a thumbnail.
 BurntPizza (22 views) 2014-09-19 03:14:18 Dwinin (35 views) 2014-09-12 09:08:26 Norakomi (62 views) 2014-09-10 13:57:51 TehJavaDev (90 views) 2014-09-10 06:39:09 Tekkerue (44 views) 2014-09-09 02:24:56 mitcheeb (65 views) 2014-09-08 06:06:29 BurntPizza (48 views) 2014-09-07 01:13:42 Longarmx (35 views) 2014-09-07 01:12:14 Longarmx (40 views) 2014-09-07 01:11:22 Longarmx (37 views) 2014-09-07 01:10:19
 BurntPizza 37x Riven 18x Rayvolution 18x princec 17x ags1 16x basil_ 16x KevinWorkman 15x LiquidNitrogen 12x kevglass 12x theagentd 11x nsigma 11x HeroesGraveDev 9x deathpat 9x The Lion King 7x TehJavaDev 6x Gibbo3771 6x
 List of Learning Resources2014-08-16 10:40:00List of Learning Resources2014-08-05 19:33:27Resources for WIP games2014-08-01 16:20:17Resources for WIP games2014-08-01 16:19:50List of Learning Resources2014-07-31 16:29:50List of Learning Resources2014-07-31 16:26:06List of Learning Resources2014-07-31 11:54:12HotSpot Optionsby dleskov2014-07-08 01:59:08
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org