Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2 3 4
  ignore  |  Print  
  So you like Textures eh? Texturing Demo in JOGL.  (Read 20840 times)
0 Members and 1 Guest are viewing this topic.
Offline gregorypierce

Senior Duke




I come upon thee like the blue screen of death....


« Posted 2003-07-20 02:13:29 »

So you're back, and you've been wondering why did Greg leave me high and dry when the time came to actually put textures on the screen. Well something unfortunate happened that has been draining my time... I picked up Bioware's Knight's of the Old Republic and everytime I sat down to work on this tutorial, the call of the Jedi order got in the way Smiley But fortunately I've reached a logical stopping point and have determined to finish this tutorial and get you folks going so the next game that I?m obsessed with is written in Java!

The first thing we want to do is come up with a class to encapsulate the texture itself. The reason I created this class is two-fold. First, I wanted to have something that I could quickly grab from a cache if I ever needed to refer to a texture or its information. The other reason I created this class is because there was something similar in LWJGL and I wanted to preserve that functionality so that I didn't have to change too much of my code. The texture class is mostly boilerplate, storing the following properties:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
       private String                          name;
      protected int                           width, height;
      protected int                           textureID;

       protected BufferedImage                 bufferedImage;
      protected int                           target;
      protected int                           srcPixelFormat;
      protected int                           dstPixelFormat;
      protected int                           minFilter;
      protected int                           magFilter;
      protected boolean                       wrap;
       protected boolean                       mipmapped;


One thing of importance for you as an OpenGL developer is the textureID. This is the textureID that you will bind to when you want a certain texture to be active. Also of importance is that the texture has a name. The reason I have a name here won?t be immediately obvious to you, but if you?ve ever dealt with a commercial engine or a real game you will quickly come to respect the value of being able to access and manipulate a texture by its name. Your artists will also like the fact that they can name textures (and when we get to the thing on loaders ? materials) and be able to access them in your tools.

There is only one method in this class that doesn?t deal with the actual texture data, and that is the bind method. This method is what you would call when you want to have that texture active (note I?m only talking about texturing in multipass, I will cover multitexture in the next tutorial).

1  
2  
3  
4  
      protected void bind( GL gl )
      {
            gl.glBindTexture( target, textureID );
      }


Cool, so now you have something that effectively wraps a texture. Now we will add some architecture to better handle textures as a whole. The first thing you will want to do is create your textures. You could set up you access methods such that Textures can be created directly, but from an architectural standpoint, that's not all that great. I have created a class  TextureFactory which has several methods for actually creating these Texture objects.

TextureFactory is a singleton and as such there is only ever one instance of the TextureFactory. If you're not familiar with the Singleton Design Pattern you may want to pick up a book on Design Patterns because it is a very useful and effective pattern and some of my later tutorials will use it and other patterns heavily to reduce the amount of code being written and also to better organize that code in maintainable units.

Anyways, TextureFactory has one method for loading an Image from a file:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
protected BufferedImage loadImage( String resourceName ) throws IOException
    {
        logger.debug("Loading resource [" + resourceName + "]");

        BufferedImage bufferedImage = ImageIO.read( new File( resourceName ));

            // Flip Image
            //
            AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
            tx.translate(0, -bufferedImage.getHeight(null));
            AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
            bufferedImage = op.filter(bufferedImage, null);

        return bufferedImage;
    }



You can see here that we are simply using ImageIO to load the texture data in as a BufferedImage. ImageIO is a fairly efficient way to load texture data from an InputStream. The next section of code you see you may not be familiar with. The section that starts with AffineTransform is flipping the image so that the image data is using the same coordinate system as OpenGL.

The next method of merit is the convertImageData method. This method will convert the BufferedImage into a ByteBuffer that we can use. It is important to note that an OpenGL texture is just a collection of bytes just like it is in C/C++. What we need to do is get this ByteBuffer organized in the right format so that when we render the texture we don't get some gibberish. In a later version of the code you will see some of this section of code change, but I wanted to keep this simple so you could understand what?s going on so that you can be empowered enough to experiment and do cool things on your own.

http://www.gregorypierce.com

She builds, she builds oh man
When she links, she links I go crazy
Cause she looks like good code but she's really a hack
I think I'll run upstairs and grab a snack!
Offline gregorypierce

