1D Texture with OpenGL or Cg Shader

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

1D Texture with OpenGL or Cg Shader

rullie
Hi folks,

    I am really dumbstruck by this. But I cannot seem to get it to work: How do I get 1D texture to work...

    I use this code to create/bind the texture:

       public static int allocateTexture(GL2 gl, Buffer textureBuffer){
                gl.glPixelStorei(GL2.GL_UNPACK_ALIGNMENT, 1);
               
                int numberOfTextures = 1;
                int textureName;
                IntBuffer texturesNames = IntBuffer.allocate(numberOfTextures);
                gl.glGenTextures(numberOfTextures, texturesNames);
                textureName = texturesNames.get(0);
               
                gl.glBindTexture(GL2.GL_TEXTURE_1D, textureName);
                gl.glTexImage1D(GL2.GL_TEXTURE_1D, 0, GL2.GL_RGBA, textureBuffer.capacity()/4, 0, GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE, textureBuffer);
                gl.glTexParameteri(GL2.GL_TEXTURE_1D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_REPEAT);
                gl.glTexParameteri(GL2.GL_TEXTURE_1D, GL2.GL_TEXTURE_MIN_FILTER,GL2.GL_LINEAR_MIPMAP_LINEAR);
                gl.glTexParameteri(GL2.GL_TEXTURE_1D, GL2.GL_TEXTURE_MAG_FILTER,GL2.GL_LINEAR_MIPMAP_LINEAR);
                gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE);
                gl.glEnable(GL2.GL_TEXTURE_GEN_S);
                gl.glEnable(GL2.GL_TEXTURE_1D);

                return textureName;
        }


   And I use this code to generate the texture:

  public static ByteBuffer getTerrainTextureBuffer(){
                int textureLength = 32;
                ByteBuffer buffer = ByteBuffer.allocateDirect(textureLength*4);
                byte[] texture = new byte[textureLength*4];
                for( int i = 0; i < texture.length-3; i+=4 ){
                        if( (i % 10) == 0 ){
                                texture[i] = (byte)(255 & 0xFF);
                                texture[i+1] = 0;
                                texture[i+2] = 0;
                                texture[i+3] = (byte)(255 & 0xFF);
                        }else{
                                texture[i] = (byte)(255 & 0xFF);
                                texture[i+1] = 0;
                                texture[i+2] = 0;
                                texture[i+3] = (byte)(255 & 0xFF);
                        }
                }
                buffer.put( texture );
                buffer.rewind();
               
                return buffer;
        }



The resulting render does not have any red on it.  Any help would be appreciated.

Regards,
Rullie
Reply | Threaded
Open this post in threaded view
|

Re: 1D Texture with OpenGL or Cg Shader

Demoscene Passivist
Administrator
I havent checked the specific code u submitted but it is generally a bad, error prone idea to use direct ByteBuffer to generate a texture.

I would recommend using com.jogamp.opengl.util.awt.TextureRenderer if u want to algorithmically generate a texture. Its really easy to use and frees u from the burden of moving the pixel bytes by hand, and as far as I can see in ur code theres no reason why u must use the direct ByteBuffer stuff.
Reply | Threaded
Open this post in threaded view
|

Re: 1D Texture with OpenGL or Cg Shader

rullie
Thanks for the tip.
Reply | Threaded
Open this post in threaded view
|

Re: 1D Texture with OpenGL or Cg Shader

Demoscene Passivist
Administrator
Sorry, I guess I was wrong when pointing u to using the TextureRenderer for a 1D texture.

Yesterday I got the problem myself while trying to generate a look-up-table (LUT) for use in a fragment shader. U were absolutly right when trying to generate the 1D texture using the direct ByteBuffer stuff. Using TextureRenderer to generate a 1D texture is possible, but its really a pain in the ass to use in that way. The TextureRenderer API is really way to complicated to handle for the puropose of a 1D texture.

So here's the code I used to convert a BufferedImage to a ByteBuffer:

    public static ByteBuffer convertARGBBufferedImageToJOGLRGBADirectByteBuffer(BufferedImage inBufferedImage) {
        ByteBuffer tBufferedImageByteBuffer = ByteBuffer.allocateDirect(inBufferedImage.getWidth()*inBufferedImage.getHeight()*4);
        tBufferedImageByteBuffer.order(ByteOrder.nativeOrder());
        int[] tBufferedImage_ARGB = ((DataBufferInt)inBufferedImage.getRaster().getDataBuffer()).getData();
        for (int i=0; i<tBufferedImage_ARGB.length; i++) {          
            byte tRed   = (byte)((tBufferedImage_ARGB[i] >> 16) & 0xFF);
            byte tGreen = (byte)((tBufferedImage_ARGB[i] >>  8) & 0xFF);
            byte tBlue  = (byte)((tBufferedImage_ARGB[i]      ) & 0xFF);
            byte tAlpha = (byte)((tBufferedImage_ARGB[i] >> 24) & 0xFF);
            tBufferedImageByteBuffer.put(tRed);
            tBufferedImageByteBuffer.put(tGreen);
            tBufferedImageByteBuffer.put(tBlue);
            tBufferedImageByteBuffer.put(tAlpha);
        }
        tBufferedImageByteBuffer.rewind();
        return tBufferedImageByteBuffer;
    }

