トップ «前の日記(2019-06-07) 最新 次の日記(2019-07-14)» 編集

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|

2019-07-13 [cocos2d-x][OpenGL ES]画面キャプチャ

cocos2d-x v2には、画面キャプチャの機能が用意されていないので、実装した。

ただし、内容には満足していない部分があって、例えば、使用しているOpenGL ESのAPIは呼び出しコストが高いという情報があるのと、フレームバッファの解像度が高ければ高いほどメモリを使用するので、機会があれば改善したい。

/*!
 @brief Screenshotクラス
 */
class MyGrab {
public:
    /*! @brief デストラクタ */
    virtual ~MyGrab();
 
    /*!
     @brief Singletonなインスタンスを返す。マルチスレッドを考えるの、この実装では不受分なのは認識している。
     @result BQGrabのインスタンス
     */
    static MyGrab* getInstance();
 
    /*!
     @brief Screenshot
     @result 画像
     */
    cocos2d::CCImage* grab();
 
private:
    /*!
     @brief コンストラクタ
     @discussion Singletonとする為、コンストラクタは非公開メンバ関数とする。
     */
    MyGrab();
 
    /*!
     @brief 初期化。
     @retval true 成功
     @retval false 失敗
     */
    bool initialize();
};
 
MyGrab::MyGrab()
{
    /* 初期化 */
    initialize();
}
 
MyGrab::~MyGrab()
{
}
 
MyGrab* MyGrab::getInstance()
{
    static MyGrab grab;
    return &grab;
}
 
bool MyGrab::initialize()
{
    return true;
}
 
CCImage* MyGrab::grab()
{
    /* EGLビューのフレーム・サイズを取得する */
    const unsigned int width = (unsigned int)CCDirector::sharedDirector()->getOpenGLView()->getFrameSize().width;
    const unsigned int height = (unsigned int)CCDirector::sharedDirector()->getOpenGLView()->getFrameSize().height;
 
    const unsigned int bytesPerPixel = 4; /* RGBA */
    GLubyte* dataBuffer = NULL;
    dataBuffer = (GLubyte*)malloc(width * height * bytesPerPixel);
 
    glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dataBuffer);
 
    GLubyte *imageBuffer = NULL;
    imageBuffer = (GLubyte*)malloc(width * height * bytesPerPixel);
    for (int i = 0; i < height; ++i) {
        memcpy(&imageBuffer[i * width * 4], &dataBuffer[(height - i - 1) * width * 4], width * 4);
    }
 
    CCImage* image = new CCImage();
    image->initWithImageData(imageBuffer, width * height * bytesPerPixel, CCImage::kFmtRawData, width, height, 8);
    free(dataBuffer);
    free(imageBuffer);
    image->autorelease();
    return image;
}

glReadPixels()はフレームバッファの内容をピクセルデータとして読み取るコマンドだ。

void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *data);

フレームバッファからウィンドウ座標xとyを左下隅としてwidth × heightのピクセル矩形を読み込み、dataで指定されたアドレスに格納する。formatパラメータは、そのピクセルが何を表しているかをOpenGLに伝える。typeパラメータは、ピクセルのデータ型を示す。


トップ «前の日記(2019-06-07) 最新 次の日記(2019-07-14)» 編集