Senior Duke




I come upon thee like the blue screen of death....


« Reply #1 - Posted 2003-07-20 02:15:07 »

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  
protected ByteBuffer convertImageData( BufferedImage bufferedImage ) throws TextureFormatException
    {
        ByteBuffer imageBuffer = null;

        switch( bufferedImage.getType() )
        {
            case BufferedImage.TYPE_3BYTE_BGR:
                {
                    byte[] data = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
                    imageBuffer = ByteBuffer.allocateDirect( data.length );
                    imageBuffer.order(ByteOrder.nativeOrder());
                    imageBuffer.put( data, 0, data.length );
                    break;
                }

            case BufferedImage.TYPE_INT_RGB:
                {
                    int[] data = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData();
                    imageBuffer.order(ByteOrder.nativeOrder());
                    imageBuffer.asIntBuffer().put(data, 0, data.length);
                    break;
                }

            default:
                throw new TextureFormatException("Unsupported image type " + bufferedImage.getType() );
        }


        return imageBuffer;
    }


Take a look at what's going on in the case statement. We're taking a look at the BufferedImages pixelformat and based on what type of format it has, we create the correct ByteBuffer. Finally, if we don't support that texture format - we throw a meaningful exception so that we can catch it.

Now for the moment you've been waiting for, when you finally create that Texture. This is handled in the, wait for it, createTexture method.

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  
      public Texture createTexture(       String name,
                                    String resourceName,
                                    int target,
                                    int srcPixelFormat,
                                    int dstPixelFormat,
                                    int minFilter,
                                    int magFilter,
                                    boolean wrap,
                                    boolean mipmapped ) throws IOException, TextureFormatException
      {
        logger.debug("Creating texture [" + name + "],[" + resourceName + "]");

          Texture texture = new Texture( name, target, srcPixelFormat, dstPixelFormat, minFilter, magFilter, wrap, mipmapped );


        // create the texture ID for this texture
        //
        int textureID = createTextureID();
        texture.setTextureID( textureID );

        // bind this texture
        //
        gl.glBindTexture(GL.GL_TEXTURE_2D, textureID );

        // load the buffered image for this resource - save a copy to we can draw into it later
        //
        BufferedImage bufferedImage = loadImage( resourceName );
        texture.setBufferedImage( bufferedImage );

        // convert that image into a byte buffer of texture data
        //
        ByteBuffer textureBuffer = convertImageData( bufferedImage );

            // set up the texture wrapping mode depending on whether or not
            // this texture is specified for wrapping or not
            //
            int wrapMode = wrap ? GL.GL_REPEAT : GL.GL_CLAMP;

            if ( target == GL.GL_TEXTURE_2D )
            {
                  gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, wrapMode);
                  gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, wrapMode);
                  gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, minFilter);
                  gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, magFilter);
            }

        // create either a series of mipmaps of a single texture image based on what's loaded
        //
        if ( mipmapped )
        {
            glu.gluBuild2DMipmaps( target,
                                   dstPixelFormat,
                                   bufferedImage.getWidth(),
                                   bufferedImage.getHeight(),
                                   srcPixelFormat,
                                   GL.GL_UNSIGNED_BYTE,
                                   textureBuffer );
        }
        else
        {
            gl.glTexImage2D(target,
                          0,
                          dstPixelFormat,
                          bufferedImage.getWidth(),
                          bufferedImage.getHeight(),
                          0,
                          srcPixelFormat,
                          GL.GL_UNSIGNED_BYTE,
                          textureBuffer );
        }

            return texture;
      }


This is a really boring method, except that it does everything you need. This is all OpenGL goodness so I won't explain too much of what's going on here except to say that if you have questions - please ask and I'll update.

Now for the final piece of architecture, the TextureManager. Having a TextureFactory that can create Texture objects is cool and all, but I wanted to be able to manage textures in an easier way. TextureManager contains an instance of the TextureFactory so you can say that it acts as a Façade (those Design Patterns again) for TextureFactory. The only class that you the developer would interact with is the TextureManager. The methods that you?d be using are createTexture() which calls the createTexture of the factory, createManagedTexture() which creates the texture and stores that Texture object , bindTexture() makes the named texture resident, and updateTexture() allows you to update the data that a texture refers to by uploading a new BufferedImage to it.

