Results 1 to 8 of 8

Thread: Creating texture from HDR image

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    19

    Creating texture from HDR image

    Hi, I'm having trouble with setting up a texture which I've read from the OpenEXR file. It's a HDR light probe image and I'm trying to set it as a texture of a big sphere for showing it as my background. The problem is that the color is not right and only a light blue color is visible. I used OpenExr library for reading the image file and stored it like this:

    Code :
    InputFile file(Filename);
      Box2i dw = file.header().dataWindow();
      m_iWidth  = dw.max.x - dw.min.x + 1;
      m_iHeight = dw.max.y - dw.min.y + 1;
      half *rgb = new half[3 * m_iWidth * m_iHeight];
      FrameBuffer frameBuffer;
      frameBuffer.insert("R", Slice(HALF, (char *)rgb,
       3*sizeof(half), m_iWidth * 3 * sizeof(half), 1, 1, 0.0));
      frameBuffer.insert("G", Slice(HALF, (char *)rgb+sizeof(half),
       3*sizeof(half), m_iWidth * 3 * sizeof(half), 1, 1, 0.0));
      frameBuffer.insert("B", Slice(HALF, (char *)rgb+2*sizeof(half),
       3*sizeof(half), m_iWidth * 3 * sizeof(half), 1, 1, 0.0));
      file.setFrameBuffer(frameBuffer);
      file.readPixels(dw.min.y, dw.max.y);
      m_Image = new Color[m_iWidth * m_iHeight];
      for (int i = 0; i < m_iWidth * m_iHeight; ++i) {
       float frgb[3] = { rgb[3*i], rgb[3*i+1], rgb[3*i+2] };
       m_Image[i] = frgb;


    where color contains float R, G , B.

    and this is how i create a texture:
    Code :
    glGenTextures(1 , &amp;texture);
    glBindTexture(GL_TEXTURE_2D,texture);
     
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
     
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, light_tex.m_iWidth, light_tex.m_iHeight, 0, GL_RGBA, GL_FLOAT, light_tex.m_Image);

  2. #2
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,674

    Re: Creating texture from HDR image

    You told OpenGL that you were uploading four components. But your data only seems to have three (unless `Color` is a 4-vector).

    Also, your conversion from half to float is... dubious. I mean, you have this line:

    Code :
    float frgb[3] = { rgb[3*i], rgb[3*i+1], rgb[3*i+2] };

    `rgb` is a `half*`; an array of `half`. So unless `half` has some implicit conversion to `float`, this isn't going to work. It'd be much easier (and a lot less confusing) to just do this:

    Code :
    m_Image[i][0] = ConvertToFloat(rgb[3*i + 0]);
    m_Image[i][1] = ConvertToFloat(rgb[3*i + 1]);
    m_Image[i][2] = ConvertToFloat(rgb[3*i + 2]);

    Lastly, what's the point of loading half-floats from the file (which is what I assume you're doing), just to convert them to 32-bit floats, all so that you can make OpenGL convert them back to half-floats?

    Just give OpenGL half-float data with GL_HALF_FLOAT instead of GL_FLOAT.

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    19

    Re: Creating texture from HDR image

    Just give OpenGL half-float data with GL_HALF_FLOAT instead of GL_FLOAT.
    I've tried what you said, and it is still not working, actually the code for reading the file is taken from PBRT and I'm sure it is correct, but I don't know how I have to assign in to a texture. I've attached the result I get with each try.

  4. #4
    Senior Member Regular Contributor Rosario Leonardi's Avatar
    Join Date
    Aug 2008
    Location
    Italy
    Posts
    356

    Re: Creating texture from HDR image

    I did this last month
    Code :
    GLuint loadTexture(const char *path)
    {
       Imf::Rgba * pixelBuffer;
       try
       {
         Imf::RgbaInputFile in(path);
     
         Imath::Box2i win = in.dataWindow();
         GLuint width  = win.max.x - win.min.x+1;
         GLuint height = win.max.y - win.min.y+1;
         Imath::V2i dim(win.max.x - win.min.x + 1,
                        win.max.y - win.min.y + 1);
     
         pixelBuffer = new Imf::Rgba[dim.x * dim.y];
     
         int dx = win.min.x;
         int dy = win.min.y;
     
         int order = in.lineOrder();
     
         in.setFrameBuffer(pixelBuffer - dx - (dy * dim.x), 1, dim.x);
         in.readPixels(win.min.y, win.max.y);
       }
       catch(Iex::BaseExc & e)
       {
         std::cerr << e.what() << std::endl;
     
         delete[]pixelBuffer;
         return GL_INVALID_VALUE;
       }
       GLuint texture;
       glGenTextures(1, &amp;texture);
       glBindTexture(GL_TEXTURE_RECTANGLE, texture);
     
       glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
       glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
       glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP);
       glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP);
       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     
       glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_HALF_FLOAT, pixelBuffer);
     
       delete[]pixelBuffer;
       return texture;
    }
    In my case i didn't do any conversion. I know that the exr image was stored as float16. In your code you are doing a lot of useless conversion.
    you read the image as float16, then you convert it as float32, then you convert the float32 to Color (can I see the layout of Color?) and then you use as internal format float16, so you are asking to openGl :
    "I have this float data in RGBA, to convert it again in float16."
    ~ ~ I tell you, realtime 3D is made of blood, sweat and screams! ~ ~

  5. #5
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    19

    Re: Creating texture from HDR image

    Quote Originally Posted by Rosario Leonardi
    In my case i didn't do any conversion. I know that the exr image was stored as float16. In your code you are doing a lot of useless conversion.
    you read the image as float16, then you convert it as float32, then you convert the float32 to Color (can I see the layout of Color?) and then you use as internal format float16, so you are asking to openGl :
    "I have this float data in RGBA, to convert it again in float16."

    First tnx for your help! I also tried your code but I can't see the image any more, I know I'm mixing sth with these conversions...

    this is my Color class:

    Code :
    class Color
    {
    public:
     
    	float R , G , B/* , A*/;
    	Color(const Color&amp; col);
    	Color();
    	virtual ~Color(void);
    	Color(const float r,const float g, const float b);
    	void Set(const float r, const float g, const float b);
     
    	friend Color operator * (const float s, const Color c);
    	Color&amp; operator=(const Color&amp; c);
    	Color&amp; operator=(const float&amp; c);
    	Color&amp; operator=(const float c[3]);
    	//Color&amp; operator=(const Lib3dsByte&amp; c);
    	Color operator*(const Color&amp; c);
    	Color operator*(float d) const;
    	Color operator/(float d) const;
    	void operator*=(const float s);
        void operator/=(const float s);
        Color&amp; operator+=(const Color&amp; c);
    	Color operator+(const Color&amp; vec3) const;
    	bool operator==(const float c) const;
    	//Color mult(const Color&amp; c) const;
    	void normalize(void);
    	Color ColorNorm(void)const;
    	void Bind();
     
    	Color Mult(const Color &amp;c);
    	void MultScalar(const float a);	
    };


    and I want to pass this texture to the shader and use latitude-longitude for mapping it on a sphere.

    this is how i pass it to the shader in my display function:

    Code :
    qobj = gluNewQuadric(); 
    	gluQuadricTexture(qobj,GL_TRUE); 
     
     
    	glEnable(GL_CULL_FACE);
     
    	glFrontFace(GL_CW /* or GL_CCW */);	//default is GL_CCW
     
    	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    	glDisable(GL_LIGHTING);
    	glDisable(GL_LIGHT0);
     
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    	gluLookAt(0.0f, 20.0f, 50.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
     
    	glPushMatrix();
    	glTranslatef(tx,ty,0);
    	glRotatef(rotx,1,0,0);
    	glRotatef(roty,0,1,0);
     
    	LShader.bind();
    	glEnable(GL_TEXTURE_2D );
    	glActiveTexture(GL_TEXTURE0);
    	glBindTexture(GL_TEXTURE_2D , texture);
     
    	int texture_location = glGetUniformLocation(LShader.GetID(), "color_texture");
    	glUniform1i(texture_location, texture_location);
     
     	gluSphere(qobj,10000,30,30);
     	gluDeleteQuadric(qobj); 
     
    	glDisable(GL_TEXTURE_2D);
    	LShader.unbind();
    	glPopMatrix();
     
     
    	glutSwapBuffers();

    and this is my fragment shader :
    Code :
     
    varying vec3 oVertexP;
     
     
    uniform sampler2D color_texture;
     
    void main()
    {
     
    	float pi = 3.1415;
    	float x , y, z;
    	vec3 viewVec = normalize(oVertexP);
    	x = viewVec.x;
    	y = viewVec.y;
    	z = viewVec.z;
     
    	//Latitude-longitude
    	float	u = 1.0 + (1.0/pi) * atan(x,-z); u /= 2.0;
    	float	v = acos(y) / pi;
     
        vec4 color = vec4(  texture2D(color_texture, vec2(u,v)) );
    	gl_FragColor = vec4(pow(color.xyz,1.0/2.2),1.0); //Tone mapping
    }

    one other thing is that I changed GL_TEXTURE_RECTANGLE to GL_TEXTURE_2D in your code, but still I can't see any result!

  6. #6
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    19

    Re: Creating texture from HDR image

    Problem solved!! I made a stupid mistake by creating the texture before initializing glut!! you code works perfectly Rosario Leonardi! tnx a lot!

  7. #7
    Senior Member Regular Contributor Rosario Leonardi's Avatar
    Join Date
    Aug 2008
    Location
    Italy
    Posts
    356

    Re: Creating texture from HDR image

    No problem.
    Your code didn't work cause your Color class have only RGB information.
    So in memory you have
    RGBRGBRGBRGBRGBRGBRGBRGB...
    but when you use

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, light_tex.m_iWidth, light_tex.m_iHeight, 0, GL_RGBA, GL_FLOAT, light_tex.m_Image);

    you are telling openGl that your image data are GL_RGBA
    so, openGL expect data as RGBARGBARGBARGBA... messing up everything.

    Passing the data in the right format also avoid a lot of work to openGl speed up the code.

    If you are going to use my code, that was a fast test to check the best HDR format for my after effect, so, no mipmap, no filter. If you are going to use that as a texture probably you need some filter. Also keep in mind that float16 picture use an huge amount of memory.
    ~ ~ I tell you, realtime 3D is made of blood, sweat and screams! ~ ~

  8. #8
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    19

    Re: Creating texture from HDR image

    it's always good to know where you're making mistake! tnx a lot for your explanation!

Similar Threads

  1. Creating a cursor shaped image as a 2D layer
    By Rakefet in forum OpenGL: Basic Coding
    Replies: 0
    Last Post: 11-01-2011, 12:59 PM
  2. creating a background image
    By Giancarlo in forum OpenGL: Advanced Coding
    Replies: 19
    Last Post: 07-26-2009, 03:56 PM
  3. problem in drawing a texture image(monochrome image)
    By philm in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 03-07-2003, 10:45 AM
  4. problem in drawing a texture image ( monochrome image)
    By philm in forum OpenGL: Advanced Coding
    Replies: 0
    Last Post: 03-07-2003, 09:00 AM
  5. Creating a texture
    By I_NeedHelp in forum OpenGL: Basic Coding
    Replies: 6
    Last Post: 01-15-2003, 01:38 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean