• Content count

  • Joined

  • Last visited

Community Reputation

112 Neutral

About eCustic

  • Rank
  1. Thanks guys! I've made it work and thought I'd post the relevant code here to help anyone else trying to do this. So I did basically exactly what mhagain suggested. I load both my sprite and palette as textures (both 2D textures for now) and then I have a fragment shader which gets the brightness value from my sprite and returns a color from the palette based on that value. [b]Fragment Shader:[/b] [CODE] uniform sampler2D texture; uniform sampler2D palette; void main() { vec4 textureColor = texture2D(texture, gl_TexCoord[0].xy).rgba; vec3 paletteColor = texture2D(palette, vec2(textureColor.r, 0)).rgb; gl_FragColor = vec4(paletteColor.r, paletteColor.g, paletteColor.b, textureColor.a); } [/CODE] In the above code only the red value of the texture color is used to look up the color in the palette. The reason for this is that the sprite is greyscaled, meaning that the R,G and B values are equal, and I felt it would be a waste to calculate the average (brightness) since it would give the same value. The gl_TexCoord[0] is set in the vertex shader which is quite simple as well. [b]Vertex Shader:[/b] [CODE] void main() { gl_Position = ftransform(); gl_TexCoord[0] = gl_MultiTexCoord0; } [/CODE] Lastly I'll just include the Java code for actually using these shaders (excluding the loading/compiling part): [CODE] int paletteLocation = GL20.glGetUniformLocation(shaderProgram, "palette"); GL20.glUniform1i(paletteLocation, 1); GL13.glActiveTexture(GL13.GL_TEXTURE1); GL11.glBindTexture(GL11.GL_TEXTURE_2D, palette.getTextureID()); int textureLocation = GL20.glGetUniformLocation(shaderProgram, "texture"); GL20.glUniform1i(textureLocation, 0); GL13.glActiveTexture(GL13.GL_TEXTURE0); GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture.getTextureID()); GL11.glBegin(GL11.GL_QUADS); GL11.glTexCoord2f(0, 0); GL11.glVertex2f(0, 0); GL11.glTexCoord2f(1, 0); GL11.glVertex2f(64, 0); GL11.glTexCoord2f(1, 1); GL11.glVertex2f(64, 128); GL11.glTexCoord2f(0, 1); GL11.glVertex2f(0, 128); GL11.glEnd(); [/CODE] Just to summarize the above code: I first bind the palette texture to GL_TEXTURE1 and enable the shader to reference it using the variable name "palette". Then I do the same thing for the sprite texture except I use GL_TEXTURE0 and the variable name "texture". I then simply draw a quad with the sprite texture in immediate mode. So thanks again for the help and I hope that this helps anyone else with a similar issue. [img][/img]
  2. Hi all, Does anyone know how I could replace the colors on a texture in run-time using OpenGL (more specifically LWJGL)? All the sprites I am loading for my game consist only of 8 shades of grey, and what I want to do is replace each of those shades of grey with a specific color which is retrieved from another 1 x 8 pixel texture. The following picture demonstrates exactly what I want to be able to do. [img][/img] The reason I want to do this is to be able to reuse the same sprite for multiple things in the game. A sword for example might have the same sprite but have a different color palette applied to it depending on which material it is made of. I've implemented a system for this once in Java2D, which I obviously can't use now that I'm using OpenGL, but I was wondering whether this could be achieved with shaders or something. Please note that in this case I can't simply use color tinting or changing the hue, since I want to be able to control the specific color for each shade of grey (so that shadows can be bluish/purplish while highlights can be more yellow/orange etc.). In my Java2D game I had implemented it so that I had 4 channels on each sprite, grey, red, green and blue, and each channel could have its own color palette applied. Thanks in advance. [img][/img]
  3. Thanks for the help guys. I've solved the problem. Before posting the OP I tried doing as Koehler mentioned: [CODE] GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER,GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER,GL11.GL_NEAREST); [/CODE] This didn't work and I couldn't understand why. After reading Koehler's post I realized that it might be because I'm using the TextureLoader from the Slick2D library (I didn't want to write my own texture loader). I found the API again and saw that one of the overloads of the getTexture method had a filter input, so the solution to the problem was changing the code in my TextureStore class from: [CODE] texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(texturesPath + textureRef)); [/CODE] to [CODE] texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(texturesPath + textureRef), GL11.GL_NEAREST); [/CODE] Hope this helps anyone who is having similar issues. Also I feel this is a cleaner solution than having to modify all your texture files to have a 1 pixel border. Thanks again! [img][/img]
  4. I have been trying to implement animated sprites using a spritesheet in LWJGL, but I'm having some issues with my sprites bleeding into each other. My sprite sheet is 256 x 512 pixels, with 4 x 4 sprites which are each 64 x 128 pixels, for a walking animation in 4 directions. The problem is that each sprite is positioned so that the pixels of the feet are on the edge of the sprite which causes lines to appear above the head on the sprite below it. However, this doesn't happen consistently, only on certain parts of the screen apparently, and not always the same colour even though it should be the same colour. All of my sprites also seem to blur slightly sometimes. Here is the code for the draw method of my Sprite class: [CODE] public void draw(float x, float y) { GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture.getTextureID()); float currentOffsetX = (float)(offsetX + currentFrame) * spriteTextureWidthRatio; float currentOffsetY = (float)offsetY * spriteTextureHeightRatio; GL11.glBegin(GL11.GL_QUADS); GL11.glTexCoord2f(currentOffsetX, currentOffsetY); GL11.glVertex2f(x,y); GL11.glTexCoord2f(currentOffsetX + spriteTextureWidthRatio, currentOffsetY); GL11.glVertex2f(x + width, y); GL11.glTexCoord2f(currentOffsetX + spriteTextureWidthRatio, currentOffsetY + spriteTextureHeightRatio); GL11.glVertex2f(x + width, y + height); GL11.glTexCoord2f(currentOffsetX, currentOffsetY + spriteTextureHeightRatio); GL11.glVertex2f(x, y + height); GL11.glEnd(); } [/CODE] The [b]spriteTextureWidthRatio[/b] and [b]spriteTextureHeightRatio[/b] variables are spriteWidth / textureWidth and spriteHeight / textureHeight respectively. I've read somewhere that the issue might be caused because I'm using floating point values for the texture coordinates. In this case the values for the coordinates will be either 0.0, 0.25, 0.50, 0.75 or 1.0 depending on which part of the sprite sheet is drawn, which would make OpenGL do some weird stuff where it offsets by a half pixel or something, causing the bleeding and the blurriness in some cases. I've heard that I could scale the texture instead using a texture matrix and then access the different parts of the spritesheet with integer values which in this case would be 0 to 4. I don't know how I would go about doing this (I'm fairly new to OpenGL) or if this would solve the problem at all. I've seen other places where people recommend using a 1 pixel transparent border around every sprite. I think the problem with this solution is that it doesn't work for tilesets where you don't want a border between your tiles. Either way, I'm hoping someone here can tell me what the right way to do it is. I'm probably only having this problem because I'm such a noob when it comes to OpenGL. [img][/img]
  5. Java - References

    Wow, I feel foolish now. I just realized that the error was not due to reference issues but something else entirely. I just assumed that the object wasn't being passed as it should and found several websites saying that java was pass-by-value only which seemed to make sense to me based on the results I was getting. However I just debugged it and it is definitely doing what it is supposed to do. I'm just handling the result badly. Anyway, I suppose this thread is now just a waste of space. Thank you all for helping me realize my mistake, I really do appreciate it.
  6. So I'm mainly a C# developer and I'm used to objects being passed by reference in methods. However I am currently attempting to make a small-medium sized game in Java and I've hit a bit of a bump. Usually when I create my game objects I like each object to have a reference to my main Game object. So currently I have the following (only the relevant part of the code is shown here): [code] public abstract class Entity { private Game game; public Entity(Game game) { = game; } } [/code] So when I instantiate a new Entity object from my Game class I just pass [font="Courier New"]this[/font] in the constructor. I expected any changes made to the Game object to be reflected by the game variable of the Entity class, but due to Java's pass-by-value property they aren't. This however is not the main problem as I can live without having a Game reference in each entity. The problem is that I had the same thoughts when making my input handler. I'm currently using Java 2D for the rendering and I'm just drawing on a canvas (my Game class extends Canvas) so I'm just extending the KeyAdapter class with my KeyInputHandler and passing it to the addKeyListener() method in my Game class. However I'd also like to be able to pass the KeyInputHandler object to my Player object so that I can handle all movement of the player within the Player class. However, since the KeyInputHandler is just copied into the Player object it doesn't update the instance variables when the KeyEvents are fired. I might be going about this the wrong way (this is how I usually do it with XNA in C#) or I might just be missing something in the way I've implemented it, but if anyone could help point me in the right direction I'd be really grateful. I'll just paste some of the relevant pieces of code from my KeyInputHandler class and my Player class, so that it might be a bit clearer what I'm trying to do. [code] public class KeyInputHandler extends KeyAdapter { private boolean rightDown; private boolean leftDown; private boolean downDown; private boolean upDown; public boolean isRightDown() { return rightDown; } public boolean isLeftDown() { return leftDown; } public boolean isUpDown() { return upDown; } public boolean isDownDown() { return downDown; } public void keyPressed(KeyEvent e) { ... } // here the rightDown, leftDown, etc. variables are changed. public void keyReleased(KeyEvent e) { ... } } [/code] [code] public class Player extends Actor { public void updateInput(KeyInputHandler keyHandler) { if(keyHandler.isLeftDown() && !keyHandler.isRightDown()) { this.setHorizontalVelocity(-1); } if(keyHandler.isRightDown() && !keyHandler.isLeftDown()) { this.setHorizontalVelocity(1); } ... } } [/code]