简体   繁体   English

SDL_surface 到 OpenGL 纹理

[英]SDL_surface to OpenGL texture

Hey, I have this script to load a SDL_Surface and save it as a OpenGL texture:嘿,我有这个脚本来加载 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;
}

The problem is that it isn't working.问题是它不起作用。 When I call the function from the main function, it just doesn't load any image (when displaying it's just turning the drawing color), and when calling from any function outside the main function, the program crashes.当我从 main 函数调用该函数时,它只是不加载任何图像(显示时它只是改变绘图颜色),并且当从 main 函数之外的任何函数调用时,程序崩溃。 It's this line that makes the program crash:正是这一行使程序崩溃:

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

Can anybody see a mistake in this?任何人都可以看到这个错误吗?

My bet is you need to convert the SDL_Surface before trying to cram it into an OpenGL texture.我敢打赌,您需要先转换 SDL_Surface,然后再尝试将其塞入 OpenGL 纹理。 Here's something that should give you the general idea:这里有一些东西可以让你大致了解:

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 . 我在这里找到了原始代码 There may be some other useful posts on GameDev as well. GameDev 上可能还有其他一些有用的帖子

The problem lies probably in 3rd argument ( internalformat ) of the call to glTexImage2D .问题可能在于调用glTexImage2D第三个参数( internalformat )。

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

You have to use constants like GL_RGB or GL_RGBA because the actual values of the macro are not related to the number of color components.您必须使用GL_RGBGL_RGBA类的GL_RGB ,因为宏的实际值与颜色分量的数量无关。

A list of allowed values is in the reference manual: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml .允许值的列表在参考手册中: https : //www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml

This seems to be a frequent mistake.这似乎是一个常见的错误。 Maybe some drivers are just clever and correct this, so the wrong line might still work for some people.也许有些司机只是聪明并纠正了这一点,所以错误的线路可能仍然适用于某些人。

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

Also, the default GL_REPLACE texture blending mode will multiply the current glColor with the incoming texel RGB values. 同样,默认的GL_REPLACE纹理混合模式会将当前的glColor与传入的texel RGB值相乘。 Consequence: glColor3f(0,0,0) will give you black where your texture should be :) 结果:glColor3f(0,0,0)将在纹理应为:)的地方为黑色:)

Make sure you glColor3f(1,1,1) before drawing your textured geometry. 在绘制带纹理的几何图形之前,请确保先使用glColor3f(1,1,1)。

Some older hardware (and, surprisingly, emscripten's opengl ES 2.0 emulation, running on the new machine I bought this year) doesn't seem to support textures whose dimensions aren't powers of two.一些较旧的硬件(令人惊讶的是,在我今年购买的新机器上运行的 emscripten 的 opengl ES 2.0 仿真)似乎不支持尺寸不是 2 的幂的纹理。 That turned out to be the problem I was stuck on for a while (I was getting a black rectangle rather than the sprite I wanted).结果证明这是我被困了一段时间的问题(我得到了一个黑色矩形而不是我想要的精灵)。 So it's possible the poster's problem would go away after resizing the image to have dimensions that are powers of two.因此,在将图像大小调整为具有 2 的幂的尺寸后,海报的问题可能会消失。

See: https://www.khronos.org/opengl/wiki/NPOT_Texture请参阅: https : //www.khronos.org/opengl/wiki/NPOT_Texture

I'm not sure if you're doing this somewhere outside your code snippet, but have you called我不确定您是否在代码片段之外的某个地方执行此操作,但是您是否已致电

glEnable(GL_TEXTURE_2D);

at some point?在某一点?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM