Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (498)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [ANSWERED] OpenGL Texutre animating  (Read 631 times)
0 Members and 1 Guest are viewing this topic.
Offline DazKins
« Posted 2013-02-20 12:21:41 »

In Opengl, how would you go about modifying the colour value of each pixel on a texture? Take, for example, in Minecraft, where the water pulses changing colour. Im not interested in the alogirthm behind changing the colour data for the pixels, I'm more inerested in how you would go about applying the moddified texture to an object.

I realise you could probably regenerate the texture each frame but that seems slow and inefficient. Is there a better way to do it?

DazKins

Check out my Dev Blog: http://dazkins.tumblr.com
Offline StrideColossus
« Reply #1 - Posted 2013-02-20 13:09:13 »

To be honest I'd be very surprised if they were actually changing the colours in the texture itself, it's more likely that the effect is implemented in the shader, possibly using alpha maps or something like that to combine the texture and the coloured pulses you mention.  Mind you I've never played Minecraft so I could be completely wrong.

If you *did* want to modify a texture then glTexSubImage() can be used to modify all or part of an uploaded texture, but as you say if you were doing that every frame I expect it wouldn't work too well.
Offline DazKins
« Reply #2 - Posted 2013-02-20 13:17:42 »

Here's the decompiled Minecraft water class from MCP. In here you can see them changing the individual pixel values. How would they go about applying those pixels to an object?

It is decompiled so it could be hard to read, but im just trying to show you how they implement pixel changing

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  
package net.minecraft.src;

public class TextureWaterFX extends TextureFX
{
    /** red RGB value for water texture */
    protected float[] red = new float[256];

    /** green RGB value for water texture */
    protected float[] green = new float[256];

    /** blue RGB value for water texture */
    protected float[] blue = new float[256];

    /** alpha RGB value for water texture */
    protected float[] alpha = new float[256];
    private int tickCounter = 0;

    public TextureWaterFX()
    {
        super(Block.waterMoving.blockIndexInTexture);
    }

    public void onTick()
    {
        ++this.tickCounter;
        int var1;
        int var2;
        float var3;
        int var5;
        int var6;

        for (var1 = 0; var1 < 16; ++var1)
        {
            for (var2 = 0; var2 < 16; ++var2)
            {
                var3 = 0.0F;

                for (int var4 = var1 - 1; var4 <= var1 + 1; ++var4)
                {
                    var5 = var4 & 15;
                    var6 = var2 & 15;
                    var3 += this.red[var5 + var6 * 16];
                }

                this.green[var1 + var2 * 16] = var3 / 3.3F + this.blue[var1 + var2 * 16] * 0.8F;
            }
        }

        for (var1 = 0; var1 < 16; ++var1)
        {
            for (var2 = 0; var2 < 16; ++var2)
            {
                this.blue[var1 + var2 * 16] += this.alpha[var1 + var2 * 16] * 0.05F;

                if (this.blue[var1 + var2 * 16] < 0.0F)
                {
                    this.blue[var1 + var2 * 16] = 0.0F;
                }

                this.alpha[var1 + var2 * 16] -= 0.1F;

                if (Math.random() < 0.05D)
                {
                    this.alpha[var1 + var2 * 16] = 0.5F;
                }
            }
        }

        float[] var12 = this.green;
        this.green = this.red;
        this.red = var12;

        for (var2 = 0; var2 < 256; ++var2)
        {
            var3 = this.red[var2];

            if (var3 > 1.0F)
            {
                var3 = 1.0F;
            }

            if (var3 < 0.0F)
            {
                var3 = 0.0F;
            }

            float var13 = var3 * var3;
            var5 = (int)(32.0F + var13 * 32.0F);
            var6 = (int)(50.0F + var13 * 64.0F);
            int var7 = 255;
            int var8 = (int)(146.0F + var13 * 50.0F);

            if (this.anaglyphEnabled)
            {
                int var9 = (var5 * 30 + var6 * 59 + var7 * 11) / 100;
                int var10 = (var5 * 30 + var6 * 70) / 100;
                int var11 = (var5 * 30 + var7 * 70) / 100;
                var5 = var9;
                var6 = var10;
                var7 = var11;
            }

            this.imageData[var2 * 4 + 0] = (byte)var5;
            this.imageData[var2 * 4 + 1] = (byte)var6;
            this.imageData[var2 * 4 + 2] = (byte)var7;
            this.imageData[var2 * 4 + 3] = (byte)var8;
        }
    }
}

DazKins

Check out my Dev Blog: http://dazkins.tumblr.com
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Longor1996
« Reply #3 - Posted 2013-02-20 14:12:09 »

They are simply re-uploading the modified texture part into the terrain-texture-atlas on the graphicscard.
And because of performance reasons this happens only if the texture is really modified.
The textures are stored in a way, so they can be directly uploaded to the graphicscard.

The whole thing is very (very) easy to implement if you know how to upload a texture to opengl.

- Longor1996

Sorry for my bad English! That's because i am from Germany.
Offline cylab

JGO Ninja


Medals: 49



« Reply #4 - Posted 2013-02-20 16:56:23 »

I would probably just make a texture atlas aka spritesheet and change the texture coordinates onTick()...

Mathias - I Know What [you] Did Last Summer!
Offline DazKins
« Reply #5 - Posted 2013-02-20 18:31:09 »

They are simply re-uploading the modified texture part into the terrain-texture-atlas on the graphicscard.
And because of performance reasons this happens only if the texture is really modified.
The textures are stored in a way, so they can be directly uploaded to the graphicscard.

The whole thing is very (very) easy to implement if you know how to upload a texture to opengl.

- Longor1996

OK, so how does one go about uploading a texture to OpenGL

I understand you can regenerate the texture and add the glTexImage2d(); function with the pixels array, or is this something different?

DazKins

Check out my Dev Blog: http://dazkins.tumblr.com
Offline Longor1996
« Reply #6 - Posted 2013-02-20 19:36:46 »

Thats correct.
Minecraft simply uploads the updated texture parts per glTexImage2d();

Here is a little code snippet that does the trick (Made by myself a year ago, still using 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  
   /**Updates an GLTexture with the given update Data. (Copys the given BufferedImage into the given texture at the given position.**/
   public static void updateTexture(GLTexture texture,BufferedImage bufferedImage,int x,int y){
      //Create Buffer
          ByteBuffer imageData = ByteBuffer.allocateDirect(bufferedImage.getWidth() * bufferedImage.getHeight() * 4);
           
           //Get values
          int width = bufferedImage.getWidth();
           int height = bufferedImage.getHeight();
           
           //Setup moar Buffers
          int rawPictureBuffer[] = new int[width * height];
           byte outputPictureBuffer[] = new byte[width * height * 4];
           
           //Put the Picture into the Raw Picture Buffer
          bufferedImage.getRGB(0, 0, width, height, rawPictureBuffer, 0, width);
           
           //Go trough the pictures RGBA data and copy it into  the output buffer
          for (int k = 0; k < rawPictureBuffer.length; k++)
           {
         //Get the Color Values
        int i1 = rawPictureBuffer[k] >> 24 & 0xff;
         int k1 = rawPictureBuffer[k] >> 16 & 0xff;
         int i2 = rawPictureBuffer[k] >> 8 & 0xff;
         int k2 = rawPictureBuffer[k] & 0xff;
         
         //Put into Output Buffer
        outputPictureBuffer[k * 4 + 0] = (byte)k1;
         outputPictureBuffer[k * 4 + 1] = (byte)i2;
         outputPictureBuffer[k * 4 + 2] = (byte)k2;
         outputPictureBuffer[k * 4 + 3] = (byte)i1;
      }
     
      //Put the Output Buffer into the ByteBuffer
     imageData.clear();
      imageData.put(outputPictureBuffer);
      imageData.position(0).limit(outputPictureBuffer.length);
     
      texture.bind();
      GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D,0,x,y,width,height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, imageData);
   }


GLTexture is a very small class that i use to store textures.
Shouldn't be hard to make your own version of it.
Also, this code is not the most performant, i did never optimize it because i never use that many animated-textures.

Have fun coding.

- Longor1996


Edit:
Almost forgot: You can easely replace the BufferedImage with a ByteBuffer/Byte-Array/Integer-Array or something.

Sorry for my bad English! That's because i am from Germany.
Offline DazKins
« Reply #7 - Posted 2013-02-20 19:43:34 »

Ahh yes, of course thank you. For some reason i thought glTeximage 2D had to be encapsulated in the textures generation code, thanks a lot!

DazKins

Check out my Dev Blog: http://dazkins.tumblr.com
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

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

The first screenshot will be displayed as a thumbnail.

BurntPizza (19 views)
2014-09-21 02:42:18

BurntPizza (14 views)
2014-09-21 01:30:30

moogie (14 views)
2014-09-21 00:26:15

UprightPath (25 views)
2014-09-20 20:14:06

BurntPizza (27 views)
2014-09-19 03:14:18

Dwinin (40 views)
2014-09-12 09:08:26

Norakomi (73 views)
2014-09-10 13:57:51

TehJavaDev (96 views)
2014-09-10 06:39:09

Tekkerue (49 views)
2014-09-09 02:24:56

mitcheeb (70 views)
2014-09-08 06:06:29
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
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!