问题描述
我正在尝试渲染到纹理,然后绘制纹理。首先,我尝试使用帧缓冲区对象来完成此操作,但是我无法glGenFrameBuffers()
给我一个有效的帧缓冲区对象。大约一年前,我在这里发布了一个问题:EGL/OpenGLES glGenFramebuffers not working with Native Android Project in VS 2019。
经过进一步研究,我了解了EGL PBuffer Surface对象。因此,我尝试使用一些参考来拼凑出一些可行的方法。但是,我仍然无法渲染纹理以使用PBuffer对象。我要遵循的主要示例如下:https://processors.wiki.ti.com/index.php/Render_to_Texture_with_OpenGL_ES。
我创建了一个RenderTarget
类,以更轻松地管理渲染目标。除了调用eglBindTexImage()
以外,其他一切似乎都正常。它返回FALSE
,错误为EGL_BAD_DISPLAY
。我给它一个与所有其他API调用相同的EGLDisplay
对象,该对象是从eglGetCurrentDisplay()
获取的,通常具有0x1
的值。
我正在使用m_pDisplay
类中的有效Engine
运行整个应用程序。
这是我的代码
void RenderTarget::CreateSurfaceTarget(EGLConfig i_pConfig,GLfloat i_fWidth,GLfloat i_fHeight)
{
EGLDisplay pCurDisplay = eglGetCurrentDisplay();
EGLContext pCurContext = eglGetCurrentContext();
EGLSurface pPrevSurface = eglGetCurrentSurface(EGL_DRAW);
m_fWidth = i_fWidth;
m_fHeight = i_fHeight;
createEglConfig(pCurDisplay,i_pConfig);
if (m_pEglConfig)
{
EGLint attr[] =
{
EGL_WIDTH,static_cast<EGLint>(i_fWidth),EGL_HEIGHT,static_cast<EGLint>(i_fHeight),EGL_TEXTURE_TARGET,EGL_TEXTURE_2D,EGL_TEXTURE_FORMAT,EGL_TEXTURE_RGBA,EGL_NONE
};
m_pSurface = eglCreatePbufferSurface(pCurDisplay,m_pEglConfig,attr);
if (m_pSurface)
{
createTexture();
eglMakeCurrent(pCurDisplay,m_pSurface,pCurContext);
eglBindTexImage(pCurDisplay,EGL_BACK_BUFFER); // <--- THIS RETURNS FALSE WITH ERROR 'EGL_BAD_DISPLAY'
eglMakeCurrent(pCurDisplay,pPrevSurface,pCurContext);
glBindTexture(GL_TEXTURE_2D,0);
}
else
ENGINE_LOGE("RenderTarget::CreateSurfaceTarget() - Failed to create a PBuffer Surface");
}
}
void RenderTarget::BindTarget(EGLDisplay i_pDisplay,EGLContext i_pContext)
{
if (eglMakeCurrent(i_pDisplay,i_pContext))
{
glViewport(0,m_fWidth,m_fHeight);
glBindTexture(GL_TEXTURE_2D,m_nTexID);
}
}
void RenderTarget::UnbindTarget(EGLDisplay i_pDisplay,EGLContext i_pContext,EGLSurface i_pPrevSurface)
{
eglReleaseTexImage(i_pDisplay,EGL_BACK_BUFFER);
eglBindTexImage(i_pDisplay,EGL_BACK_BUFFER);
eglMakeCurrent(i_pDisplay,i_pPrevSurface,i_pContext);
glBindTexture(GL_TEXTURE_2D,0);
}
void RenderTarget::createEglConfig(EGLDisplay i_pDisplay,EGLConfig i_pMainConfig)
{
EGLint configAttr[] =
{
//EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,EGL_CONFIG_CAVEAT,EGL_NONE,EGL_RED_SIZE,8,EGL_GREEN_SIZE,EGL_BLUE_SIZE,EGL_ALPHA_SIZE,//EGL_BUFFER_SIZE,32,// RGBA = 32 bits
EGL_SURFACE_TYPE,EGL_PBUFFER_BIT,// We want a PBuffer
EGL_BIND_TO_TEXTURE_RGBA,EGL_TRUE,EGL_NONE
};
EGLint nNumConfigs;
if (!eglChooseConfig(i_pDisplay,configAttr,&m_pEglConfig,1,&nNumConfigs) || nNumConfigs != 1)
ENGINE_LOGE("RenderTarget::RenderTarget() - Failed to create EGLConfig");
}
void RenderTarget::Render(PosType i_fX,PosType i_fY)
{
if (m_nTexID)
{
// Bind Vertices,TexCoords,and Texture
glVertexPointer(3,GL_FLOAT,m_Quad.Vertices);
glTexCoordPointer(2,m_TexCoord);
glColor4f(m_Color[0],m_Color[1],m_Color[2],m_Color[3]);
glBindTexture(GL_TEXTURE_2D,m_nTexID);
// Set position and Draw
glPushMatrix();
glTranslatef(i_fX,i_fY,0.0f);
glDrawArrays(GL_TRIANGLES,m_Quad.nNumVerts);
glPopMatrix();
// Unbind the texture
glBindTexture(GL_TEXTURE_2D,0);
}
}
这是我的使用方式
bool Engine::Init()
{
initWindow();
initOpenGL();
/*
APPLICATION STUFF...
*/
pTarget = new RenderTarget();
pTarget->CreateSurfaceTarget(m_pEglConfig,300.0f,300.0f);
}
void Engine::Draw()
{
if (m_pDisplay != EGL_NO_DISPLAY)
{
GLint curViewportSize[4];
glGetIntegerv(GL_VIEWPORT,curViewportSize);
pTarget->BindTarget(m_pDisplay,m_pContext);
glColor4f(1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
pTarget->UnbindTarget(m_pDisplay,m_pContext,m_pSurface);
glViewport(curViewportSize[0],curViewportSize[1],curViewportSize[2],curViewportSize[3]);
pTarget->Render(10,10);
eglSwapBuffers(m_pDisplay,m_pSurface);
}
}
这就是我初始化EGL / OpenGL的方式
bool Engine::initWindow()
{
m_pDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY));
eglInitialize(m_pDisplay,0);
eglChooseConfig(m_pDisplay,attribs,&nNumConfigs);
eglGetConfigAttrib(m_pDisplay,EGL_NATIVE_VISUAL_ID,&nFormat);
ANativeWindow_setBuffersGeometry(m_pApp->window,nFormat);
m_pSurface = eglCreateWindowSurface(m_pDisplay,m_pApp->window,nullptr);
m_pContext = eglCreateContext(m_pDisplay,nullptr,nullptr);
eglMakeCurrent(m_pDisplay,m_pContext);
eglQuerySurface(m_pDisplay,EGL_WIDTH,&m_nWidth);
eglQuerySurface(m_pDisplay,&m_nHeight);
}
bool Engine::initOpenGL()
{
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_FASTEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClearColor(1.0f,0.41f,0.71f,1.0f);
glLoadIdentity();
glOrthof(0,m_nWidth,m_nHeight,10);
}
我希望屏幕上会显示300x300的纯白色纹理,但我什么也没得到。有什么想法吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)