Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (475)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (530)
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]
1  Java Game APIs & Engines / OpenGL Development / Re: releasing shaders after glEnd doesn't apply the shader? on: 2012-04-04 15:02:19
Haha, great, that was it. Now i feel stupid, thank you very much sir xD
2  Java Game APIs & Engines / OpenGL Development / releasing shaders after glEnd doesn't apply the shader? on: 2012-04-04 13:55:41
Hey,
I found out some strange behaviour, shaders in my code work kind of wierd when you release them with ARBShaderObjects.glUseProgramObjectARB(0). In the example below after 2k ticks it starts releasing the shader in the render cycle, and as that happens, it wont apply the shaders at all even retroactively on the quad that already has been glEnded(in this case, no image is drawn on the quad). This is kind of wierd considering releasing after glEnd is suggested in most shader guides (e.g. http://lwjgl.org/wiki/index.php?title=GLSL_Shaders_with_LWJGL).

What is even more interesting but isnt demonstrated in my code here is, when i draw multiple objects with shaders and dont ever release them with ARBShaderObjects.glUseProgramObjectARB(0), just bind them, it works all good.

So, what exactly does ARBShaderObjects.glUseProgramObjectARB(0) do? Do I use it correctly? What causes this strange behaviour?

The first class is the main class that runs everything. Then I have a few utility classes that i wont post here (ShaderLoader,ImageLoader, I think you know what they do). The second class is the Shader class which is capable of loading and compiling the Shader, and some utility methods for setting up the shader and binding it.


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  
package cz.witzany.gamev2.twlgui;

import static org.lwjgl.opengl.GL11.*;

import java.awt.Rectangle;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

import cz.witzany.gamev2.graphics.shaders.Shader;
import cz.witzany.gamev2.graphics.shaders.ShaderLoader;
import cz.witzany.gamev2.graphics.shaders.SimpleImage;
import cz.witzany.gamev2.graphics.utils.ImageLoader;

public class TestCase implements Runnable {
   int texture;
   Shader shader;
   int timeout = 0;

   public static void main(String[] args) {
      new TestCase().run();
   }

   @Override
   public void run() {
      initGL();
      initObjects();

      while (!Display.isCloseRequested()) {
         glClear(GL11.GL_COLOR_BUFFER_BIT);

         glMatrixMode(GL_PROJECTION);
         glLoadIdentity();
         glOrtho(-400, 400, -300, 300, 10, -10);
         glMatrixMode(GL_MODELVIEW);
         glLoadIdentity();
         
         shader.bind();
         shader.setTexture("colorMap", 0, texture);
         shader.setUniformF("tx", 1/90.0f);
         shader.setUniformF("ty", 1/90.0f);
         shader.setUniformF("meshScale", 1.0f);

         glScaled(90, -90, 1);
         glBegin(GL11.GL_QUADS);
         glTexCoord2f(0, 0);
         glVertex2d(0, 0);
         glTexCoord2f(1, 0);
         glVertex2d(1, 0);
         glTexCoord2f(1, 1);
         glVertex2d(1, 1);
         glTexCoord2f(0, 1);
         glVertex2d(0, 1);
         glEnd();
         
         if(timeout > 2000)
            shader.unbind();
         timeout++;
         
         Display.update();
      }
   }

   private void initObjects() {
      shader = ShaderLoader.loadShader("Data/Shaders/Sprite");
      texture = ImageLoader.loadImage("Data/Textures/Sprites/Creeper/Creeper.png", new Rectangle());
   }

   private void initGL() {
      try {
         Display.setDisplayMode(new DisplayMode(800, 600));
         Display.create();
      } catch (LWJGLException e) {
         e.printStackTrace();
         System.exit(0);
      }

      glShadeModel(GL_SMOOTH);
      glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT
            | GL_STENCIL_BUFFER_BIT);
      glDepthRange(1.0f, 0.0f);
      glAlphaFunc(GL_GREATER, 0x00);
      glDepthFunc(GL_GREATER);
      glStencilFunc(GL_NEVER, 0x0, 0xFFFFFFFF);
      glBlendFunc(GL_ZERO, GL_SRC_COLOR);

      GL11.glViewport(0, 0, Display.getWidth(), Display.getHeight());
   }
}




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 cz.witzany.gamev2.graphics.shaders;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;

