今天在重载Sprite 的 OnDraw()函数中 计算顶点坐标, 获取精灵的模型矩阵 乘以 quad 的顶点结果坐标
没发生任何改变, 原来是使用了Mat4的 transformVector 方法, 然后又发现Mat4的矩阵有重载 Vec3的 *= 运算符
,又用该运算符计算结果还是没有任何改变, 有点怀疑人生了。 后来又搜索Mat4中所有和Vec3相关的函数,发现
还有个transformPoint 方法。 试了一下居然成功了, 真坑啊, 仔细对比了一下和另外两个函数的区别, 原来 transformVector 和 *= 运算符
把 Vec3 转 Vec4的时候 第四个数补了0 , 而只有transformPoint是补的1 , 因此前两个函数没有生效。
另外发现Cocos2dx的一个小与众不同的地方: 部分顶点坐标的转化计算在cpu中进行
函数:CCRenderer.cpp 中 void Renderer::fillVerticesAndIndices(const TrianglesCommand* cmd)
改函数直接用modelView来在cpu中进行了坐标转换计算。不过2d顶点数比较。不像3d模型动辄上千顶点。
反正3d模型没这么干就ok,只是记录一下。 自己计算了的话这里可以不用再次计算。 我的做法是增加
了一个 单位矩阵的判断, 毕竟矩阵乘法还是有开销的
然后找到了一个遇到同样问题的文章:
3.0 onDraw 渲染的坐标问题?
我是为了实现显示一张图片,然后指定图片显示的顶点来实现显示图片的任意形状。然后继承了Sprite并重写了onDraw,代码如下。
void SpritePoly::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags){
Sprite::draw(renderer,transform,flags);
_customCommand.init(_globalZOrder);
_customCommand.func = =](){
CC_NODE_DRAW_SETUP();
if(getTexture()!=NULL){
GL::bindTexture2D(getTexture()->getName());
}else{
GL::bindTexture2D(0);
}
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
//顶点
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertexs_);
//纹理
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, 0, uvs_);
//颜色。
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, colors_);
//根据索引draw三角形
glDrawElements(GL_TRIANGLES, (verCont_-2)*3 , GL_UNSIGNED_SHORT, indices_);
};
renderer->addCommand(&_customCommand);
}
问题来了,我自己绘制的精灵坐标在0.0点,而系统的可以正确的位置。怎么样才能让我绘制的和系统的精灵保持同一位置?
顶啊
求解决啊
不解决不沉贴
求高手解决。
。。。。。。。。。。
cocos2d好像不给custom command进行定点坐标系转换,咳咳,再说它也不知道你有啥定点。
你估计需要手动把顶点和串联后的transform矩阵进行乘法运算。
你的这个代码功能,跟batchnode的几乎一样,可以参考下它的代码。
终于有人回话了。按理来说我不是设置了setPoint吗?我是继承的精灵。你说的batchNode具体指的是?
手头没cocos代码,只能按印象说下。
好像叫SpriteBatchNode吧。
数据是继承了,但是行为没继承。sprite使用普通的command(名字忘了)。这个结构里有顶点信息Quard4和串联后的转换矩阵。
cocos在把顶点信息写入opengl buffer前,进行了一次矩阵乘法,参考类Render。custom command好像没有顶点信息,你需要自己去乘一下。
对。精灵用的是QuadCommand,通过设置参数,然后再特定解析这个QuadCommand,进行渲染,包括矩阵信息。但是custom command没有。只有一个方法。
我看DrawNode 是通过。 director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, oldModelView);
去实现的。如果注释的话draw的绘制也是在0.0坐标。
问题是,我写了这句话没有用。我不知道为什么?这个问题我卡几个月了。从3.0出来一直存在。求帮忙解决。
pushMatrix和loadMatrix好像废弃不建议使用了。它修改的是cocos2d的矩阵堆栈,跟opengl无关。
你的custom command直接操作opengl,已经把cocos2d的所有的后续处理都旁路了,调用cocos的函数肯定是不会起作用的。
Node的visit函数里有个if (xxxdirty) { transform(xxoo); }返回的就是串联后的矩阵,cocos叫它模型矩阵。
render里有个转换函数,名字忘了。你看看它是怎么把模型矩阵和原始顶点坐标转换成opengl坐标的。应该能直接调用这个函数,spritebatchnode里好像用的也是这个函数。
看了下,还是不太懂这个流程啊。。。。
以前2.x是好的。不需要设置什么的。坐标是走的sprite的setpoint。
这个问题应该就是简单的设置几个API吧。求大牛帮忙看看。感谢不尽,说下具体调用什么能实现坐标改变。我也不懂openGL。
2.x的代码我没看过,我是从3.0开始接触cocos2d的。估计2.x的代码修改了opengl的模型矩阵状态,否则不可能生效的。
你可以把你要填充的顶点都转换一下。sprite的draw函数传进来的那个Mat4,应该就是model的仿射矩阵,Mat4好像有个函数叫transformPoint。把模型坐标转换成opengl坐标,再填充到你的VB里。
再不干脆改变一下opengl的模型矩阵吧。把那个mat4,压入opengl,不过记得渲染后要改回来,否则后面的渲染就全乱套了。custom command不被优化,
每个custom command对于cocos来说都是一次call。所以修改opengl状态反倒是划算的,如果你的顶点数量比较多的话,省得乘来乘去的,让显卡去乘吧。
非常感谢。我可以手转了。只需要改顶点。。。我太笨了,以为改不了。现在可以了。谢谢了。
//顶点
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertexs_);
直接改vertexs_:14:
1月后
可以问一下 怎么指定顶点的吗?? 我游戏里有个需求也是这样的 要显示图片的任意形状部分,不过opgl 不太会写,可以指点以下吗?
你好! 看起来你挺喜欢这个讨论,但是你还没有注册账户。
当你创建了账户,我们能准确地追踪你的阅读进度,所以你能够在下一次访问时回到你上次阅读到的地方。你也可以在有新帖子的时候收到网页和邮件通知。并且你可以赞任何帖子来分享你的感谢。
注册 明天提醒我不了