openglのテクスチャマッピング

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
chin

openglのテクスチャマッピング

#1

投稿記事 by chin » 13年前

現在openglを用いて、入力画像をテクスチャマッピングするプログラムを作成しています。
メインコードのは以下のようになっています。
【やりたいこと】
入力画像を3次元平面にマッピングするプログラムの作成

【現状】
・カメラビューの計算、表示は正しく動作する
・マウス操作(プログラム中のトラックボール操作)は正しく動作する
・現状は入力画像ではなく、毎ループ単色画像を生成し、赤(255,0,0,128)を表示しようとしている
→失敗(平面は白一色 光源関連は正しくできていると思われる(?))

【補足】
毎ループ画像を作っている理由は、最終的に毎ループUSBカメラ画像から得られた
画像をテクスチャマッピングしたいからです。

参照しているtrackball.hは和歌山大学 床井先生のソースコードで、
http://read.pudn.com/downloads175/sourc ... ll.h__.htm
http://read.pudn.com/downloads175/sourc ... .cpp__.htm
から得られます。


どうすれば正しく表示されるのでしょうか。
よろしくお願いいたします。

コード:

// NuiApi.hの前にWindows.hをインクルードする
#include <Windows.h>
#include <NuiApi.h>
#include <vector>
#include <opencv2/opencv.hpp>
#include <GL/gl.h>
#include <GL/glut.h>
#include "trackball.h"

#define TEXWIDTH	512	//	テクスチャの幅
#define TEXHEIGHT	512	//	テクスチャの高さ

GLubyte texture[TEXHEIGHT][TEXWIDTH][4];	//	テクスチャ領域

//	光源の設定
static const GLfloat lightpos[] = { 0.0, 0.0, 5.0, 1.0 };	//	位置
static const GLfloat lightcol[] = { 1.0, 1.0, 1.0, 1.0 };	//	直接光強度
static const GLfloat lightamb[] = { 0.1, 0.1, 0.1, 1.0 };	//	環境光強度

void	scene(void) {
	int width  = 512;
	int height = 480;
	static const GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
	static const GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 };

	//	材質の設定
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuse);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f);

	for (int i = 0; i < height; i++) {
		for (int j = 0; j < width; j++)
		{
			texture[i][j][0] = 255;
			texture[i][j][1] = 0;
			texture[i][j][2] = 0;
			texture[i][j][3] = 128;
		}
	}

	//	テクスチャをOpenGLへ渡します
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXWIDTH, TEXHEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);

	//	1枚の4角形を描く
	glNormal3d(0.0, 0.0, 1.0);
	glBegin(GL_QUADS);
	glTexCoord2d(0.0, 1.0);
	glVertex3d(-1.0, -1.0,  0.0);
	glTexCoord2d(1.0, 1.0);
	glVertex3d( 1.0, -1.0,  0.0);
	glTexCoord2d(1.0, 0.0);
	glVertex3d( 1.0,  1.0,  0.0);
	glTexCoord2d(0.0, 0.0);
	glVertex3d(-1.0,  1.0,  0.0);
	glEnd();
}

void display_(void)
{
	//	モデルビュー変換行列の初期化
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	//	画面クリア
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//	光源の位置を設定
	glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

	//	視点の移動(物体の方を奥に移動)
	glTranslated(0.0, 0.0, -3.0);

	//	トラックボール処理による回転
	glMultMatrixd(trackballRotation());

	//	シーンの描画
	scene();

	//	ダブルバッファリング
	glutSwapBuffers();
}

void idle(void)
{
    glutPostRedisplay();
}

void resize_(int w, int h)
{
	//	トラックボールする範囲
	trackballRegion(w, h);

	//	ウィンドウ全体をビューポートにする
	glViewport(0, 0, w, h);

	//	透視変換行列の指定
	glMatrixMode(GL_PROJECTION);

	//	透視変換行列の初期化
	glLoadIdentity();
	gluPerspective(60.0, (double)w / (double)h, 1.0, 100.0);
}

void mouse(int button, int state, int x, int y)
{
	switch (button)
	{
		case GLUT_LEFT_BUTTON:
			switch (state)
			{
				case GLUT_DOWN:
					//	トラックボール開始
					trackballStart(x, y);
					break;
				case GLUT_UP:
					//	トラックボール停止
					trackballStop(x, y);
					break;
				default:
					break;
			}
		break;
		default:
		break;
	}
}