http://www.gregorypierce.com

She builds, she builds oh man
When she links, she links I go crazy
Cause she looks like good code but she's really a hack
I think I'll run upstairs and grab a snack!
Offline gregorypierce

Senior Duke




I come upon thee like the blue screen of death....


« Reply #2 - Posted 2003-07-20 02:16:09 »

So that pretty much wraps up the architecture pieces. So how do you use it? We update our init() method to instantiate the TextureManager and create our texture(s).

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
public void init(GLDrawable drawable)
    {
        this.gl = drawable.getGL();
        this.glu = drawable.getGLU();
        this.glDrawable = drawable;


        this.glDrawable.setGL( new DebugGL(drawable.getGL() ));
        this.textureManager = TextureManager.getInstance( gl, glu );

        gl.glEnable( GL.GL_TEXTURE_2D );
        gl.glShadeModel( GL.GL_SMOOTH );

        try
        {
            textureManager.createManagedTexture("foo", "data/nehe.png", GL.GL_TEXTURE_2D, GL.GL_RGB, GL.GL_RGB, GL.GL_LINEAR, GL.GL_LINEAR, true, false );
        }
        catch( Exception e )
        {
            logger.error("Unable to load texture", e );
        }

        System.out.println("Init GL is " + gl.getClass().getName());
    }


And finally, the update to the display method where the texture is being bound for drawing and the texture being drawn.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
public void display(GLDrawable drawable)
    {
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
        gl.glLoadIdentity();

        gl.glColor3f(1.0f, 0.0f, 0.0f );

        textureManager.bindTexture("foo");


        gl.glBegin( GL.GL_TRIANGLES );

            gl.glTexCoord2f( 0.0f, 0.0f );
            gl.glVertex3f( 0.0f, 0.0f, 0.0f );

            gl.glTexCoord2f( 1.0f, 0.0f );
            gl.glVertex3f( 1.0f, 0.0f, 0.0f );

            gl.glTexCoord2f( 1.0f, 1.0f );
            gl.glVertex3f( 1.0f, 1.0f, 0.0f );
        gl.glEnd();
    }


And there you have it. One textured triangle.

http://www.gregorypierce.com

She builds, she builds oh man
When she links, she links I go crazy
Cause she looks like good code but she's really a hack
I think I'll run upstairs and grab a snack!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline gregorypierce

Senior Duke




I come upon thee like the blue screen of death....


« Reply #3 - Posted 2003-07-20 02:18:04 »

Texture.java

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  
import net.java.games.jogl.GL;
import org.apache.log4j.Logger;

import java.awt.image.BufferedImage;

public class Texture
{
      private static Logger                            logger = Logger.getLogger("Texture");

    private String                          name;
      protected int                           width, height;
      protected int                           textureID;

    protected BufferedImage                 bufferedImage;
      protected int                           target;
      protected int                           srcPixelFormat;
      protected int                           dstPixelFormat;
      protected int                           minFilter;
      protected int                           magFilter;
      protected boolean                       wrap;
    protected boolean                       mipmapped;

      public Texture( String name, int target, int srcPixelFormat,
                          int dstPixelFormat, int minFilter, int magFilter,
                    boolean wrap, boolean mipmapped)
      {
            this.name = name;
            this.target = target;
            this.srcPixelFormat = srcPixelFormat;
            this.dstPixelFormat = dstPixelFormat;
            this.minFilter = minFilter;
            this.magFilter = magFilter;
            this.wrap = wrap;
        this.mipmapped = mipmapped;
      }

      public String getName()
      {
            return name;
      }

      public void setName(String name)
      {
            this.name = name;
      }

    public BufferedImage getBufferedImage()
    {
        return bufferedImage;
    }

    public void setBufferedImage(BufferedImage bufferedImage)
    {
        this.bufferedImage = bufferedImage;
    }

      public int getWidth()
      {
            return width;
      }

      public void setWidth(int width)
      {
            this.width = width;
      }

      public int getHeight()
      {
            return height;
      }

      public void setHeight(int height)
      {
            this.height = height;
      }

      public int getTextureID()
      {
            return textureID;
      }

      public void setTextureID(int textureID)
      {
            this.textureID = textureID;
      }

      public int getTarget()
      {
            return target;
      }

      public void setTarget(int target)
      {
            this.target = target;
      }

      public int getSrcPixelFormat()
      {
            return srcPixelFormat;
      }

      public void setSrcPixelFormat(int srcPixelFormat)
      {
            this.srcPixelFormat = srcPixelFormat;
      }

      public int getDstPixelFormat()
      {
            return dstPixelFormat;
      }

      public void setDstPixelFormat(int dstPixelFormat)
      {
            this.dstPixelFormat = dstPixelFormat;
      }

      public int getMinFilter()
      {
            return minFilter;
      }

      public void setMinFilter(int minFilter)
      {
            this.minFilter = minFilter;
      }

      public int getMagFilter()
      {
            return magFilter;
      }

      public void setMagFilter(int magFilter)
      {
            this.magFilter = magFilter;
      }

      public boolean isWrap()
      {
            return wrap;
      }

      public void setWrap(boolean wrap)
      {
            this.wrap = wrap;
      }

    public boolean isMipmapped()
    {
        return mipmapped;
    }

    public void setMipmapped(boolean mipmapped)
    {
        this.mipmapped = mipmapped;
    }

      protected void bind( GL gl )
      {
            gl.glBindTexture( target, textureID );
      }

}

http://www.gregorypierce.com

She builds, she builds oh man
When she links, she links I go crazy
Cause she looks like good code but she's really a hack
I think I'll run upstairs and grab a snack!
Offline gregorypierce

Senior Duke




I come upon thee like the blue screen of death....


« Reply #4 - Posted 2003-07-20 02:19:06 »

TextureFactory.java

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  
import net.java.games.jogl.GL;
import net.java.games.jogl.GLU;
import org.apache.log4j.Logger;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.AffineTransformOp;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class TextureFactory
{
    private static Logger           logger = Logger.getLogger("TextureFactory");
    private static TextureFactory   instance;


    private GLU                     glu;
    private GL                      gl;

    protected TextureFactory( GL gl, GLU glu )
    {
        this.gl = gl;
        this.glu = glu;
    }

    public static synchronized TextureFactory getFactory( GL gl, GLU glu )
    {
        if ( instance == null )
        {
            instance = new TextureFactory( gl, glu );
        }

        return instance;

    }

    protected BufferedImage loadImage( String resourceName ) throws IOException
    {
        logger.debug("Loading resource [" + resourceName + "]");

        BufferedImage bufferedImage = ImageIO.read( new File( resourceName ));

            // Flip Image
            //
            AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
            tx.translate(0, -bufferedImage.getHeight(null));
            AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
            bufferedImage = op.filter(bufferedImage, null);

        return bufferedImage;
        //return  ImageIO.read( getClass().getClassLoader().getResourceAsStream( resourceName ));
    }

    protected ByteBuffer convertImageData( BufferedImage bufferedImage ) throws TextureFormatException
    {
        ByteBuffer imageBuffer = null;

        switch( bufferedImage.getType() )
        {
            case BufferedImage.TYPE_3BYTE_BGR:
            case BufferedImage.TYPE_CUSTOM:
                {
                    byte[] data = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
                    imageBuffer = ByteBuffer.allocateDirect( data.length );
                    imageBuffer.order(ByteOrder.nativeOrder());
                    imageBuffer.put( data, 0, data.length );
                    break;
                }

            case BufferedImage.TYPE_INT_RGB:
                {
                    int[] data = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData();
                    imageBuffer.order(ByteOrder.nativeOrder());
                    imageBuffer.asIntBuffer().put(data, 0, data.length);
                    break;
                }

            default:
                throw new TextureFormatException("Unsupported image type " + bufferedImage.getType() );
        }


        return imageBuffer;
    }

    protected int createTextureID()
    {
        int[] tmp = new int[1];
        gl.glGenTextures(1, tmp);
        return tmp[0];
    }

      public Texture createTexture(       String name,
                                    String resourceName,
                                    int target,
                                    int srcPixelFormat,
                                    int dstPixelFormat,
                                    int minFilter,
                                    int magFilter,
                                    boolean wrap,
                                    boolean mipmapped ) throws IOException, TextureFormatException
      {
        logger.debug("Creating texture [" + name + "],[" + resourceName + "]");

          Texture texture = new Texture( name, target, srcPixelFormat, dstPixelFormat, minFilter, magFilter, wrap, mipmapped );


        // create the texture ID for this texture
        //
        int textureID = createTextureID();
        texture.setTextureID( textureID );

        // bind this texture
        //
        gl.glBindTexture(GL.GL_TEXTURE_2D, textureID );

        // load the buffered image for this resource - save a copy to we can draw into it later
        //
        BufferedImage bufferedImage = loadImage( resourceName );
        texture.setBufferedImage( bufferedImage );

        // convert that image into a byte buffer of texture data
        //
        ByteBuffer textureBuffer = convertImageData( bufferedImage );

            // set up the texture wrapping mode depending on whether or not
            // this texture is specified for wrapping or not
            //
            int wrapMode = wrap ? GL.GL_REPEAT : GL.GL_CLAMP;

            if ( target == GL.GL_TEXTURE_2D )
            {
                  gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, wrapMode);
                  gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, wrapMode);
                  gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, minFilter);
                  gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, magFilter);
            }

        // create either a series of mipmaps of a single texture image based on what's loaded
        //
        if ( mipmapped )
        {
            glu.gluBuild2DMipmaps( target,
                                   dstPixelFormat,
                                   bufferedImage.getWidth(),
                                   bufferedImage.getHeight(),
                                   srcPixelFormat,
                                   GL.GL_UNSIGNED_BYTE,
                                   textureBuffer );
        }
        else
        {
            gl.glTexImage2D(target,
                          0,
                          dstPixelFormat,
                          bufferedImage.getWidth(),
                          bufferedImage.getHeight(),
                          0,
                          srcPixelFormat,
                          GL.GL_UNSIGNED_BYTE,
                          textureBuffer );
        }

            return texture;
      }

    public void updateTexture( Texture texture, BufferedImage bufferedImage ) throws TextureFormatException
    {
        logger.debug("Updating texture [" + texture.getName() + "]");


        // bind this texture
        //
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture.getTextureID() );

        ByteBuffer textureBuffer = convertImageData( bufferedImage );

        // create either a series of mipmaps of a single texture image based on what's loaded
        //
        if ( texture.isMipmapped() )
        {
            glu.gluBuild2DMipmaps( texture.getTarget(),
                                   texture.getDstPixelFormat(),
                                   bufferedImage.getWidth(),
                                   bufferedImage.getHeight(),
                                   texture.getSrcPixelFormat(),
                                   GL.GL_UNSIGNED_BYTE,
                                   textureBuffer );
        }
        else
        {
            gl.glTexImage2D(texture.getTarget(),
                          0,
                          texture.getDstPixelFormat(),
                          bufferedImage.getWidth(),
                          bufferedImage.getHeight(),
                          0,
                          texture.getSrcPixelFormat(),
                          GL.GL_UNSIGNED_BYTE,
                          textureBuffer );
        }
    }

}

http://www.gregorypierce.com

She builds, she builds oh man
When she links, she links I go crazy
Cause she looks like good code but she's really a hack
I think I'll run upstairs and grab a snack!
Offline gregorypierce

Senior Duke




I come upon thee like the blue screen of death....


« Reply #5 - Posted 2003-07-20 02:22:12 »

TextureFormatException.java

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
public class TextureFormatException extends Exception
{
    public TextureFormatException()
    {
        super();
    }

    public TextureFormatException( String msg )
    {
        super( msg );
    }
}


TextureManager.java

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  
import net.java.games.jogl.GL;
import net.java.games.jogl.GLU;
import org.apache.log4j.Logger;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class TextureManager
{
      private static Logger                                  logger = Logger.getLogger("TextureManager");

      private GL                                                    gl;
      private GLU                                                    glu;

    private Map                                 textures = new HashMap();
    private TextureFactory                      textureFactory;

    private static TextureManager               instance;

      protected TextureManager( GL gl, GLU glu )
      {
            this.gl = gl;
            this.glu = glu;

        textureFactory = TextureFactory.getFactory( gl, glu );
      }

    public static synchronized TextureManager getInstance( GL gl, GLU glu )
    {
        if ( instance == null )
        {
            instance = new TextureManager( gl, glu );
        }

        return instance;
    }

      public void bindTexture( String name )
      {
            ((Texture)textures.get( name )).bind(gl);
      }

    public void updateTexture( String name, BufferedImage image ) throws TextureFormatException
    {
        textureFactory.updateTexture( (Texture)textures.get( name ), image );
    }

    public void manageTexture( Texture texture )
    {
        logger.debug("Managing texture [" + texture.getName() + "]" );

        textures.put( texture.getName(), texture );
    }

      public Texture createTexture(       String name,
                                    String resourceName,
                                    int target,
                                    int srcPixelFormat,
                                    int dstPixelFormat,
                                    int minFilter,
                                    int magFilter,
                                    boolean wrap,
                                    boolean mipmapped ) throws IOException, TextureFormatException
    {
        return textureFactory.createTexture( name, resourceName, target, srcPixelFormat,
                                      dstPixelFormat, minFilter, magFilter, wrap, mipmapped );
    }

      public Texture createManagedTexture(       String name,
                                            String resourceName,
                                            int target,
                                            int srcPixelFormat,
                                            int dstPixelFormat,
                                            int minFilter,
                                            int magFilter,
                                            boolean wrap,
                                            boolean mipmapped ) throws IOException, TextureFormatException
    {
        Texture texture = textureFactory.createTexture( name, resourceName, target, srcPixelFormat,
                                                        dstPixelFormat, minFilter, magFilter, wrap, mipmapped );

        manageTexture( texture );

        return texture;
    }

}

http://www.gregorypierce.com

She builds, she builds oh man
When she links, she links I go crazy
Cause she looks like good code but she's really a hack
I think I'll run upstairs and grab a snack!
Offline gregorypierce

Senior Duke




I come upon thee like the blue screen of death....


« Reply #6 - Posted 2003-07-20 02:24:02 »

TestRenderer.java

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  
import com.sojournermobile.engine.texture.TextureManager;
import net.java.games.jogl.*;
import org.apache.log4j.Logger;

public class TestRenderer implements GLEventListener
{
    private static Logger               logger = Logger.getLogger("TestRenderer");
    private GL                          gl;
    private GLU                         glu;
    private GLDrawable                  glDrawable;
    private TextureManager              textureManager;

    public void init(GLDrawable drawable)
    {
        this.gl = drawable.getGL();
        this.glu = drawable.getGLU();
        this.glDrawable = drawable;


        this.glDrawable.setGL( new DebugGL(drawable.getGL() ));
        this.textureManager = TextureManager.getInstance( gl, glu );

        gl.glEnable( GL.GL_TEXTURE_2D );
        gl.glShadeModel( GL.GL_SMOOTH );

        try
        {
            textureManager.createManagedTexture("foo", "data/nehe.png", GL.GL_TEXTURE_2D, GL.GL_RGB, GL.GL_RGB, GL.GL_LINEAR, GL.GL_LINEAR, true, false );
        }
        catch( Exception e )
        {
            logger.error("Unable to load texture", e );
        }

        System.out.println("Init GL is " + gl.getClass().getName());
    }

    public void display(GLDrawable drawable)
    {
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
        gl.glLoadIdentity();

        gl.glColor3f(1.0f, 0.0f, 0.0f );

        textureManager.bindTexture("foo");


        gl.glBegin( GL.GL_TRIANGLES );

            gl.glTexCoord2f( 0.0f, 0.0f );
            gl.glVertex3f( 0.0f, 0.0f, 0.0f );

            gl.glTexCoord2f( 1.0f, 0.0f );
            gl.glVertex3f( 1.0f, 0.0f, 0.0f );

            gl.glTexCoord2f( 1.0f, 1.0f );
            gl.glVertex3f( 1.0f, 1.0f, 0.0f );
        gl.glEnd();
    }

    public void reshape(GLDrawable drawable, int x, int y, int width, int height)
    {
    }

    public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged)
    {
    }

}

http://www.gregorypierce.com

She builds, she builds oh man
When she links, she links I go crazy
Cause she looks like good code but she's really a hack
I think I'll run upstairs and grab a snack!
Offline AndersDahlberg

Junior Duke





« Reply #7 - Posted 2003-07-20 09:58:44 »

This is great  Grin

Some feedback, I guess the TextureManager will be used by a lot of opengl (me included Wink and/or java newbies so maybe it would be a good idea to include some assert's in the most important methods to catch common misstakes? I guess you guru's can probably figure out real quick where most misstakes might happen!
Offline aNt

Senior Duke




AFK


« Reply #8 - Posted 2003-07-20 11:11:02 »

will this work with all sort of pixel formats (from the input texture). is there a way of setting the texture fast! as in if i wanted to do a movie texture.

just wondered if i could make a QuickTime texture. i can get a BufferedImage from QuickTime- bit slow mind.

arrrr- i will try it- thanks for your texture code dude. its loads neater then mine Smiley.
Offline gregorypierce

Senior Duke




I come upon thee like the blue screen of death....


« Reply #9 - Posted 2003-07-20 12:11:42 »

Quote
This is great  Grin

Some feedback, I guess the TextureManager will be used by a lot of opengl (me included Wink and/or java newbies so maybe it would be a good idea to include some assert's in the most important methods to catch common misstakes? I guess you guru's can probably figure out real quick where most misstakes might happen!


Thanks for your feedback,

You're right. I will take a look at the best place to add assertions and NPE checks and update this code. The next version of this code will include multitexture unit multitexturing.

http://www.gregorypierce.com

She builds, she builds oh man
When she links, she links I go crazy
Cause she looks like good code but she's really a hack
I think I'll run upstairs and grab a snack!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline gregorypierce

Senior Duke




I come upon thee like the blue screen of death....


« Reply #10 - Posted 2003-07-20 12:14:55 »

Quote
will this work with all sort of pixel formats (from the input texture). is there a way of setting the texture fast! as in if i wanted to do a movie texture.

just wondered if i could make a QuickTime texture. i can get a BufferedImage from QuickTime- bit slow mind.

arrrr- i will try it- thanks for your texture code dude. its loads neater then mine Smiley.


Thanks for your feedback.

It won't work with all of the pixel formats yet, but I'm working on that right now and within the next few days I should have the bulk of the formats covered as well as an example that would handle animation from a series of textures to do movie stuff. It won't really touch on using QuickTime movies per say (but you should be able to get the goods from the QuickTime for java classes) since Linux doesn't support it (QT4J), but at the end of that demo you will be able to make an OpenGL media player pretty easily.

http://www.gregorypierce.com

She builds, she builds oh man
When she links, she links I go crazy
Cause she looks like good code but she's really a hack
I think I'll run upstairs and grab a snack!
Offline aNt

Senior Duke




AFK


« Reply #11 - Posted 2003-07-20 15:00:57 »

top dude!

YUV would be cool Wink - get realtime textures from video input then. guess JMF would cover that also. wonder how fast it would be? i use QT4J because it works well with all media formats [also media devices]. but indeed its not a happy Lunix world..

i will play with it today see where i get. JMF is prob better when it comes to crossplatform- wonder how good JMF is on MacOSX mind Wink

cheers dude - top stuff if we had a all image loader.. u the man...
Offline gregorypierce

Senior Duke




I come upon thee like the blue screen of death....


« Reply #12 - Posted 2003-07-20 18:09:33 »

JMF and OSX Huh Smiley Will be funny that at least for the little tidbits we're supporting, we'll be more crossplatform than Sun's own standard API. It has always always surprised me that an engine like JOGL isn't what all of the Sun GUI infrastructure sits on top of. If it would have been designed that way from the start, Java would already be hardware accelerated and there would have been large games in Java ages ago.

http://www.gregorypierce.com

She builds, she builds oh man
When she links, she links I go crazy
Cause she looks like good code but she's really a hack
I think I'll run upstairs and grab a snack!
Offline aNt

Senior Duke




AFK


« Reply #13 - Posted 2003-07-20 18:31:19 »

i second that!  Grin
Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #14 - Posted 2003-07-21 01:26:04 »

Since Sun is working on OpenGL acceleration for Swing on Linux, I wonder  why not use JOGL as the binding and ditch the DirectX acceleration on Windows.  They will end up sharing more code between implementations and JOGL will get more attention.  Not to mention that would pull JOGL into the core JRE.

Actually there are probably a lot of internal Sun policies that would make JOGL in the core more of a drawback... The "core" JOGL certainly wouldn't change
(as in new features & fixes) as often as what we have now if that were the case.

8: Undefined index: online
File: /home/jgo/public_html/Themes/default/Display.template.php (main sub template - eval?)
Line: 161