質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.80%

OpenGLを使った2D画像描画方法

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,166

score 13

Youtuberの「ゲーム道館」「OpenGL道場第19~20回」を参考にさせていただき、OpenGLを使った2D画像描画プログラムを製作しています
ゲーム道館さんの動画はとても面白く、参考にさせていた抱いています。(>_<)
その中で、少しわからなかったことがあったので質問させていただきました。

まず、画像描画までの過程として、
1・画像のファイルを開く(読み込み)
2・ビットマップファイルヘッダーを読み込む
3・ビットマップインフォヘッダーを読み込む
4・ポインタ型構造体(ピクセル情報)を生成し、全メンバを扱えるようにする。
5・malloc関数を使用しピクセル数分のメモリを確保しポインタ型構造体に代入
6・色情報を補正(変更)
7・画像を反転
8・OpenGLを使用し画像を描画
9・メモリ開放

2・3・5・8がわかりません。

・・・・・・・・・・・・・・・・・・・・2・・・・・・・・・・・・・・・・・・・・・
「BITMAPFILEHEADER bf」はヘッダーのデータを格納する構造体とゲーム道館館長さんがおっしゃっていました。
ビットマップ画像とは、ピクセルを用いたもの(座標と色)
ヘッダとはファイルなどの先頭にあるデータである。
コンピュータはデータを処理する際に、まずヘッダの情報を読み取り、そのデータを処理する方法を判断する。
これはfopen_sで読み込んだ画像データの色情報をBITMAPFILEHEADER bfを使い構造体に格納しているのでしょうか?

・・・・・・・・・・・・・・・・・・・・3・・・・・・・・・・・・・・・・・・・・・
2の質問と同じようになってしまいますが...
BITMAPINFOHEADER biをネットで調べてみた結果、色情報を格納すると記述されていました。
ん~上と一緒
また、BITMAPFILEHEADER bfはBITMAPINFOHEADER biを使用できるようにするための宣言と書いてある記事もありました。どうなのでしょうか?
どのように使って、何が格納されるのか教えてください<(_ _)>

・・・・・・・・・・・・・・・・・・・・5・・・・・・・・・・・・・・・・・・・・・

    typedef struct {
        unsigned char r, g, b;
    }RGB;
    RGB* pixels = (RGB*)malloc(sizeof RGB * bi.biWidth * bi.biHeight);
    fread(pixels,                //格納先のバファ
        sizeof RGB,            //読み込むデータ1つのバイト数
        bi.biWidth* bi.biHeight,//読み込むデータの個数
        pFile);            //ファイルポインタ


ポインタ構造体変数で全メンバを扱えるようmalloc関数を使用しメモリをピクセル数分確保する。まではわかるのですが。
その変数にfreadを使用しどのようなデータが格納され、どのようにpixelsにデータが格納されるのでしょうか?

初めにfopen_sで読み込んだ画像情報の色情報を、pixelsに、一ピクセル3色分RGBのデータを画像分、格納する。と思ったのですが、そしたら2・3の意味がなくなってしまうのではないかな~と思いました。

そして、pixelsにはどのように格納されているのでしょうか?
ピクセルがRGBの3色分であり、1ピクセルにはRGBの順で色情報が並んでおり、それに伴い、pixelsのrgbに確保したメモリ分格納できる?
イメージ説明
画像が汚く本当にすみません。
マウスパッドで書いたから仕方が...

構造体のポインタ変数があまりわからないのですが、なぜこんなにも多くのデータを配列でもないのにかくのうできるのでしょうか?
malloc関数を使用しメモリを確保しているからでしょうか?

・・・・・・・・・・・・・・・・・・・・8・・・・・・・・・・・・・・・・・・・・・
「glTexParameteri()」関数を使いテクスチャマッピングを行う際の種々のパラメータの設定を行うそうなのですが、下のソースコードを見て頂いたらわかると思うのですが、なぜglTexParameteri()関数を使いパラメータの設定をおこなうのでしょうか?
2回目のglTexParameteri()をコメントにしたら画像が消えてしまいましたし...

ポインタ構造体変数はどのような構造をしていて、freadを使用しどのようなデータが格納され、どのようにpixelsにデータが格納されるのか教えてください<(_ _)>

質問攻めになってしまいますが、どうかよろしくお願いします。<(_ _)>

#include <stdio.h>
#include <Windows.h>

#include "glut.h"

#include "tex.h"

