スポンサーリンク

glActiveTextureでテクスチャの下地の色をテクスチャで設定

glColor3dで下地の色を設定

テクスチャはポリゴンに貼るが、そのポリゴンの色が何色かで張り付けた結果に違いが出る。

以下は、テクスチャを一枚用意し、それをglColor3dでポリゴンの色を指定した上に張り付けた結果。

テクスチャ:https://pixabay.com/ja/photos/%E9%B3%A5-%E3%83%96%E3%83%AB%E3%83%BC%E3%83%90%E3%83%BC%E3%83%89-%E9%B3%A5png-1232416/

//描画関数
void disp(void) {

    glViewport(0, 0, winwidth, winheight);

    glClearColor(0.2, 0.2, 0.2, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_CULL_FACE);
    double v = 0.95;

    //下地の色を設定
    glColor3d(1, 0, 0);
    //テクスチャを有効化
    glBindTexture(GL_TEXTURE_2D, texname);
    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);

    glTexCoord2d(0, 1);
    glVertex2d(-v, -v);

    glTexCoord2d(1, 1);
    glVertex2d(v, -v);

    glTexCoord2d(1, 0);
    glVertex2d(v, v);

    glTexCoord2d(0, 0);
    glVertex2d(-v, v);

    glEnd();
    glFlush();
}

glActiveTexture

glActiveTextureを使うと、下地の色用のテクスチャと、張り付けたい画像のテクスチャを同時に指定できる。「同時に指定できる」とはつまり、普通glBindTextureを一度実行したらほかのテクスチャは無効になるが、glActiveTextureを使えば二つのglBindTextureを有効にできるという意味。

OpenGLにはテクスチャスロットのような概念がある。

glActiveTexture(GL_TEXTURE0);

で、「これからスロット名"GL_TEXTURE0"の設定をする」という意味になる。

そして、一つのスロットで一度に使えるテクスチャは一枚だけで、これは「最後にglBindTextureで指定したテクスチャ」だが、一度に複数のスロットを使えるので、各スロットで glEnable(GL_TEXTURE_2D)でそのスロットを有効にしてやれば、テクスチャを複数使うことができる。

#include <iostream>

#include <Windows.h>
#include <gl/glew.h>// glActiveTextureに必要
#include <gl/GL.h>
#include <gl/GLU.h>
#include <gl/freeglut.h>

#pragma comment(lib,"glew32.lib")

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

// freeglut:
// http://freeglut.sourceforge.net/

//ウィンドウの幅と高さ
int winwidth, winheight;



GLuint texname_img;
GLuint texname_block;

//下地用のテクスチャ
void init_tex_block() {

    unsigned char pixels[] = {
        255,  0,  0,
          0,255,  0,
          0,  0,255,
        255,255,255
    };

    glGenTextures(1, &texname_block);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texname_block);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glTexImage2D(
        GL_TEXTURE_2D, 0, GL_RGB, 2, 2,
        0, GL_RGB, GL_UNSIGNED_BYTE, pixels
    );
}
//画像読み込み,テクスチャとしてロード
//pngの読み込みに STBライブラリを使用
//https://suzulang.com/stb-library-image-read/
//https://github.com/nothings/stb
void init_tex_img()
{
    unsigned char* pixels;
    int bpp;
    int imgwidth;
    int imgheight;

    // ファイルを読み込み、画像データを取り出す
    //   最後の引数でピクセルあたりのバイト数を強制できる
    pixels = stbi_load(R"(C:\Users\szl\Desktop\bird-1232416_640.png)", &imgwidth, &imgheight, &bpp, 0);

    glGenTextures(1, &texname_img);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texname_img);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glTexImage2D(
        GL_TEXTURE_2D, 0, GL_RGBA, imgwidth, imgheight,
        0, GL_RGBA, GL_UNSIGNED_BYTE, pixels
    );



    // メモリ上の画像データを破棄
    stbi_image_free(pixels);


}


//描画関数
void disp(void) { glViewport(0, 0, winwidth, winheight); glClearColor(0.2, 0.2, 0.2, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); double v = 0.95;
    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D,texname_block);
    glActiveTexture(GL_TEXTURE1);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texname_img);
    glBegin(GL_QUADS);
    glMultiTexCoord2f(GL_TEXTURE0, 0, 1);
    glMultiTexCoord2f(GL_TEXTURE1, 0, 1);
    glVertex2d(-v, -v);

    glMultiTexCoord2f(GL_TEXTURE0, 1, 1);
    glMultiTexCoord2f(GL_TEXTURE1, 1, 1);
    glVertex2d(v, -v);

    glMultiTexCoord2f(GL_TEXTURE0, 1, 0);
    glMultiTexCoord2f(GL_TEXTURE1, 1, 0);
    glVertex2d(v, v);

    glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
    glMultiTexCoord2f(GL_TEXTURE1, 0, 0);
    glVertex2d(-v, v);

    glEnd();

    glActiveTexture(GL_TEXTURE1);
    glDisable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE0);
    glDisable(GL_TEXTURE_2D);


    glFlush();
}

//ウィンドウサイズの変化時に呼び出される
void reshape(int w, int h) {
    winwidth = w; 
    winheight = h;

    disp();
}



//エントリポイント
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitWindowPosition(100, 50);
    glutInitWindowSize(640, 480);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    glutCreateWindow("sample");
    glutDisplayFunc(disp);
    glutReshapeFunc(reshape);

    glewInit();

    init_tex_img();
    init_tex_block();

    glutMainLoop();

    return 0;
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: