axmol/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp

635 lines
16 KiB
C++
Raw Normal View History

2013-09-09 17:49:13 +08:00
#include "ShaderTest2.h"
#include "ShaderTest.h"
#include "../testResource.h"
#include "cocos2d.h"
#include "renderer/CCRenderCommand.h"
#include "renderer/CCCustomCommand.h"
2013-09-09 17:49:13 +08:00
namespace ShaderTest2
{
static std::function<Layer*()> createFunctions[] =
{
CL(NormalSpriteTest),
CL(GreyScaleSpriteTest),
CL(BlurSpriteTest),
CL(NoiseSpriteTest),
CL(EdgeDetectionSpriteTest),
CL(BloomSpriteTest),
CL(CelShadingSpriteTest),
CL(LensFlareSpriteTest)
2013-09-09 17:49:13 +08:00
};
static unsigned int TEST_CASE_COUNT = sizeof(ShaderTest2::createFunctions) / sizeof(ShaderTest2::createFunctions[0]);
static int sceneIdx=-1;
Layer* createTest(int index)
{
auto layer = (createFunctions[index])();;
return layer;
}
Layer* nextAction();
Layer* backAction();
Layer* restartAction();
Layer* nextAction()
{
sceneIdx++;
sceneIdx = sceneIdx % TEST_CASE_COUNT;
return createTest(sceneIdx);
}
Layer* backAction()
{
sceneIdx--;
if( sceneIdx < 0 )
sceneIdx = TEST_CASE_COUNT -1;
return createTest(sceneIdx);
}
Layer* restartAction()
{
return createTest(sceneIdx);
}
}
ShaderTestDemo2::ShaderTestDemo2()
{
}
void ShaderTestDemo2::backCallback(Ref* sender)
2013-09-09 17:49:13 +08:00
{
2013-11-14 09:36:33 +08:00
auto s = ShaderTestScene2::create();
2013-09-09 17:49:13 +08:00
s->addChild( ShaderTest2::backAction() );
Director::getInstance()->replaceScene(s);
}
void ShaderTestDemo2::nextCallback(Ref* sender)
2013-09-09 17:49:13 +08:00
{
2013-11-14 09:36:33 +08:00
auto s = ShaderTestScene2::create();
2013-09-09 17:49:13 +08:00
s->addChild( ShaderTest2::nextAction() );
Director::getInstance()->replaceScene(s);
}
void ShaderTestDemo2::restartCallback(Ref* sender)
2013-09-09 17:49:13 +08:00
{
2013-11-14 09:36:33 +08:00
auto s = ShaderTestScene2::create();
s->addChild(ShaderTest2::restartAction());
2013-09-09 17:49:13 +08:00
Director::getInstance()->replaceScene(s);
}
void ShaderTestScene2::runThisTest()
{
auto layer = ShaderTest2::nextAction();
addChild(layer);
Director::getInstance()->replaceScene(this);
}
template <class spriteType>
class ShaderSpriteCreator
{
public:
2013-11-14 09:36:33 +08:00
static spriteType* createSprite(const std::string& filename)
2013-09-09 17:49:13 +08:00
{
2013-11-14 07:55:36 +08:00
spriteType* ret = spriteType::create();
2013-11-14 09:36:33 +08:00
ret->setTexture(filename);
ret->initShader();
ret->setBackgroundNotification();
2013-11-14 07:55:36 +08:00
return ret;
2013-09-09 17:49:13 +08:00
}
};
class ShaderSprite : public Sprite
{
public:
ShaderSprite();
~ShaderSprite();
2013-11-14 09:36:33 +08:00
virtual void initShader();
void setBackgroundNotification();
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
void listenBackToForeground(Ref *obj);
2013-09-09 17:49:13 +08:00
protected:
virtual void buildCustomUniforms() = 0;
virtual void setCustomUniforms() = 0;
protected:
std::string _fragSourceFile;
protected:
CustomCommand _renderCommand;
void onDraw(const kmMat4 &transform, bool transformUpdated);
2013-09-09 17:49:13 +08:00
};
ShaderSprite::ShaderSprite()
{
}
ShaderSprite::~ShaderSprite()
{
}
2013-11-14 09:36:33 +08:00
void ShaderSprite::setBackgroundNotification()
2013-09-09 17:49:13 +08:00
{
#if CC_ENABLE_CACHE_TEXTURE_DATA
auto listener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, [this](EventCustom* event){
this->setShaderProgram(nullptr);
this->initShader();
});
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
#endif
2013-09-09 17:49:13 +08:00
}
2013-11-14 09:36:33 +08:00
void ShaderSprite::initShader()
2013-09-09 17:49:13 +08:00
{
GLchar * fragSource = (GLchar*) String::createWithContentsOfFile(
2013-11-14 09:36:33 +08:00
FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
auto program = new GLProgram();
2014-03-05 05:51:43 +08:00
program->initWithByteArrays(ccPositionTextureColor_vert, fragSource);
setShaderProgram(program);
program->release();
2013-09-09 17:49:13 +08:00
CHECK_GL_ERROR_DEBUG();
2014-03-05 05:51:43 +08:00
program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
2013-09-09 17:49:13 +08:00
CHECK_GL_ERROR_DEBUG();
program->link();
2013-09-09 17:49:13 +08:00
CHECK_GL_ERROR_DEBUG();
program->updateUniforms();
2013-09-09 17:49:13 +08:00
CHECK_GL_ERROR_DEBUG();
buildCustomUniforms();
CHECK_GL_ERROR_DEBUG();
}
void ShaderSprite::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
2013-09-09 17:49:13 +08:00
{
_renderCommand.init(_globalZOrder);
_renderCommand.func = CC_CALLBACK_0(ShaderSprite::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_renderCommand);
}
void ShaderSprite::onDraw(const kmMat4 &transform, bool transformUpdated)
{
auto shader = getShaderProgram();
shader->use();
shader->setUniformsForBuiltins(transform);
2013-09-09 17:49:13 +08:00
setCustomUniforms();
GL::enableVertexAttribs(cocos2d::GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
2013-09-09 17:49:13 +08:00
GL::bindTexture2D( getTexture()->getName());
//
// Attributes
//
#define kQuadSize sizeof(_quad.bl)
size_t offset = (size_t)&_quad;
2013-09-09 17:49:13 +08:00
// vertex
int diff = offsetof( V3F_C4B_T2F, vertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));
// texCoods
diff = offsetof( V3F_C4B_T2F, texCoords);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));
// color
diff = offsetof( V3F_C4B_T2F, colors);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 4);
2013-09-09 17:49:13 +08:00
}
class NormalSprite : public ShaderSprite, public ShaderSpriteCreator<NormalSprite>
{
public:
2013-11-14 07:55:36 +08:00
CREATE_FUNC(NormalSprite);
2013-09-09 17:49:13 +08:00
NormalSprite();
protected:
virtual void buildCustomUniforms();
virtual void setCustomUniforms();
};
NormalSprite::NormalSprite()
{
_fragSourceFile = "Shaders/example_normal.fsh";
}
void NormalSprite::buildCustomUniforms()
{
}
void NormalSprite::setCustomUniforms()
{
}
class GreyScaleSprite : public ShaderSprite, public ShaderSpriteCreator<GreyScaleSprite>
{
public:
2013-11-14 07:55:36 +08:00
CREATE_FUNC(GreyScaleSprite);
2013-09-09 17:49:13 +08:00
GreyScaleSprite();
protected:
virtual void buildCustomUniforms();
virtual void setCustomUniforms();
};
GreyScaleSprite::GreyScaleSprite()
{
_fragSourceFile = "Shaders/example_greyScale.fsh";
}
void GreyScaleSprite::buildCustomUniforms()
{
}
void GreyScaleSprite::setCustomUniforms()
{
}
class BlurSprite : public ShaderSprite, public ShaderSpriteCreator<BlurSprite>
{
public:
2013-11-14 07:55:36 +08:00
CREATE_FUNC(BlurSprite);
2013-09-09 17:49:13 +08:00
BlurSprite();
void setBlurSize(float f);
protected:
virtual void buildCustomUniforms();
virtual void setCustomUniforms();
protected:
int _blurRadius;
Point _pixelSize;
2013-09-09 17:49:13 +08:00
int _samplingRadius;
float _scale;
float _cons;
float _weightSum;
GLuint pixelSizeLocation;
GLuint coefficientLocation;
2013-09-09 17:49:13 +08:00
};
BlurSprite::BlurSprite()
{
_fragSourceFile = "Shaders/example_Blur.fsh";
}
void BlurSprite::buildCustomUniforms()
{
auto s = getTexture()->getContentSizeInPixels();
_blurRadius = 0;
_pixelSize = Point(1/s.width, 1/s.height);
_samplingRadius = 0;
2014-03-05 05:51:43 +08:00
setBlurSize(3.0f);
2014-03-05 05:51:43 +08:00
auto program = getShaderProgram();
pixelSizeLocation = program->getUniformLocation("onePixelSize");
coefficientLocation = program->getUniformLocation("gaussianCoefficient");
2013-09-09 17:49:13 +08:00
}
void BlurSprite::setCustomUniforms()
{
2014-03-05 05:51:43 +08:00
auto program = getShaderProgram();
program->setUniformLocationWith2f(pixelSizeLocation, _pixelSize.x, _pixelSize.y);
program->setUniformLocationWith4f(coefficientLocation, _samplingRadius, _scale,_cons,_weightSum);
2013-09-09 17:49:13 +08:00
}
void BlurSprite::setBlurSize(float f)
{
if(_blurRadius == (int)f)
return;
_blurRadius = (int)f;
2013-09-09 17:49:13 +08:00
_samplingRadius = _blurRadius;
if (_samplingRadius > 10)
{
_samplingRadius = 10;
}
if (_blurRadius > 0)
{
float sigma = _blurRadius / 2.0f;
_scale = -0.5f / (sigma * sigma);
_cons = -1.0f * _scale / 3.141592f;
_weightSum = -_cons;
float weight;
int squareX;
for(int dx = 0; dx <= _samplingRadius; ++dx)
{
squareX = dx * dx;
weight = _cons * exp(squareX * _scale);
_weightSum += 2.0 * weight;
for (int dy = 1; dy <= _samplingRadius; ++dy)
{
weight = _cons * exp((squareX + dy * dy) * _scale);
_weightSum += 4.0 * weight;
}
}
}
log("_blurRadius:%d",_blurRadius);
2013-09-09 17:49:13 +08:00
}
class NoiseSprite : public ShaderSprite, public ShaderSpriteCreator<NoiseSprite>
{
public:
2013-11-14 07:55:36 +08:00
CREATE_FUNC(NoiseSprite);
2013-09-09 17:49:13 +08:00
NoiseSprite();
private:
GLfloat _resolution[2];
GLuint _resolutionLoc;
protected:
virtual void buildCustomUniforms();
virtual void setCustomUniforms();
};
NoiseSprite::NoiseSprite()
{
_fragSourceFile = "Shaders/example_Noisy.fsh";
}
void NoiseSprite::buildCustomUniforms()
{
2014-03-05 05:51:43 +08:00
auto program = getShaderProgram();
_resolutionLoc = program->getUniformLocation("resolution");
2013-09-09 17:49:13 +08:00
}
void NoiseSprite::setCustomUniforms()
{
_resolution[0] = getTexture()->getContentSizeInPixels().width;
_resolution[1] = getTexture()->getContentSizeInPixels().height;
getShaderProgram()->setUniformLocationWith2fv(_resolutionLoc, _resolution, 1);
}
class EdgeDetectionSprite : public ShaderSprite, public ShaderSpriteCreator<EdgeDetectionSprite>
{
public:
2013-11-14 07:55:36 +08:00
CREATE_FUNC(EdgeDetectionSprite);
2013-09-09 17:49:13 +08:00
EdgeDetectionSprite();
private:
GLfloat _resolution[2];
GLuint _resolutionLoc;
protected:
virtual void buildCustomUniforms();
virtual void setCustomUniforms();
};
EdgeDetectionSprite::EdgeDetectionSprite()
{
_fragSourceFile = "Shaders/example_edgeDetection.fsh";
}
void EdgeDetectionSprite::buildCustomUniforms()
{
2014-03-05 05:51:43 +08:00
auto program = getShaderProgram();
_resolutionLoc = program->getUniformLocation("resolution");
2013-09-09 17:49:13 +08:00
}
void EdgeDetectionSprite::setCustomUniforms()
{
_resolution[0] = getTexture()->getContentSizeInPixels().width;
_resolution[1] = getTexture()->getContentSizeInPixels().height;
getShaderProgram()->setUniformLocationWith2fv(_resolutionLoc, _resolution, 1);
}
class BloomSprite : public ShaderSprite, public ShaderSpriteCreator<BloomSprite>
{
public:
2013-11-14 07:55:36 +08:00
CREATE_FUNC(BloomSprite);
2013-09-09 17:49:13 +08:00
BloomSprite();
private:
GLfloat _resolution[2];
GLuint _resolutionLoc;
protected:
virtual void buildCustomUniforms();
virtual void setCustomUniforms();
};
BloomSprite::BloomSprite()
{
_fragSourceFile = "Shaders/example_bloom.fsh";
}
void BloomSprite::buildCustomUniforms()
{
2014-03-05 05:51:43 +08:00
auto program = getShaderProgram();
_resolutionLoc = program->getUniformLocation("resolution");
2013-09-09 17:49:13 +08:00
}
void BloomSprite::setCustomUniforms()
{
_resolution[0] = getTexture()->getContentSizeInPixels().width;
_resolution[1] = getTexture()->getContentSizeInPixels().height;
getShaderProgram()->setUniformLocationWith2fv(_resolutionLoc, _resolution, 1);
}
class CelShadingSprite : public ShaderSprite, public ShaderSpriteCreator<CelShadingSprite>
{
public:
2013-11-14 07:55:36 +08:00
CREATE_FUNC(CelShadingSprite);
2013-09-09 17:49:13 +08:00
CelShadingSprite();
private:
GLfloat _resolution[2];
GLuint _resolutionLoc;
protected:
virtual void buildCustomUniforms();
virtual void setCustomUniforms();
};
CelShadingSprite::CelShadingSprite()
{
_fragSourceFile = "Shaders/example_celShading.fsh";
}
void CelShadingSprite::buildCustomUniforms()
{
2014-03-05 05:51:43 +08:00
auto program = getShaderProgram();
_resolutionLoc = program->getUniformLocation("resolution");
2013-09-09 17:49:13 +08:00
}
void CelShadingSprite::setCustomUniforms()
{
_resolution[0] = getTexture()->getContentSizeInPixels().width;
_resolution[1] = getTexture()->getContentSizeInPixels().height;
getShaderProgram()->setUniformLocationWith2fv(_resolutionLoc, _resolution, 1);
}
class LensFlareSprite : public ShaderSprite, public ShaderSpriteCreator<LensFlareSprite>
{
public:
2013-11-14 07:55:36 +08:00
CREATE_FUNC(LensFlareSprite);
LensFlareSprite();
private:
GLfloat _resolution[2];
GLfloat _textureResolution[2];
GLuint _resolutionLoc;
GLuint _textureResolutionLoc;
protected:
virtual void buildCustomUniforms();
virtual void setCustomUniforms();
};
LensFlareSprite::LensFlareSprite()
{
_fragSourceFile = "Shaders/example_lensFlare.fsh";
}
void LensFlareSprite::buildCustomUniforms()
{
2014-03-05 05:51:43 +08:00
auto program = getShaderProgram();
_resolutionLoc = program->getUniformLocation("resolution");
_textureResolutionLoc = program->getUniformLocation("textureResolution");
}
void LensFlareSprite::setCustomUniforms()
{
_textureResolution[0] = getTexture()->getContentSizeInPixels().width;
_textureResolution[1] = getTexture()->getContentSizeInPixels().height;
_resolution[0] = getContentSize().width;
_resolution[1] = getContentSize().height;
getShaderProgram()->setUniformLocationWith2fv(_resolutionLoc, _resolution, 1);
getShaderProgram()->setUniformLocationWith2fv(_textureResolutionLoc, _textureResolution, 1);
}
2013-09-09 17:49:13 +08:00
NormalSpriteTest::NormalSpriteTest()
{
if (ShaderTestDemo2::init())
{
auto s = Director::getInstance()->getWinSize();
NormalSprite* sprite = NormalSprite::createSprite("Images/powered.png");
sprite->setPosition(Point(s.width/2, s.height/2));
addChild(sprite);
}
}
GreyScaleSpriteTest::GreyScaleSpriteTest()
{
if (ShaderTestDemo2::init())
{
auto s = Director::getInstance()->getWinSize();
GreyScaleSprite* sprite = GreyScaleSprite::createSprite("Images/powered.png");
sprite->setPosition(Point(s.width * 0.75, s.height/2));
auto sprite2 = Sprite::create("Images/powered.png");
sprite2->setPosition(Point(s.width * 0.25, s.height/2));
2013-09-09 17:49:13 +08:00
addChild(sprite);
addChild(sprite2);
2013-09-09 17:49:13 +08:00
}
}
BlurSpriteTest::BlurSpriteTest()
{
if (ShaderTestDemo2::init())
{
auto s = Director::getInstance()->getWinSize();
BlurSprite* sprite = BlurSprite::createSprite("Images/powered.png");
sprite->setPosition(Point(s.width * 0.75, s.height/2));
auto sprite2 = Sprite::create("Images/powered.png");
sprite2->setPosition(Point(s.width * 0.25, s.height/2));
2013-09-09 17:49:13 +08:00
addChild(sprite);
addChild(sprite2);
2013-09-09 17:49:13 +08:00
}
}
NoiseSpriteTest::NoiseSpriteTest()
{
if (ShaderTestDemo2::init())
{
auto s = Director::getInstance()->getWinSize();
NoiseSprite* sprite = NoiseSprite::createSprite("Images/powered.png");
sprite->setPosition(Point(s.width * 0.75, s.height/2));
auto sprite2 = Sprite::create("Images/powered.png");
sprite2->setPosition(Point(s.width * 0.25, s.height/2));
2013-09-09 17:49:13 +08:00
addChild(sprite);
addChild(sprite2);
2013-09-09 17:49:13 +08:00
}
}
EdgeDetectionSpriteTest::EdgeDetectionSpriteTest()
{
if (ShaderTestDemo2::init())
{
auto s = Director::getInstance()->getWinSize();
EdgeDetectionSprite* sprite = EdgeDetectionSprite::createSprite("Images/powered.png");
sprite->setPosition(Point(s.width * 0.75, s.height/2));
auto sprite2 = Sprite::create("Images/powered.png");
sprite2->setPosition(Point(s.width * 0.25, s.height/2));
2013-09-09 17:49:13 +08:00
addChild(sprite);
addChild(sprite2);
2013-09-09 17:49:13 +08:00
}
}
BloomSpriteTest::BloomSpriteTest()
{
if (ShaderTestDemo2::init())
{
auto s = Director::getInstance()->getWinSize();
BloomSprite* sprite = BloomSprite::createSprite("Images/stone.png");
sprite->setPosition(Point(s.width * 0.75, s.height/2));
auto sprite2 = Sprite::create("Images/stone.png");
sprite2->setPosition(Point(s.width * 0.25, s.height/2));
2013-09-09 17:49:13 +08:00
addChild(sprite);
addChild(sprite2);
2013-09-09 17:49:13 +08:00
}
}
CelShadingSpriteTest::CelShadingSpriteTest()
{
if (ShaderTestDemo2::init())
{
auto s = Director::getInstance()->getWinSize();
CelShadingSprite* sprite = CelShadingSprite::createSprite("Images/stone.png");
sprite->setPosition(Point(s.width * 0.75, s.height/2));
auto sprite2 = Sprite::create("Images/stone.png");
sprite2->setPosition(Point(s.width * 0.25, s.height/2));
2013-09-09 17:49:13 +08:00
addChild(sprite);
addChild(sprite2);
2013-09-09 17:49:13 +08:00
}
}
LensFlareSpriteTest::LensFlareSpriteTest()
{
if (ShaderTestDemo2::init())
{
auto s = Director::getInstance()->getWinSize();
LensFlareSprite* sprite = LensFlareSprite::createSprite("Images/noise.png");
Rect rect = Rect::ZERO;
rect.size = Size(480,320);
sprite->setPosition(Point(s.width * 0.5, s.height/2));
addChild(sprite);
}
}