PuzzleSDK
MaterialSystemTest.cpp
浏览该文件的文档.
1/****************************************************************************
2 Copyright (c) 2012 cocos2d-x.org
3 Copyright (c) 2013-2016 Chukong Technologies Inc.
4 Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
5
6 http://www.cocos2d-x.org
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 THE SOFTWARE.
25 ****************************************************************************/
26
27#include "MaterialSystemTest.h"
28
29#include <ctime>
30#include <spine/spine-cocos2dx.h>
31
32#include "../testResource.h"
33#include "cocos2d.h"
34#include "ui/CocosGUI.h"
35
37
38static void printProperties(Properties* properties, int indent);
39
40
41// MARK: Tests
42
43MaterialSystemTest::MaterialSystemTest()
44{
52}
53
55{
56 return "Material System";
57}
58
59// MARK: Tests start here
60
62{
64
65 auto sprite = Sprite3D::create("Sprite3DTest/boss1.obj");
66 sprite->setScale(8.f);
67 sprite->setTexture("Sprite3DTest/boss.png");
68 this->addChild(sprite);
69 sprite->setPositionNormalized(Vec2(0.5f,0.5f));
70}
71
73{
74 return "Material System on Sprite3D";
75}
76
78{
80
81 const char* names[] = {
82 "Sprite3DTest/ReskinGirl.c3b",
83 "Sprite3DTest/ReskinGirl.c3b",
84 "Sprite3DTest/ReskinGirl.c3b",
85 "Sprite3DTest/ReskinGirl.c3b",
86 "Sprite3DTest/ReskinGirl.c3b",
87 "Sprite3DTest/ReskinGirl.c3b",
88 "Sprite3DTest/ReskinGirl.c3b",
89 "Sprite3DTest/ReskinGirl.c3b",
90 };
91
92 const int totalNames = sizeof(names) / sizeof(names[0]);
93
94 auto size = Director::getInstance()->getWinSize();
95
96 for(int i=0;i<totalNames;i++)
97 {
98 auto sprite = Sprite3D::create(names[i]);
99 this->addChild(sprite);
100 sprite->setPosition(Vec2((size.width/(totalNames+1))*(i+1), size.height/4));
101 sprite->setScale(3);
102 }
103}
104
106{
107 return "Sprites with multiple meshes";
108}
109
110//
111// MARK: Material_2DEffects
112//
114{
116
117 auto properties = Properties::createNonRefCounted("Materials/2d_effects.material#sample");
118
119 // Print the properties of every namespace within this one.
120 printProperties(properties, 0);
121
122 Material *mat1 = Material::createWithProperties(properties);
123
124 auto spriteBlur = Sprite::create("Images/grossini.png");
125 spriteBlur->setPositionNormalized(Vec2(0.2f, 0.5f));
126 this->addChild(spriteBlur);
127 spriteBlur->setProgramState(mat1->getTechniqueByName("blur")->getPassByIndex(0)->getProgramState());
128
129 auto spriteOutline = Sprite::create("Images/grossini.png");
130 spriteOutline->setPositionNormalized(Vec2(0.4f, 0.5f));
131 this->addChild(spriteOutline);
132 spriteOutline->setProgramState(mat1->getTechniqueByName("outline")->getPassByIndex(0)->getProgramState());
133
134 auto spriteNoise = Sprite::create("Images/grossini.png");
135 spriteNoise->setPositionNormalized(Vec2(0.6f, 0.5f));
136 this->addChild(spriteNoise);
137 spriteNoise->setProgramState(mat1->getTechniqueByName("noise")->getPassByIndex(0)->getProgramState());
138
139 auto spriteEdgeDetect = Sprite::create("Images/grossini.png");
140 spriteEdgeDetect->setPositionNormalized(Vec2(0.8f, 0.5f));
141 this->addChild(spriteEdgeDetect);
142 spriteEdgeDetect->setProgramState(mat1->getTechniqueByName("edge_detect")->getPassByIndex(0)->getProgramState());
143
144 timeUniforms.clear();
145
146#define FETCH_CCTIME_LOCATION(sprite) do { \
147 auto programState = sprite->getProgramState(); \
148 auto location = programState->getUniformLocation("u_Time"); \
149 timeUniforms.emplace_back(programState, location); \
150 }while(0)
151
152 FETCH_CCTIME_LOCATION(spriteBlur);
153 FETCH_CCTIME_LOCATION(spriteOutline);
154 FETCH_CCTIME_LOCATION(spriteNoise);
155 FETCH_CCTIME_LOCATION(spriteEdgeDetect);
156
157 schedule(CC_SCHEDULE_SELECTOR(Material_2DEffects::updateCCTimeUniforms));
158
159 // properties is not a "Ref" object
160 CC_SAFE_DELETE(properties);
161}
162
164{
165 return "Testing effects on Sprite";
166}
167
169{
170 float time = Director::getInstance()->getTotalFrames() * Director::getInstance()->getAnimationInterval();
171 Vec4 random(time / 10.0f, time, time * 2.0f, time * 4.0f);
172 for (auto &loc : timeUniforms)
173 {
174 loc.programState->setUniform(loc.location, &random, sizeof(random));
175 }
176}
177
178//
179// MARK: Material_AutoBindings
180//
181
182/*
183 * Custom material auto-binding resolver for terrain.
184 */
185class EffectAutoBindingResolver : public backend::ProgramState::AutoBindingResolver
186{
187 virtual bool resolveAutoBinding(backend::ProgramState* programState,/* Node* node,*/ const std::string& uniform, const std::string& autoBinding) override;
188
189 void callbackRadius(backend::ProgramState* programState, backend::UniformLocation uniform);
190 void callbackColor(backend::ProgramState* programState, backend::UniformLocation uniform);
191};
192
193bool EffectAutoBindingResolver::resolveAutoBinding(backend::ProgramState* programState, /*Node* node,*/ const std::string& uniform, const std::string& autoBinding)
194{
195 if (autoBinding.compare("DYNAMIC_RADIUS")==0)
196 {
197 auto loc = programState->getUniformLocation(uniform);
198 programState->setCallbackUniform(loc, CC_CALLBACK_2(EffectAutoBindingResolver::callbackRadius, this));
199 return true;
200 }
201 else if (autoBinding.compare("OUTLINE_COLOR")==0)
202 {
203 auto loc = programState->getUniformLocation(uniform);
204 programState->setCallbackUniform(loc, CC_CALLBACK_2(EffectAutoBindingResolver::callbackColor, this));
205 return true;
206 }
207 return false;
208}
209
210void EffectAutoBindingResolver::callbackRadius(backend::ProgramState *programState, backend::UniformLocation uniform)
211{
212 float f = CCRANDOM_0_1() * 10;
213 programState->setUniform(uniform, &f, sizeof(f));
214}
215
216void EffectAutoBindingResolver::callbackColor(backend::ProgramState *programState, backend::UniformLocation uniform)
217{
218 float r = CCRANDOM_0_1();
219 float g = CCRANDOM_0_1();
220 float b = CCRANDOM_0_1();
221 Vec3 color(r, g, b);
222
223 programState->setUniform(uniform, &color, sizeof(color));
224}
225
227{
229}
230
232{
233 delete _resolver;
234}
235
236
238{
240
241// auto properties = Properties::createNonRefCounted("Materials/2d_effects.material#sample");
242 auto properties = Properties::createNonRefCounted("Materials/auto_binding_test.material#sample");
243
244 // Print the properties of every namespace within this one.
245 printProperties(properties, 0);
246
247 Material *mat1 = Material::createWithProperties(properties);
248
249 auto spriteBlur = Sprite::create("Images/grossini.png");
250 spriteBlur->setPositionNormalized(Vec2(0.2f, 0.5f));
251 this->addChild(spriteBlur);
252 spriteBlur->setProgramState(mat1->getTechniqueByName("blur")->getPassByIndex(0)->getProgramState());
253
254 auto spriteOutline = Sprite::create("Images/grossini.png");
255 spriteOutline->setPositionNormalized(Vec2(0.4f, 0.5f));
256 this->addChild(spriteOutline);
257 spriteOutline->setProgramState(mat1->getTechniqueByName("outline")->getPassByIndex(0)->getProgramState());
258
259 auto spriteNoise = Sprite::create("Images/grossini.png");
260 spriteNoise->setPositionNormalized(Vec2(0.6f, 0.5f));
261 this->addChild(spriteNoise);
262 spriteNoise->setProgramState(mat1->getTechniqueByName("noise")->getPassByIndex(0)->getProgramState());
263
264 auto spriteEdgeDetect = Sprite::create("Images/grossini.png");
265 spriteEdgeDetect->setPositionNormalized(Vec2(0.8f, 0.5f));
266 this->addChild(spriteEdgeDetect);
267 spriteEdgeDetect->setProgramState(mat1->getTechniqueByName("edge_detect")->getPassByIndex(0)->getProgramState());
268
269 _noiseProgramState = spriteNoise->getProgramState();
270 _locationTime = _noiseProgramState->getUniformLocation("u_Time");
271
272 schedule(CC_SCHEDULE_SELECTOR(Material_AutoBindings::updateUniformTime));
273 // properties is not a "Ref" object
274 CC_SAFE_DELETE(properties);
275}
276
278{
279 return "Testing auto-bindings uniforms";
280}
281
283{
284 float time = Director::getInstance()->getTotalFrames() * Director::getInstance()->getAnimationInterval();
285 Vec4 random(time / 10.0f, time, time * 2.0f, time * 4.0f);
286 _noiseProgramState->setUniform(_locationTime, &random, sizeof(random));
287}
288
289//
290//
291//
293{
295
296 auto sprite = Sprite3D::create("Sprite3DTest/boss1.obj");
297 sprite->setScale(6);
298 this->addChild(sprite);
299 sprite->setPositionNormalized(Vec2(0.5f,0.5f));
300 _sprite = sprite;
301
302
303 Material *mat = Material::createWithFilename("Materials/3d_effects.material");
304 sprite->setMaterial(mat);
305
306 // lights
307 auto light1 = AmbientLight::create(Color3B::RED);
308 addChild(light1);
309
310 auto light2 = DirectionLight::create(Vec3(-1,1,0), Color3B::GREEN);
311 addChild(light2);
312
313 this->schedule(CC_CALLBACK_1(Material_setTechnique::changeMaterial, this), 1, "cookie");
314 _techniqueState = 0;
315
316 auto rot = RotateBy::create(5, Vec3(30.0f,60.0f,270.0f));
317 auto repeat = RepeatForever::create(rot);
318 sprite->runAction(repeat);
319}
320
322{
323 return "Testing setTechnique()";
324}
325
327{
328 // get it from Mesh 0
329 switch (_techniqueState)
330 {
331 case 0:
332 _sprite->getMaterial(0)->setTechnique("lit");
333 break;
334 case 1:
335 _sprite->getMaterial(0)->setTechnique("normal");
336 break;
337 case 2:
338 _sprite->getMaterial(0)->setTechnique("outline");
339 break;
340 default:
341 break;
342 }
343
345}
346
347//
348//
349//
351{
353
354 auto sprite = Sprite3D::create("Sprite3DTest/boss1.obj");
355 sprite->setScale(3);
356 this->addChild(sprite);
357 sprite->setPositionNormalized(Vec2(0.25f, 0.5f));
358
359 Material *mat = Material::createWithFilename("Materials/3d_effects.material");
360 sprite->setMaterial(mat);
361
362 auto rot = RotateBy::create(5, Vec3(360.0f,240.0f,120.0f));
363 auto repeat = RepeatForever::create(rot);
364 sprite->runAction(repeat);
365
366 // sprite 2... using same material
367 auto sprite2 = Sprite3D::create("Sprite3DTest/boss1.obj");
368 sprite2->setScale(3);
369 this->addChild(sprite2);
370 sprite2->setPositionNormalized(Vec2(0.5f, 0.5f));
371 sprite2->setMaterial(mat);
372 sprite2->runAction(repeat->clone());
373
374 // sprite 3... using cloned material
375 auto sprite3 = Sprite3D::create("Sprite3DTest/boss1.obj");
376 sprite3->setScale(3);
377 this->addChild(sprite3);
378 sprite3->setPositionNormalized(Vec2(0.75f, 0.5f));
379 auto mat2 = mat->clone();
380 sprite3->setMaterial(mat2);
381 sprite3->runAction(repeat->clone());
382
383 // testing clone
384 // should affect both sprite 1 and sprite 2
385 mat->setTechnique("outline");
386
387 // should affect only sprite 3
388// mat2->setTechnique("normal");
389
390}
391
392std::string Material_clone::subtitle() const
393{
394 return "Testing material->clone()";
395}
396
397//
398//
399//
400const int SHOW_LEBAL_TAG = 114;
401
403{
405
406 _maxParsingCoumt = 5e3;
407
408 auto screenSize = Director::getInstance()->getWinSize();
409
410 ui::Slider* slider = ui::Slider::create();
411 slider->loadBarTexture("cocosui/sliderTrack.png");
412 slider->loadSlidBallTextures("cocosui/sliderThumb.png", "cocosui/sliderThumb.png", "");
413 slider->loadProgressBarTexture("cocosui/sliderProgress.png");
414 slider->setPercent(50);
415
416 slider->setPosition(Vec2(screenSize.width / 2.0f, screenSize.height / 3.0f));
417 slider->addEventListener([&](Ref* sender, ui::Slider::EventType type) {
418
419 if (type == ui::Slider::EventType::ON_SLIDEBALL_UP)
420 {
421 ui::Slider* slider = dynamic_cast<ui::Slider*>(sender);
422 float p = slider->getPercent() / 100.0f;
423 slider->setTouchEnabled(false);
424 CCLOG("Will parsing material %d times", (int)(p * _maxParsingCoumt));
425 Label* label = dynamic_cast<Label*>(this->getChildByTag(SHOW_LEBAL_TAG));
426 if(label)
427 {
428 label->setString("Testing start!");
429 }
430 this->scheduleOnce(
431 [this, p, slider](float)
432 {
434 slider->setTouchEnabled(true);
435 },
436 1.0, "schedule test parsing");
437
438 }
439 });
440
441 addChild(slider);
442
443 auto label = Label::createWithSystemFont("Max parsing count is 10000, which may crash because of high memory consumption.", "Helvetica", 10);
444 label->setPosition(Vec2(screenSize.width / 2.0f, screenSize.height / 2.0f - 20));
445 addChild(label);
446 label = Label::createWithSystemFont("Slide to test parsing performance", "Helvetica", 10);
447 label->setPosition(Vec2(screenSize.width / 2.0f, screenSize.height / 2.0f));
448 addChild(label);
449
450 label = Label::createWithSystemFont("", "Helvetica", 10);
451 label->setPosition(Vec2(screenSize.width / 2.0f, screenSize.height / 2.0f + 20));
452 label->setTag(SHOW_LEBAL_TAG);
453 addChild(label);
454
455}
456
458{
459 std::clock_t begin = std::clock();
460
461 for (unsigned int i = 0; i < count; i++)
462 {
463 Material::createWithFilename("Materials/2d_effects.material");
464 Material::createWithFilename("Materials/3d_effects.material");
465 }
466
467 std::clock_t end = std::clock();
468 double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
469 Label* label = dynamic_cast<Label*>(this->getChildByTag(SHOW_LEBAL_TAG));
470 if(label)
471 {
472 std::string str = StringUtils::format("Testing completed! Took: %.3f seconds for parsing material %d times.", elapsed_secs, count);
473 label->setString(str);
474
475 CCLOG("Took: %.3f seconds for parsing material %d times.", elapsed_secs, count);
476 }
477}
478
480{
481 return "Testing parsing performance";
482}
483
484// MARK: Helper functions
485
486static void printProperties(Properties* properties, int indent)
487{
488 // Print the name and ID of the current namespace.
489 const char* spacename = properties->getNamespace();
490 const char* id = properties->getId();
491 char chindent[64];
492 int i=0;
493 for(i=0; i<indent*2;i++)
494 chindent[i] = ' ';
495 chindent[i] = '\0';
496
497 log("%sNamespace: %s ID: %s\n%s{", chindent, spacename, id, chindent);
498
499 // Print all properties in this namespace.
500 const char* name = properties->getNextProperty();
501 const char* value = NULL;
502 while (name != NULL)
503 {
504 value = properties->getString(name);
505 log("%s%s = %s", chindent, name, value);
506 name = properties->getNextProperty();
507 }
508
509 Properties* space = properties->getNextNamespace();
510 while (space != NULL)
511 {
512 printProperties(space, indent+1);
513 space = properties->getNextNamespace();
514 }
515
516 log("%s}\n",chindent);
517}
#define ADD_TEST_CASE(__className__)
Definition: BaseTest.h:211
static void printProperties(Properties *properties, int indent)
const int SHOW_LEBAL_TAG
#define FETCH_CCTIME_LOCATION(sprite)
void callbackRadius(backend::ProgramState *programState, backend::UniformLocation uniform)
virtual bool resolveAutoBinding(backend::ProgramState *programState, const std::string &uniform, const std::string &autoBinding) override
void callbackColor(backend::ProgramState *programState, backend::UniformLocation uniform)
virtual void onEnter() override
void updateCCTimeUniforms(float)
std::vector< Locations > timeUniforms
virtual std::string subtitle() const override
EffectAutoBindingResolver * _resolver
virtual void onEnter() override
cocos2d::backend::ProgramState * _noiseProgramState
cocos2d::backend::UniformLocation _locationTime
virtual std::string subtitle() const override
virtual std::string subtitle() const override
virtual void onEnter() override
virtual std::string subtitle() const override
virtual void onEnter() override
virtual void onEnter() override
virtual std::string subtitle() const override
virtual void onEnter() override
void parsingTesting(unsigned int count)
virtual std::string subtitle() const override
cocos2d::Sprite3D * _sprite
virtual std::string subtitle() const override
virtual void onEnter() override
virtual std::string title() const override
virtual void onEnter() override
Definition: BaseTest.cpp:430