public class Shader {
   private static int activeShader = -1;
   public int shader;
   public int vertShader;
   public int fragShader;
   private boolean useShader;

   public Shader(String shaderDir) {
      File sDir = new File(shaderDir);
      useShader = true;
      if (!sDir.exists() || !sDir.isDirectory()) {
         useShader = false;
         return;
      }
      File vShader = new File(sDir, sDir.getName() + ".vert");
      File fShader = new File(sDir, sDir.getName() + ".frag");
      if (!vShader.exists() || !fShader.exists()) {
         useShader = false;
         return;
      }
      shader = ARBShaderObjects.glCreateProgramObjectARB();
      if (shader == 0) {
         useShader = false;
         return;
      }
      vertShader = createShader(vShader.getAbsolutePath(),
            ARBVertexShader.GL_VERTEX_SHADER_ARB);
      fragShader = createShader(fShader.getAbsolutePath(),
            ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
      if (vertShader == 0 || fragShader == 0) {
         useShader = false;
         return;
      }
      ARBShaderObjects.glAttachObjectARB(shader, vertShader);
      ARBShaderObjects.glAttachObjectARB(shader, fragShader);
      ARBShaderObjects.glLinkProgramARB(shader);

      if (GL20.glGetShader(shader, GL20.GL_LINK_STATUS) == GL11.GL_FALSE) {
         printLogInfo(shaderDir, shader);
         useShader = false;
         return;
      }

      ARBShaderObjects.glValidateProgramARB(shader);

      if (GL20.glGetShader(shader, GL20.GL_VALIDATE_STATUS) == GL11.GL_FALSE) {
         printLogInfo(shaderDir, shader);
         useShader = false;
         return;
      }
      useShader = true;
      System.out.println("Loaded shader " + shaderDir);
   }

   private int createShader(String filename, int type) {
      int nshader = ARBShaderObjects.glCreateShaderObjectARB(type);
      if (nshader == 0) {
         return 0;
      }
      String code = "";
      String line;
      try {
         BufferedReader reader = new BufferedReader(new FileReader(filename));
         while ((line = reader.readLine()) != null) {
            code += line + "\n";
         }
         reader.close();
      } catch (Exception e) {
         System.out.println("Fail reading vertex shading code");
         return 0;
      }
      ARBShaderObjects.glShaderSourceARB(nshader, code);
      ARBShaderObjects.glCompileShaderARB(nshader);
      printLogInfo(filename, nshader);

      if (GL20.glGetShader(nshader, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE)
         return 0;
      return nshader;
   }

   private boolean printLogInfo(String name, int obj) {
      IntBuffer iVal = BufferUtils.createIntBuffer(1);
      ARBShaderObjects.glGetObjectParameterARB(obj,
            ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);

      int length = iVal.get();
      if (length > 1) {
         // We have some info we need to output.
        ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
         iVal.flip();
         ARBShaderObjects.glGetInfoLogARB(obj, iVal, infoLog);
         byte[] infoBytes = new byte[length];
         infoLog.get(infoBytes);
         String out = new String(infoBytes);
         System.out.println(name + " log:\n" + out);
      }
      return true;
   }

   private int getUniformLocation(String name) {
      int location = ARBShaderObjects.glGetUniformLocationARB(shader, name);
      if (location == -1)
         throw new RuntimeException(name + " not available");
      return location;
   }

   public void setTexture(String name, int index, int pointer) {
      int location = getUniformLocation(name);
      GL13.glActiveTexture(GL13.GL_TEXTURE0 + index);
      GL11.glBindTexture(GL11.GL_TEXTURE_2D, pointer);
      ARBShaderObjects.glUniform1iARB(location, index);
   }

   public synchronized void bind() {
      if (activeShader == shader)
         return;
      if (useShader) {
         //unbind();
        ARBShaderObjects.glUseProgramObjectARB(shader);
         activeShader = shader;
      } else
         System.out.println("warning, shader not used");
   }

   public void unbind() {
      ARBShaderObjects.glUseProgramObjectARB(0);
   }
   
   public void setUniformF(String name, Float value){
      int location = getUniformLocation(name);
      ARBShaderObjects.glUniform1fARB(location, value);
   }
}
3  Java Game APIs & Engines / OpenGL Development / Re: Heightmapping sprites on: 2011-11-06 16:07:46
TL but i did read, thanks for the insight.
Even though this looks like an interesting thing to do, i think ill do fine with my 2000 sprites for now.
And now i feel bad cause i have such a short reply for this wall of text Cheesy
4  Java Game APIs & Engines / OpenGL Development / Re: Heightmapping sprites on: 2011-11-05 21:06:18
By batching together you mean something like not calling those shader and vertex binds if they are already bound? And call only transforms and drawarrays? I think i could do that, but i dont think it will help much, i think that could be already optimized.
5  Java Game APIs & Engines / OpenGL Development / Re: Heightmapping sprites on: 2011-11-05 13:52:14
Doesnt seems to help, tried both big and little endian.
1  
2  
3  
4  
5  
6  
7  
8  
9  
      // push data to the buffer
     ByteBuffer fbuffer = ByteBuffer.allocateDirect(vertices.length * 4);
      fbuffer.order(ByteOrder.LITTLE_ENDIAN);
      for (float f : vertices)
         fbuffer.putFloat(f);
      fbuffer.rewind();
      ARBVertexBufferObject.glBufferDataARB(
            ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, fbuffer,
            ARBVertexBufferObject.GL_STATIC_DRAW_ARB);

And, im not sure if drawing points is good, cause the frag shader filters the 0 height points (which the corners are), so they wouldnt be displayed.
EDIT: i get image now, i changed the debug draw from points to triangle strip again + the byte ordering and it started working Smiley
EDIT2: changed it to draw quads... drawing quads is a lot faster than drawing triangle strips (50fps agains 30 fps)
Whats interesting is that i didnt get any performance boost from this... my fps with 2000 sprites is around 25 with, and without vertex buffering.
6  Java Game APIs & Engines / OpenGL Development / Re: Heightmapping sprites on: 2011-11-05 13:03:38
Hi again, ok now, im trying to get the vertex buffer approach to work, but im stuck. I've tried doing it as described in the lwjgl tutorial but i think that doesnt work with shaders. I digged around the web a little more and I found a method that surely uses shaders. So I tried binding the vertex buffer to shader variables, but i couldnt get it to draw anything on the screen either. Is this approach the right one? There is simply too much stuff on the internet to know whats right and whats wrong Smiley Here is my code:
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  
// Mesh.java==============================================================================================
package cz.witzany.gamev2.graphics.utils;

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.ARBVertexBufferObject;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;

import cz.witzany.gamev2.graphics.utils.ShaderLoader.Shader;

public class Mesh {
   private int VBOBuffer;
   private int stride;
   private Shader shader;
   private int position, texture;

   public Mesh(String file, Shader shader) {
      // #TODO load from a file
     // x y z u v
     float[] vertices = { 0f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 1f, 0f, 1f, 1f,
            0f, 1f, 1f, 0f, 1f, 0f, 0f, 1f };
      this.stride = 5 * 4;
      this.shader = shader;

      //register vertex buffer
     VBOBuffer = genBuffer();

      //bind
     ARBVertexBufferObject.glBindBufferARB(
            ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, VBOBuffer);

      //push data to the buffer
     FloatBuffer fbuffer = ByteBuffer.allocateDirect(vertices.length * 4)
            .asFloatBuffer();
      fbuffer.put(vertices);
      fbuffer.rewind();
      ARBVertexBufferObject.glBufferDataARB(
            ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, fbuffer,
            ARBVertexBufferObject.GL_STATIC_DRAW_ARB);

      //get the texture and position location pointers
     shader.apply();
      position = GL20.glGetAttribLocation(shader.shader, "position");
      texture = GL20.glGetAttribLocation(shader.shader, "texture");
      shader.release();
   }

   private int genBuffer() {
      IntBuffer buffer = BufferUtils.createIntBuffer(1);
      ARBVertexBufferObject.glGenBuffersARB(buffer);
      return buffer.get(0);
   }

   public void draw() {
      //bind the buffer
     ARBVertexBufferObject.glBindBufferARB(
            ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, VBOBuffer);

      //set the position and texture to point on the buffer
     GL20.glVertexAttribPointer(position, 3, GL11.GL_FLOAT, false, stride, 0);
      GL20.glVertexAttribPointer(texture, 2, GL11.GL_FLOAT, false, stride, 12);

      GL20.glEnableVertexAttribArray(position);
      GL20.glEnableVertexAttribArray(texture);

      //debug draw, draw anything
     GL11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 3); // #TODO indices
  }

   public void dispose() {
      ARBVertexBufferObject.glDeleteBuffersARB(VBOBuffer);
   }
}
// DepthSprite.java=========================================================================================
package cz.witzany.gamev2.graphics;

import java.awt.Rectangle;
import java.io.File;

import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.GL11;

import cz.witzany.gamev2.graphics.utils.ImageLoader;
import cz.witzany.gamev2.graphics.utils.Mesh;
import cz.witzany.gamev2.graphics.utils.MeshLoader;
import cz.witzany.gamev2.graphics.utils.ShaderLoader;
import cz.witzany.gamev2.graphics.utils.Shader;

public class DepthSprite extends Node {

