現在地 >> メニュー >> サンプルコード::OpenGL >> リフレクション


問題


「ステンシルバッファ」、「クリップ処理」、「半透明処理」を利用して、
「物体のうつりこみ」を表現せよ。
その他条件:
 キーボードで物体を上下させられるようにせよ
 「↑」:上
 「↓」:下


答え


#include <iostream>
#include <cstdio>
#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>

void display();
void reshape(int w, int h);
void timer(int value);

inline void DRAW_FLOOR();


void SpecialKey(int key, int x, int y);


using namespace std;

inline void GLUT_INIT()
{
glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH| GLUT_STENCIL);
glutInitWindowSize(200,200);
}

inline void GLUT_CALL_FUNC()
{
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(10,timer,0);

glutSpecialFunc(SpecialKey);
}

inline void MY_INIT()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glClearStencil(0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}


int main(int argc, char **argv)
{
glutInit(&argc,argv);
GLUT_INIT();
glutCreateWindow("window name");
GLUT_CALL_FUNC();
MY_INIT();
glutMainLoop();

return 0;
}


double trans_y;
double clip00[]={0,-1,0,0};
/********[ここからコールバック]****************************************/
void display()
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT);

glLoadIdentity();
gluLookAt(1.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);



/***** ステンシル値を1に変えてゆく(REPLACE) *****/
glStencilFunc(GL_ALWAYS, 1, ~0);
glStencilOp(GL_KEEP,GL_REPLACE,GL_REPLACE);
glEnable(GL_STENCIL_TEST); ///////////ステンシル開始////////////////


glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glColorMask(0,0,0,0);

DRAW_FLOOR(); //床

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glColorMask(1,1,1,1);




/***** これ以降はステンシル値1のみ該当 *****/
glStencilFunc(GL_EQUAL, 1, ~0);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);


glEnable(GL_CLIP_PLANE0); //プレーンクリップ開始
glClipPlane(GL_CLIP_PLANE0, clip00);


/* 物体 うつりこみ用 */
glPushMatrix();
glScaled(1.0, -1.0, 1.0);
glTranslated(0,trans_y,0);
glutSolidCube(0.5); //物体
glPopMatrix();

glDisable(GL_CLIP_PLANE0); //プレーンクリップ終了



glDisable(GL_STENCIL_TEST); ///////////ステンシル終了//////////////////////




/***** これ以降が本体 *****/

glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4d(1,0,0,0.5);
DRAW_FLOOR(); //床
glDisable(GL_BLEND);



glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glPushMatrix();
glTranslated(0,trans_y,0);
glutSolidCube(0.5); //物体
glPopMatrix();


glutSwapBuffers();

}


void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);

}

void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(1,timer,0); //タイマー関数
}



void SpecialKey(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_UP:
trans_y += 0.1;
break;

case GLUT_KEY_DOWN:
trans_y -= 0.1;
break;

}
}


inline void DRAW_FLOOR()
{

glBegin(GL_QUADS);
glVertex3d(-1,0,-1);
glVertex3d(-1,0,1);
glVertex3d(1,0,1);
glVertex3d(1,0,-1);
glEnd();
}

メモ


y軸反転はglScaled(1,-1,1)。

プレーンクリップをすることで、
物体が床より下に沈んだ後のうつりこみが消えるようになっている。

光源の処理のON・OFFのせいで見にくいコードかも..

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます