C++ 如何在 GLUT 上加载 bmp 以将其用作纹理?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12518111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:20:58  来源:igfitidea点击:

How to load a bmp on GLUT to use it as a texture?

c++opengltexturesglutbmp

提问by Patricio Jerí

I've been searching all around for a simple solution to add sprites to my OpenGl GLUT simple moon lander game in c++ and it appears I must use bmp's since they're easiest to load and use them as textures on a rectangle.

我一直在四处寻找一个简单的解决方案,以在 C++ 中将精灵添加到我的 OpenGl GLUT 简单月球着陆器游戏中,看来我必须使用 bmp,因为它们最容易加载并用作矩形上的纹理。

How exactly can I load the bmp's as textures though?

我究竟如何才能将 bmp 加载为纹理?

回答by Dinesh Subedi

Look my simple c implementation function to load texture.

看我简单的c实现函数来加载纹理。

GLuint LoadTexture( const char * filename )
{
  GLuint texture;
  int width, height;
  unsigned char * data;

  FILE * file;
  file = fopen( filename, "rb" );

  if ( file == NULL ) return 0;
  width = 1024;
  height = 512;
  data = (unsigned char *)malloc( width * height * 3 );
  //int size = fseek(file,);
  fread( data, width * height * 3, 1, file );
  fclose( file );

  for(int i = 0; i < width * height ; ++i)
  {
    int index = i*3;
    unsigned char B,R;
    B = data[index];
    R = data[index+2];

    data[index] = R;
    data[index+2] = B;
  }

  glGenTextures( 1, &texture );
  glBindTexture( GL_TEXTURE_2D, texture );
  glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE );
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST );

  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR );
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT );
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT );
  gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,GL_RGB, GL_UNSIGNED_BYTE, data );
  free( data );

  return texture;
}

Above function returns the texture data. Store the texture data in variable

以上函数返回纹理数据。将纹理数据存储在变量中

GLuint texture;
texture= LoadTexture( "your_image_name.bmp" );

Now you can bind the texture using glBindTexture

现在您可以使用 glBindTexture 绑定纹理

glBindTexture (GL_TEXTURE_2D, texture);

回答by Mortennobel

Checkout my the TextureLoader (TextureLoader.h + TextureLoader.cpp) from OpenGL_3_2_Utils:

从 OpenGL_3_2_Utils 查看我的 TextureLoader (TextureLoader.h + TextureLoader.cpp):

https://github.com/mortennobel/OpenGL_3_2_Utils

https://github.com/mortennobel/OpenGL_3_2_Utils

The two files does not depend on any other files and should also work seamless on any version of OpenGL (and any platform). Example usage can be found in the file comment.

这两个文件不依赖于任何其他文件,也应该可以在任何版本的 OpenGL(和任何平台)上无缝运行。示例用法可以在文件注释中找到。

回答by XiaJun

You can use library GLAUX and SOIL(Simple OpenGL Image Library). There are also other image libriries for OpenGL.

您可以使用库 GLAUX 和SOIL(Simple OpenGL Image Library)。还有其他用于 OpenGL 的图像库

回答by Rabbid76

How to load a bmp on GLUT to use it as a texture?

如何在 GLUT 上加载 bmp 以将其用作纹理?

Another very simple solution would be to use STB library, which can be found at GitHub - nothings/stb.

另一个非常简单的解决方案是使用STB 库,它可以在GitHub - nothings/stb 上找到

All what is needed is one source file, the header file "stb_image.h". It doesn't require to link any library file or to compile any additional source file.

所需要的只是一个源文件,即头文件“stb_image.h”。它不需要链接任何库文件或编译任何额外的源文件。

Include the header file and enable image reading by the setting the preprocessor definition STB_IMAGE IMPLEMENTATION:

包含头文件并通过设置预处理器定义启用图像读取STB_IMAGE IMPLEMENTATION

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

The image file can be read by the function stbi_load:

图像文件可以被函数读取stbi_load

const char *filename = .....; // path and filename
int         req_channels = 3; // 3 color channels of BMP-file   

int width = 0, height = 0, channels = 0;
stbi_uc *image = stbi_load( filename, &width, &height, &channels, 3 ); 

When the image is loaded to a texture object, then GL_UNPACK_ALIGNMENThas to be set to 1.
By default GL_UNPACK_ALIGNMENTis 4, so each line of an image is assumed to be aligned to 4 bytes. The pixels of a BMP-file in common have a size of 3 bytes and are tightly packed, this would cause a misalignment.
After loading the image, the memory can be freed by stbi_image_free:

当图像加载到纹理对象时,则GL_UNPACK_ALIGNMENT必须设置为 1。
默认情况下GL_UNPACK_ALIGNMENT为 4,因此假设图像的每一行都对齐到 4 个字节。一个 BMP 文件的像素通常有 3 个字节的大小并且被紧密压缩,这会导致未对齐。
加载图像后,可以通过以下方式释放内存stbi_image_free

GLuint texture_obj = 0;
if ( image != nullptr )
{
    glGenTextures(1, &texture_obj);
    glBindTexture(GL_TEXTURE_2D, texture_obj);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // default

    stbi_image_free( image );
}