OpenEXR + OpenGL未处理的异常

时间:2015-01-01 14:24:05

标签: c++ opengl exception openexr

在尝试从OpenGL SuperBible 5th ed执行示例时,我遇到了很多问题。来自Chapter09 / hdr_bloom。

问题是由于链接OpenEXR库造成的,所以我手工构建它们并用作者的lib替换它们。

现在,我可以设法运行该程序,但是当我尝试加载用作纹理的HDR图像时,我得到了未处理的异常错误。

这是用于加载HDR纹理的代码片段,如果我全部注释掉,程序运行没有问题但是我的对象上没有纹理。

bool LoadOpenEXRImage(char *fileName, GLint textureName, GLuint &texWidth, GLuint &texHeight)
{
    // The OpenEXR uses exception handling to report errors or failures
    // Do all work in a try block to catch any thrown exceptions.
    try
    {
        Imf::Array2D<Imf::Rgba> pixels;
        Imf::RgbaInputFile file(fileName); // UNHANDLED EXCEPTION
        Imath::Box2i dw = file.dataWindow();

        texWidth = dw.max.x - dw.min.x + 1;
        texHeight = dw.max.y - dw.min.y + 1;

        pixels.resizeErase(texHeight, texWidth);

        file.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * texWidth, 1, texWidth);
        file.readPixels(dw.min.y, dw.max.y);

        GLfloat* texels = (GLfloat*)malloc(texWidth * texHeight * 3 * sizeof(GLfloat));
        GLfloat* pTex = texels;

        // Copy OpenEXR into local buffer for loading into a texture
        for (unsigned int v = 0; v < texHeight; v++)
        {
            for (unsigned int u = 0; u < texWidth; u++)
            {
                Imf::Rgba texel = pixels[texHeight - v - 1][u];
                pTex[0] = texel.r;
                pTex[1] = texel.g;
                pTex[2] = texel.b;

                pTex += 3;
            }
        }

        // Bind texture, load image, set tex state
        glBindTexture(GL_TEXTURE_2D, textureName);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, texWidth, texHeight, 0, GL_RGB, GL_FLOAT, texels);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

        free(texels);
    }
    catch (Iex::BaseExc & e)
    {
        std::cerr << e.what() << std::endl;
        //
        // Handle exception.
        //
    }

    return true;
}

它被称为:

LoadOpenEXRImage("window.exr", windowTexture, texWidth, texHeight);

请注意我的标记,该标记显示未处理的异常发生的确切位置。

如果我尝试运行它,我会收到此错误:

  

hdr_bloom.exe中0x77938E19(ntdll.dll)的未处理异常:   0xC0000005:访问冲突写入位置0x00000014。

我的调试器指向这段代码:

virtual void __CLR_OR_THIS_CALL _Lock()
    {   // lock file instead of stream buffer
    if (_Myfile)
        _CSTD _lock_file(_Myfile); // here
    }

这是fstream

的一部分

我的声明如下:

#include <ImfRgbaFile.h>            // OpenEXR headers
#include <ImfArray.h>

#ifdef _WIN32
#pragma comment (lib, "half.lib") 
#pragma comment (lib, "Iex.lib")
#pragma comment (lib, "IlmImf.lib")
#pragma comment (lib, "IlmThread.lib")
#pragma comment (lib, "Imath.lib")
#pragma comment (lib, "zlib.lib")
#endif

#pragma warning( disable : 4244)

我不知道这是否重要,但是当我第一次尝试运行它时,我得到了关于我的zlib.lib的SAFESEH错误,所以我在Linker-&gt; Advanced中关闭了SAFESEH。

作者提供的项目是在VisualStudio2008中创建的,我使用的是较新的版本,并且我在打开时对其进行了转换。

另外,我使用的是Windows 7 64位和Microsoft Visual Studio 2013 Ultimate。

如果需要,请告诉我,我会发布更详细的信息,我试图尽可能地缩短信息。

1 个答案:

答案 0 :(得分:1)

我终于找到了这个问题,虽然我不确定它是怎么回事。

要解决这个问题,我必须创建一个全新的项目,只需复制原始项目中的所有内容,因此我的预测是在原始项目转换期间的某个地方,某些项目属性发生了变化,这导致了一些错误。

我发现这样转换后的项目可能不具备如何在某些目录中写入或读取文件的权限,以及为什么我从fstream获得未处理的异常。

因此,对于具有类似问题的未来人员,不是转换您的项目,而是创建一个全新的项目,只需复制您需要的内容,在我的情况下,我只需要复制Library和Include目录:)。