cocos2dx下离屏渲染遇到的问题

102 篇文章 0 订阅
81 篇文章 2 订阅

1. 离屏渲染流程,基于opengles2.0

2.2.6下面选了SimpleGame例子,在jni中添加了nativeBegin和nativeEnd函数。最终离屏绘制流程:

nativeBegin();
nativeRender(); // cocos2dx的绘制。。。
nativeEnd();
nativeBegin函数中,创建屏幕大小的fbo,绑定一个纹理和深度,然后绑定到当前创建的fbo上。nativeEnd中将fbo的纹理贴到屏幕上。。。

2. cocos2dx-2.2.6 下黑屏问题

但是运行以后结果是残忍的黑屏。。。好吧。又是状态错乱的问题,一步步排查吧:

nativeBegin和nativeEnd之间如果替换我自己render函数结果ok。进一步证明是nativeBegin和End函数与cocos2dx的render函数状态不吻合导致。追查了三天左右,最终问题定位在nativeEnd中renderQuad代码段上:

#if 0
	// This section will call 0x500 Invalid Enum Error.
	glEnable(GL_TEXTURE_2D);
	checkGLError("glEnable");
#endif

	glActiveTexture(GL_TEXTURE0);
	checkGLError("glActiveTexture");
	// glBindTexture(GL_TEXTURE_2D, mPostPass.color_id);
	glBindTexture(GL_TEXTURE_2D, mPass.color_id);
	checkGLError("glBindTexture");
	glUniform1i(mBoard.uTexLoc, 0);
	checkGLError("glUniform1i");

	float vertices[] = {-1.0,1.0, -1.0,-1.0, 1.0,1.0, 1.0,-1.0};
	const float texcoords[] = {0,1, 0,0, 1,1, 1,0};

	glVertexAttribPointer(mBoard.aPosLoc, 2, GL_FLOAT, GL_FALSE, 0, vertices);
	glVertexAttribPointer(mBoard.aUVLoc, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
	glEnableVertexAttribArray(mBoard.aPosLoc);
	glEnableVertexAttribArray(mBoard.aUVLoc);
		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

#if 0
	glDisableVertexAttribArray(mBoard.aUVLoc);
	glDisableVertexAttribArray(mBoard.aPosLoc);
#endif
opengles2.0中,不需要显式调用glEnable(TEXTURE_2D),否则LogCat中会报0x500错误。屏幕黑屏问题出在:绘制结束时候关闭了定点数组的纹理和位置属性。。。从而导致下一帧绘制时,cocos2dx中这两个属性也没有开启,从而绘制到fbo上的内容为黑。。。

3. cocos2dx-3.2下黑屏问题

2.2下面没问题了,放到3.2上面依然黑屏,而且logcat中没有警告和error。。这下郁闷了,据说2.x到3.x变化很大。为了差这个bug,把3.2的渲染代码也研究了下。。。引入vbo和批量绘制。回到黑屏问题上,没辙了只能通过glReadpixels试试读取帧内容写文件看。

nativeRender函数刚开始一段时间,数据还没准备好是黑屏正常,直到数据准备好才有内容绘制。这点对我定位问题中干扰很大。因为刚开始渲染黑屏是正常的,大概100帧以后才开始有内容绘制。。。

为了测试构造一些特定场景:

当有内容绘制,begin和end中fbo才起作用:

0-100帧,nativeBegin和nativeEnd为空,nativeRender直接到屏幕。结果OK。

101帧,nativeBegin中fbo生效;1)nativeRender此时是否绘制正常?然后nativeEnd2)此时屏幕上是否OK?

102帧,nativeBegin依然生效;上一帧的nativeBegin和nativeEnd已经生效,3)此时nativeRender否是绘制正常?4)nativeEnd完成屏幕如何?

103帧,重复102模式了。。。

问题4是比较明显,肯定是黑屏了。

问题1,2,3只能通过glReadPixels读取当前绑定的帧缓冲内容写文件看。。。结论是1处绘制正常,2处绘制正常,3处已经黑屏了。

是nativeEnd第一次执行后导致了后续nativeRender的失效。。。

最近花了两三天,最终定位到问题。3.2中对gl绘制状态进行了缓存,例如shaderProgram,textureId这些东西。。缓存的宏开关在ccConfig.h头文件中:

#ifndef CC_ENABLE_GL_STATE_CACHE
#define CC_ENABLE_GL_STATE_CACHE 1
#endif

CC_ENABLE_GL_STATE_CACHE 定义成0,关闭GL状态缓存使用以后,结果ok。

或者不要直接调用gl的函数,而是通过ccGLStateCache组件中的接口调用GL指令,结果ok。

4. 2.2.6下部分手机左边留白问题

SimpleGame中的游戏积分label文字位置问题,nexus4手机上屏幕左边,在华为部分机器和小米3上面,左边跟屏幕有几十像素的距离。。这个问题比较eazy了,通过glGetIntegerv获取cocos2dx设置的viewport居然不是0,0,wid,height,nativeBegin中采用cocos2d的设置的viewport,nativeEnd中将纹理贴到屏幕上时使用0,0,wid,height。问题解决了。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Cocos2d-x中实现流光效果可以使用shader来进行渲染。首先,我们需要创建一个自定义的shader,并将其应用于需要实现流光效果的节点上。 在使用Cocos2d-x的过程中,我们可以使用GLSL语言编写shader代码。在实现流光效果的shader中,我们可以通过改变像素的颜色和透明度来创建流动的效果。 首先,我们定义一个uniform变量time,用于控制流光的移动速度。然后,在片段着色器中,通过改变颜色和透明度的计算公式来实现流动的效果。我们可以使用sin函数或者其他数学函数来计算出每个像素点的颜色和透明度,然后将其应用到节点上。 在节点的渲染流程中,我们将这个自定义的shader应用到节点上,然后传入时间参数,即更新uniform变量time的值。随着时间的增加,我们就可以看到节点上的流光效果在不断地移动。 为了实现更加逼真的流光效果,我们可以尝试给流光添加一些额外的效果,比如模糊、叠加等。通过调整shader代码中的计算公式和传入的参数,我们可以根据自己的需求来调整流光效果的强度和样式。 总结起来,在Cocos2d-x中实现流光效果需要创建一个自定义的shader,并将其应用于需要实现效果的节点上。通过改变颜色和透明度的计算公式、传入时间参数等,我们可以实现一个流光效果,使节点看起来具有流动的动画效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值