   private int x, y, width, height;
   private Rectangle origSize;
   private double scale;
   private Shader shader;
   private Mesh mesh;
   private int tex, normal;
   private float heightScale;

   public DepthSprite(int guid, int x, int y, double scale, String texture, float heightScale) {
      super(guid);
      shader = ShaderLoader.loadShader("Data/Shaders/Depthsprite");
      mesh = MeshLoader.loadMesh("Data/Mesh/Quad",shader);
      origSize = new Rectangle();
      File f = new File(texture);
      File color = new File(f, "rgbd"+f.getName() + ".png");
      this.tex = ImageLoader.loadImage(color.getAbsolutePath(), origSize);
      width = (int) (origSize.width*scale);
      height = (int) (origSize.height*scale);
      this.x = x;
      this.y = y;
      this.scale = scale;
      this.heightScale = heightScale;
   }

   public void update() {
      GL11.glLoadIdentity();
      GL11.glPushMatrix();
      GL11.glTranslatef(x, y, 1);
      GL11.glScaled(width, height, 0);

      shader.apply();
      shader.setTexture("colorMap", 0, tex);

      int location = ARBShaderObjects.glGetUniformLocationARB(shader.shader, "height");
      if(location == -1)
         throw new RuntimeException("height not available");
      ARBShaderObjects.glUniform1fARB(location, heightScale);
     
      mesh.draw();

      shader.release();

      GL11.glPopMatrix();
   }
}
// Depthsprite.vert=========================================================================================
attribute vec3 position;
attribute vec2 texture;

varying vec2 texturep;
void main(){
    texturep = texture;
    gl_Position = gl_ModelViewProjectionMatrix*vec4(position,1.0);
}
// Depthsprite.frag=========================================================================================
uniform sampler2D colorMap;
uniform float height;
varying vec2 texturep;

void main(){
     vec4 c = texture2D(colorMap, (texturep.st));
     if(c.a > 0.0){
       gl_FragColor = vec4(c.rgb,1.0);
       gl_FragDepth = 1.0-height*c.a;
     }
}
7  Java Game APIs & Engines / OpenGL Development / Re: Heightmapping sprites on: 2011-11-04 11:38:44
I dont think discarding is necessary, i clear the depth to 1 (furthest) on each update so these dont pass the depth test anyway, in fact depth 1 is reserved for stuff i dont want to see. In fact, i tested it and calling discard actually lowers my fps.
1  
gl_FragColor = vec4(c,1.0);

Doesnt work... c is a vec4, this works:
1  
gl_FragColor = vec4(vec3(c),1.0);
8  Java Game APIs & Engines / OpenGL Development / Re: Heightmapping sprites on: 2011-11-03 20:59:36
The shader loading, yeah, i noticed that soon after posting, i already load each shader only once...
About the performance, i dont have any numbers, but i can run now with 500 of these sprites on the screen with above 60 fps (i have my fps limited to 60), previously, i couldnt do that (less than 1 fps). However, more sprites lower the fps under the sweet 60 fps value.
Cause of the performance im thinking about moving the depth value into the alpha channel (now its another png file, with 3 bytes wasted per depth value), with a alpha test for greater than 0, leaving only 1 bit for alpha. And playing with the depth to take advantage of the depth buffers size is probably a good thing to do, but first i need to have some stuff to test it on, these cubes wont do anymore Smiley
About aliasing, im quite satisfied with the graphics for now, perhaps later ill look into it, but it doesnt concern me just now.

Edit:
moving the depth channel into the alpha channel and turning off blending helped a lot with performance, now i can have 1000 sprites with 50 fps. Wierdly enough, i had to move the alpha test into the shader, GL11.glAlphaFunc(GL11.GL_GREATER, 0x00); didnt mask off anything.
1  
2  
3  
4  
5  
6  
7  
8  
9  
uniform sampler2D colorMap;

void main(){
    vec4 c = texture2D(colorMap, (gl_TexCoord[0].st));
    if(c.a > 0.0){
      gl_FragColor = vec4(c.r,c.g,c.b,1.0);
      gl_FragDepth = 1.0-c.a;
    }
}
9  Java Game APIs & Engines / OpenGL Development / Re: Heightmapping sprites on: 2011-11-03 18:55:44
Well, i have no experience with shaders, but its quite easy, and it works great! The resulting image! Ill post this for future generations to find Smiley

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  
//DepthSprite.java=========================================================================================
package cz.witzany.gamev2.graphics;

import java.io.File;

import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;

import cz.witzany.gamev2.graphics.utils.ImageLoader;
import cz.witzany.gamev2.graphics.utils.Shader;

public class DepthSprite extends Node {

   public static final int MSG_SET_POS = 1;
   
   private int x,y,width,height;
   private double scale;
   private Shader shader;
   private int tex, depth;
   
   public DepthSprite(int guid, int x, int y, double scale, String texture) {
      super(guid);
      shader = new Shader("Data/Shaders/texture");
      java.awt.Rectangle r = new java.awt.Rectangle();
      File f = new File(texture);
      File color = new File(f,f.getName()+".png");
      File depth = new File(f,"z-"+f.getName()+".png");
      tex = ImageLoader.loadImage(color.getAbsolutePath(), r);
      width = r.width;
      height = r.height;
      this.depth = ImageLoader.loadImage(depth.getAbsolutePath(), r);
      this.x=x;
      this.y=y;
      this.scale = scale;
   }

   public void update() {
      GL11.glLoadIdentity();
      GL11.glPushMatrix();
      GL11.glTranslatef(x, y, 1);
      GL11.glScaled(width*scale, height*scale, 0);
     
      shader.apply();
     
      int colorMap = ARBShaderObjects.glGetUniformLocationARB(shader.shader, "colorMap");
      if(colorMap == -1)
         throw new RuntimeException("Sampler not available:"+colorMap);
      GL13.glActiveTexture(GL13.GL_TEXTURE0);
      GL11.glBindTexture(GL11.GL_TEXTURE_2D,tex);
      ARBShaderObjects.glUniform1iARB(colorMap, 0);

      int depthMap = ARBShaderObjects.glGetUniformLocationARB(shader.shader, "depthMap");
      if(depthMap == -1)
         throw new RuntimeException("Sampler not available:"+depthMap);
      GL13.glActiveTexture(GL13.GL_TEXTURE1);
      GL11.glBindTexture(GL11.GL_TEXTURE_2D,depth);
      ARBShaderObjects.glUniform1iARB(depthMap, 1);
     
      GL11.glBegin(GL11.GL_QUADS);
      GL11.glColor4f(1, 0, 0, 1);
      GL11.glTexCoord2f(0, 0);
      GL11.glVertex2d(0, 0);

      GL11.glTexCoord2f(1, 0);
      GL11.glVertex2d(1, 0);

      GL11.glTexCoord2f(1, 1);
      GL11.glVertex2d(1, 1);

      GL11.glTexCoord2f(0, 1);
      GL11.glVertex2d(0, 1);
      GL11.glEnd();
     
      shader.release();
     
      GL11.glPopMatrix();
   }

}
//Shader.java=============================================================================================
package cz.witzany.gamev2.graphics.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;

public class Shader {
   
