Opengl es 绘制多个图像纹理时出现的一些问题
我希望使用OpenGl将4幅图像混合到屏幕上。第一个图像包含背景,其他3个图像包含一些具有透明度的卡通。我的目标是一次渲染这4个图像。在每次调用渲染时,我都会用新图像更新前3个图像以组成新帧 我是OpenGL新手,到目前为止,我能够实现这些图像的混合,但是我在渲染时注意到一些可怕的问题。我看到前三名中的一些图像有时会丢失,或者有些图像被渲染,但看起来像是被隐形人裁剪过的 每一行代表一个不同的图像 图像裁剪问题:Opengl es 绘制多个图像纹理时出现的一些问题,opengl-es,android-ndk,Opengl Es,Android Ndk,我希望使用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坐标设置为不同的值,然后查看是否存在此问题。