PuzzleSDK
DrawNode3D.cpp
浏览该文件的文档.
1/****************************************************************************
2 Copyright (c) 2014-2016 Chukong Technologies Inc.
3 Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
4
5 http://www.cocos2d-x.org
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 THE SOFTWARE.
24 ****************************************************************************/
25
26#include "DrawNode3D.h"
27#include "renderer/backend/Buffer.h"
28NS_CC_BEGIN
29
30
31DrawNode3D::DrawNode3D()
32{
33 _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
34}
35
37{
38 CC_SAFE_RELEASE_NULL(_programStateLine);
39 CC_SAFE_DELETE(_depthstencilDescriptor);
40}
41
43{
44 DrawNode3D* ret = new (std::nothrow) DrawNode3D();
45 if (ret && ret->init())
46 {
47 ret->autorelease();
48 }
49 else
50 {
51 CC_SAFE_DELETE(ret);
52 }
53
54 return ret;
55}
56
58{
59 CCASSERT(count>=0, "capacity must be >= 0");
60
61 auto EXTENDED_SIZE = _bufferLines.size() + count;
62
63 _bufferLines.reserve(EXTENDED_SIZE);
64
65 if (!_customCommand.getVertexBuffer() || _customCommand.getVertexBuffer()->getSize() < (EXTENDED_SIZE * sizeof(_bufferLines[0])))
66 {
67 _customCommand.createVertexBuffer(sizeof(V3F_C4B), EXTENDED_SIZE + (EXTENDED_SIZE >> 1), CustomCommand::BufferUsage::DYNAMIC);
68 }
69
70}
71
73{
74 _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
75 auto &pd = _customCommand.getPipelineDescriptor();
76 auto program = backend::Program::getBuiltinProgram(backend::ProgramType::LINE_COLOR_3D);
77 _programStateLine = new backend::ProgramState(program);
78 pd.programState = _programStateLine;
79
80 _locMVPMatrix = _programStateLine->getUniformLocation("u_MVPMatrix");
81
82 _customCommand.setBeforeCallback(CC_CALLBACK_0(DrawNode3D::onBeforeDraw, this));
83 _customCommand.setAfterCallback(CC_CALLBACK_0(DrawNode3D::onAfterDraw, this));
84
85 auto layout = _programStateLine->getVertexLayout();
86#define INITIAL_VERTEX_BUFFER_LENGTH 512
87
89
90 _customCommand.setDrawType(CustomCommand::DrawType::ARRAY);
91 _customCommand.setPrimitiveType(CustomCommand::PrimitiveType::LINE);
92
93 const auto& attributeInfo = _programStateLine->getProgram()->getActiveAttributes();
94 auto iter = attributeInfo.find("a_position");
95 if(iter != attributeInfo.end())
96 {
97 layout->setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT3, 0, false);
98 }
99 iter = attributeInfo.find("a_color");
100 if(iter != attributeInfo.end())
101 {
102 layout->setAttribute("a_color", iter->second.location, backend::VertexFormat::UBYTE4, sizeof(Vec3), true);
103 }
104 layout->setLayout(sizeof(V3F_C4B));
105
106 _customCommand.createVertexBuffer(sizeof(V3F_C4B), INITIAL_VERTEX_BUFFER_LENGTH, CustomCommand::BufferUsage::DYNAMIC);
107 _isDirty = true;
108
109#if CC_ENABLE_CACHE_TEXTURE_DATA
110 // Need to listen the event only when not use batchnode, because it will use VBO
111 auto listener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, [this](EventCustom* event){
113 this->init();
114 });
115
116 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
117#endif
118
119 return true;
120}
121
122void DrawNode3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
123{
124 _customCommand.init(_globalZOrder, transform, flags);
125
126 updateCommand(renderer, transform, flags);
127
128 if (_isDirty && !_bufferLines.empty())
129 {
130 _customCommand.updateVertexBuffer(_bufferLines.data(), (unsigned int)(_bufferLines.size() * sizeof(_bufferLines[0])));
131 _customCommand.setVertexDrawInfo(0, _bufferLines.size());
132 _isDirty = false;
133 }
134
135 if (!_bufferLines.empty())
136 {
137 renderer->addCommand(&_customCommand);
138 }
139}
140
141void DrawNode3D::updateCommand(cocos2d::Renderer* renderer,const Mat4 &transform, uint32_t flags)
142{
143 auto &matrixP = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
144 auto mvp = matrixP * transform;
145
146 _programStateLine->setUniform(_locMVPMatrix, mvp.m, sizeof(mvp.m));
147
148
149 auto &blend = _customCommand.getPipelineDescriptor().blendDescriptor;
150 blend.blendEnabled = true;
151 blend.sourceRGBBlendFactor = blend.sourceAlphaBlendFactor = _blendFunc.src;
152 blend.destinationRGBBlendFactor = blend.destinationAlphaBlendFactor = _blendFunc.dst;
153
154 CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, _bufferLines.size());
155}
156
157void DrawNode3D::drawLine(const Vec3 &from, const Vec3 &to, const Color4F &color)
158{
159 unsigned int vertex_count = 2;
160 ensureCapacity(vertex_count);
161
162 Color4B col = Color4B(color);
163 V3F_C4B a = {Vec3(from.x, from.y, from.z), col};
164 V3F_C4B b = {Vec3(to.x, to.y, to.z), col, };
165
166 _bufferLines.push_back(a);
167 _bufferLines.push_back(b);
168
169 _isDirty = true;
170}
171
172void DrawNode3D::drawCube(Vec3* vertices, const Color4F &color)
173{
174 // front face
175 drawLine(vertices[0], vertices[1], color);
176 drawLine(vertices[1], vertices[2], color);
177 drawLine(vertices[2], vertices[3], color);
178 drawLine(vertices[3], vertices[0], color);
179
180 // back face
181 drawLine(vertices[4], vertices[5], color);
182 drawLine(vertices[5], vertices[6], color);
183 drawLine(vertices[6], vertices[7], color);
184 drawLine(vertices[7], vertices[4], color);
185
186 // edge
187 drawLine(vertices[0], vertices[7], color);
188 drawLine(vertices[1], vertices[6], color);
189 drawLine(vertices[2], vertices[5], color);
190 drawLine(vertices[3], vertices[4], color);
191}
192
194{
195 _bufferLines.clear();
196 _isDirty = true;
197}
198
199const BlendFunc& DrawNode3D::getBlendFunc() const
200{
201 return _blendFunc;
202}
203
204void DrawNode3D::setBlendFunc(const BlendFunc &blendFunc)
205{
206 _blendFunc = blendFunc;
207}
208
209
211{
212 auto *renderer = Director::getInstance()->getRenderer();
213 _rendererDepthTestEnabled = renderer->getDepthTest();
214 renderer->setDepthTest(true);
215}
216
218{
219 auto *renderer = Director::getInstance()->getRenderer();
220 renderer->setDepthTest(_rendererDepthTestEnabled);
221}
222
223
224NS_CC_END
#define INITIAL_VERTEX_BUFFER_LENGTH
void clear()
Definition: DrawNode3D.cpp:193
std::vector< V3F_C4B > _bufferLines
Definition: DrawNode3D.h:108
cocos2d::CustomCommand _customCommand
Definition: DrawNode3D.h:104
virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags) override
Definition: DrawNode3D.cpp:122
backend::ProgramState * _programStateLine
Definition: DrawNode3D.h:105
void onAfterDraw()
Definition: DrawNode3D.cpp:217
void onBeforeDraw()
Definition: DrawNode3D.cpp:210
bool _rendererDepthTestEnabled
Definition: DrawNode3D.h:115
virtual ~DrawNode3D()
Definition: DrawNode3D.cpp:36
BlendFunc _blendFunc
Definition: DrawNode3D.h:103
void ensureCapacity(int count)
Definition: DrawNode3D.cpp:57
const BlendFunc & getBlendFunc() const
Definition: DrawNode3D.cpp:199
backend::DepthStencilDescriptor * _depthstencilDescriptor
Definition: DrawNode3D.h:106
bool _isDirty
Definition: DrawNode3D.h:114
void setBlendFunc(const BlendFunc &blendFunc)
Definition: DrawNode3D.cpp:204
void drawCube(cocos2d::Vec3 *vertices, const Color4F &color)
Definition: DrawNode3D.cpp:172
void updateCommand(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)
Definition: DrawNode3D.cpp:141
backend::UniformLocation _locMVPMatrix
Definition: DrawNode3D.h:107
static cocos2d::DrawNode3D * create()
Definition: DrawNode3D.cpp:42
void drawLine(const cocos2d::Vec3 &from, const cocos2d::Vec3 &to, const Color4F &color)
Definition: DrawNode3D.cpp:157
virtual bool init() override
Definition: DrawNode3D.cpp:72