   public int shader;
   public int vertShader;
   public int fragShader;
   private boolean useShader;

   public Shader(String shaderDir){
      File sDir = new File(shaderDir);
      useShader = true;
      if(!sDir.exists() || !sDir.isDirectory()){
         useShader = false;
         return;
      }
      File vShader = new File(sDir,sDir.getName()+".vert");
      File fShader = new File(sDir,sDir.getName()+".frag");
      if(!vShader.exists() || !fShader.exists()){
         useShader = false;
         return;
      }
      shader = ARBShaderObjects.glCreateProgramObjectARB();
      if(shader == 0){
         useShader = false;
         return;
      }
      vertShader = createShader(vShader.getAbsolutePath(),ARBVertexShader.GL_VERTEX_SHADER_ARB);
      fragShader = createShader(fShader.getAbsolutePath(),ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
      if(vertShader == 0 || fragShader == 0){
         useShader = false;
         return;
      }
        ARBShaderObjects.glAttachObjectARB(shader, vertShader);
        ARBShaderObjects.glAttachObjectARB(shader, fragShader);
        ARBShaderObjects.glLinkProgramARB(shader);
        ARBShaderObjects.glValidateProgramARB(shader);
        useShader=printLogInfo(shader);
   }
   
   private int createShader(String filename, int type){
      int shader = ARBShaderObjects
            .glCreateShaderObjectARB(type);
      if (shader == 0) {
         return 0;
      }
      String code = "";
      String line;
      try {
         BufferedReader reader = new BufferedReader(new FileReader(filename));
         while ((line = reader.readLine()) != null) {
            code += line + "\n";
         }
      } catch (Exception e) {
         System.out.println("Fail reading vertex shading code");
         return 0;
      }
      ARBShaderObjects.glShaderSourceARB(shader, code);
      ARBShaderObjects.glCompileShaderARB(shader);

      if (!printLogInfo(shader))
         return 0;
      return shader;
   }
   
    private boolean printLogInfo(int obj){
        IntBuffer iVal = BufferUtils.createIntBuffer(1);
        ARBShaderObjects.glGetObjectParameterARB(obj,
        ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);

        int length = iVal.get();
        if (length > 1) {
            // We have some info we need to output.
           ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
            iVal.flip();
            ARBShaderObjects.glGetInfoLogARB(obj, iVal, infoLog);
            byte[] infoBytes = new byte[length];
            infoLog.get(infoBytes);
            String out = new String(infoBytes);
            System.out.println("Info log:\n"+out);
        }
        else return true;
        return false;
    }
   
    public void apply(){
       if(useShader)
            ARBShaderObjects.glUseProgramObjectARB(shader);
       else
          System.out.println("warning, shader not used");
    }
   
    public void release(){
       ARBShaderObjects.glUseProgramObjectARB(0);
    }
}
//ImageLoader.java=========================================================================================
package cz.witzany.gamev2.graphics.utils;

import java.awt.Rectangle;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;

import net.sourceforge.fastpng.PNGDecoder;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;

public class ImageLoader {

