Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (808)
Games in Android Showcase (239)
games submitted by our members
Games in WIP (872)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
   Home   Help   Search   Login   Register   
  Show Posts
Pages: [1] 2 3
1  Games Center / WIP games, tools & toy projects / Re: [Now w/Demo] Shard Master - 3D Software Rasterized RPG on: 2015-08-01 02:22:05
I have created a demo for you guys, it isn't much, I just wanted you guys to know what the feel of the game is like and how it works. Feedback is appreciated.

http://www.mediafire.com/download/nleul28qgrjnnnd/ShardMasterDemo.jar.zip

Looking forward to some updates after you collect user feedback Smiley
2  Game Development / Newbie & Debugging Questions / Tile Connections? on: 2015-07-02 23:23:49
I am using lwjgl with no external libraries, so every step in my project is manual and usually a fun challenge. Anyways here is what my terrain looks like when using a tile map + simplex noise to generate a region/chunk.. I need some direction for getting the tiles touch/connect (it's my first time using heights with a tile grid) Thanks

3  Games Center / Cube World Projects / Re: Technetium - A realistic voxel game on: 2015-06-27 02:08:36
I've been looking this over, and your game looks exactly like ThinMatrix's tutorial
https://www.youtube.com/watch?v=yGjMzIePKNQ&list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP&index=20
I was going to say that myself.

@OP: You need to implement distance based rendering for those "floating props" it looks extremely amateur with the current setup. Also, if you're trying to make a voxel game I would suggest at least using a flat terrain (if you're using a heightmap just set it all to the same color value or whatever - if you're using a .obj file then maybe google "Nemesis terrain gen" and simply generate a flat terrain object model)
For a voxel game you need a solid understanding of 3d/vector math... It's mostly just numbers. Anyways not to be rude but it seems that your team is lacking all of the experience required to actually create a 3D game so why not find a more suitable code base and take it from there? Here's an example of a game which is powered almost entirely by vector structures and if you implemented a cube class - then you'd be on the right path. The only downside is that the game uses immediate mode and is only good for playing around with and definitely not a production game - but I would recommend using this just to get the hang of basic 3d mathematics
https://www.youtube.com/watch?v=O0xtgfcxcq0
4  Games Center / WIP games, tools & toy projects / [lwjgl]Powerful 3D Client - Digital World Creation on: 2015-06-26 07:54:05
..
5  Games Center / WIP games, tools & toy projects / Re: DemonQuest - 3D Software Rasterized RPG on: 2015-06-18 11:32:23
I dunno. I've made a 3D client with the same mechanics as RuneScape (hence the name "Magic Terrain" in the photo below); the path finder was pretty simple as I've used it for many projects over the years. If you want help I'd be happy to write some code and send it to you (I don't need the src, and I assume you wouldn't want to share it anyways since it's 100% original)

Not to swagjack your thread so here's a url instead of an image tag: http://puu.sh/i9ir2/07e1a740f1.jpg
6  Games Center / WIP games, tools & toy projects / Re: DemonQuest - 3D Software Rasterized RPG on: 2015-06-17 21:29:02
NEW UPDATE:

Basic gameframe. (Looks awful right now, will fix)

(Image in main post)

Finally decided on name : Demon Quest

First off, if you're using tile based collision why not implement A* path finding and have the player model translate across the map in an automated manner Wink ? As for bridges why not throw in a plane and toggle the tile clipping settings under neath it, instead of scooting across the ground :p

.. and second  Pointing
7  Games Center / WIP games, tools & toy projects / Re: 3D Software Rasterized RPG on: 2015-06-10 01:35:55
I remember your first build (or at least nearly the same project) from you before! Excellent progress. It certainly fits the theme of RuneScape Classic. Perhaps you should do a better region system though - instead of only loading one chunk, load and selectively render/process surrounding regions/mobs. Looking forward to seeing some more progress by the way Wink
8  Game Development / Newbie & Debugging Questions / How To Render A Smoother Tile Based Map? on: 2015-05-16 02:31:32
Ok so this is my tile based game. I am using jPCT and the square tiles are code generated objects with a texture applied. I use A* for all translations and that system is built around a tile based region.



You can see in the image how the tiles are jagged looking. How could I make this better? I've tried using a triangle based tile terrain but it looked even worse lol.

I would like to replace tiles with hexagons, and retain clipping based on tile data. How can I go about this, or just blending the tile textures in the in-between areas using a magical shader or something?!
9  Discussions / Community & Volunteer Projects / Re: Looking for +1 to join LWJGL RPG on: 2015-03-19 17:30:49
Sorry, this thread should be locked. My winter season is over and I'm back to work full time so I barely have time to check my email let alone program Sad
10  Games Center / WIP games, tools & toy projects / Re: Imp City, build an underground empire on: 2015-03-19 17:29:56
This is looking pretty neat. I haven't tried it yet. Will you list some technical specifications?
11  Game Development / Newbie & Debugging Questions / Re: shader not working on my machine on: 2015-02-22 23:32:03
Source of error printing:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
   /**
    * Link the shader program to the GPU , must be done before attaching to a
    * Vbo
    */

   public void link() {
      glLinkProgram(programID);
      if (glGetProgrami(programID, GL_LINK_STATUS) == GL_FALSE) {
         System.err.println("Unable to link shader program:");
         dispose();
      }
   }


