画像表示を含む自分用アプリの雛形(6) OpenGL/GLES, OpenCVの利用

前回までで、
PNG等の汎用フォーマット画像や、各種APIによる描画を、Direct2Dのbitmap (D2D1Bitmap1) を通じて表示させることができるようになりました。
今回は、各種ライブラリによる利用方法を考えます。

## OpenGL
これまたWin32APIと並んでふっるいですな。
当時、SGIのワークステーションはちょっとした憧れでした。

```
#include <gl/gl.h>
#include <gl/glu.h>
#pragma comment(lib, "OpenGL32.lib")
#pragma comment(lib, "glu32.lib")
```
```
      ImageWidth1=FrameWidth;
      ImageHeight1=FrameHeight;
      
      BITMAPINFO *BitmapInfo=(BITMAPINFO *)calloc(sizeof(BITMAPV5HEADER), 1);
      
      BITMAPV5HEADER biv5={};
      biv5.bV5Size=sizeof(BITMAPV5HEADER);
      biv5.bV5Width=ImageWidth1;
      biv5.bV5Height=ImageHeight1;
      biv5.bV5Planes=1;
      biv5.bV5BitCount=32;
      biv5.bV5Compression=BI_BITFIELDS;
      biv5.bV5SizeImage=((ImageWidth1*biv5.bV5BitCount+31)/32*4)*ImageHeight1;
      biv5.bV5RedMask  =0x00ff0000;
      biv5.bV5GreenMask=0x0000ff00;
      biv5.bV5BlueMask =0x000000ff;
      biv5.bV5AlphaMask=0xff000000;
      memcpy(&(BitmapInfo->bmiHeader), &biv5, sizeof(biv5));
      hImageBMP1=CreateDIBSection(NULL, BitmapInfo, DIB_RGB_COLORS, (void **)(&ImageBuffer1), NULL, 0);
      free(BitmapInfo);

      HDC hdc=GetDC(NULL);
      HDC hmemdc=CreateCompatibleDC(hdc);
      ReleaseDC(NULL, hdc);
      HBITMAP hOldBMP=(HBITMAP)SelectObject(hmemdc, hImageBMP1);

      {
        PIXELFORMATDESCRIPTOR OpenGL_PixelFormat={
          sizeof(PIXELFORMATDESCRIPTOR),
          1,
          PFD_DRAW_TO_BITMAP|PFD_SUPPORT_GDI|PFD_SUPPORT_OPENGL,
          PFD_TYPE_RGBA, 32,
          0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0,
          24, 0,
          0,
          PFD_MAIN_PLANE, 0, 0, 0, 0
        };
        SetPixelFormat(hmemdc, ChoosePixelFormat(hmemdc, &OpenGL_PixelFormat), &OpenGL_PixelFormat);

        HGLRC hglrc;
        hglrc=wglCreateContext(hmemdc);
        wglMakeCurrent(hmemdc, hglrc);
        {
        glClearColor(0.0, 1.0, 1.0, 1.0);      
        glClear(GL_COLOR_BUFFER_BIT);
        }
        wglMakeCurrent(hmemdc, NULL);
        wglDeleteContext(hglrc);
      }
      SelectObject(hmemdc, hOldBMP);
      DeleteDC(hmemdc);

      if(pD2D_Bitmap!=NULL){ pD2D_Bitmap->Release(); pD2D_Bitmap=NULL; }
      if(pRT!=NULL) pRT->CreateBitmap(D2D1::SizeU(ImageWidth1, ImageHeight1), ImageBuffer1, ImageWidth1*32/8,
                                      D2D1::BitmapProperties(D2D_PixelFormat), (ID2D1Bitmap **)&pD2D_Bitmap);
      if(pDC!=NULL) pDC->CreateBitmap(D2D1::SizeU(ImageWidth1, ImageHeight1), ImageBuffer1, ImageWidth1*32/8,
                                      D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE, D2D_PixelFormat), &pD2D_Bitmap);
```

## OpenGL ES (ANGLE)
今はANGLEを使うらしい、ということで、初めて使ってみたので処理的に間違っているかもしれません。
このサンプルをいろいろといじっているところです。

```
#include <EGL/egl.h>
#pragma comment(lib, "ANGLE/libEGL.lib")
#include <angle_gl.h>
#pragma comment(lib, "ANGLE/libGLESv2.lib")

EGLDisplay eglDisplay;

```

```
      ImageWidth1=FrameWidth;
      ImageHeight1=FrameHeight;
      
      BITMAPINFO *BitmapInfo=(BITMAPINFO *)calloc(sizeof(BITMAPV5HEADER), 1);
      
      BITMAPV5HEADER biv5={};
      biv5.bV5Size=sizeof(BITMAPV5HEADER);
      biv5.bV5Width=ImageWidth1;
      biv5.bV5Height=ImageHeight1;
      biv5.bV5Planes=1;
      biv5.bV5BitCount=32;
      biv5.bV5Compression=BI_BITFIELDS;
      biv5.bV5SizeImage=((ImageWidth1*biv5.bV5BitCount+31)/32*4)*ImageHeight1;
      biv5.bV5RedMask  =0x00ff0000;
      biv5.bV5GreenMask=0x0000ff00;
      biv5.bV5BlueMask =0x000000ff;
      biv5.bV5AlphaMask=0xff000000;
      memcpy(&(BitmapInfo->bmiHeader), &biv5, sizeof(biv5));
      hImageBMP1=CreateDIBSection(NULL, BitmapInfo, DIB_RGB_COLORS, (void **)(&ImageBuffer1), NULL, 0);
      free(BitmapInfo);

      if(eglDisplay==NULL){
        eglDisplay=eglGetDisplay((EGLNativeDisplayType)0); //EGL_DEFAULT_DISPLAY); // eglGetDisplay(hdc);
        eglInitialize(eglDisplay, NULL, NULL);
      }

      eglBindAPI(EGL_OPENGL_ES_API);
      EGLConfig eglConfig; EGLint num_eglConfig;
      EGLint eglConfigAttributes[]={
        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
        EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
        EGL_BUFFER_SIZE, 32,
        EGL_BLUE_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_RED_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_NONE
      };
      eglChooseConfig(eglDisplay, eglConfigAttributes, &eglConfig, 1, &num_eglConfig);

      EGLint pbufferAttributes[]={
        EGL_WIDTH, ImageWidth1,
        EGL_HEIGHT, ImageHeight1,
        EGL_NONE
      };
      EGLSurface eglSurface=eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttributes);
      
      EGLint eglContextAttributes[]={
        EGL_CONTEXT_CLIENT_VERSION, 3,
        EGL_NONE
      };
      EGLContext eglContext=eglCreateContext(eglDisplay, eglConfig, NULL, eglContextAttributes);
      
      eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
      glClearColor(0.0, 1.0, 1.0, 1.0);      
      glClear(GL_COLOR_BUFFER_BIT);
      #ifndef GL_BGRA
      #define GL_BGRA 0x80e1
      #endif
      glReadPixels(0, 0, ImageWidth1, ImageHeight1, GL_BGRA, GL_UNSIGNED_BYTE, ImageBuffer1);

      if(pD2D_Bitmap!=NULL){ pD2D_Bitmap->Release(); pD2D_Bitmap=NULL; }
      if(pRT!=NULL) pRT->CreateBitmap(D2D1::SizeU(ImageWidth1, ImageHeight1), ImageBuffer1, ImageWidth1*32/8,
                                      D2D1::BitmapProperties(D2D_PixelFormat), (ID2D1Bitmap **)&pD2D_Bitmap);
      if(pDC!=NULL) pDC->CreateBitmap(D2D1::SizeU(ImageWidth1, ImageHeight1), ImageBuffer1, ImageWidth1*32/8,
                                      D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE, D2D_PixelFormat), &pD2D_Bitmap);
```

## OpenCV
Intel IPL の頃から使用してました。
昔はSSEの利用販促のためにintelが無償提供してたようなもので、ビット演算的な画像処理以外はおまけ程度のものでした。

```
  CvSize sz=cvSize(ImageWidth1, ImageHeight1);
  
  IplImage *src=cvCreateImageHeader(sz, IPL_DEPTH_8U,  4); // 32bitARGB
  src->imageData=(char *)ImageBuffer1;
  IplImage *dst=cvCreateImageHeader(sz, IPL_DEPTH_8U,  4); // 32bitARGB
  dst->imageData=(char *)malloc(sz*4);

  //// some ImageProcessing, src->dst

  D2D1_RECT_U rc=D2D1::RectU(0, 0, ImageWidth1, ImageHeight1);
  pD2D_Bitmap->CopyFromMemory(&rc, dst->imageData, ImageWidth*4);
  free(dst->imageData);
  cvReleaseImageHeader(&src);
  cvReleaseImageHeader(&dst);
```