   private HashMap<String, Integer> images = new HashMap<String, Integer>();
   private HashMap<String, Rectangle> dimensions = new HashMap<String, Rectangle>();
   private static ImageLoader instance = new ImageLoader();

   private ImageLoader() {
   }

   private int load(String path, Rectangle dimension) {
      if(images.containsKey(path)){
         Rectangle dim = dimensions.get(path);
         dimension.height = dim.height;
         dimension.width = dim.width;
         return images.get(path);
      }
      try{
         InputStream in = new FileInputStream(path);
         PNGDecoder decoder = new PNGDecoder(in);

         dimension.width = decoder.getWidth();
         dimension.height = decoder.getHeight();
         dimensions.put(path, new Rectangle(dimension));
         
         ByteBuffer data = ByteBuffer.allocateDirect(4*decoder.getWidth()*decoder.getHeight());
         decoder.decode(data, decoder.getWidth()*4, PNGDecoder.TextureFormat.RGBA);
         data.rewind();
         
         IntBuffer tmp = BufferUtils.createIntBuffer(1);
         GL11.glGenTextures(tmp);
         tmp.rewind();
         GL11.glBindTexture(GL11.GL_TEXTURE_2D, tmp.get(0));
         tmp.rewind();
         GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
         GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
         GL11.glTexImage2D(GL11.GL_TEXTURE_2D,0,GL11.GL_RGBA,decoder.getWidth(),decoder.getHeight(),0,GL11.GL_RGBA,GL11.GL_UNSIGNED_BYTE,data);
         GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 4);
         int p = tmp.get(0);
         images.put(path, p);
         return p;
      }catch (FileNotFoundException ex){
         return -1;
      } catch (IOException e) {
         return -1;
      }
   }

