HDR cube maps & OpenEXR

Hello,

I need to load vertical cross cube maps from openEXR pictures to use it as an environment in an OpenGL scene.
I load 48 bits openexr files using the code provided in the documentation.
the loaded data is stored in a Rgba array where Rgba is this structure:

struct Rgba{
half r; // red
half g; // green
half b; // blue
half a; // alpha (opacity)
};

I would know for those who used (or are using) the file format how they adapt this data to the gl representation.

As far as I am concerned, I convert data in a rgb array removing the useless alpha component…
I use GL_RGB16F_ARB internal format and GL_HALF_FLOAT_ARB data type.

But looking at r, g, b, a components in the data, what I see is values between around 0.02 and 0.2 not more than a 10 factor between the smallest and greatest values. Astonishing with a HDR cube map no?
What do you think about it for those who use openEXR?

Thank you.

Haven’t used the OpenEXR format myself, but I seriously doubt that removing the alpha component will help. My guess is that it’s being converted to a GL_RGBA16F_ARB internally anyway.

I use RGBA images:

glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA16F_ARB,
width,
height,
0,
GL_RGBA,
GL_HALF_FLOAT_ARB,
(GLvoid*)pixeles

);

Can you post some of your code for loading into memory, crop alpha component and uploading to OpenGL?.

Thank you both for your replies.

Nico> I can keep the alpha component but it is the same. The alpha component is always 1 so I thought that it is useless if I do not need transparency. At the beginning I thought that the alpha component would have been like the color “module” but it is always 1.
The point is why the data values are so small?

RGHP> I do the same for glTexImage2D or this:

glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB16F_ARB,
width,
height,
0,
GL_RGB,
GL_HALF_FLOAT_ARB,
(GLvoid*)pixeles
);

if I don’t want the alpha component.

Removing the alpha component works well because I see exactly the same thing with or without it.

This is the function that loads OpenEXR pictures and extracts the alpha component:


/**

 * @brief loads a 48 bits openEXR picture in memory

 * @param filename file path

 * @param width address of a Texture.width
 * @param height address of a Texture.height

 * @return Timage the picture data

 */
GLubyte* loadEXR48(char* filename, GLuint* width, GLuint* height)
{
	GLubyte*Timage=NULL;
	Imf::Array2D<Imf::Rgba> pixels;
	
	const int bulkSize=6;
	
	Imf::RgbaInputFile file (filename);
	Imath::Box2i dw = file.dataWindow();
	*width = dw.max.x - dw.min.x + 1;
	*height = dw.max.y - dw.min.y + 1;
	pixels.resizeErase ((long int)*height, (long int)*width);
	file.setFrameBuffer (&pixels[0][0] - dw.min.x - dw.min.y *(*width), 1, (*width));
	file.readPixels (dw.min.y, dw.max.y);
	
	int size=(*width)*(*height);
	
	Timage=new GLubyte[size*bulkSize];
	
	for(int i=0;i<(int)(*height);i++)
	{
		for(int j=0;j<(int)(*width);j++)
		{
			memcpy(Timage+bulkSize*(i*(*width)+j), &pixels[i][j], bulkSize*sizeof(char));
			//cout<<"R="<<pixels[i][j].r<<"  G="<<pixels[i][j].g<<"  B="<<pixels[i][j].b<<"  A="<<pixels[i][j].a<<endl;
		}
	}
	
	return Timage;
}

You just have to change bulkSize by 8 to keep the alpha component . bulkSize is the pixel byte size.

thanks

My point was that if your card does not support GL_RGB16F_ARB natively (which is most likely the case), your data will have to be converted to GL_RGBA16F_ARB before it is downloaded to the GPU. So if it’s not supported natively you’d be better off sticking to GL_RGBA16F_ARB value even if the alpha is always 1 because you will get accelerated data transfer to GPU without conversion.

Don’t know why the range is so small, haven’t used HDR textures myself.

Thank you nico.

I let the GL_RGBA16F_ARB and I have the same thing. I think that both are supported by my cg. It is ATI mobility X1600.

I have projected the loaded cube map on a quad (You must reconize the famous uffizi picture).

There is another problem, as you can see, the texture is very pixelated as if I let the GL_NEAREST filter. But even if I put the GL_LINEAR filter I see the same thing.
I don’t understand because it worked with a LDR cube map…

for information the size of the loaded cube map is 64

thanks

Did you use GL_LINEAR for both the minification and magnification filters? What graphics card hardware are you using?

lol you post so quickly that in my last post I did not take into account your post before this last one ^^ (So I have tried to adapt it after…)