int texFromBMP(const char* _fileName) {
    FILE* pFile;
    fopen_s(&pFile, _fileName, "rb");
    if (pFile == nullptr) {
        printf("%s open failed!\n", _fileName);
        return 1;
    }
    printf("%s opened.\n", _fileName);
\*2*\
    BITMAPFILEHEADER bf;        //ヘッダーのデータを格納する構造体
    fread(&bf,            //格納先のバファ
        sizeof BITMAPFILEHEADER,//読み込むデータ1つのバイト数
        1,            //読み込むデータの個数
        pFile);            //ファイルポインタ
    printf("bfSize:%d\n", bf.bfSize);
/*3*/
    BITMAPINFOHEADER bi;
    fread(&bi,            //格納先のバファ
        sizeof BITMAPINFOHEADER,//読み込むデータ1つのバイト数
        1,            //読み込むデータの個数
        pFile);            //ファイルポインタ
/*5*/    
    typedef struct {
        unsigned char r, g, b;
    }RGB;
    RGB* pixels = (RGB*)malloc(sizeof RGB * bi.biWidth * bi.biHeight);
    fread(pixels,                //格納先のバファ
        sizeof RGB,            //読み込むデータ1つのバイト数
        bi.biWidth* bi.biHeight,//読み込むデータの個数
        pFile);            //ファイルポインタ

    for (int y= 0; y < bi.biHeight; y++) {
        for (int x = 0; x < bi.biWidth; x++) {
            RGB* pPixel = &pixels[y * bi.biWidth + x];
            unsigned char temp = pPixel->r;
            pPixel->r = pPixel->b;
            pPixel->b = temp;
        }
    }

    for (int y = 0; y < bi.biHeight/2; y++) 
        for (int x = 0; x < bi.biWidth; x++) {
            RGB* pPixel0 = &pixels[y * bi.biWidth + x];
            RGB* pPixel1 = &pixels[(bi.biHeight -1-y )*bi.biWidth +x];
            RGB temp = *pPixel0;
            *pPixel0 = *pPixel1;
            *pPixel1 = temp;

        }

    glTexImage2D(
        GL_TEXTURE_2D,        // GLenum target
        0,            // GLint level
        GL_RGB,            // GLint internalformat
        bi.biWidth,bi.biHeight,    // GLsizei width, height
        0,            // GLint border
        GL_RGB,                    // GLenum format
        GL_UNSIGNED_BYTE,       // GLenum type
        pixels);        // const GLvoid *pixels
/*8*/
    glTexParameteri(
        GL_TEXTURE_2D,            // GLenum target
        GL_TEXTURE_MAG_FILTER,            // GLenum pname
        GL_NEAREST);            // GLint param
    glTexParameteri(
        GL_TEXTURE_2D,            // GLenum target
        GL_TEXTURE_MIN_FILTER,          // GLenum pname
        GL_NEAREST);            // GLint param

    free(pixels);
    fclose(pFile);

    return 0;
}


追記

  int pixecls_[25] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,12,22,13,14,15};
 int* a = pixecls_;

int main() {
    typedef struct {
        unsigned int r, g, b;
    }RGB2;
    RGB2* pixels2 = (RGB2*)malloc(sizeof RGB2 * 5 * 5);
    pixels2->b = *a;
    pixels2->g = *a;
    pixels2->r = *a;

    for (int i=0; i < 30;i++) {
        printf("pixels->r:%d ,pixels->g:%d ,pixels->b:%d\n",
 pixels->r+i, pixels->g+i, pixels->b+i);
    }
    return 0;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • nskydiving

    2020/02/13 10:04

    その「わからなかったこと」とは何でしょうか?
    質問文が途中で切れてしまっていないでしょうか?

    キャンセル

  • hikar

    2020/02/13 23:04

    ご返答ありがとうございます。なぜか、投稿したはずの質問が初期に戻っていました。
    本当に申し訳ございません。<(_ _)>
    修正させていただきました。
    よろしくお願いします。(>_<)

    キャンセル

回答 1

checkベストアンサー

+1

【2】【3】
BITMAPFILEHEADER、BITMAPINFOHEADER について、認識が誤っています。
以下URLを参照して、どのようなデータが格納されているのか確認してください。

Bitmapファイルフォーマット
http://www.umekkii.jp/data/computer/file_format/bitmap.cgi

【5】

ピクセルがRGBの3色分であり、1ピクセルにはRGBの順で色情報が並んでおり、それに伴い、pixelsのrgbに確保したメモリ分格納できる?

そのイメージで合っていると思います。

構造体のポインタ変数があまりわからないのですが、なぜこんなにも多くのデータを配列でもないのにかくのうできるのでしょうか?
malloc関数を使用しメモリを確保しているからでしょうか?

その通りです。

【8】

「glTexParameteri()」関数を使いテクスチャマッピングを行う際の種々のパラメータの設定を行うそうなのですが、下のソースコードを見て頂いたらわかると思うのですが、なぜglTexParameteri()関数を使いパラメータの設定をおこなうのでしょうか?

拡大時、縮小時のフィルタリング方法を指定しています。
詳細は以下URLを参照してください。

OpenGL ES2.0 入門 基礎編(テクスチャのパラメータ)
https://qiita.com/kazoo/items/27d2c18d14dbb99bebf3

glTexParameter
https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glTexParameter.xml

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/16 12:47

    ご返答ありがとうございました。とても分かりやすくて助かりました。(>_<)
    教えていただいたサイトを参考にさせていただき、理解出来ました。

    「BITMAPINFOHEADER 」を使用しpFileに保持した画像の色ビット数をbiに格納し、
    それを基にmalloc関数を使用しメモリを確保する。
    BITMAPINFOHEADER は画像の情報を多く所持していて、その値を変数に格納してあるから汎用性が高いということですね!
    そして次に、freadを使用し、pFileが保持している色情報をpixelsに格納しているということですね!

    それと追記でソースコードを記載させていただき、試行錯誤を繰り返し、上のようなソースコードにまとめてみました。
    *pixelsに直で*aを代入するとエラーが出てしまいました。
    代入の方法を変えてもみましたが、同じくエラーが出てしまい、上のソースコードのようにメンバに直で*aを代入するに至りました。
    freadでは格納するpixels(r,g,b)にpFile内の色情報を格納するような計算があるということでしょうか?
    (例えば、上のソースコードの用にメンバに直に代入するような....)
    お手数をおかけしますが、何か参考になるサイトなどがありましたら、教えてください<(_ _)>

    キャンセル

  • 2020/02/16 20:32

    ほとんどの回答者は同じ質問は一度しか閲覧しませんので、質問の追加や変更をしても回答を得られる可能性は低いです。
    この質問は「解決済み」にして、別の質問として投稿することをおすすめします。

    キャンセル

  • 2020/02/16 23:55

    ご返答ありがとうございます。<(_ _)>
    そのようにさせていただきます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る