That code should've not only checked the link status of the program but also any log messages generated by the driver upon linking the program.
Since compiling the individual shader objects seemed to have succeeded but the linker now complaining about something (maybe some varyings not fitting together), the error messages produced by the linker would now be very useful.
If you can, add (or have it added by the original author) the following right after the invocation of glLinkProgram, and see what gets printed:
1  
2  
String log = glGetProgramInfoLog(programID, 1024);
System.err.println("Linkage log: " + log);

That would give more insight into what goes wrong there.

Thank you! Finally I'm on the right path.. The console error says:
Linkage log: Fragment shader uses varying vecdata but vertex shader does not write to it.
I'm going to toy around with the shaders myself but I'm not sure if I'll be able to solve this.
12  Game Development / Newbie & Debugging Questions / Re: shader not working on my machine on: 2015-02-22 19:47:17
... now that my thread has been saturated with stupid pointless annoying messages. I'm still having the same problem with the shader
13  Game Development / Newbie & Debugging Questions / Re: shader not working on my machine on: 2015-02-21 23:01:07
So... you don't have the time to learn to use OpenGL directly, yet for some reason you don't want to use a library that abstracts that away and would rather waste hours looking for other programmers who can be bothered to do it for you, and then pay them $100s to give you an inferior product to what already exists for free.

It doesn't add up at all.

I've used libraries such as LibGDX, jPCT, other small stuff from the net/githubs, etc.
I want something extremely lightweight, well documented, and written to MY EXACT specifications so that I can read and understand each and every single function at a later date when I have the available free time.
This isn't a spontaneous idea I came up with over night. I have responsibilities in the real world and I'm doing things a certain way for very specific reasons. My personal library will be able to produce the assets I will need for my upcoming game - saving me money in the long run when it comes to needing models and certain textures.
It is what it is and I'm not really sure why anybody would be concerned about how my project is developed or why I'm doing things the way I do them....  Clueless

Also if I wanted top notch quality I would use a game engine and mitigate the manual coding process completely. This is a part of my life that I do for fun. I'm not trying to create a number one MORPG or knock off of some other game. People spend money on stuff like drugs all the time, if I want to spend money on an inferior lwjgl product, so be it. I'm enjoying myself. Smiley
14  Game Development / Newbie & Debugging Questions / Re: shader not working on my machine on: 2015-02-21 22:34:59
If you don't understad the code then you either need to put more time into learning it, or use a library that handles it for you.

I only have free time from my job to study programming during the winter season.. the rest of the year I travel to a lot of different states AND I have a toddler. I'm kind of tired of getting "learn what it does, use libgdx, etc etc"... No offence.
There's a reason I'm paying $100s USD to other developers to create a solid foundation for me.. If I had the time I did when I was a teenager, I'd love to learn the background code. But I simply can't..
There's nothing wrong with paying people to write a library and developer tools to my exact specifications. I'd much rather invest money and enjoy the little free time I have writing game play than spending my 1 or 2 days every other week stressing over background code and making 0 progress.
15  Game Development / Newbie & Debugging Questions / Re: shader not working on my machine on: 2015-02-21 22:08:04
Now your shader compile fine. Rest of bugs are from render monkey.

In my Eclipse project I am still getting one error, but I'm not sure if this is something the general public could help with since lcass is the author of my wrapper.
But this still prints in my console: "Unable to link shader program:"

Source of error printing:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
   /**
    * Link the shader program to the GPU , must be done before attaching to a
    * Vbo
    */

   public void link() {
      glLinkProgram(programID);
      if (glGetProgrami(programID, GL_LINK_STATUS) == GL_FALSE) {
         System.err.println("Unable to link shader program:");
         dispose();
      }
   }


I'm a bit confused as to how to fix this, since I really don't understand the code itself.
16  Game Development / Newbie & Debugging Questions / Re: shader not working on my machine on: 2015-02-21 21:46:28
The most important part of the error message is cut off in your screenshot but you could try replacing the
0
s with
0.0
s.

That actually helped with 1 of 2 Eclipse debug errors. I'll run the code through RenderMonkey and get a full screen shot of the error too for you:

Direct img url: http://i.imgur.com/noXZ3iW.jpg

Sorry if the error is completely amateur I really don't know much about shaders at all. I've always paid people to write them for my programs due to lack of study time...

Updated shader code, all that's different is the 0 are now 0.0
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
attribute vec3 vertex;
attribute vec2 texturecoordinate;
uniform vec3 rotation;
uniform vec3 translation;
uniform vec3 rotation_centre;