void	motion(int x, int y)
{
	//	トラックボール移動
	trackballMotion(x, y);
}


void keyboard(unsigned char key, int x, int y)
{
    switch (key) {
    case 'q':
    case 'Q':
    case '\033':  /* '\033' は ESC の ASCII コード */
        exit(0);
    default:
        break;
    }
}

void init(void)
{
    glClearColor(1.0, 1.0, 1.0, 1.0);
}


void GLTextureInit () {

	//	テクスチャ領域の初期化
	memset(&texture, 0x0, sizeof(texture));

	//	テクスチャ画像はバイト単位に詰め込まれている
	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);

	//	テクスチャの繰り返し方法の指定
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	//	初期設定
	glClearColor(0.3, 0.3, 1.0, 0.0);
	glEnable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);

	//	光源の初期設定
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, lightcol);
	glLightfv(GL_LIGHT0, GL_SPECULAR, lightcol);
	glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb);
	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);   
}

int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
	glutCreateWindow(argv[0]);
	glutDisplayFunc(display_);
	glutReshapeFunc(resize_);
	glutIdleFunc(idle);
	glutMouseFunc(mouse);
	glutMotionFunc(motion);
	glutKeyboardFunc(keyboard);
	init();
	GLTextureInit ();
	glutMainLoop();
	return 0;
}

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: openglのテクスチャマッピング

#2

投稿記事 by ISLe » 13年前

テクスチャを使うには、あらかじめglGenTexturesでテクスチャオブジェクトを作成しテクスチャ番号を取得しておいて、テクスチャオブジェクトにアクセスする際にはglBindTextureでターゲットにバインドする必要があります。

GL_TEXTURE_2Dはターゲット名です。

chin

Re: openglのテクスチャマッピング

#3

投稿記事 by chin » 13年前

ISLeさん ご回答ありがとうございます。
以下のようにコードを変更しました。
ISLeさんの意図したとおりに実装できていないと思われ、
実際にも正しく動作しませんでした(同様に白いテクスチャになってしまう→失敗)。
どこが間違っているのでしょうか?

コード:

// NuiApi.hの前にWindows.hをインクルードする
#include <Windows.h>
#include <NuiApi.h>
#include <vector>
#include <opencv2/opencv.hpp>
#include <GL/gl.h>
#include <GL/glut.h>
#include "trackball.h"
 
#define TEXWIDTH    512 //  テクスチャの幅
#define TEXHEIGHT   512 //  テクスチャの高さ
 
GLubyte texture[TEXHEIGHT][TEXWIDTH][4];    //  テクスチャ領域
GLuint texName; //////////////////////////////////////////////////////////////////////////////////////// new
 
//  光源の設定
static const GLfloat lightpos[] = { 0.0, 0.0, 5.0, 1.0 };   //  位置
static const GLfloat lightcol[] = { 1.0, 1.0, 1.0, 1.0 };   //  直接光強度
static const GLfloat lightamb[] = { 0.1, 0.1, 0.1, 1.0 };   //  環境光強度
 
void    scene(void) {
    int width  = 512;
    int height = 480;
    static const GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
    static const GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 };
 
    //  材質の設定
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuse);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f);

    glBindTexture(GL_TEXTURE_2D , texName);  ////////////////////////////////////////////////////////// new
 
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++)
        {
            texture[i][j][0] = 255;
            texture[i][j][1] = 0;
            texture[i][j][2] = 0;
            texture[i][j][3] = 128;
        }
    }
 
    //  テクスチャをOpenGLへ渡します
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXWIDTH, TEXHEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
 
    //  1枚の4角形を描く
    glNormal3d(0.0, 0.0, 1.0);
    glBegin(GL_QUADS);
    glTexCoord2d(0.0, 1.0);
    glVertex3d(-1.0, -1.0,  0.0);
    glTexCoord2d(1.0, 1.0);
    glVertex3d( 1.0, -1.0,  0.0);
    glTexCoord2d(1.0, 0.0);
    glVertex3d( 1.0,  1.0,  0.0);
    glTexCoord2d(0.0, 0.0);
    glVertex3d(-1.0,  1.0,  0.0);
    glEnd();

    glBindTexture( GL_TEXTURE_2D, 0 ); //////////////////////////////////////////////////////////////// new

}
 
void display_(void)
{
    //  モデルビュー変換行列の初期化
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
 
    //  画面クリア
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    //  光源の位置を設定
    glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
 
    //  視点の移動(物体の方を奥に移動)
    glTranslated(0.0, 0.0, -3.0);
 
    //  トラックボール処理による回転
    glMultMatrixd(trackballRotation());
 
    //  シーンの描画
    scene();
 
    //  ダブルバッファリング
    glutSwapBuffers();
}
 
void idle(void)
{
    glutPostRedisplay();
}
 
void resize_(int w, int h)
{
    //  トラックボールする範囲
    trackballRegion(w, h);
 
    //  ウィンドウ全体をビューポートにする
    glViewport(0, 0, w, h);
 
    //  透視変換行列の指定
    glMatrixMode(GL_PROJECTION);
 
    //  透視変換行列の初期化
    glLoadIdentity();
    gluPerspective(60.0, (double)w / (double)h, 1.0, 100.0);
}
 
void mouse(int button, int state, int x, int y)
{
    switch (button)
    {
        case GLUT_LEFT_BUTTON:
            switch (state)
            {
                case GLUT_DOWN:
                    //  トラックボール開始
                    trackballStart(x, y);
                    break;
                case GLUT_UP:
                    //  トラックボール停止
                    trackballStop(x, y);
                    break;
                default:
                    break;
            }
        break;
        default:
        break;
    }
}
 
void    motion(int x, int y)
{
    //  トラックボール移動
    trackballMotion(x, y);
}
 
 
void keyboard(unsigned char key, int x, int y)
{
    switch (key) {
    case 'q':
    case 'Q':
    case '\033':  /* '\033' は ESC の ASCII コード */
        exit(0);
    default:
        break;
    }
}
 
void init(void)
{
    glClearColor(1.0, 1.0, 1.0, 1.0);
}
 
 
void GLTextureInit () {
 
    //  テクスチャ領域の初期化
    memset(&texture, 0x0, sizeof(texture));
 
    //  テクスチャ画像はバイト単位に詰め込まれている
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glGenTextures(1 , &texName); ////////////////////////////////////////////////////////////////////// new
 
    //  テクスチャを拡大・縮小する方法の指定
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
    //  テクスチャの繰り返し方法の指定
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
    //  初期設定
    glClearColor(0.3, 0.3, 1.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);
 
    //  光源の初期設定
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightcol);
    glLightfv(GL_LIGHT0, GL_SPECULAR, lightcol);
    glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb);
    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);   
}
 
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
    glutCreateWindow(argv[0]);
    glutDisplayFunc(display_);
    glutReshapeFunc(resize_);
    glutIdleFunc(idle);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);
    init();
    GLTextureInit ();
    glutMainLoop();
    return 0;
}

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: openglのテクスチャマッピング

#4

投稿記事 by ISLe » 13年前

169,170,173,174行目でテクスチャターゲットに対して設定していますが、テクスチャオブジェクトがバインドされていません。

ポリゴンを描画する前(scene関数49行目より前)に、
glEnable(GL_TEXTURE_2D);
としてテクスチャを有効にして、
ポリゴンを描画した後(scene関数58行目より後)に、
glDisable(GL_TEXTURE_2D);
としてテクスチャを無効にしてください。

テクスチャ番号0に特別な意味は無いはずです。

chin

Re: openglのテクスチャマッピング

#5

投稿記事 by chin » 13年前

ISLeさん ご回答ありがとうございます。
テクスチャは最終的にカメラ画像しか使わないということで、
以下のように、バインド作業せずに単純に描写前にTexImageをメモリにレジストするように変更しました。

動作は思った通りに動きました。
的確なご回答ありがとうございました。
現状で新たな質問が出てきそうなので、それは新たにスレッドを立てます。

ありがとうございました。次回もよろしくお願いいたします。

コード:

// NuiApi.hの前にWindows.hをインクルードする
#include <Windows.h>
#include <NuiApi.h>
#include <vector>
#include <opencv2/opencv.hpp>
#include <GL/gl.h>
#include <GL/glut.h>
#include "trackball.h"
 
#define TEXWIDTH    512 //  テクスチャの幅
#define TEXHEIGHT   512 //  テクスチャの高さ
 
