アルファブレンディング

アルファブレンディングです。
アルファブレンディングで注意しなければならない事があります。
いかなるグラフィック描画でも基本的には一番最後に描画したものだけが表示されて、
それまでにあった描画は全て上書きされてしまいます。
ですが、3D描画ライブラリにはデプスバッファやZバッファがあり隠面消去を使うと手前のものは
上書きされないようにすることができます。
しかし、透明度のある物体を描画するときに隠面消去を使用すると本来は色が合成されて
表示されるはずのものが隠面消去により、まるまる描画されなかったりします。
それを解決するには、
1.不透明なオブジェクトを描画
2.半透明オブジェクトをZソート(視点からの奥行き順)
3.半透明オブジェクトの、奥にあるものから描画
という手順を踏む必要があります。
今回のプログラムではスペースキーを押す度にブレンディング係数を切り替えます。

 

ファイル
main.cpp

main.cpp

#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(lib, "glew32.lib")

#include <string>
#include <gl/glew.h>
#include <GL/freeglut/freeglut.h>

using namespace std;

#define WIDTH 640
#define HEIGHT 480

int Current=-1;
string str="";


void display(void)
{
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 glViewport(0, 0, WIDTH, HEIGHT);
 gluPerspective(30.0, double(WIDTH)/HEIGHT, 0.1, 200);
 gluLookAt(0.0, 1.5, 3.0, 0.0 ,0.0 ,0.0, 0.0,1.0, 0.0);

 glDisable(GL_DEPTH_TEST);//デプステストの無効化
 glEnable(GL_BLEND);//ブレンドの有効化

 //奥の物から描画
 glTranslatef(0.0f,0.0f,-1.0f);
 glColor4f(0.0f, 0.0f, 1.0f, 0.5f);//青
 glRectf(-0.5,0.5,0.5,-0.5);
 
 glTranslatef(0.0f,0.0f,1.0f);
 glColor4f(1.f, 0.f, 0.f, 0.7f);//赤
 glRectf(-0.5,0.5,0.5,-0.5);

 glDisable(GL_BLEND);
 glEnable(GL_DEPTH_TEST);

 glutSwapBuffers();
}

void key(unsigned char key , int x , int y) {
 if(key == ' '){//スペースキーで切り替え
  Current++;
  if(Current==6)Current=0;
  str="アルファブレンディング";
  if(Current==0){str+=":0 透明度無し描画";glBlendFunc(GL_ONE, GL_ZERO);}
  if(Current==1){str+=":1 半透明合成";glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);}
  if(Current==2){str+=":2 加算合成";glBlendFunc(GL_SRC_ALPHA, GL_ONE);}
  if(Current==3){str+=":3 減算合成";
  glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE);}
  if(Current==4){str+=":4 乗算合成";
  glBlendEquationEXT(GL_FUNC_ADD_EXT);//glBlendEquationEXTを戻す
  glBlendFunc(GL_ZERO, GL_SRC_COLOR);}
  if(Current==5){str+=":5 反転合成";glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);}
  glutSetWindowTitle(str.c_str());
  glutPostRedisplay();
 }
}

void idle(void)
{
 glutPostRedisplay();
}

void Init(){
 glewInit();
  glClearColor(0.5f, 0.5f, 0.5f, 1.f);
 glEnable(GL_DEPTH_TEST);
 key(' ',0,0);
}

int main(int argc, char *argv[])
{
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(WIDTH, HEIGHT);
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
 glutCreateWindow("アルファブレンディング");
 glutDisplayFunc(display);
 glutKeyboardFunc(key);
 glutIdleFunc(idle);
 Init();
 glutMainLoop();
 return 0;
}

 

添付ファイル