void main() {

   vec3 adjusted = vertex + translation;
   
   if (rotation.x != 0.0 || rotation.y != 0.0 || rotation.z != 0.0) {
      adjusted -= rotation_centre;
      float cosx = cos(rotation.x);
      float sinx = sin(rotation.x);
      float cosy = cos(rotation.y);
      float siny = sin(rotation.y);
      float cosz = cos(rotation.z);
      float sinz = sin(rotation.z);
      float nx = adjusted.x;
      float ny = (adjusted.y * cosx) - (adjusted.z * sinx);
      float nz = (adjusted.y * sinx) + (adjusted.z * cosx);
      float cz = (nz * cosy) - (nx * siny);
      float cx = (nz * siny) + (nx * cosy);
      float cy = ny;
      nx = (cx * cosz) - (cy * sinz);
      ny = (cx * sinz) + (cy * cosz);
      nz = cz;
      adjusted = vec3(nx,ny,nz) + rotation_centre;
   }
   
   vec4 mvv = gl_ModelViewMatrix * vec4(adjusted, 1.0);
   gl_Position = gl_ProjectionMatrix *  mvv;
   
}
17  Game Development / Newbie & Debugging Questions / shader not working on my machine on: 2015-02-21 20:43:28
Before you tell me to update my drivers, I have. And the highest my machine will update to is:
OpenGL Version: 2.1.0 - Build 8.15.10.2086

Here's the vertex shader code.. it just wont compile for me
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
attribute vec3 vertex;
attribute vec2 texturecoordinate;
uniform vec3 rotation;
uniform vec3 translation;
uniform vec3 rotation_centre;
void main() {

   vec3 adjusted = vertex + translation;
   
   if (rotation.x != 0 || rotation.y != 0 || rotation.z != 0) {
      adjusted -= rotation_centre;
      float cosx = cos(rotation.x);
      float sinx = sin(rotation.x);
      float cosy = cos(rotation.y);
      float siny = sin(rotation.y);
      float cosz = cos(rotation.z);
      float sinz = sin(rotation.z);
      float nx = adjusted.x;
      float ny = (adjusted.y * cosx) - (adjusted.z * sinx);
      float nz = (adjusted.y * sinx) + (adjusted.z * cosx);
      float cz = (nz * cosy) - (nx * siny);
      float cx = (nz * siny) + (nx * cosy);
      float cy = ny;
      nx = (cx * cosz) - (cy * sinz);
      ny = (cx * sinz) + (cy * cosz);
      nz = cz;
      adjusted = vec3(nx,ny,nz) + rotation_centre;
   }
   
   vec4 mvv = gl_ModelViewMatrix * vec4(adjusted, 1.0);
   gl_Position = gl_ProjectionMatrix *  mvv;
   
}


Here is the error when I try to compile the vertex shader using RenderMonkey

Direct image link: http://i.imgur.com/wZ0vvWk.jpg
18  Discussions / Jobs and Resumes / Re: need senior lwjgl dev to polish up some my project (~5 classes) on: 2015-02-18 04:37:55
At this point I don't care if somebody writes a couple helper classes for me or an entire wrapper. I just want what I want, and time is limited so it's easier to pay.
19  Discussions / Jobs and Resumes / Re: need senior lwjgl dev to polish up some my project (~5 classes) on: 2015-02-17 20:56:21
believe me , its not a few functions , it ends up being a few classes if not more. If you would like some help with this such as wrapper functions that you can then implement I will gladly provide some minor framework but I would move to a PM for info on this if you really would like my services  persecutioncomplex.
Perfect timing for a reply I just got paid last night Wink Would you mind contacting me via Skype for quicker chat? name is sandbox.morpg and the display name is Minigame
20  Java Game APIs & Engines / OpenGL Development / Re: [Solved] Rendering text in lwjgl without slick on: 2015-02-17 20:12:46
Because everyone copied Slick2D Tongue.
Yeah, it's hard for beginners. But there's still a small amount of pride (and learning experience) compiling the snippets together into our own wrappers.

Quote
Because everyone copied Slick2D Tongue.
Well I wish people would realize the optimization to font loading that could be done Tongue
Feel free to explain in depth Wink
21  Discussions / General Discussions / Re: 95 free high resolution tiles for your games on: 2015-02-16 02:25:12
IF ANYBODY KNOWS AN IMG TAG THAT FIXES THE SCROLLING ISSUE PLEASE POST SO I CAN FIX
[img width=880][/img]

Thanks!

Anyways.. I paid for an artist to make these for one of my first 2D games 3, 4, maybe 5 years ago,

I hope you didn't pay much. I mean, they're not terrible. But I wouldn't pay for them.
Eh. It was $5 worth it IMO
22  Discussions / General Discussions / 95 free high resolution tiles for your games on: 2015-02-14 07:31:28
Well, first of all I have absolutely no idea what forum category to post these in.. so moderators please move this thread if I'm doing wrong posting in General Discussion.

Anyways.. I paid for an artist to make these for one of my first 2D games 3, 4, maybe 5 years ago, and I've recycled them countless times in a large array of projects. In fact, I still use these... but soon will be having a new set made and figured it would be nice to hand these out to other indie developers. <3

Preview:


Download here 100% free for personal or commercial use.
23  Game Development / Newbie & Debugging Questions / Re: WorkerThread, how to pass an undefined method to be executed..? on: 2015-02-13 22:07:38
So then use ExecutorService.invokeAll().

So the scheduled executor code you and I have pasted would be the best route? And by abstract, I just meant, instead of passing variables into a secondary class that maybe it would be better to wrap them locally (where they exist) using the worker thread.
Sorry for wording that so weird.
24  Game Development / Newbie & Debugging Questions / Re: WorkerThread, how to pass an undefined method to be executed..? on: 2015-02-13 21:58:15
Would it maybe be better to create something a tad more abstract, instead of passing variables off to a separate executor? Here's an example from a jPCT powered application I wrote a few years ago, using jPCT's worker instance

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
      /**
       * Load prop models and spawns
       */

      Worker worker = new Worker(1);
      worker.add(new WorkLoad() {
         public void doWork() {
            propManager = new PropManager(fileStorage, world, terrain);
         }
         public void done() { }
         public void error(Exception arg0) { }
      });
      worker.waitForAll();
      worker.dispose();
25  Game Development / Newbie & Debugging Questions / Re: WorkerThread, how to pass an undefined method to be executed..? on: 2015-02-13 21:45:53
Seems like with the information you've all provided, I'll have to do a little more research as well. But you've all put me in the right direction so kudos  Smiley
26  Game Development / Newbie & Debugging Questions / Re: WorkerThread, how to pass an undefined method to be executed..? on: 2015-02-13 21:37:54
Like cylab said, I also don't really understand why would you not just use a simple Runnable interface for this purpose and want to hack stuff like that.
I'm reading each and every reply from this thread, and refining my original snippet. Wouldn't have posted for public help and then ignored it Wink
27  Game Development / Newbie & Debugging Questions / Re: WorkerThread, how to pass an undefined method to be executed..? on: 2015-02-13 21:35:20
Alright, well what would be the most efficient way of going about this? A lot of people specifically are having issues loading game regions and constructing their random generated content / loading static map data. I don't want to do anything that would be less than ethical

Just do the normal thing and have a big thread pool somewhere that you hand Runnables/Callables to and get Futures from. Shut down the pool when your app exists or is otherwise appropriate.

Excellent details! Thank you very much. Appreciated Smiley
28  Game Development / Newbie & Debugging Questions / Re: WorkerThread, how to pass an undefined method to be executed..? on: 2015-02-13 21:28:48
1  
2  
3  
4  
5  
public WorkerThread(Runnable r) {
      ExecutorService executorService = Executors.newFixedThreadPool(1);
      executorService.execute(r);
      executorService.shutdown();
}


Creating a new thread pool each time you want to run something is a terrible idea though.

Alright, well what would be the most efficient way of going about this? A lot of people specifically are having issues loading game regions and constructing their random generated content / loading static map data. I don't want to do anything that would be less than ethical
29  Game Development / Newbie & Debugging Questions / WorkerThread, how to pass an undefined method to be executed..? on: 2015-02-13 21:24:24
I'm not even sure if the thread title makes sense. But essentially, I'm trying to use a scheduled executor to execute an undefined method.

This is the pseudo class:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * A simple worker thread. This should be used for things such as loading game assets,
 * or constructing a new region for your game.. without putting the stress on the render Processor,
 * or optional LogicThread.
 */

public class WorkerThread {
   
   public WorkerThread(Method method) { // pseudo
      ExecutorService executorService = Executors.newFixedThreadPool(1);
      executorService.execute(new Runnable() {
          public void run() {
            method(); // pseudo
          }
      });
      executorService.shutdown();
   }

}


It's part of an abstract lwjgl wrapper, which I've been working on for a little over a month now. And have a handful of followers who use it religiously to power their games. But I've never done anything like THIS specifically so I'm lost  Stare
30  Java Game APIs & Engines / OpenGL Development / Re: [Solved] Rendering text in lwjgl without slick on: 2015-02-12 22:33:38
@minigame

You are not supposed to be drawing 50 strings each frame. You are supposed to render text to a texture which you draw every frame and only render text to textures again once the text changes.

Oh, right. Well I implemented a TrueTypeFont class and GLFont for managing custom font instances and drawing them. With a few "logical fonts" integrated into the class.

It's not the best, but it's pretty efficient. Not a single loss of frame count, even when drawing 500+ strings per frame.

Source:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
233  
234  
235  
236  
237  
238  
239  
240  
241  
242  
243  
244  
245  
246  
247  
248  
249  
250  
251  
252  
253  
254  
255  
256  
257  
258  
259  
260  
261  
262  
263  
264  
265  
266  
267  
268  
269  
270  
271  
272  
273  
274  
275  
276  
277  
278  
279  
280  
281  
282  
283  
284  
285  
286  
287  
288  
289  
290  
291  
292  
293  
294  
295  
296  
297  
298  
299  
300  
301  
302  
303  
304  
305  
306  
307  
308  
309  
310  
311  
312  
313  
314  
315  
316  
317  
318  
319  
320  
321  
322  
323  
324  
325  
326  
327  
328  
329  
330  
331  
332  
333  
334  
335  
336  
337  
338  
339  
340  
341  
342  
343  
344  
345  
346  
347  
348  
349  
350  
351  
352  
353  
354  
355  
356  
357  
358  
359  
360  
361  
362  
363  
364  
365  
366  
367  
368  
369  
370  
371  
372  
373  
374  
375  
376  
377  
378  
379  
380  
381  
382  
383  
384  
385  
386  
387  
388  
389  
390  
391  
392  
393  
394  
395  
396  
397  
398  
399  
400  
401  
402  
403  
404  
405  
406  
407  
408  
409  
410  
411  
412  
413  
414  
415  
416  
417  
418  
419  
420  
421  
422  
423  
424  
425  
426  
427  
428  
429  
430  
431  
432  
433  
434  
435  
436  
437  
438  
439  
440  
441  
442  
443  
444  
445  
446  
447  
448  
449  
450  
451  
452  
453  
454  
455  
456  
457  
458  
459  
460  
461  
462  
463  
464  
465  
466  
467  
468  
package com.javarpg.twod.font;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

/**
 * A TrueType font implementation originally for Slick, edited for Bobjob's
 * Engine by David Aaron Muhar (bobjob), then edited by Yousef Amar
 * (Paraknight).
 *
 * Further modified on 2/11/2015 for use with the Two-D lwjgl 2D wrapper, by Minigame.
 *
 * @author James Chambers (Jimmy)
 * @author Jeremy Adams (elias4444)
 * @author Kevin Glass (kevglass)
 * @author Peter Korzuszek (genail)
 * @author David Aaron Muhar (bobjob)
 * @author Yousef Amar (Paraknight)
 * @author Corey K****** (Minigame)
 */

public class TrueTypeFont {
   
   public final static int ALIGN_LEFT = 0, ALIGN_RIGHT = 1, ALIGN_CENTER = 2;
   /** Array that holds necessary information about the font characters */
   private IntObject[] charArray = new IntObject[256];

   /** Map of user defined font characters (Character <-> IntObject) */
   private Map<Character, IntObject> customChars = new HashMap<Character, IntObject>();

   /** Boolean flag on whether AntiAliasing is enabled or not */
   private boolean antiAlias;

   /** Font's size */
   private int fontSize = 0;

   /** Font's height */
   private int fontHeight = 0;

   /** Texture used to cache the font 0-255 characters */
   private int fontTextureID;

   /** Default font texture width */
   private int textureWidth = 512;

   /** Default font texture height */
   private int textureHeight = 512;

   /** A reference to Java's AWT Font that we create our font texture from */
   private Font font;

   /** The font metrics for our Java AWT font */
   private FontMetrics fontMetrics;

   private int correctL = 9, correctR = 8;

   // TODO : create a texture cache in GLFont specifically for font textures!
   // we will need to enable alpha for the texture instance, so that we can draw Strings
   // without having to call gl blend/alpha settings locally in the TTF class.
   // until that is done, there could be compatibility issues with games powered by
   // Two-D, or possible unnecessary overhead due to settings not being disabled
   private static AtomicInteger fontId = new AtomicInteger(0);

   private class IntObject {
      /** Character's width */
      public int width;

      /** Character's height */
      public int height;

      /** Character's stored x position */
      public int storedX;

      /** Character's stored y position */
      public int storedY;
   }

   public TrueTypeFont(Font font, boolean antiAlias, char[] additionalChars) {
      this.font = font;
      this.fontSize = font.getSize() + 3;
      this.antiAlias = antiAlias;

      createSet(additionalChars);

      fontHeight -= 1;
      if (fontHeight <= 0)
         fontHeight = 1;
   }

   public TrueTypeFont(Font font, boolean antiAlias) {
      this(font, antiAlias, null);
   }

   public void setCorrection(boolean on) {
      if (on) {
         correctL = 2;
         correctR = 1;
      } else {
         correctL = 0;
         correctR = 0;
      }
   }

   private BufferedImage getFontImage(char ch) {
      // Create a temporary image to extract the character's size
      BufferedImage tempfontImage = new BufferedImage(1, 1,
            BufferedImage.TYPE_INT_ARGB);
      Graphics2D g = (Graphics2D) tempfontImage.getGraphics();
      if (antiAlias == true) {
         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
      }
      g.setFont(font);
      fontMetrics = g.getFontMetrics();
      int charwidth = fontMetrics.charWidth(ch) + 8;

      if (charwidth <= 0) {
         charwidth = 7;
      }
      int charheight = fontMetrics.getHeight() + 3;
      if (charheight <= 0) {
         charheight = fontSize;
      }

      // Create another image holding the character we are creating
      BufferedImage fontImage;
      fontImage = new BufferedImage(charwidth, charheight,
            BufferedImage.TYPE_INT_ARGB);
      Graphics2D gt = (Graphics2D) fontImage.getGraphics();
      if (antiAlias == true) {
         gt.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      }
      gt.setFont(font);
      gt.setColor(Color.WHITE);
      int charx = 3;
      int chary = 1;
      gt.drawString(String.valueOf(ch), (charx), (chary) + fontMetrics.getAscent());
      return fontImage;

   }

   private void createSet(char[] customCharsArray) {
      // If there are custom chars then I expand the font texture twice
      if (customCharsArray != null && customCharsArray.length > 0) {
         textureWidth *= 2;
      }

      // In any case this should be done in other way. Texture with size
      // 512x512
      // can maintain only 256 characters with resolution of 32x32. The
      // texture
      // size should be calculated dynamicaly by looking at character sizes.

      try {

         BufferedImage imgTemp = new BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB);
         Graphics2D g = (Graphics2D) imgTemp.getGraphics();

         g.setColor(new Color(0, 0, 0, 1));
         g.fillRect(0, 0, textureWidth, textureHeight);

         int rowHeight = 0;
         int positionX = 0;
         int positionY = 0;

         int customCharsLength = (customCharsArray != null) ? customCharsArray.length : 0;

         for (int i = 0; i < 256 + customCharsLength; i++) {

            // get 0-255 characters and then custom characters
            char ch = (i < 256) ? (char) i : customCharsArray[i - 256];

            BufferedImage fontImage = getFontImage(ch);

            IntObject newIntObject = new IntObject();

            newIntObject.width = fontImage.getWidth();
            newIntObject.height = fontImage.getHeight();

            if (positionX + newIntObject.width >= textureWidth) {
               positionX = 0;
               positionY += rowHeight;
               rowHeight = 0;
            }

            newIntObject.storedX = positionX;
            newIntObject.storedY = positionY;

            if (newIntObject.height > fontHeight) {
               fontHeight = newIntObject.height;
            }

            if (newIntObject.height > rowHeight) {
               rowHeight = newIntObject.height;
            }

            // Draw it here
            g.drawImage(fontImage, positionX, positionY, null);

            positionX += newIntObject.width;

            if (i < 256) { // standard characters
               charArray[i] = newIntObject;
            } else { // custom characters
               customChars.put(new Character(ch), newIntObject);
            }

            fontImage = null;
         }

         fontTextureID = loadImage(imgTemp);

         // .getTexture(font.toString(), imgTemp);

      } catch (Exception e) {
         System.err.println("Failed to create font.");
         e.printStackTrace();
      }
   }

   private void drawQuad(float drawX, float drawY, float drawX2, float drawY2, float srcX, float srcY, float srcX2, float srcY2) {
      float DrawWidth = drawX2 - drawX;
      float DrawHeight = drawY2 - drawY;
      float TextureSrcX = srcX / textureWidth;
      float TextureSrcY = srcY / textureHeight;
      float SrcWidth = srcX2 - srcX;
      float SrcHeight = srcY2 - srcY;
      float RenderWidth = (SrcWidth / textureWidth);
      float RenderHeight = (SrcHeight / textureHeight);

      GL11.glTexCoord2f(TextureSrcX, TextureSrcY);
      GL11.glVertex2f(drawX, drawY + DrawHeight);
      GL11.glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY);
      GL11.glVertex2f(drawX + DrawWidth, drawY + DrawHeight);
      GL11.glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY + RenderHeight);
      GL11.glVertex2f(drawX + DrawWidth, drawY);
      GL11.glTexCoord2f(TextureSrcX, TextureSrcY + RenderHeight);
      GL11.glVertex2f(drawX, drawY);
   }

   public int getWidth(String whatchars) {
      int totalwidth = 0;
      IntObject intObject = null;
      int currentChar = 0;
      for (int i = 0; i < whatchars.length(); i++) {
         currentChar = whatchars.charAt(i);
         if (currentChar < 256) {
            intObject = charArray[currentChar];
         } else {
            intObject = (IntObject) customChars.get(new Character((char) currentChar));
         }
         if (intObject != null) {
            totalwidth += intObject.width;
         }
      }
      return totalwidth;
   }

   public int getHeight() {
      return fontHeight;
   }

   public int getHeight(String HeightString) {
      return fontHeight;
   }

   public int getLineHeight() {
      return fontHeight;
   }

   public void drawString(float x, float y, String whatchars, float scaleX, float scaleY) {
      drawString(x, y, whatchars, 0, whatchars.length() - 1, scaleX, scaleY, ALIGN_LEFT);
   }

   public void drawString(float x, float y, String whatchars, float scaleX, float scaleY, int format) {
      drawString(x, y, whatchars, 0, whatchars.length() - 1, scaleX, scaleY, format);
   }

   public void drawString(float x, float y, String whatchars, int startIndex, int endIndex, float scaleX, float scaleY, int format) {
      IntObject intObject = null;
      int charCurrent;
      int totalwidth = 0;
      int i = startIndex, d, c;
      float startY = 0;

      switch (format) {
      case ALIGN_RIGHT: {
         d = -1;
         c = correctR;
         while (i < endIndex) {
            if (whatchars.charAt(i) == '\n') {
               startY -= fontHeight;
            }
            i++;
         }
      }
      case ALIGN_CENTER: {
         for (int l = startIndex; l <= endIndex; l++) {
            charCurrent = whatchars.charAt(l);
            if (charCurrent == '\n') {
               break;
            }
            if (charCurrent < 256) {
               intObject = charArray[charCurrent];
            } else {
               intObject = (IntObject) customChars.get(new Character((char) charCurrent));
            }
            totalwidth += intObject.width - correctL;
         }
         totalwidth /= -2;
      }
      case ALIGN_LEFT:
         default:
            d = 1;
            c = correctL;
            break;
      }

      GL11.glEnable(GL11.GL_TEXTURE_2D);
      GL11.glEnable(GL11.GL_BLEND);
      GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
      GL11.glBindTexture(GL11.GL_TEXTURE_2D, fontTextureID);
      //TextureManager.getInstance().getTextureById(fontTextureID).bind();
      GL11.glBegin(GL11.GL_QUADS);

      while (i >= startIndex && i <= endIndex) {
         charCurrent = whatchars.charAt(i);
         if (charCurrent < 256) {
            intObject = charArray[charCurrent];
         } else {
            intObject = (IntObject) customChars.get(new Character((char) charCurrent));
         }
         if (intObject != null) {
            if (d < 0)
               totalwidth += (intObject.width - c) * d;
            if (charCurrent == '\n') {
               startY -= fontHeight * d;
               totalwidth = 0;
               if (format == ALIGN_CENTER) {
                  for (int l = i + 1; l <= endIndex; l++) {
                     charCurrent = whatchars.charAt(l);
                     if (charCurrent == '\n')
                        break;
                     if (charCurrent < 256) {
                        intObject = charArray[charCurrent];
                     } else {
                        intObject = (IntObject) customChars
                              .get(new Character((char) charCurrent));
                     }
                     totalwidth += intObject.width - correctL;
                  }
                  totalwidth /= -2;
               }
               // if center get next lines total width/2;
            } else {
               drawQuad((totalwidth + intObject.width) * scaleX + x,
                     startY * scaleY + y, totalwidth * scaleX + x,
                     (startY + intObject.height) * scaleY + y,
                     intObject.storedX + intObject.width,
                     intObject.storedY + intObject.height,
                     intObject.storedX, intObject.storedY);
               if (d > 0)
                  totalwidth += (intObject.width - c) * d;
            }
            i += d;

         }
      }
      GL11.glEnd();
      //GL11.glDisable(GL11.GL_BLEND);
      //GL11.glDisable(GL11.GL_TEXTURE_2D);
   }

   public static int loadImage(BufferedImage bufferedImage) {
      // TODO : store the bufferedimage as a com.javarpg.twod.Texture instance
      // in the GLFont class. we need to keep track of font textures,
      // but cannot store them locally in the TTF class..
      try {
         short width = (short) bufferedImage.getWidth();
         short height = (short) bufferedImage.getHeight();
         // textureLoader.bpp = bufferedImage.getColorModel().hasAlpha() ?
         // (byte)32 : (byte)24;
         int bpp = (byte) bufferedImage.getColorModel().getPixelSize();
         ByteBuffer byteBuffer;
         DataBuffer db = bufferedImage.getData().getDataBuffer();
         if (db instanceof DataBufferInt) {
            int intI[] = ((DataBufferInt) (bufferedImage.getData().getDataBuffer())).getData();
            byte newI[] = new byte[intI.length * 4];
            for (int i = 0; i < intI.length; i++) {
               byte b[] = intToByteArray(intI[i]);
               int newIndex = i * 4;
               newI[newIndex] = b[1];
               newI[newIndex + 1] = b[2];
               newI[newIndex + 2] = b[3];
               newI[newIndex + 3] = b[0];
            }
            byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(newI);
         } else {
            byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(((DataBufferByte) (bufferedImage.getData() .getDataBuffer())).getData());
         }
         byteBuffer.flip();

         int internalFormat = GL11.GL_RGBA8, format = GL11.GL_RGBA;
         IntBuffer textureId = BufferUtils.createIntBuffer(1);
         
         GL11.glGenTextures(textureId);
         GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId.get(0));

         GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
         GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);

         GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
         GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);

         GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);

         GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, internalFormat, width, height, format, GL11.GL_UNSIGNED_BYTE, byteBuffer);
         return textureId.get(0);

      } catch (Exception e) {
         e.printStackTrace();
         System.exit(-1);
      }
      return -1;
   }

   public static boolean isSupported(String fontname) {
      Font font[] = getFonts();
      for (int i = font.length - 1; i >= 0; i--) {
         if (font[i].getName().equalsIgnoreCase(fontname)) {
            return true;
         }
      }
      return false;
   }

   public static Font[] getFonts() {
      return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
   }

   public static byte[] intToByteArray(int value) {
      return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value };
   }

   public void destroy() {
      IntBuffer scratch = BufferUtils.createIntBuffer(1);
      scratch.put(0, fontTextureID);
      GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
      GL11.glDeleteTextures(scratch);
   }
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
package com.javarpg.twod.font;

import java.awt.Font;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

import com.javarpg.twod.texture.Texture;

public class GLFont {

   private static final GLFont INSTANCE = new GLFont();

   /*
    * A list of "logical fonts", based on an article from the oracle website.
    */

   private final TrueTypeFont logicalFonts[] = new TrueTypeFont[5];
   private final String fontNames[] = { "Dialog", "DialogInput", "Monospaced", "Serif", "SansSerif" };

   /*
    * A list of custom fonts which the Two-D developer can implement.
    */

   private Map<String, TrueTypeFont> customFonts = new HashMap<String, TrueTypeFont>();

   // TODO store a texture instance of the custom fonts, instead of using a seperate system.
   // If you are using slick2D, just ignore this. I use my own texture/texturemanager classes
   // as part of the learning process for me is to not use slick2d
   private List<Texture> fontTextures = new CopyOnWriteArrayList<Texture>();
   
   public enum FontType {
      Dialog, DialogInput, Monospaced, Serif, SansSerif
   }

   public GLFont() {
      for (int i = 0; i < logicalFonts.length; i++) {
         logicalFonts[i] = new TrueTypeFont(new Font(fontNames[i], Font.PLAIN, 12), true);
      }
     
      // just testing custom fonts
      addCustomFont("Arial", false, 12, true);
      addCustomFont("Helvetica", false, 12, true);
   }

