使用未声明的标识符 GluBuildMipMaps (emscripten)

Posted

技术标签:

【中文标题】使用未声明的标识符 GluBuildMipMaps (emscripten)【英文标题】:Use of undeclared identifier GluBuildMipMaps (emscripten) 【发布时间】:2015-11-19 15:25:22 【问题描述】:

我使用 SDL 创建了一个 OpenGL 程序。我尝试使用 emscripten 将其编译为 html5+JS,但出现此错误:

我不明白,为什么会出现这个错误。 GluBuildMipMaps 定义在glu.h:https://github.com/kripken/emscripten/blob/master/system/include/GL/glu.h

glm 错误也令人困惑,因为我已经将 glm 库复制到了glm 目录,并且它包含在我使用它的地方。


编辑

纯文本的错误信息:

D:\proj\e_bead>emcc main.cpp MyApp.cpp ObjParser_OGL3.cpp -s FULL_ES2=1 -O3 --me
mory-init-file 0
In file included from MyApp.cpp:2:
./GLUtils.hpp:148:2: error: use of undeclared identifier 'gluBuild2DMipmaps'
        gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, loaded_img->w, loaded_i...
        ^
MyApp.cpp:194:25: error: no matching function for call to 'translate'
  ...spaceShipTransform = glm::translate<float>(randnum, randnum, randnum);
                               ^~~~~~~~~~~~~~~~~~~~~
./glm/gtc/matrix_transform.inl:40:35: note: candidate function template not
      viable: requires 2 arguments, but 3 were provided
        GLM_FUNC_QUALIFIER tmat4x4<T, P> translate
                                         ^
./glm/gtx/transform.inl:36:35: note: candidate function template not viable:
      requires single argument 'v', but 3 arguments were provided
        GLM_FUNC_QUALIFIER tmat4x4<T, P> translate(
                                         ^
MyApp.cpp:199:25: error: no matching function for call to 'translate'
  ...spaceShipTransform = glm::translate<float>(randnum, randnum, randnum);
                               ^~~~~~~~~~~~~~~~~~~~~
./glm/gtc/matrix_transform.inl:40:35: note: candidate function template not
      viable: requires 2 arguments, but 3 were provided
        GLM_FUNC_QUALIFIER tmat4x4<T, P> translate
                                         ^
./glm/gtx/transform.inl:36:35: note: candidate function template not viable:
      requires single argument 'v', but 3 arguments were provided
        GLM_FUNC_QUALIFIER tmat4x4<T, P> translate(
                                         ^
MyApp.cpp:234:9: error: no matching function for call to 'translate'
        mvp *= glm::translate(0.0f, 5.0f, 0.0f);
               ^~~~~~~~~~~~~~
./glm/gtc/matrix_transform.inl:40:35: note: candidate function template not
      viable: requires 2 arguments, but 3 were provided
        GLM_FUNC_QUALIFIER tmat4x4<T, P> translate
                                         ^
./glm/gtx/transform.inl:36:35: note: candidate function template not viable:
      requires single argument 'v', but 3 arguments were provided
        GLM_FUNC_QUALIFIER tmat4x4<T, P> translate(
                                         ^
4 errors generated.
ERROR:root:compiler frontend failed to generate LLVM bitcode, halting

编辑2

我已将 glm 库复制到 glm 目录中,并将其包含在以下代码中:

// GLM
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtx/transform2.hpp"

纹理加载代码,其中gluBuild2DMipmaps被调用:

GLuint TextureFromFile(const char* filename)

    SDL_Surface* loaded_img = IMG_Load(filename);  

    int img_mode = 0;

    if ( loaded_img == 0 )
    
        std::cout << "[TextureFromFile] Error when loading image: " << filename << std::endl;
        return 0;
    

    #if SDL_BYTEORDER == SDL_LIL_ENDIAN
        if ( loaded_img->format->BytesPerPixel == 4 )
            img_mode = GL_BGRA;
        else
            img_mode = GL_BGR;
    #else
        if ( loaded_img->format->BytesPerPixel == 4 )
            img_mode = GL_RGBA;
        else
            img_mode = GL_RGB;
    #endif

    GLuint tex;
    glGenTextures(1, &tex);

    glBindTexture(GL_TEXTURE_2D, tex);
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, loaded_img->w, loaded_img->h, img_mode, GL_UNSIGNED_BYTE, loaded_img->pixels);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    SDL_FreeSurface( loaded_img );

    return tex;


编辑3

我已经根据Robert Rouhani 的回答编辑了GLUtils.hpp,现在我在这一行没有出现编译错误:

glBindTexture(GL_TEXTURE_2D, tex);
//gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, loaded_img->w, loaded_img->h, img_mode, GL_UNSIGNED_BYTE, loaded_img->pixels);

glTexImage2D(GL_TEXTURE_2D,
    0,
    GL_RGB,
    loaded_img->w,
    loaded_img->h,
    0,
    img_mode,
    GL_UNSIGNED_BYTE,
    loaded_img->pixels);
glGenerateMipmap(GL_TEXTURE_2D); // /!\ Allocate the mipmaps /!\

【问题讨论】:

更常见的做法是将您收到的错误文本以文本而不是屏幕截图的形式发布,这样既便于现在阅读,也便于日后搜索。这样做可以吗? 感谢您的评论。我编辑了问题。 【参考方案1】:

我对 emscripten 不太熟悉,但从一些搜索来看,您的 FULL_ES2=1 选项似乎意味着您获得了整个 OpenGL ES 2.0 API。我猜这意味着您获得的唯一包含目录是 GLES2 而不是 GL,即包含您链接到的 glu.h 的文件夹。

GLU 现在已经快 20 年了,并且只支持 OpenGL 1.3(2001 年发布)。这意味着你不能在 ES 2.0 中使用它。你想要的是 glGenerateMipmapglHintGL_GENERATE_MIPMAP_HINT 选项。一个例子:

//Create the mipmapped texture
glGenTextures(1, &ColorbufferName);
glBindTexture(ColorbufferName);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_UNSIGNED_BYTE, NULL);
glGenerateMipmap(GL_TEXTURE_2D); // /!\ Allocate the mipmaps /!\

取自this article。

至于 glm 错误,它看起来可以正确找到 glm,只是不喜欢您使用它的方式(并且仅适用于 translate 函数)。您能否发布 MyApp.cpp 中的相关行(有错误的行以及上下几行作为上下文)?

其他人已经让 glm 与 emscripten 合作,也许这个邮件列表帖子会对你有所帮助:https://groups.google.com/forum/#!topic/emscripten-discuss/b6DY3GCDlug


编辑:对于 glm 错误

您只是使用了错误的包含。

glm/gtc/matrix_transform.hpp 仅包含 glm::transform 的一个版本,它接受一个矩阵和一个顶点并返回转换后的矩阵。 glm/gtx/transform2.hpp 不包含任何版本的 glm::translate

你想要的是glm/gtx/transform.hpp

【讨论】:

我不相信这个代码序列会起作用。 glGenerateMipmap() 根据基础纹理级别中的当前数据生成 mipmap。由于您刚刚调用glTexImage2D()NULL 获取数据,因此没有纹理数据,也不会生成mipmap。 @RetoKoradi 代码完全取自文章(由 glm 的作者编写),旨在解释如何/在何处调用 glGenerateMipmap,而不是用于复制/粘贴。尽管如此,为数据传递NULL 是considered valid by the spec。它为所描述的纹理分配足够的内存,因此您的纹理将是黑色或垃圾数据。此外,NULL0 是有效的,如果有任何东西绑定到GL_PIXEL_UNPACK_BUFFER,则将复制像素,因为data 是缓冲区的偏移量。你仍然会得到一个 mipmap。 当然你可以调用glTexImage2D()NULL 来获取数据,这是非常常用的。但是您需要在 用数据填充它之后调用glGenerateMipmap()。仅仅因为代码在互联网上并不能使其正确。 再一次,glTexImage2D 调用不是 sn-p 的重点,这只是一个挑剔。如果您愿意,可以在您的机器上进行测试,我很确定您将在 nvidia 和 Intel 卡上获得带有 mipmap 的黑色纹理,以及在带有 mipmap 的 AMD 上获得某种嘈杂的纹理。内存已分配,OpenGL 不在乎它是垃圾数据还是纹理。 它也来自 g-truc,他编写了 glm 并通读并撰写了对每个新 OpenGL 规范的评论。我相信他的 OpenGL 代码胜过地球上大多数其他人。

以上是关于使用未声明的标识符 GluBuildMipMaps (emscripten)的主要内容,如果未能解决你的问题,请参考以下文章

错误:使用未声明的标识符“touchesBegan”

使用未声明的类型“DKAsset”,使用未解析的标识符“DKImagePickerController”?

使用声明[关闭]的未声明标识符'k'

使用未声明的标识符“top”;您指的是 'pop' 吗?

如何处理`使用未声明的标识符'UIDevice'`

在 CoreLocation 中使用未声明的标识符错误