GLubyte texture[TEXHEIGHT][TEXWIDTH][4];    //  テクスチャ領域
 
//  光源の設定
static const GLfloat lightpos[] = { 0.0, 0.0, 5.0, 1.0 };   //  位置
static const GLfloat lightcol[] = { 1.0, 1.0, 1.0, 1.0 };   //  直接光強度
static const GLfloat lightamb[] = { 0.1, 0.1, 0.1, 1.0 };   //  環境光強度
 
void    scene(void) {
    int width  = 512;
    int height = 480;
    static const GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
    static const GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 };
 
    //  材質の設定
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuse);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f);
 
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++)
        {
            texture[i][j][0] = 255;
            texture[i][j][1] = 0;
            texture[i][j][2] = 0;
            texture[i][j][3] = 128;
        }
    }
 
    //  テクスチャをOpenGLへ渡します
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXWIDTH, TEXHEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
 
    //  1枚の4角形を描く
    glEnable(GL_TEXTURE_2D); /////////////////////////////////////////////////////////////// new
    glNormal3d(0.0, 0.0, 1.0);
    glBegin(GL_QUADS);
    glTexCoord2d(0.0, 1.0);
    glVertex3d(-1.0, -1.0,  0.0);
    glTexCoord2d(1.0, 1.0);
    glVertex3d( 1.0, -1.0,  0.0);
    glTexCoord2d(1.0, 0.0);
    glVertex3d( 1.0,  1.0,  0.0);
    glTexCoord2d(0.0, 0.0);
    glVertex3d(-1.0,  1.0,  0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D); /////////////////////////////////////////////////////////////// new
 
}
 
void display_(void)
{
    //  モデルビュー変換行列の初期化
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
 
    //  画面クリア
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    //  光源の位置を設定
    glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
 
    //  視点の移動(物体の方を奥に移動)
    glTranslated(0.0, 0.0, -3.0);
 
    //  トラックボール処理による回転
    glMultMatrixd(trackballRotation());
 
    //  シーンの描画
    scene();
 
    //  ダブルバッファリング
    glutSwapBuffers();
}
 
void idle(void)
{
    glutPostRedisplay();
}
 
void resize_(int w, int h)
{
    //  トラックボールする範囲
    trackballRegion(w, h);
 
    //  ウィンドウ全体をビューポートにする
    glViewport(0, 0, w, h);
 
    //  透視変換行列の指定
    glMatrixMode(GL_PROJECTION);
 
    //  透視変換行列の初期化
    glLoadIdentity();
    gluPerspective(60.0, (double)w / (double)h, 1.0, 100.0);
}
 
void mouse(int button, int state, int x, int y)
{
    switch (button)
    {
        case GLUT_LEFT_BUTTON:
            switch (state)
            {
                case GLUT_DOWN:
                    //  トラックボール開始
                    trackballStart(x, y);
                    break;
                case GLUT_UP:
                    //  トラックボール停止
                    trackballStop(x, y);
                    break;
                default:
                    break;
            }
        break;
        default:
        break;
    }
}
 
void    motion(int x, int y)
{
    //  トラックボール移動
    trackballMotion(x, y);
}
 
 
void keyboard(unsigned char key, int x, int y)
{
    switch (key) {
    case 'q':
    case 'Q':
    case '\033':  /* '\033' は ESC の ASCII コード */
        exit(0);
    default:
        break;
    }
}
 
void init(void)
{
    glClearColor(1.0, 1.0, 1.0, 1.0);
}
 
 
void GLTextureInit () {
 
    //  テクスチャ領域の初期化
    memset(&texture, 0x0, sizeof(texture));
 
    //  テクスチャ画像はバイト単位に詰め込まれている
    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);
 
    //  テクスチャの繰り返し方法の指定
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
    //  初期設定
    glClearColor(0.3, 0.3, 1.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);
 
    //  光源の初期設定
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightcol);
    glLightfv(GL_LIGHT0, GL_SPECULAR, lightcol);
    glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb);
    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);   
}
 
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
    glutCreateWindow(argv[0]);
    glutDisplayFunc(display_);
    glutReshapeFunc(resize_);
    glutIdleFunc(idle);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);
    init();
    GLTextureInit ();
    glutMainLoop();
    return 0;
}


閉鎖

“C言語何でも質問掲示板” へ戻る