サンプルプログラム

目次

16.最も単純なプログラム(スケルトンプログラム)
17.グラフィックとテキストの描画
18.BMPファイル読み込み
19.テキストウィンドウへの文字出力
20.複数のテキストウィンドウへの文字出力
21.テキストの描画
22.インプットボックス
23.文字入力
24.お絵かきプログラム1
25.お絵かきプログラム2
26.TrueType文字の描画
27.ボタンボックス
28.OpenGLを利用する
29.ベジェ曲線の描画

1〜15 はじめに,使用手順 等
30〜41 関数リファレンス
42 バージョンアップ履歴
43〜46 著作権・使用許諾,作者への連絡先 等


最も単純なプログラム(スケルトンプログラム)

 最も単純なプログラムの例です.実行すると,メインウィンドウが出現します.メインウィンドウに画像ファイルをドラッグ&ドロップすれば,そのファイルが表示されます.表示されたイメージウィンドウ上でマウス右ボタンを押せばポップアップメニュー(1)が現れます.また,Ctrlキーを押しながらマウス右ボタンを押せばポップアップメニュー(2)が現れます.

#include <esplib.h>

void ESP_Ready(void)
{
}

void ESP_Main(void)
{
}

void ESP_Finish(void)
{
}

この単純なプログラムがコンパイルできないときは,以下の点をチェックしてみてください.
  プロジェクトを作成しているか.Visual C++におけるプロジェクト作成方法は使用手順を参考にしてください.
  プロジェクトのタイプに"Win32 アプリケーション"を選択しているか.
  ソースファイルの拡張子を .cpp にしているか. .c はコンパイルでエラーが出ます.



グラフィックとテキストの描画

 イメージウィンドウが2つ,テキストウィンドウが1つ出現します.スタートさせると,テキストと円と直線が描画されます.Start メニューを繰り返し押してみてください.

// グラフィックとテキストの描画
#include <esplib.h>

void ESP_Ready(void)
{
    ESP_CreateImage(0,"Image1",0,0,200,160,100);
    ESP_CreateImage(1,"Image2",244,0,200,160,100);
    ESP_OpenTextWindow(0,132,199,198,106);
}

void ESP_Main(void)
{
    ESP_Printf("Hello, ESPLIB. ");
    ESP_Select(0);
    ESP_CircleFill(90,70,40,RGB2C(255,255,255),RGB2C(0,128,0));
    ESP_Select(1);
    ESP_Line(30,20,150,100,0x0080ff);
    ESP_UpdateAll();
}

void ESP_Finish(void)
{
}



BMPファイル読み込み

 FILEの値には実在のファイル名を事前に記述しておいてください.
 実行すると指定されたBMPファイルを開きます.
 スタートさせるとイメージウィンドウの表示倍率を上げていきます.途中でポーズしますのでOKまたはCALCELボタンをクリックしてください.

// BMPファイル読み込み
#include <esplib.h>

#define FILE "c:\\bmp\\image.bmp"

void ESP_Ready(void)
{
    ESP_CreateImage(0,"Bmp",0,0,320,240,100);
    ESP_BmpLoad(FILE,0,0);
    ESP_Update();
}

void ESP_Main(void)
{
    for(int z=35; z<=200; z+=5){
        ESP_ZoomImage(0,z);
        ESP_Sleep(200);
        if(z==110){
            if(ESP_Pause("OKで続行,CANCELで中断")) break;
        }
    }
}

void ESP_Finish(void)
{
}



テキストウィンドウへの文字出力

 テキストウィンドウを開いて,文字を出力します.スタートさせると,0〜9999の番号を表示します.表示途中で Stopメニュー(あるいはCキー)を押すと表示を中止させることができます.

// テキストウィンドウへの文字出力
#include <esplib.h>

void ESP_Ready(void)
{
    ESP_OpenTextWindow(0,0,0,384,234);
    ESP_Locate(3,1);
    ESP_Printf(" 123 x 4.56 = %5.1f\n",123*4.56);
}

void ESP_Main(void)
{
    for(int i=0; i<10000; i++){
        if(ESP_STOP) break;
        ESP_Printf("%d ",i);
    }
}

void ESP_Finish(void)
{
}



複数のテキストウィンドウへの文字出力

 複数のテキストウィンドウを開いて文字を出力します.スタートさせると番号を表示し,最後に所要時間を表示します.表示途中で Stopメニュー(あるいはCキー)を押すと表示を中止させることができます.テキストの色は各テキストウィンドウで独立して設定することができます.

// 複数のテキストウィンドウへの文字出力
#include <esplib.h>

int n=0;

void ESP_Ready(void)
{
    ESP_OpenTextWindow(0,0,0,142,152);
    ESP_OpenTextWindow(1,158,0,142,152);
    ESP_OpenTextWindow(2,0,190,142,152);
    ESP_SetColor(0x00ff00,0);
    ESP_OpenTextWindow(3,158,190,142,152);
    ESP_SetColor(0xff4040,0xff);
}

void ESP_Main(void)
{
    ESP_ResetClock();
    ESP_StartClock();

    for(int j=0; j<2000; j++){
        for(int i=0; i<4; i++){
            ESP_SelectTW(i);
            ESP_Printf("%d\n",n++);
        }
        if(ESP_STOP) break;
    }
    ESP_Printf("time=%dms\n",ESP_GetClock());
}

void ESP_Finish(void)
{
}



テキストの描画

 実行させるとイメージウィンドウを開きます.スタートさせるとテキストを描画します.

// テキストの描画
#include <esplib.h>

void ESP_Ready(void)
{
        ESP_CreateImage(0,"Image1",0,0,400,200,100);
        ESP_Glocate(50,16);
}

void ESP_Main(void)
{
        ESP_Select(0);
        ESP_Gtextcolor(0xffff00);
        ESP_Gprintf("Ok? 1/3=%8.3f\n",1.0/3.0);
        ESP_Gputs("test.\n");
        ESP_Gputc('\\');
        ESP_Update();
}

void ESP_Finish(void)
{
}



インプットボックス

 インプットボックスの使用例です.スタートさせると,項目1と項目2の内容はテキストウィンドウに出力されます.また,項目1の内容は+1されます.

// インプットボックス
#include <esplib.h>

void ESP_Ready(void)
{
    ESP_OpenTextWindow(0,0,0,320,240);
    ESP_OpenInputBox(400,300,2);
    ESP_SetInputBoxTitle(0,"Plus 1");
    ESP_SetInputBoxTitle(1,"String");
}

void ESP_Main(void)
{
    int n;
    char s[100];
    n=ESP_GetInputBoxI(0);
    ESP_GetInputBoxS(1,s,100);
    ESP_Printf("%d %s\n",n,s);
    ESP_SetInputBoxI(0,n+1);
}

void ESP_Finish(void)
{
}



文字入力

 テキストウィンドウにおける文字入力の例です.

// 文字入力
#include <esplib.h>

void ESP_Ready(void)
{
    ESP_OpenTextWindow(0,0,0,500,240);
}

void ESP_Main(void)
{
    char buf[256];

    ESP_Printf("適当な文字列を入力してください.\n(終了するにはENDを入力):");
    ESP_Input(buf);
    if(!strcmp(buf,"END")){
        ESP_Exit();
                return;
    }
    ESP_Printf("[%s]が入力されました.\n",buf);
}

void ESP_Finish(void)
{
}



お絵かきプログラム1

 簡単なお絵かきプログラムの例です.

// お絵かきプログラム1
#include <esplib.h>

void msg1(void)
{
    ESP_Printf("Startを選択して下さい.\n");
}

void msg2(void)
{
    ESP_Printf("マウスの左クリックを繰り返して下さい.\n");
    ESP_Printf("ただし,終点はSHIFTキーを押しながら.\n");
}

