mieki256's diary



2024/02/28(水) [n年前の日記]

#1 [prog] SOILのインストールと使い方をメモ

OpenGLの利用時、テクスチャ画像ファイルの読み込み等を簡単にしてくれる、SOIL (Simple OpenGL Image Library) というライブラリがある。試用してみた。

環境は、Windows10 x64 22H2 + MinGW (gcc 9.2.0、OSDN版), MSYS2 (gcc 13.2.0)。

MSYS2上でインストール :

MSYS2 は SOIL のパッケージも用意されている。ありがたや。pacman でインストールできる。
  • pacman -Ss hoge でパッケージの検索。
  • pacman -S hoge でパッケージのインストール。
$ pacman -Ss soil
mingw32/mingw-w64-i686-soil 1.16.0-2 [インストール済み]
    C library used for loading image files into OpenGL (mingw-w64)
mingw64/mingw-w64-x86_64-soil 1.16.0-2 [インストール済み]
    C library used for loading image files into OpenGL (mingw-w64)
...

$ pacman -S mingw-w64-i686-soil mingw-w64-x86_64-soil

MinGW上でインストール :

MinGW (gcc 9.2.0、OSDN版)の場合は、公式サイトで公開されてるzipを入手して、中に入っている libsoil.a と SOIL.h を使う。ただ、公式サイトは消滅してしまっているので、WebArchive から入手した。

_lonesock.net: SOIL (WebArchive)

「here」と書かれてるところのリンクをクリックすれば、soil.zip が入手できる。解凍すると、lib/ に libSOIL.a が、src/ に SOIL.h が入ってる。
  • libSOIL.a を、MinGWインストールフォルダ/lib/ にコピー。
  • SOIL.h を、MinGWインストールフォルダ/include/ 内に、SOIL/ というディレクトリを作ってから、その中にコピー。

SOILの使い方 :

C言語のソースの最初のほうで、以下を記述。
#include <SOIL/SOIL.h>

例えば logo.png という画像をテクスチャ画像として読み込むなら、以下のように記述。正常に読み込めたら 0 より大きい値が返ってくる。
  // load texture image file. use SOIL
  tex_id = SOIL_load_OGL_texture("logo.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_POWER_OF_TWO);
  if (tex_id > 0)
  {
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex_id);
  }
  else
  {
    glDisable(GL_TEXTURE_2D);
  }
  
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_BLEND);

gcc や g++ にリンク指定をする際は、-lSOIL と記述する。以下は一例。
gcc 01_helloglfw.c -o 01_helloglfw.exe -static -lSOIL -lglfw3 -lopengl32 -lwinmm -lgdi32 -mwindows

ただ、-lSOIL を最初のほうに書いておかないと、何故かリンクエラーが出てしまう。

SOIL/SOIL.h を眺めると、memory がどうとかの関数もあるので、おそらくメモリ上に存在する画像ファイルのバイナリを利用してテクスチャにすることもできたりするのではないかと…。また、OpenGLの描画画面を画像ファイルとして保存する機能もあるように見えた。

サンプルソース :

png画像をテクスチャ画像として読み込んで、OpenGL + glfw3 で描画するサンプルを書いてみた。MinGW (gcc 9.2.0、OSDN版)、MSYS2 gcc 13.2.0 でコンパイルできることを確認した。

_01_helloglfw.c
#include <stdlib.h>
#include <stdio.h>
#include <GLFW/glfw3.h>
#include <SOIL/SOIL.h>

void error_callback(int error, const char *description)
{
  fprintf(stderr, "Error: %s\n", description);
}

static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
  if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
  {
    glfwSetWindowShouldClose(window, GLFW_TRUE);
  }
}

int main(void)
{
  GLFWwindow *window;
  GLuint tex_id;

  glfwSetErrorCallback(error_callback);

  if (!glfwInit())
  {
    // Initialization failed
    exit(EXIT_FAILURE);
  }

  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1); // set OpenGL 1.1
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

  // create window
  window = glfwCreateWindow(1280, 720, "Hello GLFW", NULL, NULL);
  if (!window)
  {
    // Window or OpenGL context creation failed
    glfwTerminate();
    exit(EXIT_FAILURE);
  }

  glfwSetKeyCallback(window, key_callback);

  glfwMakeContextCurrent(window);

  glfwSwapInterval(1);

  // load texture image file. use SOIL
  tex_id = SOIL_load_OGL_texture("logo.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_POWER_OF_TWO);
  if (tex_id > 0)
  {
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex_id);
  }
  else
  {
    glDisable(GL_TEXTURE_2D);
  }

  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_BLEND);

  int scrw, scrh;
  glfwGetFramebufferSize(window, &scrw, &scrh);
  glViewport(0, 0, scrw, scrh);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  double a = (double)scrw / (double)scrh;
  glOrtho(-a, a, -1.0, 1.0, 1.0, -1.0);
  
  double angle = 0.0;

  // main loop
  while (!glfwWindowShouldClose(window))
  {
    angle += (45.0 / 60.0);

    glClearColor(0.1, 0.2, 0.4, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(angle, 0, 0, 1);

    float w = 0.8;
    float h = 0.8;
    glColor4f(1.0, 1.0, 1.0, 1.0);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-w, +h, -0.5);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(+w, +h, -0.5);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(+w, -h, -0.5);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-w, -h, -0.5);
    glEnd();

    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  glfwDestroyWindow(window);
  glfwTerminate();
  exit(EXIT_SUCCESS);
}


使用画像は以下。512x512、RGBAのpng画像。

_logo.png


Makefile は以下。

_Makefile
01_helloglfw.exe: 01_helloglfw.c Makefile
    gcc 01_helloglfw.c -o 01_helloglfw.exe -static -lSOIL -lglfw3 -lopengl32 -lwinmm -lgdi32 -mwindows
#   gcc 01_helloglfw.c -o 01_helloglfw.exe -static -lSOIL -lglfw3dll -lopengl32 -lwinmm -lgdi32 -mwindows

.PHONY: clean
clean:
    rm -f *.exe
    rm -f *.o

もし、MinGW gcc 9.2.0 (OSDN版)ではなくて、MinGW gcc 6.3.0 (SourceForge版) を使う時は、-lglfw3 を -lglfw3dll にして、glfw3.dll をプロジェクトフォルダにコピーしておく必要がある。

make と打ってコンパイルして、01_helloglfw.exe を生成。

実行結果。




png画像を読み込んで、テクスチャ画像として利用できていることが分かる。

以上です。

過去ログ表示

Prev - 2024/02 - Next
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project