Opengl es 绘制多个图像纹理时出现的一些问题

Opengl es 绘制多个图像纹理时出现的一些问题,opengl-es,android-ndk,Opengl Es,Android Ndk,我希望使用OpenGl将4幅图像混合到屏幕上。第一个图像包含背景,其他3个图像包含一些具有透明度的卡通。我的目标是一次渲染这4个图像。在每次调用渲染时,我都会用新图像更新前3个图像以组成新帧 我是OpenGL新手,到目前为止,我能够实现这些图像的混合,但是我在渲染时注意到一些可怕的问题。我看到前三名中的一些图像有时会丢失,或者有些图像被渲染,但看起来像是被隐形人裁剪过的 每一行代表一个不同的图像 图像裁剪问题: 图像被裁剪,缺少一个图像: 它应该是什么样子: 如果有人能帮我解决这个问题,我

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

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

每一行代表一个不同的图像

图像裁剪问题:

图像被裁剪,缺少一个图像:

它应该是什么样子:

如果有人能帮我解决这个问题,我将不胜感激!下面是我正在使用的代码

下面是我用来渲染图像的代码

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();
}
void MoviePreview::prepareTexture(胶合纹理、闪烁格式、int w、int h)
{
//绑定到生成的纹理
glBindTexture(GL_TEXTURE_2D,纹理);
glTexParameterf(GL_纹理2D、GL_纹理最小过滤器、GL_线性);
glTexParameterf(GL_TEXTURE_2D、GL_TEXTURE_MAG_FILTER、GL_LINEAR);
glShadeModel(GLU平面);
//glShadeModel(GL_平滑);
GLTEXAGE2D(GL_纹理_2D,0,格式,w,h,0,格式,GL_无符号字节,0);
if(GL_RGBA==格式)
{
//glColor4f(1.0f、1.0f、1.0f、1.0f);
}
//裁剪纹理矩形
闪烁rect[]={0,h,w,-h};
glTexParameteriv(GL_纹理_2D,GL_纹理_裁剪_矩形,矩形);
glDrawTexiOES(0,0,0,w,h);
}
void MoviePreview::调整大小(int w,int h)
{
LOGI(“本机大小%d%d”,w,h);
//初始化开放式gl
//glClearColor(1.0,1.0,1.0,1.0);
glEnable(GL_纹理_2D);
glEnable(GL_混合物);
glDisable(GLU抖动);
glDisable(GLU照明);
glDisable(GLU深度测试);
glDisable(GL_颜色_材质);
glDisable(GLU雾);
glDisable(GLU消隐面);
glDisable(GLU模板测试);
glDisable(GLU颜色逻辑运算);
glDisable(GLU阿尔法测试);
//glBlendFunc(GL_ONE,GL_ONE减去SRC_ALPHA);//新
glBlendFunc(GL_SRC_ALPHA,GL_ONE_减去_SRC_ALPHA);//新
//glBlendFunc(GL_SRC_ALPHA,GL_ONE_减去DST_ALPHA);
//生成一个纹理对象
glgentexture(最大纹理、最大纹理);
检查GLU错误(“glGenTextures”);
int frameHeight=h;//image.rows;
int frameWidth=w;//image.cols;
//第一个纹理是我们的背景纹理
准备结构(mTexture[0],GL_RGBA,mBg.cols,mBg.rows);
prepareTexture(mTexture[1],GL_RGBA,帧宽,帧高);
prepareTexture(mTexture[2],GL_RGBA,帧宽,帧高);
prepareTexture(mTexture[3],GL_RGBA,帧宽,帧高);
mSurfaceWidth=w;
mSurfaceHeight=h;
}
void MoviePreview::render(int64_t*imageid,const int图像)
{
int i=0;
双睡眠持续时间=0;
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
//TODO试着看看我们是否能摆脱总是加载bg的困扰
//因为它不会经常更改,所以可能值得加载一次
//是不是。。。
//glBindTexture(GL_TEXTURE_2D,mTexture[0]);
//glTexSubImage2D(GL_TEXTURE_2D,0,0,mBg.cols,mBg.rows,GL_RGBA,GL_UNSIGNED_BYTE,mBg.ptr());
//glDrawTexiOES(0,0,0,mSurfaceWidth,mSurfaceHeight);
//TODO传递图像批处理加载程序
//加载图像

对于(i=0;i当OpenGl试图绘制图像源时,我的图像源最终被另一个线程修改了…

这可能是Z-fighting吗?我猜不会是Z-fighting,因为我使用的是GL_纹理_2D?这是一个非3D交易,但可能有一些设置我不知道?OpenGl没有2D模式。一切都是3D的。排除Z-fight请尝试将精灵的z坐标设置为不同的值,然后查看是否存在此问题。