Texture Arrays

Problems building or running the engine, queries about how to use features etc.
Post Reply
zfx
Gnoblar
Posts: 6
Joined: Thu Sep 23, 2010 4:34 pm

Texture Arrays

Post by zfx »

Hi everyone!
I just started using Ogre and am currently in the process of porting my existing project from another rendering engine. I've been using 2D Texture arrays (as of DX10, or GL_TEXTURE_ARRAY extension for OpenGL) in order to minimize occupied texture units. I searched google, the forums and the wiki for some info on that topic, but was only able to find something dicussing this "new" feature in some DX10 topic in the year 2008! I strongly suspect that it is implemented in some form, but it would really help me if someone could point me in the right direction to look (i.e. some links to the API reference, discussions, samples, whatever). Any help is much appreciated!
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218
Contact:

Re: Texture Arrays

Post by Jabberwocky »

I've never used, nor heard of a texture array. Although I'm not exactly up on the cutting edge graphics techniques. If it's a DX10-only feature, I think you're going to need to find an alternative. I don't believe Ogre has formally advanced beyond DX9 yet, although there has been some preliminary work to do so.

There are some implementations of a "texture atlas" kicking around, which may accomplish the same thing.
Try searching for those terms in the forum search box.
Image
zfx
Gnoblar
Posts: 6
Joined: Thu Sep 23, 2010 4:34 pm

Re: Texture Arrays

Post by zfx »

Well it's a fairly used feature by now. It is basically what is says, an array of textures which can be referenced by texture index in the shader. It is strictly for shader usage. Problems with atlases are bleeding issues when textures are of odd sizes and the other severe problem (which i avoided by using texture arrays) is that they do not support tiling without specialized shaders, which of course introduce a severe performance penalty themselves. I saw that OGRE has DX10 & DX11 renderers. I read a bit in the forums and found that the DX10 renderer is abandoned by now and only DX11 is actively developed. If the DX11 renderer is compatible with DX10 that should not be a problem. But I don't know if DX10 is included in the DX11 system. And also what features of DX10 are currently exposed, what are the limitations. OGRE is a very nice engine from what I've seen so far, especially material scripts and exporter support. I really hope they get more serious about DX10/11, cuz it's about time now, when pretty much any gfx card you can buy today supports it and it is used actively :) I come from an OpenGL background, but I am ready to assist with what I can to add the features that i need to whatever rendering system they need to be added (both OpenGL and DirectX) :)
User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel
x 76

Re: Texture Arrays

Post by Assaf Raman »

No texture arrays support for now.
I will put it in my todo list.
Watch out for my OGRE related tweets here.
User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel
x 76

Re: Texture Arrays

Post by Assaf Raman »

Added texture array support.
For now the texture array sample only supports GL.
Latest code committed to the trunk.
Attachments
15 textures in one texture array rendered with a shader that interpolate between two nearest layers in the array.
15 textures in one texture array rendered with a shader that interpolate between two nearest layers in the array.
Watch out for my OGRE related tweets here.
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218
Contact:

Re: Texture Arrays

Post by Jabberwocky »

Wow, that looks like a Salvador Dali painting. :shock:

Nice work on the new feature Assaf! Your work is much appreciated as always.
Image
LBDude
Gnome
Posts: 389
Joined: Mon Jul 26, 2010 10:53 pm
x 22

Re: Texture Arrays

Post by LBDude »

NOOOO... when are going to see this in the DX renderer? I may just have to look at your code and see if I can add it myself...but is texture arrays even available for DX9?

I would definitely use OpenGL if it were not the fact I'm using some shaders that is HLSL only :(. Hell, I would be coding in Linux if it weren't for that.
My blog here.
Game twitter here
User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel
x 76

Re: Texture Arrays

Post by Assaf Raman »

No d3d9 or gl es support, only d3d11 and gl support.
Watch out for my OGRE related tweets here.
plfiorini
Gnoblar
Posts: 15
Joined: Thu Feb 21, 2008 8:24 am