So, yes I use GL_LINEAR filter for minification and magnification filters like I did for LDR cube maps.
My graphic card is ATI mobility X1600.

thanks

Probably a hardware limitation. My guess is that 16 bit floating point textures are not supported natively on ATi X1k hardware so it uses 32 bit floating point substitution, which in turn does not support linear filtering.

I’d be happy to try out the code if I can compile it for linux.

Yes it could…
Actually I work on linux. I checked the presence of GL_ARB_half_float_pixel with glxinfo and I found nothing. But when I do that with glew in my code, glew seems to have found this extension! Maybe it is because of 16 bits floating point -> 32 bits floating points replacement mechanism…

If you want to compile my code on your linux you have to be brave ^^.
actually it is a school project to demonstrate HDR rendering and I don’t know for now how to create configure files. So you will need to install manually the ilmbase and openexr libraries and maybe modify the Makefile to make it works.

But if it is your wish I can do that.
On my side, I will find out about how to make easier my project compilation.

Try this code to see if it supports 16bit fp filtering:


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

int ww,hh;
GLuint tex;

void changeSize(int w, int h) {
	ww=w;
	hh=h;
	glViewport(0,0,ww,hh);
}

void renderScene(void) {

	glClearColor(0.0,0.0,0.0,0.0);
	glClear(GL_COLOR_BUFFER_BIT);

	glEnable(GL_TEXTURE_2D);

	glBegin(GL_QUADS);
	glTexCoord2f(0.0f,0.0f);
	glVertex2f(-1.0f,-1.0f);
	glTexCoord2f(1.0f,0.0f);
	glVertex2f( 1.0f,-1.0f);
	glTexCoord2f(1.0f,1.0f);
	glVertex2f(1.0f,1.0f);
	glTexCoord2f(0.0f,1.0f);
	glVertex2f(-1.0f,1.0f);
	glEnd();

	glutSwapBuffers();
}

void initTex() {

	float texdata[] = {	0.0f,0.0f,0.0f,1.0f,
						1.0f,0.0f,0.0f,1.0f,
						0.0f,1.0f,0.0f,1.0f,
						0.0f,0.0f,1.0f,1.0f};

	glGenTextures(1,&tex);
	glBindTexture(GL_TEXTURE_2D,tex);
	glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16F_ARB,2,2,0,GL_RGBA,GL_FLOAT,&texdata[0]);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

}

int main(int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(512,512);
    glutCreateWindow("HDR");

    glutDisplayFunc(renderScene);
    glutReshapeFunc(changeSize);

    glewInit();

    initTex();

    glutMainLoop();

    return 0;
}


Here’s my output:

I tried your code and this is what I obtain:

It looks like 16 fp linear filtering do not work with my current cg…

I forgot something,
I don’t understand why in your code you use float data and GL_FLOAT in glTexImage2D if you want to test if 16 fp filtering works ?

GL_FLOAT only indicates the data type of the client (CPU) side texture. By specifying GL_RGBA16F_ARB, the driver will convert it to 16bit fp and then upload it to the server (GPU) side. I could just as easily have specified GL_UNSIGNED_BYTE and still get the same result.

PS. I just tried your program code and I get linear filtering.

Ok I understand.

Cool! ^^

Thank for your help, I think I will do the linear filtering manually in the fragment shader.

Just pass us the code ;).

In this page says that your card model support half textures(and acelerated tone mapping, how? ) :

http://ati.amd.com/products/mobilityradeonx1600/specs.html

which drivers are you using? maybe ypu are working with Mesa and you have no access to all the features opf your card.

Just pass us the code ;).

In this page says that your card model support half textures(and acelerated tone mapping, how? ) :

http://ati.amd.com/products/mobilityradeonx1600/specs.html

which drivers are you using? maybe ypu are working with Mesa and you have no access to all the features opf your card.

Just pass us the code ;).

In this page says that your card model support half textures(and acelerated tone mapping, how? ) :

http://ati.amd.com/products/mobilityradeonx1600/specs.html

which drivers are you using? maybe ypu are working with Mesa and you have no access to all the features opf your card.

Just pass us the code ;).

In this page says that your card model support half textures(and acelerated tone mapping, how? ) :

http://ati.amd.com/products/mobilityradeonx1600/specs.html

which drivers are you using? maybe ypu are working with Mesa and you have no access to all the features opf your card.

Just pass us the code ;).

In this page says that your card model support half textures(and acelerated tone mapping, how? ) :

http://ati.amd.com/products/mobilityradeonx1600/specs.html

which drivers are you using? maybe ypu are working with Mesa and you have no access to all the features opf your card.