テクスチャつき背景

opengl-background-tex.png

もし、このとおりにやって背景が見えなくなっちゃったらデプステストを疑え。

bgch.png
#include <Windows.h>
#include <gdiplus.h>
#include <stdio.h>
#include <miffy/gl/glutility.h>
#include <GL/freeglut.h>
#include <string>
#include <iostream>
#include <fstream>
#include <float.h>
#include <assert.h>
#define _USE_MATH_DEFINES 
#include <math.h>//クォータニオンに必要
#include <miffy/math/matrix.h>
#include <miffy/math/quaternion.h>
#include <miffy/math/vertex.h>
 
using namespace std;
bool quaternionflag=false;
const int WINWIDTH =329;
const int WINHEIGHT =484;
float background[3]={0.0,0.0,0.0};//背景色
float myrotate[3]={0.0,0.0,0.0};
float translate_speed=0.01;
float zoom_speed=0.2;
float eyePoint[3]={0.0,0.0,1.2};
miffy::quat<float> current_quaternion(1.0,0.0,0.0,0.0);
miffy::quat<float> target_quaternion;
int previous_x;
int previous_y;
int mouse_down[2];
//回転マトリックス
miffy::mat4<float> rotate;
//平行移動
float trans[3]={0,0,-4.0};//最初のズーム位置を決める
float area=1.0;
float offset=-0.5;
float offsetz=10;
float aspectratio=1.0;//y/xデータの縦横比
//debug情報
//回転行列
miffy::mat4<float> rotation_matrix;
GLuint texId[3];
enum{CHARACTOR,BACKGROUND};
 
GLfloat gFovy=30.0;
GLfloat gNearClip=1.0;
GLfloat gFarClip=100.0;
GLfloat gRatio=(float)WINWIDTH/(float)WINHEIGHT;
void LoadBg(){
    Gdiplus::BitmapData data;
    Gdiplus::GdiplusStartupInput gpSI;
    ULONG_PTR lpToken;
    Gdiplus::GdiplusStartup(&lpToken, &gpSI, NULL);
    Gdiplus::Bitmap* image=new Gdiplus::Bitmap(L"icehotel.jpg");
    image->LockBits( 0,  Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &data );
    glGenTextures( 1, &texId[BACKGROUND] );
    glBindTexture( GL_TEXTURE_2D, texId[BACKGROUND] );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
    glTexImage2D( GL_TEXTURE_2D, 0, 4, data.Width, data.Height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data.Scan0 );
 
    image->UnlockBits( &data );
    delete image;//GdiplusShutdownより後に来てはダメ。
    Gdiplus::GdiplusShutdown(lpToken);
}
 void DrawBackGround(){
     glBindTexture(GL_TEXTURE_2D , texId[BACKGROUND]);
     glEnable(GL_TEXTURE_2D);
    float bgz=-(gFarClip-1.0);
    float size=gNearClip*(float)tan(gFovy*M_PI/360.0)*gFarClip/gNearClip;
    glColor4d(1.0,1.0,1.0,1.0);
    //printf("%f,%f,%f\n",size*gRatio,size,bgz);
    glBegin(GL_QUADS);
        glTexCoord2f(0.0f, 1.0f);glVertex3f(-size*gRatio,-size,bgz); 
        glTexCoord2f(1.0f, 1.0f);glVertex3f( size*gRatio,-size,bgz);
        glTexCoord2f(1.0f, 0.0f);glVertex3f( size*gRatio, size,bgz);
        glTexCoord2f(0.0f, 0.0f);glVertex3f(-size*gRatio, size,bgz);
    glEnd();
    glDisable(GL_TEXTURE_2D);
 
}
 void DrawPlane(){
    glEnable(GL_BLEND);
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glColor4f(0.0,0.0,1.0,1.0);
    //glEnable(GL_BLEND
    glBindTexture(GL_TEXTURE_2D , texId[CHARACTOR]);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GEQUAL,0.5);
 
    glBegin(GL_POLYGON);
    glTexCoord2f(1.0f, 0.0f); glVertex3d(1.0,1.0,0.0);
    glTexCoord2f(0.0f, 0.0f); glVertex3d(-1.0,1.0,0.0);
    glTexCoord2f(0.0f, 1.0f); glVertex3d(-1.0,-1.0,0.0);
    glTexCoord2f(1.0f, 1.0f); glVertex3d(1.0,-1.0,0.0);
    glEnd();
    glDisable(GL_ALPHA_TEST);
    glDisable(GL_TEXTURE_2D);
 
    glDisable(GL_BLEND);
 
}
void LoadPng(){
    Gdiplus::GdiplusStartupInput gpSI;
    ULONG_PTR lpToken;
    Gdiplus::GdiplusStartup(&lpToken, &gpSI, NULL);
    Gdiplus::Bitmap* image=new Gdiplus::Bitmap(L"kanu.png");
    Gdiplus::BitmapData data;
    image->LockBits( 0,  Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &data );
    glGenTextures( 1, &texId[CHARACTOR] );
    glBindTexture( GL_TEXTURE_2D, texId[CHARACTOR] );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
    glTexImage2D( GL_TEXTURE_2D, 0, 4, data.Width, data.Height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data.Scan0 );
 
    image->UnlockBits( &data );
    delete image;//GdiplusShutdownより後に来てはダメ。
    Gdiplus::GdiplusShutdown(lpToken);
 
}
void End(){
 
}
void InitGeometry(){
}
void InitCamera(){
    current_quaternion.toMat4(rotation_matrix.m);
}
void Destroy(){
}
void idle(){
    glutPostRedisplay();
}
void reshape (int w, int h)
{
    //射影変換行列
    glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity (); 
    gRatio=(float)w / (float)h;
    gluPerspective(gFovy, gRatio, gNearClip, gFarClip);
    glMatrixMode (GL_MODELVIEW);
}
void Init(){
    InitGeometry();
    InitCamera();
    LoadPng();
    LoadBg();
}
 