... and after the conversion u can easily set up a 1D texture using the following snippet:

    public static int generateTexture1DFromBufferedImage(GL2 inGL,BufferedImage inBufferedImage) {
        inGL.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        int tLUTTextureID = TextureUtils.generateTextureID(inGL);
        inGL.glEnable(GL_TEXTURE_1D);
        inGL.glBindTexture(GL_TEXTURE_1D, tLUTTextureID);
        inGL.glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, inBufferedImage.getWidth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, convertARGBBufferedImageToJOGLRGBADirectByteBuffer(inBufferedImage));
        inGL.glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        inGL.glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        inGL.glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_WRAP_S,GL_CLAMP);
        inGL.glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_WRAP_T,GL_CLAMP);
        return tLUTTextureID;
    }

... hope that u got it working in the meantime or at least know now how to get it working using the code snippets from above.
Reply | Threaded
Open this post in threaded view
|

Re: 1D Texture with OpenGL or Cg Shader

Michael Bien
  On 09/13/2010 03:55 AM, Demoscene Passivist [via jogamp] wrote:
>   Using TextureRenderer to generate a 1D texture is possible, but its
> really a pain in the ass to use in that way. The TextureRenderer API
> is really way to complicated to handle for the puropose of a 1D texture.
what methods are missing? We could add a few shortcuts...

--
- - - -
http://michael-bien.com

Reply | Threaded
Open this post in threaded view
|

Re: 1D Texture with OpenGL or Cg Shader

Demoscene Passivist
Administrator
>what methods are missing? We could add a few shortcuts...

Cool, modifying/extending the API would be really helpful here. Let me explain where the problem lies:

In the TextureRenderer API theres no way to set the texture target. It implicitly generates a GL_TEXTURE_2D Texture internally wich u can obtained via getTexture() . Ok, then I got the Texture and tried to modifiy the target to GL_TEXTURE_1D directly. But in the Texture API theres only a getTarget() method. So I dug deeper into the rabbithole and tried to change the target via updateImage(TextureData data, int target) using a custom generated TextureData object. But that more or less failed because the constructor for TextureData wants the data as NIO Buffer. And so here we are going round in circles juggling around with Buffers what we wanted to avoid in the first place when using TextureRenderer ...

So my suggestion for TextureRenderer is: Add a method to directly change the texture target e.g. "setTarget(int inTarget)". For the sake of encapslation this maybe put into the Texture class and two "higher-level" functions e.g. "setTexture1D()" "setTexture2D()" could be added to the TextureRenderer API.
Reply | Threaded
Open this post in threaded view
|

Re: 1D Texture with OpenGL or Cg Shader

Sven Gothel
Administrator
On Monday, September 13, 2010 14:00:16 Demoscene Passivist [via jogamp] wrote:

>
> >what methods are missing? We could add a few shortcuts...
>
> Cool, modifying/extending the API would be really helpful here. Let me
> explain where the problem lies:
>
> In the TextureRenderer API theres no way to set the texture target. It
> implicitly generates a GL_TEXTURE_2D Texture internally wich u can obtained
> via getTexture() . Ok, then I got the Texture and tried to modifiy the
> target to GL_TEXTURE_1D directly. But in the Texture API theres only a
> getTarget() method. So I dug deeper into the rabbithole and tried to change
> the target via updateImage(TextureData data, int target) using a custom
> generated TextureData object. But that more or less failed because the
> constructor for TextureData wants the data as NIO Buffer. And so here we are
> going round in circles juggling around with Buffers what we wanted to avoid
> in the first place when using TextureRenderer ...
>
> So my suggestion for TextureRenderer is: Add a method to directly change the
> texture target e.g. "setTarget(int inTarget)". For the sake of encapslation
> this maybe put into the Texture class and two "higher-level" functions e.g.
> "setTexture1D()" "setTexture2D()" could be added to the TextureRenderer API.

sounds very reasonable, looking forward to reviewing your pull request.
thx a lot.

damn .. now I have to order those t-shirts ! :)
thx for those too!

~Sven