Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Playing with ARB_direct_state_access

  1. #1
    Junior Member Newbie
    Join Date
    Dec 2009
    Location
    Greece
    Posts
    18

    Playing with ARB_direct_state_access

    I am trying to write my code with extension ARB_direct_state_access (core in 4.5) and a fall-back in pre-ARB_direct_state_access times.

    So, I have the texture loading functions, which work.

    To render, I must run the old code: (when I run this code, texture appears).
    Code :
    glActiveTexture(GL_TEXTURE0 + unit);
    gl.glBindTexture(target, texture);

    Or the new code: (when I run this code, texture doesn't appear).
    Code :
    glBindTextureUnit(GL_TEXTURE0 + unit, texture);

    What is wrong, with this? Is n't glBindTextureUnit() enough for rendering?

    I include the full code:

    Texture.java
    Code :
    public class Texture implements Release {
        public Texture() {
            int a[] = new int[1];
            gl.glGenTextures(1, a, 0);
            texture = a[0];
        }
        protected Texture(int tex) { texture = tex; }
        @Override public void release() { gl.glDeleteTextures(1, new int[] { texture }, 0); }
     
        public final int texture;
     
        /** Bind texture to texture target.
         * @param target texture target like GL_TEXTURE_2D. */
        public void bindToTarget(int target) { gl.glBindTexture(target, texture); }
        /** Bind texture to texture unit.
         * @param unit index of the texture unit. */
        public void bindToUnit(int unit) { gl.glBindTextureUnit(GL_TEXTURE0 + unit, texture); }
        /** Set active texture unit.
         * @param unit index of the texture unit. */
        static public void setActiveUnit(int unit) { gl.glActiveTexture(GL_TEXTURE0 + unit); }
        static public float getFloat(int pname) {
            float[] ret = new float[1];
            gl.glGetFloatv(pname, ret, 0);
            return ret[0];
        }
        static public int getInteger(int pname) {
            int[] ret = new int[1];
            gl.glGetIntegerv(pname, ret, 0);
            return ret[0];
        }
     
        static public class Config {
            /** Max supported anisotropy from device. At least 1.f */
            private static float max_anisotropy = 0;
            /** Get max supported anisotropy from device.
             * @return max anisotropy. 1.f means no anisotropy available. */
            public static float getMaxAnisotropy() {
                if (max_anisotropy == 0) {
                    max_anisotropy = getFloat(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
                    if (max_anisotropy < 1.0f) max_anisotropy = 1.0f;
                }
                return max_anisotropy;
            }
            /** Texture anisotropy for request.
             * Must be lower than getMaxAnisotropy(). No anisotropy is 1.f */
            public float anisotropy = getMaxAnisotropy();
            //public int magnify = GL_LINEAR;    // default
            //public int minify = GL_LINEAR_MIPMAP_LINEAR;    // not default
            //public int edgePolicy = GL_REPEAT;    //default
            /** Skip higher mipmap levels.
             * e.g if 3, skip levels 4*4 and higher. Default 0. */
            public int skip_last_levels = 0;
     
            /** Edge policy of texture coordinate s. */
            public int s_edge = GL_CLAMP_TO_EDGE;
            /** Edge policy of texture coordinate t. */
            public int t_edge = GL_CLAMP_TO_EDGE;
            /** Edge policy of texture coordinate r. */
            public int r_edge = GL_CLAMP_TO_EDGE;
            /** Border color for texture, if it has border. */
            public int border;
     
            public void textureParameters(int texture) {
                //default: gl.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                gl.glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                gl.glTextureParameterf(texture, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
                gl.glTextureParameteri(texture, GL_TEXTURE_WRAP_S, s_edge);
                gl.glTextureParameteri(texture, GL_TEXTURE_WRAP_T, t_edge);
                gl.glTextureParameteri(texture, GL_TEXTURE_WRAP_R, r_edge);
                gl.glTextureParameterfv(texture, GL_TEXTURE_BORDER_COLOR, getColorFromInt(border), 0);
            }
     
            public void texParameters(int target) {
                //default: gl.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                gl.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                gl.glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
                gl.glTexParameteri(target, GL_TEXTURE_WRAP_S, s_edge);
                gl.glTexParameteri(target, GL_TEXTURE_WRAP_T, t_edge);
                gl.glTexParameteri(target, GL_TEXTURE_WRAP_R, r_edge);
                gl.glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, getColorFromInt(border), 0);
            }
     
            /** Convert an integer RGBA, to a float array of 4 components.
             * @param color A 4 byte integer as RGBA color, with lower byte the red.
             * @return A float array with 4 color components, where 0-th element is red. */
            protected static float[] getColorFromInt(int color) {
                float[] c = new float[4];
                for (int z = 0; z < 4; ++z, color >>= 8)
                    c[0] = color & 255;
                return c;
            }
        }
     
        /** How many levels a texture can have.
         * @param i Texture image.
         * @param cfg Texture loading preferences. Can be null.
         * @return Number of mipmap levels for that texture. */
        public static int getMipmaps(Image i, Config cfg) {
            return max(1, i.getMipmaps() - cfg.skip_last_levels);
        }
     
        public static Texture loadTexture2D(InputStream is, Config cfg) throws IOException {
            if (is == null) throw new IOException("InputStream parameter is null, on loadTexture2D");
            if (cfg == null) cfg = new Config();
            Image i = new Image(is);
            if (i.width != i.height) throw new IOException("2d textures must be square");
            Texture texture = new Texture();
            texture.bindToTarget(GL_TEXTURE_2D);    // needed to baptize texture
            final int levels = getMipmaps(i, cfg);
            gl.glTextureStorage2D(texture.texture, levels, i.format, i.width, i.height);
            if (i.isCompressed) 
                for (int z = 0, sz, offs = 0; z < levels; ++z, offs += sz) {
                    sz = i.getMipmapSize(z);
                    gl.glCompressedTextureSubImage2D(texture.texture, z/*level*/,
                            0/*offset_x*/, 0/*offset_y*/, i.width, i.height, i.format,
                            sz/*image_size*/, ByteBuffer.wrap(i.raw, offs, sz));
                }
            else {
                gl.glTextureSubImage2D(texture.texture, 0/*level*/, 0, 0/*offset_x-y*/,
                        i.width, i.height, i.extformat, i.type, ByteBuffer.wrap(i.raw));
                gl.glGenerateTextureMipmap(texture.texture);
            }
            cfg.textureParameters(texture.texture);
     
            return texture;
        }
     
        public static Texture loadTex2D(InputStream is, Config cfg) throws IOException {
            if (is == null) throw new IOException("InputStream parameter is null, on loadTex2D");
            if (cfg == null) cfg = new Config();
            Image i = new Image(is);
            if (i.width != i.height) throw new IOException("2d textures must be square");
            Texture texture = new Texture();
            texture.bindToTarget(GL_TEXTURE_2D);
            final int levels = getMipmaps(i, cfg);
            gl.glTexStorage2D(GL_TEXTURE_2D, levels, i.format, i.width, i.height);
            if (i.isCompressed) 
                for (int z = 0, sz, offs = 0; z < levels; ++z, offs += sz) {
                    sz = i.getMipmapSize(z);
                    gl.glCompressedTexSubImage2D(GL_TEXTURE_2D, z/*level*/,
                            0/*offset_x*/, 0/*offset_y*/, i.width, i.height, i.format,
                            sz/*image_size*/, ByteBuffer.wrap(i.raw, offs, sz));
                }
            else {
                gl.glTexSubImage2D(GL_TEXTURE_2D, 0/*level*/, 0, 0/*offset_x-y*/,
                        i.width, i.height, i.extformat, i.type, ByteBuffer.wrap(i.raw));
                gl.glGenerateMipmap(GL_TEXTURE_2D);
            }
            cfg.texParameters(GL_TEXTURE_2D);
            return texture;
        }
     
        public static Texture loadTextureArray2D(InputStream is, Config cfg) throws IOException {
            if (is == null) throw new IOException("InputStream parameter is null, on loadTexArray2D");
            if (cfg == null) cfg = new Config();
            Image i = new Image(is);
            if (i.width != i.height) throw new IOException("2d array textures must be square");
            Texture texture = new Texture();
            texture.bindToTarget(GL_TEXTURE_2D_ARRAY);    // needed to baptize texture
            final int levels = getMipmaps(i, cfg);
            gl.glTextureStorage3D(texture.texture, levels, i.format, i.width, i.height, i.depth);
            if (i.isCompressed)
                for (int z = 0, sz, offs = 0; z < levels; ++z, offs += sz) {
                    sz = i.getMipmapSize(z);
                    gl.glCompressedTextureSubImage3D(texture.texture, z/*level*/,
                            0, 0, 0/*offset_x-y-z*/, i.width, i.height, i.depth,
                            i.format, sz/*image_size*/, ByteBuffer.wrap(i.raw, offs, sz));
                }
            else {
                gl.glTextureSubImage3D(texture.texture, 0/*level*/, 0, 0, 0/*offset_x-y-z*/,
                        i.width, i.height, i.depth, i.extformat, i.type, ByteBuffer.wrap(i.raw));
                gl.glGenerateTextureMipmap(texture.texture);
            }
            cfg.textureParameters(texture.texture);
            return texture;
        }
     
        public static Texture loadTexArray2D(InputStream is, Config cfg) throws IOException {
            if (is == null) throw new IOException("InputStream parameter is null, on loadTextureArray2D");
            if (cfg == null) cfg = new Config();
            Image i = new Image(is);
            if (i.width != i.height) throw new IOException("2d array textures must be square");
            Texture texture = new Texture();
            texture.bindToTarget(GL_TEXTURE_2D_ARRAY);
            final int levels = getMipmaps(i, cfg);
            gl.glTexStorage3D(GL_TEXTURE_2D_ARRAY, levels, i.format, i.width, i.height, i.depth);
            if (i.isCompressed)
                for (int z = 0, sz, offs = 0; z < levels; ++z, offs += sz) {
                    sz = i.getMipmapSize(z);
                    gl.glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, z/*level*/,
                            0, 0, 0/*offset_x-y-z*/, i.width, i.height, i.depth,
                            i.format, sz/*image_size*/, ByteBuffer.wrap(i.raw, offs, sz));
                }
            else {
                gl.glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0/*level*/, 0, 0, 0/*offset_x-y-z*/,
                        i.width, i.height, i.depth, i.extformat, i.type, ByteBuffer.wrap(i.raw));
                gl.glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
            }
            cfg.texParameters(GL_TEXTURE_2D_ARRAY);
            return texture;
        }
    }

    TextureOld.java
    Code :
    public class TextureOld extends Texture {
        /** Target of texture. Like GL_TEXTURE_2D. */
        protected final int target;
        protected TextureOld(int tex, int target) { super(tex); this.target = target; }
        /** Bind texture to texture unit.
         * @param unit index of the texture unit. */
        @Override
        public void bindToUnit(int unit) {
            gl.glActiveTexture(GL_TEXTURE0 + unit);
            gl.glBindTexture(target, texture);
        }
     
        public static Texture loadTexture2D(InputStream is, Config cfg) throws IOException {
            return isDirectStateAccessSupported()
                    ? Texture.loadTexture2D(is, cfg)
                    : new TextureOld(Texture.loadTex2D(is, cfg).texture, GL_TEXTURE_2D);
        }
     
        public static Texture loadTextureArray2D(InputStream is, Config cfg) throws IOException {
            return isDirectStateAccessSupported()
                    ? Texture.loadTextureArray2D(is, cfg)
                    : new TextureOld(Texture.loadTexArray2D(is, cfg).texture, GL_TEXTURE_2D_ARRAY);
        }
     
        private static int ARB_direct_state_access = -1;
        public static boolean isDirectStateAccessSupported() {
            if (ARB_direct_state_access == -1) {
                // Check if OpenGL core version is at least 4.5
                int r = getInteger(GL_MAJOR_VERSION);
                if (r > 4 || r == 4 && getInteger(GL_MINOR_VERSION) >= 5)
                    ARB_direct_state_access = 2;
                // Check if extension ARB_direct_state_access is supported
                else ARB_direct_state_access = gl.glGetString(GL_EXTENSIONS).contains("ARB_direct_state_access") ? 1 : 0;
            }
            return ARB_direct_state_access > 0;
        }
    }

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,685
    https://www.khronos.org/registry/Ope...tureUnit.xhtml

    Description

    glBindTextureUnit binds an existing texture object to the texture unit numbered unit.
    It could probably be more explicit, but the first parameter to glBindTextureUnit is not "GL_TEXTURE0 + unit":
    Code :
    glBindTextureUnit(unit, texture);

  3. #3
    Junior Member Newbie
    Join Date
    Dec 2009
    Location
    Greece
    Posts
    18
    Whow! That solves the problem!

    Indeed, OpenGL API prototypes have different parameter types:
    Code :
    void glActiveTexture(GLenum texture);        // GL_TEXTURE0 + unit
    void glBindTextureUnit(GLuint unit, GLuint texture); // unit, textureid

  4. #4
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,685
    I also note the two separate meanings assigned to the "texture" parameter, depending on which function you use.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •