【问题标题】:SDL_surface to OpenGL textureSDL_surface 到 OpenGL 纹理
【发布时间】:2009-05-04 18:11:05
【问题描述】:

嘿,我有这个脚本来加载 SDL_Surface 并将其保存为 OpenGL 纹理:

typedef GLuint texture;

texture load_texture(std::string fname){
    SDL_Surface *tex_surf = IMG_Load(fname.c_str());
    if(!tex_surf){
        return 0;
    }
    texture ret;
    glGenTextures(1, &ret);
    glBindTexture(GL_TEXTURE_2D, ret);
    glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_surf->w, tex_surf->h, 0, GL_RGB, GL_UNSIGNED_BYTE, tex_surf->pixels);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    SDL_FreeSurface(tex_surf);
    return ret;
}

问题是它不起作用。当我从主函数调用该函数时,它只是不加载任何图像(当显示它只是改变绘图颜色时),当从主函数之外的任何函数调用时,程序崩溃。 正是这一行导致程序崩溃:

2D(GL_TEXTURE_2D, 0, 3, tex_surf->w, tex_surf->h, 0, GL_RGB, GL_UNSIGNED_BYTE, tex_surf->pixels);

谁能看出这里有错误?

【问题讨论】:

  • 发布一个最小的、可编译的源代码来展示你的问题。你会得到更好的答案。很难从理论上解释问题是什么。

标签: c++ opengl sdl textures


【解决方案1】:

我敢打赌,您需要先转换 SDL_Surface,然后再尝试将其塞入 OpenGL 纹理。以下内容应该可以让您大致了解:

SDL_Surface* originalSurface; // Load like an other SDL_Surface

int w = pow(2, ceil( log(originalSurface->w)/log(2) ) ); // Round up to the nearest power of two

SDL_Surface* newSurface = 
  SDL_CreateRGBSurface(0, w, w, 24, 0xff000000, 0x00ff0000, 0x0000ff00, 0);
SDL_BlitSurface(originalSurface, 0, newSurface, 0); // Blit onto a purely RGB Surface

texture ret;

glGenTextures( 1, &ret );
glBindTexture( GL_TEXTURE_2D, ret );
glTexImage2D( GL_TEXTURE_2D, 0, 3, w, w, 0, GL_RGB,
          GL_UNSIGNED_BYTE, newSurface->pixels );

I found the original code here。可能还有一些other useful posts on GameDev

【讨论】:

  • 如果没有更多来源,将很难确定为什么您的 blitting 不起作用。你能发布你用来渲染的代码吗?
  • 你为什么用ceil()而不是round()
  • @ShambhavGautam 很难说,因为我在 11 年前发布了这篇文章,但可能是因为 round() 可以四舍五入,而我只想四舍五入。
【解决方案2】:

问题可能在于对glTexImage2D 的调用的第三个参数(internalformat)。

glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_surf->w, tex_surf->h, 0, GL_RGB, GL_UNSIGNED_BYTE, tex_surf->pixels);

您必须使用像GL_RGBGL_RGBA 这样的常量,因为宏的实际值与颜色分量的数量无关。

参考手册中有一个允许值列表:https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml

这似乎是一个常见的错误。也许有些司机只是聪明并纠正了这一点,所以错误的线路可能仍然适用于某些人。

/usr/include/GL/gl.h:473:#define GL_RGB             0x1907
/usr/include/GL/gl.h:474:#define GL_RGBA            0x1908

【讨论】:

    【解决方案3】:

    我不确定您是否在代码 sn-p 之外的某个地方执行此操作,但您是否调用过

    glEnable(GL_TEXTURE_2D);

    在某个时候?

    【讨论】:

    • 这不仅完全没有帮助,甚至可能导致 OpenGL 上下文出错,因为在较新的 OpenGL 版本中不推荐使用固定管道纹理。
    【解决方案4】:

    一些较旧的硬件(令人惊讶的是,emscripten 的 opengl ES 2.0 仿真,在我今年购买的新机器上运行)似乎不支持尺寸不是 2 次方的纹理。原来是我被困了一段时间的问题(我得到了一个黑色矩形而不是我想要的精灵)。因此,在将图像大小调整为具有 2 次方的尺寸后,海报的问题可能会消失。

    见:https://www.khronos.org/opengl/wiki/NPOT_Texture

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-27
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2011-05-19
      • 1970-01-01
      相关资源
      最近更新 更多