2012-04-08 14:16:29 +08:00
|
|
|
#include "CCConfiguration.h"
|
|
|
|
#include "RenderTextureTest.h"
|
2013-03-06 16:36:44 +08:00
|
|
|
#include "../testBasic.h"
|
2012-04-08 14:16:29 +08:00
|
|
|
|
|
|
|
// Test #1 by Jason Booth (slipster216)
|
|
|
|
// Test #3 by David Deaco (ddeaco)
|
|
|
|
|
2011-02-25 11:31:49 +08:00
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
static std::function<Layer*()> createFunctions[] = {
|
2013-06-08 08:21:11 +08:00
|
|
|
CL(RenderTextureSave),
|
|
|
|
CL(RenderTextureIssue937),
|
|
|
|
CL(RenderTextureZbuffer),
|
|
|
|
CL(RenderTextureTestDepthStencil),
|
|
|
|
CL(RenderTextureTargetNode),
|
|
|
|
CL(SpriteRenderTextureBug),
|
2013-02-28 16:35:42 +08:00
|
|
|
};
|
2011-02-25 11:31:49 +08:00
|
|
|
|
2013-03-01 18:37:37 +08:00
|
|
|
#define MAX_LAYER (sizeof(createFunctions)/sizeof(createFunctions[0]))
|
2013-02-28 16:35:42 +08:00
|
|
|
static int sceneIdx = -1;
|
2011-02-25 11:31:49 +08:00
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
static Layer* nextTestCase()
|
2011-02-25 11:31:49 +08:00
|
|
|
{
|
|
|
|
sceneIdx++;
|
|
|
|
sceneIdx = sceneIdx % MAX_LAYER;
|
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto layer = (createFunctions[sceneIdx])();
|
2013-07-23 08:25:44 +08:00
|
|
|
return layer;
|
2011-02-25 11:31:49 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
static Layer* backTestCase()
|
2010-09-10 10:29:39 +08:00
|
|
|
{
|
2011-02-25 11:31:49 +08:00
|
|
|
sceneIdx--;
|
|
|
|
int total = MAX_LAYER;
|
|
|
|
if( sceneIdx < 0 )
|
|
|
|
sceneIdx += total;
|
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto layer = (createFunctions[sceneIdx])();
|
2013-07-23 08:25:44 +08:00
|
|
|
return layer;
|
2011-02-25 11:31:49 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
static Layer* restartTestCase()
|
2011-02-25 11:31:49 +08:00
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto layer = (createFunctions[sceneIdx])();
|
2013-07-23 08:25:44 +08:00
|
|
|
return layer;
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2012-06-14 18:37:57 +08:00
|
|
|
void RenderTextureTest::onEnter()
|
2011-02-25 11:31:49 +08:00
|
|
|
{
|
2013-06-08 08:21:11 +08:00
|
|
|
BaseTest::onEnter();
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-07-26 06:53:24 +08:00
|
|
|
void RenderTextureTest::restartCallback(Object* sender)
|
2011-02-25 11:31:49 +08:00
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto s = new RenderTextureScene();
|
2011-02-25 11:31:49 +08:00
|
|
|
s->addChild(restartTestCase());
|
|
|
|
|
2013-07-12 06:24:23 +08:00
|
|
|
Director::getInstance()->replaceScene(s);
|
2011-02-25 11:31:49 +08:00
|
|
|
s->release();
|
2010-09-10 10:29:39 +08:00
|
|
|
}
|
|
|
|
|
2013-07-26 06:53:24 +08:00
|
|
|
void RenderTextureTest::nextCallback(Object* sender)
|
2011-02-25 11:31:49 +08:00
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto s = new RenderTextureScene();
|
2011-02-25 11:31:49 +08:00
|
|
|
s->addChild( nextTestCase() );
|
2013-07-12 06:24:23 +08:00
|
|
|
Director::getInstance()->replaceScene(s);
|
2011-02-25 11:31:49 +08:00
|
|
|
s->release();
|
|
|
|
}
|
|
|
|
|
2013-07-26 06:53:24 +08:00
|
|
|
void RenderTextureTest::backCallback(Object* sender)
|
2011-02-25 11:31:49 +08:00
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto s = new RenderTextureScene();
|
2011-02-25 11:31:49 +08:00
|
|
|
s->addChild( backTestCase() );
|
2013-07-12 06:24:23 +08:00
|
|
|
Director::getInstance()->replaceScene(s);
|
2011-02-25 11:31:49 +08:00
|
|
|
s->release();
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureTest::title() const
|
2010-09-10 10:29:39 +08:00
|
|
|
{
|
2012-06-14 18:37:57 +08:00
|
|
|
return "No title";
|
2010-09-10 10:29:39 +08:00
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureTest::subtitle() const
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Impelmentation of RenderTextureSave
|
|
|
|
*/
|
|
|
|
RenderTextureSave::RenderTextureSave()
|
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto s = Director::getInstance()->getWinSize();
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// create a render texture, this is what we are going to draw into
|
2013-12-23 17:13:41 +08:00
|
|
|
_target = RenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA8888);
|
2013-06-15 14:03:30 +08:00
|
|
|
_target->retain();
|
2013-07-12 14:11:55 +08:00
|
|
|
_target->setPosition(Point(s.width / 2, s.height / 2));
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
// note that the render texture is a Node, and contains a sprite of its texture for convience,
|
|
|
|
// so we can just parent it to the scene like any other Node
|
2013-06-15 14:03:30 +08:00
|
|
|
this->addChild(_target, -1);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// create a brush image to draw into the texture with
|
2013-06-20 14:17:10 +08:00
|
|
|
_brush = Sprite::create("Images/fire.png");
|
2013-06-15 14:03:30 +08:00
|
|
|
_brush->retain();
|
2013-07-08 18:11:32 +08:00
|
|
|
_brush->setColor(Color3B::RED);
|
2013-06-15 14:03:30 +08:00
|
|
|
_brush->setOpacity(20);
|
2013-10-23 16:14:03 +08:00
|
|
|
|
|
|
|
auto listener = EventListenerTouchAllAtOnce::create();
|
|
|
|
listener->onTouchesMoved = CC_CALLBACK_2(RenderTextureSave::onTouchesMoved, this);
|
2013-10-26 15:04:01 +08:00
|
|
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
2013-10-23 16:14:03 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
// Save Image menu
|
2013-06-20 14:17:10 +08:00
|
|
|
MenuItemFont::setFontSize(16);
|
2013-08-16 16:05:27 +08:00
|
|
|
auto item1 = MenuItemFont::create("Save Image", CC_CALLBACK_1(RenderTextureSave::saveImage, this));
|
|
|
|
auto item2 = MenuItemFont::create("Clear", CC_CALLBACK_1(RenderTextureSave::clearImage, this));
|
|
|
|
auto menu = Menu::create(item1, item2, NULL);
|
2012-04-19 14:35:52 +08:00
|
|
|
this->addChild(menu);
|
|
|
|
menu->alignItemsVertically();
|
2013-07-12 14:11:55 +08:00
|
|
|
menu->setPosition(Point(VisibleRect::rightTop().x - 80, VisibleRect::rightTop().y - 30));
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureSave::title() const
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
return "Touch the screen";
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureSave::subtitle() const
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
return "Press 'Save Image' to create an snapshot of the render texture";
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-09-07 09:46:33 +08:00
|
|
|
void RenderTextureSave::clearImage(cocos2d::Object *sender)
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_target->clear(CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1());
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-09-07 09:46:33 +08:00
|
|
|
void RenderTextureSave::saveImage(cocos2d::Object *sender)
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
static int counter = 0;
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
char png[20];
|
|
|
|
sprintf(png, "image-%d.png", counter);
|
|
|
|
char jpg[20];
|
|
|
|
sprintf(jpg, "image-%d.jpg", counter);
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-07-26 05:49:43 +08:00
|
|
|
_target->saveToFile(png, Image::Format::PNG);
|
|
|
|
_target->saveToFile(jpg, Image::Format::JPG);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-09-07 09:46:33 +08:00
|
|
|
auto image = _target->newImage();
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-11-07 21:48:39 +08:00
|
|
|
auto tex = Director::getInstance()->getTextureCache()->addImage(image, png);
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-09-07 09:46:33 +08:00
|
|
|
CC_SAFE_DELETE(image);
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto sprite = Sprite::createWithTexture(tex);
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
sprite->setScale(0.3f);
|
|
|
|
addChild(sprite);
|
2013-07-12 14:11:55 +08:00
|
|
|
sprite->setPosition(Point(40, 40));
|
2012-04-19 14:35:52 +08:00
|
|
|
sprite->setRotation(counter * 3);
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
CCLOG("Image saved %s and %s", png, jpg);
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
counter++;
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
RenderTextureSave::~RenderTextureSave()
|
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_brush->release();
|
|
|
|
_target->release();
|
2013-11-07 21:48:39 +08:00
|
|
|
Director::getInstance()->getTextureCache()->removeUnusedTextures();
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-09-03 18:22:03 +08:00
|
|
|
void RenderTextureSave::onTouchesMoved(const std::vector<Touch*>& touches, Event* event)
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
2013-09-03 18:22:03 +08:00
|
|
|
auto touch = touches[0];
|
2013-08-16 16:05:27 +08:00
|
|
|
auto start = touch->getLocation();
|
|
|
|
auto end = touch->getPreviousLocation();
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// begin drawing to the render texture
|
2013-06-15 14:03:30 +08:00
|
|
|
_target->begin();
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// for extra points, we'll draw this smoothly from the last position and vary the sprite's
|
|
|
|
// scale/rotation/offset
|
2013-07-11 16:38:58 +08:00
|
|
|
float distance = start.getDistance(end);
|
2012-04-19 14:35:52 +08:00
|
|
|
if (distance > 1)
|
|
|
|
{
|
|
|
|
int d = (int)distance;
|
|
|
|
for (int i = 0; i < d; i++)
|
|
|
|
{
|
|
|
|
float difx = end.x - start.x;
|
|
|
|
float dify = end.y - start.y;
|
|
|
|
float delta = (float)i / distance;
|
2013-07-12 14:11:55 +08:00
|
|
|
_brush->setPosition(Point(start.x + (difx * delta), start.y + (dify * delta)));
|
2013-06-15 14:03:30 +08:00
|
|
|
_brush->setRotation(rand() % 360);
|
2012-04-19 14:35:52 +08:00
|
|
|
float r = (float)(rand() % 50 / 50.f) + 0.25f;
|
2013-06-15 14:03:30 +08:00
|
|
|
_brush->setScale(r);
|
2013-07-05 16:49:22 +08:00
|
|
|
/*_brush->setColor(Color3B(CCRANDOM_0_1() * 127 + 128, 255, 255));*/
|
2012-04-19 14:35:52 +08:00
|
|
|
// Use CCRANDOM_0_1() will cause error when loading libtests.so on android, I don't know why.
|
2013-07-05 16:49:22 +08:00
|
|
|
_brush->setColor(Color3B(rand() % 127 + 128, 255, 255));
|
2012-04-19 14:35:52 +08:00
|
|
|
// Call visit to draw the brush, don't call draw..
|
2013-06-15 14:03:30 +08:00
|
|
|
_brush->visit();
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// finish drawing and return context back to the screen
|
2013-06-15 14:03:30 +08:00
|
|
|
_target->end();
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Impelmentation of RenderTextureIssue937
|
|
|
|
*/
|
|
|
|
|
|
|
|
RenderTextureIssue937::RenderTextureIssue937()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 1 2
|
|
|
|
* A: A1 A2
|
|
|
|
*
|
|
|
|
* B: B1 B2
|
|
|
|
*
|
|
|
|
* A1: premulti sprite
|
|
|
|
* A2: premulti render
|
|
|
|
*
|
|
|
|
* B1: non-premulti sprite
|
|
|
|
* B2: non-premulti render
|
|
|
|
*/
|
2013-08-16 16:05:27 +08:00
|
|
|
auto background = LayerColor::create(Color4B(200,200,200,255));
|
2012-04-08 14:16:29 +08:00
|
|
|
addChild(background);
|
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto spr_premulti = Sprite::create("Images/fire.png");
|
2013-07-12 14:11:55 +08:00
|
|
|
spr_premulti->setPosition(Point(16,48));
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto spr_nonpremulti = Sprite::create("Images/fire.png");
|
2013-07-12 14:11:55 +08:00
|
|
|
spr_nonpremulti->setPosition(Point(16,16));
|
2012-04-08 14:16:29 +08:00
|
|
|
|
|
|
|
|
2012-04-19 17:01:24 +08:00
|
|
|
|
|
|
|
|
2012-04-08 14:16:29 +08:00
|
|
|
/* A2 & B2 setup */
|
2013-12-23 17:13:41 +08:00
|
|
|
auto rend = RenderTexture::create(32, 64, Texture2D::PixelFormat::RGBA8888);
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
if (NULL == rend)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2012-04-08 14:16:29 +08:00
|
|
|
|
|
|
|
// It's possible to modify the RenderTexture blending function by
|
2013-07-05 16:49:22 +08:00
|
|
|
// [[rend sprite] setBlendFunc:(BlendFunc) {GL_ONE, GL_ONE_MINUS_SRC_ALPHA}];
|
2012-04-08 14:16:29 +08:00
|
|
|
|
|
|
|
rend->begin();
|
|
|
|
spr_premulti->visit();
|
|
|
|
spr_nonpremulti->visit();
|
|
|
|
rend->end();
|
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto s = Director::getInstance()->getWinSize();
|
2012-04-08 14:16:29 +08:00
|
|
|
|
|
|
|
/* A1: setup */
|
2013-07-12 14:11:55 +08:00
|
|
|
spr_premulti->setPosition(Point(s.width/2-16, s.height/2+16));
|
2012-04-08 14:16:29 +08:00
|
|
|
/* B1: setup */
|
2013-07-12 14:11:55 +08:00
|
|
|
spr_nonpremulti->setPosition(Point(s.width/2-16, s.height/2-16));
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-07-12 14:11:55 +08:00
|
|
|
rend->setPosition(Point(s.width/2+16, s.height/2));
|
2012-04-08 14:16:29 +08:00
|
|
|
|
|
|
|
addChild(spr_nonpremulti);
|
|
|
|
addChild(spr_premulti);
|
|
|
|
addChild(rend);
|
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureIssue937::title() const
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
|
|
|
return "Testing issue #937";
|
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureIssue937::subtitle() const
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
|
|
|
return "All images should be equal...";
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderTextureScene::runThisTest()
|
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto layer = nextTestCase();
|
2013-07-23 08:25:44 +08:00
|
|
|
addChild(layer);
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-07-12 06:24:23 +08:00
|
|
|
Director::getInstance()->replaceScene(this);
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Impelmentation of RenderTextureZbuffer
|
|
|
|
*/
|
|
|
|
|
|
|
|
RenderTextureZbuffer::RenderTextureZbuffer()
|
|
|
|
{
|
2013-10-23 16:14:03 +08:00
|
|
|
auto listener = EventListenerTouchAllAtOnce::create();
|
|
|
|
listener->onTouchesBegan = CC_CALLBACK_2(RenderTextureZbuffer::onTouchesBegan, this);
|
|
|
|
listener->onTouchesMoved = CC_CALLBACK_2(RenderTextureZbuffer::onTouchesMoved, this);
|
|
|
|
listener->onTouchesEnded = CC_CALLBACK_2(RenderTextureZbuffer::onTouchesEnded, this);
|
2013-10-26 15:04:01 +08:00
|
|
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
2013-10-23 16:14:03 +08:00
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto size = Director::getInstance()->getWinSize();
|
|
|
|
auto label = LabelTTF::create("vertexZ = 50", "Marker Felt", 64);
|
2013-07-12 14:11:55 +08:00
|
|
|
label->setPosition(Point(size.width / 2, size.height * 0.25f));
|
2012-04-19 14:35:52 +08:00
|
|
|
this->addChild(label);
|
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto label2 = LabelTTF::create("vertexZ = 0", "Marker Felt", 64);
|
2013-07-12 14:11:55 +08:00
|
|
|
label2->setPosition(Point(size.width / 2, size.height * 0.5f));
|
2012-04-19 14:35:52 +08:00
|
|
|
this->addChild(label2);
|
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto label3 = LabelTTF::create("vertexZ = -50", "Marker Felt", 64);
|
2013-07-12 14:11:55 +08:00
|
|
|
label3->setPosition(Point(size.width / 2, size.height * 0.75f));
|
2012-04-19 14:35:52 +08:00
|
|
|
this->addChild(label3);
|
|
|
|
|
|
|
|
label->setVertexZ(50);
|
|
|
|
label2->setVertexZ(0);
|
|
|
|
label3->setVertexZ(-50);
|
|
|
|
|
2013-07-12 06:24:23 +08:00
|
|
|
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("Images/bugs/circle.plist");
|
2013-06-20 14:17:10 +08:00
|
|
|
mgr = SpriteBatchNode::create("Images/bugs/circle.png", 9);
|
2012-04-19 14:35:52 +08:00
|
|
|
this->addChild(mgr);
|
2013-06-20 14:17:10 +08:00
|
|
|
sp1 = Sprite::createWithSpriteFrameName("circle.png");
|
|
|
|
sp2 = Sprite::createWithSpriteFrameName("circle.png");
|
|
|
|
sp3 = Sprite::createWithSpriteFrameName("circle.png");
|
|
|
|
sp4 = Sprite::createWithSpriteFrameName("circle.png");
|
|
|
|
sp5 = Sprite::createWithSpriteFrameName("circle.png");
|
|
|
|
sp6 = Sprite::createWithSpriteFrameName("circle.png");
|
|
|
|
sp7 = Sprite::createWithSpriteFrameName("circle.png");
|
|
|
|
sp8 = Sprite::createWithSpriteFrameName("circle.png");
|
|
|
|
sp9 = Sprite::createWithSpriteFrameName("circle.png");
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
mgr->addChild(sp1, 9);
|
|
|
|
mgr->addChild(sp2, 8);
|
|
|
|
mgr->addChild(sp3, 7);
|
|
|
|
mgr->addChild(sp4, 6);
|
|
|
|
mgr->addChild(sp5, 5);
|
|
|
|
mgr->addChild(sp6, 4);
|
|
|
|
mgr->addChild(sp7, 3);
|
|
|
|
mgr->addChild(sp8, 2);
|
|
|
|
mgr->addChild(sp9, 1);
|
|
|
|
|
|
|
|
sp1->setVertexZ(400);
|
|
|
|
sp2->setVertexZ(300);
|
|
|
|
sp3->setVertexZ(200);
|
|
|
|
sp4->setVertexZ(100);
|
|
|
|
sp5->setVertexZ(0);
|
|
|
|
sp6->setVertexZ(-100);
|
|
|
|
sp7->setVertexZ(-200);
|
|
|
|
sp8->setVertexZ(-300);
|
|
|
|
sp9->setVertexZ(-400);
|
|
|
|
|
|
|
|
sp9->setScale(2);
|
2013-07-08 18:11:32 +08:00
|
|
|
sp9->setColor(Color3B::YELLOW);
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureZbuffer::title() const
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
return "Testing Z Buffer in Render Texture";
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureZbuffer::subtitle() const
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
return "Touch screen. It should be green";
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-09-03 18:22:03 +08:00
|
|
|
void RenderTextureZbuffer::onTouchesBegan(const std::vector<Touch*>& touches, Event *event)
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
2013-06-22 11:02:43 +08:00
|
|
|
|
2013-09-03 18:22:03 +08:00
|
|
|
for (auto &item: touches)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto touch = static_cast<Touch*>(item);
|
|
|
|
auto location = touch->getLocation();
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
sp1->setPosition(location);
|
|
|
|
sp2->setPosition(location);
|
|
|
|
sp3->setPosition(location);
|
|
|
|
sp4->setPosition(location);
|
|
|
|
sp5->setPosition(location);
|
|
|
|
sp6->setPosition(location);
|
|
|
|
sp7->setPosition(location);
|
|
|
|
sp8->setPosition(location);
|
|
|
|
sp9->setPosition(location);
|
|
|
|
}
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-09-03 18:22:03 +08:00
|
|
|
void RenderTextureZbuffer::onTouchesMoved(const std::vector<Touch*>& touches, Event* event)
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
2013-09-03 18:22:03 +08:00
|
|
|
for (auto &item: touches)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto touch = static_cast<Touch*>(item);
|
|
|
|
auto location = touch->getLocation();
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
sp1->setPosition(location);
|
|
|
|
sp2->setPosition(location);
|
|
|
|
sp3->setPosition(location);
|
|
|
|
sp4->setPosition(location);
|
|
|
|
sp5->setPosition(location);
|
|
|
|
sp6->setPosition(location);
|
|
|
|
sp7->setPosition(location);
|
|
|
|
sp8->setPosition(location);
|
|
|
|
sp9->setPosition(location);
|
|
|
|
}
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2013-09-03 18:22:03 +08:00
|
|
|
void RenderTextureZbuffer::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
|
2012-04-08 14:16:29 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
this->renderScreenShot();
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderTextureZbuffer::renderScreenShot()
|
|
|
|
{
|
2013-12-23 17:13:41 +08:00
|
|
|
auto texture = RenderTexture::create(512, 512);
|
2012-04-19 14:35:52 +08:00
|
|
|
if (NULL == texture)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2013-07-12 14:11:55 +08:00
|
|
|
texture->setAnchorPoint(Point(0, 0));
|
2012-04-19 14:35:52 +08:00
|
|
|
texture->begin();
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
this->visit();
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
texture->end();
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto sprite = Sprite::createWithTexture(texture->getSprite()->getTexture());
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-07-12 14:11:55 +08:00
|
|
|
sprite->setPosition(Point(256, 256));
|
2012-04-19 14:35:52 +08:00
|
|
|
sprite->setOpacity(182);
|
2013-09-16 20:38:03 +08:00
|
|
|
sprite->setFlippedY(1);
|
2012-04-19 14:35:52 +08:00
|
|
|
this->addChild(sprite, 999999);
|
2013-07-08 18:11:32 +08:00
|
|
|
sprite->setColor(Color3B::GREEN);
|
2012-04-08 14:16:29 +08:00
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
sprite->runAction(Sequence::create(FadeTo::create(2, 0),
|
|
|
|
Hide::create(),
|
2012-04-19 14:35:52 +08:00
|
|
|
NULL));
|
2012-04-08 14:16:29 +08:00
|
|
|
}
|
|
|
|
|
2012-06-14 18:37:57 +08:00
|
|
|
// RenderTextureTestDepthStencil
|
|
|
|
|
|
|
|
RenderTextureTestDepthStencil::RenderTextureTestDepthStencil()
|
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto s = Director::getInstance()->getWinSize();
|
2012-06-14 18:37:57 +08:00
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto sprite = Sprite::create("Images/fire.png");
|
2013-07-12 14:11:55 +08:00
|
|
|
sprite->setPosition(Point(s.width * 0.25f, 0));
|
2012-06-14 18:37:57 +08:00
|
|
|
sprite->setScale(10);
|
2013-12-23 17:13:41 +08:00
|
|
|
auto rend = RenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA4444, GL_DEPTH24_STENCIL8);
|
2012-06-14 18:37:57 +08:00
|
|
|
|
|
|
|
glStencilMask(0xFF);
|
|
|
|
rend->beginWithClear(0, 0, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
//! mark sprite quad into stencil buffer
|
|
|
|
glEnable(GL_STENCIL_TEST);
|
2013-07-29 14:13:36 +08:00
|
|
|
glStencilFunc(GL_NEVER, 1, 0xFF);
|
|
|
|
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
2012-06-14 18:37:57 +08:00
|
|
|
sprite->visit();
|
|
|
|
|
|
|
|
//! move sprite half width and height, and draw only where not marked
|
2013-07-29 14:11:21 +08:00
|
|
|
sprite->setPosition(sprite->getPosition() + Point(sprite->getContentSize().width * sprite->getScale() * 0.5, sprite->getContentSize().height * sprite->getScale() * 0.5));
|
2012-06-14 18:37:57 +08:00
|
|
|
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
|
|
|
|
sprite->visit();
|
|
|
|
|
|
|
|
rend->end();
|
|
|
|
|
|
|
|
glDisable(GL_STENCIL_TEST);
|
|
|
|
|
2013-07-12 14:11:55 +08:00
|
|
|
rend->setPosition(Point(s.width * 0.5f, s.height * 0.5f));
|
2012-06-14 18:37:57 +08:00
|
|
|
|
|
|
|
this->addChild(rend);
|
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureTestDepthStencil::title() const
|
2012-06-12 15:55:23 +08:00
|
|
|
{
|
|
|
|
return "Testing depthStencil attachment";
|
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureTestDepthStencil::subtitle() const
|
2012-06-14 18:37:57 +08:00
|
|
|
{
|
|
|
|
return "Circle should be missing 1/4 of its region";
|
|
|
|
}
|
2012-06-12 15:55:23 +08:00
|
|
|
|
2012-11-20 16:45:59 +08:00
|
|
|
// RenderTextureTest
|
|
|
|
RenderTextureTargetNode::RenderTextureTargetNode()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 1 2
|
|
|
|
* A: A1 A2
|
|
|
|
*
|
|
|
|
* B: B1 B2
|
|
|
|
*
|
|
|
|
* A1: premulti sprite
|
|
|
|
* A2: premulti render
|
|
|
|
*
|
|
|
|
* B1: non-premulti sprite
|
|
|
|
* B2: non-premulti render
|
|
|
|
*/
|
2013-08-16 16:05:27 +08:00
|
|
|
auto background = LayerColor::create(Color4B(40,40,40,255));
|
2012-11-20 16:45:59 +08:00
|
|
|
addChild(background);
|
|
|
|
|
|
|
|
// sprite 1
|
2013-06-20 14:17:10 +08:00
|
|
|
sprite1 = Sprite::create("Images/fire.png");
|
2012-11-20 16:45:59 +08:00
|
|
|
|
|
|
|
// sprite 2
|
2013-06-20 14:17:10 +08:00
|
|
|
sprite2 = Sprite::create("Images/fire_rgba8888.pvr");
|
2012-11-20 16:45:59 +08:00
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto s = Director::getInstance()->getWinSize();
|
2012-11-20 16:45:59 +08:00
|
|
|
|
|
|
|
/* Create the render texture */
|
2013-12-23 17:13:41 +08:00
|
|
|
auto renderTexture = RenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA4444);
|
2012-11-20 16:45:59 +08:00
|
|
|
this->renderTexture = renderTexture;
|
|
|
|
|
2013-07-12 14:11:55 +08:00
|
|
|
renderTexture->setPosition(Point(s.width/2, s.height/2));
|
2013-07-12 18:04:32 +08:00
|
|
|
// [renderTexture setPosition:Point(s.width, s.height)];
|
2012-11-20 16:45:59 +08:00
|
|
|
// renderTexture.scale = 2;
|
|
|
|
|
|
|
|
/* add the sprites to the render texture */
|
|
|
|
renderTexture->addChild(sprite1);
|
|
|
|
renderTexture->addChild(sprite2);
|
2013-07-05 16:49:22 +08:00
|
|
|
renderTexture->setClearColor(Color4F(0, 0, 0, 0));
|
2012-11-20 16:45:59 +08:00
|
|
|
renderTexture->setClearFlags(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
|
|
|
/* add the render texture to the scene */
|
|
|
|
addChild(renderTexture);
|
|
|
|
|
|
|
|
renderTexture->setAutoDraw(true);
|
|
|
|
|
|
|
|
scheduleUpdate();
|
|
|
|
|
|
|
|
// Toggle clear on / off
|
2013-08-16 16:05:27 +08:00
|
|
|
auto item = MenuItemFont::create("Clear On/Off", CC_CALLBACK_1(RenderTextureTargetNode::touched, this));
|
|
|
|
auto menu = Menu::create(item, NULL);
|
2012-11-20 16:45:59 +08:00
|
|
|
addChild(menu);
|
|
|
|
|
2013-07-12 14:11:55 +08:00
|
|
|
menu->setPosition(Point(s.width/2, s.height/2));
|
2012-11-20 16:45:59 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
void RenderTextureTargetNode::touched(Object* sender)
|
2012-11-20 16:45:59 +08:00
|
|
|
{
|
|
|
|
if (renderTexture->getClearFlags() == 0)
|
|
|
|
{
|
|
|
|
renderTexture->setClearFlags(GL_COLOR_BUFFER_BIT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
renderTexture->setClearFlags(0);
|
2013-07-05 16:49:22 +08:00
|
|
|
renderTexture->setClearColor(Color4F( CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), 1));
|
2012-11-20 16:45:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderTextureTargetNode::update(float dt)
|
|
|
|
{
|
|
|
|
static float time = 0;
|
|
|
|
float r = 80;
|
2013-07-12 14:11:55 +08:00
|
|
|
sprite1->setPosition(Point(cosf(time * 2) * r, sinf(time * 2) * r));
|
|
|
|
sprite2->setPosition(Point(sinf(time * 2) * r, cosf(time * 2) * r));
|
2012-11-20 16:45:59 +08:00
|
|
|
|
|
|
|
time += dt;
|
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureTargetNode::title() const
|
2012-11-20 16:45:59 +08:00
|
|
|
{
|
|
|
|
return "Testing Render Target Node";
|
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string RenderTextureTargetNode::subtitle() const
|
2012-11-20 16:45:59 +08:00
|
|
|
{
|
|
|
|
return "Sprites should be equal and move with each frame";
|
|
|
|
}
|
|
|
|
|
2013-02-28 16:35:42 +08:00
|
|
|
// SpriteRenderTextureBug
|
|
|
|
|
2013-11-15 08:33:43 +08:00
|
|
|
SpriteRenderTextureBug::SimpleSprite::SimpleSprite() : _rt(nullptr) {}
|
2013-02-28 16:35:42 +08:00
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
SpriteRenderTextureBug::SimpleSprite* SpriteRenderTextureBug::SimpleSprite::create(const char* filename, const Rect &rect)
|
2013-02-28 16:35:42 +08:00
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto sprite = new SimpleSprite();
|
2013-02-28 16:35:42 +08:00
|
|
|
if (sprite && sprite->initWithFile(filename, rect))
|
|
|
|
{
|
|
|
|
sprite->autorelease();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CC_SAFE_DELETE(sprite);
|
|
|
|
}
|
|
|
|
|
|
|
|
return sprite;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SpriteRenderTextureBug::SimpleSprite::draw()
|
|
|
|
{
|
2013-11-15 08:33:43 +08:00
|
|
|
if (_rt == nullptr)
|
2013-02-28 16:35:42 +08:00
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto s = Director::getInstance()->getWinSize();
|
2013-12-23 17:13:41 +08:00
|
|
|
_rt = RenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA8888);
|
2013-11-15 08:33:43 +08:00
|
|
|
_rt->retain();
|
2013-02-28 16:35:42 +08:00
|
|
|
}
|
2013-11-15 08:33:43 +08:00
|
|
|
_rt->beginWithClear(0.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
_rt->end();
|
2013-02-28 16:35:42 +08:00
|
|
|
|
|
|
|
CC_NODE_DRAW_SETUP();
|
|
|
|
|
2013-07-05 16:49:22 +08:00
|
|
|
BlendFunc blend = getBlendFunc();
|
2013-07-26 09:42:53 +08:00
|
|
|
GL::blendFunc(blend.src, blend.dst);
|
2013-02-28 16:35:42 +08:00
|
|
|
|
2013-07-26 09:42:53 +08:00
|
|
|
GL::bindTexture2D(getTexture()->getName());
|
2013-02-28 16:35:42 +08:00
|
|
|
|
|
|
|
//
|
|
|
|
// Attributes
|
|
|
|
//
|
|
|
|
|
2013-07-26 09:42:53 +08:00
|
|
|
GL::enableVertexAttribs(cocos2d::GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
|
2013-02-28 16:35:42 +08:00
|
|
|
|
2013-06-15 14:03:30 +08:00
|
|
|
#define kQuadSize sizeof(_quad.bl)
|
|
|
|
long offset = (long)&_quad;
|
2013-02-28 16:35:42 +08:00
|
|
|
|
|
|
|
// vertex
|
2013-07-05 16:49:22 +08:00
|
|
|
int diff = offsetof( V3F_C4B_T2F, vertices);
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));
|
2013-02-28 16:35:42 +08:00
|
|
|
|
|
|
|
// texCoods
|
2013-07-05 16:49:22 +08:00
|
|
|
diff = offsetof( V3F_C4B_T2F, texCoords);
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));
|
2013-02-28 16:35:42 +08:00
|
|
|
|
|
|
|
// color
|
2013-07-05 16:49:22 +08:00
|
|
|
diff = offsetof( V3F_C4B_T2F, colors);
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));
|
2013-02-28 16:35:42 +08:00
|
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
SpriteRenderTextureBug::SpriteRenderTextureBug()
|
|
|
|
{
|
2013-10-23 16:14:03 +08:00
|
|
|
auto listener = EventListenerTouchAllAtOnce::create();
|
|
|
|
listener->onTouchesEnded = CC_CALLBACK_2(SpriteRenderTextureBug::onTouchesEnded, this);
|
2013-10-26 15:04:01 +08:00
|
|
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
2013-02-28 16:35:42 +08:00
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto s = Director::getInstance()->getWinSize();
|
2013-07-12 14:11:55 +08:00
|
|
|
addNewSpriteWithCoords(Point(s.width/2, s.height/2));
|
2013-02-28 16:35:42 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
SpriteRenderTextureBug::SimpleSprite* SpriteRenderTextureBug::addNewSpriteWithCoords(const Point& p)
|
2013-02-28 16:35:42 +08:00
|
|
|
{
|
|
|
|
int idx = CCRANDOM_0_1() * 1400 / 100;
|
|
|
|
int x = (idx%5) * 85;
|
|
|
|
int y = (idx/5) * 121;
|
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto sprite = SpriteRenderTextureBug::SimpleSprite::create("Images/grossini_dance_atlas.png",
|
2013-07-12 14:30:26 +08:00
|
|
|
Rect(x,y,85,121));
|
2013-02-28 16:35:42 +08:00
|
|
|
addChild(sprite);
|
|
|
|
|
|
|
|
sprite->setPosition(p);
|
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
FiniteTimeAction *action = NULL;
|
2013-02-28 16:35:42 +08:00
|
|
|
float rd = CCRANDOM_0_1();
|
|
|
|
|
|
|
|
if (rd < 0.20)
|
2013-06-20 14:17:10 +08:00
|
|
|
action = ScaleBy::create(3, 2);
|
2013-02-28 16:35:42 +08:00
|
|
|
else if (rd < 0.40)
|
2013-06-20 14:17:10 +08:00
|
|
|
action = RotateBy::create(3, 360);
|
2013-02-28 16:35:42 +08:00
|
|
|
else if (rd < 0.60)
|
2013-06-20 14:17:10 +08:00
|
|
|
action = Blink::create(1, 3);
|
2013-02-28 16:35:42 +08:00
|
|
|
else if (rd < 0.8 )
|
2013-06-20 14:17:10 +08:00
|
|
|
action = TintBy::create(2, 0, -255, -255);
|
2013-02-28 16:35:42 +08:00
|
|
|
else
|
2013-06-20 14:17:10 +08:00
|
|
|
action = FadeOut::create(2);
|
2013-02-28 16:35:42 +08:00
|
|
|
|
2013-08-16 16:05:27 +08:00
|
|
|
auto action_back = action->reverse();
|
|
|
|
auto seq = Sequence::create(action, action_back, NULL);
|
2013-02-28 16:35:42 +08:00
|
|
|
|
2013-06-20 14:17:10 +08:00
|
|
|
sprite->runAction(RepeatForever::create(seq));
|
2013-02-28 16:35:42 +08:00
|
|
|
|
|
|
|
//return sprite;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-09-03 18:22:03 +08:00
|
|
|
void SpriteRenderTextureBug::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
|
2013-02-28 16:35:42 +08:00
|
|
|
{
|
2013-09-03 18:22:03 +08:00
|
|
|
for (auto &touch: touches)
|
2013-02-28 16:35:42 +08:00
|
|
|
{
|
2013-08-16 16:05:27 +08:00
|
|
|
auto location = touch->getLocation();
|
2013-02-28 16:35:42 +08:00
|
|
|
addNewSpriteWithCoords(location);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string SpriteRenderTextureBug::title() const
|
2013-02-28 16:35:42 +08:00
|
|
|
{
|
|
|
|
return "SpriteRenderTextureBug";
|
|
|
|
}
|
|
|
|
|
2013-12-19 05:52:10 +08:00
|
|
|
std::string SpriteRenderTextureBug::subtitle() const
|
2013-02-28 16:35:42 +08:00
|
|
|
{
|
|
|
|
return "Touch the screen. Sprite should appear on under the touch";
|
|
|
|
}
|