   /**
    * Draws a default logicalFont. The list includes a small array of Two-D integrated fonts, see the {@link #GLFont.FontType} enum
    * to see which fonts are available by default. Note Arail and Helvetica and be drawn using drawCustomString (as they are
    * both integrated custom fonts, but not listed as a logic font or part of the FonType enum)
    *
    * @param string The string to be rendered.
    * @param x The x coordinate in 2D space.
    * @param y The y coordinate in 2D space.
    * @param scaleX The scale (size) you want to use while drawing the string.
    * @param scaleY The scale (size) you want to use while drawing the string.
    * @param format The string format. 0 = align left, 1 = align right, 2 = align center
    * @param customFont The name of the custom font. This would have been set when adding a
    * new font using {@link #addCustomFont(String, boolean, int, boolean)}
    * @param fontType See {@link #GLFont.FontType} enum for a list of default integrated logical fonts.
    */

   public void drawString(String string, int x, int y, int scaleX, int scaleY, int format, FontType fontType) {
      switch (fontType) {
      case Dialog:
         logicalFonts[0].drawString(x, y, string, scaleX, scaleY, format);
         break;
      case DialogInput:
         logicalFonts[1].drawString(x, y, string, scaleX, scaleY, format);
         break;
      case Monospaced:
         logicalFonts[2].drawString(x, y, string, scaleX, scaleY, format);
         break;
      case Serif:
         logicalFonts[3].drawString(x, y, string, scaleX, scaleY, format);
         break;
      case SansSerif:
         logicalFonts[4].drawString(x, y, string, scaleX, scaleY, format);
         break;
      default:
         System.err.println("Unknown font type selected!");
         System.exit(1);
         break;
      }
   }

   /**
    * Adds a custom font to memory using the given variables. This essentially just creates a java.awt.Font
    * and converts it to a TrueFontType instance for lwjgl display.
    *
    * @param fontName The name of the given font. This will use a java.awt.Font instance to create
    * an lwjgl suitable TrueTypeFont.
    * @param bold Whether or not the font will be bold.
    * @param fontSize The size of the font.
    * @param antiAlias Whether or not you want to use anti aliasing for the custom font.
    */

   public void addCustomFont(String fontName, boolean bold, int fontSize, boolean antiAlias) {
      try {
         TrueTypeFont ttf = new TrueTypeFont(new Font(fontName, bold ? Font.BOLD : Font.PLAIN, fontSize), antiAlias);
         customFonts.put(fontName.toLowerCase(), ttf);
      } catch (Exception e) {
         e.printStackTrace();
         System.err.println("Error adding custom font: " + fontName);
      }
   }

   /**
    * Draws a String at the given x, y coordinates, using the specified customFont type.
    *
    * @param string The string to be rendered.
    * @param x The x coordinate in 2D space.
    * @param y The y coordinate in 2D space.
    * @param format The string format. 0 = align left, 1 = align right, 2 = align center
    * @param customFont The name of the custom font. This would have been set when adding a
    * new font using {@link #addCustomFont(String, boolean, int, boolean)}
    */

   public void drawString(String string, int x, int y, int format, String customFont) {
      try {
         customFonts.get(customFont.toLowerCase()).drawString(x, y, string, 1, 1, format);
      } catch (Exception e) {
         e.printStackTrace();
         System.err.println("Error drawing string using custom font: " + customFont);
      }
   }

   /**
    *
    * Draws a String at the given x, y coordinates, using the specified customFont type.
    *
    * @param string The string to be rendered.
    * @param x The x coordinate in 2D space.
    * @param y The y coordinate in 2D space.
    * @param scaleX The scale (size) you want to use while drawing the string.
    * @param scaleY The scale (size) you want to use while drawing the string.
    * @param format The string format. 0 = align left, 1 = align right, 2 = align center
    * @param customFont The name of the custom font. This would have been set when adding a
    * new font using {@link #addCustomFont(String, boolean, int, boolean)}
    */

   public void drawString(String string, int x, int y, int scaleX, int scaleY, int format, String customFont) {
      try {
         customFonts.get(customFont.toLowerCase()).drawString(x, y, string, scaleX, scaleY, format);
      } catch (Exception e) {
         e.printStackTrace();
         System.err.println("Error drawing string using custom font: " + customFont);
      }
   }

   public static GLFont getInstance() {
      return INSTANCE;
   }

}
Pages: [1] 2 3
 
mercenarius (4 views)
2020-06-04 19:26:01

mercenarius (2 views)
2020-06-04 19:13:43

Riven (850 views)
2019-09-04 15:33:17

hadezbladez (5834 views)
2018-11-16 13:46:03

hadezbladez (2635 views)
2018-11-16 13:41:33

hadezbladez (6251 views)
2018-11-16 13:35:35

hadezbladez (1504 views)
2018-11-16 13:32:03

EgonOlsen (4739 views)
2018-06-10 19:43:48

EgonOlsen (5797 views)
2018-06-10 19:43:44

EgonOlsen (3282 views)
2018-06-10 19:43:20
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04: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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!