   public static int loadImage(String path, Rectangle dimensions) {
      return instance.load(path, dimensions);
   }
}
//vertex shader============================================================================================
void main(){
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
}
//fragment shader==========================================================================================
uniform sampler2D colorMap;
uniform sampler2D depthMap;

void main(){
    gl_FragColor = texture2D( colorMap, (gl_TexCoord[0].st));
    vec3 depth = vec3(texture2D( depthMap, (gl_TexCoord[0].st)));
    gl_FragDepth = depth.r;
}

Now, my next goal is lighting, that is, make some basic dynamic lighting. Ill ask here if i have any problems.
10  Java Game APIs & Engines / OpenGL Development / Re: Heightmapping sprites on: 2011-11-02 19:58:20
Thanks for the reply. Nailbord search did indeed spit out some similar stuff, but sadly, mostly questions and a few papers (mainly theory in those). But, i found this: http://glprogramming.com/red/chapter14.html#name18 which looks like exactly what i need. Ill write here if im any successfull.

Ok well, I've read a bit about how the buffers work and i think this should work, even though it doesnt:
I call this each update
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
      GL11.glClearDepth(0xFF);
      GL11.glClearColor(0,0,0,0);
      GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
      GL11.glPushAttrib(GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
      GL11.glDepthRange(0x0, 0xFF);
     
      GL11.glEnable(GL11.GL_STENCIL_TEST);
      GL11.glEnable(GL11.GL_DEPTH_TEST);
      GL11.glEnable(GL11.GL_BLEND);
     
      GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
      GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);

And this is the new update in the Image class above (this is called multiple times per update cycle - once per each image)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
      GL11.glDepthMask(true);
      GL11.glColorMask(false, false, false, false);
      GL11.glStencilMask(GL11.GL_TRUE);

      GL11.glDepthFunc(GL11.GL_LESS);
      GL11.glStencilFunc(GL11.GL_ALWAYS, 0x0, 0xFFFFFFFF);
      GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
     
      GL11.glRasterPos2i(x, y);
      GL11.glDrawPixels(width, height, GL11.GL_BYTE,
            GL11.GL_DEPTH_COMPONENT, dataZ);
     
      GL11.glDepthMask(false);
      GL11.glColorMask(true, true, true, true);
      GL11.glStencilMask(GL11.GL_TRUE);

      GL11.glStencilFunc(GL11.GL_GREATER, 0x0, 0xFFFFFFFF);
      GL11.glStencilOp(GL11.GL_ZERO, GL11.GL_ZERO, GL11.GL_ZERO);
     
      GL11.glDrawPixels(width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,
            dataRGBA);

I do this in 2 passes, first i draw my heightmap (bytearray with each byte height - later ill probably want floats) to the z buffer, and i use this stencil buffer thing to create a map of pixels that are updated, those are the pixels that had their z good enough to get to the z buffer. After that I draw the image, but with the stencil mask applied. The z is from 0 to 255 (byte), 0 being near and 255 far, therefore the depth function is LESS and the depth buffer is initially set to 0xFF. What is wierd is that even if i play with the stencil function in the second pass (set it to never) everything gets rendered, as if it had no influence on the rendering.
I think this should work, however im probably missing some GL calls or something, cause it only draws the image, as if there was no zbuffer.
Anybody knows what am I doing wrong? Thanks in advance Smiley
11  Java Game APIs & Engines / OpenGL Development / Heightmapping sprites on: 2011-11-02 14:59:48
Hi there, im playing with OGL and ive made a little experiment about 2.5d graphics. I want to have 2 images for each sprite, one a colormap and one a heightmap/zmap (more like distance to camera-map - similar to those that are used when you want to do depth of view). The heightmap adds a lot more feeling that the sprite is actually a 3D model, even though it is just an image. Ive coded this working example:
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  
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.lwjgl.opengl.GL11;

public class Image extends Node {

