0

我正在寻找使用 OpenGL 将 4 个图像混合到屏幕上。第一个图像包含背景,其他 3 个图像包含一些具有透明度的卡通。我的目标是一次渲染这 4 张图像。在每次渲染调用时,我都会用新图像更新前 3 个图像以组成新帧。

我是 OpenGL 的新手,到目前为止,我能够实现这些图像的混合,但是我在渲染时注意到了一些可怕的问题。我看到前 3 张图片中的一些有时会丢失,或者有些被渲染,但看起来它们是被隐形人裁剪的......

每条线代表一个不同的图像。

图片裁剪问题:
在此处输入图像描述

图像被裁剪并且缺少一张图像:
在此处输入图像描述

它应该是什么样子:
在此处输入图像描述

任何解决问题的帮助我将不胜感激!在我正在使用的代码下方。

这是我用来渲染图像的代码。

void MoviePreview::prepareTexture (GLuint texture, GLint format, int w, int h)
{
    // Bind to generated texture
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glShadeModel(GL_FLAT);
    //glShadeModel(GL_SMOOTH);

    glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, 0);

    if (GL_RGBA == format)
    {
        //glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    }

    // Crop the texture rectangle
    GLint rect[] = {0, h, w, -h};
    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, rect);
    glDrawTexiOES(0, 0, 0, w, h);
}

void MoviePreview::resize (int w, int h)
{
    LOGI("native_gl_resize %d %d", w, h);

    // init open gl
    //glClearColor(1.0, 1.0, 1.0, 1.0);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glDisable(GL_DITHER);
    glDisable(GL_LIGHTING);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_COLOR_MATERIAL);
    glDisable(GL_FOG);
    glDisable(GL_CULL_FACE);
    glDisable(GL_STENCIL_TEST);
    glDisable(GL_COLOR_LOGIC_OP);
    glDisable(GL_ALPHA_TEST);

    //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);//NEW
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//NEW
    //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA);

    // Generate one texture object
    glGenTextures(MAX_TEXTURES, mTexture);
    check_gl_error("glGenTextures");

    int frameHeight = h;//image.rows;
    int frameWidth = w;//image.cols;

    // first texture is our background texture
    prepareTexture(mTexture[0], GL_RGBA, mBg.cols, mBg.rows);
    prepareTexture(mTexture[1], GL_RGBA, frameWidth, frameHeight);
    prepareTexture(mTexture[2], GL_RGBA, frameWidth, frameHeight);
    prepareTexture(mTexture[3], GL_RGBA, frameWidth, frameHeight);

    mSurfaceWidth = w;
    mSurfaceHeight = h;
}

void MoviePreview::render (int64_t* imageIds, const int images)
{
    int i                   = 0;
    double sleepDuration    = 0;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // TODO try to see if we can just get away from always loading the bg
    // since it doesn't change often might be worth loading it once and that
    // is it...
    //glBindTexture(GL_TEXTURE_2D, mTexture[0]);
    //glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mBg.cols, mBg.rows, GL_RGBA, GL_UNSIGNED_BYTE, mBg.ptr());
    //glDrawTexiOES(0, 0, 0, mSurfaceWidth, mSurfaceHeight);

    // TODO pass the image batch loader
    // load images
    for (i=0; i<images; i++)
    {
        if (0 < imageIds[i])
        {
            sprintf(mTempPath, "%s/f1_%lld.png",mProjectPath.c_str(), imageIds[i]);
            mImageLoader[i].loadImage(mTempPath);
        }
    }

    if (0 < mFrameDuration)
    {
        // here we try to control the suggested frame rate
        // set. We calculate since the last show image time
        // if we should sleep or not...
        if (0 < mLastDrawTimestamp) {
            sleepDuration = mFrameDuration - (now_ms() - mLastDrawTimestamp);
        }

        if (0 < sleepDuration) {
            usleep((long)sleepDuration*NANO_IN_MS);
        }
    }

    // draw images
    i = 0;
    for (i=0; i<images; i++)
    {
        if (0 < imageIds[i])
        {
            cv::Mat img = mImageLoader[i].getImage();
            if (!img.empty())
            {
                glBindTexture(GL_TEXTURE_2D, mTexture[i+1]);
                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.cols, img.rows, GL_RGBA, GL_UNSIGNED_BYTE, img.ptr());
                glDrawTexiOES(0, 0, 0, img.cols, img.rows);
            }
        }
    }

    mLastDrawTimestamp = now_ms();
}
4

1 回答 1

0

问题最终是我的图像源在 OpenGL 试图绘制它们时被另一个线程修改......

于 2013-07-05T10:37:56.227 回答