mirror of https://github.com/axmolengine/axmol.git
Improve shader managment
1. Rename uniformId to batchId, refine batch draw check logic, not use xxhash to compute uniforms id 2. Material works, not check all cpp-tests, but some 2d/3d material works fine 3. Shader load/cache API improvements. 4. BREAK compatibliity: Node::setProgramState change parameter needsRetain to ownPS and value inverted. 5. custom vertexLayout setup: add new API ProgramState::getMutableVertexLayout, mark ProgramState::setVertexAttrib deprecated. 6. ProgramManager registerCustomProgram change to gen progId by vsName, fsName with xxhash64, if register succed, user can load it by progId with `loadProgram` 7. Add API ProgramManager::loadProgram for loading builtin by progType or loding a custom program by id 8. Add API ProgramManager::loadProgram to load program by vsName, fsName immediately without register as CUSTOM_PROGRAM 9. Add API Node::setProgramStateByProgramId(progTypeOrId); for set programState with programType or programId explicit. 10. Migrate material load logic
This commit is contained in:
parent
5a0838e52b
commit
c37af4c38e
|
@ -92,9 +92,9 @@ bool AtlasNode::initWithTexture(Texture2D* texture, int tileWidth, int tileHeigh
|
|||
return true;
|
||||
}
|
||||
|
||||
bool AtlasNode::setProgramState(backend::ProgramState* programState, bool needsRetain)
|
||||
bool AtlasNode::setProgramState(backend::ProgramState* programState, bool ownPS /*= false*/)
|
||||
{
|
||||
if (Node::setProgramState(programState, needsRetain))
|
||||
if (Node::setProgramState(programState, ownPS))
|
||||
{
|
||||
auto& pipelineDescriptor = _quadCommand.getPipelineDescriptor();
|
||||
pipelineDescriptor.programState = _programState;
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
void setQuadsToDraw(ssize_t quadsToDraw);
|
||||
size_t getQuadsToDraw() const;
|
||||
|
||||
bool setProgramState(backend::ProgramState* programState, bool needsRetain = true) override;
|
||||
bool setProgramState(backend::ProgramState* programState, bool ownPS = false) override;
|
||||
|
||||
AtlasNode() = default;
|
||||
virtual ~AtlasNode();
|
||||
|
|
|
@ -178,7 +178,7 @@ void DrawNode::updateShaderInternal(CustomCommand& cmd,
|
|||
void DrawNode::setVertexLayout(CustomCommand& cmd)
|
||||
{
|
||||
auto* programState = cmd.getPipelineDescriptor().programState;
|
||||
programState->validateSharedVertexLayout(VertexLayoutHelper::setupDrawNode);
|
||||
programState->validateSharedVertexLayout(backend::VertexLayoutType::DrawNode);
|
||||
}
|
||||
|
||||
void DrawNode::freeShaderInternal(CustomCommand& cmd)
|
||||
|
|
|
@ -117,17 +117,19 @@ bool GridBase::initWithSize(const Vec2& gridSize, Texture2D* texture, bool flipp
|
|||
uint32_t totalSize = (VERTEX_POSITION_SIZE + VERTEX_TEXCOORD_SIZE) * sizeof(float);
|
||||
const auto& attributeInfo = _programState->getProgram()->getActiveAttributes();
|
||||
auto iter = attributeInfo.find("a_position");
|
||||
|
||||
auto layout = _programState->getMutableVertexLayout();
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
_programState->setVertexAttrib("a_position", iter->second.location, backend::VertexFormat::FLOAT3, 0, false);
|
||||
layout->setAttrib("a_position", iter->second.location, backend::VertexFormat::FLOAT3, 0, false);
|
||||
}
|
||||
iter = attributeInfo.find("a_texCoord");
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
_programState->setVertexAttrib("a_texCoord", iter->second.location, backend::VertexFormat::FLOAT2, texcoordOffset,
|
||||
layout->setAttrib("a_texCoord", iter->second.location, backend::VertexFormat::FLOAT2, texcoordOffset,
|
||||
false);
|
||||
}
|
||||
_programState->setVertexStride(totalSize);
|
||||
layout->setStride(totalSize);
|
||||
|
||||
calculateVertexPoints();
|
||||
updateBlendState();
|
||||
|
|
|
@ -676,12 +676,12 @@ static Texture2D* _getTexture(Label* label)
|
|||
|
||||
void Label::setVertexLayout()
|
||||
{
|
||||
_programState->validateSharedVertexLayout(VertexLayoutHelper::setupSprite);
|
||||
_programState->validateSharedVertexLayout(backend::VertexLayoutType::Sprite);
|
||||
}
|
||||
|
||||
bool Label::setProgramState(backend::ProgramState* programState, bool needsRetain)
|
||||
bool Label::setProgramState(backend::ProgramState* programState, bool ownPS /*= false*/)
|
||||
{
|
||||
if (Node::setProgramState(programState, needsRetain))
|
||||
if (Node::setProgramState(programState, ownPS))
|
||||
{
|
||||
updateUniformLocations();
|
||||
for (auto&& batch : _batchCommands)
|
||||
|
@ -743,8 +743,7 @@ void Label::updateShaderProgram()
|
|||
}
|
||||
}
|
||||
|
||||
auto* program = backend::Program::getBuiltinProgram(programType);
|
||||
setProgramState(new backend::ProgramState(program), false);
|
||||
this->setProgramStateByProgramId(programType);
|
||||
|
||||
updateUniformLocations();
|
||||
|
||||
|
|
|
@ -674,7 +674,7 @@ public:
|
|||
*/
|
||||
float getAdditionalKerning() const;
|
||||
|
||||
bool setProgramState(backend::ProgramState* programState, bool needsRetain = true) override;
|
||||
bool setProgramState(backend::ProgramState* programState, bool ownPS = false) override;
|
||||
|
||||
FontAtlas* getFontAtlas() { return _fontAtlas; }
|
||||
|
||||
|
|
|
@ -221,9 +221,9 @@ void MotionStreak::setTexture(Texture2D* texture)
|
|||
}
|
||||
}
|
||||
|
||||
bool MotionStreak::setProgramState(backend::ProgramState* programState, bool needsRetain)
|
||||
bool MotionStreak::setProgramState(backend::ProgramState* programState, bool ownPS /*= false*/)
|
||||
{
|
||||
if (Node::setProgramState(programState, needsRetain))
|
||||
if (Node::setProgramState(programState, ownPS))
|
||||
{
|
||||
AXASSERT(programState, "argument should not be nullptr");
|
||||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
|
@ -235,23 +235,24 @@ bool MotionStreak::setProgramState(backend::ProgramState* programState, bool nee
|
|||
// setup custom vertex layout for V2F_T2F_C4B
|
||||
const auto& attributeInfo = _programState->getProgram()->getActiveAttributes();
|
||||
auto iter = attributeInfo.find("a_position");
|
||||
auto layout = _programState->getMutableVertexLayout();
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
_programState->setVertexAttrib("a_position", iter->second.location, backend::VertexFormat::FLOAT2, 0, false);
|
||||
layout->setAttrib("a_position", iter->second.location, backend::VertexFormat::FLOAT2, 0, false);
|
||||
}
|
||||
iter = attributeInfo.find("a_texCoord");
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
_programState->setVertexAttrib("a_texCoord", iter->second.location, backend::VertexFormat::FLOAT2,
|
||||
layout->setAttrib("a_texCoord", iter->second.location, backend::VertexFormat::FLOAT2,
|
||||
2 * sizeof(float), false);
|
||||
}
|
||||
iter = attributeInfo.find("a_color");
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
_programState->setVertexAttrib("a_color", iter->second.location, backend::VertexFormat::UBYTE4,
|
||||
layout->setAttrib("a_color", iter->second.location, backend::VertexFormat::UBYTE4,
|
||||
4 * sizeof(float), true);
|
||||
}
|
||||
_programState->setVertexStride(4 * sizeof(float) + 4 * sizeof(uint8_t));
|
||||
layout->setStride(4 * sizeof(float) + 4 * sizeof(uint8_t));
|
||||
|
||||
updateProgramStateTexture(_texture);
|
||||
return true;
|
||||
|
|
|
@ -156,7 +156,7 @@ public:
|
|||
_startingPositionInitialized = bStartingPositionInitialized;
|
||||
}
|
||||
|
||||
bool setProgramState(backend::ProgramState* programState, bool needsRetain) override;
|
||||
bool setProgramState(backend::ProgramState* programState, bool ownPS = false) override;
|
||||
|
||||
MotionStreak();
|
||||
virtual ~MotionStreak();
|
||||
|
|
|
@ -45,6 +45,7 @@ THE SOFTWARE.
|
|||
#include "2d/Component.h"
|
||||
#include "renderer/Material.h"
|
||||
#include "math/TransformUtils.h"
|
||||
#include "renderer/backend/ProgramManager.h"
|
||||
#include "renderer/backend/ProgramStateRegistry.h"
|
||||
|
||||
#if AX_NODE_RENDER_SUBPIXEL
|
||||
|
@ -2228,22 +2229,33 @@ void Node::setProgramStateWithRegistry(uint32_t programType, Texture2D* texture)
|
|||
{
|
||||
auto samplerFlags = texture ? texture->getSamplerFlags() : 0;
|
||||
auto programState = backend::ProgramStateRegistry::getInstance()->newProgramState(programType, samplerFlags);
|
||||
setProgramState(programState, false);
|
||||
setProgramState(programState, true);
|
||||
}
|
||||
|
||||
bool Node::setProgramState(backend::ProgramState* programState, bool needsRetain)
|
||||
bool Node::setProgramState(backend::ProgramState* programState, bool ownPS/* = false*/)
|
||||
{
|
||||
if (_programState != programState)
|
||||
{
|
||||
AX_SAFE_RELEASE(_programState);
|
||||
_programState = programState;
|
||||
if (needsRetain)
|
||||
if (!ownPS)
|
||||
AX_SAFE_RETAIN(_programState);
|
||||
return !!_programState;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
backend::ProgramState* Node::setProgramStateByProgramId(uint64_t programId)
|
||||
{
|
||||
auto prog = ProgramManager::getInstance()->loadProgram(programId);
|
||||
if (prog)
|
||||
{
|
||||
this->setProgramState(new ProgramState(prog), true);
|
||||
return _programState;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Node::updateProgramStateTexture(Texture2D* texture)
|
||||
{
|
||||
if (texture == nullptr || texture->getBackendTexture() == nullptr || _programState == nullptr)
|
||||
|
|
|
@ -1828,7 +1828,14 @@ public:
|
|||
* Sets ProgramState with retain
|
||||
* @param programState
|
||||
*/
|
||||
virtual bool setProgramState(backend::ProgramState* programState, bool needsRetain = true);
|
||||
virtual bool setProgramState(backend::ProgramState* programState, bool ownPS = false);
|
||||
|
||||
/**
|
||||
* Sets ProgramState by programId
|
||||
* @param progId the program id or programType used to create programState
|
||||
* @return ProgramState* (nullable)
|
||||
*/
|
||||
backend::ProgramState* setProgramStateByProgramId(uint64_t progId);
|
||||
|
||||
backend::ProgramState* getProgramState() const;
|
||||
|
||||
|
|
|
@ -57,15 +57,16 @@ backend::ProgramState* initPipelineDescriptor(ax::CustomCommand& command,
|
|||
pipelieDescriptor.programState = programState;
|
||||
|
||||
// set custom vertexLayout according to V2F_C4B_T2F structure
|
||||
programState->setVertexAttrib("a_position", program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT2, 0, false);
|
||||
programState->setVertexAttrib("a_texCoord", program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2,
|
||||
offsetof(V2F_C4B_T2F, texCoords), false);
|
||||
programState->setVertexAttrib("a_color", program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
auto vertexLayout = programState->getMutableVertexLayout();
|
||||
vertexLayout->setAttrib("a_position", program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT2, 0, false);
|
||||
vertexLayout->setAttrib("a_texCoord", program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2,
|
||||
offsetof(V2F_C4B_T2F, texCoords), false);
|
||||
vertexLayout->setAttrib("a_color", program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::UBYTE4,
|
||||
offsetof(V2F_C4B_T2F, colors), true);
|
||||
programState->setVertexStride(sizeof(V2F_C4B_T2F));
|
||||
vertexLayout->setStride(sizeof(V2F_C4B_T2F));
|
||||
|
||||
if (ridal)
|
||||
{
|
||||
|
@ -107,7 +108,7 @@ bool ProgressTimer::initWithSprite(Sprite* sp)
|
|||
|
||||
// TODO: Use ProgramState Vector to Node
|
||||
AX_SAFE_RELEASE(_programState2);
|
||||
setProgramState(initPipelineDescriptor(_customCommand, true, _locMVP1, _locTex1), false);
|
||||
setProgramState(initPipelineDescriptor(_customCommand, true, _locMVP1, _locTex1), true);
|
||||
_programState2 = initPipelineDescriptor(_customCommand2, false, _locMVP2, _locTex2);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -159,7 +159,7 @@ bool RenderTexture::initWithWidthAndHeight(int w,
|
|||
PixelFormat depthStencilFormat,
|
||||
bool sharedRenderTarget)
|
||||
{
|
||||
AXASSERT(format == backend::PixelFormat::RGBA8 || format == PixelFormat::RGB8, "only RGB and RGBA formats are valid for a render texture");
|
||||
AXASSERT(format == backend::PixelFormat::RGBA8 || format == PixelFormat::RGB8 || format == PixelFormat::RGBA4, "only RGB and RGBA formats are valid for a render texture");
|
||||
|
||||
bool ret = false;
|
||||
do
|
||||
|
|
|
@ -358,7 +358,7 @@ void Sprite::setTexture(std::string_view filename)
|
|||
void Sprite::setVertexLayout()
|
||||
{
|
||||
AXASSERT(_programState, "programState should not be nullptr");
|
||||
_programState->validateSharedVertexLayout(VertexLayoutHelper::setupSprite);
|
||||
_programState->validateSharedVertexLayout(backend::VertexLayoutType::Sprite);
|
||||
}
|
||||
|
||||
void Sprite::setProgramState(uint32_t type)
|
||||
|
@ -366,10 +366,10 @@ void Sprite::setProgramState(uint32_t type)
|
|||
setProgramStateWithRegistry(type, _texture);
|
||||
}
|
||||
|
||||
bool Sprite::setProgramState(backend::ProgramState* programState, bool needsRetain)
|
||||
bool Sprite::setProgramState(backend::ProgramState* programState, bool ownPS/* = false*/)
|
||||
{
|
||||
AXASSERT(programState, "argument should not be nullptr");
|
||||
if (Node::setProgramState(programState, needsRetain))
|
||||
if (Node::setProgramState(programState, ownPS))
|
||||
{
|
||||
auto& pipelineDescriptor = _trianglesCommand.getPipelineDescriptor();
|
||||
pipelineDescriptor.programState = _programState;
|
||||
|
|
|
@ -425,7 +425,7 @@ public:
|
|||
/**
|
||||
* Set or Attach new ProgramState
|
||||
*/
|
||||
bool setProgramState(backend::ProgramState* programState, bool needsRetain = true) override;
|
||||
bool setProgramState(backend::ProgramState* programState, bool ownPS = false) override;
|
||||
|
||||
/**
|
||||
* Sets the weak reference of the TextureAtlas when the sprite is rendered using via SpriteBatchNode.
|
||||
|
|
|
@ -124,13 +124,13 @@ void SpriteBatchNode::setUniformLocation()
|
|||
void SpriteBatchNode::setVertexLayout()
|
||||
{
|
||||
AXASSERT(_programState, "programState should not be nullptr");
|
||||
_programState->validateSharedVertexLayout(VertexLayoutHelper::setupSprite);
|
||||
_programState->validateSharedVertexLayout(backend::VertexLayoutType::Sprite);
|
||||
}
|
||||
|
||||
bool SpriteBatchNode::setProgramState(backend::ProgramState* programState, bool needsRetain)
|
||||
bool SpriteBatchNode::setProgramState(backend::ProgramState* programState, bool ownPS/* = false*/)
|
||||
{
|
||||
AXASSERT(programState, "programState should not be nullptr");
|
||||
if (Node::setProgramState(programState, needsRetain))
|
||||
if (Node::setProgramState(programState, ownPS))
|
||||
{
|
||||
auto& pipelineDescriptor = _quadCommand.getPipelineDescriptor();
|
||||
pipelineDescriptor.programState = _programState;
|
||||
|
|
|
@ -213,7 +213,7 @@ public:
|
|||
*/
|
||||
virtual std::string getDescription() const override;
|
||||
|
||||
bool setProgramState(backend::ProgramState* programState, bool needsRetain = true) override;
|
||||
bool setProgramState(backend::ProgramState* programState, bool ownPS = false) override;
|
||||
|
||||
/** Inserts a quad at a certain index into the texture atlas. The Sprite won't be added into the children array.
|
||||
* This method should be called only when you are dealing with very big AtlasSprite and when most of the Sprite
|
||||
|
|
|
@ -835,9 +835,9 @@ void MeshRenderer::draw(Renderer* renderer, const Mat4& transform, uint32_t flag
|
|||
}
|
||||
}
|
||||
|
||||
bool MeshRenderer::setProgramState(backend::ProgramState* programState, bool needsRetain)
|
||||
bool MeshRenderer::setProgramState(backend::ProgramState* programState, bool ownPS/* = false*/)
|
||||
{
|
||||
if (Node::setProgramState(programState, needsRetain))
|
||||
if (Node::setProgramState(programState, ownPS))
|
||||
{
|
||||
for (auto&& state : _meshes)
|
||||
{
|
||||
|
|
|
@ -129,7 +129,7 @@ public:
|
|||
|
||||
// overrides
|
||||
/** Sets ProgramState, attributes should be bound by the user */
|
||||
bool setProgramState(backend::ProgramState* programState, bool needsRetain = true) override;
|
||||
bool setProgramState(backend::ProgramState* programState, bool ownPS = false) override;
|
||||
|
||||
/*
|
||||
* Get AABB
|
||||
|
|
|
@ -121,8 +121,7 @@ bool MotionStreak3D::initWithFade(float fade, float minSeg, float stroke, const
|
|||
_blendFunc = BlendFunc::ALPHA_NON_PREMULTIPLIED;
|
||||
|
||||
// shader state
|
||||
auto* program = backend::Program::getBuiltinProgram(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
setProgramState(new backend::ProgramState(program), false);
|
||||
this->setProgramStateByProgramId(ProgramType::POSITION_TEXTURE_COLOR);
|
||||
|
||||
_customCommand.getPipelineDescriptor().programState = _programState;
|
||||
|
||||
|
|
|
@ -64,8 +64,7 @@ bool Skybox::init()
|
|||
_customCommand.setAfterCallback(AX_CALLBACK_0(Skybox::onAfterDraw, this));
|
||||
|
||||
// create and set our custom shader
|
||||
auto* program = backend::Program::getBuiltinProgram(backend::ProgramType::SKYBOX_3D);
|
||||
setProgramState(new backend::ProgramState(program), false);
|
||||
setProgramStateByProgramId(backend::ProgramType::SKYBOX_3D);
|
||||
|
||||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
|
||||
|
|
|
@ -106,8 +106,7 @@ void ax::Terrain::setLightDir(const Vec3& lightDir)
|
|||
|
||||
bool Terrain::initProperties()
|
||||
{
|
||||
auto* program = backend::Program::getBuiltinProgram(backend::ProgramType::TERRAIN_3D);
|
||||
setProgramState(new backend::ProgramState(program), false);
|
||||
setProgramStateByProgramId(ProgramType::TERRAIN_3D);
|
||||
|
||||
_stateBlock.depthWrite = true;
|
||||
_stateBlock.depthTest = true;
|
||||
|
|
|
@ -90,15 +90,17 @@ bool VertexAttribBinding::init(MeshIndexData* meshIndexData, Pass* pass, MeshCom
|
|||
// Parse and set attributes
|
||||
parseAttributes();
|
||||
int offset = 0;
|
||||
auto vertexLayout = _programState->getMutableVertexLayout();
|
||||
for (auto k = 0; k < attributeCount; k++)
|
||||
{
|
||||
auto meshattribute = meshVertexData->getMeshVertexAttrib(k);
|
||||
setVertexAttribPointer(shaderinfos::getAttributeName(meshattribute.vertexAttrib), meshattribute.type, false,
|
||||
setVertexAttribPointer(vertexLayout, shaderinfos::getAttributeName(meshattribute.vertexAttrib),
|
||||
meshattribute.type, false,
|
||||
offset, 1 << k);
|
||||
offset += meshattribute.getAttribSizeBytes();
|
||||
}
|
||||
|
||||
_programState->setVertexStride(offset);
|
||||
vertexLayout->setStride(offset);
|
||||
|
||||
AXASSERT(offset == meshVertexData->getSizePerVertex(), "vertex layout mismatch!");
|
||||
|
||||
|
@ -133,7 +135,8 @@ const backend::AttributeBindInfo* VertexAttribBinding::getVertexAttribValue(std:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void VertexAttribBinding::setVertexAttribPointer(std::string_view name,
|
||||
void VertexAttribBinding::setVertexAttribPointer(VertexLayout* vertexLayout,
|
||||
std::string_view name,
|
||||
backend::VertexFormat type,
|
||||
bool normalized,
|
||||
int offset,
|
||||
|
@ -143,7 +146,7 @@ void VertexAttribBinding::setVertexAttribPointer(std::string_view name,
|
|||
if (v)
|
||||
{
|
||||
// AXLOG("axmol: set attribute '%s' location: %d, offset: %d", name.c_str(), v->location, offset);
|
||||
_programState->setVertexAttrib(name, v->location, type, offset, normalized);
|
||||
vertexLayout->setAttrib(name, v->location, type, offset, normalized);
|
||||
_vertexAttribsFlags |= flag;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -107,7 +107,7 @@ private:
|
|||
VertexAttribBinding& operator=(const VertexAttribBinding&);
|
||||
|
||||
bool init(MeshIndexData* meshIndexData, Pass* pass, MeshCommand*);
|
||||
void setVertexAttribPointer(std::string_view name,
|
||||
void setVertexAttribPointer(VertexLayout* vertexLayout, std::string_view name,
|
||||
backend::VertexFormat type,
|
||||
bool normalized,
|
||||
int offset,
|
||||
|
|
|
@ -566,9 +566,7 @@ bool GLViewImpl::initWithRect(std::string_view viewName, const ax::Rect& rect, f
|
|||
#endif
|
||||
|
||||
#if defined(AX_USE_GL)
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
glfwSwapInterval(_glContextAttrs.vsync ? 1 : 0);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
// check OpenGL version at first
|
||||
const GLubyte* glVersion = glGetString(GL_VERSION);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
set(_AX_RENDERER_HEADER
|
||||
renderer/CallbackCommand.h
|
||||
renderer/Colorizer.h
|
||||
renderer/CustomCommand.h
|
||||
renderer/GroupCommand.h
|
||||
renderer/Material.h
|
||||
|
@ -63,7 +62,6 @@ set(_AX_RENDERER_SRC
|
|||
renderer/TextureCube.cpp
|
||||
renderer/TrianglesCommand.cpp
|
||||
renderer/Shaders.cpp
|
||||
renderer/Colorizer.cpp
|
||||
|
||||
renderer/backend/ProgramManager.cpp
|
||||
renderer/backend/ProgramStateRegistry.cpp
|
||||
|
|
|
@ -1,865 +0,0 @@
|
|||
#include "Colorizer.h"
|
||||
#include "math/Mat3.h"
|
||||
#include "2d/Node.h"
|
||||
#include "renderer/Shaders.h"
|
||||
#include "renderer/backend/Device.h"
|
||||
|
||||
NS_AX_BEGIN
|
||||
|
||||
#define FLT_SQRT_2 1.4142135623730950488016887242097
|
||||
#define FLT_SQRT_3 1.7320508075688772935274463415059
|
||||
#define FLT_XRS (1 / FLT_SQRT_2)
|
||||
#define FLT_XRC FLT_XRS
|
||||
#define FLT_YRS (-1 / FLT_SQRT_3)
|
||||
#define FLT_YRC (FLT_SQRT_2 / FLT_SQRT_3)
|
||||
#define RLUM (0.3086)
|
||||
#define GLUM (0.6094)
|
||||
#define BLUM (0.0820)
|
||||
|
||||
#define CLZ_PRINTMAT 0
|
||||
|
||||
typedef float _M3X3[3][3];
|
||||
typedef float _M4X4[4][4];
|
||||
|
||||
static Vec3 fastest_rgb2hsv(const Color3B& rgb)
|
||||
{
|
||||
float r = rgb.r / 255.0f;
|
||||
float g = rgb.g / 255.0f;
|
||||
float b = rgb.b / 255.0f;
|
||||
|
||||
float h, s, v;
|
||||
|
||||
float K = 0.f;
|
||||
|
||||
if (g < b)
|
||||
{
|
||||
std::swap(g, b);
|
||||
K = -1.f;
|
||||
}
|
||||
|
||||
if (r < g)
|
||||
{
|
||||
std::swap(r, g);
|
||||
K = -2.f / 6.f - K;
|
||||
}
|
||||
|
||||
float chroma = r - std::min(g, b);
|
||||
h = fabs(K + (g - b) / (6.f * chroma + 1e-20f));
|
||||
s = chroma / (r + 1e-20f);
|
||||
v = r;
|
||||
|
||||
return Vec3(h, s, v);
|
||||
}
|
||||
|
||||
static Vec3 rgb2hsv(const Color3B& rgb)
|
||||
{
|
||||
unsigned char dst_h, dst_s, dst_v;
|
||||
|
||||
float r = rgb.r / 255.0f;
|
||||
float g = rgb.g / 255.0f;
|
||||
float b = rgb.b / 255.0f;
|
||||
|
||||
float h, s, v; // h:0-360.0, s:0.0-1.0, v:0.0-1.0
|
||||
|
||||
float max = std::max({r, g, b});
|
||||
float min = std::min({r, g, b});
|
||||
|
||||
v = max;
|
||||
|
||||
if (max == 0.0f)
|
||||
{
|
||||
s = 0;
|
||||
h = 0;
|
||||
}
|
||||
else if (max - min == 0.0f)
|
||||
{
|
||||
s = 0;
|
||||
h = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = (max - min) / max;
|
||||
|
||||
if (max == r)
|
||||
{
|
||||
h = 60 * ((g - b) / (max - min)) + 0;
|
||||
}
|
||||
else if (max == g)
|
||||
{
|
||||
h = 60 * ((b - r) / (max - min)) + 120;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = 60 * ((r - g) / (max - min)) + 240;
|
||||
}
|
||||
}
|
||||
|
||||
if (h < 0)
|
||||
h += 360.0f;
|
||||
|
||||
dst_h = (unsigned char)(h / 2); // dst_h : 0-180
|
||||
dst_s = (unsigned char)(s /* * 255*/); // dst_s : 0-255
|
||||
dst_v = (unsigned char)(v /** 255*/); // dst_v : 0-255
|
||||
|
||||
return Vec3(dst_h / 180.f, dst_s, dst_v);
|
||||
}
|
||||
|
||||
static void hsv2rgb(const unsigned char& src_h,
|
||||
const unsigned char& src_s,
|
||||
const unsigned char& src_v,
|
||||
unsigned char& dst_r,
|
||||
unsigned char& dst_g,
|
||||
unsigned char& dst_b)
|
||||
{
|
||||
float h = src_h * 2.0f; // 0-360
|
||||
float s = src_s / 255.0f; // 0.0-1.0
|
||||
float v = src_v / 255.0f; // 0.0-1.0
|
||||
|
||||
float r, g, b; // 0.0-1.0
|
||||
|
||||
int hi = (int)(h / 60.0f) % 6;
|
||||
float f = (h / 60.0f) - hi;
|
||||
float p = v * (1.0f - s);
|
||||
float q = v * (1.0f - s * f);
|
||||
float t = v * (1.0f - s * (1.0f - f));
|
||||
|
||||
switch (hi)
|
||||
{
|
||||
case 0:
|
||||
r = v, g = t, b = p;
|
||||
break;
|
||||
case 1:
|
||||
r = q, g = v, b = p;
|
||||
break;
|
||||
case 2:
|
||||
r = p, g = v, b = t;
|
||||
break;
|
||||
case 3:
|
||||
r = p, g = q, b = v;
|
||||
break;
|
||||
case 4:
|
||||
r = t, g = p, b = v;
|
||||
break;
|
||||
case 5:
|
||||
r = v, g = p, b = q;
|
||||
break;
|
||||
}
|
||||
|
||||
dst_r = (unsigned char)(r * 255); // dst_r : 0-255
|
||||
dst_g = (unsigned char)(g * 255); // dst_r : 0-255
|
||||
dst_b = (unsigned char)(b * 255); // dst_r : 0-255
|
||||
}
|
||||
|
||||
#if CLZ_PRINTMAT
|
||||
static void printmat3(float mat[3][3])
|
||||
{
|
||||
int x, y;
|
||||
char svalue[256];
|
||||
int n = 0;
|
||||
for (y = 0; y < 3; y++)
|
||||
{
|
||||
for (x = 0; x < 3; x++)
|
||||
n += sprintf(svalue + n, "%f ", mat[y][x]);
|
||||
n += sprintf(svalue + n, "\n");
|
||||
}
|
||||
n += sprintf(svalue + n, "\n");
|
||||
|
||||
log("%s", svalue);
|
||||
}
|
||||
|
||||
static void printmat4(float mat[4][4])
|
||||
{
|
||||
int x, y;
|
||||
char svalue[256];
|
||||
int n = 0;
|
||||
for (y = 0; y < 4; y++)
|
||||
{
|
||||
for (x = 0; x < 4; x++)
|
||||
n += sprintf(svalue + n, "%f ", mat[y][x]);
|
||||
n += sprintf(svalue + n, "\n");
|
||||
}
|
||||
n += sprintf(svalue + n, "\n");
|
||||
|
||||
log("%s", svalue);
|
||||
}
|
||||
|
||||
inline void printmat3(float (&mat)[9])
|
||||
{
|
||||
printmat3((_M3X3&)mat);
|
||||
}
|
||||
|
||||
inline void printmat4(float (&mat)[16])
|
||||
{
|
||||
printmat4((_M4X4&)mat);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void createRotationX(Mat4* dst, float sv, float cv)
|
||||
{
|
||||
dst->m[5] = cv;
|
||||
dst->m[6] = sv;
|
||||
dst->m[9] = -sv;
|
||||
dst->m[10] = cv;
|
||||
}
|
||||
|
||||
inline void createRotationY(Mat4* dst, float sv, float cv)
|
||||
{
|
||||
dst->m[0] = cv;
|
||||
dst->m[2] = -sv;
|
||||
dst->m[8] = sv;
|
||||
dst->m[10] = cv;
|
||||
}
|
||||
|
||||
inline void createRotationZ(Mat4* dst, float sv, float cv)
|
||||
{
|
||||
dst->m[0] = cv;
|
||||
dst->m[1] = sv;
|
||||
dst->m[4] = -sv;
|
||||
dst->m[5] = cv;
|
||||
}
|
||||
|
||||
inline void rotateX(Mat4* dst, float sv, float cv)
|
||||
{
|
||||
Mat4 temp;
|
||||
createRotationX(&temp, sv, cv);
|
||||
Mat4::multiply(temp, *dst, dst);
|
||||
}
|
||||
|
||||
inline void rotateY(Mat4* dst, float sv, float cv)
|
||||
{
|
||||
Mat4 temp;
|
||||
createRotationY(&temp, sv, cv);
|
||||
Mat4::multiply(temp, *dst, dst); // dst->multiply(temp); pitfall: matrix1 * matrix2 != matrix2 * matrix1
|
||||
}
|
||||
|
||||
inline void rotateZ(Mat4* dst, float sv, float cv)
|
||||
{
|
||||
Mat4 temp;
|
||||
createRotationZ(&temp, sv, cv);
|
||||
Mat4::multiply(temp, *dst, dst);
|
||||
}
|
||||
|
||||
inline void rotateZ(Mat4* dst, float angle)
|
||||
{
|
||||
Mat4 temp;
|
||||
Mat4::createRotationZ(angle, &temp);
|
||||
Mat4::multiply(temp, *dst, dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* matrixmult -
|
||||
* multiply two matricies
|
||||
*/
|
||||
static void matrixmult(float a[4][4], float b[4][4], float c[4][4])
|
||||
{
|
||||
int x, y;
|
||||
float temp[4][4];
|
||||
|
||||
for (y = 0; y < 4; y++)
|
||||
for (x = 0; x < 4; x++)
|
||||
{
|
||||
temp[y][x] = b[y][0] * a[0][x] + b[y][1] * a[1][x] + b[y][2] * a[2][x] + b[y][3] * a[3][x];
|
||||
}
|
||||
for (y = 0; y < 4; y++)
|
||||
for (x = 0; x < 4; x++)
|
||||
c[y][x] = temp[y][x];
|
||||
}
|
||||
|
||||
/*
|
||||
* identmat -
|
||||
* make an identity matrix
|
||||
*/
|
||||
inline void identmat(float* matrix)
|
||||
{
|
||||
*matrix++ = 1.0; /* row 1 */
|
||||
*matrix++ = 0.0;
|
||||
*matrix++ = 0.0;
|
||||
*matrix++ = 0.0;
|
||||
*matrix++ = 0.0; /* row 2 */
|
||||
*matrix++ = 1.0;
|
||||
*matrix++ = 0.0;
|
||||
*matrix++ = 0.0;
|
||||
*matrix++ = 0.0; /* row 3 */
|
||||
*matrix++ = 0.0;
|
||||
*matrix++ = 1.0;
|
||||
*matrix++ = 0.0;
|
||||
*matrix++ = 0.0; /* row 4 */
|
||||
*matrix++ = 0.0;
|
||||
*matrix++ = 0.0;
|
||||
*matrix++ = 1.0;
|
||||
}
|
||||
|
||||
/*
|
||||
* xformpnt -
|
||||
* transform a 3D point using a matrix
|
||||
*/
|
||||
static void xformpnt(float matrix[4][4], float x, float y, float z, float* tx, float* ty, float* tz)
|
||||
{
|
||||
*tx = x * matrix[0][0] + y * matrix[1][0] + z * matrix[2][0] + matrix[3][0];
|
||||
*ty = x * matrix[0][1] + y * matrix[1][1] + z * matrix[2][1] + matrix[3][1];
|
||||
*tz = x * matrix[0][2] + y * matrix[1][2] + z * matrix[2][2] + matrix[3][2];
|
||||
}
|
||||
|
||||
/*
|
||||
* cscalemat -
|
||||
* make a color scale marix
|
||||
*/
|
||||
static void cscalemat(float mat[4][4], float rscale, float gscale, float bscale)
|
||||
{
|
||||
float mmat[4][4];
|
||||
|
||||
mmat[0][0] = rscale;
|
||||
mmat[0][1] = 0.0;
|
||||
mmat[0][2] = 0.0;
|
||||
mmat[0][3] = 0.0;
|
||||
|
||||
mmat[1][0] = 0.0;
|
||||
mmat[1][1] = gscale;
|
||||
mmat[1][2] = 0.0;
|
||||
mmat[1][3] = 0.0;
|
||||
|
||||
mmat[2][0] = 0.0;
|
||||
mmat[2][1] = 0.0;
|
||||
mmat[2][2] = bscale;
|
||||
mmat[2][3] = 0.0;
|
||||
|
||||
mmat[3][0] = 0.0;
|
||||
mmat[3][1] = 0.0;
|
||||
mmat[3][2] = 0.0;
|
||||
mmat[3][3] = 1.0;
|
||||
matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
/*
|
||||
* lummat -
|
||||
* make a luminance marix
|
||||
*/
|
||||
static void lummat(float mat[4][4])
|
||||
{
|
||||
float mmat[4][4];
|
||||
float rwgt, gwgt, bwgt;
|
||||
|
||||
rwgt = RLUM;
|
||||
gwgt = GLUM;
|
||||
bwgt = BLUM;
|
||||
mmat[0][0] = rwgt;
|
||||
mmat[0][1] = rwgt;
|
||||
mmat[0][2] = rwgt;
|
||||
mmat[0][3] = 0.0;
|
||||
|
||||
mmat[1][0] = gwgt;
|
||||
mmat[1][1] = gwgt;
|
||||
mmat[1][2] = gwgt;
|
||||
mmat[1][3] = 0.0;
|
||||
|
||||
mmat[2][0] = bwgt;
|
||||
mmat[2][1] = bwgt;
|
||||
mmat[2][2] = bwgt;
|
||||
mmat[2][3] = 0.0;
|
||||
|
||||
mmat[3][0] = 0.0;
|
||||
mmat[3][1] = 0.0;
|
||||
mmat[3][2] = 0.0;
|
||||
mmat[3][3] = 1.0;
|
||||
matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
/*
|
||||
* saturatemat -
|
||||
* make a saturation marix
|
||||
*/
|
||||
static void saturatemat(float mat[4][4], float sat)
|
||||
{
|
||||
float mmat[4][4];
|
||||
float a, b, c, d, e, f, g, h, i;
|
||||
float rwgt, gwgt, bwgt;
|
||||
|
||||
rwgt = RLUM;
|
||||
gwgt = GLUM;
|
||||
bwgt = BLUM;
|
||||
|
||||
a = (1.0 - sat) * rwgt + sat;
|
||||
b = (1.0 - sat) * rwgt;
|
||||
c = (1.0 - sat) * rwgt;
|
||||
d = (1.0 - sat) * gwgt;
|
||||
e = (1.0 - sat) * gwgt + sat;
|
||||
f = (1.0 - sat) * gwgt;
|
||||
g = (1.0 - sat) * bwgt;
|
||||
h = (1.0 - sat) * bwgt;
|
||||
i = (1.0 - sat) * bwgt + sat;
|
||||
mmat[0][0] = a;
|
||||
mmat[0][1] = b;
|
||||
mmat[0][2] = c;
|
||||
mmat[0][3] = 0.0;
|
||||
|
||||
mmat[1][0] = d;
|
||||
mmat[1][1] = e;
|
||||
mmat[1][2] = f;
|
||||
mmat[1][3] = 0.0;
|
||||
|
||||
mmat[2][0] = g;
|
||||
mmat[2][1] = h;
|
||||
mmat[2][2] = i;
|
||||
mmat[2][3] = 0.0;
|
||||
|
||||
mmat[3][0] = 0.0;
|
||||
mmat[3][1] = 0.0;
|
||||
mmat[3][2] = 0.0;
|
||||
mmat[3][3] = 1.0;
|
||||
matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
/*
|
||||
* offsetmat -
|
||||
* offset r, g, and b
|
||||
*/
|
||||
static void offsetmat(float mat[4][4], float roffset, float goffset, float boffset)
|
||||
{
|
||||
float mmat[4][4];
|
||||
|
||||
mmat[0][0] = 1.0;
|
||||
mmat[0][1] = 0.0;
|
||||
mmat[0][2] = 0.0;
|
||||
mmat[0][3] = 0.0;
|
||||
|
||||
mmat[1][0] = 0.0;
|
||||
mmat[1][1] = 1.0;
|
||||
mmat[1][2] = 0.0;
|
||||
mmat[1][3] = 0.0;
|
||||
|
||||
mmat[2][0] = 0.0;
|
||||
mmat[2][1] = 0.0;
|
||||
mmat[2][2] = 1.0;
|
||||
mmat[2][3] = 0.0;
|
||||
|
||||
mmat[3][0] = roffset;
|
||||
mmat[3][1] = goffset;
|
||||
mmat[3][2] = boffset;
|
||||
mmat[3][3] = 1.0;
|
||||
matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
/*
|
||||
* xrotate -
|
||||
* rotate about the x (red) axis
|
||||
*/
|
||||
inline void xrotatemat(float mat[4][4], float rs, float rc)
|
||||
{
|
||||
float mmat[4][4];
|
||||
|
||||
mmat[0][0] = 1.0;
|
||||
mmat[0][1] = 0.0;
|
||||
mmat[0][2] = 0.0;
|
||||
mmat[0][3] = 0.0;
|
||||
|
||||
mmat[1][0] = 0.0;
|
||||
mmat[1][1] = rc;
|
||||
mmat[1][2] = rs;
|
||||
mmat[1][3] = 0.0;
|
||||
|
||||
mmat[2][0] = 0.0;
|
||||
mmat[2][1] = -rs;
|
||||
mmat[2][2] = rc;
|
||||
mmat[2][3] = 0.0;
|
||||
|
||||
mmat[3][0] = 0.0;
|
||||
mmat[3][1] = 0.0;
|
||||
mmat[3][2] = 0.0;
|
||||
mmat[3][3] = 1.0;
|
||||
matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
/*
|
||||
* yrotate -
|
||||
* rotate about the y (green) axis
|
||||
*/
|
||||
static void yrotatemat(float mat[4][4], float rs, float rc)
|
||||
{
|
||||
float mmat[4][4];
|
||||
|
||||
mmat[0][0] = rc;
|
||||
mmat[0][1] = 0.0;
|
||||
mmat[0][2] = -rs;
|
||||
mmat[0][3] = 0.0;
|
||||
|
||||
mmat[1][0] = 0.0;
|
||||
mmat[1][1] = 1.0;
|
||||
mmat[1][2] = 0.0;
|
||||
mmat[1][3] = 0.0;
|
||||
|
||||
mmat[2][0] = rs;
|
||||
mmat[2][1] = 0.0;
|
||||
mmat[2][2] = rc;
|
||||
mmat[2][3] = 0.0;
|
||||
|
||||
mmat[3][0] = 0.0;
|
||||
mmat[3][1] = 0.0;
|
||||
mmat[3][2] = 0.0;
|
||||
mmat[3][3] = 1.0;
|
||||
matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
/*
|
||||
* zrotate -
|
||||
* rotate about the z (blue) axis
|
||||
*/
|
||||
static void zrotatemat(float mat[4][4], float rs, float rc)
|
||||
{
|
||||
float mmat[4][4];
|
||||
|
||||
mmat[0][0] = rc;
|
||||
mmat[0][1] = rs;
|
||||
mmat[0][2] = 0.0;
|
||||
mmat[0][3] = 0.0;
|
||||
|
||||
mmat[1][0] = -rs;
|
||||
mmat[1][1] = rc;
|
||||
mmat[1][2] = 0.0;
|
||||
mmat[1][3] = 0.0;
|
||||
|
||||
mmat[2][0] = 0.0;
|
||||
mmat[2][1] = 0.0;
|
||||
mmat[2][2] = 1.0;
|
||||
mmat[2][3] = 0.0;
|
||||
|
||||
mmat[3][0] = 0.0;
|
||||
mmat[3][1] = 0.0;
|
||||
mmat[3][2] = 0.0;
|
||||
mmat[3][3] = 1.0;
|
||||
matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
/*
|
||||
* zshear -
|
||||
* shear z using x and y.
|
||||
*/
|
||||
static void zshearmat(float mat[4][4], float dx, float dy)
|
||||
{
|
||||
float mmat[4][4];
|
||||
|
||||
mmat[0][0] = 1.0;
|
||||
mmat[0][1] = 0.0;
|
||||
mmat[0][2] = dx;
|
||||
mmat[0][3] = 0.0;
|
||||
|
||||
mmat[1][0] = 0.0;
|
||||
mmat[1][1] = 1.0;
|
||||
mmat[1][2] = dy;
|
||||
mmat[1][3] = 0.0;
|
||||
|
||||
mmat[2][0] = 0.0;
|
||||
mmat[2][1] = 0.0;
|
||||
mmat[2][2] = 1.0;
|
||||
mmat[2][3] = 0.0;
|
||||
|
||||
mmat[3][0] = 0.0;
|
||||
mmat[3][1] = 0.0;
|
||||
mmat[3][2] = 0.0;
|
||||
mmat[3][3] = 1.0;
|
||||
matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
/*
|
||||
* simplehuerotatemat -
|
||||
* simple hue rotation. This changes luminance
|
||||
*/
|
||||
static void simplehuerotatemat(float mat[4][4], float rot)
|
||||
{
|
||||
// log("************* simplehuerotatemat");
|
||||
|
||||
float mag;
|
||||
float xrs, xrc;
|
||||
float yrs, yrc;
|
||||
float zrs, zrc;
|
||||
identmat((float*)mat);
|
||||
|
||||
/* rotate the grey vector into positive Z */
|
||||
mag = sqrt(2.0);
|
||||
xrs = 1.0 / mag;
|
||||
xrc = 1.0 / mag;
|
||||
xrotatemat(mat, xrs, xrc);
|
||||
// printmat(mat);
|
||||
|
||||
mag = sqrt(3.0);
|
||||
yrs = -1.0 / mag;
|
||||
yrc = sqrt(2.0) / mag;
|
||||
yrotatemat(mat, yrs, yrc);
|
||||
// printmat(mat);
|
||||
|
||||
/* rotate the hue */
|
||||
zrs = sin(rot);
|
||||
zrc = cos(rot);
|
||||
zrotatemat(mat, zrs, zrc);
|
||||
// printmat(mat);
|
||||
|
||||
/* rotate the grey vector back into place */
|
||||
yrotatemat(mat, -yrs, yrc);
|
||||
// printmat(mat);
|
||||
xrotatemat(mat, -xrs, xrc);
|
||||
// printmat(mat);
|
||||
|
||||
// log("############## simplehuerotatemat");
|
||||
}
|
||||
|
||||
/*
|
||||
* huerotatemat -
|
||||
* rotate the hue, while maintaining luminance.
|
||||
*/
|
||||
static void huerotatemat(float mat[4][4], float rot)
|
||||
{
|
||||
float mmat[4][4];
|
||||
float mag;
|
||||
float lx, ly, lz;
|
||||
float xrs, xrc;
|
||||
float yrs, yrc;
|
||||
float zrs, zrc;
|
||||
float zsx, zsy;
|
||||
|
||||
identmat((float*)mat);
|
||||
identmat((float*)&mmat);
|
||||
|
||||
/* rotate the grey vector into positive Z */
|
||||
mag = sqrt(2.0);
|
||||
xrs = 1.0 / mag;
|
||||
xrc = 1.0 / mag;
|
||||
xrotatemat(mmat, xrs, xrc);
|
||||
mag = sqrt(3.0);
|
||||
yrs = -1.0 / mag;
|
||||
yrc = sqrt(2.0) / mag;
|
||||
yrotatemat(mmat, yrs, yrc);
|
||||
|
||||
/* shear the space to make the luminance plane horizontal */
|
||||
xformpnt(mmat, RLUM, GLUM, BLUM, &lx, &ly, &lz);
|
||||
zsx = lx / lz;
|
||||
zsy = ly / lz;
|
||||
zshearmat(mmat, zsx, zsy);
|
||||
|
||||
/* rotate the hue */
|
||||
zrs = sin(rot);
|
||||
zrc = cos(rot);
|
||||
zrotatemat(mmat, zrs, zrc);
|
||||
|
||||
/* unshear the space to put the luminance plane back */
|
||||
zshearmat(mmat, -zsx, -zsy);
|
||||
|
||||
/* rotate the grey vector back into place */
|
||||
yrotatemat(mmat, -yrs, yrc);
|
||||
xrotatemat(mmat, -xrs, xrc);
|
||||
|
||||
matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
/*
|
||||
* xformpnt -
|
||||
* transform a 3D point using a matrix
|
||||
*/
|
||||
static void xformpnt(Mat3* matrix, float x, float y, float z, float* tx, float* ty, float* tz)
|
||||
{
|
||||
*tx = x * matrix->m[0] + y * matrix->m[3] + z * matrix->m[6];
|
||||
*ty = x * matrix->m[1] + y * matrix->m[4] + z * matrix->m[7];
|
||||
*tz = x * matrix->m[2] + y * matrix->m[5] + z * matrix->m[8];
|
||||
}
|
||||
|
||||
/*
|
||||
* zshear -
|
||||
* shear z using x and y.
|
||||
*/
|
||||
static void zshearmat(Mat3* mat, float dx, float dy)
|
||||
{
|
||||
// float mmat[4][4];
|
||||
Mat3 mmat;
|
||||
// mmat[0][0] = 1.0;
|
||||
// mmat[0][1] = 0.0;
|
||||
mmat.m[2] = dx;
|
||||
// mmat[0][3] = 0.0;
|
||||
|
||||
// mmat[1][0] = 0.0;
|
||||
// mmat[1][1] = 1.0;
|
||||
mmat.m[5] = dy;
|
||||
// mmat[1][3] = 0.0;
|
||||
|
||||
// mmat[2][0] = 0.0;
|
||||
// mmat[2][1] = 0.0;
|
||||
// mmat[2][2] = 1.0;
|
||||
// mmat[2][3] = 0.0;
|
||||
|
||||
// mmat[3][0] = 0.0;
|
||||
// mmat[3][1] = 0.0;
|
||||
// mmat[3][2] = 0.0;
|
||||
// mmat[3][3] = 1.0;
|
||||
mat->mult(mmat); // matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
static void createHueMatrix(Mat4* dst, float angle)
|
||||
{
|
||||
// log("************* createHueMatrix4f");
|
||||
|
||||
memcpy(dst, &dst->IDENTITY, sizeof(*dst));
|
||||
|
||||
/* rotate the grey vector into positive Z */
|
||||
createRotationX(dst, FLT_XRS, FLT_XRC); // rotateX(dst, FLT_XRS, FLT_XRC);
|
||||
rotateY(dst, FLT_YRS, FLT_YRC);
|
||||
|
||||
/* rotate the hue */
|
||||
rotateZ(dst, angle);
|
||||
|
||||
/* rotate the grey vector back into place */
|
||||
rotateY(dst, -FLT_YRS, FLT_YRC);
|
||||
rotateX(dst, -FLT_XRS, FLT_XRC);
|
||||
|
||||
// log("############## createHueMatrix4f");
|
||||
}
|
||||
|
||||
static void setMatrixHueOptimized(Mat3* dst, float angle)
|
||||
{
|
||||
float lx, ly, lz;
|
||||
float zsx, zsy;
|
||||
// memcpy(dst, &dst->IDENTITY, sizeof(*dst));
|
||||
|
||||
/* rotate the grey vector into positive Z */
|
||||
dst->createRotationX(FLT_XRS, FLT_XRC); // rotateX(dst, FLT_XRS, FLT_XRC);
|
||||
dst->rotateY(FLT_YRS, FLT_YRC);
|
||||
|
||||
/* shear the space to make the luminance plane horizontal */
|
||||
xformpnt(dst, RLUM, GLUM, BLUM, &lx, &ly, &lz);
|
||||
zsx = lx / lz;
|
||||
zsy = ly / lz;
|
||||
zshearmat(dst, zsx, zsy);
|
||||
|
||||
/* rotate the hue */
|
||||
dst->rotateZ(angle);
|
||||
|
||||
/* unshear the space to put the luminance plane back */
|
||||
zshearmat(dst, -zsx, -zsy);
|
||||
|
||||
/* rotate the grey vector back into place */
|
||||
dst->rotateY(-FLT_YRS, FLT_YRC);
|
||||
dst->rotateX(-FLT_XRS, FLT_XRC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hue -
|
||||
* HSV - H
|
||||
*/
|
||||
static void setMatrixHue(Mat3* dst, float angle)
|
||||
{
|
||||
log("************* createHueMat3");
|
||||
|
||||
// memcpy(dst, &dst->IDENTITY, sizeof(*dst));
|
||||
|
||||
/* rotate the grey vector into positive Z */
|
||||
dst->createRotationX(FLT_XRS, FLT_XRC); // rotateX(dst, FLT_XRS, FLT_XRC);
|
||||
dst->rotateY(FLT_YRS, FLT_YRC);
|
||||
|
||||
/* rotate the hue */
|
||||
dst->rotateZ(angle);
|
||||
|
||||
/* rotate the grey vector back into place */
|
||||
dst->rotateY(-FLT_YRS, FLT_YRC);
|
||||
dst->rotateX(-FLT_XRS, FLT_XRC);
|
||||
|
||||
log("############## createHueMat3");
|
||||
}
|
||||
|
||||
/*
|
||||
* saturatemat - 0~1, 0%~100% ?
|
||||
* HSV - S
|
||||
*/
|
||||
static void setMatrixSat(Mat3* dst, float sat)
|
||||
{
|
||||
Mat3 temp;
|
||||
float a, b, c, d, e, f, g, h, i;
|
||||
float rwgt, gwgt, bwgt;
|
||||
|
||||
rwgt = RLUM;
|
||||
gwgt = GLUM;
|
||||
bwgt = BLUM;
|
||||
|
||||
a = (1.0 - sat) * rwgt + sat;
|
||||
b = (1.0 - sat) * rwgt;
|
||||
c = (1.0 - sat) * rwgt;
|
||||
d = (1.0 - sat) * gwgt;
|
||||
e = (1.0 - sat) * gwgt + sat;
|
||||
f = (1.0 - sat) * gwgt;
|
||||
g = (1.0 - sat) * bwgt;
|
||||
h = (1.0 - sat) * bwgt;
|
||||
i = (1.0 - sat) * bwgt + sat;
|
||||
temp.m[0] = a;
|
||||
temp.m[1] = b;
|
||||
temp.m[2] = c;
|
||||
// mmat[0][3] = 0.0;
|
||||
|
||||
temp.m[3] = d;
|
||||
temp.m[4] = e;
|
||||
temp.m[5] = f;
|
||||
// mmat[1][3] = 0.0;
|
||||
|
||||
temp.m[6] = g;
|
||||
temp.m[7] = h;
|
||||
temp.m[8] = i;
|
||||
// mmat[2][3] = 0.0;
|
||||
|
||||
// mmat[3][0] = 0.0;
|
||||
// mmat[3][1] = 0.0;
|
||||
// mmat[3][2] = 0.0;
|
||||
// mmat[3][3] = 1.0;
|
||||
// matrixmult(mmat, mat, mat);
|
||||
dst->mult(temp);
|
||||
}
|
||||
|
||||
/* Value
|
||||
* HSV - V: 0~1, 0%, 100%
|
||||
*/
|
||||
static void setMatrixVal(Mat3* dst, float value)
|
||||
{
|
||||
// float mmat[4][4];
|
||||
Mat3 temp;
|
||||
temp.m[0] = value;
|
||||
// temp.m[1] = 0.0;
|
||||
// temp.m[2] = 0.0;
|
||||
// mmat[0][3] = 0.0;
|
||||
|
||||
// mmat[1][0] = 0.0;
|
||||
temp.m[4] = value;
|
||||
// mmat[1][2] = 0.0;
|
||||
// mmat[1][3] = 0.0;
|
||||
|
||||
// mmat[2][0] = 0.0;
|
||||
// mmat[2][1] = 0.0;
|
||||
temp.m[8] = value;
|
||||
// mmat[2][3] = 0.0;
|
||||
|
||||
dst->mult(temp);
|
||||
// matrixmult(mmat, mat, mat);
|
||||
}
|
||||
|
||||
bool Colorizer::enableNodeIntelliShading(Node* node, const Vec3& hsv, const Vec3& filter)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return false;
|
||||
|
||||
node->setProgramState(backend::ProgramType::HSV);
|
||||
|
||||
updateNodeHsv(node, hsv, filter);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Colorizer::updateNodeHsv(Node* node, const Vec3& hsv, const Vec3& filter)
|
||||
{
|
||||
Mat3 hsvMatrix;
|
||||
setMatrixHueOptimized(&hsvMatrix, hsv.x);
|
||||
setMatrixSat(&hsvMatrix, hsv.y);
|
||||
setMatrixVal(&hsvMatrix, hsv.z);
|
||||
|
||||
#if CLZ_PRINTMAT
|
||||
printmat3(hsvMatrix.m);
|
||||
#endif
|
||||
|
||||
auto programState = node->getProgramState();
|
||||
programState->setUniform(programState->getUniformLocation("u_mix_hsv"), &hsvMatrix.m[0], sizeof(hsvMatrix));
|
||||
programState->setUniform(programState->getUniformLocation("u_filter_rgb"), &filter, sizeof(filter));
|
||||
programState->hashOfUniforms();
|
||||
}
|
||||
|
||||
NS_AX_END
|
|
@ -1,23 +0,0 @@
|
|||
/**
|
||||
* CCColorizer, for color translate matrix
|
||||
* reference: http://graficaobscura.com/matrix/index.html
|
||||
* @autohr HALX99 2020
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef _CCCOLORIZER_H_
|
||||
# define _CCCOLORIZER_H_
|
||||
# include "math/Math.h"
|
||||
# include "base/Types.h"
|
||||
# include <string>
|
||||
|
||||
NS_AX_BEGIN
|
||||
class AX_DLL Colorizer
|
||||
{
|
||||
public:
|
||||
static bool enableNodeIntelliShading(Node* node, const Vec3& hsv, const Vec3& filter = Vec3(1.0f, 0.45f, 0.3109f));
|
||||
|
||||
static void updateNodeHsv(Node* node, const Vec3& hsv, const Vec3& filter = Vec3(1.0f, 0.45f, 0.3109f));
|
||||
};
|
||||
NS_AX_END
|
||||
|
||||
#endif
|
|
@ -367,24 +367,12 @@ bool Material::parseShader(Pass* pass, Properties* shaderProperties)
|
|||
// fragmentShader
|
||||
const char* fragShader = getOptionalString(shaderProperties, "fragmentShader", nullptr);
|
||||
|
||||
// compileTimeDefines
|
||||
const char* compileTimeDefines = getOptionalString(shaderProperties, "defines", "");
|
||||
|
||||
auto* fu = FileUtils::getInstance();
|
||||
// compileTimeDefines, since axmol-1.1 no longer support compile time defines
|
||||
// const char* compileTimeDefines = getOptionalString(shaderProperties, "defines", "");
|
||||
|
||||
if (vertShader && fragShader)
|
||||
{
|
||||
|
||||
auto vertShaderSrc = fu->getStringFromFile(vertShader);
|
||||
auto fragShaderSrc = fu->getStringFromFile(fragShader);
|
||||
|
||||
//since axmol-1.1 no longer support compile time defines
|
||||
//auto defs = replaceDefines(compileTimeDefines);
|
||||
|
||||
//vertShaderSrc = defs + "\n" + vertShaderSrc;
|
||||
//fragShaderSrc = defs + "\n" + fragShaderSrc;
|
||||
|
||||
auto* program = backend::Device::getInstance()->newProgram(vertShaderSrc, fragShaderSrc);
|
||||
auto program = ProgramManager::getInstance()->loadProgram(vertShader, fragShader);
|
||||
auto programState = new backend::ProgramState(program);
|
||||
pass->setProgramState(programState);
|
||||
|
||||
|
@ -410,8 +398,7 @@ bool Material::parseShader(Pass* pass, Properties* shaderProperties)
|
|||
}
|
||||
space = shaderProperties->getNextNamespace();
|
||||
}
|
||||
AX_SAFE_RELEASE(program);
|
||||
AX_SAFE_RELEASE(programState);
|
||||
programState->release();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -62,8 +62,8 @@ AX_DLL const std::string_view hsv_frag = "hsv_fs"sv;
|
|||
AX_DLL const std::string_view dualSampler_hsv_frag = "dualSampler_hsv_fs"sv;
|
||||
AX_DLL const std::string_view videoTextureYUY2_frag = "videoTextureYUY2_fs"sv;
|
||||
AX_DLL const std::string_view videoTextureNV12_frag = "videoTextureNV12_fs"sv;
|
||||
AX_DLL const std::string_view lineColor3D_frag = "lineColor3D_fs"sv;
|
||||
AX_DLL const std::string_view lineColor3D_vert = "lineColor3D_vs"sv;
|
||||
AX_DLL const std::string_view lineColor_frag = "lineColor_fs"sv;
|
||||
AX_DLL const std::string_view lineColor_vert = "lineColor_vs"sv;
|
||||
AX_DLL const std::string_view color_frag = "color_fs"sv;
|
||||
AX_DLL const std::string_view colorNormal_frag = "colorNormal_fs"sv;
|
||||
AX_DLL const std::string_view colorNormalTexture_frag = "colorNormalTexture_fs"sv;
|
||||
|
|
|
@ -75,8 +75,8 @@ extern AX_DLL const std::string_view videoTextureYUY2_frag;
|
|||
extern AX_DLL const std::string_view videoTextureNV12_frag;
|
||||
|
||||
/* below is 3d shaders */
|
||||
extern AX_DLL const std::string_view lineColor3D_frag;
|
||||
extern AX_DLL const std::string_view lineColor3D_vert;
|
||||
extern AX_DLL const std::string_view lineColor_frag;
|
||||
extern AX_DLL const std::string_view lineColor_vert;
|
||||
extern AX_DLL const std::string_view color_frag;
|
||||
extern AX_DLL const std::string_view colorNormal_frag;
|
||||
extern AX_DLL const std::string_view colorNormalTexture_frag;
|
||||
|
|
|
@ -53,15 +53,16 @@ void TrianglesCommand::init(float globalOrder,
|
|||
}
|
||||
_mv = mv;
|
||||
|
||||
auto programType = _pipelineDescriptor.programState->getProgram()->getProgramType();
|
||||
auto uniformID = _pipelineDescriptor.programState->hashOfUniforms();
|
||||
if (_programType != programType || _texture != texture->getBackendTexture() || _blendType != blendType ||
|
||||
_uniformID != uniformID)
|
||||
auto batchId = _pipelineDescriptor.programState->getBatchId();
|
||||
if (_batchId != batchId || _texture != texture->getBackendTexture() || _blendType != blendType)
|
||||
{
|
||||
_programType = programType;
|
||||
_texture = texture->getBackendTexture();
|
||||
_blendType = blendType;
|
||||
_uniformID = uniformID;
|
||||
_batchId = batchId;
|
||||
_texture = texture->getBackendTexture();
|
||||
_blendType = blendType;
|
||||
|
||||
// since it would be too expensive to check the uniforms, simplify enable batching for built-in program.
|
||||
// if (_programType == backend::ProgramType::CUSTOM_PROGRAM)
|
||||
// setSkipBatching(true);
|
||||
|
||||
// TODO: minggo set it in Node?
|
||||
auto& blendDescriptor = _pipelineDescriptor.blendDescriptor;
|
||||
|
@ -87,8 +88,7 @@ void TrianglesCommand::generateMaterialID()
|
|||
struct
|
||||
{
|
||||
void* texture;
|
||||
uint32_t programType;
|
||||
uint32_t uniformID;
|
||||
uint64_t batchId;
|
||||
backend::BlendFactor src;
|
||||
backend::BlendFactor dst;
|
||||
} hashMe;
|
||||
|
@ -98,12 +98,11 @@ void TrianglesCommand::generateMaterialID()
|
|||
// are set to random values by different compilers.
|
||||
memset(&hashMe, 0, sizeof(hashMe));
|
||||
|
||||
hashMe.texture = _texture;
|
||||
hashMe.src = _blendType.src;
|
||||
hashMe.dst = _blendType.dst;
|
||||
hashMe.programType = _programType;
|
||||
hashMe.uniformID = _uniformID;
|
||||
_materialID = XXH32((const void*)&hashMe, sizeof(hashMe), 0);
|
||||
hashMe.texture = _texture;
|
||||
hashMe.src = _blendType.src;
|
||||
hashMe.dst = _blendType.dst;
|
||||
hashMe.batchId = _batchId;
|
||||
_materialID = XXH32((const void*)&hashMe, sizeof(hashMe), 0);
|
||||
}
|
||||
|
||||
NS_AX_END
|
||||
|
|
|
@ -117,8 +117,7 @@ protected:
|
|||
|
||||
// Cached value to determine to generate material id or not.
|
||||
BlendFunc _blendType = BlendFunc::DISABLE;
|
||||
uint32_t _programType = backend::ProgramType::CUSTOM_PROGRAM;
|
||||
uint32_t _uniformID = 0;
|
||||
uint64_t _batchId = 0;
|
||||
backend::TextureBackend* _texture = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
@ -398,8 +398,9 @@ struct ProgramType
|
|||
BUILTIN_COUNT,
|
||||
|
||||
VIDEO_TEXTURE_RGB32 = POSITION_TEXTURE_COLOR,
|
||||
CUSTOM_PROGRAM = 0x1000, // user-define program, used by engine
|
||||
CUSTOM_PROGRAM = 0x1000, // user-define program, used by engine
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
NS_AX_BACKEND_END
|
||||
|
|
|
@ -28,6 +28,154 @@
|
|||
|
||||
NS_AX_BACKEND_BEGIN
|
||||
|
||||
|
||||
/*
|
||||
* shader vertex layout setup functions
|
||||
*/
|
||||
struct VertexLayoutHelper
|
||||
{
|
||||
static void setupDummy(Program*) {}
|
||||
static void setupTexture(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
|
||||
/// a_position
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT2, 0, false);
|
||||
/// a_texCoord
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_TEXCOORD,
|
||||
program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2, 2 * sizeof(float), false);
|
||||
|
||||
vertexLayout->setStride(4 * sizeof(float));
|
||||
}
|
||||
|
||||
static void setupSprite(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
|
||||
/// a_position
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT3, 0, false);
|
||||
/// a_texCoord
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_TEXCOORD,
|
||||
program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2, offsetof(V3F_C4B_T2F, texCoords), false);
|
||||
|
||||
/// a_color
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_COLOR,
|
||||
program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true);
|
||||
vertexLayout->setStride(sizeof(V3F_C4B_T2F));
|
||||
}
|
||||
|
||||
static void setupDrawNode(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT2, 0, false);
|
||||
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_TEXCOORD,
|
||||
program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2, offsetof(V2F_C4B_T2F, texCoords), false);
|
||||
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_COLOR,
|
||||
program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::UBYTE4, offsetof(V2F_C4B_T2F, colors), true);
|
||||
|
||||
vertexLayout->setStride(sizeof(V2F_C4B_T2F));
|
||||
}
|
||||
|
||||
static void setupDrawNode3D(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT3, 0, false);
|
||||
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_COLOR,
|
||||
program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::UBYTE4, sizeof(Vec3), true);
|
||||
|
||||
vertexLayout->setStride(sizeof(V3F_C4B));
|
||||
}
|
||||
|
||||
static void setupSkyBox(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
auto attrNameLoc = program->getAttributeLocation(shaderinfos::attribute::ATTRIBUTE_NAME_POSITION);
|
||||
vertexLayout->setAttrib(shaderinfos::attribute::ATTRIBUTE_NAME_POSITION, attrNameLoc,
|
||||
backend::VertexFormat::FLOAT3, 0, false);
|
||||
vertexLayout->setStride(sizeof(Vec3));
|
||||
}
|
||||
|
||||
static void setupPU3D(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT3, offsetof(V3F_T2F_C4F, position), false);
|
||||
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_TEXCOORD,
|
||||
program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2, offsetof(V3F_T2F_C4F, uv), false);
|
||||
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_COLOR,
|
||||
program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::FLOAT4, offsetof(V3F_T2F_C4F, color), false);
|
||||
|
||||
vertexLayout->setStride(sizeof(V3F_T2F_C4F));
|
||||
}
|
||||
|
||||
static void setupPos(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT2, 0, false);
|
||||
vertexLayout->setStride(sizeof(Vec2));
|
||||
}
|
||||
|
||||
static void setupPosColor(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT3, 0, false);
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_COLOR,
|
||||
program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::FLOAT4, offsetof(V3F_C4F, colors), false);
|
||||
vertexLayout->setStride(sizeof(V3F_C4F));
|
||||
}
|
||||
|
||||
static void setupTerrain3D(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT3, 0, false);
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_TEXCOORD,
|
||||
program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2, offsetof(V3F_T2F_N3F, texcoord), false);
|
||||
vertexLayout->setAttrib(backend::ATTRIBUTE_NAME_NORMAL,
|
||||
program->getAttributeLocation(backend::Attribute::NORMAL),
|
||||
backend::VertexFormat::FLOAT3, offsetof(V3F_T2F_N3F, normal), false);
|
||||
vertexLayout->setStride(sizeof(V3F_T2F_N3F));
|
||||
}
|
||||
};
|
||||
std::function<void(Program*)> Program::s_vertexLayoutSetupList[static_cast<int>(VertexLayoutType::Count)] = {
|
||||
VertexLayoutHelper::setupDummy, VertexLayoutHelper::setupPos, VertexLayoutHelper::setupTexture,
|
||||
VertexLayoutHelper::setupSprite, VertexLayoutHelper::setupDrawNode, VertexLayoutHelper::setupDrawNode3D,
|
||||
VertexLayoutHelper::setupSkyBox, VertexLayoutHelper::setupPU3D, VertexLayoutHelper::setupPosColor,
|
||||
VertexLayoutHelper::setupTerrain3D
|
||||
};
|
||||
|
||||
Program::Program(std::string_view vs, std::string_view fs)
|
||||
: _vertexShader(vs), _fragmentShader(fs), _vertexLayout(new VertexLayout())
|
||||
{}
|
||||
|
@ -36,9 +184,10 @@ Program::~Program() {
|
|||
delete _vertexLayout;
|
||||
}
|
||||
|
||||
void Program::setProgramType(uint32_t type)
|
||||
void Program::setupVertexLayout(VertexLayoutType vlt)
|
||||
{
|
||||
_programType = type;
|
||||
if (vlt < VertexLayoutType::Count)
|
||||
s_vertexLayoutSetupList[static_cast<int>(vlt)](this);
|
||||
}
|
||||
|
||||
Program* Program::getBuiltinProgram(uint32_t type)
|
||||
|
@ -46,4 +195,9 @@ Program* Program::getBuiltinProgram(uint32_t type)
|
|||
return ProgramManager::getInstance()->getBuiltinProgram(type);
|
||||
}
|
||||
|
||||
void Program::setProgramIds(uint32_t progType, uint64_t progId) {
|
||||
_programType = progType;
|
||||
_programId = progId;
|
||||
_batchEnabled = _programType != ProgramType::CUSTOM_PROGRAM;
|
||||
}
|
||||
NS_AX_BACKEND_END
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "Types.h"
|
||||
#include "ShaderCache.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
@ -40,6 +41,26 @@ class ShaderModule;
|
|||
class VertexLayout;
|
||||
class ProgramManager;
|
||||
|
||||
/**
|
||||
* @addtogroup _backend
|
||||
* @{
|
||||
*/
|
||||
|
||||
enum class VertexLayoutType
|
||||
{
|
||||
Unspec, // needs binding after program load
|
||||
Pos, // V2F
|
||||
Texture, // T2F
|
||||
Sprite, // V3F_C4B_T2F posTexColor
|
||||
DrawNode, // V2F_C4B_T2F
|
||||
DrawNode3D, // V3F_C4B
|
||||
SkyBox, // V3F
|
||||
PU3D, // V3F_C4B_T2F // same with sprite, TODO: reuse spriete
|
||||
posColor, // V3F_C4B
|
||||
Terrain3D, // V3F_T2F_V3F
|
||||
Count
|
||||
};
|
||||
|
||||
/**
|
||||
* @addtogroup _backend
|
||||
* @{
|
||||
|
@ -116,12 +137,23 @@ public:
|
|||
*/
|
||||
std::string_view getFragmentShader() const { return _fragmentShader; }
|
||||
|
||||
/**
|
||||
* Sets the program shared vertex layout type, see: VertexLayoutType
|
||||
*/
|
||||
void setupVertexLayout(VertexLayoutType vlt);
|
||||
|
||||
/**
|
||||
* Get engine built-in program type.
|
||||
* @return The built-in program type.
|
||||
*/
|
||||
uint32_t getProgramType() const { return _programType; }
|
||||
|
||||
/**
|
||||
* Get program id.
|
||||
* @return The program id.
|
||||
*/
|
||||
int64_t getProgramId() const { return _programId; }
|
||||
|
||||
/**
|
||||
* Get uniform buffer size in bytes that can hold all the uniforms.
|
||||
* @param stage Specifies the shader stage. The symbolic constant can be either VERTEX or FRAGMENT.
|
||||
|
@ -143,15 +175,18 @@ public:
|
|||
*/
|
||||
virtual const hlookup::string_map<UniformInfo>& getAllActiveUniformInfo(ShaderStage stage) const = 0;
|
||||
|
||||
/**
|
||||
* Set engin built-in program type.
|
||||
* @param type Specifies the program type.
|
||||
*/
|
||||
void setProgramType(uint32_t type);
|
||||
|
||||
inline VertexLayout* getVertexLayout() const { return _vertexLayout; }
|
||||
|
||||
/**
|
||||
* Sets batch draw enabled
|
||||
*/
|
||||
void setBatchDrawEnabled(bool enabled) { _batchEnabled = enabled; }
|
||||
bool isBatchEnabled() const { return _batchEnabled; }
|
||||
|
||||
protected:
|
||||
|
||||
void setProgramIds(uint32_t progType, uint64_t progId);
|
||||
|
||||
/**
|
||||
* @param vs Specifes the vertex shader source.
|
||||
* @param fs Specifes the fragment shader source.
|
||||
|
@ -192,6 +227,12 @@ protected:
|
|||
std::string _fragmentShader; ///< Fragment shader.
|
||||
VertexLayout* _vertexLayout = nullptr;
|
||||
uint32_t _programType = ProgramType::CUSTOM_PROGRAM; ///< built-in program type, initial value is CUSTOM_PROGRAM.
|
||||
uint64_t _programId = 0;
|
||||
bool _batchEnabled = false;
|
||||
|
||||
using VERTEX_LAYOUT_SETUP_FUNC = std::function<void(Program*)>;
|
||||
|
||||
static std::function<void(Program*)> s_vertexLayoutSetupList[static_cast<int>(VertexLayoutType::Count)];
|
||||
};
|
||||
|
||||
// end of _backend group
|
||||
|
|
|
@ -30,20 +30,12 @@
|
|||
#include "base/Macros.h"
|
||||
#include "base/Configuration.h"
|
||||
|
||||
#include "xxhash.h"
|
||||
|
||||
NS_AX_BACKEND_BEGIN
|
||||
|
||||
ProgramManager* ProgramManager::_sharedProgramManager = nullptr;
|
||||
|
||||
Program* ProgramManager::newProgram(std::string_view vertShaderSource,
|
||||
std::string_view fragShaderSource,
|
||||
std::function<void(Program*)> fnSetupLayout)
|
||||
{
|
||||
auto program = Device::getInstance()->newProgram(vertShaderSource, fragShaderSource);
|
||||
if (program)
|
||||
fnSetupLayout(program);
|
||||
return program;
|
||||
}
|
||||
|
||||
ProgramManager* ProgramManager::getInstance()
|
||||
{
|
||||
if (!_sharedProgramManager)
|
||||
|
@ -62,8 +54,15 @@ void ProgramManager::destroyInstance()
|
|||
AX_SAFE_RELEASE_NULL(_sharedProgramManager);
|
||||
}
|
||||
|
||||
ProgramManager::ProgramManager()
|
||||
{
|
||||
_programIdGen = XXH64_createState();
|
||||
}
|
||||
|
||||
ProgramManager::~ProgramManager()
|
||||
{
|
||||
XXH64_freeState(_programIdGen);
|
||||
|
||||
for (auto&& program : _cachedPrograms)
|
||||
{
|
||||
AX_SAFE_RELEASE(program.second);
|
||||
|
@ -72,139 +71,6 @@ ProgramManager::~ProgramManager()
|
|||
backend::ShaderCache::destroyInstance();
|
||||
}
|
||||
|
||||
/*
|
||||
* shader vertex layout setup functions
|
||||
*/
|
||||
void VertexLayoutHelper::setupDummy(Program*) {}
|
||||
void VertexLayoutHelper::setupTexture(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
|
||||
/// a_position
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT2, 0, false);
|
||||
/// a_texCoord
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_TEXCOORD,
|
||||
program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2, 2 * sizeof(float), false);
|
||||
|
||||
vertexLayout->setStride(4 * sizeof(float));
|
||||
}
|
||||
|
||||
void VertexLayoutHelper::setupSprite(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
|
||||
/// a_position
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT3, 0, false);
|
||||
/// a_texCoord
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_TEXCOORD,
|
||||
program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2, offsetof(V3F_C4B_T2F, texCoords), false);
|
||||
|
||||
/// a_color
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_COLOR, program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true);
|
||||
vertexLayout->setStride(sizeof(V3F_C4B_T2F));
|
||||
}
|
||||
|
||||
void VertexLayoutHelper::setupDrawNode(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT2, 0, false);
|
||||
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_TEXCOORD,
|
||||
program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2, offsetof(V2F_C4B_T2F, texCoords), false);
|
||||
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_COLOR, program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::UBYTE4, offsetof(V2F_C4B_T2F, colors), true);
|
||||
|
||||
vertexLayout->setStride(sizeof(V2F_C4B_T2F));
|
||||
}
|
||||
|
||||
void VertexLayoutHelper::setupDrawNode3D(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT3, 0, false);
|
||||
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_COLOR, program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::UBYTE4, sizeof(Vec3), true);
|
||||
|
||||
vertexLayout->setStride(sizeof(V3F_C4B));
|
||||
}
|
||||
|
||||
void VertexLayoutHelper::setupSkyBox(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
auto attrNameLoc = program->getAttributeLocation(shaderinfos::attribute::ATTRIBUTE_NAME_POSITION);
|
||||
vertexLayout->setAttribute(shaderinfos::attribute::ATTRIBUTE_NAME_POSITION, attrNameLoc,
|
||||
backend::VertexFormat::FLOAT3, 0, false);
|
||||
vertexLayout->setStride(sizeof(Vec3));
|
||||
}
|
||||
|
||||
void VertexLayoutHelper::setupPU3D(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT3, offsetof(V3F_T2F_C4F, position), false);
|
||||
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_TEXCOORD,
|
||||
program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2, offsetof(V3F_T2F_C4F, uv), false);
|
||||
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_COLOR, program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::FLOAT4, offsetof(V3F_T2F_C4F, color), false);
|
||||
|
||||
vertexLayout->setStride(sizeof(V3F_T2F_C4F));
|
||||
}
|
||||
|
||||
void VertexLayoutHelper::setupPos(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT2, 0, false);
|
||||
vertexLayout->setStride(sizeof(Vec2));
|
||||
}
|
||||
|
||||
void VertexLayoutHelper::setupPosColor(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT3, 0, false);
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_COLOR, program->getAttributeLocation(backend::Attribute::COLOR),
|
||||
backend::VertexFormat::FLOAT4, offsetof(V3F_C4F, colors), false);
|
||||
vertexLayout->setStride(sizeof(V3F_C4F));
|
||||
}
|
||||
|
||||
void VertexLayoutHelper::setupTerrain3D(Program* program)
|
||||
{
|
||||
auto vertexLayout = program->getVertexLayout();
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_POSITION,
|
||||
program->getAttributeLocation(backend::Attribute::POSITION),
|
||||
backend::VertexFormat::FLOAT3, 0, false);
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_TEXCOORD,
|
||||
program->getAttributeLocation(backend::Attribute::TEXCOORD),
|
||||
backend::VertexFormat::FLOAT2, offsetof(V3F_T2F_N3F, texcoord), false);
|
||||
vertexLayout->setAttribute(backend::ATTRIBUTE_NAME_NORMAL,
|
||||
program->getAttributeLocation(backend::Attribute::NORMAL), backend::VertexFormat::FLOAT3,
|
||||
offsetof(V3F_T2F_N3F, normal), false);
|
||||
vertexLayout->setStride(sizeof(V3F_T2F_N3F));
|
||||
}
|
||||
|
||||
// ### end of vertex layout setup functions
|
||||
static std::string joinPath(std::string_view path, std::string_view childPath)
|
||||
{
|
||||
|
@ -227,70 +93,62 @@ bool ProgramManager::init()
|
|||
#endif
|
||||
|
||||
registerProgram(ProgramType::POSITION_TEXTURE_COLOR, positionTextureColor_vert, positionTextureColor_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
registerProgram(ProgramType::DUAL_SAMPLER, positionTextureColor_vert, dualSampler_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::DUAL_SAMPLER, positionTextureColor_vert, dualSampler_frag, VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::LABEL_DISTANCE_NORMAL, positionTextureColor_vert, label_distanceNormal_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
registerProgram(ProgramType::LABEL_NORMAL, positionTextureColor_vert, label_normal_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::LABEL_NORMAL, positionTextureColor_vert, label_normal_frag, VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::LABLE_OUTLINE, positionTextureColor_vert, label_outline_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::LABEL_DISTANCE_OUTLINE, positionTextureColor_vert, label_distanceOutline_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::LABLE_DISTANCE_GLOW, positionTextureColor_vert, label_distanceGlow_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::POSITION_COLOR_LENGTH_TEXTURE, positionColorLengthTexture_vert,
|
||||
positionColorLengthTexture_frag, VertexLayoutHelper::setupDrawNode);
|
||||
positionColorLengthTexture_frag, VertexLayoutType::DrawNode);
|
||||
registerProgram(ProgramType::POSITION_COLOR_TEXTURE_AS_POINTSIZE, positionColorTextureAsPointsize_vert,
|
||||
positionColor_frag, VertexLayoutHelper::setupDrawNode);
|
||||
registerProgram(ProgramType::POSITION_COLOR, positionColor_vert, positionColor_frag,
|
||||
VertexLayoutHelper::setupPosColor);
|
||||
registerProgram(ProgramType::LAYER_RADIA_GRADIENT, position_vert, layer_radialGradient_frag,
|
||||
VertexLayoutHelper::setupPos);
|
||||
positionColor_frag, VertexLayoutType::DrawNode);
|
||||
registerProgram(ProgramType::POSITION_COLOR, positionColor_vert, positionColor_frag, VertexLayoutType::posColor);
|
||||
registerProgram(ProgramType::LAYER_RADIA_GRADIENT, position_vert, layer_radialGradient_frag, VertexLayoutType::Pos);
|
||||
registerProgram(ProgramType::POSITION_TEXTURE, positionTexture_vert, positionTexture_frag,
|
||||
VertexLayoutHelper::setupTexture);
|
||||
VertexLayoutType::Texture);
|
||||
registerProgram(ProgramType::POSITION_TEXTURE_COLOR_ALPHA_TEST, positionTextureColor_vert,
|
||||
positionTextureColorAlphaTest_frag, VertexLayoutHelper::setupSprite);
|
||||
registerProgram(ProgramType::POSITION_UCOLOR, positionUColor_vert, positionColor_frag,
|
||||
VertexLayoutHelper::setupPos);
|
||||
positionTextureColorAlphaTest_frag, VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::POSITION_UCOLOR, positionUColor_vert, positionColor_frag, VertexLayoutType::Pos);
|
||||
registerProgram(ProgramType::DUAL_SAMPLER_GRAY, positionTextureColor_vert, dualSampler_gray_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
registerProgram(ProgramType::GRAY_SCALE, positionTextureColor_vert, grayScale_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
registerProgram(ProgramType::LINE_COLOR_3D, lineColor3D_vert, lineColor3D_frag,
|
||||
VertexLayoutHelper::setupDrawNode3D);
|
||||
registerProgram(ProgramType::CAMERA_CLEAR, cameraClear_vert, cameraClear_frag, VertexLayoutHelper::setupSprite);
|
||||
registerProgram(ProgramType::SKYBOX_3D, skybox_vert, skybox_frag, VertexLayoutHelper::setupSkyBox);
|
||||
VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::GRAY_SCALE, positionTextureColor_vert, grayScale_frag, VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::LINE_COLOR_3D, lineColor_vert, lineColor_frag, VertexLayoutType::DrawNode3D);
|
||||
registerProgram(ProgramType::CAMERA_CLEAR, cameraClear_vert, cameraClear_frag, VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::SKYBOX_3D, skybox_vert, skybox_frag, VertexLayoutType::SkyBox);
|
||||
registerProgram(ProgramType::SKINPOSITION_TEXTURE_3D, skinPositionTexture_vert, colorTexture_frag,
|
||||
VertexLayoutHelper::setupDummy);
|
||||
VertexLayoutType::Unspec);
|
||||
registerProgram(ProgramType::SKINPOSITION_NORMAL_TEXTURE_3D, skinPositionNormalTexture_vert,
|
||||
colorNormalTexture_frag, VertexLayoutHelper::setupDummy);
|
||||
colorNormalTexture_frag, VertexLayoutType::Unspec);
|
||||
registerProgram(ProgramType::POSITION_NORMAL_TEXTURE_3D, positionNormalTexture_vert, colorNormalTexture_frag,
|
||||
VertexLayoutHelper::setupDummy);
|
||||
VertexLayoutType::Unspec);
|
||||
registerProgram(ProgramType::POSITION_TEXTURE_3D, positionTexture3D_vert, colorTexture_frag,
|
||||
VertexLayoutHelper::setupDummy);
|
||||
registerProgram(ProgramType::POSITION_3D, positionTexture3D_vert, color_frag, VertexLayoutHelper::setupSprite);
|
||||
VertexLayoutType::Unspec);
|
||||
registerProgram(ProgramType::POSITION_3D, positionTexture3D_vert, color_frag, VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::POSITION_NORMAL_3D, positionNormalTexture_vert, colorNormal_frag,
|
||||
VertexLayoutHelper::setupDummy);
|
||||
VertexLayoutType::Unspec);
|
||||
registerProgram(ProgramType::POSITION_BUMPEDNORMAL_TEXTURE_3D, positionNormalTexture_vert_1,
|
||||
colorNormalTexture_frag_1, VertexLayoutHelper::setupDummy);
|
||||
colorNormalTexture_frag_1, VertexLayoutType::Unspec);
|
||||
registerProgram(ProgramType::SKINPOSITION_BUMPEDNORMAL_TEXTURE_3D, skinPositionNormalTexture_vert_1,
|
||||
colorNormalTexture_frag_1, VertexLayoutHelper::setupDummy);
|
||||
registerProgram(ProgramType::TERRAIN_3D, terrain_vert, terrain_frag, VertexLayoutHelper::setupTerrain3D);
|
||||
registerProgram(ProgramType::PARTICLE_TEXTURE_3D, particle_vert, particleTexture_frag,
|
||||
VertexLayoutHelper::setupPU3D);
|
||||
registerProgram(ProgramType::PARTICLE_COLOR_3D, particle_vert, particleColor_frag, VertexLayoutHelper::setupPU3D);
|
||||
registerProgram(ProgramType::QUAD_COLOR_2D, quadColor_vert, quadColor_frag, VertexLayoutHelper::setupDummy);
|
||||
registerProgram(ProgramType::QUAD_TEXTURE_2D, quadTexture_vert, quadTexture_frag, VertexLayoutHelper::setupDummy);
|
||||
registerProgram(ProgramType::HSV, positionTextureColor_vert, hsv_frag, VertexLayoutHelper::setupSprite);
|
||||
colorNormalTexture_frag_1, VertexLayoutType::Unspec);
|
||||
registerProgram(ProgramType::TERRAIN_3D, terrain_vert, terrain_frag, VertexLayoutType::Terrain3D);
|
||||
registerProgram(ProgramType::PARTICLE_TEXTURE_3D, particle_vert, particleTexture_frag, VertexLayoutType::PU3D);
|
||||
registerProgram(ProgramType::PARTICLE_COLOR_3D, particle_vert, particleColor_frag, VertexLayoutType::PU3D);
|
||||
registerProgram(ProgramType::QUAD_COLOR_2D, quadColor_vert, quadColor_frag, VertexLayoutType::Unspec);
|
||||
registerProgram(ProgramType::QUAD_TEXTURE_2D, quadTexture_vert, quadTexture_frag, VertexLayoutType::Unspec);
|
||||
registerProgram(ProgramType::HSV, positionTextureColor_vert, hsv_frag, VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::HSV_DUAL_SAMPLER, positionTextureColor_vert, dualSampler_hsv_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
VertexLayoutType::Sprite);
|
||||
|
||||
registerProgram(ProgramType::VIDEO_TEXTURE_YUY2, positionTextureColor_vert, videoTextureYUY2_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
VertexLayoutType::Sprite);
|
||||
registerProgram(ProgramType::VIDEO_TEXTURE_NV12, positionTextureColor_vert, videoTextureNV12_frag,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
VertexLayoutType::Sprite);
|
||||
|
||||
// The builtin dual sampler shader registry
|
||||
ProgramStateRegistry::getInstance()->registerProgram(ProgramType::POSITION_TEXTURE_COLOR,
|
||||
|
@ -304,111 +162,117 @@ bool ProgramManager::init()
|
|||
return true;
|
||||
}
|
||||
|
||||
Program* ProgramManager::getCustomProgram(uint32_t type) const
|
||||
Program* ProgramManager::getBuiltinProgram(uint32_t type)
|
||||
{
|
||||
return getBuiltinProgram(type | ProgramType::CUSTOM_PROGRAM);
|
||||
assert(type < ProgramType::BUILTIN_COUNT);
|
||||
|
||||
auto& info = _builtinRegistry[static_cast<int>(type)];
|
||||
return loadProgram(info.vsName, info.fsName, type, static_cast<uint64_t>(type), info.vlt);
|
||||
}
|
||||
|
||||
Program* ProgramManager::getBuiltinProgram(uint32_t type) const
|
||||
Program* ProgramManager::loadProgram(uint64_t progId)
|
||||
{
|
||||
auto iter = _cachedPrograms.find(type);
|
||||
if (iter != _cachedPrograms.end())
|
||||
return iter->second;
|
||||
if (progId < ProgramType::BUILTIN_COUNT)
|
||||
return getBuiltinProgram(static_cast<uint32_t>(progId));
|
||||
|
||||
return addProgram(type);
|
||||
auto it = _customRegistry.find(progId);
|
||||
if (it != _customRegistry.end())
|
||||
return loadProgram(it->second.vsName, it->second.fsName, ProgramType::CUSTOM_PROGRAM, progId, it->second.vlt);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Program* ProgramManager::addProgram(uint32_t internalType) const
|
||||
Program* ProgramManager::loadProgram(std::string_view vsName, std::string_view fsName, VertexLayoutType vlt)
|
||||
{
|
||||
Program* program = nullptr;
|
||||
if (internalType < ProgramType::BUILTIN_COUNT)
|
||||
{
|
||||
auto& func = _builtinRegistry[internalType];
|
||||
if (func)
|
||||
program = func();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto iter = _customRegistry.find(internalType);
|
||||
if (iter != _customRegistry.end())
|
||||
{
|
||||
auto& func = iter->second;
|
||||
if (func)
|
||||
program = func();
|
||||
}
|
||||
}
|
||||
return loadProgram(vsName, fsName, ProgramType::CUSTOM_PROGRAM, computeProgramId(vsName, fsName), vlt);
|
||||
}
|
||||
|
||||
Program* ProgramManager::loadProgram(std::string_view vsName,
|
||||
std::string_view fsName,
|
||||
uint32_t progType,
|
||||
uint64_t progId,
|
||||
VertexLayoutType vlt)
|
||||
{
|
||||
assert(!vsName.empty() && !fsName.empty());
|
||||
|
||||
auto it = _cachedPrograms.find(progId);
|
||||
if (it != _cachedPrograms.end())
|
||||
return it->second;
|
||||
|
||||
auto fileUtils = FileUtils::getInstance();
|
||||
auto vertFile = fileUtils->fullPathForFilename(vsName);
|
||||
auto fragFile = fileUtils->fullPathForFilename(fsName);
|
||||
auto vertSource = fileUtils->getStringFromFile(vertFile);
|
||||
auto fragSource = fileUtils->getStringFromFile(fragFile);
|
||||
auto program = backend::Device::getInstance()->newProgram(vertSource, fragSource);
|
||||
|
||||
if (program)
|
||||
{
|
||||
program->setProgramType(internalType);
|
||||
_cachedPrograms.emplace(internalType, program);
|
||||
program->setProgramIds(progType, progId);
|
||||
if (vlt < VertexLayoutType::Count)
|
||||
program->setupVertexLayout(vlt);
|
||||
_cachedPrograms.emplace(progId, program);
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
bool ProgramManager::registerCustomProgram(uint32_t type,
|
||||
std::string_view vsName,
|
||||
std::string_view fsName,
|
||||
std::function<void(Program*)> fnSetupLayout, bool force)
|
||||
uint64_t ProgramManager::registerCustomProgram(std::string_view vsName,
|
||||
std::string_view fsName,
|
||||
VertexLayoutType vlt,
|
||||
bool force)
|
||||
{
|
||||
auto internalType = ProgramType::CUSTOM_PROGRAM | type;
|
||||
return registerProgram(internalType, vsName, fsName, std::move(fnSetupLayout), force);
|
||||
return registerProgram(ProgramType::CUSTOM_PROGRAM, vsName, fsName, vlt, force);
|
||||
}
|
||||
|
||||
bool ProgramManager::registerProgram(uint32_t internalType,
|
||||
std::string_view vertShaderName,
|
||||
std::string_view fragShaderName,
|
||||
std::function<void(Program*)> fnSetupLayout,
|
||||
bool force)
|
||||
uint64_t ProgramManager::registerProgram(uint32_t progType,
|
||||
std::string_view vsName,
|
||||
std::string_view fsName,
|
||||
VertexLayoutType vlt,
|
||||
bool force)
|
||||
{
|
||||
auto loadShaderFunc = [vsName = std::string{vertShaderName}, fsName = std::string{fragShaderName},
|
||||
setupLayout = std::move(fnSetupLayout)]() mutable {
|
||||
auto fileUtils = FileUtils::getInstance();
|
||||
auto vertFile = fileUtils->fullPathForFilename(vsName);
|
||||
auto fragFile = fileUtils->fullPathForFilename(fsName);
|
||||
auto vertSource = fileUtils->getStringFromFile(vertFile);
|
||||
auto fragSource = fileUtils->getStringFromFile(fragFile);
|
||||
auto program = backend::Device::getInstance()->newProgram(vertSource, fragSource);
|
||||
setupLayout(program);
|
||||
return program;
|
||||
};
|
||||
|
||||
bool ret = true;
|
||||
if (internalType < ProgramType::BUILTIN_COUNT)
|
||||
_builtinRegistry[internalType] = loadShaderFunc;
|
||||
uint64_t progId = 0;
|
||||
if (progType < ProgramType::BUILTIN_COUNT)
|
||||
{
|
||||
_builtinRegistry[static_cast<int>(progType)] = {vsName, fsName, vlt};
|
||||
progId = progType;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = _customRegistry.find(internalType);
|
||||
progId = computeProgramId(vsName, fsName);
|
||||
auto it = _customRegistry.find(progId);
|
||||
if (it == _customRegistry.end())
|
||||
_customRegistry.emplace(internalType, loadShaderFunc);
|
||||
else if (ret = force)
|
||||
it->second = loadShaderFunc;
|
||||
_customRegistry.emplace(progId, BuiltinRegInfo{vsName, fsName, vlt});
|
||||
else if (force)
|
||||
it->second = BuiltinRegInfo{vsName, fsName, vlt};
|
||||
else
|
||||
progId = 0;
|
||||
}
|
||||
return ret;
|
||||
return progId;
|
||||
}
|
||||
|
||||
void ProgramManager::removeProgram(Program* program)
|
||||
uint64_t ProgramManager::computeProgramId(std::string_view vsName, std::string_view fsName)
|
||||
{
|
||||
XXH64_reset(_programIdGen, 0);
|
||||
XXH64_update(_programIdGen, vsName.data(), vsName.length());
|
||||
XXH64_update(_programIdGen, fsName.data(), fsName.length());
|
||||
return XXH64_digest(_programIdGen);
|
||||
}
|
||||
|
||||
void ProgramManager::unloadProgram(Program* program)
|
||||
{
|
||||
if (!program)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = _cachedPrograms.cbegin(); it != _cachedPrograms.cend();)
|
||||
auto it = _cachedPrograms.find(program->_programId);
|
||||
if (it != _cachedPrograms.end())
|
||||
{
|
||||
if (it->second == program)
|
||||
{
|
||||
it->second->release();
|
||||
it = _cachedPrograms.erase(it);
|
||||
break;
|
||||
}
|
||||
else
|
||||
++it;
|
||||
it->second->release();
|
||||
_cachedPrograms.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void ProgramManager::removeUnusedProgram()
|
||||
void ProgramManager::unloadUnusedPrograms()
|
||||
{
|
||||
for (auto iter = _cachedPrograms.cbegin(); iter != _cachedPrograms.cend();)
|
||||
{
|
||||
|
@ -426,7 +290,7 @@ void ProgramManager::removeUnusedProgram()
|
|||
}
|
||||
}
|
||||
|
||||
void ProgramManager::removeAllPrograms()
|
||||
void ProgramManager::unloadAllPrograms()
|
||||
{
|
||||
ProgramStateRegistry::getInstance()->clearPrograms();
|
||||
for (auto&& program : _cachedPrograms)
|
||||
|
|
|
@ -32,40 +32,23 @@
|
|||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <string_view>
|
||||
#include "ProgramStateRegistry.h"
|
||||
|
||||
struct XXH64_state_s;
|
||||
|
||||
NS_AX_BACKEND_BEGIN
|
||||
/**
|
||||
* @addtogroup _backend
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct AX_DLL VertexLayoutHelper
|
||||
{
|
||||
static void setupDummy(Program*);
|
||||
static void setupPos(Program*);
|
||||
static void setupTexture(Program*);
|
||||
static void setupSprite(Program*);
|
||||
static void setupDrawNode(Program*);
|
||||
static void setupDrawNode3D(Program*);
|
||||
static void setupSkyBox(Program*);
|
||||
static void setupPU3D(Program*);
|
||||
static void setupPosColor(Program*);
|
||||
static void setupTerrain3D(Program*);
|
||||
};
|
||||
|
||||
/**
|
||||
* Cache and reuse program object.
|
||||
*/
|
||||
class AX_DLL ProgramManager : public Ref
|
||||
{
|
||||
public:
|
||||
/** new progrma with vertexLayout setup support, user should use this API */
|
||||
static Program* newProgram(std::string_view vertShaderSource,
|
||||
std::string_view fragShaderSource,
|
||||
std::function<void(Program*)> fnSetupLayout = VertexLayoutHelper::setupDummy);
|
||||
|
||||
/** returns the shared instance */
|
||||
static ProgramManager* getInstance();
|
||||
|
||||
|
@ -73,36 +56,73 @@ public:
|
|||
static void destroyInstance();
|
||||
|
||||
/// get built-in program
|
||||
Program* getBuiltinProgram(uint32_t type) const;
|
||||
Program* getBuiltinProgram(uint32_t type);
|
||||
|
||||
// get custom program, should call registerCustomProgram first
|
||||
Program* getCustomProgram(uint32_t type) const;
|
||||
/*
|
||||
* register a custom program
|
||||
* @returns
|
||||
* the id of custom program, 0: fail, the id can use by loadProgram
|
||||
*/
|
||||
uint64_t registerCustomProgram(std::string_view vsName,
|
||||
std::string_view fsName,
|
||||
VertexLayoutType vlt = VertexLayoutType::Unspec,
|
||||
bool force = false);
|
||||
|
||||
// register custom program create factory, if custom programType already registered, will failed
|
||||
bool registerCustomProgram(uint32_t type,
|
||||
std::string_view vsName,
|
||||
std::string_view fsName,
|
||||
std::function<void(Program*)> fnSetupLayout = VertexLayoutHelper::setupDummy,
|
||||
bool force = false);
|
||||
/*
|
||||
* load a builtin/or custom program:
|
||||
* @param id: the id of program to load, the id value returned by registerCustomProgram
|
||||
* or builtin programType, whe the id < ProgramType:BUILTIN_COUNT, this function
|
||||
* is identical to 'getBuiltinProgram'
|
||||
*/
|
||||
Program* loadProgram(uint64_t progId);
|
||||
|
||||
/*
|
||||
* load a program with vsName, fsName as CUSTOM immediately without register
|
||||
* @params
|
||||
* @param vsName: the vertex shader name: custom/xxx_vs
|
||||
* @param fsName: the fragment shader name: custom/xxx_vs
|
||||
* @param vlt: the builtin vertex layout type used for loading program
|
||||
* @returns Program* (nullable)
|
||||
* @remark: the returend program type always ProgramType::CUSTOM_PROGRAM
|
||||
*/
|
||||
Program* loadProgram(std::string_view vsName,
|
||||
std::string_view fsName,
|
||||
VertexLayoutType vlt = VertexLayoutType::Unspec);
|
||||
|
||||
/**
|
||||
* Unload a program object from cache.
|
||||
* @param program Specifies the program object to move.
|
||||
*/
|
||||
void unloadProgram(Program* program);
|
||||
|
||||
/**
|
||||
* Unload all unused program objects from cache.
|
||||
*/
|
||||
void unloadUnusedPrograms();
|
||||
|
||||
/**
|
||||
* Unload all program objects from cache.
|
||||
*/
|
||||
void unloadAllPrograms();
|
||||
|
||||
/**
|
||||
* Remove a program object from cache.
|
||||
* @param program Specifies the program object to move.
|
||||
*/
|
||||
void removeProgram(Program* program);
|
||||
AX_DEPRECATED_ATTRIBUTE void removeProgram(Program* prog) { unloadProgram(prog); }
|
||||
|
||||
/**
|
||||
* Remove all unused program objects from cache.
|
||||
*/
|
||||
void removeUnusedProgram();
|
||||
AX_DEPRECATED_ATTRIBUTE void removeUnusedProgram() { unloadUnusedPrograms(); }
|
||||
|
||||
/**
|
||||
* Remove all program objects from cache.
|
||||
*/
|
||||
void removeAllPrograms();
|
||||
AX_DEPRECATED_ATTRIBUTE void removeAllPrograms() { unloadAllPrograms(); }
|
||||
|
||||
protected:
|
||||
ProgramManager() = default;
|
||||
ProgramManager();
|
||||
virtual ~ProgramManager();
|
||||
|
||||
/**
|
||||
|
@ -110,18 +130,41 @@ protected:
|
|||
*/
|
||||
bool init();
|
||||
|
||||
bool registerProgram(uint32_t internalType,
|
||||
std::string_view vsName,
|
||||
std::string_view fsName,
|
||||
std::function<void(Program*)> fnSetupLayout,
|
||||
bool force = false);
|
||||
Program* addProgram(uint32_t internalType) const;
|
||||
/**
|
||||
* register a program
|
||||
*/
|
||||
uint64_t registerProgram(uint32_t progType,
|
||||
std::string_view vsName,
|
||||
std::string_view fsName,
|
||||
VertexLayoutType vlt,
|
||||
bool force = false);
|
||||
|
||||
std::function<Program*()> _builtinRegistry[(int)backend::ProgramType::BUILTIN_COUNT];
|
||||
std::unordered_map<uint32_t, std::function<Program*()>> _customRegistry;
|
||||
/**
|
||||
* load a custom program by vsName, fsName, vertexLayout
|
||||
*/
|
||||
Program* loadProgram(std::string_view vsName,
|
||||
std::string_view fsName,
|
||||
uint32_t progType,
|
||||
uint64_t progId,
|
||||
VertexLayoutType vlt);
|
||||
|
||||
mutable std::unordered_map<uint32_t, Program*> _cachedPrograms; ///< The cached program object.
|
||||
static ProgramManager* _sharedProgramManager; ///< A shared instance of the program cache.
|
||||
uint64_t computeProgramId(std::string_view vsName, std::string_view fsName);
|
||||
|
||||
struct BuiltinRegInfo
|
||||
{ // builtin shader name is literal string, so use std::string_view ok
|
||||
std::string_view vsName;
|
||||
std::string_view fsName;
|
||||
VertexLayoutType vlt;
|
||||
};
|
||||
|
||||
BuiltinRegInfo _builtinRegistry[(int)backend::ProgramType::BUILTIN_COUNT];
|
||||
std::unordered_map<int64_t, BuiltinRegInfo> _customRegistry;
|
||||
|
||||
std::unordered_map<int64_t, Program*> _cachedPrograms; ///< The cached program object.
|
||||
|
||||
XXH64_state_s* _programIdGen;
|
||||
|
||||
static ProgramManager* _sharedProgramManager; ///< A shared instance of the program cache.
|
||||
};
|
||||
|
||||
using ProgramCache = ProgramManager; // for compatible
|
||||
|
@ -136,11 +179,12 @@ NS_AX_BACKEND_END
|
|||
|
||||
NS_AX_BEGIN
|
||||
|
||||
using ProgramType = ::ax::backend::ProgramType;
|
||||
using Program = ::ax::backend::Program;
|
||||
using VertexLayout = ::ax::backend::VertexLayout;
|
||||
using VertexLayoutHelper = ::ax::backend::VertexLayoutHelper;
|
||||
using ProgramManager = ::ax::backend::ProgramManager;
|
||||
using ProgramRegistry = ::ax::backend::ProgramStateRegistry;
|
||||
using ProgramType = ::ax::backend::ProgramType;
|
||||
using ProgramState = ::ax::backend::ProgramState;
|
||||
using Program = ::ax::backend::Program;
|
||||
using VertexLayout = ::ax::backend::VertexLayout;
|
||||
using VertexLayoutType = ::ax::backend::VertexLayoutType;
|
||||
using ProgramManager = ::ax::backend::ProgramManager;
|
||||
using ProgramRegistry = ::ax::backend::ProgramStateRegistry;
|
||||
|
||||
NS_AX_END
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "base/Director.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include "xxhash.h"
|
||||
#include "glslcc/sgs-spec.h"
|
||||
|
||||
NS_AX_BACKEND_BEGIN
|
||||
|
@ -204,9 +203,18 @@ bool ProgramState::init(Program* program)
|
|||
EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*) { this->resetUniforms(); });
|
||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, -1);
|
||||
#endif
|
||||
|
||||
updateBatchId();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProgramState::updateBatchId()
|
||||
{
|
||||
_batchId = _program->isBatchEnabled() ? _program->getProgramId()
|
||||
: static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
|
||||
void ProgramState::resetUniforms()
|
||||
{
|
||||
#if AX_ENABLE_CACHE_TEXTURE_DATA
|
||||
|
@ -257,7 +265,7 @@ ProgramState* ProgramState::clone() const
|
|||
#ifdef AX_USE_METAL
|
||||
memcpy(cp->_fragmentUniformBuffer, _fragmentUniformBuffer, _fragmentUniformBufferSize);
|
||||
#endif
|
||||
cp->_uniformID = _uniformID;
|
||||
cp->_batchId = this->_batchId;
|
||||
return cp;
|
||||
}
|
||||
|
||||
|
@ -392,8 +400,6 @@ void ProgramState::setVertexUniform(int location, const void* data, std::size_t
|
|||
assert(location + offset + size <= _vertexUniformBufferSize);
|
||||
memcpy(_vertexUniformBuffer + location + offset, data, size);
|
||||
#endif
|
||||
|
||||
_uniformDirty = true;
|
||||
}
|
||||
|
||||
void ProgramState::setFragmentUniform(int location, const void* data, std::size_t size)
|
||||
|
@ -426,7 +432,7 @@ void ProgramState::setVertexAttrib(std::string_view name,
|
|||
{
|
||||
ensureVertexLayoutMutable();
|
||||
|
||||
_vertexLayout->setAttribute(name, index, format, offset, needToBeNormallized);
|
||||
_vertexLayout->setAttrib(name, index, format, offset, needToBeNormallized);
|
||||
}
|
||||
|
||||
void ProgramState::setVertexStride(uint32_t stride)
|
||||
|
@ -435,16 +441,10 @@ void ProgramState::setVertexStride(uint32_t stride)
|
|||
_vertexLayout->setStride(stride);
|
||||
}
|
||||
|
||||
void ProgramState::setVertexLayout(const VertexLayout& vertexLayout)
|
||||
{
|
||||
ensureVertexLayoutMutable();
|
||||
*_vertexLayout = vertexLayout;
|
||||
}
|
||||
|
||||
void ProgramState::validateSharedVertexLayout(std::function<void(Program*)> fnValidate)
|
||||
void ProgramState::validateSharedVertexLayout(VertexLayoutType vlt)
|
||||
{
|
||||
if (!_ownVertexLayout && !_vertexLayout->isValid())
|
||||
fnValidate(_program);
|
||||
_program->setupVertexLayout(vlt);
|
||||
}
|
||||
|
||||
void ProgramState::ensureVertexLayoutMutable()
|
||||
|
@ -456,22 +456,21 @@ void ProgramState::ensureVertexLayoutMutable()
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t ProgramState::hashOfUniforms()
|
||||
VertexLayout* ProgramState::getMutableVertexLayout()
|
||||
{
|
||||
if (!_uniformDirty)
|
||||
return _uniformID;
|
||||
if (_ownVertexLayout || !_vertexLayout->isValid())
|
||||
return _vertexLayout;
|
||||
|
||||
_uniformDirty = false;
|
||||
#ifdef AX_USE_METAL
|
||||
XXH32_reset(_uniformHashState, 0);
|
||||
XXH32_update(_uniformHashState, _vertexUniformBuffer, _vertexUniformBufferSize);
|
||||
XXH32_update(_uniformHashState, _fragmentUniformBuffer, _fragmentUniformBufferSize);
|
||||
_uniformID = XXH32_digest(_uniformHashState);
|
||||
#else
|
||||
_uniformID = XXH32(_vertexUniformBuffer, _vertexUniformBufferSize, 0);
|
||||
#endif
|
||||
_ownVertexLayout = true;
|
||||
return _vertexLayout = new VertexLayout();
|
||||
}
|
||||
|
||||
return _uniformID;
|
||||
void ProgramState::setSharedVertexLayout(VertexLayout* vertexLayout)
|
||||
{
|
||||
if (_ownVertexLayout)
|
||||
delete _vertexLayout;
|
||||
_ownVertexLayout = false;
|
||||
_vertexLayout = vertexLayout;
|
||||
}
|
||||
|
||||
void ProgramState::setTexture(backend::TextureBackend* texture)
|
||||
|
|
|
@ -294,32 +294,38 @@ public:
|
|||
|
||||
inline const VertexLayout* getVertexLayout() const { return _vertexLayout; }
|
||||
|
||||
VertexLayout* getMutableVertexLayout();
|
||||
|
||||
/**
|
||||
* Updates uniformID, it's part of materialID for batch draw
|
||||
* @param uniformID if not -1, will compute with uniform buffer by XXH32 algorithm and should call
|
||||
* this function after any unstable uniforms set
|
||||
* @remark If your custom shader uniform not stable, you needs call this function to update uniformID for
|
||||
* render to generate a different materialID
|
||||
void setSharedVertexLayout(VertexLayout* vertexLayout);
|
||||
|
||||
/*
|
||||
* Gets batch id of current program state, part of batch draw materialID
|
||||
*/
|
||||
uint64_t getBatchId() const { return _batchId; };
|
||||
|
||||
/*
|
||||
* Update batchID of current program state, by default, custom program was traits with mutable uniforms
|
||||
* so batch ID was set to address of valid ProgramState object
|
||||
* If your programState not volatile, you can invoke this API to set with your custom ProgramId prog->getProgramId()
|
||||
*/
|
||||
void updateBatchId();
|
||||
|
||||
/*
|
||||
* Follow API is deprecated, use getMutableVertexLayout instead
|
||||
*/
|
||||
uint32_t hashOfUniforms();
|
||||
|
||||
void setVertexAttrib(std::string_view name,
|
||||
std::size_t index,
|
||||
VertexFormat format,
|
||||
std::size_t offset,
|
||||
bool needToBeNormallized);
|
||||
void setVertexStride(uint32_t stride);
|
||||
|
||||
void setVertexLayout(const VertexLayout& vertexLayout);
|
||||
AX_DEPRECATED_ATTRIBUTE void setVertexAttrib(std::string_view name,
|
||||
std::size_t index,
|
||||
VertexFormat format,
|
||||
std::size_t offset,
|
||||
bool needToBeNormallized);
|
||||
AX_DEPRECATED_ATTRIBUTE void setVertexStride(uint32_t stride);
|
||||
|
||||
/** Custom shader program's vertex layout maybe not setup
|
||||
* so engine specific render node(such as Sprite) should invoke this API when ProgramState changed
|
||||
*/
|
||||
void validateSharedVertexLayout(std::function <void(Program*)> fnValidate);
|
||||
void validateSharedVertexLayout(VertexLayoutType);
|
||||
|
||||
protected:
|
||||
|
||||
void ensureVertexLayoutMutable();
|
||||
|
||||
/**
|
||||
|
@ -406,13 +412,9 @@ protected:
|
|||
|
||||
static std::vector<AutoBindingResolver*> _customAutoBindingResolvers;
|
||||
VertexLayout* _vertexLayout = nullptr;
|
||||
bool _ownVertexLayout = false;
|
||||
bool _ownVertexLayout = false;
|
||||
|
||||
uint32_t _uniformID = 0;
|
||||
bool _uniformDirty = false;
|
||||
#ifdef AX_USE_METAL
|
||||
struct XXH32_state_s* _uniformHashState = nullptr;
|
||||
#endif
|
||||
uint64_t _batchId = 0;
|
||||
|
||||
#if AX_ENABLE_CACHE_TEXTURE_DATA
|
||||
EventListenerCustom* _backToForegroundListener = nullptr;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
NS_AX_BACKEND_BEGIN
|
||||
|
||||
void VertexLayout::setAttribute(std::string_view name,
|
||||
void VertexLayout::setAttrib(std::string_view name,
|
||||
std::size_t index,
|
||||
VertexFormat format,
|
||||
std::size_t offset,
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
bool needToBeNormallized = false;
|
||||
};
|
||||
|
||||
VertexLayout() = default;
|
||||
VertexLayout() = default;
|
||||
VertexLayout(const VertexLayout&) = default;
|
||||
|
||||
/**
|
||||
|
@ -75,11 +75,20 @@ public:
|
|||
* @param needToBeNormallized Specifies whether fixed-point data values should be normalized (true) or converted
|
||||
* directly as fixed-point values (false) when they are accessed.
|
||||
*/
|
||||
void setAttribute(std::string_view name,
|
||||
void setAttrib(std::string_view name,
|
||||
std::size_t index,
|
||||
VertexFormat format,
|
||||
std::size_t offset,
|
||||
bool needNormalized);
|
||||
|
||||
AX_DEPRECATED_ATTRIBUTE void setAttribute(std::string_view name,
|
||||
std::size_t index,
|
||||
VertexFormat format,
|
||||
std::size_t offset,
|
||||
bool needToBeNormallized);
|
||||
bool needNormalized)
|
||||
{
|
||||
setAttrib(name, index, format, offset, needNormalized);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set stride of vertices.
|
||||
|
|
|
@ -208,8 +208,6 @@ private:
|
|||
UniformLocation _builtinUniformLocation[UNIFORM_MAX];
|
||||
int _builtinAttributeLocation[Attribute::ATTRIBUTE_MAX];
|
||||
std::unordered_map<int, int> _bufferOffset;
|
||||
|
||||
uint32_t _hashOfUniforms = 0;
|
||||
};
|
||||
// end of _opengl group
|
||||
/// @}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef M_PI
|
||||
#define M_PI 3.141592654
|
||||
#endif
|
||||
|
||||
/*
|
||||
* transform color with HSV
|
||||
* @params
|
||||
* inColor: input color in rgb
|
||||
* h: hue shift (in degrees)
|
||||
* s: saturation multiplier (scalar)
|
||||
* v: value multiplier (scalar)
|
||||
* @refers
|
||||
* https://beesbuzz.biz/code/16-hsv-color-transforms
|
||||
* https://www.shadertoy.com/view/3syyW1
|
||||
*/
|
||||
vec3 transformHSV(vec3 inColor, vec3 hsv)
|
||||
{
|
||||
float h = hsv.x;
|
||||
float s = hsv.y;
|
||||
float v = hsv.z;
|
||||
|
||||
float vsu = v * s * cos(h * M_PI / 180.0);
|
||||
float vsw = v * s * sin(h * M_PI / 180.0);
|
||||
vec3 outColor = vec3(
|
||||
(.299 * v + .701 * vsu + .168 * vsw) * inColor.r + (.587 * v - .587 * vsu + .330 * vsw) * inColor.g +
|
||||
(.114 * v - .114 * vsu - .497 * vsw) * inColor.b,
|
||||
(.299 * v - .299 * vsu - .328 * vsw) * inColor.r + (.587 * v + .413 * vsu + .035 * vsw) * inColor.g +
|
||||
(.114 * v - .114 * vsu + .292 * vsw) * inColor.b,
|
||||
(.299 * v - .300 * vsu + 1.25 * vsw) * inColor.r + (.587 * v - .588 * vsu - 1.05 * vsw) * inColor.g +
|
||||
(.114 * v + .886 * vsu - .203 * vsw) * inColor.b
|
||||
);
|
||||
return outColor;
|
||||
}
|
||||
|
||||
vec3 trasnformYUV(vec3 YUV, mat4 colorTransform)
|
||||
{
|
||||
YUV -= vec3(colorTransform[0].w, colorTransform[1].w, colorTransform[2].w);
|
||||
return mat3(
|
||||
colorTransform[0].xyz,
|
||||
colorTransform[1].xyz,
|
||||
colorTransform[2].xyz
|
||||
) * YUV;
|
||||
}
|
|
@ -2,39 +2,18 @@
|
|||
precision highp float;
|
||||
precision highp int;
|
||||
|
||||
#include "colorUtils.glsl"
|
||||
|
||||
layout(location = 0) in vec2 v_texCoord;
|
||||
layout(location = 1) in vec4 v_fragmentColor;
|
||||
|
||||
layout(binding = 0) uniform sampler2D u_tex0;
|
||||
layout(binding = 1) uniform sampler2D u_tex1;
|
||||
|
||||
// HSV matrix
|
||||
|
||||
// filter color RGB values
|
||||
|
||||
layout(std140) uniform fs_ub {
|
||||
mat3 u_mix_hsv;
|
||||
vec3 u_filter_rgb;
|
||||
vec3 u_hsv;
|
||||
};
|
||||
|
||||
vec3 rgb2hsv(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
vec3 hsv2rgb(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
|
@ -42,21 +21,7 @@ void main()
|
|||
vec4 texColor = vec4(texture(u_tex0, v_texCoord).rgb, texture(u_tex1, v_texCoord).r);
|
||||
texColor.rgb *= texColor.a; // Premultiply with Alpha channel
|
||||
|
||||
vec3 rgbColor = u_mix_hsv * texColor.rgb;
|
||||
texColor.rgb = transformHSV(texColor.rgb, u_hsv);
|
||||
|
||||
float sum = texColor.r + texColor.g + texColor.b;
|
||||
float rv = texColor.r / sum;
|
||||
float gv = texColor.g / sum;
|
||||
float bv = texColor.b / sum;
|
||||
if( (rv < u_filter_rgb.r && gv < u_filter_rgb.g && bv < u_filter_rgb.b) || texColor.a < 0.1)
|
||||
{ // color filters, resume to original color
|
||||
rgbColor = texColor.rgb;
|
||||
|
||||
rgbColor.r *= v_fragmentColor.a;
|
||||
rgbColor.g *= v_fragmentColor.a;
|
||||
rgbColor.b *= v_fragmentColor.a;
|
||||
}
|
||||
|
||||
rgbColor.rgb = rgbColor.rgb * v_fragmentColor.rgb;
|
||||
FragColor = vec4(rgbColor, texColor.a * v_fragmentColor.a);
|
||||
FragColor = texColor * v_fragmentColor;
|
||||
}
|
||||
|
|
|
@ -2,58 +2,22 @@
|
|||
precision highp float;
|
||||
precision highp int;
|
||||
|
||||
#include "colorUtils.glsl"
|
||||
|
||||
layout(location = 0) in vec2 v_texCoord;
|
||||
layout(location = 1) in vec4 v_fragmentColor;
|
||||
layout(binding = 0) uniform sampler2D u_tex0;
|
||||
|
||||
// HSV matrix
|
||||
|
||||
// filter color RGB values
|
||||
|
||||
layout(std140) uniform fs_ub {
|
||||
mat3 u_mix_hsv;
|
||||
vec3 u_filter_rgb;
|
||||
vec3 u_hsv;
|
||||
};
|
||||
|
||||
vec3 rgb2hsv(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
vec3 hsv2rgb(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pixColor = texture(u_tex0, v_texCoord); // * v_fragmentColor;
|
||||
vec3 rgbColor = u_mix_hsv * pixColor.rgb;
|
||||
vec4 outColor = texture(u_tex0, v_texCoord);
|
||||
outColor.rgb = transformHSV(outColor.rgb, u_hsv);
|
||||
|
||||
float sum = pixColor.r + pixColor.g + pixColor.b;
|
||||
float rv = pixColor.r / sum;
|
||||
float gv = pixColor.g / sum;
|
||||
float bv = pixColor.b / sum;
|
||||
if( (rv < u_filter_rgb.r && gv < u_filter_rgb.g && bv < u_filter_rgb.b) || pixColor.a < 0.1)
|
||||
{ // color filters, resume to original color
|
||||
rgbColor = pixColor.rgb;
|
||||
|
||||
rgbColor.r *= v_fragmentColor.a;
|
||||
rgbColor.g *= v_fragmentColor.a;
|
||||
rgbColor.b *= v_fragmentColor.a;
|
||||
}
|
||||
|
||||
rgbColor.rgb = rgbColor.rgb * v_fragmentColor.rgb;
|
||||
FragColor = vec4(rgbColor, pixColor.a * v_fragmentColor.a);
|
||||
FragColor = outColor * v_fragmentColor.a;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
precision highp float;
|
||||
precision highp int;
|
||||
|
||||
#include "colorUtils.glsl"
|
||||
|
||||
layout(location = 0) in vec4 v_fragmentColor;
|
||||
layout(location = 1) in vec2 v_texCoord;
|
||||
|
@ -13,16 +14,6 @@ layout(std140) uniform fs_ub {
|
|||
mat4 colorTransform;
|
||||
};
|
||||
|
||||
vec3 trasnformYUV(vec3 YUV)
|
||||
{
|
||||
YUV -= vec3(colorTransform[0].w, colorTransform[1].w, colorTransform[2].w);
|
||||
return mat3(
|
||||
colorTransform[0].xyz,
|
||||
colorTransform[1].xyz,
|
||||
colorTransform[2].xyz
|
||||
) * YUV;
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
|
@ -34,7 +25,7 @@ void main()
|
|||
|
||||
/* Convert YUV to RGB */
|
||||
vec4 OutColor;
|
||||
OutColor.xyz = trasnformYUV(YUV);
|
||||
OutColor.xyz = trasnformYUV(YUV, colorTransform);
|
||||
OutColor.w = 1.0;
|
||||
|
||||
FragColor = v_fragmentColor * OutColor;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
precision highp float;
|
||||
precision highp int;
|
||||
|
||||
#include "colorUtils.glsl"
|
||||
|
||||
layout(location = 0) in vec4 v_fragmentColor;
|
||||
layout(location = 1) in vec2 v_texCoord;
|
||||
|
@ -13,16 +14,6 @@ layout(std140) uniform fs_ub {
|
|||
mat4 colorTransform;
|
||||
};
|
||||
|
||||
vec3 trasnformYUV(vec3 YUV)
|
||||
{
|
||||
YUV -= vec3(colorTransform[0].w, colorTransform[1].w, colorTransform[2].w);
|
||||
return mat3(
|
||||
colorTransform[0].xyz,
|
||||
colorTransform[1].xyz,
|
||||
colorTransform[2].xyz
|
||||
) * YUV;
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
|
@ -35,7 +26,7 @@ void main()
|
|||
|
||||
/* Convert YUV to RGB */
|
||||
vec4 OutColor;
|
||||
OutColor.xyz = trasnformYUV(YUV);
|
||||
OutColor.xyz = trasnformYUV(YUV, colorTransform);
|
||||
OutColor.w = 1.0;
|
||||
|
||||
FragColor = v_fragmentColor * OutColor;
|
||||
|
|
|
@ -1491,9 +1491,11 @@ static bool ImGui_ImplAx_CreateDeviceObjects()
|
|||
|
||||
static void ImGui_ImplAx_DestroyDeviceObjects()
|
||||
{
|
||||
auto pm = ProgramManager::getInstance();
|
||||
|
||||
auto bd = ImGui_ImplGlfw_GetBackendData();
|
||||
AX_SAFE_RELEASE_NULL(bd->ProgramInfo.program);
|
||||
AX_SAFE_RELEASE_NULL(bd->ProgramFontInfo.program);
|
||||
pm->unloadProgram(bd->ProgramInfo.program);
|
||||
pm->unloadProgram(bd->ProgramFontInfo.program);
|
||||
ImGui_ImplAx_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
|
@ -1503,26 +1505,14 @@ static bool ImGui_ImplAx_createShaderPrograms()
|
|||
|
||||
auto bd = ImGui_ImplGlfw_GetBackendData();
|
||||
|
||||
enum
|
||||
{
|
||||
ImGuiSprite = 0xFF,
|
||||
ImGuiFont = 0xFE,
|
||||
};
|
||||
auto pm = ProgramManager::getInstance();
|
||||
pm->registerCustomProgram(ImGuiSprite, "custom/imgui_sprite_vs"sv, ax::positionTextureColor_frag);
|
||||
pm->registerCustomProgram(ImGuiFont, "custom/imgui_sprite_vs"sv, "custom/imgui_font_fs");
|
||||
|
||||
AX_SAFE_RELEASE(bd->ProgramInfo.program);
|
||||
AX_SAFE_RELEASE(bd->ProgramFontInfo.program);
|
||||
|
||||
bd->ProgramInfo.program = pm->getCustomProgram(ImGuiSprite);
|
||||
bd->ProgramFontInfo.program = pm->getCustomProgram(ImGuiFont);
|
||||
bd->ProgramInfo.program = pm->loadProgram("custom/imgui_sprite_vs"sv, ax::positionTextureColor_frag);
|
||||
bd->ProgramFontInfo.program = pm->loadProgram("custom/imgui_sprite_vs"sv, "custom/imgui_font_fs");
|
||||
|
||||
IM_ASSERT(bd->ProgramInfo.program);
|
||||
IM_ASSERT(bd->ProgramFontInfo.program);
|
||||
|
||||
AX_SAFE_RETAIN(bd->ProgramInfo.program);
|
||||
AX_SAFE_RETAIN(bd->ProgramFontInfo.program);
|
||||
if (!bd->ProgramInfo.program || !bd->ProgramFontInfo.program)
|
||||
return false;
|
||||
|
||||
|
@ -1727,7 +1717,7 @@ IMGUI_IMPL_API void ImGui_ImplAx_RenderDrawData(ImDrawData* draw_data)
|
|||
auto& desc = cmd->getPipelineDescriptor();
|
||||
desc.programState = state;
|
||||
// setup attributes for ImDrawVert
|
||||
desc.programState->setVertexLayout(pinfo->layout);
|
||||
desc.programState->setSharedVertexLayout(&pinfo->layout);
|
||||
desc.programState->setUniform(pinfo->projection, &bd->Projection, sizeof(Mat4));
|
||||
desc.programState->setTexture(pinfo->texture, 0, tex->getBackendTexture());
|
||||
// In order to composite our output buffer we need to preserve alpha
|
||||
|
|
|
@ -703,7 +703,7 @@ IMGUI_IMPL_API void ImGui_ImplAx_RenderDrawData(ImDrawData* draw_data)
|
|||
auto& desc = cmd->getPipelineDescriptor();
|
||||
desc.programState = state;
|
||||
// setup attributes for ImDrawVert
|
||||
desc.programState->setVertexLayout(pinfo->layout);
|
||||
desc.programState->setSharedVertexLayout(&pinfo->layout);
|
||||
desc.programState->setUniform(pinfo->projection, &bd->Projection, sizeof(Mat4));
|
||||
desc.programState->setTexture(pinfo->texture, 0, tex->getBackendTexture());
|
||||
// In order to composite our output buffer we need to preserve alpha
|
||||
|
|
|
@ -72,7 +72,7 @@ bool BoneNode::init()
|
|||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
auto* program =
|
||||
ax::backend::Program::getBuiltinProgram(ax::backend::ProgramType::POSITION_COLOR); // TODO: noMVP?
|
||||
setProgramState(new ax::backend::ProgramState(program), false);
|
||||
setProgramState(new ax::backend::ProgramState(program), true);
|
||||
pipelineDescriptor.programState = _programState;
|
||||
|
||||
_mvpLocation = _programState->getUniformLocation("u_MVPMatrix"sv);
|
||||
|
|
|
@ -53,7 +53,7 @@ bool SkeletonNode::init()
|
|||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
auto* program =
|
||||
ax::backend::Program::getBuiltinProgram(ax::backend::ProgramType::POSITION_COLOR); // TODO: noMVP?
|
||||
setProgramState(new ax::backend::ProgramState(program), false);
|
||||
setProgramState(new ax::backend::ProgramState(program), true);
|
||||
pipelineDescriptor.programState = _programState;
|
||||
|
||||
_mvpLocation = _programState->getUniformLocation("u_MVPMatrix");
|
||||
|
|
|
@ -36,7 +36,9 @@
|
|||
#include "WidgetReader/NodeReader/NodeReader.h"
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "renderer/Colorizer.h"
|
||||
|
||||
#include "renderer/backend/ProgramManager.h"
|
||||
#include "renderer/backend/ProgramState.h"
|
||||
|
||||
USING_NS_AX;
|
||||
using namespace flatbuffers;
|
||||
|
@ -326,8 +328,11 @@ void SpriteReader::setPropsWithFlatBuffers(ax::Node* node, const flatbuffers::Ta
|
|||
auto filter = options->filter();
|
||||
if (hsv != nullptr && filter != nullptr)
|
||||
{
|
||||
Colorizer::enableNodeIntelliShading(sprite, Vec3(hsv->x(), hsv->y(), hsv->z()),
|
||||
Vec3(filter->x(), filter->y(), filter->z()));
|
||||
auto prog = ProgramManager::getInstance()->getBuiltinProgram(ProgramType::HSV);
|
||||
auto ps = new backend::ProgramState(prog);
|
||||
sprite->setProgramState(ps, true);
|
||||
Vec3 axhsv{hsv->x(), hsv->y(), hsv->z()};
|
||||
ps->setUniform(ps->getUniformLocation("u_hsv"), &axhsv, sizeof(axhsv));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,4 +21,7 @@ endif()
|
|||
|
||||
target_include_directories(${target_name} PUBLIC "runtime/include")
|
||||
|
||||
ax_find_shaders(${CMAKE_CURRENT_LIST_DIR}/shaders SPINE_SHADER_SOURCES)
|
||||
ax_target_compile_shaders(${target_name} FILES ${SPINE_SHADER_SOURCES} CUSTOM)
|
||||
|
||||
setup_ax_extension_config(${target_name})
|
||||
|
|
|
@ -89,8 +89,8 @@ namespace spine {
|
|||
{
|
||||
auto& currentState = command->getPipelineDescriptor().programState;
|
||||
#if defined(AX_VERSION)
|
||||
if (currentState == nullptr || currentState->getProgram() != programState->getProgram() ||
|
||||
currentState->hashOfUniforms() != programState->hashOfUniforms())
|
||||
if (currentState == nullptr ||
|
||||
currentState->getBatchId() != programState->getBatchId())
|
||||
{
|
||||
#else
|
||||
if(currentState == nullptr || currentState->getProgram() != programState->getProgram()) {
|
||||
|
|
|
@ -47,52 +47,8 @@ using std::max;
|
|||
#define MAX_VERTICES 64000
|
||||
#define MAX_INDICES 64000
|
||||
|
||||
#define STRINGIFY(A) #A
|
||||
|
||||
namespace {
|
||||
|
||||
const char *TWO_COLOR_TINT_VERTEX_SHADER = STRINGIFY(
|
||||
uniform mat4 u_PMatrix;
|
||||
attribute vec4 a_position;
|
||||
attribute vec4 a_color;
|
||||
attribute vec4 a_color2;
|
||||
attribute vec2 a_texCoords;
|
||||
|
||||
\n #ifdef GL_ES\n
|
||||
varying lowp vec4 v_light;
|
||||
varying lowp vec4 v_dark;
|
||||
varying mediump vec2 v_texCoord;
|
||||
\n #else \n
|
||||
varying vec4 v_light;
|
||||
varying vec4 v_dark;
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
\n #endif \n
|
||||
|
||||
void main() {
|
||||
v_light = a_color;
|
||||
v_dark = a_color2;
|
||||
v_texCoord = a_texCoords;
|
||||
gl_Position = u_PMatrix * a_position;
|
||||
});
|
||||
|
||||
const char *TWO_COLOR_TINT_FRAGMENT_SHADER = STRINGIFY(
|
||||
\n #ifdef GL_ES\n
|
||||
precision lowp float;
|
||||
\n #endif \n
|
||||
uniform sampler2D u_texture;
|
||||
varying vec4 v_light;
|
||||
varying vec4 v_dark;
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
void main() {
|
||||
vec4 texColor = texture2D(u_texture, v_texCoord);
|
||||
float alpha = texColor.a * v_light.a;
|
||||
gl_FragColor.a = alpha;
|
||||
gl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
|
||||
});
|
||||
|
||||
|
||||
std::shared_ptr<backend::ProgramState> __twoColorProgramState = nullptr;
|
||||
backend::UniformLocation __locPMatrix;
|
||||
backend::UniformLocation __locTexture;
|
||||
|
@ -106,21 +62,25 @@ namespace {
|
|||
auto locColor = programState->getAttributeLocation("a_color");
|
||||
auto locColor2 = programState->getAttributeLocation("a_color2");
|
||||
|
||||
programState->setVertexAttrib("a_position", locPosition, backend::VertexFormat::FLOAT3, offsetof(spine::V3F_C4B_C4B_T2F, position), false);
|
||||
programState->setVertexAttrib("a_color", locColor, backend::VertexFormat::UBYTE4, offsetof(spine::V3F_C4B_C4B_T2F, color), true);
|
||||
programState->setVertexAttrib("a_color2", locColor2, backend::VertexFormat::UBYTE4, offsetof(spine::V3F_C4B_C4B_T2F, color2), true);
|
||||
programState->setVertexAttrib("a_texCoords", locTexcoord, backend::VertexFormat::FLOAT2, offsetof(spine::V3F_C4B_C4B_T2F, texCoords), false);
|
||||
programState->setVertexStride(sizeof(spine::V3F_C4B_C4B_T2F));
|
||||
auto vertexLayout = programState->getMutableVertexLayout();
|
||||
vertexLayout->setAttrib("a_position", locPosition, backend::VertexFormat::FLOAT3,
|
||||
offsetof(spine::V3F_C4B_C4B_T2F, position), false);
|
||||
vertexLayout->setAttrib("a_color", locColor, backend::VertexFormat::UBYTE4,
|
||||
offsetof(spine::V3F_C4B_C4B_T2F, color), true);
|
||||
vertexLayout->setAttrib("a_color2", locColor2, backend::VertexFormat::UBYTE4,
|
||||
offsetof(spine::V3F_C4B_C4B_T2F, color2), true);
|
||||
vertexLayout->setAttrib("a_texCoords", locTexcoord, backend::VertexFormat::FLOAT2,
|
||||
offsetof(spine::V3F_C4B_C4B_T2F, texCoords), false);
|
||||
vertexLayout->setStride(sizeof(spine::V3F_C4B_C4B_T2F));
|
||||
}
|
||||
|
||||
static void initTwoColorProgramState() {
|
||||
if (__twoColorProgramState) {
|
||||
return;
|
||||
}
|
||||
auto program = backend::Device::getInstance()->newProgram(TWO_COLOR_TINT_VERTEX_SHADER, TWO_COLOR_TINT_FRAGMENT_SHADER);
|
||||
auto program = ProgramManager::getInstance()->loadProgram("custom/spineTwoColorTint_vs",
|
||||
"custom/spineTwoColorTint_fs");
|
||||
auto *programState = new backend::ProgramState(program);
|
||||
program->release();
|
||||
|
||||
updateProgramStateLayout(programState);
|
||||
|
||||
__twoColorProgramState = std::shared_ptr<backend::ProgramState>(programState);
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#version 310 es
|
||||
|
||||
precision highp float;
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
in vec4 v_light;
|
||||
in vec4 v_dark;
|
||||
in vec2 v_texCoord;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec4 texColor = texture(u_texture, v_texCoord);
|
||||
float alpha = texColor.a * v_light.a;
|
||||
FragColor.a = alpha;
|
||||
FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#version 310 es
|
||||
|
||||
in vec4 a_position;
|
||||
in vec4 a_color;
|
||||
in vec4 a_color2;
|
||||
in vec2 a_texCoords;
|
||||
|
||||
out vec4 v_light;
|
||||
out vec4 v_dark;
|
||||
out vec2 v_texCoord;
|
||||
|
||||
layout(std140) uniform vs_ub {
|
||||
mat4 u_PMatrix;
|
||||
};
|
||||
|
||||
void main() {
|
||||
v_light = a_color;
|
||||
v_dark = a_color2;
|
||||
v_texCoord = a_texCoords;
|
||||
gl_Position = u_PMatrix * a_position;
|
||||
}
|
|
@ -221,8 +221,6 @@ list(APPEND GAME_HEADER
|
|||
Source/SchedulerTest/SchedulerTest.h
|
||||
Source/MultiTouchTest/MultiTouchTest.h
|
||||
Source/testResource.h
|
||||
Source/ShaderTest/ShaderTest.vsh.h
|
||||
Source/ShaderTest/shaderTest.psh.h
|
||||
Source/ShaderTest/ShaderTest.h
|
||||
Source/ShaderTest/ShaderTest2.h
|
||||
Source/NewRendererTest/NewRendererTest.h
|
||||
|
|
|
@ -1253,12 +1253,9 @@ void FogTestDemo::onEnter()
|
|||
AX_SAFE_RELEASE_NULL(_programState1);
|
||||
AX_SAFE_RELEASE_NULL(_programState2);
|
||||
|
||||
auto vertexSource = FileUtils::getInstance()->getStringFromFile("MeshRendererTest/fog.vert");
|
||||
auto fragSource = FileUtils::getInstance()->getStringFromFile("MeshRendererTest/fog.frag");
|
||||
auto program = ProgramManager::newProgram(vertexSource, fragSource);
|
||||
auto program = ProgramManager::getInstance()->loadProgram("custom/fog_vs", "custom/fog_fs");
|
||||
_programState1 = new backend::ProgramState(program);
|
||||
_programState2 = new backend::ProgramState(program);
|
||||
AX_SAFE_RELEASE(program);
|
||||
|
||||
_mesh1 = MeshRenderer::create("MeshRendererTest/teapot.c3b");
|
||||
_mesh2 = MeshRenderer::create("MeshRendererTest/teapot.c3b");
|
||||
|
@ -1303,15 +1300,12 @@ void FogTestDemo::onEnter()
|
|||
AX_SAFE_RELEASE_NULL(_programState1);
|
||||
AX_SAFE_RELEASE_NULL(_programState2);
|
||||
|
||||
auto vertexSource = FileUtils::getInstance()->getStringFromFile("MeshRendererTest/fog.vert");
|
||||
auto fragSource = FileUtils::getInstance()->getStringFromFile("MeshRendererTest/fog.frag");
|
||||
auto program = ProgramManager::newProgram(vertexSource, fragSource);
|
||||
auto program = ProgramManager::getInstance()->loadProgram("custom/fog_vs", "custom/fog_fs");
|
||||
_programState1 = new backend::ProgramState(program);
|
||||
_programState2 = new backend::ProgramState(program);
|
||||
|
||||
_mesh1->setProgramState(_programState1);
|
||||
_mesh2->setProgramState(_programState2);
|
||||
AX_SAFE_RELEASE(program);
|
||||
|
||||
auto fogColor = Vec4(0.5, 0.5, 0.5, 1.0);
|
||||
float fogStart = 10;
|
||||
|
|
|
@ -31,11 +31,8 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
enum CustomProgramType : uint32_t
|
||||
{
|
||||
BLUR = 1,
|
||||
SEPIA = 2,
|
||||
};
|
||||
static uint64_t s_blur_program_id = 0;
|
||||
static uint64_t s_sepia_program_id = 0;
|
||||
}
|
||||
|
||||
USING_NS_AX;
|
||||
|
@ -74,14 +71,13 @@ private:
|
|||
|
||||
NewRendererTests::NewRendererTests()
|
||||
{
|
||||
auto programManager = ProgramManager::getInstance();
|
||||
programManager->registerCustomProgram(CustomProgramType::BLUR, positionTextureColor_vert,
|
||||
"example_Blur_fs"sv,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
programManager->registerCustomProgram(
|
||||
CustomProgramType::SEPIA, positionTextureColor_vert,
|
||||
"example_Sepia_fs"sv,
|
||||
VertexLayoutHelper::setupSprite);
|
||||
auto programManager = ProgramManager::getInstance();
|
||||
s_blur_program_id = programManager->registerCustomProgram(positionTextureColor_vert,
|
||||
"custom/example_Blur_fs"sv,
|
||||
VertexLayoutType::Sprite);
|
||||
s_sepia_program_id = programManager->registerCustomProgram(positionTextureColor_vert,
|
||||
"custom/example_Sepia_fs"sv,
|
||||
VertexLayoutType::Sprite);
|
||||
|
||||
ADD_TEST_CASE(NewSpriteTest);
|
||||
ADD_TEST_CASE(GroupCommandTest);
|
||||
|
@ -857,7 +853,7 @@ RendererUniformBatch::RendererUniformBatch()
|
|||
ax::backend::ProgramState* RendererUniformBatch::createBlurProgramState()
|
||||
{
|
||||
auto programState =
|
||||
new backend::ProgramState(ProgramManager::getInstance()->getCustomProgram(CustomProgramType::BLUR));
|
||||
new backend::ProgramState(ProgramManager::getInstance()->loadProgram(s_blur_program_id));
|
||||
programState->autorelease();
|
||||
|
||||
backend::UniformLocation loc = programState->getUniformLocation("resolution");
|
||||
|
@ -877,11 +873,7 @@ ax::backend::ProgramState* RendererUniformBatch::createBlurProgramState()
|
|||
|
||||
ax::backend::ProgramState* RendererUniformBatch::createSepiaProgramState()
|
||||
{
|
||||
auto programState =
|
||||
new backend::ProgramState(ProgramManager::getInstance()->getCustomProgram(CustomProgramType::SEPIA));
|
||||
|
||||
// programState->hashOfUniforms();
|
||||
|
||||
auto programState = new backend::ProgramState(ProgramManager::getInstance()->loadProgram(s_sepia_program_id));
|
||||
programState->autorelease();
|
||||
return programState;
|
||||
}
|
||||
|
@ -931,7 +923,7 @@ RendererUniformBatch2::RendererUniformBatch2()
|
|||
backend::ProgramState* RendererUniformBatch2::createBlurProgramState()
|
||||
{
|
||||
auto programState =
|
||||
new backend::ProgramState(ProgramManager::getInstance()->getCustomProgram(CustomProgramType::BLUR));
|
||||
new backend::ProgramState(ProgramManager::getInstance()->loadProgram(s_blur_program_id));
|
||||
|
||||
backend::UniformLocation loc = programState->getUniformLocation("resolution");
|
||||
auto resolution = Vec2(85, 121);
|
||||
|
@ -951,7 +943,7 @@ backend::ProgramState* RendererUniformBatch2::createBlurProgramState()
|
|||
backend::ProgramState* RendererUniformBatch2::createSepiaProgramState()
|
||||
{
|
||||
auto programState =
|
||||
new backend::ProgramState(ProgramManager::getInstance()->getCustomProgram(CustomProgramType::SEPIA));
|
||||
new backend::ProgramState(ProgramManager::getInstance()->loadProgram(s_sepia_program_id));
|
||||
programState->autorelease();
|
||||
return programState;
|
||||
}
|
||||
|
|
|
@ -943,19 +943,19 @@ public:
|
|||
sprite->autorelease();
|
||||
auto program = backend::Program::getBuiltinProgram(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
auto programState = new backend::ProgramState(program);
|
||||
sprite->setProgramState(programState, false);
|
||||
sprite->setProgramState(programState, true);
|
||||
return sprite;
|
||||
}
|
||||
bool setProgramState(backend::ProgramState* programState, bool needsRetain = true) override;
|
||||
bool setProgramState(backend::ProgramState* programState, bool ownPS = false) override;
|
||||
virtual void draw(Renderer* renderer, const Mat4& transform, uint32_t flags) override;
|
||||
|
||||
protected:
|
||||
CustomCommand _customCommand;
|
||||
};
|
||||
|
||||
bool MySprite::setProgramState(backend::ProgramState* programState, bool needsRetain)
|
||||
bool MySprite::setProgramState(backend::ProgramState* programState, bool ownPS/* = false*/)
|
||||
{
|
||||
if (Sprite::setProgramState(programState, needsRetain))
|
||||
if (Sprite::setProgramState(programState, ownPS))
|
||||
{
|
||||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
pipelineDescriptor.programState = programState;
|
||||
|
|
|
@ -88,6 +88,8 @@ ShaderNode* ShaderNode::shaderNodeWithVertex(std::string_view vert, std::string_
|
|||
|
||||
bool ShaderNode::initWithVertex(std::string_view vert, std::string_view frag)
|
||||
{
|
||||
if (vert.empty())
|
||||
vert = position_vert;
|
||||
_vertFileName = vert;
|
||||
_fragFileName = frag;
|
||||
|
||||
|
@ -103,11 +105,13 @@ bool ShaderNode::initWithVertex(std::string_view vert, std::string_view frag)
|
|||
|
||||
// init custom command
|
||||
auto attrPosLoc = _programState->getAttributeLocation("a_position");
|
||||
_programState->setVertexAttrib("a_position", attrPosLoc, backend::VertexFormat::FLOAT2, 0, false);
|
||||
|
||||
auto vertexLayout = _programState->getMutableVertexLayout();
|
||||
vertexLayout->setAttrib("a_position", attrPosLoc, backend::VertexFormat::FLOAT2, 0, false);
|
||||
|
||||
float w = SIZE_X, h = SIZE_Y;
|
||||
Vec2 vertices[6] = {Vec2(0.0f, 0.0f), Vec2(w, 0.0f), Vec2(w, h), Vec2(0.0f, 0.0f), Vec2(0.0f, h), Vec2(w, h)};
|
||||
_programState->setVertexStride(sizeof(Vec2));
|
||||
vertexLayout->setStride(sizeof(Vec2));
|
||||
|
||||
/*
|
||||
* TODO: the Y-coordinate of subclasses are flipped in metal
|
||||
|
@ -125,28 +129,10 @@ bool ShaderNode::initWithVertex(std::string_view vert, std::string_view frag)
|
|||
|
||||
void ShaderNode::loadShaderVertex(std::string_view vert, std::string_view frag)
|
||||
{
|
||||
auto fileUtiles = FileUtils::getInstance();
|
||||
|
||||
// frag
|
||||
auto fragmentFilePath = fileUtiles->fullPathForFilename(frag);
|
||||
auto fragSource = fileUtiles->getStringFromFile(fragmentFilePath);
|
||||
|
||||
// vert
|
||||
std::string vertSource;
|
||||
if (vert.empty())
|
||||
{
|
||||
vertSource = position_vert;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string vertexFilePath = fileUtiles->fullPathForFilename(vert);
|
||||
vertSource = fileUtiles->getStringFromFile(vertexFilePath);
|
||||
}
|
||||
auto program = ProgramManager::newProgram(vertSource, fragSource, VertexLayoutHelper::setupSprite);
|
||||
auto program = ProgramManager::getInstance()->loadProgram(vert, frag, VertexLayoutType::Sprite);
|
||||
auto programState = new backend::ProgramState(program);
|
||||
setProgramState(programState);
|
||||
AX_SAFE_RELEASE(programState);
|
||||
AX_SAFE_RELEASE(program);
|
||||
}
|
||||
|
||||
void ShaderNode::update(float dt)
|
||||
|
@ -217,7 +203,7 @@ bool ShaderMonjori::init()
|
|||
{
|
||||
if (ShaderTestDemo::init())
|
||||
{
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "Shaders/example_Monjori.fsh");
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "custom/example_Monjori_fs");
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
sn->setPosition(Vec2(s.width / 2, s.height / 2));
|
||||
|
@ -247,7 +233,7 @@ bool ShaderMandelbrot::init()
|
|||
{
|
||||
if (ShaderTestDemo::init())
|
||||
{
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "Shaders/example_Mandelbrot.fsh");
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "custom/example_Mandelbrot_fs");
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
sn->setPosition(Vec2(s.width / 2, s.height / 2));
|
||||
|
@ -276,7 +262,7 @@ bool ShaderJulia::init()
|
|||
{
|
||||
if (ShaderTestDemo::init())
|
||||
{
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "Shaders/example_Julia.fsh");
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "custom/example_Julia_fs");
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
sn->setPosition(Vec2(s.width / 2, s.height / 2));
|
||||
|
@ -305,7 +291,7 @@ bool ShaderHeart::init()
|
|||
{
|
||||
if (ShaderTestDemo::init())
|
||||
{
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "Shaders/example_Heart.fsh");
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "custom/example_Heart_fs");
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
sn->setPosition(Vec2(s.width / 2, s.height / 2));
|
||||
|
@ -335,7 +321,7 @@ bool ShaderFlower::init()
|
|||
{
|
||||
if (ShaderTestDemo::init())
|
||||
{
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "Shaders/example_Flower.fsh");
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "custom/example_Flower_fs");
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
sn->setPosition(Vec2(s.width / 2, s.height / 2));
|
||||
|
@ -365,7 +351,7 @@ bool ShaderPlasma::init()
|
|||
{
|
||||
if (ShaderTestDemo::init())
|
||||
{
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "Shaders/example_Plasma.fsh");
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "custom/example_Plasma_fs");
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
sn->setPosition(Vec2(s.width / 2, s.height / 2));
|
||||
|
@ -448,14 +434,10 @@ bool SpriteBlur::initWithTexture(Texture2D* texture, const Rect& rect)
|
|||
|
||||
void SpriteBlur::initProgram()
|
||||
{
|
||||
std::string fragSource = FileUtils::getInstance()->getStringFromFile(
|
||||
FileUtils::getInstance()->fullPathForFilename("Shaders/example_Blur.fsh"));
|
||||
|
||||
auto program = ProgramManager::newProgram(positionTextureColor_vert, fragSource, VertexLayoutHelper::setupSprite);
|
||||
auto program = ProgramManager::getInstance()->loadProgram(positionTextureColor_vert, "custom/example_Blur_fs", VertexLayoutType::Sprite);
|
||||
auto programState = new backend::ProgramState(program);
|
||||
setProgramState(programState);
|
||||
AX_SAFE_RELEASE(programState);
|
||||
AX_SAFE_RELEASE(program);
|
||||
|
||||
auto size = getTexture()->getContentSizeInPixels();
|
||||
|
||||
|
@ -581,10 +563,10 @@ bool ShaderRetroEffect::init()
|
|||
{
|
||||
|
||||
auto fragStr = FileUtils::getInstance()->getStringFromFile(
|
||||
FileUtils::getInstance()->fullPathForFilename("Shaders/example_HorizontalColor.fsh"));
|
||||
FileUtils::getInstance()->fullPathForFilename("custom/example_HorizontalColor_fs"));
|
||||
char* fragSource = (char*)fragStr.c_str();
|
||||
|
||||
auto program = ProgramManager::newProgram(positionTextureColor_vert, fragSource, VertexLayoutHelper::setupSprite);
|
||||
auto program = ProgramManager::getInstance()->loadProgram(positionTextureColor_vert, "custom/example_HorizontalColor_fs", VertexLayoutType::Sprite);
|
||||
auto p = new backend::ProgramState(program);
|
||||
auto director = Director::getInstance();
|
||||
const auto& screenSizeLocation = p->getUniformLocation("u_screenSize");
|
||||
|
@ -605,7 +587,6 @@ bool ShaderRetroEffect::init()
|
|||
addChild(_label);
|
||||
|
||||
scheduleUpdate();
|
||||
AX_SAFE_RELEASE(program);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -658,7 +639,7 @@ bool ShaderLensFlare::init()
|
|||
{
|
||||
if (ShaderTestDemo::init())
|
||||
{
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "Shaders/shadertoy_LensFlare.fsh");
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "custom/shadertoy_LensFlare_fs");
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
sn->setPosition(Vec2(s.width / 2, s.height / 2));
|
||||
|
@ -690,7 +671,7 @@ bool ShaderGlow::init()
|
|||
{
|
||||
if (ShaderTestDemo::init())
|
||||
{
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "Shaders/shadertoy_Glow.fsh");
|
||||
auto sn = ShaderNode::shaderNodeWithVertex("", "custom/shadertoy_Glow_fs");
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
sn->setPosition(Vec2(s.width / 2, s.height / 2));
|
||||
|
@ -764,10 +745,7 @@ bool ShaderMultiTexture::init()
|
|||
addChild(_sprite);
|
||||
_sprite->setPosition(Vec2(s.width / 2, s.height / 2));
|
||||
|
||||
auto* fu = FileUtils::getInstance();
|
||||
auto vertexShader = fu->getStringFromFile("Shaders/example_MultiTexture.vsh");
|
||||
auto fragmentShader = fu->getStringFromFile("Shaders/example_MultiTexture.fsh");
|
||||
auto program = ProgramManager::newProgram(vertexShader, fragmentShader, VertexLayoutHelper::setupSprite);
|
||||
auto program = ProgramManager::getInstance()->loadProgram("custom/example_MultiTexture_vs", "custom/example_MultiTexture_fs", VertexLayoutType::Sprite);
|
||||
auto programState = new backend::ProgramState(program);
|
||||
_sprite->setProgramState(programState);
|
||||
|
||||
|
@ -785,7 +763,6 @@ bool ShaderMultiTexture::init()
|
|||
menu->setPosition(s.width * 7 / 8, s.height / 2);
|
||||
|
||||
AX_SAFE_RELEASE(programState);
|
||||
AX_SAFE_RELEASE(program);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -153,9 +153,9 @@ protected:
|
|||
bool initWithVertex(std::string_view vert, std::string_view frag);
|
||||
void loadShaderVertex(std::string_view vert, std::string_view frag);
|
||||
|
||||
virtual bool setProgramState(ax::backend::ProgramState* programState, bool needsRetain = true) override
|
||||
virtual bool setProgramState(ax::backend::ProgramState* programState, bool ownPS = false) override
|
||||
{
|
||||
if (Node::setProgramState(programState, needsRetain))
|
||||
if (Node::setProgramState(programState, ownPS))
|
||||
{
|
||||
_customCommand.getPipelineDescriptor().programState = programState;
|
||||
updateUniforms();
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://axmolengine.github.io/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#define STRINGIFY(A) #A
|
||||
static const char* shadertestvsh = STRINGIFY(
|
||||
|
||||
attribute vec4 a_position;
|
||||
|
||||
void main() { gl_Position = AX_MVPMatrix * a_position; }
|
||||
|
||||
);
|
|
@ -183,17 +183,9 @@ protected:
|
|||
|
||||
bool Effect::initProgramState(std::string_view fragmentFilename)
|
||||
{
|
||||
auto fileUtiles = FileUtils::getInstance();
|
||||
auto fragmentFullPath = fileUtiles->fullPathForFilename(fragmentFilename);
|
||||
auto fragSource = fileUtiles->getStringFromFile(fragmentFullPath);
|
||||
|
||||
#if (AX_TARGET_PLATFORM == AX_PLATFORM_ANDROID)
|
||||
_fragSource = fragSource;
|
||||
#endif
|
||||
auto program = ProgramManager::newProgram(positionTextureColor_vert, fragSource, VertexLayoutHelper::setupSprite);
|
||||
auto program = ProgramManager::getInstance()->loadProgram(positionTextureColor_vert, fragmentFilename, VertexLayoutType::Sprite);
|
||||
auto programState = new backend::ProgramState(program);
|
||||
AX_SAFE_RELEASE(_programState);
|
||||
AX_SAFE_RELEASE(program);
|
||||
_programState = programState;
|
||||
|
||||
return _programState != nullptr;
|
||||
|
@ -235,7 +227,7 @@ void EffectBlur::setTarget(EffectSprite* sprite)
|
|||
|
||||
bool EffectBlur::init(float blurRadius, float sampleNum)
|
||||
{
|
||||
initProgramState("Shaders/example_Blur.fsh");
|
||||
initProgramState("custom/example_Blur_fs");
|
||||
_blurRadius = blurRadius;
|
||||
_blurSampleNum = sampleNum;
|
||||
|
||||
|
@ -260,7 +252,7 @@ public:
|
|||
|
||||
bool init()
|
||||
{
|
||||
initProgramState("Shaders/example_Outline.fsh");
|
||||
initProgramState("custom/example_Outline_fs");
|
||||
|
||||
Vec3 color(1.0f, 0.2f, 0.3f);
|
||||
float radius = 0.01f;
|
||||
|
@ -282,7 +274,7 @@ public:
|
|||
protected:
|
||||
bool init()
|
||||
{
|
||||
initProgramState("Shaders/example_Noisy.fsh");
|
||||
initProgramState("custom/example_Noisy_fs");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -302,7 +294,7 @@ public:
|
|||
protected:
|
||||
bool init()
|
||||
{
|
||||
initProgramState("Shaders/example_EdgeDetection.fsh");
|
||||
initProgramState("custom/example_EdgeDetection_fs");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -322,7 +314,7 @@ public:
|
|||
protected:
|
||||
bool init()
|
||||
{
|
||||
initProgramState("Shaders/example_GreyScale.fsh");
|
||||
initProgramState("custom/example_GreyScale_fs");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -336,7 +328,7 @@ public:
|
|||
protected:
|
||||
bool init()
|
||||
{
|
||||
initProgramState("Shaders/example_Sepia.fsh");
|
||||
initProgramState("custom/example_Sepia_fs");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -350,7 +342,7 @@ public:
|
|||
protected:
|
||||
bool init()
|
||||
{
|
||||
initProgramState("Shaders/example_Bloom.fsh");
|
||||
initProgramState("custom/example_Bloom_fs");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -370,7 +362,7 @@ public:
|
|||
protected:
|
||||
bool init()
|
||||
{
|
||||
initProgramState("Shaders/example_CelShading.fsh");
|
||||
initProgramState("custom/example_CelShading_fs");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -390,7 +382,7 @@ public:
|
|||
protected:
|
||||
bool init()
|
||||
{
|
||||
initProgramState("Shaders/example_LensFlare.fsh");
|
||||
initProgramState("custom/example_LensFlare_fs");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -436,7 +428,7 @@ protected:
|
|||
|
||||
bool EffectNormalMapped::init()
|
||||
{
|
||||
initProgramState("Shaders3D/Normal.frag");
|
||||
initProgramState("custom/Normal_fs");
|
||||
_kBump = 2;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,437 +0,0 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://axmolengine.github.io/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#define STRINGIFY(A) #A
|
||||
|
||||
static const char* starFlame = STRINGIFY(
|
||||
|
||||
uniform vec2 center; uniform vec2 resolution;
|
||||
|
||||
vec2 iResolution = resolution; // viewport resolution (in pixels)
|
||||
float iGlobalTime = AX_Time[1]; // shader playback time (in seconds)
|
||||
// uniform float iChannelTime[4]; // channel playback time (in seconds)
|
||||
// uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)
|
||||
vec4 iMouse = vec4(0, 0, 0, 0); // mouse pixel coords. xy: current (if MLB down), zw: click
|
||||
// uniform sampler2D iChannel0; // input channel. XX = 2D/Cube
|
||||
|
||||
float noise(vec3 p) // Thx to Las^Mercury
|
||||
{
|
||||
vec3 i = floor(p);
|
||||
vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
|
||||
vec3 f = cos((p - i) * acos(-1.)) * (-.5) + .5;
|
||||
a = mix(sin(cos(a) * a), sin(cos(1. + a) * (1. + a)), f.x);
|
||||
a.xy = mix(a.xz, a.yw, f.y);
|
||||
return mix(a.x, a.y, f.z);
|
||||
}
|
||||
|
||||
float sphere(vec3 p, vec4 spr) { return length(spr.xyz - p) - spr.w; }
|
||||
|
||||
float flame(vec3 p) {
|
||||
float d = sphere(p * vec3(1., .5, 1.), vec4(.0, -1., .0, 1.));
|
||||
return d + (noise(p + vec3(.0, iGlobalTime * 2., .0)) + noise(p * 3.) * .5) * .25 * (p.y);
|
||||
}
|
||||
|
||||
float scene(vec3 p) { return min(100. - length(p), abs(flame(p))); }
|
||||
|
||||
vec4 raymarch(vec3 org, vec3 dir) {
|
||||
float d = 0.0;
|
||||
float glow = 0.0;
|
||||
float eps = 0.02;
|
||||
vec3 p = org;
|
||||
bool glowed = false;
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
d = scene(p) + eps;
|
||||
p += d * dir;
|
||||
if (d > eps)
|
||||
{
|
||||
if (flame(p) < .0)
|
||||
glowed = true;
|
||||
if (glowed)
|
||||
glow = float(i) / 64.;
|
||||
}
|
||||
}
|
||||
return vec4(p, glow);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 v = -1.0 + (2.0 * gl_FragCoord.xy) / iResolution.xy;
|
||||
// vec2 v = 2.0 * gl_FragCoord.xy / iResolution.xy;
|
||||
v.x *= iResolution.x / iResolution.y;
|
||||
|
||||
vec3 org = vec3(0., -2., 4.);
|
||||
vec3 dir = normalize(vec3(v.x * 1.6, -v.y, -1.5));
|
||||
|
||||
vec4 p = raymarch(org, dir);
|
||||
float glow = p.w;
|
||||
|
||||
vec4 col = mix(vec4(1., .5, .1, 1.), vec4(0.1, .5, 1., 1.), p.y * .02 + .4);
|
||||
|
||||
gl_FragColor = mix(vec4(0.), col, pow(glow * 2., 4.));
|
||||
// gl_FragColor = col;
|
||||
// gl_FragColor = mix(vec4(1.), mix(vec4(1.,.5,.1,1.),vec4(0.1,.5,1.,1.),p.y*.02+.4), pow(glow*2.,4.));
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
static const char* starNestFrg = STRINGIFY(
|
||||
|
||||
uniform vec2 center; uniform vec2 resolution;
|
||||
|
||||
vec2 iCenter = center;
|
||||
vec2 iResolution = resolution; // viewport resolution (in pixels)
|
||||
float iGlobalTime = AX_Time[1]; // shader playback time (in seconds)
|
||||
// uniform float iChannelTime[4]; // channel playback time (in seconds)
|
||||
// uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)
|
||||
vec4 iMouse = vec4(0, 0, 0, 0); // mouse pixel coords. xy: current (if MLB down), zw: click
|
||||
// uniform sampler2D iChannel0; // input channel. XX = 2D/Cube
|
||||
|
||||
// Star Nest by Pablo Román Andrioli
|
||||
|
||||
// This content is under the MIT License.
|
||||
|
||||
int iterations = 17;
|
||||
float formuparam = 0.53;
|
||||
|
||||
int volsteps = 20;
|
||||
float stepsize = 0.1;
|
||||
|
||||
float zoom = 0.800;
|
||||
float tile = 0.850;
|
||||
float speed = 0.010;
|
||||
|
||||
float brightness = 0.0015;
|
||||
float darkmatter = 0.300;
|
||||
float distfading = 0.730;
|
||||
float saturation = 0.850;
|
||||
|
||||
void main() {
|
||||
// iCenter = vec2(300, 300);
|
||||
// get coords and direction
|
||||
vec2 uv = gl_FragCoord.xy / iResolution.xy - .5;
|
||||
// vec2 uv=gl_FragCoord.xy/iResolution.xy ;
|
||||
// vec2 uv = ( 2* gl_FragCoord.xy - iCenter.xy) / resolution.xy;
|
||||
uv.y *= iResolution.y / iResolution.x;
|
||||
|
||||
// vec2 uv = 2.0* (gl_FragCoord.xy-iResolution.xy)/min(iResolution.y,iResolution.x);
|
||||
|
||||
vec3 dir = vec3(uv * zoom, 1.);
|
||||
float time = iGlobalTime * speed + .25;
|
||||
|
||||
// mouse rotation
|
||||
float a1 = .5 + iMouse.x / iResolution.x * 2.;
|
||||
float a2 = .8 + iMouse.y / iResolution.y * 2.;
|
||||
mat2 rot1 = mat2(cos(a1), sin(a1), -sin(a1), cos(a1));
|
||||
mat2 rot2 = mat2(cos(a2), sin(a2), -sin(a2), cos(a2));
|
||||
dir.xz *= rot1;
|
||||
dir.xy *= rot2;
|
||||
vec3 from = vec3(1., .5, 0.5);
|
||||
from += vec3(time * 2., time, -2.);
|
||||
from.xz *= rot1;
|
||||
from.xy *= rot2;
|
||||
|
||||
// volumetric rendering
|
||||
float s = 0.1;
|
||||
float fade = 1.;
|
||||
vec3 v = vec3(0.);
|
||||
for (int r = 0; r < volsteps; r++)
|
||||
{
|
||||
vec3 p = from + s * dir * .5;
|
||||
p = abs(vec3(tile) - mod(p, vec3(tile * 2.))); // tiling fold
|
||||
|
||||
float a = 0.;
|
||||
float pa = 0.;
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
p = abs(p) / dot(p, p) - formuparam; // the magic formula
|
||||
a += abs(length(p) - pa); // absolute sum of average change
|
||||
pa = length(p);
|
||||
}
|
||||
float dm = max(0., darkmatter - a * a * .001); // dark matter
|
||||
a *= a * a; // add contrast
|
||||
if (r > 6)
|
||||
fade *= 1. - dm; // dark matter, don't render near
|
||||
// v+=vec3(dm,dm*.5,0.);
|
||||
v += fade;
|
||||
v += vec3(s, s * s, s * s * s * s) * a * brightness * fade; // coloring based on distance
|
||||
fade *= distfading; // distance fading
|
||||
s += stepsize;
|
||||
}
|
||||
v = mix(vec3(length(v)), v, saturation); // color adjust
|
||||
gl_FragColor = vec4(v * .01, 1.);
|
||||
});
|
||||
|
||||
static const char* shadertoyRelentlessFrag = STRINGIFY(
|
||||
|
||||
uniform vec2 center; uniform vec2 resolution;
|
||||
|
||||
vec2 iCenter = center;
|
||||
vec2 iResolution = resolution; // viewport resolution (in pixels)
|
||||
float iGlobalTime = AX_Time[1]; // shader playback time (in seconds)
|
||||
// uniform float iChannelTime[4]; // channel playback time (in seconds)
|
||||
// uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)
|
||||
|
||||
vec4 iMouse = vec4(0, 0, 0, 0); // mouse pixel coords. xy: current (if MLB down), zw: click
|
||||
// uniform sampler2D iChannel0; // input channel. XX = 2D/Cube
|
||||
|
||||
// srtuss, 2013
|
||||
// collecting some design ideas for a new game project.
|
||||
// no raymarching is used.
|
||||
|
||||
// if i could add a custom soundtrack, it'd use this one (essential for desired sensation)
|
||||
// http://www.youtube.com/watch?v=1uFAu65tZpo
|
||||
|
||||
//#define GREEN_VERSION
|
||||
|
||||
// ** improved camera shaking
|
||||
// ** cleaned up code
|
||||
// ** added stuff to the gates
|
||||
|
||||
float time = iGlobalTime;
|
||||
|
||||
vec2 rotate(vec2 p, float a) {
|
||||
return vec2(p.x * cos(a) - p.y * sin(a), p.x * sin(a) + p.y * cos(a));
|
||||
} float box(vec2 p, vec2 b, float r) { return length(max(abs(p) - b, 0.0)) - r; }
|
||||
|
||||
// iq's ray-plane-intersection code
|
||||
vec3 intersect(in vec3 o, in vec3 d, vec3 c, vec3 u, vec3 v) {
|
||||
vec3 q = o - c;
|
||||
return vec3(dot(cross(u, v), q), dot(cross(q, u), d), dot(cross(v, q), d)) / dot(cross(v, u), d);
|
||||
}
|
||||
|
||||
// some noise functions for fast developing
|
||||
float rand11(float p) { return fract(sin(p * 591.32) * 43758.5357); }
|
||||
|
||||
float rand12(vec2 p) { return fract(sin(dot(p.xy, vec2(12.9898, 78.233))) * 43758.5357); }
|
||||
|
||||
vec2 rand21(float p) { return fract(vec2(sin(p * 591.32), cos(p * 391.32))); }
|
||||
|
||||
vec2 rand22(in vec2 p) { return fract(vec2(sin(p.x * 591.32 + p.y * 154.077), cos(p.x * 391.32 + p.y * 49.077))); }
|
||||
|
||||
float noise11(float p) {
|
||||
float fl = floor(p);
|
||||
return mix(rand11(fl), rand11(fl + 1.0), fract(p)); // smoothstep(0.0, 1.0, fract(p)));
|
||||
}
|
||||
|
||||
float fbm11(float p) { return noise11(p) * 0.5 + noise11(p * 2.0) * 0.25 + noise11(p * 5.0) * 0.125; }
|
||||
|
||||
vec3 noise31(float p) { return vec3(noise11(p), noise11(p + 18.952), noise11(p - 11.372)) * 2.0 - 1.0; }
|
||||
|
||||
// something that looks a bit like godrays coming from the surface
|
||||
float sky(vec3 p) {
|
||||
float a = atan(p.x, p.z);
|
||||
float t = time * 0.1;
|
||||
float v =
|
||||
rand11(floor(a * 4.0 + t)) * 0.5 + rand11(floor(a * 8.0 - t)) * 0.25 + rand11(floor(a * 16.0 + t)) * 0.125;
|
||||
return v;
|
||||
}
|
||||
|
||||
vec3 voronoi(in vec2 x) {
|
||||
vec2 n = floor(x); // grid cell id
|
||||
vec2 f = fract(x); // grid internal position
|
||||
vec2 mg; // shortest distance...
|
||||
vec2 mr; // ..and second shortest distance
|
||||
float md = 8.0;
|
||||
float md2 = 8.0;
|
||||
for (int j = -1; j <= 1; j++)
|
||||
{
|
||||
for (int i = -1; i <= 1; i++)
|
||||
{
|
||||
vec2 g = vec2(float(i), float(j)); // cell id
|
||||
vec2 o = rand22(n + g); // offset to edge point
|
||||
vec2 r = g + o - f;
|
||||
|
||||
float d = max(abs(r.x), abs(r.y)); // distance to the edge
|
||||
|
||||
if (d < md)
|
||||
{
|
||||
md2 = md;
|
||||
md = d;
|
||||
mr = r;
|
||||
mg = g;
|
||||
}
|
||||
else if (d < md2)
|
||||
{
|
||||
md2 = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vec3(n + mg, md2 - md);
|
||||
}
|
||||
|
||||
//#define A2V(a) vec2(sin((a) * 6.28318531 / 100.0), cos((a) * 6.28318531 / 100.0))
|
||||
vec2 A2V(float a) { return vec2(sin((a)*6.28318531 / 100.0), cos((a)*6.28318531 / 100.0)); }
|
||||
|
||||
float circles(vec2 p) {
|
||||
float v;
|
||||
float w;
|
||||
float l;
|
||||
float c;
|
||||
vec2 pp;
|
||||
l = length(p);
|
||||
|
||||
pp = rotate(p, time * 3.0);
|
||||
c = max(dot(pp, normalize(vec2(-0.2, 0.5))), -dot(pp, normalize(vec2(0.2, 0.5))));
|
||||
c = min(c, max(dot(pp, normalize(vec2(0.5, -0.5))), -dot(pp, normalize(vec2(0.2, -0.5)))));
|
||||
c = min(c, max(dot(pp, normalize(vec2(0.3, 0.5))), -dot(pp, normalize(vec2(0.2, 0.5)))));
|
||||
|
||||
// innerest stuff
|
||||
v = abs(l - 0.5) - 0.03;
|
||||
v = max(v, -c);
|
||||
v = min(v, abs(l - 0.54) - 0.02);
|
||||
v = min(v, abs(l - 0.64) - 0.05);
|
||||
|
||||
pp = rotate(p, time * -1.333);
|
||||
c = max(dot(pp, A2V(-5.0)), -dot(pp, A2V(5.0)));
|
||||
c = min(c, max(dot(pp, A2V(25.0 - 5.0)), -dot(pp, A2V(25.0 + 5.0))));
|
||||
c = min(c, max(dot(pp, A2V(50.0 - 5.0)), -dot(pp, A2V(50.0 + 5.0))));
|
||||
c = min(c, max(dot(pp, A2V(75.0 - 5.0)), -dot(pp, A2V(75.0 + 5.0))));
|
||||
|
||||
w = abs(l - 0.83) - 0.09;
|
||||
v = min(v, max(w, c));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
float shade1(float d) {
|
||||
float v = 1.0 - smoothstep(0.0, mix(0.012, 0.2, 0.0), d);
|
||||
float g = exp(d * -20.0);
|
||||
return v + g * 0.5;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = gl_FragCoord.xy / iResolution.xy;
|
||||
uv = uv * 2.0 - 1.0;
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
|
||||
// using an iq styled camera this time :)
|
||||
// ray origin
|
||||
vec3 ro = 0.7 * vec3(cos(0.2 * time), 0.0, sin(0.2 * time));
|
||||
ro.y = cos(0.6 * time) * 0.3 + 0.65;
|
||||
// camera look at
|
||||
vec3 ta = vec3(0.0, 0.2, 0.0);
|
||||
|
||||
// camera shake intensity
|
||||
float shake = clamp(3.0 * (1.0 - length(ro.yz)), 0.3, 1.0);
|
||||
float st = mod(time, 10.0) * 143.0;
|
||||
|
||||
// build camera matrix
|
||||
vec3 ww = normalize(ta - ro + noise31(st) * shake * 0.01);
|
||||
vec3 uu = normalize(cross(ww, normalize(vec3(0.0, 1.0, 0.2 * sin(time)))));
|
||||
vec3 vv = normalize(cross(uu, ww));
|
||||
// obtain ray direction
|
||||
vec3 rd = normalize(uv.x * uu + uv.y * vv + 1.0 * ww);
|
||||
|
||||
// shaking and movement
|
||||
ro += noise31(-st) * shake * 0.015;
|
||||
ro.x += time * 2.0;
|
||||
|
||||
float inten = 0.0;
|
||||
|
||||
// background
|
||||
float sd = dot(rd, vec3(0.0, 1.0, 0.0));
|
||||
inten = pow(1.0 - abs(sd), 20.0) + pow(sky(rd), 5.0) * step(0.0, rd.y) * 0.2;
|
||||
|
||||
vec3 its;
|
||||
float v;
|
||||
float g;
|
||||
|
||||
// voronoi floor layers
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float layer = float(i);
|
||||
its = intersect(ro, rd, vec3(0.0, -5.0 - layer * 5.0, 0.0), vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0));
|
||||
if (its.x > 0.0)
|
||||
{
|
||||
vec3 vo = voronoi((its.yz) * 0.05 + 8.0 * rand21(float(i)));
|
||||
v = exp(-100.0 * (vo.z - 0.02));
|
||||
|
||||
float fx = 0.0;
|
||||
|
||||
// add some special fx to lowest layer
|
||||
if (i == 3)
|
||||
{
|
||||
float crd = 0.0; // fract(time * 0.2) * 50.0 - 25.0;
|
||||
float fxi = cos(vo.x * 0.2 + time * 1.5); // abs(crd - vo.x);
|
||||
fx = clamp(smoothstep(0.9, 1.0, fxi), 0.0, 0.9) * 1.0 * rand12(vo.xy);
|
||||
fx *= exp(-3.0 * vo.z) * 2.0;
|
||||
}
|
||||
inten += v * 0.1 + fx;
|
||||
}
|
||||
}
|
||||
|
||||
// draw the gates, 4 should be enough
|
||||
float gatex = floor(ro.x / 8.0 + 0.5) * 8.0 + 4.0;
|
||||
float go = -16.0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
its = intersect(ro, rd, vec3(gatex + go, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0));
|
||||
if (dot(its.yz, its.yz) < 2.0 && its.x > 0.0)
|
||||
{
|
||||
v = circles(its.yz);
|
||||
inten += shade1(v);
|
||||
}
|
||||
|
||||
go += 8.0;
|
||||
}
|
||||
|
||||
// draw the stream
|
||||
for (int j = 0; j < 20; j++)
|
||||
{
|
||||
float id = float(j);
|
||||
|
||||
vec3 bp = vec3(0.0, (rand11(id) * 2.0 - 1.0) * 0.25, 0.0);
|
||||
vec3 its = intersect(ro, rd, bp, vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0));
|
||||
|
||||
if (its.x > 0.0)
|
||||
{
|
||||
vec2 pp = its.yz;
|
||||
float spd = (1.0 + rand11(id) * 3.0) * 2.5;
|
||||
pp.y += time * spd;
|
||||
pp += (rand21(id) * 2.0 - 1.0) * vec2(0.3, 1.0);
|
||||
float rep = rand11(id) + 1.5;
|
||||
pp.y = mod(pp.y, rep * 2.0) - rep;
|
||||
float d = box(pp, vec2(0.02, 0.3), 0.1);
|
||||
float foc = 0.0;
|
||||
float v = 1.0 - smoothstep(0.0, 0.03, abs(d) - 0.001);
|
||||
float g = min(exp(d * -20.0), 2.0);
|
||||
|
||||
inten += (v + g * 0.7) * 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
inten *= 0.4 + (sin(time) * 0.5 + 0.5) * 0.6;
|
||||
|
||||
// find a color for the computed intensity
|
||||
#ifdef GREEN_VERSION
|
||||
vec3 col = pow(vec3(inten), vec3(2.0, 0.15, 9.0));
|
||||
#else
|
||||
vec3 col = pow(vec3(inten), 1.5 * vec3(0.15, 2.0, 9.0));
|
||||
#endif
|
||||
|
||||
gl_FragColor = vec4(col, 1.0);
|
||||
}
|
||||
|
||||
);
|
|
@ -28,7 +28,6 @@
|
|||
#include <fstream>
|
||||
#include <string.h>
|
||||
#include "spine/spine.h"
|
||||
#include "renderer/Colorizer.h"
|
||||
|
||||
USING_NS_AX;
|
||||
using namespace std;
|
||||
|
@ -146,7 +145,6 @@ bool SpineTestLayer::init()
|
|||
SET_UNIFORM(skeleton1PS, "resolution", resolution);
|
||||
SET_UNIFORM(skeleton1PS, "blurRadius", blurRadius);
|
||||
SET_UNIFORM(skeleton1PS, "sampleNum", sampleNum);
|
||||
skeleton1PS->hashOfUniforms();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -364,7 +362,11 @@ bool MixAndMatchExample::init()
|
|||
|
||||
SCALE_SKELETON_NODE(skeletonNode);
|
||||
|
||||
Colorizer::enableNodeIntelliShading(skeletonNode, Vec3(92.0f, 1.0f, 1.2f), Vec3::ZERO);
|
||||
// load hsv as custom, we don't want batch draw
|
||||
auto hsvProg = ProgramManager::getInstance()->loadProgram(positionTextureColor_vert, hsv_frag);
|
||||
auto ps1 = new backend::ProgramState(hsvProg);
|
||||
SET_UNIFORM(ps1, "u_hsv", Vec3(92.0f, 1.0f, 1.2f));
|
||||
skeletonNode->setProgramState(ps1, true);
|
||||
|
||||
/* -------- skeletonNode2 with same spine animation file ------------ */
|
||||
auto skeletonNode2 = SkeletonAnimation::createWithBinaryFile("mix-and-match-pro.skel", "mix-and-match.atlas", 0.5);
|
||||
|
@ -392,7 +394,9 @@ bool MixAndMatchExample::init()
|
|||
|
||||
SCALE_SKELETON_NODE(skeletonNode2);
|
||||
|
||||
Colorizer::enableNodeIntelliShading(skeletonNode2, Vec3(45.0f, 1.0f, 1.2f), Vec3::ZERO);
|
||||
auto ps2 = new backend::ProgramState(hsvProg);
|
||||
SET_UNIFORM(ps2, "u_hsv", Vec3(-45.0f, 1.0f, 1.2f));
|
||||
skeletonNode2->setProgramState(ps2, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -516,11 +520,9 @@ bool SpineboyExample::init()
|
|||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
||||
addChild(skeletonNode);
|
||||
|
||||
auto programCache = backend::ProgramCache::getInstance();
|
||||
programCache->registerCustomProgram(101, positionTextureColor_vert,
|
||||
FileUtils::getInstance()->getStringFromFile("Shaders/example_Blur.fsh"), VertexLayoutHelper::setupSprite);
|
||||
auto program = programCache->getCustomProgram(101);
|
||||
skeletonNode->setProgramState(new backend::ProgramState(program), false);
|
||||
auto program = ProgramManager::getInstance()->loadProgram(positionTextureColor_vert, "custom/example_Blur_fs",
|
||||
VertexLayoutType::Sprite);
|
||||
skeletonNode->setProgramState(new backend::ProgramState(program), true);
|
||||
|
||||
//auto skeleton1PS = skeletonNode->getProgramState();
|
||||
|
||||
|
|
|
@ -722,13 +722,9 @@ function FogTestDemo:createLayer3D()
|
|||
self:addChild(layer3D,0)
|
||||
self._layer3D = layer3D
|
||||
|
||||
local vertexShader = cc.FileUtils:getInstance():getStringFromFile("MeshRendererTest/fog.vert")
|
||||
local fragmentShader = cc.FileUtils:getInstance():getStringFromFile("MeshRendererTest/fog.frag")
|
||||
|
||||
local program = ccb.Device:getInstance():newProgram(vertexShader, fragmentShader)
|
||||
local program = axb.ProgramManager:getInstance():loadProgram('custom/fog_vs', 'custom/fog_fs')
|
||||
self._shader1 = ccb.ProgramState:new(program)
|
||||
self._shader2 = self._shader1:clone()
|
||||
program:release()
|
||||
|
||||
self._sprite3D1 = cc.Sprite3D:create("MeshRendererTest/teapot.c3b")
|
||||
self._sprite3D2 = cc.Sprite3D:create("MeshRendererTest/teapot.c3b")
|
||||
|
|
|
@ -312,11 +312,8 @@ function Scene3DTest:create3DWorld()
|
|||
--then, create skybox
|
||||
--create and set our custom shader
|
||||
|
||||
local cmVert = cc.FileUtils:getInstance():getStringFromFile("MeshRendererTest/cube_map.vert")
|
||||
local cmFrag = cc.FileUtils:getInstance():getStringFromFile("MeshRendererTest/cube_map.frag")
|
||||
local program = ccb.Device:getInstance():newProgram(cmVert, cmFrag)
|
||||
local program = axb.ProgramManager:getInstance():loadProgram('custom/cube_map_vs', 'custom/cube_map_fs')
|
||||
local state = ccb.ProgramState:new(program)
|
||||
program:release()
|
||||
--create the second texture for cylinder
|
||||
self._textureCube = cc.TextureCube:create("MeshRendererTest/skybox/left.jpg", "MeshRendererTest/skybox/right.jpg",
|
||||
"MeshRendererTest/skybox/top.jpg", "MeshRendererTest/skybox/bottom.jpg",
|
||||
|
|
|
@ -1123,11 +1123,8 @@ function Sprite3DCubeMapTest:addNewSpriteWithCoords(pos)
|
|||
--create a teapot
|
||||
self._teapot = cc.Sprite3D:create("MeshRendererTest/teapot.c3b")
|
||||
|
||||
local vertexShader = cc.FileUtils:getInstance():getStringFromFile("MeshRendererTest/cube_map.vert")
|
||||
local fragmentShader = cc.FileUtils:getInstance():getStringFromFile("MeshRendererTest/cube_map.frag")
|
||||
local program = ccb.Device:getInstance():newProgram(vertexShader, fragmentShader)
|
||||
local program = axb.ProgramManager:getInstance():loadProgram('custom/cube_map_vs', 'custom/cube_map_fs')
|
||||
local programState = ccb.ProgramState:new(program)
|
||||
program:release()
|
||||
|
||||
self._textureCube = cc.TextureCube:create("MeshRendererTest/skybox/left.jpg", "MeshRendererTest/skybox/right.jpg",
|
||||
"MeshRendererTest/skybox/top.jpg", "MeshRendererTest/skybox/bottom.jpg",
|
||||
|
|
|
@ -157,16 +157,18 @@ bool DrawNode3D::init()
|
|||
|
||||
const auto& attributeInfo = _programState->getProgram()->getActiveAttributes();
|
||||
auto iter = attributeInfo.find("a_position");
|
||||
auto vertexLayout = _programState->getMutableVertexLayout();
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
_programState->setVertexAttrib(iter->first, iter->second.location, backend::VertexFormat::FLOAT3, 0, false);
|
||||
vertexLayout->setAttrib(iter->first, iter->second.location, backend::VertexFormat::FLOAT3, 0, false);
|
||||
}
|
||||
iter = attributeInfo.find("a_color");
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
_programState->setVertexAttrib(iter->first, iter->second.location, backend::VertexFormat::UBYTE4, sizeof(Vec3), true);
|
||||
vertexLayout->setAttrib(iter->first, iter->second.location, backend::VertexFormat::UBYTE4, sizeof(Vec3),
|
||||
true);
|
||||
}
|
||||
_programState->setVertexStride(sizeof(V3F_C4B));
|
||||
vertexLayout->setStride(sizeof(V3F_C4B));
|
||||
|
||||
_customCommand.createVertexBuffer(sizeof(V3F_C4B), INITIAL_VERTEX_BUFFER_LENGTH,
|
||||
CustomCommand::BufferUsage::DYNAMIC);
|
||||
|
|
Loading…
Reference in New Issue