void ESP_Ready(void)
{
    ESP_CreateImage(0,"Test",0,0,320,240,100);
    ESP_CircleFill(100,90,60,0xff,0xff);
    ESP_BoxFill(200,170,260,210,0xff,0xff);
    ESP_Update();
    ESP_OpenTextWindow(0,400,0,500,240);
    ESP_Printf("★連続直線お絵かきプログラム\n");
    ESP_Printf("(注意)ただし青色の上は描けないようチェックが入ります.\n");
    msg1();
}

void ESP_Main(void)
{
    int x1,y1,x2,y2;
    msg2();
    ESP_GetPoint(0,&x1,&y1);
    ESP_Printf("X[%d] Y[%d]\n",x1,y1);
    ESP_Pset(x1,y1,0xff0000);
    ESP_Update();
    if(ESP_SHIFT){
        ESP_Printf("End\n");
        msg1();
        return;
    }
    while(1){
        ESP_GetRectL2(0,x1,y1,&x2,&y2);
        if(ESP_CheckLine(x1,y1,x2,y2,0xff))goto skip;
        ESP_Printf("X[%d] Y[%d]\n",x2,y2);
        ESP_Line(x1,y1,x2,y2,0xff0000);
        ESP_Update();
        x1=x2;
        y1=y2;
        skip:
        if(ESP_SHIFT){
            ESP_Printf("End\n");
            msg1();
            break;
        }
    }
}

void ESP_Finish(void)
{
}



お絵かきプログラム2

 マウスの座標とボタン情報をリアルタイムに読みとり,絵を描くプログラムの例です.マウス左ボタンで丸を描きます.ShiftキーやCtrlキーを押すと色が変わります.

//お絵かきプログラム2
#include <esplib.h>

void ESP_Ready(void)
{
        ESP_CreateImage(0,"Image1",0,0,320,240,100);
        ESP_CreateImage(1,"Image2",336,0,320,240,100);
        ESP_CreateImage(2,"Image3",0,278,320,240,100);
        ESP_CreateImage(3,"Image4",336,278,320,240,100);
        ESP_OpenInputBox(158,556,1);
        ESP_SetInputBoxTitle(0,"ESP_MOUSE");
        ESP_SetForeground(ESPMAINWINDOW);

        ESP_SetInputBoxI(0,1);
        ESP_START=1;
}

void ESP_Main(void)
{
    ESP_Glocate(0,20);
    ESP_Gtextcolor(0x00ff00);
    ESP_Gprintf("Mouse L-Button, Shift key, Ctrl Key");
    while(1){
        if(ESP_STOP) break;
        ESP_MOUSE=ESP_GetInputBoxI(0);
        ESP_Select(ESP_MW);
        if(ESP_ML) ESP_CircleFill(ESP_MX,ESP_MY,2+ESP_MW,0xffffff,0xffffff);
        else if(ESP_SHIFT) ESP_CircleFill(ESP_MX,ESP_MY,2+2*ESP_MW,0xff00ff,0xff00ff);
        else if(ESP_CTRL) ESP_CircleFill(ESP_MX,ESP_MY,2+3*ESP_MW,0x00ffff,0x00ffff);
        ESP_Update();
    }
}

void ESP_Finish(void)
{
}



TrueType文字の描画

 TrueTypeフォントの文字を描画する例です.

//TrueTypeフォント文字の描画
#include <esplib.h>

void ESP_Ready(void)
{
    ESP_CreateImage(0,"(000)",0,0,400,400,100);
    ESP_SetForeground(ESPMAINWINDOW);
    ESP_TTSize(400,400);
    ESP_TTColor(0x0000ff);
    ESP_TTFont("MS 明朝");
    ESP_TTStyle(0);
    ESP_TTPosition(0,400);
    ESP_TTPuts("@");
    ESP_Update();
}