Re: Texture Arrays

Post by plfiorini »

LBDude wrote: I would definitely use OpenGL if it were not the fact I'm using some shaders that is HLSL only :(. Hell, I would be coding in Linux if it weren't for that.
Well, try to port your HLSL shaders to Cg. It should be pretty straightforward.
plfiorini
Gnoblar
Posts: 15
Joined: Thu Feb 21, 2008 8:24 am

Re: Texture Arrays

Post by plfiorini »

Assaf Raman wrote:Added texture array support.
For now the texture array sample only supports GL.
Latest code committed to the trunk.
Thank you very much! I'm coding on Linux now (and planning to use it on OSX as well) using Ogre 1.8 from trunk.
I think that texture arrays may be useful to get terrains working with deferred shading (I'm basically using Ogre's demo code in my project, just extended the GBuffer vertex and fragment program generator with Parallax Occlusion Mapping), in fact as far as I understand with terrains you'll have to handle it with the GBuffer scheme so the fragment program may run out of texture units. Am I right?
User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel
x 76

Re: Texture Arrays

Post by Assaf Raman »

I am not sure, but it seems you know what you are talking about.
Watch out for my OGRE related tweets here.
zfx
Gnoblar
Posts: 6
Joined: Thu Sep 23, 2010 4:34 pm

Re: Texture Arrays

Post by zfx »

This is great!! WOW! Only OpenGL, but it is a very good start :) DirectX equivalent would require DX10 or greater. Here you can see a sampe of it:
http://developer.download.nvidia.com/SD ... mples.html

Just scroll down to the end of the page, it is the last example! Thanks again for the great feature, I will test it next week :)
Wolfski
Gnoblar
Posts: 6
Joined: Wed Sep 21, 2011 12:07 am

Re: Texture Arrays

Post by Wolfski »

Hello

I'm struggling to get the sample to work with compressed textures. There seems to be an placeholder for handling this at line 204 of OgreGLTexture.cpp.

case TEX_TYPE_2D_ARRAY: // todo - check this...
case TEX_TYPE_3D:

With the original code I get a “zero sized texture on surface on texture” error. If I insert

glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, mip, format,
width, height, depth, 0,
size, template);
break;

then the buffer would seem to be created, but I get a “cannot return subvolume of compressed PixelBuffer” error when the sample tries to lock the buffer prior to adding the first texture - at line 71 of TextureArray.h:

const PixelBox& currImage = pixelBufferBuf->lock(Box(0,0,i,terrainTex.getHeight(), terrainTex.getHeight(), i+1), HardwareBuffer::HBL_DISCARD);

Looking at PixelBox::getSubVolume (OgrePixelFormat.cpp) it would seem it doesn't support compressed formats.

Any ideas what to do next?

Also, are there any plans to fully integrate texture arrays into the material system, so the list of textures might be specified in the material script?
User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel
x 76

Re: Texture Arrays

Post by Assaf Raman »

Regarding your issue - find a working GL compressed textures sample by someone and give us a link - then we can compare it to what is going on in OGRE.
Regarding the integrating into the scripts - I don't think this is in any of us todo list.
Watch out for my OGRE related tweets here.
Wolfski
Gnoblar
Posts: 6
Joined: Wed Sep 21, 2011 12:07 am

Re: Texture Arrays

Post by Wolfski »

I've modified NVIDIA's SDK sample ( which looks like it was the basis for Ogre's sample ) and that seems to work OK.

Changes from the original are marked with: // change #

Code: Select all

//
// simple texture array example
//
// Demonstrates the use of EXT_texure_array.
//
// Author: Simon Green
// Email: sdkfeedback@nvidia.com
//
// Copyright (c) NVIDIA Corporation. All rights reserved.
////////////////////////////////////////////////////////////////////////////////

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <map>

#include <GL/glew.h>
#include <GL/glut.h>

#include <nvImage.h>
#include <nvGlutManipulators.h>

#define NV_REPORT_COMPILE_ERRORS
#include <nvShaderUtils.h>

using std::map;

////////////////////////////////////////////////////////////////////////////////
//
// Globals
//
////////////////////////////////////////////////////////////////////////////////

// change #1, path adjusted to run from the IDE
//#define IMAGE_PATH "../media/textures/"
#define IMAGE_PATH "../../media/textures/"

nv::GlutExamine manipulator;
GLuint fprog, lerp_fprog;

enum UIOption {
    OPTION_DISPLAY_WIREFRAME,
    OPTION_LERP_LAYERS,
    OPTION_ANIMATE,
    OPTION_USE_PROGRAM,
    OPTION_COUNT
};
bool options[OPTION_COUNT];
map<char,UIOption> optionKeyMap;

//
// fragment program to look up in texture array
//
static const char *fprog_code = 
"!!NVfp4.0                                        \n"
"TEMP texcoord;                                   \n"
"MOV texcoord, fragment.texcoord[0];              \n"
"FLR texcoord.z, texcoord;                        \n"
"TEX result.color, texcoord, texture[0], ARRAY2D; \n"
"END";

//
// interpolate between two nearest layers in array
//
static const char *lerp_fprog_code = 
"!!NVfp4.0                                        \n"
"TEMP texcoord, c0, c1, frac;                     \n"
"MOV texcoord, fragment.texcoord[0];              \n"
"FLR texcoord.z, texcoord;                        \n"
"TEX c0, texcoord, texture[0], ARRAY2D;           \n"
"ADD texcoord.z, texcoord, { 0, 0, 1, 0 };        \n"
"TEX c1, texcoord, texture[0], ARRAY2D;           \n"
"FRC frac.x, fragment.texcoord[0].z;              \n"
"LRP result.color, frac.x, c1, c0;                \n"
"END";

////////////////////////////////////////////////////////////////////////////////
//
// Functions
//
////////////////////////////////////////////////////////////////////////////////


//
//
//////////////////////////////////////////////////////////////////////
void init_opengl() {
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.2, 0.2, 0.2, 1.0);

    glewInit();

    if (!glewIsSupported(
        "GL_VERSION_2_0 "
		"GL_ARB_vertex_program "
        "GL_ARB_fragment_program "
        "GL_EXT_texture_array "
        "GL_NV_gpu_program4 "   // also initializes NV_fragment_program4 etc.
        ))
    {
        printf("Unable to load extension(s), this sample requires:\n  OpenGL version 2.0\n"
               "  GL_ARB_vertex_program\n  GL_ARB_fragment_program\n  GL_EXT_texture_array\n"
               "  GL_NV_gpu_program4\n Exiting...\n");
        exit(-1);
    }

    // load images
    #define NIMAGES 4

	// change #2, use dds (dxt5) images
    char *imageName[] = {
        //IMAGE_PATH "rock.png",
        //IMAGE_PATH "snow.png",
        //IMAGE_PATH "grass.png",
        //IMAGE_PATH "graydirt.png"
        IMAGE_PATH "rock.dds",
        IMAGE_PATH "snow.dds",
        IMAGE_PATH "grass.dds",
        IMAGE_PATH "graydirt.dds"
    };

    nv::Image images[NIMAGES];
    for(int i=0; i<NIMAGES; i++) {
        images[i].loadImageFromFile( imageName[i]);
    }

    // load images as 2d texture array
    GLuint texid;
    glGenTextures(1, &texid);
    glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, texid);

    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);

	// change #3, allocate some storage
	char *tmp = new char[512*512*4];
    
	// 2D Texture arrays a loaded just like 3D textures

	// change #4, use glCompressedTexImage3D instead of glTexImage3D
    //glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGBA8, images[0].getWidth(), images[0].getHeight(), NIMAGES, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0,  GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, images[0].getWidth(), images[0].getHeight(), NIMAGES, 0, 512*512*4, tmp);

    for (int i = 0; i < NIMAGES; i++) {
		// change #5, use glCompressedTexSubImage instead of glTexSubImage
        //glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, i, images[i].getWidth(), images[i].getHeight(), 1, images[i].getFormat(), images[i].getType(), images[i].getLevel(0));
		glCompressedTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, i, images[i].getWidth(), images[i].getHeight(), 1, images[i].getFormat(), images[i].getImageSize(), images[i].getLevel(0));
    }

    fprog = nv::CompileASMShader(GL_FRAGMENT_PROGRAM_ARB, fprog_code);
    lerp_fprog = nv::CompileASMShader(GL_FRAGMENT_PROGRAM_ARB, lerp_fprog_code);
}

//
//
//////////////////////////////////////////////////////////////////////
void draw_quad() {
    // r texture coordinate is used to select layer
    glBegin(GL_QUADS);
    glTexCoord3f(0.0, 0.0, 0.0);
    glVertex2f(-1.0, -1.0);
    glTexCoord3f(1.0, 0.0, 4.0);
    glVertex2f(1.0, -1.0);
    glTexCoord3f(1.0, 1.0, 4.0);
    glVertex2f(1.0, 1.0);
    glTexCoord3f(0.0, 1.0, 0.0);
    glVertex2f(-1.0, 1.0);
    glEnd();
}

//
//
//////////////////////////////////////////////////////////////////////
void display() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    manipulator.applyTransform();

    glColor3f(1.0, 1.0, 1.0);

    if ( options[OPTION_LERP_LAYERS]) {
        glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, lerp_fprog);
    } else {
        glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fprog);
    }

    if (options[OPTION_USE_PROGRAM]) {
        glEnable(GL_FRAGMENT_PROGRAM_ARB);
    }

    glPolygonMode( GL_FRONT_AND_BACK, options[OPTION_DISPLAY_WIREFRAME] ? GL_LINE : GL_FILL);

    draw_quad();

    glDisable(GL_FRAGMENT_PROGRAM_ARB);

    glutSwapBuffers();
}

//
//
//////////////////////////////////////////////////////////////////////
void idle() {
    if ( options[OPTION_ANIMATE])
        manipulator.idle();
    
    glutPostRedisplay();
}

//
//
//////////////////////////////////////////////////////////////////////
void key(unsigned char k, int x, int y) {
    k = tolower(k);

    if (optionKeyMap.find(k) != optionKeyMap.end())
        options[optionKeyMap[k]] = !options[optionKeyMap[k]];
	
    switch(k) {
        case 27:
        case 'q':
            exit(0);
            break;
    }
    
	glutPostRedisplay();
}

//
//
//////////////////////////////////////////////////////////////////////
void resize(int w, int h) {
    glViewport(0, 0, w, h);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 0.1, 100.0);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    manipulator.reshape(w, h);
}

//
//
//////////////////////////////////////////////////////////////////////
void mouse(int button, int state, int x, int y) {
    manipulator.mouse(button, state, x, y);
}

//
//
//////////////////////////////////////////////////////////////////////
void motion(int x, int y) {
    manipulator.motion(x, y);
}

//
//
//////////////////////////////////////////////////////////////////////
int main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitWindowSize(512, 512);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
	glutCreateWindow("simple_texture_array");

	init_opengl();

    manipulator.setDollyActivate( GLUT_LEFT_BUTTON, GLUT_ACTIVE_CTRL);
    manipulator.setPanActivate( GLUT_LEFT_BUTTON, GLUT_ACTIVE_SHIFT);
    manipulator.setDollyPosition( -2.0f);

	glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutIdleFunc(idle);
    glutKeyboardFunc(key);
    glutReshapeFunc(resize);

    //configure the options
    optionKeyMap['w'] = OPTION_DISPLAY_WIREFRAME;
    options[OPTION_DISPLAY_WIREFRAME] = false;

    optionKeyMap['f'] = OPTION_USE_PROGRAM;
    options[OPTION_USE_PROGRAM] = true;
    
    optionKeyMap[' '] = OPTION_ANIMATE;
    options[OPTION_ANIMATE] = true;

    optionKeyMap['l'] = OPTION_LERP_LAYERS;
    options[OPTION_LERP_LAYERS] = false;

    //print the help info
    printf( "Simple_texture_array - sample showing the usage of texture arrays\n");
    printf( "  Commands:\n");
    printf( "    q / [ESC] - Quit the application\n");
    printf( "    [SPACE]   - Toggle continuous animation\n");
    printf( "    f         - Toggle using a fragment program\n");
    printf( "    w         - Toggle displaying wireframe\n");
    printf( "    l         - Toggle interpolation between texture layers\n\n");

	glutMainLoop();

	return 0;
}
I've also modified PixelBox::getSubVolume to return what appear to be correct values for a DXT5 texture, and Ogre's sample now at least runs.