void display(void)
{
    glClearColor(background[0],background[1], background[2], 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
    glEnable(GL_DEPTH_TEST);
 
    glLoadIdentity ();/* clear the matrix */
    DrawBackGround();
    glPushMatrix();
    gluLookAt (eyePoint[0], eyePoint[1], eyePoint[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
 
    glTranslatef(trans[0],trans[1],trans[2]);//平行移動
    glMultMatrixf(rotation_matrix.m);//クォータニオンによる回転
 
    DrawPlane();
 
    glPopMatrix();
    glutSwapBuffers();
 
}
void key(unsigned char key , int x , int y) {
    //printf("key=%d\n",key);
    switch(key){
    case '+':
        trans[2]+=zoom_speed;
        break;
    case '-':
        trans[2]-=zoom_speed;
        break;
    }
    printf("gFarClip=%f\n",gFarClip);
    //printf("zoom%f\n",trans[2]);
    glutPostRedisplay();
}
void wheel(int button, int direction, int x, int y) 
{ 
    if(direction>0){
        trans[2]-=zoom_speed;
    }else{
        trans[2]+=zoom_speed;
    }
    glutPostRedisplay();
}
void mouse(int button , int state , int x , int y) {
 
    if(button == GLUT_RIGHT_BUTTON){//平行移動
 
        quaternionflag=false;
        if(state==GLUT_DOWN){
            mouse_down[0]=x;
            mouse_down[1]=y;
            //printf("down:%d,%d\n",x,y);
        }else if(state==GLUT_UP){
            trans[0]+=translate_speed*(x-mouse_down[0]);
            trans[1]+=-translate_speed*(y-mouse_down[1]);//yは上下逆
            //printf("up:%d,%d\n",x,y);
        }
 
    }
    else 
        if(button == GLUT_LEFT_BUTTON){
            quaternionflag=true;
            switch(state){        
            case GLUT_DOWN://Quaternion:マウスボタンを押した位置を記憶 
                previous_x = x;
                previous_y = y;
            case GLUT_UP://Quaternion:姿勢を保存
                current_quaternion=target_quaternion;
 
                break;
            default:
                break;
            }
 
        }
        glutPostRedisplay();
 
}
//http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20040321
void move(int x, int y)
{
    if(quaternionflag){
        //移動量を計算 画面の中で何%ぐらい動いたか?
        float dx = (x - previous_x) * 1.0/WINWIDTH;
        float dy = (y - previous_y) * 1.0/WINHEIGHT;
 
        //クォータニオンの長さ
        float length = sqrt(dx * dx + dy * dy);
 
        if (length != 0.0) {
            //M_PIは適当な換算係数 piにしておくと、画面いっぱい動かした時にちょうど一回転になる
            float radian = length * M_PI;
            float theta = sin(radian) / length;
            miffy::quat<float> after( cos(radian), dy * theta, dx * theta, 0.0);//回転後の姿勢
            target_quaternion = after * current_quaternion;
            target_quaternion.toMat4(rotation_matrix.m);
 
        }
    }else{//平行移動
        trans[0]+=translate_speed*(x-mouse_down[0]);
        trans[1]+=-translate_speed*(y-mouse_down[1]);//yは上下逆
        mouse_down[0]=x;
        mouse_down[1]=y;
    }
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);       
    //glutMainLoopから抜け出してから何か表示するためのもの
    glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS);
    glutInitWindowSize (WINWIDTH, WINHEIGHT); 
    glutInitWindowPosition (0, 0);
    glutCreateWindow("miffy program");
    glewInit();
    Init();
 
    glutDisplayFunc(display);
    glutIdleFunc(idle);
 
    glutReshapeFunc(reshape);
    glutKeyboardFunc(key);
    glutMouseFunc(mouse);
    glutMotionFunc(move);
    glutMouseWheelFunc(wheel);
    glutMainLoop();
 
    printf("終了");
    exit(0);
    return 0;
}

background

サポートサイト Wikidot.com background