2014年12月12日金曜日

5.OpenGL サンプルプログラム

新しいプロジェクトを追加します。

まずはコード。(折りたたみ機能ほしいね。(折りたたみできました。


#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(lib,"../../freeglut-2.8.1/lib/x86/freeglut.lib")
#pragma comment(lib,"../../glew-1.11.0/lib/Release/Win32/glew32.lib")

#ifdef _WIN32
#include   <windows.h>
#include   <locale.h>
#endif
#include   <stdio.h>
#include   <malloc.h>
#include   <string.h>
#include   <time.h>
#include   <GL/glew.h>
#include   <GL/glut.h>
#include   <GL/gl.h>

int WindowWidth = 640;   // ウィンドウの幅
int WindowHeight = 480;   // ウィンドウの高さ
static GLuint   texturePage[2];
static float   textureAspect[2];
/************************************************************/
/* Bitmap Header                      */
/************************************************************/
typedef struct _BMP_HEADER {
    unsigned short type;    // BM
    unsigned long file_size;
    unsigned long reserved0;
    unsigned long header_size; // must be 54
    unsigned long offset;   // must be 40
    unsigned long width;
    unsigned long height;
    unsigned short must_be_1;  // 0x0001
    unsigned short color_bits;
    unsigned long reserved1;
    unsigned long must_be_C;  // 0x00000C00
    unsigned long reserved2;
    unsigned long reserved3;
    unsigned long reserved4;
    unsigned long reserved5;
    int color_bytes;
    int line_words;
}BMP_HEADER;
/************************************************************/
/* Read Bitmap                       */
/************************************************************/
unsigned int read_bmp_header(FILE *fp, BMP_HEADER *p)
{
    fread(&p->type, 1, 2, fp);
    fread(&p->file_size, 1, 4, fp);
    fread(&p->reserved0, 1, 4, fp);
    fread(&p->header_size, 1, 4, fp);
    fread(&p->offset, 1, 4, fp);
    fread(&p->width, 1, 4, fp);
    fread(&p->height, 1, 4, fp);
    fread(&p->must_be_1, 1, 2, fp);
    fread(&p->color_bits, 1, 2, fp);
    fread(&p->reserved1, 1, 4, fp);
    fread(&p->must_be_C, 1, 4, fp);
    fread(&p->reserved2, 1, 4, fp);
    fread(&p->reserved3, 1, 4, fp);
    fread(&p->reserved3, 1, 4, fp);
    fread(&p->reserved3, 1, 4, fp);
    p->color_bytes = p->color_bits / 8;
    p->line_words = ((p->width*p->color_bytes) + 3) / 4;
    return (2 + 4 + 4 + 4 + 4 + 4 + 4 + 2 + 2 + 4 + 4 + 4 + 4 + 4 + 4);
}
/************************************************************/
int open_texture(GLuint *textureID, float* aspect, char* filepath)
{
    unsigned int i;
    unsigned int *buffer;
    BMP_HEADER tex;
    FILE *fbmp;
    fopen_s(&fbmp, filepath, "rb");
// ファイルが開けない
{
unsigned int read_size = read_bmp_header(fbmp, &tex);

    buffer = (unsigned int *)malloc(tex.file_size);
    if (read_size < tex.header_size){
        fread(buffer, 1, tex.header_size - read_size, fbmp);
    }
    fread(buffer, 1, tex.file_size, fbmp);
    fclose(fbmp);
    }
    if (tex.color_bits == 24)
    {
        unsigned char *rgb = (unsigned char *)buffer;
        for (i = 0; i < tex.width * tex.height; i++)
        {
            unsigned char swap = rgb[i * 3];
            rgb[i * 3] = rgb[i * 3 + 2];
            rgb[i * 3 + 2] = swap;
        }
        glGenTextures(1, textureID);
        glBindTexture(GL_TEXTURE_2D, *textureID);
        glEnable(GL_TEXTURE_2D);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.width, tex.height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
        // S方向(横方向)で元のテクスチャ画像外の位置が
        // T方向(縦方向)で元のテクスチャ画像外の位置が
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glBindTexture(GL_TEXTURE_2D, 0);
    }else{
        unsigned char *rgba = (unsigned char *)buffer;
        for (i = 0; i < tex.width * tex.height; i++) // BitMap→OpenGL RGBA
        {
            unsigned char swap = rgba[i * 4];
            rgba[i * 4] = rgba[i * 4 + 3];
            rgba[i * 4 + 3] = swap;
            swap = rgba[i * 4 + 1];
            rgba[i * 4 + 1] = rgba[i * 4 + 2];
            rgba[i * 4 + 2] = swap;
        }
        glGenTextures(1, textureID);
        glBindTexture(GL_TEXTURE_2D, *textureID);
        glEnable(GL_TEXTURE_2D);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width, tex.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glBindTexture(GL_TEXTURE_2D, 0);
    }
    *aspect = (float)tex.height / (float)tex.width;
    free(buffer);
    return 1;
}
//----------------------------------------------------
void Initialize(void)
{
    open_texture(&texturePage[0], &textureAspect[0], "../BMP/GAME.bmp");
    open_texture(&texturePage[1], &textureAspect[1], "../BMP/MENSEX.bmp");
    glClearColor(1.0, 1.0, 1.0, 0.0); //背景色
    glEnable(GL_DEPTH_TEST);//デプスバッファを使用:glutInitDisplayMode() で GLUT_DEPTH を指定する
}
//----------------------------------------------------
void Idle(){
    glutPostRedisplay(); // glutDisplayFunc()を1回実行する
}
//----------------------------------------------------
#define PERSPECTIVE_FOVY  (25.0f) /* field of view in degree */
#define PERSPECTIVE_ASPECT (1.0f)  /* aspect ratio */
#define PERSPECTIVE_NEAR  (1.0f)  /* Z near */
#define PERSPECTIVE_FAR  (400.0f) /* Z far */
void Display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //バッファの消去
    glMatrixMode(GL_MODELVIEW); // モデルビュー変換行列)
    glLoadIdentity();      //行列の初期化
    glViewport(0, 0, WindowWidth, WindowHeight);
    glMatrixMode(GL_PROJECTION); // 透視変換行列の設定
    glLoadIdentity();      //行列の初期化
    gluPerspective(PERSPECTIVE_FOVY, PERSPECTIVE_ASPECT, PERSPECTIVE_NEAR, PERSPECTIVE_FAR);
    gluLookAt( 0,0,5, 0,0,0, 0,1,0);   /* up is in positive Y direction */
    glColor3d(1.0, 0, 0);
    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texturePage[0]);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
    glBegin(GL_TRIANGLE_FAN);
    glVertex2d(-0.8f, -0.9f); glTexCoord2f(1.0, 0.0);
    glVertex2d(0,   -0.9f); glTexCoord2f(1.0, 1.0);
    glVertex2d(0,   0.9f); glTexCoord2f(0.0, 1.0);
    glVertex2d(-0.8f, 0.9f); glTexCoord2f(0.0, 0.0);
    glEnd();
    glColor3d(0, 1.0, 0);
    glBindTexture(GL_TEXTURE_2D, texturePage[1]);
    float v[] = {
        0,  -0.9f, 0,
        0.8f, -0.9f, 0,
        0.8f, 0.9f, 0,
        0,   0.9f, 0,
    };
    float t[] = {
        0, 0,
        1, 0,
        1, 1,
        0, 1,
    };
    glEnableClientState(GL_VERTEX_ARRAY);        // 有効化
    glVertexPointer(3, GL_FLOAT, 0, v);          // 1頂点はx,y,z:float型 0番目から利用 ソース
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); // 有効化
    glTexCoordPointer(2, GL_FLOAT, 0, t);        // 1頂点はx,y:float型 0番目から利用 ソース
    glDrawArrays(GL_QUADS, 0, 4);                // 描画
    glDisableClientState(GL_VERTEX_ARRAY);        // 無効化
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); // 無効化
    glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_TEXTURE_2D);
    glutSwapBuffers(); // ダブルバッファリング
}
//----------------------------------------------------
void visibility(int visible)
{
    glutIdleFunc(Idle);
    glutIdleFunc(NULL);
}
//----------------------------------------------------
void resize(int w, int h)
{
    WindowWidth = w;
    WindowHeight = h;
    glutReshapeWindow(w, h);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
//----------------------------------------------------
int main(int argc, char *argv[]){
    glutInit(&argc, argv);                                 // glut の初期化
    glutInitWindowPosition( 50 , 50 );                         // ウィンドウの位置
    glutInitWindowSize(WindowWidth, WindowHeight);             // ウィンドウサイズ
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); // ディスプレイモード
    glutCreateWindow("サンプル1");                            // ウィンドウの作成
    glutIdleFunc(Idle);                                        // アイドル時コールバック
    glutDisplayFunc(Display);                                  // 描画時コールバック
    glutReshapeFunc(resize);                                   // サイズ変更時コールバック
    glutVisibilityFunc(visibility);                            // 可視化時コールバック
    glewInit();                                                // glew の初期化
    Initialize();                                              // 初期設定
    glutMainLoop();
    return 0;
}

設定は4.GLUT サンプルプログラムと同じです。が、前回必要のなかったglew32.libとglew32.dllのケアをします。
インクルードファイルディレクトリを設定します。


ソースコードの先頭にpragmaを書きます。
#pragma comment(lib,"../../freeglut-2.8.1/lib/x86/freeglut.lib")
コンソールウインドウが出てきたのを消すためのpragmaも追加します。
#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")

0 件のコメント:

コメントを投稿