Code: Select all

	PixelBox PixelBox::getSubVolume(const Box &def) const
	{
		// change #1, allow DXT5
		//if(PixelUtil::isCompressed(format))
		if(PixelUtil::isCompressed(format) && (format != PF_DXT5))
		{
			if(def.left == left && def.top == top && def.front == front &&
			   def.right == right && def.bottom == bottom && def.back == back)
			{
				// Entire buffer is being queried
				return *this;
			}
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot return subvolume of compressed PixelBuffer", "PixelBox::getSubVolume");
		}
		if(!contains(def))
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Bounds out of range", "PixelBox::getSubVolume");

		// change #2, set elemSize = 1 for DXT5
		//const size_t elemSize = PixelUtil::getNumElemBytes(format);
		size_t elemSize = PixelUtil::getNumElemBytes(format);
		if (format == PF_DXT5)
			elemSize = 1;

		// Calculate new data origin
		// Notice how we do not propagate left/top/front from the incoming box, since
		// the returned pointer is already offset
		PixelBox rval(def.getWidth(), def.getHeight(), def.getDepth(), format, 
			((uint8*)data) + ((def.left-left)*elemSize)
			+ ((def.top-top)*rowPitch*elemSize)
			+ ((def.front-front)*slicePitch*elemSize)
		);

		rval.rowPitch = rowPitch;
		rval.slicePitch = slicePitch;
		rval.format = format;

		return rval;
	}
But all I can see from the shader is the texture from the first layer.

The obvious difference between the two is glCompressedTexSubImage3D vs PixelUtil::bulkPixelConversion.
User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel
x 76

Re: Texture Arrays

Post by Assaf Raman »

Nice work,I will have a look when I can.
Watch out for my OGRE related tweets here.
Wolfski
Gnoblar
Posts: 6
Joined: Wed Sep 21, 2011 12:07 am

Re: Texture Arrays

Post by Wolfski »

I've found the cause of why I can only see the first layer of a compressed texture array.

There is code in OgreGLHardwarePixelBuffer.cpp (line 354 onwards) for "some systems (e.g. old Apple) don't like compressed subimage calls so prefer non-sub versions". If I disable this code, the other layers become visible.

Code: Select all

			case GL_TEXTURE_2D_ARRAY:
				// some systems (e.g. old Apple) don't like compressed subimage calls
				// so prefer non-sub versions
				
				// change #1, this non sub call makes only the front layer of the texture accessable
				// remove it and compressed texture arrays work

				//if (dest.left == 0 && dest.top == 0 && dest.front == 0)
				if (false)
				{
					glCompressedTexImage3DARB(mTarget, mLevel,
						format,
						dest.getWidth(),
						dest.getHeight(),
						dest.getDepth(),
						0,
						data.getConsecutiveSize(),
						data.data);
				}
				else
				{
					glCompressedTexSubImage3DARB(mTarget, mLevel, 
						dest.left, dest.top, dest.front,
						dest.getWidth(), dest.getHeight(), dest.getDepth(),
						format, data.getConsecutiveSize(),
						data.data);
				}
				break;