   public Image(String path, String dmap, int guid) {
      super(guid);
      this.path = path;
      this.dmap = dmap;
   }

   private String path, dmap;
   public int width, height;
   public int x = 100, y=100;
   public double scale = 0.3;
   byte[] dataABGR, dataHeight;

   public void update() {
      if (dataABGR == null) {
         Rectangle r = new Rectangle();
         dataABGR = loadImage(path,r,scale);
         width = r.width;
         height = r.height;
         dataHeight = loadImage(dmap,r,scale);
      }
      GL11.glBegin(GL11.GL_POINTS);
      for(int x = 0; x < width; x++)
         for(int y = 0; y < height; y++){
            int o = (x+y*width)*4;
            byte r = dataABGR[o+3];
            byte g = dataABGR[o+2];
            byte b = dataABGR[o+1];
            byte a = dataABGR[o];
            float z = height(x,y);
            GL11.glColor4ub(r,g,b,a);
            if(a != 0)//#TODO fix this... gl should support alpha
              GL11.glVertex3f(this.x+x, this.y+y, z/500.0f);
         }
      GL11.glEnd();
   }
   
   private float height(int x, int y){
      return (int)dataHeight[(x+y*width)*4+1] & 0xFF;
   }

   public static byte[] loadImage(String path, Rectangle dimensions, double scale) {

      try {
         BufferedImage load = ImageIO.read(new File(path));
         int width = (int)(load.getWidth()*scale);
         int height = (int)(load.getHeight()*scale);
         dimensions.width = width;
         dimensions.height = height;
         
         BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
         Graphics2D g = img.createGraphics();
         g.setTransform(AffineTransform.getScaleInstance(scale, scale));
         g.drawImage(load, null, null);
         int[] data = new int[width*height];
         System.out.println("Loaded texture "+path+" mapped on "+width+"x"+height);
         return ((DataBufferByte)img.getRaster().getDataBuffer()).getData();
      } catch (IOException e) {
         e.printStackTrace();
      }
      return null;
   }
}

I suppose most of you dont wanna read the code, so ill explain a bit. The class represents a sprite with a heightmap, it loads the sprite and heightmap and on each update draws each pixel (no it doesnt hand the texture or byte array to OGL, it sends each pixel individually) on the correct x,y and heighmap calculated z position. I like this method because i can draw my sprites, or model them, and i think i could have them composed into nice complex structures. Maybe a simple 3D approach would be better, but because i like hand-drawn graphics i wanted to try this out Smiley

Ok so... now to the question. This approach works, here is a result http://filesmelt.com/dl/result1.png and the colormap and the heightmap used in the example. The problem is, it is slow. I suppose there is some way to do the same thing with a shader, to use the gpu. My experience with 3D and OGL is more theoretical than practical, so thats why i ask you here if you know about some more performance efficient way. I suppose I could send the colormap and the heightmap to the gpu and let some vertex shader do the work, but I dont know how Smiley

PS: this is a copied post from http://goo.gl/8tkNv i think here i might have better chances of getting an answer
Pages: [1]
 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

ctomni231 (36 views)
2014-07-18 06:55:21

Zero Volt (34 views)
2014-07-17 23:47:54

danieldean (27 views)
2014-07-17 23:41:23

MustardPeter (30 views)
2014-07-16 23:30:00

Cero (44 views)
2014-07-16 00:42:17

Riven (46 views)
2014-07-14 18:02:53

OpenGLShaders (35 views)
2014-07-14 16:23:47

Riven (35 views)
2014-07-14 11:51:35

quew8 (31 views)
2014-07-13 13:57:52

SHC (67 views)
2014-07-12 17:50:04
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
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!