我想实现的功能是这样的。
- 有一批 Texture2D
- 根据程序中的状态,要在一个 cc.Layer 中不断切换这些 Texture2D 的部分 vertex 的显示。
- 目前的实现是用 Sprite,类似于 TMXTile 但是这个实现不灵活,而且 Sprite 还需要管理,很麻烦
- 所以我想有没有什么办法,可以象 DrawNode 那样用 Texture2D 来绘制呢?
我想实现的功能是这样的。
lz 是想把一个texture 贴在一个多边形上面
不知道我理解的对不对。
如果是的话。。。哈哈。
我知道怎么搞,前提是需要自己准备定点坐标,
如果那个多边形是动态的(比如说,在程序里面生成的不固定的多边形)。 那个纹理坐标够lz 折腾的了。
是滴,我就是想做你说的那样。
我已经做好思想准备了,请楼上告诉我吧!
lz 竟然是 2dx 的版主。
我就认为lz 肯定是很熟悉 2dx 和 OpenGL ES 2.0的特性的哈
首先,确认一点是,OpenGL ES 只支持三角形的片元。
那么自己绘制多边形 就需要把多边形分解成三角形来绘制。
如图。 比如说你有1,2,3,4,5个定点坐标来确认这个多边形。
那么我就是这样来分解多边形的。
1,2,3
1,3,4
1,4,5
三个三角形。
ps: 其实还有其它的三角形绘制方法,但是这个简单些。lz 肯定也懂的。
有了三角形 接下来就是确定每个坐标的纹理了。
注意:纹理坐标是[0-1]哦
可以参见游戏开发区里面 西蒙里面关于纹理的那一部分。
我也不知道lz的纹理要怎么贴上去。lz 自己搞定吧哈。
现在我认为楼主已经确定好了 定点数据和纹理数据。
接下来就是绘制这个东西的时候了。对不对。
因为是要自定义的,肯定不会用cocos2dx 标准的组建了。
lz sublcass 一个node吧。
class YourNode : public cocos2d::Node , public cocos2d::TextureProtocol
然后
1 选址合适的 opengl program
我这里是cocos2dx 3.0的版本。
我看了下cocos2dx 的shader。
如图红色框框里面的适合lz。
当然也可以用下面的那个ccShader_PositionTexture_uColor
这个有个颜色相乘。
然后就是自定义 node 的绘制函数了。
void YourNode::draw(Renderer *renderer, const Mat4 &transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(YourNode::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_customCommand);
}
void YourNode::onDraw(const Mat4& transform, bool transformUpdated)
{
GLYourProgram * program = static_cast<GLYourProgram *>(this->getGLProgram());
program->use();
program->setUniformsForBuiltins(transform);
GL::bindTexture2D(_texture->getName());
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
// draw.
GL::bindVAO(_node_vao);
glDrawElements(GL_TRIANGLES, _indexCounts, GL_UNSIGNED_SHORT, 0);
GL::bindVAO(0);
}
我草。。。 lz请原谅我这里我用了vao
我想传一些定点数据和纹理数据这种小事肯定是难不倒 lz 这样腻害的版主的。
祝愿lz 好远。
@konglongdan ,说的很详细,谢谢。
我是 quick-x 那里的,对 cocos 的实现代码正在熟悉中。
对于实现一个自定义的 Node 的实现成本,我觉得有点高。
我的问题是,是不是可以直接把 Texture2D 绑定到 DrawNode 上,对 DrawNode 的绘制方法扩展呢?
这方面的实现代码,我刚开始看,可能问题很低级。我仔细看一下代码再来请教您。
版主大人我又来了。







你要附在DrawNode 就更简单了。
你肯定已经看过DrawNode 的源代码了撒。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void drawDot(const Vec2 &pos, float radius, const Color4F &color);
void drawSegment(const Vec2 &from, const Vec2 &to, float radius, const Color4F &color);
void drawPolygon(Vec2 *verts, int count, const Color4F &fillColor, float borderWidth, const Color4F &borderColor);
void drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, const Color4F &color);
void drawCubicBezier(const Vec2& from, const Vec2& control1, const Vec2& control2, const Vec2& to, unsigned int segments, const Color4F &color);
void drawQuadraticBezier(const Vec2& from, const Vec2& control, const Vec2& to, unsigned int segments, const Color4F &color);
内置的这些方法其实就是生成定点数组撒。
所以版主大人都不用自己生成定点数组了。happy
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
V2F_C4B_T2F
对头你没有看错,定点数组就是用的这个数据结构。
而他的定义是:
struct V2F_C4B_T2F
{
//! vertices (2F)
Vec2 vertices;
//! colors (4B)
Color4B colors;
//! tex coords (2F)
Tex2F texCoords;
};
版主大人看了是不是泪流满面。我x,我需要的东西都有啊。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
再看一下绘制的代码。哎,版主大人肯定爱死cocos2dx了。数据传递,vao 什么的,一切需要的东西都在。
问提来了。 怎么加纹理了???
继续看下去。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void DrawNode::draw(Renderer *renderer, const Mat4 &transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(DrawNode::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_customCommand);
}
void DrawNode::onDraw(const Mat4 &transform, bool transformUpdated)
{
auto glProgram = getGLProgram();
glProgram->use();
glProgram->setUniformsForBuiltins(transform);
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
if (_dirty)
{
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(V2F_C4B_T2F)*_bufferCapacity, _buffer, GL_STREAM_DRAW);
_dirty = false;
}
if (Configuration::getInstance()->supportsShareableVAO())
{
GL::bindVAO(_vao);
}
else
{
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
// vertex
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, vertices));
// color
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, colors));
// texcood
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, texCoords));
}
glDrawArrays(GL_TRIANGLES, 0, _bufferCount);
glBindBuffer(GL_ARRAY_BUFFER, 0);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_bufferCount);
CHECK_GL_ERROR_DEBUG();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
以上都再解析DrawNode 下面的就是重点了。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
接下来就是启用纹理不就对了。
是的。
这里要subclass 一下没有问题了吧。
只需要 从这里继承就完了。
public cocos2d::TextureProtocol
然后设置自己的 program 是ccShader_PositionTextureColor 不就对了
(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR)
绘制的时候 onDraw 方法里面加上
GL::bindTexture2D(_texture->getName());
不就启用纹理了。
那纹理坐标怎么来???
假如你自己有一个方法叫 updateTextureCoords 的方法。
比如说drawPolygon 这个方法。
你重载下。先调用super 的drawPolygon 然后再调用自己的updateTextureCoords 方法不就更新了吗。
happy 啊 原来这么方方便,只需要少量改动。
其实也不用subclass 改那个DrawNode 也可以的。
ps: 以上仅仅是自己的的意见。 祝愿版主好远。
版主不用感谢我,请叫我红领巾。
好人啊! 好人啊!
我感动的热泪盈眶,你把我想做的要做的都做了。。。。。。。求认识。。。。
— Begin quote from ____
引用第6楼good-day于2014-07-25 17:22发表的 回 5楼(konglongdan) 的帖子 :
好人啊! 好人啊!
我感动的热泪盈眶,你把我想做的要做的都做了。。。。。。。求认识。。。。 http://www.cocoachina.com/bbs/job.php?action=topost&tid=216582&pid=1013351
— End quote
能认识版主大大简直是我莫大的荣幸啊。
不错 思路很不错 性能也能提升不少吧
大神能否给我封装一个完整的类,看来你的,小白的我还是不会咋搞啊