I don't know the history behind this non sub image compressed image call for the front layer, but there must be a better test for systems that don't like compressed subimage calls. Could I request a fix for this please.

Also, could someone explain the PixelUtil::getMemorySize calculations for DXT1 and 5 formats:

Code: Select all

				case PF_DXT1:
					return ((width+3)/4)*((height+3)/4)*8 * depth;
				case PF_DXT2:
				case PF_DXT3:
				case PF_DXT4:
				case PF_DXT5:
					return ((width+3)/4)*((height+3)/4)*16 * depth;
My understanding is, DXT1 and 5 compress a 4 x 4 block of pixels into 8 and 16 bytes respectively. Which would simply be:

DXT1 width * height * depth / 2
DXT5 width * height * depth

Am I missing something here?
User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel
x 76

Re: Texture Arrays

Post by Assaf Raman »

Regarding OgreGLHardwarePixelBuffer.cpp - what is your suggested fix?

Regarding dx format - no clue. Anyone else?
Watch out for my OGRE related tweets here.
Wolfski
Gnoblar
Posts: 6
Joined: Wed Sep 21, 2011 12:07 am

Re: Texture Arrays

Post by Wolfski »

I'm probably a bit out of my depth here, but glCompressedTexImage would only seem to make sense for a bulk copy of all the layers.

So how about:

Code: Select all

			case GL_TEXTURE_2D_ARRAY:
				// some systems (e.g. old Apple) don't like compressed subimage calls
				// so prefer non-sub versions
				
				// change #1, only use glCompressedTexImage3D if copying all the layers at once
				//if (dest.left == 0 && dest.top == 0 && dest.front == 0)
				GLint textureDepth;
				glGetTexLevelParameteriv(mTarget, mLevel, GL_TEXTURE_DEPTH, &textureDepth);
				if (dest.left == 0 && dest.top == 0 && dest.getDepth() == textureDepth)
				{
					glCompressedTexImage3DARB(mTarget, mLevel,
						format,
						dest.getWidth(),
						dest.getHeight(),
						dest.getDepth(),
						0,
						data.getConsecutiveSize(),
						data.data);
				}
				else
				{
					glCompressedTexSubImage3DARB(mTarget, mLevel, 
						dest.left, dest.top, dest.front,
						dest.getWidth(), dest.getHeight(), dest.getDepth(),
						format, data.getConsecutiveSize(),
						data.data);
				}
				break;
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Texture Arrays

Post by Kojack »

My understanding is, DXT1 and 5 compress a 4 x 4 block of pixels into 8 and 16 bytes respectively. Which would simply be:

DXT1 width * height * depth / 2
DXT5 width * height * depth

Am I missing something here?
It's because dxt textures only work on resolutions which are multiples of 4.
If you have a 5x5 texture, it takes the memory of an 8x8, size is always padded to the next multiple of 4. That's what ogre's code is doing.
Wolfski
Gnoblar
Posts: 6
Joined: Wed Sep 21, 2011 12:07 am

Re: Texture Arrays

Post by Wolfski »

Doh. Of course, they're integers. I was missing something.

Thanks
User avatar
m2codeGEN
Halfling
Posts: 52
Joined: Tue Apr 26, 2011 9:13 am
Location: Russia, Tver
x 2

Re: Texture Arrays

Post by m2codeGEN »

Tanks to masterfalcon.
rev 3421 (048a35d56fda) GL: 2D array texture support for GLSL. The texture array sample now works on GL
v1-8
2012-02-19
pontus
Gnoblar
Posts: 9
Joined: Wed Feb 17, 2010 8:29 pm
Location: Stockholm, Sweden
x 7

Re: Texture Arrays

Post by pontus »

I had some trouble with using texture arrays with the GL RenderSystem. Got a vector bounds error. I checked the source and found that GCT_SAMPLER2DARRAY is not listed as an int type in updateUniforms(), causing the uniform to default to float. Here is the fix:
https://www.dropbox.com/s/g8wexm23afwr2al/6349.patch
Post Reply