void ESP_Main(void)
{
    ESP_TTSize(30,30);
    ESP_TTColor(0xffe000);
    ESP_TTPosition(10,40);
    ESP_TTPuts("\1 斜体の設定:\\1");
    ESP_TTPosition(20,80);
    ESP_TTPuts("\2 斜体の解除:\\2");

    ESP_TTColor(0xff8080);
    ESP_TTPosition(30,120);
    ESP_TTPuts("\3 強調の設定:\\3");
    ESP_TTPosition(40,160);
    ESP_TTPuts("\4 強調の解除:\\4");

    ESP_TTColor(0x30c020);
    ESP_TTPosition(50,200);
    ESP_TTPuts("\5 下線の設定:\\5");
    ESP_TTPosition(60,240);
    ESP_TTPuts("\6 下線の解除:\\6");

    ESP_TTColor(0xffffff);
    ESP_TTSize(50,50);
    ESP_TTFont("Arial");
    ESP_TTStyle(ESP_TT_ITALIC);
    ESP_TTPosition(28,300);
    ESP_TTPuts("\5TrueType\6 font\n");

    ESP_Update();
}

void ESP_Finish(void)
{
}



ボタンボックス

 スタートさせると,ボタンの選択に対応して値が変化します.ストップ状態でもボタンの押下は内部でカウントされています.

#include <esplib.h>

void ESP_Ready(void)
{
    ESP_OpenTextWindow(0,0,0,256,232);
    ESP_OpenButtonBox(272,138,1,3);
    ESP_SetButtonBoxTitle(0,"+2");
    ESP_SetButtonBoxTitle(1,"-1");
    ESP_SetButtonBoxTitle(2,"*2");
    ESP_Printf("Startを選択してください.\n");
}

int n=0;

void disp(void)
{
    ESP_Printf("値=%d\n",n);
}

void ESP_Main(void)
{
    disp();
    for(;;){
        if(ESP_STOP) break;
        if(ESP_GetButtonBox(0)){n+=2;disp();}
        if(ESP_GetButtonBox(1)){n--; disp();}
        if(ESP_GetButtonBox(2)){n*=2;disp();}
    }
    ESP_Printf("Stop状態です.Startを選択してください.\n");
}

void ESP_Finish(void)
{
}



OpenGLを利用する

 ESPLIB を OpenGL と組み合わせて使用する場合のサンプルプログラムです.




// ESPLIBとOpenGLを組み合わせたプログラムの例
// 2002/2/14 ver.1.1 by I.N.
// 2002/6/19 ver.1.3
// 2004/7/22 ver.1.4 for ESPLIB 6.3
// 2004/11/18 ver.1.5 for ESPLIB 6.4
// 2012/06/14 ver.1.6 for ESPLIB 7.7/VS2008
#include <esplib.h>

// OpenGLで必要となるヘッダファイルおよびライブラリ
#include <gl\gl.h>
#include <gl\glu.h>
//#include <gl\glaux.h>
#pragma comment (lib ,"opengl32.lib")
#pragma comment (lib ,"glu32.lib")

HDC hDC;
HGLRC hRC;
int nMyPixelFormatID;

#define WX 128
#define WY 128

int depth[WX][WY];
int image[WX][WY];

//出力ウィンドウのサイズ
#define W 500
#define H 500

void ESP_Ready(void)
{
    static PIXELFORMATDESCRIPTOR pfd = {
        sizeof(PIXELFORMATDESCRIPTOR),
            1,
            PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
            PFD_TYPE_RGBA,
            24,
            0,0,0,          0,0,0,          0,0,            0,0,0,0,0,
            16,
            0,              0,
            PFD_MAIN_PLANE,
            0,              0,              0,              0
    };

        ESP_CreateImage(0,"OpenGL output",0,0,500,500,100);
        ESP_CreateImage(1,"Texture",516,0,128,128,100);
        ESP_CreateImage(2,"Depth",516,166,128,128,100);

    // OpenGL用レンダリングコンテキストhRCの生成
    hDC=esp_iw[0].hdc;
    nMyPixelFormatID=ChoosePixelFormat(hDC,&pfd);
    SetPixelFormat(hDC,nMyPixelFormatID,&pfd);
    hRC=wglCreateContext(hDC);
}

// 高さ画像の描画(ランダム)
void DepthImage(void)
{
    int x,y,i,j,c;
    
    srand(GetTickCount());
    ESP_Select(2);
    for(i=0;i<100;i++){
        c=random(256);
        ESP_BoxFill(random(WX),random(WY),random(WX),random(WY),RGB2C(c/2,c/2,c/2),RGB2C(c,c,c));
    }
    for(i=0;i<10;i++){
        c=random(256);
        ESP_Line(random(WX),random(WY),random(WX),random(WY),RGB2C(c,c,c));
    }
    for(i=0;i<30;i++){
        c=random(256);
        ESP_CircleFill(random(WX),random(WY),random(10),RGB2C(c/2,c/2,c/2),RGB2C(c,c,c));
    }
    for(i=0;i<3;i++){
    for(i=0;i<WX;i++){
        for(j=0;j<WY;j++){
            c=(ESP_PointG(i,j)+ESP_PointG(i-1,j)+ESP_PointG(i,j-1)+ESP_PointG(i-1,j-1))/4;
            ESP_Pset(i,j,RGB2C(c,c,c));
        }
    }
    }
    ESP_Update();

    ESP_Select(1);
    c=random(3);
    if(c==0)ESP_TestPat_RGB();
    if(c==1)ESP_TestPat_HSV();
    if(c==2)ESP_TestPat_CrCb();
    ESP_Update();

    for(y=0;y<WY;y++){
        for(x=0;x<WX;x++){
            ESP_Select(1);  image[x][y]=ESP_Point(x,y);
            ESP_Select(2);  depth[x][y]=ESP_PointB(x,y);
        }
    }
}

static GLdouble vdata[4][3];
static GLdouble vnorm[2][3];
static GLdouble d1[3],d2[3];

// ベクトルの正規化
void normalize(double v[3])
{
    GLdouble d=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
    if(d==0.0){
        return;
    }
    v[0]/=d; v[1]/=d; v[2]/=d;
}

// 法線ベクトル取得
void normcrossprod(double v1[3], double v2[3], double out[3])
{
    out[0]=v1[1]*v2[2]-v1[2]*v2[1];
    out[1]=v1[2]*v2[0]-v1[0]*v2[2];
    out[2]=v1[0]*v2[1]-v1[1]*v2[0];
    normalize(out);
}

GLfloat mat_specular[]={1.0,1.0,1.0,1.0};
GLfloat mat_diffuse[]={0.0,1.0,0.0,1.0};
GLfloat mat_shininess[]={30.0};
GLfloat light_position[]={1.0f,1.0f,1.0f,0.2f};

void ESP_Main(void)
{
    int j,t,t1;
    int x,y;
    int az=0,daz;

    //高さ画像の描画
    DepthImage();

    //3次元空間の設定
    wglMakeCurrent(hDC,hRC);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(30.0,(double)W/(double)H,1.0,8.0);
    glViewport(0,0,W,H);
    
    //光源の設定
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
    glLightfv(GL_LIGHT0,GL_POSITION,light_position);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glDepthFunc(GL_LEQUAL);

    //glPolygonMode(GL_FRONT, GL_FILL); 
    
    //glEnable(GL_POLYGON_SMOOTH);
    glEnable(GL_COLOR_MATERIAL);
    
    //glColorMaterial(GL_FRONT,GL_DIFFUSE);

    // scene
    glEnable(GL_DEPTH_TEST);

    //glShadeModel(GL_FLAT);
    glShadeModel(GL_SMOOTH);

    t1=GetTickCount();

    for(;;){
        if(ESP_STOP)break;

        t=GetTickCount();
        daz=1;
        az+=daz;
        if(az>=360)az-=360;

        // 7秒毎に高さ画像を更新
        if(t-t1>7000){
            t1=t;
            DepthImage();
        }
    
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -2.5f);
    glRotated(50,-1.0,0.0,0.0);
    glRotated(az,0.0,0.0,1.0);
    //glRotated(180,0.0,0.0,1.0);
    //glScalef(0.1f,0.1f,0.1f);

    for(y=0;y<WY-1;y++){    for(x=0;x<WX-1;x++){
    vdata[0][0]=(x+0-(WX/2.0))/(WX/1.0);
    vdata[0][1]=-(y+0-(WY/2.0))/(WY/1.0);
    vdata[0][2]=depth[x+0][y+0]/(255.0*3.0);
    vdata[1][0]=(x+0-(WX/2.0))/(WX/1.0);
    vdata[1][1]=-(y+1-(WY/2.0))/(WY/1.0);
    vdata[1][2]=depth[x+0][y+1]/(255.0*3.0);
    vdata[2][0]=(x+1-(WX/2.0))/(WX/1.0);
    vdata[2][1]=-(y+1-(WY/2.0))/(WY/1.0);
    vdata[2][2]=depth[x+1][y+1]/(255.0*3.0);
    vdata[3][0]=(x+1-(WX/2.0))/(WX/1.0);
    vdata[3][1]=-(y+0-(WY/2.0))/(WY/1.0);
    vdata[3][2]=depth[x+1][y+0]/(255.0*3.0);

    for(j=0;j<3;j++){
        d1[j]=vdata[1][j]-vdata[0][j];
        d2[j]=vdata[2][j]-vdata[0][j];
    }
    normcrossprod(d1,d2,&vnorm[0][0]);
    for(j=0;j<3;j++){
        d1[j]=vdata[2][j]-vdata[0][j];
        d2[j]=vdata[3][j]-vdata[0][j];
    }
    normcrossprod(d1,d2,&vnorm[1][0]);

    glBegin(GL_TRIANGLE_FAN);
        glNormal3dv(&vnorm[0][0]);
        glColor3f(C2R(image[x+0][y+0])/255.0f,C2G(image[x+0][y+0])/255.0f,C2B(image[x+0][y+0])/255.0f);
        glVertex3dv(&vdata[0][0]);
        glVertex3dv(&vdata[1][0]);
        glVertex3dv(&vdata[2][0]);

        glNormal3dv(&vnorm[1][0]);
        glColor3f(C2R(image[x+1][y+0])/255.0f,C2G(image[x+1][y+0])/255.0f,C2B(image[x+1][y+0])/255.0f);
        glVertex3dv(&vdata[3][0]);
    glEnd();
    }}

    glFlush();
    SwapBuffers(hDC);
    
    }

    //終了時にウィンドウの内容をESPLIBの画像メモリにコピー
    BitBlt(esp_iw[0].memdc,0,0,esp_iw[0].wx,esp_iw[0].wy,esp_iw[0].hdc,0,0,SRCCOPY);
    
    //クリップボードへコピー
    ESP_Select(0);
    ESP_CopyImage();

    wglMakeCurrent(NULL,NULL);
}

void ESP_Finish(void)
{
}



ベジェ曲線の描画



 ベジェ曲線描画関数ESP_Bezier()を使用したデモンストレーションです.
 ランダムな位置・形状のベジェ曲線を1秒毎に赤色で描画します.
 また,制御点の様子も分かるように水色で表示しています.

#include <esplib.h>

void ESP_Ready(void)
{
    ESP_CreateImage(0,"Bezier-curve",0,0,350,350,100);
    ESP_START=1;
}

void ESP_Main(void)
{
    for(;;){
        if(ESP_STOP) break;
        ESP_Cls();
        srand(GetTickCount());
        int x0=random(350);
        int y0=random(350);
        int x1=random(350);
        int y1=random(350);
        int x2=random(350);
        int y2=random(350);
        int x3=random(350);
        int y3=random(350);
        ESP_Line(x0,y0,x1,y1,0x00ffff);
        ESP_Line(x2,y2,x3,y3,0x00ffff);
        ESP_CircleFill(x0,y0,3,0xff0000,0xff0000);
        ESP_CircleFill(x1,y1,3,0x00ffff,0x00ffff);
        ESP_CircleFill(x2,y2,3,0x00ffff,0x00ffff);
        ESP_CircleFill(x3,y3,3,0xff0000,0xff0000);
        ESP_Bezier(x0,y0,x1,y1,x2,y2,x3,y3,20,0xff0000);
        ESP_Update();
        ESP_Sleep(1000);
    }
}

void ESP_Finish(void)
{
}