mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2026-01-10 02:06:52 +00:00
初始化
This commit is contained in:
192
cocos2d-x/cocos/renderer/Macro.h
Normal file
192
cocos2d-x/cocos/renderer/Macro.h
Normal file
@@ -0,0 +1,192 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
#ifndef RENDERER_BEGIN
|
||||
#define RENDERER_BEGIN namespace cocos2d { namespace renderer {
|
||||
#endif // RENDERER_BEGIN
|
||||
|
||||
#ifndef RENDERER_END
|
||||
#define RENDERER_END }}
|
||||
#endif // RENDERER_END
|
||||
|
||||
//#ifndef DISALLOW_COPY_ASSIGN_AND_MOVE
|
||||
#define CC_DISALLOW_COPY_ASSIGN_AND_MOVE(type) \
|
||||
type(const type&) = delete; \
|
||||
type& operator =(const type&) = delete; \
|
||||
type(type &&) = delete; \
|
||||
type& operator =(const type &&) = delete;
|
||||
//#endif // DISALLOW_COPY_ASSIGN_AND_MOVE
|
||||
|
||||
#define RENDERER_LOG_TAG "renderer"
|
||||
#define RENDERER_QUOTEME_(x) #x
|
||||
#define RENDERER_QUOTEME(x) RENDERER_QUOTEME_(x)
|
||||
|
||||
#if defined(COCOS2D_DEBUG) && COCOS2D_DEBUG > 0
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#define RENDERER_LOGV(fmt, ...) __android_log_print(ANDROID_LOG_VERBOSE, RENDERER_LOG_TAG, " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define RENDERER_LOGV(fmt, ...) printf("V/" RENDERER_LOG_TAG " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
|
||||
#endif // (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#else
|
||||
#define RENDERER_LOGV(fmt, ...) do {} while(false)
|
||||
#endif // defined(COCOS2D_DEBUG) && COCOS2D_DEBUG > 0
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#define RENDERER_LOGD(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, RENDERER_LOG_TAG, " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
|
||||
#define RENDERER_LOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, RENDERER_LOG_TAG, " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
|
||||
#define RENDERER_LOGW(fmt, ...) __android_log_print(ANDROID_LOG_WARN, RENDERER_LOG_TAG, " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
|
||||
#define RENDERER_LOGE(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, RENDERER_LOG_TAG, " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define RENDERER_LOGD(fmt, ...) printf("D/" RENDERER_LOG_TAG " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
|
||||
#define RENDERER_LOGI(fmt, ...) printf("I/" RENDERER_LOG_TAG " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
|
||||
#define RENDERER_LOGW(fmt, ...) printf("W/" RENDERER_LOG_TAG " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
|
||||
#define RENDERER_LOGE(fmt, ...) printf("E/" RENDERER_LOG_TAG " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
|
||||
#endif // (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
|
||||
|
||||
#define RENDERER_DEBUG 1 // REFINE: remove this
|
||||
|
||||
#define RENDERER_SAFE_RELEASE(p) do { if((p) != nullptr) (p)->release(); } while(false)
|
||||
#define RENDERER_SAFE_RETAIN(p) do { if((p) != nullptr) (p)->retain(); } while(false)
|
||||
|
||||
#define RENDERER_DEFINE_CREATE_METHOD_0(clsName, initMethod) \
|
||||
static clsName* create() \
|
||||
{ \
|
||||
clsName* ret = new (std::nothrow) clsName(); \
|
||||
if (ret && ret->initMethod()) \
|
||||
{ \
|
||||
ret->autorelease(); \
|
||||
return ret; \
|
||||
} \
|
||||
delete ret; \
|
||||
return nullptr; \
|
||||
}
|
||||
|
||||
#define RENDERER_DEFINE_CREATE_METHOD_1(clsName, initMethod, arg0Type) \
|
||||
static clsName* create(arg0Type arg0) \
|
||||
{ \
|
||||
clsName* ret = new (std::nothrow) clsName(); \
|
||||
if (ret && ret->initMethod(arg0)) \
|
||||
{ \
|
||||
ret->autorelease(); \
|
||||
return ret; \
|
||||
} \
|
||||
delete ret; \
|
||||
return nullptr; \
|
||||
}
|
||||
|
||||
#define RENDERER_DEFINE_CREATE_METHOD_2(clsName, initMethod, arg0Type, arg1Type) \
|
||||
static clsName* create(arg0Type arg0, arg1Type arg1) \
|
||||
{ \
|
||||
clsName* ret = new (std::nothrow) clsName(); \
|
||||
if (ret && ret->initMethod(arg0, arg1)) \
|
||||
{ \
|
||||
ret->autorelease(); \
|
||||
return ret; \
|
||||
} \
|
||||
delete ret; \
|
||||
return nullptr; \
|
||||
}
|
||||
|
||||
#define RENDERER_DEFINE_CREATE_METHOD_3(clsName, initMethod, arg0Type, arg1Type, arg2Type) \
|
||||
static clsName* create(arg0Type arg0, arg1Type arg1, arg2Type arg2) \
|
||||
{ \
|
||||
clsName* ret = new (std::nothrow) clsName(); \
|
||||
if (ret && ret->initMethod(arg0, arg1, arg2)) \
|
||||
{ \
|
||||
ret->autorelease(); \
|
||||
return ret; \
|
||||
} \
|
||||
delete ret; \
|
||||
return nullptr; \
|
||||
}
|
||||
|
||||
#define RENDERER_DEFINE_CREATE_METHOD_4(clsName, initMethod, arg0Type, arg1Type, arg2Type, arg3Type) \
|
||||
static clsName* create(arg0Type arg0, arg1Type arg1, arg2Type arg2, arg3Type arg3) \
|
||||
{ \
|
||||
clsName* ret = new (std::nothrow) clsName(); \
|
||||
if (ret && ret->initMethod(arg0, arg1, arg2, arg3)) \
|
||||
{ \
|
||||
ret->autorelease(); \
|
||||
return ret; \
|
||||
} \
|
||||
delete ret; \
|
||||
return nullptr; \
|
||||
}
|
||||
|
||||
#define RENDERER_DEFINE_CREATE_METHOD_5(clsName, initMethod, arg0Type, arg1Type, arg2Type, arg3Type, arg4Type) \
|
||||
static clsName* create(arg0Type arg0, arg1Type arg1, arg2Type arg2, arg3Type arg3, arg4Type arg4) \
|
||||
{ \
|
||||
clsName* ret = new (std::nothrow) clsName(); \
|
||||
if (ret && ret->initMethod(arg0, arg1, arg2, arg3, arg4)) \
|
||||
{ \
|
||||
ret->autorelease(); \
|
||||
return ret; \
|
||||
} \
|
||||
delete ret; \
|
||||
return nullptr; \
|
||||
}
|
||||
|
||||
#define RENDERER_DEFINE_CREATE_METHOD_6(clsName, initMethod, arg0Type, arg1Type, arg2Type, arg3Type, arg4Type, arg5Type) \
|
||||
static clsName* create(arg0Type arg0, arg1Type arg1, arg2Type arg2, arg3Type arg3, arg4Type arg4, arg5Type arg5) \
|
||||
{ \
|
||||
clsName* ret = new (std::nothrow) clsName(); \
|
||||
if (ret && ret->initMethod(arg0, arg1, arg2, arg3, arg4, arg5)) \
|
||||
{ \
|
||||
ret->autorelease(); \
|
||||
return ret; \
|
||||
} \
|
||||
delete ret; \
|
||||
return nullptr; \
|
||||
}
|
||||
|
||||
// enum class to GLENUM
|
||||
#define ENUM_CLASS_TO_GLENUM(value) static_cast<GLenum>(value)
|
||||
|
||||
#define _GL_CHECK(_call) \
|
||||
do { \
|
||||
_call; \
|
||||
GLenum gl_err = glGetError(); \
|
||||
if (0 != gl_err) \
|
||||
RENDERER_LOGE(#_call "; GL error 0x%x: %s:%s", gl_err, glEnumName(gl_err), __FUNCTION__); \
|
||||
} while(false)
|
||||
|
||||
|
||||
#if COCOS2D_DEBUG > 0
|
||||
# define GL_CHECK(_call) _GL_CHECK(_call)
|
||||
#else
|
||||
# define GL_CHECK(_call) _call
|
||||
#endif // BRENDERER_CONFIG_DEBUG
|
||||
|
||||
#ifndef RENDERER_PI
|
||||
#define RENDERER_PI 3.1415926535897932385f
|
||||
#endif // RENDERER_PI
|
||||
87
cocos2d-x/cocos/renderer/Types.cpp
Normal file
87
cocos2d-x/cocos/renderer/Types.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
const char* ATTRIB_NAME_POSITION = "a_position";
|
||||
const char* ATTRIB_NAME_NORMAL = "a_normal";
|
||||
const char* ATTRIB_NAME_TANGENT = "a_tangent";
|
||||
const char* ATTRIB_NAME_BITANGENT = "a_bitangent";
|
||||
const char* ATTRIB_NAME_WEIGHTS = "a_weights";
|
||||
const char* ATTRIB_NAME_JOINTS = "a_joints";
|
||||
const char* ATTRIB_NAME_COLOR = "a_color";
|
||||
const char* ATTRIB_NAME_COLOR0 = "a_color0";
|
||||
const char* ATTRIB_NAME_COLOR1 = "a_color1";
|
||||
const char* ATTRIB_NAME_UV = "a_uv";
|
||||
const char* ATTRIB_NAME_UV0 = "a_uv0";
|
||||
const char* ATTRIB_NAME_UV1 = "a_uv1";
|
||||
const char* ATTRIB_NAME_UV2 = "a_uv2";
|
||||
const char* ATTRIB_NAME_UV3 = "a_uv3";
|
||||
const char* ATTRIB_NAME_UV4 = "a_uv4";
|
||||
const char* ATTRIB_NAME_UV5 = "a_uv5";
|
||||
const char* ATTRIB_NAME_UV6 = "a_uv6";
|
||||
const char* ATTRIB_NAME_UV7 = "a_uv7";
|
||||
|
||||
const size_t ATTRIB_NAME_POSITION_HASH = std::hash<std::string>{}(ATTRIB_NAME_POSITION);
|
||||
const size_t ATTRIB_NAME_NORMAL_HASH = std::hash<std::string>{}(ATTRIB_NAME_NORMAL);
|
||||
const size_t ATTRIB_NAME_TANGENT_HASH = std::hash<std::string>{}(ATTRIB_NAME_TANGENT);
|
||||
const size_t ATTRIB_NAME_BITANGENT_HASH = std::hash<std::string>{}(ATTRIB_NAME_BITANGENT);
|
||||
const size_t ATTRIB_NAME_WEIGHTS_HASH = std::hash<std::string>{}(ATTRIB_NAME_WEIGHTS);
|
||||
const size_t ATTRIB_NAME_JOINTS_HASH = std::hash<std::string>{}(ATTRIB_NAME_JOINTS);
|
||||
const size_t ATTRIB_NAME_COLOR_HASH = std::hash<std::string>{}(ATTRIB_NAME_COLOR);
|
||||
const size_t ATTRIB_NAME_COLOR0_HASH = std::hash<std::string>{}(ATTRIB_NAME_COLOR0);
|
||||
const size_t ATTRIB_NAME_COLOR1_HASH = std::hash<std::string>{}(ATTRIB_NAME_COLOR1);
|
||||
const size_t ATTRIB_NAME_UV_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV);
|
||||
const size_t ATTRIB_NAME_UV0_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV0);
|
||||
const size_t ATTRIB_NAME_UV1_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV1);
|
||||
const size_t ATTRIB_NAME_UV2_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV2);
|
||||
const size_t ATTRIB_NAME_UV3_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV3);
|
||||
const size_t ATTRIB_NAME_UV4_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV4);
|
||||
const size_t ATTRIB_NAME_UV5_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV5);
|
||||
const size_t ATTRIB_NAME_UV6_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV6);
|
||||
const size_t ATTRIB_NAME_UV7_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV7);
|
||||
|
||||
Rect Rect::ZERO;
|
||||
|
||||
Rect::Rect()
|
||||
{}
|
||||
|
||||
Rect::Rect(float x, float y, float w, float h)
|
||||
: x(x)
|
||||
, y(y)
|
||||
, w(w)
|
||||
, h(h)
|
||||
{}
|
||||
|
||||
void Rect::set(float x, float y, float w, float h)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->w = w;
|
||||
this->h = h;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
222
cocos2d-x/cocos/renderer/Types.h
Normal file
222
cocos2d-x/cocos/renderer/Types.h
Normal file
@@ -0,0 +1,222 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <new>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include "base/CCValue.h"
|
||||
|
||||
#include "Macro.h"
|
||||
#include "platform/CCGL.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
enum ClearFlag : uint8_t
|
||||
{
|
||||
NONE = 0x00, // No clear flags.
|
||||
COLOR = 0x01, // Clear color.
|
||||
DEPTH = 0x02, // Clear depth.
|
||||
STENCIL = 0x04 // Clear stencil.
|
||||
};
|
||||
|
||||
enum class ComparisonFunc : uint16_t
|
||||
{
|
||||
NEVER = GL_NEVER,
|
||||
LESS = GL_LESS,
|
||||
EQUAL = GL_EQUAL,
|
||||
LESS_EQUAL = GL_LEQUAL,
|
||||
GREATER = GL_GREATER,
|
||||
NOT_EQUAL = GL_NOTEQUAL,
|
||||
GREATOR_EQUAL = GL_GEQUAL,
|
||||
ALWAYS = GL_ALWAYS
|
||||
};
|
||||
typedef ComparisonFunc DepthFunc;
|
||||
typedef ComparisonFunc StencilFunc;
|
||||
typedef ComparisonFunc SamplerFunc;
|
||||
|
||||
enum class StencilOp : uint16_t
|
||||
{
|
||||
ZERO = GL_ZERO,
|
||||
KEEP = GL_KEEP,
|
||||
REPLACE = GL_REPLACE,
|
||||
INCR = GL_INCR,
|
||||
DECR = GL_DECR,
|
||||
INVERT = GL_INVERT,
|
||||
|
||||
// Does these two belongs to stencil operation?
|
||||
INCR_WRAP = GL_INCR_WRAP,
|
||||
DECR_WRAP = GL_DECR_WRAP
|
||||
};
|
||||
|
||||
enum class BlendFactor : uint16_t
|
||||
{
|
||||
ZERO = GL_ZERO,
|
||||
ONE = GL_ONE,
|
||||
SRC_COLOR = GL_SRC_COLOR,
|
||||
ONE_MINUS_SRC_COLOR = GL_ONE_MINUS_SRC_COLOR,
|
||||
SRC_ALPHA = GL_SRC_ALPHA,
|
||||
ONE_MINUS_SRC_ALPHA = GL_ONE_MINUS_SRC_ALPHA,
|
||||
DST_ALPHA = GL_DST_ALPHA,
|
||||
ONE_MINUS_DST_ALPHA = GL_ONE_MINUS_DST_ALPHA,
|
||||
DST_COLOR = GL_DST_COLOR,
|
||||
ONE_MINUS_DST_COLOR = GL_ONE_MINUS_DST_COLOR,
|
||||
SRC_ALPHA_SATURATE = GL_SRC_ALPHA_SATURATE,
|
||||
|
||||
CONSTANT_COLOR = GL_CONSTANT_COLOR,
|
||||
ONE_MINUS_CONSTANT_COLOR = GL_ONE_MINUS_CONSTANT_COLOR,
|
||||
CONSTANT_ALPHA = GL_CONSTANT_ALPHA,
|
||||
ONE_MINUS_CONSTANT_ALPHA = GL_ONE_MINUS_CONSTANT_ALPHA
|
||||
};
|
||||
enum class BlendOp : uint16_t
|
||||
{
|
||||
ADD = GL_FUNC_ADD,
|
||||
SUBTRACT = GL_FUNC_SUBTRACT,
|
||||
REVERSE_SUBTRACT = GL_FUNC_REVERSE_SUBTRACT
|
||||
};
|
||||
|
||||
enum class CullMode : uint16_t
|
||||
{
|
||||
NONE = GL_NONE,
|
||||
BACK = GL_BACK,
|
||||
FRONT = GL_FRONT,
|
||||
FRONT_AND_BACK = GL_FRONT_AND_BACK
|
||||
};
|
||||
|
||||
enum class PrimitiveType : uint16_t
|
||||
{
|
||||
POINTS = GL_POINTS,
|
||||
LINES = GL_LINES,
|
||||
LINE_LOOP = GL_LINE_LOOP,
|
||||
LINE_STRIP = GL_LINE_STRIP,
|
||||
TRIANGLES = GL_TRIANGLES,
|
||||
TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
|
||||
TRIANGLE_FAN = GL_TRIANGLE_FAN
|
||||
};
|
||||
|
||||
enum class Usage : uint16_t
|
||||
{
|
||||
STATIC = GL_STATIC_DRAW,
|
||||
DYNAMIC = GL_DYNAMIC_DRAW,
|
||||
STREAM = GL_STREAM_DRAW
|
||||
};
|
||||
|
||||
enum class IndexFormat : uint16_t
|
||||
{
|
||||
UINT8 = GL_UNSIGNED_BYTE,
|
||||
UINT16 = GL_UNSIGNED_SHORT,
|
||||
UINT32 = GL_UNSIGNED_INT// (OES_element_index_uint)
|
||||
};
|
||||
|
||||
// vertex attribute semantic
|
||||
|
||||
extern const char* ATTRIB_NAME_POSITION;
|
||||
extern const char* ATTRIB_NAME_NORMAL;
|
||||
extern const char* ATTRIB_NAME_TANGENT;
|
||||
extern const char* ATTRIB_NAME_BITANGENT;
|
||||
extern const char* ATTRIB_NAME_WEIGHTS;
|
||||
extern const char* ATTRIB_NAME_JOINTS;
|
||||
extern const char* ATTRIB_NAME_COLOR;
|
||||
extern const char* ATTRIB_NAME_COLOR0;
|
||||
extern const char* ATTRIB_NAME_COLOR1;
|
||||
extern const char* ATTRIB_NAME_UV;
|
||||
extern const char* ATTRIB_NAME_UV0;
|
||||
extern const char* ATTRIB_NAME_UV1;
|
||||
extern const char* ATTRIB_NAME_UV2;
|
||||
extern const char* ATTRIB_NAME_UV3;
|
||||
extern const char* ATTRIB_NAME_UV4;
|
||||
extern const char* ATTRIB_NAME_UV5;
|
||||
extern const char* ATTRIB_NAME_UV6;
|
||||
extern const char* ATTRIB_NAME_UV7;
|
||||
|
||||
extern const size_t ATTRIB_NAME_POSITION_HASH;
|
||||
extern const size_t ATTRIB_NAME_NORMAL_HASH;
|
||||
extern const size_t ATTRIB_NAME_TANGENT_HASH;
|
||||
extern const size_t ATTRIB_NAME_BITANGENT_HASH;
|
||||
extern const size_t ATTRIB_NAME_WEIGHTS_HASH;
|
||||
extern const size_t ATTRIB_NAME_JOINTS_HASH;
|
||||
extern const size_t ATTRIB_NAME_COLOR_HASH;
|
||||
extern const size_t ATTRIB_NAME_COLOR0_HASH;
|
||||
extern const size_t ATTRIB_NAME_COLOR1_HASH;
|
||||
extern const size_t ATTRIB_NAME_UV_HASH;
|
||||
extern const size_t ATTRIB_NAME_UV0_HASH;
|
||||
extern const size_t ATTRIB_NAME_UV1_HASH;
|
||||
extern const size_t ATTRIB_NAME_UV2_HASH;
|
||||
extern const size_t ATTRIB_NAME_UV3_HASH;
|
||||
extern const size_t ATTRIB_NAME_UV4_HASH;
|
||||
extern const size_t ATTRIB_NAME_UV5_HASH;
|
||||
extern const size_t ATTRIB_NAME_UV6_HASH;
|
||||
extern const size_t ATTRIB_NAME_UV7_HASH;
|
||||
|
||||
// vertex attribute type
|
||||
enum class AttribType : uint16_t
|
||||
{
|
||||
INVALID = 0,
|
||||
INT8 = GL_BYTE,
|
||||
UINT8 = GL_UNSIGNED_BYTE,
|
||||
INT16 = GL_SHORT,
|
||||
UINT16 = GL_UNSIGNED_SHORT,
|
||||
INT32 = GL_INT,
|
||||
UINT32 = GL_UNSIGNED_INT,
|
||||
FLOAT32 = GL_FLOAT
|
||||
};
|
||||
|
||||
enum class UniformElementType : uint8_t
|
||||
{
|
||||
FLOAT,
|
||||
INT
|
||||
};
|
||||
|
||||
enum class ProjectionType : uint8_t
|
||||
{
|
||||
PERSPECTIVE,
|
||||
ORTHOGRAPHIC
|
||||
};
|
||||
|
||||
struct Define
|
||||
{
|
||||
std::string key;
|
||||
Value value;
|
||||
};
|
||||
typedef std::vector<Define> DefineVector;
|
||||
|
||||
struct Rect
|
||||
{
|
||||
Rect();
|
||||
Rect(float x, float y, float w, float h);
|
||||
|
||||
void set(float x, float y, float w, float h);
|
||||
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
float w = 0;
|
||||
float h = 0;
|
||||
|
||||
static Rect ZERO;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
1186
cocos2d-x/cocos/renderer/gfx/DeviceGraphics.cpp
Normal file
1186
cocos2d-x/cocos/renderer/gfx/DeviceGraphics.cpp
Normal file
File diff suppressed because it is too large
Load Diff
365
cocos2d-x/cocos/renderer/gfx/DeviceGraphics.h
Normal file
365
cocos2d-x/cocos/renderer/gfx/DeviceGraphics.h
Normal file
@@ -0,0 +1,365 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include "base/ccTypes.h"
|
||||
#include "base/CCRef.h"
|
||||
#include "math/Vec2.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Vec4.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
#include "State.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class FrameBuffer;
|
||||
class VertexBuffer;
|
||||
class IndexBuffer;
|
||||
class Program;
|
||||
class Texture;
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* DeviceGraphics is a direct abstraction for OpenGL APIs.
|
||||
* This fundamental class takes responsibility for all GL states management and GL call invocations.
|
||||
*/
|
||||
class DeviceGraphics final : public Ref
|
||||
{
|
||||
public:
|
||||
struct Capacity
|
||||
{
|
||||
int maxVextexTextures;
|
||||
int maxFragUniforms;
|
||||
int maxTextureUnits;
|
||||
int maxVertexAttributes;
|
||||
int maxDrawBuffers;
|
||||
int maxColorAttatchments;
|
||||
};
|
||||
|
||||
struct Uniform
|
||||
{
|
||||
Uniform(const void* v, size_t bytes, UniformElementType elementType_, size_t count);
|
||||
Uniform(Uniform&& h);
|
||||
Uniform();
|
||||
~Uniform();
|
||||
|
||||
Uniform& operator=(Uniform&& h);
|
||||
|
||||
void setValue(const void* v, size_t bytes, size_t count = 1);
|
||||
|
||||
void* value = nullptr;
|
||||
size_t bytes = 0;
|
||||
size_t count = 0;
|
||||
|
||||
bool dirty;
|
||||
UniformElementType elementType;
|
||||
|
||||
private:
|
||||
// Disable copy operator
|
||||
Uniform& operator=(const Uniform& o);
|
||||
};
|
||||
|
||||
/**
|
||||
* .
|
||||
*/
|
||||
static void destroy();
|
||||
|
||||
/**
|
||||
* Returns a shared instance of the director.
|
||||
*/
|
||||
static DeviceGraphics* getInstance();
|
||||
|
||||
/**
|
||||
* Sets the target FrameBuffer
|
||||
*/
|
||||
void setFrameBuffer(const FrameBuffer* fb);
|
||||
/**
|
||||
* Sets viewport with x, y, width and height
|
||||
*/
|
||||
void setViewport(int x, int y, int w, int h);
|
||||
/**
|
||||
* Sets scissor clipping area
|
||||
*/
|
||||
void setScissor(int x, int y, int w, int h);
|
||||
|
||||
/**
|
||||
* Clear with flags, including color, depth and stencil,
|
||||
* you should also specify the color, depth and stencil value to use.
|
||||
*/
|
||||
void clear(uint8_t flags, Color4F *color, double depth, int32_t stencil);
|
||||
|
||||
/**
|
||||
* Enables blend in GL state
|
||||
*/
|
||||
void enableBlend();
|
||||
/**
|
||||
* Enables depth test in GL state
|
||||
*/
|
||||
void enableDepthTest();
|
||||
/**
|
||||
* Enables depth write in GL state
|
||||
*/
|
||||
void enableDepthWrite();
|
||||
/**
|
||||
* Enables stencil test in GL state
|
||||
*/
|
||||
void enableStencilTest();
|
||||
|
||||
/**
|
||||
* Sets both the front and back function and reference value for stencil testing
|
||||
*/
|
||||
void setStencilFunc(StencilFunc func, int ref, unsigned int mask);
|
||||
/**
|
||||
* Sets the front function and reference value for stencil testing
|
||||
*/
|
||||
void setStencilFuncFront(StencilFunc func, int ref, unsigned int mask);
|
||||
/**
|
||||
* Sets the back function and reference value for stencil testing
|
||||
*/
|
||||
void setStencilFuncBack(StencilFunc func, int ref, unsigned int mask);
|
||||
|
||||
/**
|
||||
* Sets both the front and back-facing stencil test actions
|
||||
*/
|
||||
void setStencilOp(StencilOp failOp, StencilOp zFailOp, StencilOp zPassOp, unsigned int writeMask);
|
||||
/**
|
||||
* Sets the front stencil test actions
|
||||
*/
|
||||
void setStencilOpFront(StencilOp failOp, StencilOp zFailOp, StencilOp zPassOp, unsigned int writeMask);
|
||||
/**
|
||||
* Sets the back stencil test actions
|
||||
*/
|
||||
void setStencilOpBack(StencilOp failOp, StencilOp zFailOp, StencilOp zPassOp, unsigned int writeMask);
|
||||
|
||||
/**
|
||||
* Specifies the depth comparison function, which sets the conditions under which the pixel will be drawn.
|
||||
*/
|
||||
void setDepthFunc(DepthFunc func);
|
||||
|
||||
/**
|
||||
* Sets the source and destination blending factors with all channel packed into a 32bit unsigned int
|
||||
*/
|
||||
void setBlendColor(uint32_t rgba);
|
||||
/**
|
||||
* Sets the source and destination blending factors with separate color channel values
|
||||
*/
|
||||
void setBlendColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||
/**
|
||||
* Sets which function is used for blending pixel arithmetic
|
||||
*/
|
||||
void setBlendFunc(BlendFactor src, BlendFactor dst);
|
||||
/**
|
||||
* Sets which function is used for blending pixel arithmetic for RGB and alpha components separately
|
||||
*/
|
||||
void setBlendFuncSeparate(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha, BlendFactor dstAlpha);
|
||||
/**
|
||||
* Sets both the RGB blend equation and alpha blend equation to a single equation.
|
||||
*/
|
||||
void setBlendEquation(BlendOp mode);
|
||||
/**
|
||||
* Sets the RGB blend equation and alpha blend equation separately.
|
||||
*/
|
||||
void setBlendEquationSeparate(BlendOp modeRGB, BlendOp modeAlpha);
|
||||
|
||||
/**
|
||||
* Specifies whether or not front and/or back-facing polygons can be culled.
|
||||
*/
|
||||
void setCullMode(CullMode mode);
|
||||
|
||||
/**
|
||||
* Sets the vertex buffer
|
||||
*/
|
||||
void setVertexBuffer(int stream, VertexBuffer* buffer, int start = 0);
|
||||
/**
|
||||
* Sets the index buffer
|
||||
*/
|
||||
void setIndexBuffer(IndexBuffer *buffer);
|
||||
/**
|
||||
* Sets a linked program
|
||||
*/
|
||||
void setProgram(Program *program);
|
||||
/**
|
||||
* Sets a texture into a GL texture slot then set to the specified uniform
|
||||
*/
|
||||
void setTexture(size_t hashName, Texture* texture, int slot);
|
||||
/**
|
||||
* Sets textures array into GL texture slots then set to the specified uniform
|
||||
*/
|
||||
void setTextureArray(size_t hashName, const std::vector<Texture*>& textures, const std::vector<int>& slots);
|
||||
|
||||
/**
|
||||
* Sets a integer to the specified uniform
|
||||
*/
|
||||
void setUniformi(size_t hashName, int i1);
|
||||
/**
|
||||
* Sets two integers to the specified uniform
|
||||
*/
|
||||
void setUniformi(size_t hashName, int i1, int i2);
|
||||
/**
|
||||
* Sets three integers to the specified uniform
|
||||
*/
|
||||
void setUniformi(size_t hashName, int i1, int i2, int i3);
|
||||
/**
|
||||
* Sets four integers to the specified uniform
|
||||
*/
|
||||
void setUniformi(size_t hashName, int i1, int i2, int i3, int i4);
|
||||
/**
|
||||
* Sets a vector of integers to the specified uniform
|
||||
*/
|
||||
void setUniformiv(size_t hashName, size_t elementCount, const int* value, size_t uniformCount);
|
||||
/**
|
||||
* Sets a float to the specified uniform
|
||||
*/
|
||||
void setUniformf(size_t hashName, float f1);
|
||||
/**
|
||||
* Sets two floats to the specified uniform
|
||||
*/
|
||||
void setUniformf(size_t hashName, float f1, float f2);
|
||||
/**
|
||||
* Sets three floats to the specified uniform
|
||||
*/
|
||||
void setUniformf(size_t hashName, float f1, float f2, float f3);
|
||||
/**
|
||||
* Sets four floats to the specified uniform
|
||||
*/
|
||||
void setUniformf(size_t hashName, float f1, float f2, float f3, float f4);
|
||||
/**
|
||||
* Sets a vector of floats to the specified uniform
|
||||
*/
|
||||
void setUniformfv(size_t hashName, size_t elementCount, const float* value, size_t uniformCount);
|
||||
/**
|
||||
* Sets a Vec2 to the specified uniform
|
||||
*/
|
||||
void setUniformVec2(size_t hashName, const cocos2d::Vec2& value);
|
||||
/**
|
||||
* Sets a Vec3 to the specified uniform
|
||||
*/
|
||||
void setUniformVec3(size_t hashName, const cocos2d::Vec3& value);
|
||||
/**
|
||||
* Sets a Vec4 to the specified uniform
|
||||
*/
|
||||
void setUniformVec4(size_t hashName, const cocos2d::Vec4& value);
|
||||
/**
|
||||
* Sets a 2x2 matrix to the specified uniform
|
||||
*/
|
||||
void setUniformMat2(size_t hashName, float* value);
|
||||
/**
|
||||
* Sets a 3x3 matrix to the specified uniform
|
||||
*/
|
||||
void setUniformMat3(size_t hashName, float* value);
|
||||
/**
|
||||
* Sets a 4x4 matrix specified by float pointer to the given uniform
|
||||
*/
|
||||
void setUniformMat4(size_t hashName, float* value);
|
||||
/**
|
||||
* Sets a Mat4 object to the given uniform
|
||||
*/
|
||||
void setUniformMat4(size_t hashName, const cocos2d::Mat4& value);
|
||||
/**
|
||||
* Sets data specified by data pointer, type and bytes to the given uniform
|
||||
*/
|
||||
void setUniform(size_t hashName, const void* v, size_t bytes, UniformElementType elementType, size_t uniformCount = 1);
|
||||
|
||||
/**
|
||||
* Sets the primitive type for draw calls
|
||||
*/
|
||||
void setPrimitiveType(PrimitiveType type);
|
||||
|
||||
/**
|
||||
* Draw elements using the current gl states
|
||||
*/
|
||||
void draw(size_t base, GLsizei count);
|
||||
|
||||
/**
|
||||
* Resets the draw call counter to 0
|
||||
*/
|
||||
void resetDrawCalls() { _drawCalls = 0; };
|
||||
/**
|
||||
* Gets current draw call counts
|
||||
*/
|
||||
uint32_t getDrawCalls() const { return _drawCalls; };
|
||||
|
||||
inline const Capacity& getCapacity() const { return _caps; }
|
||||
|
||||
private:
|
||||
DeviceGraphics();
|
||||
~DeviceGraphics();
|
||||
CC_DISALLOW_COPY_ASSIGN_AND_MOVE(DeviceGraphics);
|
||||
|
||||
inline void initStates();
|
||||
inline void initCaps();
|
||||
void restoreTexture(uint32_t index);
|
||||
void restoreIndexBuffer();
|
||||
|
||||
inline void commitBlendStates();
|
||||
inline void commitDepthStates();
|
||||
inline void commitStencilStates();
|
||||
inline void commitCullMode();
|
||||
inline void commitVertexBuffer();
|
||||
inline void commitTextures();
|
||||
|
||||
int _vx;
|
||||
int _vy;
|
||||
int _vw;
|
||||
int _vh;
|
||||
|
||||
int _sx;
|
||||
int _sy;
|
||||
int _sw;
|
||||
int _sh;
|
||||
|
||||
uint32_t _drawCalls = 0;
|
||||
|
||||
int _defaultFbo;
|
||||
|
||||
Capacity _caps;
|
||||
char* _glExtensions;
|
||||
|
||||
FrameBuffer *_frameBuffer;
|
||||
std::vector<int> _enabledAtrributes;
|
||||
std::vector<int> _newAttributes;
|
||||
std::unordered_map<size_t, Uniform> _uniforms;
|
||||
|
||||
State* _nextState;
|
||||
State* _currentState;
|
||||
|
||||
friend class IndexBuffer;
|
||||
friend class Texture2D;
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
140
cocos2d-x/cocos/renderer/gfx/FrameBuffer.cpp
Normal file
140
cocos2d-x/cocos/renderer/gfx/FrameBuffer.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "FrameBuffer.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "base/CCGLUtils.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
FrameBuffer::FrameBuffer()
|
||||
: _device(nullptr)
|
||||
, _depthBuffer(nullptr)
|
||||
, _stencilBuffer(nullptr)
|
||||
, _depthStencilBuffer(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FrameBuffer::~FrameBuffer()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void FrameBuffer::destroy()
|
||||
{
|
||||
for (auto colorBufffer : _colorBuffers)
|
||||
RENDERER_SAFE_RELEASE(colorBufffer);
|
||||
_colorBuffers.clear();
|
||||
|
||||
RENDERER_SAFE_RELEASE(_depthBuffer);
|
||||
_depthBuffer = nullptr;
|
||||
|
||||
RENDERER_SAFE_RELEASE(_stencilBuffer);
|
||||
_stencilBuffer = nullptr;
|
||||
|
||||
RENDERER_SAFE_RELEASE(_depthStencilBuffer);
|
||||
_depthStencilBuffer = nullptr;
|
||||
|
||||
if (_glID != 0)
|
||||
{
|
||||
glDeleteFramebuffers(1, &_glID);
|
||||
_glID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool FrameBuffer::init(DeviceGraphics* device, uint16_t width, uint16_t height)
|
||||
{
|
||||
_device = device;
|
||||
_width = width;
|
||||
_height = height;
|
||||
|
||||
glGenFramebuffers(1, &_glID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FrameBuffer::setColorBuffer(RenderTarget* rt, int index)
|
||||
{
|
||||
if (index >= _colorBuffers.size())
|
||||
_colorBuffers.resize(index + 1);
|
||||
|
||||
RENDERER_SAFE_RETAIN(rt);
|
||||
RENDERER_SAFE_RELEASE(_colorBuffers[index]);
|
||||
_colorBuffers[index] = rt;
|
||||
}
|
||||
|
||||
void FrameBuffer::setColorBuffers(const std::vector<RenderTarget*>& renderTargets)
|
||||
{
|
||||
for (auto& colorBufffer : renderTargets)
|
||||
RENDERER_SAFE_RETAIN(colorBufffer);
|
||||
for (auto& colorBufffer : _colorBuffers)
|
||||
RENDERER_SAFE_RELEASE(colorBufffer);
|
||||
_colorBuffers = renderTargets;
|
||||
}
|
||||
|
||||
void FrameBuffer::setDepthBuffer(RenderTarget* rt)
|
||||
{
|
||||
RENDERER_SAFE_RETAIN(rt);
|
||||
RENDERER_SAFE_RELEASE(_depthBuffer);
|
||||
_depthBuffer = rt;
|
||||
}
|
||||
|
||||
void FrameBuffer::setStencilBuffer(RenderTarget* rt)
|
||||
{
|
||||
RENDERER_SAFE_RETAIN(rt);
|
||||
RENDERER_SAFE_RELEASE(_stencilBuffer);
|
||||
_stencilBuffer = rt;
|
||||
}
|
||||
|
||||
void FrameBuffer::setDepthStencilBuffer(RenderTarget* rt)
|
||||
{
|
||||
RENDERER_SAFE_RETAIN(rt);
|
||||
RENDERER_SAFE_RELEASE(_depthStencilBuffer);
|
||||
_depthStencilBuffer = rt;
|
||||
}
|
||||
|
||||
const std::vector<RenderTarget*>& FrameBuffer::getColorBuffers() const
|
||||
{
|
||||
return _colorBuffers;
|
||||
}
|
||||
|
||||
const RenderTarget* FrameBuffer::getDepthBuffer() const
|
||||
{
|
||||
return _depthBuffer;
|
||||
}
|
||||
|
||||
const RenderTarget* FrameBuffer::getStencilBuffer() const
|
||||
{
|
||||
return _stencilBuffer;
|
||||
}
|
||||
|
||||
const RenderTarget* FrameBuffer::getDepthStencilBuffer() const
|
||||
{
|
||||
return _depthStencilBuffer;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
|
||||
|
||||
128
cocos2d-x/cocos/renderer/gfx/FrameBuffer.h
Normal file
128
cocos2d-x/cocos/renderer/gfx/FrameBuffer.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
#include "GraphicsHandle.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class DeviceGraphics;
|
||||
class RenderTarget;
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The FrameBuffer class can store the render results of DeviceGraphics.
|
||||
* It contains color buffers, depth buffers and stencil buffers,
|
||||
* they are destinations for drawing, clearing and writing operations during the render process.
|
||||
*/
|
||||
class FrameBuffer final : public GraphicsHandle
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a FrameBuffer object with device and size
|
||||
*/
|
||||
RENDERER_DEFINE_CREATE_METHOD_3(FrameBuffer, init, DeviceGraphics*, uint16_t, uint16_t)
|
||||
|
||||
FrameBuffer();
|
||||
/**
|
||||
* Inits the frame buffer with device and size
|
||||
*/
|
||||
bool init(DeviceGraphics* device, uint16_t width, uint16_t height);
|
||||
/**
|
||||
* Destroys the GL buffers created by this frame buffer object
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
/**
|
||||
* Sets the color buffers as drawing and clearing destinations
|
||||
*/
|
||||
void setColorBuffers(const std::vector<RenderTarget*>& renderTargets);
|
||||
/**
|
||||
* Sets a color buffer at specific index
|
||||
*/
|
||||
void setColorBuffer(RenderTarget* rt, int index);
|
||||
/**
|
||||
* Sets the depth buffer as depth writing destination
|
||||
*/
|
||||
void setDepthBuffer(RenderTarget* rt);
|
||||
/**
|
||||
* Sets the stencil buffer as stencil writing destination
|
||||
*/
|
||||
void setStencilBuffer(RenderTarget* rt);
|
||||
/**
|
||||
* Sets the depth and stencil buffer at the same time.
|
||||
* If you want to set both with the same RenderTarget, you should use this instead of setting them separatly.
|
||||
*/
|
||||
void setDepthStencilBuffer(RenderTarget* rt);
|
||||
|
||||
/**
|
||||
* Sets the width of frame buffer
|
||||
*/
|
||||
inline int getWidth() const { return _width; }
|
||||
/**
|
||||
* Sets the width of frame buffer
|
||||
*/
|
||||
inline int getHeight() const { return _height; }
|
||||
|
||||
/**
|
||||
* Gets the color buffers
|
||||
*/
|
||||
const std::vector<RenderTarget*>& getColorBuffers() const;
|
||||
/**
|
||||
* Gets the depth buffer
|
||||
*/
|
||||
const RenderTarget* getDepthBuffer() const;
|
||||
/**
|
||||
* Gets the stencil buffer
|
||||
*/
|
||||
const RenderTarget* getStencilBuffer() const;
|
||||
/**
|
||||
* Gets the depth and stencil buffer if they share the same one.
|
||||
*/
|
||||
const RenderTarget* getDepthStencilBuffer() const;
|
||||
|
||||
private:
|
||||
virtual ~FrameBuffer();
|
||||
|
||||
DeviceGraphics* _device;
|
||||
std::vector<RenderTarget*> _colorBuffers;
|
||||
RenderTarget* _depthBuffer;
|
||||
RenderTarget* _stencilBuffer;
|
||||
RenderTarget* _depthStencilBuffer;
|
||||
uint16_t _width;
|
||||
uint16_t _height;
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
25
cocos2d-x/cocos/renderer/gfx/GFX.cpp
Normal file
25
cocos2d-x/cocos/renderer/gfx/GFX.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "GFX.h"
|
||||
35
cocos2d-x/cocos/renderer/gfx/GFX.h
Normal file
35
cocos2d-x/cocos/renderer/gfx/GFX.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IndexBuffer.h"
|
||||
#include "VertexBuffer.h"
|
||||
#include "DeviceGraphics.h"
|
||||
#include "FrameBuffer.h"
|
||||
#include "State.h"
|
||||
#include "RenderBuffer.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "Texture2D.h"
|
||||
#include "Program.h"
|
||||
57
cocos2d-x/cocos/renderer/gfx/GFXUtils.cpp
Normal file
57
cocos2d-x/cocos/renderer/gfx/GFXUtils.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "GFXUtils.h"
|
||||
#include "Macro.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
const char* glEnumName(GLenum _enum)
|
||||
{
|
||||
#define GLENUM(_ty) case _ty: return #_ty
|
||||
|
||||
switch (_enum)
|
||||
{
|
||||
GLENUM(GL_TEXTURE);
|
||||
GLENUM(GL_RENDERBUFFER);
|
||||
|
||||
GLENUM(GL_INVALID_ENUM);
|
||||
GLENUM(GL_INVALID_FRAMEBUFFER_OPERATION);
|
||||
GLENUM(GL_INVALID_VALUE);
|
||||
GLENUM(GL_INVALID_OPERATION);
|
||||
GLENUM(GL_OUT_OF_MEMORY);
|
||||
|
||||
GLENUM(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
|
||||
GLENUM(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
|
||||
// GLENUM(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
|
||||
// GLENUM(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
|
||||
GLENUM(GL_FRAMEBUFFER_UNSUPPORTED);
|
||||
}
|
||||
|
||||
#undef GLENUM
|
||||
|
||||
RENDERER_LOGW("Unknown enum? %x", _enum);
|
||||
return "<GLenum?>";
|
||||
}
|
||||
|
||||
30
cocos2d-x/cocos/renderer/gfx/GFXUtils.h
Normal file
30
cocos2d-x/cocos/renderer/gfx/GFXUtils.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "platform/CCGL.h"
|
||||
|
||||
const char* glEnumName(GLenum _enum);
|
||||
|
||||
40
cocos2d-x/cocos/renderer/gfx/GraphicsHandle.cpp
Normal file
40
cocos2d-x/cocos/renderer/gfx/GraphicsHandle.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "GraphicsHandle.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
GraphicsHandle::GraphicsHandle()
|
||||
: _glID(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GraphicsHandle::~GraphicsHandle()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
60
cocos2d-x/cocos/renderer/gfx/GraphicsHandle.h
Normal file
60
cocos2d-x/cocos/renderer/gfx/GraphicsHandle.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
|
||||
#include "base/CCRef.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract class for GL graphic classes that uses a GL handle id.
|
||||
* Such as Texture, FrameBuffer, IndexBuffer, VertexBuffer, Program.
|
||||
*/
|
||||
class GraphicsHandle : public Ref
|
||||
{
|
||||
public:
|
||||
GraphicsHandle();
|
||||
virtual ~GraphicsHandle();
|
||||
/**
|
||||
* Gets the GL handle
|
||||
*/
|
||||
inline GLuint getHandle() const { return _glID; }
|
||||
|
||||
protected:
|
||||
GLuint _glID = 0;
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
133
cocos2d-x/cocos/renderer/gfx/IndexBuffer.cpp
Normal file
133
cocos2d-x/cocos/renderer/gfx/IndexBuffer.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "IndexBuffer.h"
|
||||
#include "DeviceGraphics.h"
|
||||
#include "base/CCGLUtils.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
IndexBuffer::IndexBuffer()
|
||||
: _device(nullptr)
|
||||
, _format(IndexFormat::UINT16)
|
||||
, _usage(Usage::STATIC)
|
||||
, _numIndices(0)
|
||||
, _bytesPerIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
IndexBuffer::~IndexBuffer()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
bool IndexBuffer::init(DeviceGraphics* device, IndexFormat format, Usage usage, const void* data, size_t dataByteLength, uint32_t numIndices)
|
||||
{
|
||||
_device = device;
|
||||
_format = format;
|
||||
_usage = usage;
|
||||
_numIndices = numIndices;
|
||||
_bytesPerIndex = 0;
|
||||
|
||||
_needExpandDataStore = true;
|
||||
|
||||
// calculate bytes
|
||||
if (format == IndexFormat::UINT8)
|
||||
{
|
||||
_bytesPerIndex = 1;
|
||||
}
|
||||
else if (format == IndexFormat::UINT16)
|
||||
{
|
||||
_bytesPerIndex = 2;
|
||||
}
|
||||
else if (format == IndexFormat::UINT32)
|
||||
{
|
||||
_bytesPerIndex = 4;
|
||||
}
|
||||
|
||||
_bytes = _bytesPerIndex * numIndices;
|
||||
|
||||
// update
|
||||
glGenBuffers(1, &_glID);
|
||||
update(0, data, dataByteLength);
|
||||
|
||||
// stats
|
||||
//REFINE: device._stats.ib += _bytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IndexBuffer::update(uint32_t offset, const void* data, size_t dataByteLength)
|
||||
{
|
||||
if (_glID == 0)
|
||||
{
|
||||
RENDERER_LOGE("The buffer is destroyed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == nullptr || dataByteLength == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataByteLength + offset > _bytes)
|
||||
{
|
||||
if (offset) {
|
||||
RENDERER_LOGE("Failed to update index buffer data, bytes exceed.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
_needExpandDataStore = true;
|
||||
_bytes = offset + dataByteLength;
|
||||
_numIndices = _bytes / _bytesPerIndex;
|
||||
}
|
||||
}
|
||||
|
||||
GLenum glUsage = (GLenum)_usage;
|
||||
ccBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _glID);
|
||||
if (_needExpandDataStore)
|
||||
{
|
||||
// glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)dataByteLength, data, glUsage);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _bytes, (const GLvoid*)data, glUsage);
|
||||
_needExpandDataStore = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, (GLintptr)offset, (GLsizeiptr)dataByteLength, (const GLvoid*)data);
|
||||
}
|
||||
|
||||
_device->restoreIndexBuffer();
|
||||
}
|
||||
|
||||
void IndexBuffer::destroy()
|
||||
{
|
||||
if (_glID == 0)
|
||||
return;
|
||||
|
||||
ccDeleteBuffers(1, &_glID);
|
||||
//REFINE: _device._stats.ib -= _bytes;
|
||||
_glID = 0;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
154
cocos2d-x/cocos/renderer/gfx/IndexBuffer.h
Normal file
154
cocos2d-x/cocos/renderer/gfx/IndexBuffer.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
#include "GraphicsHandle.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
class DeviceGraphics;
|
||||
|
||||
/**
|
||||
* IndexBuffer manages the GL buffer for element indices.
|
||||
* It creates, updates and destoies the GL buffer.
|
||||
*/
|
||||
class IndexBuffer final : public GraphicsHandle
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates an IndexBuffer object
|
||||
* @param[in] device DeviceGraphics pointer.
|
||||
* @param[in] format Index element format.
|
||||
* @param[in] usage The usage pattern of the index buffer.
|
||||
* @param[in] data Data pointer, could be nullptr, then nothing is updated to the buffer.
|
||||
* @param[in] dataByteLength Data's byte length.
|
||||
* @param[in] numIndices Count of indices.
|
||||
*/
|
||||
RENDERER_DEFINE_CREATE_METHOD_6(IndexBuffer, init, DeviceGraphics*, IndexFormat, Usage, const void*, size_t, uint32_t)
|
||||
|
||||
IndexBuffer();
|
||||
virtual ~IndexBuffer();
|
||||
|
||||
/**
|
||||
* Initializes the index buffer with necessary options.
|
||||
* @param[in] device DeviceGraphics pointer.
|
||||
* @param[in] format Index element format.
|
||||
* @param[in] usage The usage pattern of the index buffer.
|
||||
* @param[in] data Data pointer, could be nullptr, then nothing is updated to the buffer.
|
||||
* @param[in] dataByteLength Data's byte length.
|
||||
* @param[in] numIndices Count of indices.
|
||||
*/
|
||||
bool init(DeviceGraphics* device, IndexFormat format, Usage usage, const void* data, size_t dataByteLength, uint32_t numIndices);
|
||||
/**
|
||||
* Update data to the GL index buffer
|
||||
* @param[in] offset Destination offset for filling buffer data.
|
||||
* @param[in] data Data to be updated.
|
||||
* @param[in] dataByteLength Data byte length to be updated.
|
||||
*/
|
||||
void update(uint32_t offset, const void* data, size_t dataByteLength);
|
||||
|
||||
/**
|
||||
* Gets the count of indices.
|
||||
*/
|
||||
inline uint32_t getCount() const { return _numIndices; }
|
||||
/**
|
||||
* Sets the count of indices.
|
||||
*/
|
||||
inline void setCount(uint32_t numIndices) { _numIndices = numIndices; }
|
||||
|
||||
/**
|
||||
* Gets the format of indices.
|
||||
*/
|
||||
inline IndexFormat getFormat() const { return _format; }
|
||||
/**
|
||||
* Sets the format of indices.
|
||||
*/
|
||||
inline void setFormat(IndexFormat format) { _format = format; }
|
||||
|
||||
/**
|
||||
* Gets bytes occupied by each index.
|
||||
*/
|
||||
inline uint32_t getBytesPerIndex() const { return _bytesPerIndex; }
|
||||
/**
|
||||
* Sets bytes occupied by each index.
|
||||
*/
|
||||
inline void setBytesPerIndex(uint32_t bytesPerIndex) {_bytesPerIndex = bytesPerIndex; }
|
||||
|
||||
/**
|
||||
* Gets usage pattern of the index buffer
|
||||
*/
|
||||
inline Usage getUsage() const { return _usage; }
|
||||
/**
|
||||
* Sets usage pattern of the index buffer
|
||||
*/
|
||||
inline void setUsage(Usage usage) { _usage = usage; }
|
||||
|
||||
/**
|
||||
* Gets byte size of the index buffer
|
||||
*/
|
||||
inline uint32_t getBytes() const { return _bytes; }
|
||||
|
||||
using FetchDataCallback = std::function<uint8_t*(size_t*)>;
|
||||
void setFetchDataCallback(const FetchDataCallback& cb) { _fetchDataCallback = cb; }
|
||||
uint8_t* invokeFetchDataCallback(size_t* bytes) {
|
||||
if (_fetchDataCallback == nullptr)
|
||||
{
|
||||
*bytes = 0;
|
||||
return nullptr;
|
||||
}
|
||||
return _fetchDataCallback(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroies the index buffer
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
DeviceGraphics* _device;
|
||||
IndexFormat _format;
|
||||
Usage _usage;
|
||||
uint32_t _numIndices;
|
||||
uint32_t _bytesPerIndex;
|
||||
uint32_t _bytes;
|
||||
bool _needExpandDataStore = true;
|
||||
|
||||
FetchDataCallback _fetchDataCallback;
|
||||
|
||||
CC_DISALLOW_COPY_ASSIGN_AND_MOVE(IndexBuffer)
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
398
cocos2d-x/cocos/renderer/gfx/Program.cpp
Normal file
398
cocos2d-x/cocos/renderer/gfx/Program.cpp
Normal file
@@ -0,0 +1,398 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Program.h"
|
||||
#include "GFXUtils.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace {
|
||||
|
||||
uint32_t _genID = 0;
|
||||
|
||||
std::string logForOpenGLShader(GLuint shader)
|
||||
{
|
||||
GLint logLength = 0;
|
||||
|
||||
GL_CHECK(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength));
|
||||
if (logLength < 1)
|
||||
return "";
|
||||
|
||||
char *logBytes = (char*)malloc(sizeof(char) * logLength);
|
||||
GL_CHECK(glGetShaderInfoLog(shader, logLength, nullptr, logBytes));
|
||||
std::string ret(logBytes);
|
||||
|
||||
free(logBytes);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string logForOpenGLProgram(GLuint program)
|
||||
{
|
||||
GLint logLength = 0;
|
||||
|
||||
GL_CHECK(glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength));
|
||||
if (logLength < 1)
|
||||
return "";
|
||||
|
||||
char *logBytes = (char*)malloc(sizeof(char) * logLength);
|
||||
GL_CHECK(glGetProgramInfoLog(program, logLength, nullptr, logBytes));
|
||||
std::string ret(logBytes);
|
||||
|
||||
free(logBytes);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool _createShader(GLenum type, const std::string& src, GLuint* outShader)
|
||||
{
|
||||
assert(outShader != nullptr);
|
||||
GLuint shader = glCreateShader(type);
|
||||
const GLchar* sources[] = { src.c_str() };
|
||||
GL_CHECK(glShaderSource(shader, 1, sources, nullptr));
|
||||
GL_CHECK(glCompileShader(shader));
|
||||
|
||||
GLint status;
|
||||
GL_CHECK(glGetShaderiv(shader, GL_COMPILE_STATUS, &status));
|
||||
|
||||
if (!status)
|
||||
{
|
||||
GLsizei length;
|
||||
GL_CHECK(glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &length));
|
||||
GLchar* source = (GLchar *)malloc(sizeof(GLchar) * length);
|
||||
|
||||
GL_CHECK(glGetShaderSource(shader, length, nullptr, source));
|
||||
RENDERER_LOGE("ERROR: Failed to compile shader:\n%s", source);
|
||||
|
||||
std::string shaderLog = logForOpenGLShader(shader);
|
||||
RENDERER_LOGE("%s", shaderLog.c_str());
|
||||
|
||||
free(source);
|
||||
|
||||
*outShader = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
*outShader = shader;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define DEF_TO_INT(pointer) (*(int*)(pointer))
|
||||
#define DEF_TO_FLOAT(pointer) (*(float*)(pointer))
|
||||
|
||||
void setUniform1i(GLint location, GLsizei count , const void* value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
assert(count == 1);
|
||||
if (elementType == cocos2d::renderer::UniformElementType::INT)
|
||||
{
|
||||
glUniform1i(location, DEF_TO_INT(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
float floatVal = *((float*)value);
|
||||
GLint intVal = (GLint)floatVal;
|
||||
glUniform1i(location, intVal);
|
||||
}
|
||||
}
|
||||
|
||||
void setUniform1iv(GLint location, GLsizei count , const void* value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniform1iv(location, count, (const GLint*)value);
|
||||
}
|
||||
|
||||
void setUniform2iv(GLint location, GLsizei count , const void* value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniform2iv(location, count, (const GLint*)value);
|
||||
}
|
||||
|
||||
void setUniform3iv(GLint location, GLsizei count , const void* value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniform3iv(location, count, (const GLint*)value);
|
||||
}
|
||||
|
||||
void setUniform4iv(GLint location, GLsizei count , const void* value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniform4iv(location, count, (const GLint*)value);
|
||||
}
|
||||
|
||||
void setUniform1f(GLint location, GLsizei count , const void* value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
assert(count == 1);
|
||||
glUniform1f(location, DEF_TO_FLOAT(value));
|
||||
}
|
||||
|
||||
void setUniform1fv(GLint location, GLsizei count , const void* value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniform1fv(location, count, (const GLfloat*)value);
|
||||
}
|
||||
|
||||
void setUniform2fv(GLint location, GLsizei count , const void* value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniform2fv(location, count, (const GLfloat*)value);
|
||||
}
|
||||
|
||||
void setUniform3fv(GLint location, GLsizei count , const void* value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniform3fv(location, count, (const GLfloat*)value);
|
||||
}
|
||||
|
||||
void setUniform4fv(GLint location, GLsizei count , const void* value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniform4fv(location, count, (const GLfloat*)value);
|
||||
}
|
||||
|
||||
void setUniformMatrix2fv(GLint location, GLsizei count, const void *value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniformMatrix2fv(location, count, GL_FALSE, (const GLfloat*)value);
|
||||
}
|
||||
|
||||
void setUniformMatrix3fv(GLint location, GLsizei count, const void *value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniformMatrix3fv(location, count, GL_FALSE, (const GLfloat*)value);
|
||||
}
|
||||
|
||||
void setUniformMatrix4fv(GLint location, GLsizei count, const void *value, cocos2d::renderer::UniformElementType elementType)
|
||||
{
|
||||
glUniformMatrix4fv(location, count, GL_FALSE, (const GLfloat*)value);
|
||||
}
|
||||
|
||||
/**
|
||||
* _type2uniformCommit
|
||||
*/
|
||||
std::unordered_map<GLenum, cocos2d::renderer::Program::Uniform::SetUniformCallback> _type2uniformCommit = {
|
||||
{ GL_INT, setUniform1i },
|
||||
{ GL_FLOAT, setUniform1f },
|
||||
{ GL_FLOAT_VEC2, setUniform2fv },
|
||||
{ GL_FLOAT_VEC3, setUniform3fv },
|
||||
{ GL_FLOAT_VEC4, setUniform4fv },
|
||||
{ GL_INT_VEC2, setUniform2iv },
|
||||
{ GL_INT_VEC3, setUniform3iv },
|
||||
{ GL_INT_VEC4, setUniform4iv },
|
||||
{ GL_BOOL, setUniform1i },
|
||||
{ GL_BOOL_VEC2, setUniform2iv },
|
||||
{ GL_BOOL_VEC3, setUniform3iv },
|
||||
{ GL_BOOL_VEC4, setUniform4iv },
|
||||
{ GL_FLOAT_MAT2, setUniformMatrix2fv },
|
||||
{ GL_FLOAT_MAT3, setUniformMatrix3fv },
|
||||
{ GL_FLOAT_MAT4, setUniformMatrix4fv },
|
||||
{ GL_SAMPLER_2D, setUniform1i },
|
||||
{ GL_SAMPLER_CUBE, setUniform1i }
|
||||
};
|
||||
|
||||
/**
|
||||
* _type2uniformArrayCommit
|
||||
*/
|
||||
std::unordered_map<GLenum, cocos2d::renderer::Program::Uniform::SetUniformCallback> _type2uniformArrayCommit = {
|
||||
{ GL_INT, setUniform1iv },
|
||||
{ GL_FLOAT, setUniform1fv },
|
||||
{ GL_FLOAT_VEC2, setUniform2fv },
|
||||
{ GL_FLOAT_VEC3, setUniform3fv },
|
||||
{ GL_FLOAT_VEC4, setUniform4fv },
|
||||
{ GL_INT_VEC2, setUniform2iv },
|
||||
{ GL_INT_VEC3, setUniform3iv },
|
||||
{ GL_INT_VEC4, setUniform4iv },
|
||||
{ GL_BOOL, setUniform1iv },
|
||||
{ GL_BOOL_VEC2, setUniform2iv },
|
||||
{ GL_BOOL_VEC3, setUniform3iv },
|
||||
{ GL_BOOL_VEC4, setUniform4iv },
|
||||
{ GL_FLOAT_MAT2, setUniformMatrix2fv },
|
||||
{ GL_FLOAT_MAT3, setUniformMatrix3fv },
|
||||
{ GL_FLOAT_MAT4, setUniformMatrix4fv },
|
||||
{ GL_SAMPLER_2D, setUniform1iv },
|
||||
{ GL_SAMPLER_CUBE, setUniform1iv }
|
||||
};
|
||||
} // namespace {
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
void Program::Uniform::setUniform(const void* value, UniformElementType elementType, size_t uniformCount) const
|
||||
{
|
||||
// uniformCount may bigger than size.
|
||||
if (size >= 1 && size < uniformCount) uniformCount = size;
|
||||
GLsizei count = size == -1 ? 1 : (GLsizei)uniformCount;
|
||||
_callback(location, count, value, elementType);
|
||||
}
|
||||
|
||||
Program::Program()
|
||||
: _device(nullptr)
|
||||
, _id(0)
|
||||
, _linked(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Program::~Program()
|
||||
{
|
||||
GL_CHECK(glDeleteProgram(_glID));
|
||||
}
|
||||
|
||||
bool Program::init(DeviceGraphics* device, const char* vertSource, const char* fragSource)
|
||||
{
|
||||
assert(device);
|
||||
assert(vertSource);
|
||||
assert(fragSource);
|
||||
|
||||
_device = device;
|
||||
_vertSource = vertSource;
|
||||
_fragSource = fragSource;
|
||||
_id = _genID++;
|
||||
_linked = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Program::link()
|
||||
{
|
||||
if (_linked) {
|
||||
return;
|
||||
}
|
||||
|
||||
GLuint vertShader;
|
||||
bool ok = _createShader(GL_VERTEX_SHADER, _vertSource, &vertShader);
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
GLuint fragShader;
|
||||
ok = _createShader(GL_FRAGMENT_SHADER, _fragSource, &fragShader);
|
||||
if (!ok)
|
||||
{
|
||||
glDeleteShader(vertShader);
|
||||
return;
|
||||
}
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
GL_CHECK(glAttachShader(program, vertShader));
|
||||
GL_CHECK(glAttachShader(program, fragShader));
|
||||
GL_CHECK(glLinkProgram(program));
|
||||
|
||||
GLint status = GL_TRUE;
|
||||
GL_CHECK(glGetProgramiv(program, GL_LINK_STATUS, &status));
|
||||
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
RENDERER_LOGE("ERROR: Failed to link program: %u", program);
|
||||
std::string programLog = logForOpenGLProgram(program);
|
||||
RENDERER_LOGE("%s", programLog.c_str());
|
||||
glDeleteShader(vertShader);
|
||||
glDeleteShader(fragShader);
|
||||
glDeleteProgram(program);
|
||||
return;
|
||||
}
|
||||
|
||||
glDeleteShader(vertShader);
|
||||
glDeleteShader(fragShader);
|
||||
|
||||
_glID = program;
|
||||
|
||||
// parse attribute
|
||||
GLint numAttributes;
|
||||
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttributes);
|
||||
|
||||
if (numAttributes > 0)
|
||||
{
|
||||
GLint length;
|
||||
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length);
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
GLchar* attribName = (GLchar*) malloc(length + 1);
|
||||
Attribute attribute;
|
||||
for (GLint i = 0; i < numAttributes; ++i) {
|
||||
// Query attribute info.
|
||||
glGetActiveAttrib(program, i, length, nullptr, &attribute.size, &attribute.type, attribName);
|
||||
attribName[length] = '\0';
|
||||
attribute.name = attribName;
|
||||
attribute.hashName = std::hash<std::string>{}(attribName);
|
||||
// Query the pre-assigned attribute location
|
||||
attribute.location = glGetAttribLocation(program, attribName);
|
||||
|
||||
_attributes.push_back(std::move(attribute));
|
||||
}
|
||||
free(attribName);
|
||||
}
|
||||
}
|
||||
|
||||
// Query and store uniforms from the program.
|
||||
GLint activeUniforms;
|
||||
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniforms);
|
||||
if (activeUniforms > 0)
|
||||
{
|
||||
GLint length;
|
||||
glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length);
|
||||
if (length > 0)
|
||||
{
|
||||
GLchar* uniformName = (GLchar*) malloc(length + 1);
|
||||
|
||||
Uniform uniform;
|
||||
for (int i = 0; i < activeUniforms; ++i)
|
||||
{
|
||||
// Query uniform info.
|
||||
GL_CHECK(glGetActiveUniform(program, i, length, nullptr, &uniform.size, &uniform.type, uniformName));
|
||||
uniformName[length] = '\0';
|
||||
bool isArray = false;
|
||||
// remove possible array '[]' from uniform name
|
||||
if (length > 3)
|
||||
{
|
||||
char* c = strrchr(uniformName, '[');
|
||||
if (c)
|
||||
{
|
||||
*c = '\0';
|
||||
isArray = true;
|
||||
}
|
||||
}
|
||||
|
||||
uniform.name = uniformName;
|
||||
uniform.hashName = std::hash<std::string>{}(uniformName);
|
||||
GL_CHECK(uniform.location = glGetUniformLocation(program, uniformName));
|
||||
|
||||
GLenum err = glGetError();
|
||||
if (err != GL_NO_ERROR)
|
||||
{
|
||||
RENDERER_LOGE("error: 0x%x uniformName: %s", (int)err, uniformName);
|
||||
}
|
||||
assert(err == GL_NO_ERROR);
|
||||
|
||||
if (!isArray)
|
||||
{
|
||||
uniform.size = -1;
|
||||
auto iter = _type2uniformCommit.find(uniform.type);
|
||||
assert(iter != _type2uniformCommit.end());
|
||||
uniform._callback = iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto iter = _type2uniformArrayCommit.find(uniform.type);
|
||||
assert(iter != _type2uniformArrayCommit.end());
|
||||
uniform._callback = iter->second;
|
||||
}
|
||||
_uniforms.push_back(std::move(uniform));
|
||||
}
|
||||
|
||||
free(uniformName);
|
||||
}
|
||||
}
|
||||
|
||||
_linked = true;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
166
cocos2d-x/cocos/renderer/gfx/Program.h
Normal file
166
cocos2d-x/cocos/renderer/gfx/Program.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
|
||||
#include "GraphicsHandle.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
class DeviceGraphics;
|
||||
|
||||
/**
|
||||
* Program class manages the internal GL shader program.
|
||||
*/
|
||||
class Program final: public GraphicsHandle
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Describes vertex attribute informations used in the program
|
||||
* @struct Attribute
|
||||
*/
|
||||
struct Attribute
|
||||
{
|
||||
/**
|
||||
* Attribute name
|
||||
*/
|
||||
std::string name;
|
||||
size_t hashName;
|
||||
/**
|
||||
* Number of components per attribute
|
||||
*/
|
||||
GLsizei size;
|
||||
/**
|
||||
* Attribute location
|
||||
*/
|
||||
GLuint location;
|
||||
/**
|
||||
* Attribute type
|
||||
*/
|
||||
GLenum type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes uniform informations used in the program
|
||||
* @struct Uniform
|
||||
*/
|
||||
struct Uniform
|
||||
{
|
||||
/**
|
||||
* Uniform name
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* Uniform hash name
|
||||
*/
|
||||
size_t hashName;
|
||||
/**
|
||||
* The length of the array for uniforms declared as arrays, default value is 1
|
||||
*/
|
||||
GLsizei size;
|
||||
/**
|
||||
* Uniform location
|
||||
*/
|
||||
GLint location;
|
||||
/**
|
||||
* Uniform type
|
||||
*/
|
||||
GLenum type;
|
||||
/**
|
||||
* Sets the uniform value
|
||||
*/
|
||||
void setUniform(const void* value, UniformElementType elementType, size_t uniformCount) const;
|
||||
/**
|
||||
* Sets the callback which will be called when uniform updated
|
||||
*/
|
||||
using SetUniformCallback = void (*)(GLint, GLsizei, const void*, UniformElementType); // location, count, value, elementType
|
||||
private:
|
||||
SetUniformCallback _callback;
|
||||
friend class Program;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a Program with device and shader sources
|
||||
*/
|
||||
RENDERER_DEFINE_CREATE_METHOD_3(Program, init, DeviceGraphics*, const char*, const char*)
|
||||
Program();
|
||||
virtual ~Program();
|
||||
|
||||
/**
|
||||
* Initializes a Program with device and program sources
|
||||
* @param[in] device DeviceGraphics pointer
|
||||
* @param[in] vertSource Vertex shader program
|
||||
* @param[in] fragSource Fragment shader program
|
||||
*/
|
||||
bool init(DeviceGraphics* device, const char* vertSource, const char* fragSource);
|
||||
/**
|
||||
* Gets the id of program
|
||||
*/
|
||||
inline uint32_t getID() const { return _id; }
|
||||
/**
|
||||
* Gets the attibutes used in the program
|
||||
*/
|
||||
inline const std::vector<Attribute>& getAttributes() const { return _attributes; }
|
||||
/**
|
||||
* Gets the uniforms used in the program
|
||||
*/
|
||||
inline const std::vector<Uniform>& getUniforms() const { return _uniforms; }
|
||||
/**
|
||||
* Indicates whether the program is successfully linked
|
||||
*/
|
||||
inline bool isLinked() const { return _linked; }
|
||||
/**
|
||||
* Link the program with its shader sources
|
||||
*/
|
||||
void link();
|
||||
|
||||
inline size_t getHash() const { return _hash; }
|
||||
inline void setHash(size_t hash) { _hash = hash; }
|
||||
private:
|
||||
DeviceGraphics* _device;
|
||||
std::vector<Attribute> _attributes;
|
||||
std::vector<Uniform> _uniforms;
|
||||
std::string _vertSource;
|
||||
std::string _fragSource;
|
||||
uint32_t _id;
|
||||
bool _linked;
|
||||
size_t _hash = 0;
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
78
cocos2d-x/cocos/renderer/gfx/RenderBuffer.cpp
Normal file
78
cocos2d-x/cocos/renderer/gfx/RenderBuffer.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "RenderBuffer.h"
|
||||
#include "GFXUtils.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
RenderBuffer::RenderBuffer()
|
||||
: _device(nullptr)
|
||||
, _format(Format::RGBA4)
|
||||
, _width(0)
|
||||
, _height(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RenderBuffer::~RenderBuffer()
|
||||
{
|
||||
if (_glID == 0)
|
||||
{
|
||||
RENDERER_LOGE("The render-buffer (%p) is invalid!", this);
|
||||
return;
|
||||
}
|
||||
|
||||
GL_CHECK(glDeleteRenderbuffers(1, &_glID));
|
||||
}
|
||||
|
||||
bool RenderBuffer::init(DeviceGraphics* device, Format format, uint16_t width, uint16_t height)
|
||||
{
|
||||
_device = device;
|
||||
_format = format;
|
||||
_width = width;
|
||||
_height = height;
|
||||
|
||||
GLint oldRenderBuffer;
|
||||
glGetIntegerv(GL_RENDERBUFFER_BINDING, &oldRenderBuffer);
|
||||
GL_CHECK(glGenRenderbuffers(1, &_glID));
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, _glID));
|
||||
GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, (GLenum)format, width, height));
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, oldRenderBuffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderBuffer::update (uint16_t width, uint16_t height) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
|
||||
GLint oldRenderBuffer;
|
||||
glGetIntegerv(GL_RENDERBUFFER_BINDING, &oldRenderBuffer);
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, _glID));
|
||||
GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, (GLenum)_format, width, height));
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, oldRenderBuffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
84
cocos2d-x/cocos/renderer/gfx/RenderBuffer.h
Normal file
84
cocos2d-x/cocos/renderer/gfx/RenderBuffer.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "renderer/Types.h"
|
||||
|
||||
#include "RenderTarget.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
class DeviceGraphics;
|
||||
|
||||
/**
|
||||
* RenderBuffer manages the GL render buffer.
|
||||
* A render buffer stores data such as an image, or can be source or target of a rendering operation.
|
||||
*/
|
||||
class RenderBuffer final : public RenderTarget
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* RenderBuffer's pixel format
|
||||
*/
|
||||
enum class Format : uint32_t
|
||||
{
|
||||
RGBA4 = GL_RGBA4,
|
||||
RGB5_A1 = GL_RGB5_A1,
|
||||
D16 = GL_DEPTH_COMPONENT16,
|
||||
S8 = GL_STENCIL_INDEX8,
|
||||
// D24S8 = GL_DEPTH_STENCIL
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a RenderBuffer with device, pixel format and size
|
||||
*/
|
||||
RENDERER_DEFINE_CREATE_METHOD_4(RenderBuffer, init, DeviceGraphics*, Format, uint16_t, uint16_t)
|
||||
|
||||
RenderBuffer();
|
||||
virtual ~RenderBuffer();
|
||||
|
||||
/**
|
||||
* Initializes a RenderBuffer with device, pixel format and size
|
||||
*/
|
||||
bool init(DeviceGraphics* device, Format format, uint16_t width, uint16_t height);
|
||||
|
||||
bool update (uint16_t width, uint16_t height);
|
||||
private:
|
||||
DeviceGraphics* _device;
|
||||
Format _format;
|
||||
uint16_t _width;
|
||||
uint16_t _height;
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
25
cocos2d-x/cocos/renderer/gfx/RenderTarget.cpp
Normal file
25
cocos2d-x/cocos/renderer/gfx/RenderTarget.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "RenderTarget.h"
|
||||
53
cocos2d-x/cocos/renderer/gfx/RenderTarget.h
Normal file
53
cocos2d-x/cocos/renderer/gfx/RenderTarget.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
|
||||
#include "base/CCRef.h"
|
||||
|
||||
#include "GraphicsHandle.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract class for all classes that could act as a render target
|
||||
*/
|
||||
class RenderTarget : public GraphicsHandle
|
||||
{
|
||||
public:
|
||||
virtual ~RenderTarget() {}
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
224
cocos2d-x/cocos/renderer/gfx/State.cpp
Normal file
224
cocos2d-x/cocos/renderer/gfx/State.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "State.h"
|
||||
|
||||
#include "VertexBuffer.h"
|
||||
#include "IndexBuffer.h"
|
||||
#include "Texture2D.h"
|
||||
#include "Program.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
State::State()
|
||||
{
|
||||
_textureUnits.resize(10);
|
||||
_vertexBuffers.resize(10);
|
||||
_vertexBufferOffsets.resize(10);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
State::~State()
|
||||
{
|
||||
for (auto vertexBuf : _vertexBuffers)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(vertexBuf);
|
||||
}
|
||||
|
||||
RENDERER_SAFE_RELEASE(_indexBuffer);
|
||||
|
||||
for (auto texture : _textureUnits)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(texture);
|
||||
}
|
||||
|
||||
RENDERER_SAFE_RELEASE(_program);
|
||||
}
|
||||
|
||||
void State::reset()
|
||||
{
|
||||
blend = false;
|
||||
blendSeparation = false;
|
||||
blendColor = 0xFFFFFFFF;
|
||||
blendEq = BlendOp::ADD;
|
||||
blendAlphaEq = BlendOp::ADD;
|
||||
blendSrc = BlendFactor::ONE;
|
||||
blendDst = BlendFactor::ZERO;
|
||||
blendSrcAlpha = BlendFactor::ONE;
|
||||
blendDstAlpha = BlendFactor::ZERO;
|
||||
// depth
|
||||
depthTest = false;
|
||||
depthWrite = false;
|
||||
depthFunc = DepthFunc::LESS;
|
||||
// stencil
|
||||
stencilTest = false;
|
||||
stencilSeparation = false;
|
||||
stencilFuncFront = StencilFunc::ALWAYS;
|
||||
stencilRefFront = 0;
|
||||
stencilMaskFront = 0xFF;
|
||||
stencilFailOpFront = StencilOp::KEEP;
|
||||
stencilZFailOpFront = StencilOp::KEEP;
|
||||
stencilZPassOpFront = StencilOp::KEEP;
|
||||
stencilWriteMaskFront = 0xFF;
|
||||
stencilFuncBack = StencilFunc::ALWAYS;
|
||||
stencilRefBack = 0;
|
||||
stencilMaskBack = 0xFF;
|
||||
stencilFailOpBack = StencilOp::KEEP;
|
||||
stencilZFailOpBack = StencilOp::KEEP;
|
||||
stencilZPassOpBack = StencilOp::KEEP;
|
||||
stencilWriteMaskBack = 0xFF;
|
||||
// cull-mode
|
||||
cullMode = CullMode::BACK;
|
||||
|
||||
// primitive-type
|
||||
primitiveType = PrimitiveType::TRIANGLES;
|
||||
|
||||
// bindings
|
||||
maxStream = -1;
|
||||
|
||||
|
||||
for (auto i = 0; i < _textureUnits.size(); i++) {
|
||||
if (_textureUnits[i]) {
|
||||
RENDERER_SAFE_RELEASE(_textureUnits[i]);
|
||||
}
|
||||
_textureUnits[i] = nullptr;
|
||||
}
|
||||
|
||||
for (auto i = 0; i < _vertexBuffers.size(); i++) {
|
||||
if (_vertexBuffers[i]) {
|
||||
RENDERER_SAFE_RELEASE(_vertexBuffers[i]);
|
||||
}
|
||||
_vertexBuffers[i] = nullptr;
|
||||
}
|
||||
|
||||
if (_indexBuffer)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_indexBuffer);
|
||||
}
|
||||
_indexBuffer = nullptr;
|
||||
|
||||
if (_program)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_program);
|
||||
}
|
||||
_program = nullptr;
|
||||
}
|
||||
|
||||
void State::setVertexBuffer(size_t index, VertexBuffer* vertBuf)
|
||||
{
|
||||
if (index >= _vertexBuffers.size())
|
||||
{
|
||||
_vertexBuffers.resize(index + 1);
|
||||
}
|
||||
|
||||
VertexBuffer* oldBuf = _vertexBuffers[index];
|
||||
if (oldBuf != vertBuf)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(oldBuf);
|
||||
_vertexBuffers[index] = vertBuf;
|
||||
RENDERER_SAFE_RETAIN(vertBuf);
|
||||
}
|
||||
}
|
||||
|
||||
VertexBuffer* State::getVertexBuffer(size_t index) const
|
||||
{
|
||||
if (_vertexBuffers.empty())
|
||||
return nullptr;
|
||||
assert(index < _vertexBuffers.size());
|
||||
return _vertexBuffers[index];
|
||||
}
|
||||
|
||||
void State::setVertexBufferOffset(size_t index, int32_t offset)
|
||||
{
|
||||
if (index >= _vertexBufferOffsets.size())
|
||||
{
|
||||
_vertexBufferOffsets.resize(index + 1);
|
||||
}
|
||||
|
||||
_vertexBufferOffsets[index] = offset;
|
||||
}
|
||||
|
||||
int32_t State::getVertexBufferOffset(size_t index) const
|
||||
{
|
||||
assert(index < _vertexBufferOffsets.size());
|
||||
return _vertexBufferOffsets[index];
|
||||
}
|
||||
|
||||
void State::setIndexBuffer(IndexBuffer* indexBuf)
|
||||
{
|
||||
if (_indexBuffer != indexBuf)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_indexBuffer);
|
||||
_indexBuffer = indexBuf;
|
||||
RENDERER_SAFE_RETAIN(_indexBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
IndexBuffer* State::getIndexBuffer() const
|
||||
{
|
||||
return _indexBuffer;
|
||||
}
|
||||
|
||||
void State::setTexture(size_t index, Texture* texture)
|
||||
{
|
||||
if (index >= _textureUnits.size())
|
||||
{
|
||||
_textureUnits.resize(index + 1);
|
||||
}
|
||||
|
||||
Texture* oldTexture = _textureUnits[index];
|
||||
if (oldTexture != texture)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(oldTexture);
|
||||
_textureUnits[index] = texture;
|
||||
RENDERER_SAFE_RETAIN(texture);
|
||||
}
|
||||
}
|
||||
|
||||
Texture* State::getTexture(size_t index) const
|
||||
{
|
||||
if (_textureUnits.empty())
|
||||
return nullptr;
|
||||
assert(index < _textureUnits.size());
|
||||
return _textureUnits[index];
|
||||
}
|
||||
|
||||
void State::setProgram(Program* program)
|
||||
{
|
||||
assert(program != nullptr);
|
||||
if (_program != program)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_program);
|
||||
_program = program;
|
||||
RENDERER_SAFE_RETAIN(_program);
|
||||
}
|
||||
}
|
||||
|
||||
Program* State::getProgram() const
|
||||
{
|
||||
return _program;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
277
cocos2d-x/cocos/renderer/gfx/State.h
Normal file
277
cocos2d-x/cocos/renderer/gfx/State.h
Normal file
@@ -0,0 +1,277 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class VertexBuffer;
|
||||
class IndexBuffer;
|
||||
class Program;
|
||||
class Texture;
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* State class save the GL states used in one draw call.
|
||||
* It will be used to compare between the previous states and the current states, so that we know which GL states should be updated.
|
||||
* User shouldn't be using this Class directly. Instead, they should set the states in Pass of material system.
|
||||
* @see `Pass`
|
||||
*/
|
||||
struct State final
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
State();
|
||||
~State();
|
||||
|
||||
/**
|
||||
* Reset all states to default values
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
@name Blend
|
||||
@{
|
||||
*/
|
||||
/**
|
||||
* Indicates blending enabled or not
|
||||
*/
|
||||
bool blend;
|
||||
/**
|
||||
* Indicates the RGB blend equation and alpha blend equation settings are separate or not
|
||||
*/
|
||||
bool blendSeparation;
|
||||
/**
|
||||
* The blending color
|
||||
*/
|
||||
uint32_t blendColor;
|
||||
/**
|
||||
* The blending equation
|
||||
*/
|
||||
BlendOp blendEq;
|
||||
/**
|
||||
* The blending equation for alpha channel
|
||||
*/
|
||||
BlendOp blendAlphaEq;
|
||||
/**
|
||||
* The blending source factor
|
||||
*/
|
||||
BlendFactor blendSrc;
|
||||
/**
|
||||
* The blending destination factor
|
||||
*/
|
||||
BlendFactor blendDst;
|
||||
/**
|
||||
* The blending source factor for alpha
|
||||
*/
|
||||
BlendFactor blendSrcAlpha;
|
||||
/**
|
||||
* The blending destination factor for alpha
|
||||
*/
|
||||
BlendFactor blendDstAlpha;
|
||||
/**
|
||||
end of Blend
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@name Depth
|
||||
@{
|
||||
*/
|
||||
/**
|
||||
* Indicates depth test enabled or not
|
||||
*/
|
||||
bool depthTest;
|
||||
/**
|
||||
* Indicates depth writing enabled or not
|
||||
*/
|
||||
bool depthWrite;
|
||||
/**
|
||||
* The depth comparison function
|
||||
*/
|
||||
DepthFunc depthFunc;
|
||||
/**
|
||||
end of Depth
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@name Stencil
|
||||
@{
|
||||
*/
|
||||
/**
|
||||
* Indicates stencil test enabled or not
|
||||
*/
|
||||
bool stencilTest;
|
||||
/**
|
||||
* Indicates stencil test function for front and back is set separatly or not
|
||||
*/
|
||||
bool stencilSeparation;
|
||||
/**
|
||||
* The front face function for stencil test
|
||||
*/
|
||||
StencilFunc stencilFuncFront;
|
||||
/**
|
||||
* The front reference value for stencil test
|
||||
*/
|
||||
int32_t stencilRefFront;
|
||||
/**
|
||||
* The front mask value to AND with the reference value and store the result into stencil buffer when test is done
|
||||
*/
|
||||
uint32_t stencilMaskFront;
|
||||
/**
|
||||
* The function to use when the stencil test fails for front face
|
||||
*/
|
||||
StencilOp stencilFailOpFront;
|
||||
/**
|
||||
* The function to use when the stencil test passes but the depth test fails for front face
|
||||
*/
|
||||
StencilOp stencilZFailOpFront;
|
||||
/**
|
||||
* The function to use when both the stencil and the depth test pass for front face.
|
||||
* Or when the stencil test passes and there is no depth buffer or depth testing is disabled.
|
||||
*/
|
||||
StencilOp stencilZPassOpFront;
|
||||
/**
|
||||
* The bit mask to enable or disable writing of individual bits in the front stencil planes
|
||||
*/
|
||||
uint32_t stencilWriteMaskFront;
|
||||
/**
|
||||
* The back face function for stencil test
|
||||
*/
|
||||
StencilFunc stencilFuncBack;
|
||||
/**
|
||||
* The back reference value for stencil test
|
||||
*/
|
||||
int32_t stencilRefBack;
|
||||
/**
|
||||
* The back mask value to AND with the reference value and store the result into stencil buffer when test is done
|
||||
*/
|
||||
uint32_t stencilMaskBack;
|
||||
/**
|
||||
* The function to use when the stencil test fails for back face
|
||||
*/
|
||||
StencilOp stencilFailOpBack;
|
||||
/**
|
||||
* The function to use when the stencil test passes but the depth test fails for back face
|
||||
*/
|
||||
StencilOp stencilZFailOpBack;
|
||||
/**
|
||||
* The function to use when both the stencil and the depth test pass for back face.
|
||||
* Or when the stencil test passes and there is no depth buffer or depth testing is disabled.
|
||||
*/
|
||||
StencilOp stencilZPassOpBack;
|
||||
/**
|
||||
* The bit mask to enable or disable writing of individual bits in the back stencil planes
|
||||
*/
|
||||
uint32_t stencilWriteMaskBack;
|
||||
/**
|
||||
end of Stencil
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Specifies whether front-facing or back-facing polygons are candidates for culling.
|
||||
*/
|
||||
CullMode cullMode;
|
||||
|
||||
/**
|
||||
* Specifies the primitive type for rendering
|
||||
*/
|
||||
PrimitiveType primitiveType;
|
||||
|
||||
int32_t maxStream;
|
||||
|
||||
/**
|
||||
* Specifies the vertex buffer
|
||||
*/
|
||||
void setVertexBuffer(size_t index, VertexBuffer* vertBuf);
|
||||
/**
|
||||
* Gets the vertex buffer
|
||||
*/
|
||||
VertexBuffer* getVertexBuffer(size_t index) const;
|
||||
|
||||
/**
|
||||
* Specifies the vertex buffer offset
|
||||
*/
|
||||
void setVertexBufferOffset(size_t index, int32_t offset);
|
||||
/**
|
||||
* Gets the vertex buffer offset
|
||||
*/
|
||||
int32_t getVertexBufferOffset(size_t index) const;
|
||||
|
||||
/**
|
||||
* Specifies the index buffer
|
||||
*/
|
||||
void setIndexBuffer(IndexBuffer* indexBuf);
|
||||
/**
|
||||
* Gets the index buffer
|
||||
*/
|
||||
IndexBuffer* getIndexBuffer() const;
|
||||
|
||||
/**
|
||||
* Sets the texture for specific texture unit
|
||||
*/
|
||||
void setTexture(size_t index, Texture* texture);
|
||||
/**
|
||||
* Gets the specific texture unit
|
||||
*/
|
||||
Texture* getTexture(size_t index) const;
|
||||
|
||||
/**
|
||||
* Gets all texture units
|
||||
*/
|
||||
const std::vector<Texture*>& getTextureUnits() const { return _textureUnits; }
|
||||
|
||||
/**
|
||||
* Sets the program used for rendering
|
||||
*/
|
||||
void setProgram(Program* program);
|
||||
/**
|
||||
* Gets the program used for rendering
|
||||
*/
|
||||
Program* getProgram() const;
|
||||
|
||||
private:
|
||||
std::vector<VertexBuffer*> _vertexBuffers;
|
||||
std::vector<int32_t> _vertexBufferOffsets;
|
||||
IndexBuffer *_indexBuffer = nullptr;
|
||||
std::vector<Texture*> _textureUnits;
|
||||
Program *_program = nullptr;
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
125
cocos2d-x/cocos/renderer/gfx/Texture.cpp
Normal file
125
cocos2d-x/cocos/renderer/gfx/Texture.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Texture.h"
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
#include "base/CCGLUtils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
struct GLFilter
|
||||
{
|
||||
GLuint min;
|
||||
GLuint mag;
|
||||
GLuint mip;
|
||||
};
|
||||
|
||||
GLFilter _filterGL[] = {
|
||||
{ GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR },
|
||||
{ GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR },
|
||||
};
|
||||
|
||||
} // namespace {
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
Texture::Texture()
|
||||
: _device(nullptr)
|
||||
, _anisotropy(1)
|
||||
, _target(0)
|
||||
, _wrapS(WrapMode::REPEAT)
|
||||
, _wrapT(WrapMode::REPEAT)
|
||||
, _width(4)
|
||||
, _height(4)
|
||||
, _minFilter(Filter::LINEAR)
|
||||
, _magFilter(Filter::LINEAR)
|
||||
, _mipFilter(Filter::LINEAR)
|
||||
, _hasMipmap(false)
|
||||
, _compressed(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
if (_glID == 0)
|
||||
{
|
||||
RENDERER_LOGE("Invalid texture: %p", this);
|
||||
return;
|
||||
}
|
||||
|
||||
glDeleteTextures(1, &_glID);
|
||||
|
||||
//REFINE: this._device._stats.tex -= this.bytes;
|
||||
}
|
||||
|
||||
bool Texture::init(DeviceGraphics* device)
|
||||
{
|
||||
if (device == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_device = device;
|
||||
_width = 4;
|
||||
_height = 4;
|
||||
_hasMipmap = false;
|
||||
_compressed = false;
|
||||
|
||||
_anisotropy = 1;
|
||||
_minFilter = Filter::LINEAR;
|
||||
_magFilter = Filter::LINEAR;
|
||||
_mipFilter = Filter::LINEAR;
|
||||
_wrapS = WrapMode::REPEAT;
|
||||
_wrapT = WrapMode::REPEAT;
|
||||
// wrapR available in webgl2
|
||||
// _wrapR = WrapMode::REPEAT;
|
||||
|
||||
_target = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLenum Texture::glFilter(Filter filter, Filter mipFilter/* = TextureFilter::NONE*/)
|
||||
{
|
||||
if (filter < Filter::NEAREST || filter > Filter::LINEAR)
|
||||
{
|
||||
RENDERER_LOGW("Unknown filter: %u", (uint32_t)filter);
|
||||
return mipFilter == Filter::NONE ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR;
|
||||
}
|
||||
|
||||
if (mipFilter < Filter::NONE || mipFilter > Filter::LINEAR)
|
||||
{
|
||||
RENDERER_LOGW("Unknown mipFilter: %u", (uint32_t)filter);
|
||||
return mipFilter == Filter::NONE ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR;
|
||||
}
|
||||
|
||||
const GLFilter& p = _filterGL[(uint8_t)filter];
|
||||
GLenum ret = p.min;
|
||||
if (mipFilter == Filter::NEAREST)
|
||||
ret = p.mag;
|
||||
else if (mipFilter == Filter::LINEAR)
|
||||
ret = p.mip;
|
||||
return ret;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
300
cocos2d-x/cocos/renderer/gfx/Texture.h
Normal file
300
cocos2d-x/cocos/renderer/gfx/Texture.h
Normal file
@@ -0,0 +1,300 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
|
||||
#include "GraphicsHandle.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "base/CCData.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class DeviceGraphics;
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The base texture class
|
||||
*/
|
||||
class Texture : public RenderTarget
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @enum Filter
|
||||
* Texture filter modes
|
||||
*/
|
||||
enum class Filter : int8_t
|
||||
{
|
||||
NONE = -1,
|
||||
NEAREST = 0,
|
||||
LINEAR = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* @enum Filter
|
||||
* Texture wrap modes
|
||||
*/
|
||||
enum class WrapMode : uint16_t
|
||||
{
|
||||
REPEAT = GL_REPEAT,
|
||||
CLAMP = GL_CLAMP_TO_EDGE,
|
||||
MIRROR = GL_MIRRORED_REPEAT
|
||||
};
|
||||
|
||||
/**
|
||||
* @enum Format
|
||||
* Texture formats
|
||||
*/
|
||||
enum class Format : uint8_t
|
||||
{
|
||||
BEGIN = 0,
|
||||
// compress formats
|
||||
RGB_DXT1 = 0,
|
||||
RGBA_DXT1 = 1,
|
||||
RGBA_DXT3 = 2,
|
||||
RGBA_DXT5 = 3,
|
||||
RGB_ETC1 = 4,
|
||||
RGB_PVRTC_2BPPV1 = 5,
|
||||
RGBA_PVRTC_2BPPV1 = 6,
|
||||
RGB_PVRTC_4BPPV1 = 7,
|
||||
RGBA_PVRTC_4BPPV1 = 8,
|
||||
//
|
||||
// normal formats
|
||||
A8 = 9,
|
||||
L8 = 10,
|
||||
L8_A8 = 11,
|
||||
R5_G6_B5 = 12,
|
||||
R5_G5_B5_A1 = 13,
|
||||
R4_G4_B4_A4 = 14,
|
||||
RGB8 = 15, // each channel has 8 bits
|
||||
RGBA8 = 16, // each channel has 8 bits
|
||||
RGB16F = 17, // each channel has 16 bits
|
||||
RGBA16F = 18, // each channel has 16 bits
|
||||
RGB32F = 19, // each channel has 32 bits
|
||||
RGBA32F = 20, // each channel has 32 bits
|
||||
R32F = 21,
|
||||
_111110F = 22,
|
||||
SRGB = 23,
|
||||
SRGBA = 24,
|
||||
//
|
||||
// depth formats
|
||||
D16 = 25,
|
||||
END = 25
|
||||
//
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct Image
|
||||
* Raw image data
|
||||
*/
|
||||
struct Image
|
||||
{
|
||||
uint8_t* data = nullptr;
|
||||
size_t length = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct Options
|
||||
* Texture setting options including format, width, height, wrap mode, filter etc.
|
||||
*/
|
||||
struct Options
|
||||
{
|
||||
/**
|
||||
* Image mipmaps
|
||||
*/
|
||||
std::vector<Image> images;
|
||||
/**
|
||||
* The maximum anisotropy for the texture
|
||||
*/
|
||||
int32_t anisotropy = 1;
|
||||
/**
|
||||
* The internal format specifying the color components in the texture
|
||||
*/
|
||||
GLenum glInternalFormat = GL_RGBA;
|
||||
/**
|
||||
* The pixel format of the texel data
|
||||
*/
|
||||
GLenum glFormat = GL_RGB;
|
||||
/**
|
||||
* The data type of the texel data
|
||||
*/
|
||||
GLenum glType = GL_UNSIGNED_BYTE;
|
||||
/**
|
||||
* The width of the texture
|
||||
*/
|
||||
uint16_t width = 4;
|
||||
/**
|
||||
* The height of the texture
|
||||
*/
|
||||
uint16_t height = 4;
|
||||
uint8_t bpp = 0;
|
||||
|
||||
/**
|
||||
* The wrapping function for texture coordinate s
|
||||
*/
|
||||
WrapMode wrapS = WrapMode::CLAMP;
|
||||
/**
|
||||
* The wrapping function for texture coordinate t
|
||||
*/
|
||||
WrapMode wrapT = WrapMode::CLAMP;
|
||||
/**
|
||||
* The texture minification filter
|
||||
*/
|
||||
Filter minFilter = Filter::LINEAR;
|
||||
/**
|
||||
* The texture magnification filter
|
||||
*/
|
||||
Filter magFilter = Filter::LINEAR;
|
||||
/**
|
||||
* The texture filter for mipmaps
|
||||
*/
|
||||
Filter mipFilter = Filter::LINEAR;
|
||||
|
||||
/**
|
||||
* Specifies whether the texture have mipmaps
|
||||
*/
|
||||
bool hasMipmap = false;
|
||||
/**
|
||||
* Specifies whether the texture if flipped vertically
|
||||
*/
|
||||
bool flipY = false;
|
||||
/**
|
||||
* Specifies whether the texture have alpha premultiplied
|
||||
*/
|
||||
bool premultiplyAlpha = false;
|
||||
/**
|
||||
* Specifies whether the texture is compressed
|
||||
*/
|
||||
bool compressed = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct ImageOption
|
||||
* The informations of Image which indicates the mipmap level, width, height, filpY and premultiplyAlpha
|
||||
*/
|
||||
struct ImageOption
|
||||
{
|
||||
Image image;
|
||||
int32_t level = 0;
|
||||
uint16_t width = 4;
|
||||
uint16_t height = 4;
|
||||
|
||||
bool flipY = false;
|
||||
bool premultiplyAlpha = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct SubImageOption
|
||||
* The informations of sub image which indicates the area to update, mipmap level, filpY and premultiplyAlpha
|
||||
*/
|
||||
struct SubImageOption
|
||||
{
|
||||
SubImageOption(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t level, bool flipY, bool premultiplyAlpha)
|
||||
: x(x)
|
||||
, y(y)
|
||||
, width(width)
|
||||
, height(height)
|
||||
, level(level)
|
||||
, flipY(flipY)
|
||||
, premultiplyAlpha(premultiplyAlpha)
|
||||
{}
|
||||
|
||||
SubImageOption() {}
|
||||
|
||||
uint32_t imageDataLength = 0;
|
||||
uint16_t x = 0;
|
||||
uint16_t y = 0;
|
||||
uint16_t width = 0;
|
||||
uint16_t height = 0;
|
||||
uint8_t* imageData = nullptr;
|
||||
uint8_t level = 0;
|
||||
bool flipY = false;
|
||||
bool premultiplyAlpha = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the target gl location
|
||||
*/
|
||||
inline GLuint getTarget() const { return _target; }
|
||||
/**
|
||||
* Gets the width of texture
|
||||
*/
|
||||
inline uint16_t getWidth() const { return _width; }
|
||||
/**
|
||||
* Gets the height of texture
|
||||
*/
|
||||
inline uint16_t getHeight() const { return _height; }
|
||||
|
||||
|
||||
inline void setAlphaAtlas(bool value) { _useAlphaAtlas = value; }
|
||||
inline bool isAlphaAtlas() const { return _useAlphaAtlas; }
|
||||
|
||||
protected:
|
||||
|
||||
static GLenum glFilter(Filter filter, Filter mipFilter = Filter::NONE);
|
||||
|
||||
static bool isPow2(int32_t v) {
|
||||
return !(v & (v - 1)) && (!!v);
|
||||
}
|
||||
|
||||
Texture();
|
||||
virtual ~Texture();
|
||||
|
||||
bool init(DeviceGraphics* device);
|
||||
|
||||
DeviceGraphics* _device;
|
||||
GLint _anisotropy;
|
||||
GLuint _target;
|
||||
|
||||
WrapMode _wrapS;
|
||||
WrapMode _wrapT;
|
||||
uint16_t _width;
|
||||
uint16_t _height;
|
||||
uint8_t _bpp = 0;
|
||||
|
||||
Filter _minFilter;
|
||||
Filter _magFilter;
|
||||
Filter _mipFilter;
|
||||
GLenum _glInternalFormat;
|
||||
GLenum _glFormat;
|
||||
GLenum _glType;
|
||||
|
||||
bool _hasMipmap;
|
||||
bool _compressed;
|
||||
|
||||
bool _useAlphaAtlas = false;
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
293
cocos2d-x/cocos/renderer/gfx/Texture2D.cpp
Normal file
293
cocos2d-x/cocos/renderer/gfx/Texture2D.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Texture2D.h"
|
||||
#include "DeviceGraphics.h"
|
||||
#include "GFXUtils.h"
|
||||
|
||||
#include "base/CCGLUtils.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
Texture2D::Texture2D()
|
||||
{
|
||||
// RENDERER_LOGD("Construct Texture2D: %p", this);
|
||||
}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
// RENDERER_LOGD("Destruct Texture2D: %p", this);
|
||||
}
|
||||
|
||||
bool Texture2D::init(DeviceGraphics* device, Options& options)
|
||||
{
|
||||
bool ok = Texture::init(device);
|
||||
if (ok)
|
||||
{
|
||||
_target = GL_TEXTURE_2D;
|
||||
GL_CHECK(glGenTextures(1, &_glID));
|
||||
|
||||
if (options.images.empty())
|
||||
options.images.push_back(Image());
|
||||
|
||||
update(options);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void Texture2D::update(const Options& options)
|
||||
{
|
||||
bool genMipmap = _hasMipmap;
|
||||
|
||||
_width = options.width;
|
||||
_height = options.height;
|
||||
_anisotropy = options.anisotropy;
|
||||
_minFilter = options.minFilter;
|
||||
_magFilter = options.magFilter;
|
||||
_mipFilter = options.mipFilter;
|
||||
_wrapS = options.wrapS;
|
||||
_wrapT = options.wrapT;
|
||||
_glFormat = options.glFormat;
|
||||
_glInternalFormat = options.glInternalFormat;
|
||||
_glType = options.glType;
|
||||
_compressed = options.compressed;
|
||||
_bpp = options.bpp;
|
||||
|
||||
// check if generate mipmap
|
||||
_hasMipmap = options.hasMipmap;
|
||||
genMipmap = options.hasMipmap;
|
||||
|
||||
if (options.images.size() > 1)
|
||||
{
|
||||
genMipmap = false; //REFINE: is it true here?
|
||||
uint16_t maxLength = options.width > options.height ? options.width : options.height;
|
||||
if (maxLength >> (options.images.size() - 1) != 1)
|
||||
RENDERER_LOGE("texture-2d mipmap is invalid, should have a 1x1 mipmap.");
|
||||
}
|
||||
|
||||
// NOTE: get pot after _width, _height has been assigned.
|
||||
bool pot = isPow2(_width) && isPow2(_height);
|
||||
if (!pot)
|
||||
genMipmap = false;
|
||||
|
||||
GL_CHECK(glActiveTexture(GL_TEXTURE0));
|
||||
GL_CHECK(glBindTexture(GL_TEXTURE_2D, _glID));
|
||||
if (!options.images.empty())
|
||||
setMipmap(options.images, options.flipY, options.premultiplyAlpha);
|
||||
|
||||
setTexInfo();
|
||||
|
||||
if (genMipmap)
|
||||
{
|
||||
GL_CHECK(glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST));
|
||||
GL_CHECK(glGenerateMipmap(GL_TEXTURE_2D));
|
||||
}
|
||||
_device->restoreTexture(0);
|
||||
}
|
||||
|
||||
void Texture2D::updateSubImage(const SubImageOption& option)
|
||||
{
|
||||
GL_CHECK(glActiveTexture(GL_TEXTURE0));
|
||||
GL_CHECK(glBindTexture(GL_TEXTURE_2D, _glID));
|
||||
setSubImage(option);
|
||||
_device->restoreTexture(0);
|
||||
}
|
||||
|
||||
void Texture2D::updateImage(const ImageOption& option)
|
||||
{
|
||||
GL_CHECK(glActiveTexture(GL_TEXTURE0));
|
||||
GL_CHECK(glBindTexture(GL_TEXTURE_2D, _glID));
|
||||
setImage(option);
|
||||
_device->restoreTexture(0);
|
||||
}
|
||||
|
||||
// Private methods:
|
||||
|
||||
void Texture2D::setSubImage(const SubImageOption& option)
|
||||
{
|
||||
bool flipY = option.flipY;
|
||||
bool premultiplyAlpha = option.premultiplyAlpha;
|
||||
|
||||
//Set the row align only when mipmapsNum == 1 and the data is uncompressed
|
||||
GLint aligment = 1;
|
||||
if (!_hasMipmap && !_compressed && _bpp > 0)
|
||||
{
|
||||
unsigned int bytesPerRow = option.width * _bpp / 8;
|
||||
|
||||
if (bytesPerRow % 8 == 0)
|
||||
aligment = 8;
|
||||
else if (bytesPerRow % 4 == 0)
|
||||
aligment = 4;
|
||||
else if (bytesPerRow % 2 == 0)
|
||||
aligment = 2;
|
||||
else
|
||||
aligment = 1;
|
||||
}
|
||||
|
||||
GL_CHECK(ccPixelStorei(GL_UNPACK_ALIGNMENT, aligment));
|
||||
|
||||
GL_CHECK(ccPixelStorei(GL_UNPACK_FLIP_Y_WEBGL, flipY));
|
||||
GL_CHECK(ccPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha));
|
||||
|
||||
ccFlipYOrPremultiptyAlphaIfNeeded(_glFormat, option.width, option.height, (uint32_t)option.imageDataLength, option.imageData);
|
||||
|
||||
if (_compressed)
|
||||
{
|
||||
glCompressedTexSubImage2D(GL_TEXTURE_2D,
|
||||
option.level,
|
||||
option.x,
|
||||
option.y,
|
||||
option.width,
|
||||
option.height,
|
||||
_glFormat,
|
||||
option.imageDataLength,
|
||||
option.imageData);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glTexSubImage2D(GL_TEXTURE_2D,
|
||||
option.level,
|
||||
option.x,
|
||||
option.y,
|
||||
option.width,
|
||||
option.height,
|
||||
_glFormat,
|
||||
_glType, option.imageData));
|
||||
}
|
||||
}
|
||||
|
||||
void Texture2D::setImage(const ImageOption& option)
|
||||
{
|
||||
const auto& img = option.image;
|
||||
|
||||
bool flipY = option.flipY;
|
||||
bool premultiplyAlpha = option.premultiplyAlpha;
|
||||
|
||||
//Set the row align only when mipmapsNum == 1 and the data is uncompressed
|
||||
GLint aligment = 1;
|
||||
unsigned int bytesPerRow = option.width * _bpp / 8;
|
||||
if (_hasMipmap && !_compressed && _bpp > 0)
|
||||
{
|
||||
if (bytesPerRow % 8 == 0)
|
||||
aligment = 8;
|
||||
else if (bytesPerRow % 4 == 0)
|
||||
aligment = 4;
|
||||
else if (bytesPerRow % 2 == 0)
|
||||
aligment = 2;
|
||||
else
|
||||
aligment = 1;
|
||||
}
|
||||
|
||||
GL_CHECK(ccPixelStorei(GL_UNPACK_ALIGNMENT, aligment));
|
||||
GL_CHECK(ccPixelStorei(GL_UNPACK_FLIP_Y_WEBGL, flipY));
|
||||
GL_CHECK(ccPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha));
|
||||
|
||||
uint32_t pixelBytes = (uint32_t)img.length;
|
||||
|
||||
switch(_glType)
|
||||
{
|
||||
case GL_FLOAT:
|
||||
{
|
||||
pixelBytes /= sizeof(float);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ccFlipYOrPremultiptyAlphaIfNeeded(_glFormat, option.width, option.height, pixelBytes, img.data);
|
||||
|
||||
if (_compressed)
|
||||
{
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D,
|
||||
option.level,
|
||||
_glInternalFormat,
|
||||
option.width,
|
||||
option.height,
|
||||
0,
|
||||
(GLsizei)img.length,
|
||||
img.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glTexImage2D(GL_TEXTURE_2D,
|
||||
option.level,
|
||||
_glInternalFormat,
|
||||
option.width,
|
||||
option.height,
|
||||
0,
|
||||
_glFormat,
|
||||
_glType,
|
||||
img.data));
|
||||
}
|
||||
}
|
||||
|
||||
void Texture2D::setMipmap(const std::vector<Image>& images, bool isFlipY, bool isPremultiplyAlpha)
|
||||
{
|
||||
ImageOption options;
|
||||
options.width = _width;
|
||||
options.height = _height;
|
||||
options.flipY = isFlipY;
|
||||
options.premultiplyAlpha = isPremultiplyAlpha;
|
||||
options.level = 0;
|
||||
|
||||
for (size_t i = 0, len = images.size(); i < len; ++i)
|
||||
{
|
||||
options.level = (GLint)i;
|
||||
options.width = _width >> i;
|
||||
options.height = _height >> i;
|
||||
options.image = images[i];
|
||||
setImage(options);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture2D::setTexInfo()
|
||||
{
|
||||
bool pot = isPow2(_width) && isPow2(_height);
|
||||
|
||||
// WebGL1 doesn't support all wrap modes with NPOT textures
|
||||
if (!pot && (_wrapS != WrapMode::CLAMP || _wrapT != WrapMode::CLAMP))
|
||||
{
|
||||
RENDERER_LOGW("WebGL1 doesn\'t support all wrap modes with NPOT textures");
|
||||
_wrapS = WrapMode::CLAMP;
|
||||
_wrapT = WrapMode::CLAMP;
|
||||
}
|
||||
|
||||
Filter mipFilter = _hasMipmap ? _mipFilter : Filter::NONE;
|
||||
if (!pot && mipFilter != Filter::NONE)
|
||||
{
|
||||
RENDERER_LOGW("NPOT textures do not support mipmap filter");
|
||||
mipFilter = Filter::NONE;
|
||||
}
|
||||
|
||||
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glFilter(_minFilter, mipFilter)));
|
||||
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glFilter(_magFilter, Filter::NONE)));
|
||||
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (GLint)_wrapS));
|
||||
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (GLint)_wrapT));
|
||||
|
||||
//REFINE: let ext = this._device.ext('EXT_texture_filter_anisotropic');
|
||||
// if (ext) {
|
||||
// GL_CHECK(glTexParameteri(GL_TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, this._anisotropy));
|
||||
// }
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
90
cocos2d-x/cocos/renderer/gfx/Texture2D.h
Normal file
90
cocos2d-x/cocos/renderer/gfx/Texture2D.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
|
||||
#include "Texture.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The 2d texture class\n
|
||||
* JS API: gfx.Texture2D
|
||||
@code
|
||||
let texture = new gfx.Texture2D(cc.renderer.device, {
|
||||
images: [],
|
||||
width: 128,
|
||||
height: 128,
|
||||
wrapS: renderEngine.gfx.WRAP_REPEAT,
|
||||
wrapT: renderEngine.gfx.WRAP_REPEAT,
|
||||
format: renderEngine.gfx.TEXTURE_FMT_RGB8,
|
||||
mipmap: false,
|
||||
});
|
||||
@endcode
|
||||
*/
|
||||
class Texture2D : public Texture
|
||||
{
|
||||
public:
|
||||
Texture2D();
|
||||
~Texture2D();
|
||||
|
||||
/*
|
||||
* Init the texture with device and options
|
||||
* @see Texture::Options
|
||||
*/
|
||||
bool init(DeviceGraphics* device, Options& options);
|
||||
/**
|
||||
* Update the texture with new options
|
||||
* @see Texture::Options
|
||||
*/
|
||||
void update(const Options& options);
|
||||
/**
|
||||
* Update a sub area of the texture with sub image option
|
||||
* @see Texture::SubImageOption
|
||||
*/
|
||||
void updateSubImage(const SubImageOption& option);
|
||||
/**
|
||||
* Update the image of a given level mipmap specified in image option
|
||||
* @see Texture::ImageOption
|
||||
*/
|
||||
void updateImage(const ImageOption& option);
|
||||
private:
|
||||
void setSubImage(const SubImageOption& options);
|
||||
void setImage(const ImageOption& options);
|
||||
void setMipmap(const std::vector<Image>& images, bool isFlipY, bool isPremultiplyAlpha);
|
||||
void setTexInfo();
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
149
cocos2d-x/cocos/renderer/gfx/VertexBuffer.cpp
Normal file
149
cocos2d-x/cocos/renderer/gfx/VertexBuffer.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "VertexBuffer.h"
|
||||
#include "DeviceGraphics.h"
|
||||
#include "base/CCGLUtils.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
VertexBuffer::VertexBuffer()
|
||||
: _device(nullptr)
|
||||
, _usage(Usage::STATIC)
|
||||
, _numVertices(0)
|
||||
, _bytes(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
bool VertexBuffer::init(DeviceGraphics* device, VertexFormat* format, Usage usage, const void* data, size_t dataByteLength, uint32_t numVertices)
|
||||
{
|
||||
_device = device;
|
||||
setFormat(format);
|
||||
_usage = usage;
|
||||
_numVertices = numVertices;
|
||||
_needExpandDataStore = true;
|
||||
|
||||
// calculate bytes
|
||||
_bytes = _format->_bytes * numVertices;
|
||||
|
||||
// update
|
||||
glGenBuffers(1, &_glID);
|
||||
update(0, data, dataByteLength);
|
||||
|
||||
// stats
|
||||
//REFINE: device._stats.ib += _bytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VertexBuffer::setFormat(VertexFormat* format)
|
||||
{
|
||||
if (_format == format)
|
||||
return;
|
||||
|
||||
CC_SAFE_RELEASE(_format);
|
||||
_format = format;
|
||||
CC_SAFE_RETAIN(_format);
|
||||
|
||||
}
|
||||
|
||||
void VertexBuffer::update(uint32_t offset, const void* data, size_t dataByteLength)
|
||||
{
|
||||
if(data == nullptr || dataByteLength == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_glID == 0)
|
||||
{
|
||||
RENDERER_LOGE("The buffer is destroyed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataByteLength + offset > _bytes)
|
||||
{
|
||||
if (offset) {
|
||||
RENDERER_LOGE("Failed to update index buffer data, bytes exceed.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
_needExpandDataStore = true;
|
||||
_bytes = offset + dataByteLength;
|
||||
_numVertices = _bytes / _format->_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
GLenum glUsage = (GLenum)_usage;
|
||||
ccBindBuffer(GL_ARRAY_BUFFER, _glID);
|
||||
if (_needExpandDataStore)
|
||||
{
|
||||
glBufferData(GL_ARRAY_BUFFER, _bytes, (const GLvoid*)data, glUsage);
|
||||
_needExpandDataStore = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)offset, (GLsizeiptr)dataByteLength, (const GLvoid*)data);
|
||||
}
|
||||
ccBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void VertexBuffer::destroy()
|
||||
{
|
||||
if (_glID == 0)
|
||||
return;
|
||||
|
||||
CC_SAFE_RELEASE_NULL(_format);
|
||||
|
||||
ccDeleteBuffers(1, &_glID);
|
||||
//REFINE: _device._stats.ib -= _bytes;
|
||||
|
||||
_glID = 0;
|
||||
}
|
||||
|
||||
#if GFX_DEBUG > 0
|
||||
static void testVertexBuffer()
|
||||
{
|
||||
VertexFormat vertexFmt({
|
||||
{ ATTRIB_NAME_POSITION, AttribType::FLOAT32, 2 }
|
||||
});
|
||||
|
||||
DeviceGraphics* device = nullptr;
|
||||
float vertex[] = {
|
||||
-1, 0, 0
|
||||
-1, 1, 1
|
||||
};
|
||||
VertexBuffer* buffer = new VertexBuffer();
|
||||
buffer->init(device, vertexFmt, Usage::STATIC, vertex, sizeof(vertex), 3);
|
||||
|
||||
buffer->release();
|
||||
}
|
||||
#endif
|
||||
|
||||
RENDERER_END
|
||||
146
cocos2d-x/cocos/renderer/gfx/VertexBuffer.h
Normal file
146
cocos2d-x/cocos/renderer/gfx/VertexBuffer.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
#include "VertexFormat.h"
|
||||
#include "GraphicsHandle.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
class DeviceGraphics;
|
||||
|
||||
/**
|
||||
* VertexBuffer manages the GL vertex attributes buffer.
|
||||
* It creates, updates and destoies the GL vertex buffer.
|
||||
*/
|
||||
class VertexBuffer final : public GraphicsHandle
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates a vertex buffer object
|
||||
* @param[in] device DeviceGraphics pointer
|
||||
* @param[in] format Specifies the vertex attributes layout
|
||||
* @param[in] usage The usage pattern
|
||||
* @param[in] data Data pointer, could be nullptr, then nothing is updated to the buffer.
|
||||
* @param[in] dataByteLength Data's byte length.
|
||||
* @param[in] numVertices Count of vertices.
|
||||
*/
|
||||
RENDERER_DEFINE_CREATE_METHOD_6(VertexBuffer, init, DeviceGraphics*, VertexFormat*, Usage, const void*, size_t, uint32_t)
|
||||
|
||||
VertexBuffer();
|
||||
virtual ~VertexBuffer();
|
||||
|
||||
/**
|
||||
* Initializes a vertex buffer object
|
||||
* @param[in] device DeviceGraphics pointer
|
||||
* @param[in] format Specifies the vertex attributes layout
|
||||
* @param[in] usage The usage pattern
|
||||
* @param[in] data Data pointer, could be nullptr, then nothing is updated to the buffer.
|
||||
* @param[in] dataByteLength Data's byte length.
|
||||
* @param[in] numVertices Count of vertices.
|
||||
*/
|
||||
bool init(DeviceGraphics* device, VertexFormat* format, Usage usage, const void* data, size_t dataByteLength, uint32_t numVertices);
|
||||
/**
|
||||
* Update data to the GL vertex buffer
|
||||
* @param[in] offset Destination offset for filling buffer data.
|
||||
* @param[in] data Data to be updated.
|
||||
* @param[in] dataByteLength Data byte length to be updated.
|
||||
*/
|
||||
void update(uint32_t offset, const void* data, size_t dataByteLength);
|
||||
|
||||
/**
|
||||
* Gets the count of vertices
|
||||
*/
|
||||
inline uint32_t getCount() const { return _numVertices; }
|
||||
/**
|
||||
* Sets the count of vertices
|
||||
*/
|
||||
inline void setCount(uint32_t numVertices) { _numVertices = numVertices; }
|
||||
|
||||
/**
|
||||
* Gets the attributes layout and format of vertices.
|
||||
*/
|
||||
inline const VertexFormat& getFormat() const { return *_format; }
|
||||
// inline void setFormat(VertexFormat&& format) { _format = std::move(format); }
|
||||
/**
|
||||
* Sets the attributes layout and format of vertices.
|
||||
*/
|
||||
void setFormat(VertexFormat* format);
|
||||
|
||||
/**
|
||||
* Gets usage pattern of the vertex buffer
|
||||
*/
|
||||
inline Usage getUsage() const { return _usage; }
|
||||
/**
|
||||
* Sets usage pattern of the vertex buffer
|
||||
*/
|
||||
inline void setUsage(Usage usage) { _usage = usage; }
|
||||
|
||||
/**
|
||||
* Gets byte size of the vertex buffer
|
||||
*/
|
||||
inline uint32_t getBytes() const { return _bytes; }
|
||||
|
||||
using FetchDataCallback = std::function<uint8_t*(size_t*)>;
|
||||
void setFetchDataCallback(const FetchDataCallback& cb) { _fetchDataCallback = cb; }
|
||||
uint8_t* invokeFetchDataCallback(size_t* bytes) {
|
||||
if (_fetchDataCallback == nullptr)
|
||||
{
|
||||
*bytes = 0;
|
||||
return nullptr;
|
||||
}
|
||||
return _fetchDataCallback(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroies the vertex buffer
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
DeviceGraphics* _device = nullptr;
|
||||
VertexFormat* _format = nullptr;
|
||||
Usage _usage;
|
||||
uint32_t _numVertices;
|
||||
uint32_t _bytes;
|
||||
bool _needExpandDataStore = true;
|
||||
|
||||
FetchDataCallback _fetchDataCallback;
|
||||
|
||||
CC_DISALLOW_COPY_ASSIGN_AND_MOVE(VertexBuffer)
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
164
cocos2d-x/cocos/renderer/gfx/VertexFormat.cpp
Normal file
164
cocos2d-x/cocos/renderer/gfx/VertexFormat.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "VertexFormat.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
static uint32_t attrTypeBytes(AttribType attrType)
|
||||
{
|
||||
if (attrType == AttribType::INT8) {
|
||||
return 1;
|
||||
} else if (attrType == AttribType::UINT8) {
|
||||
return 1;
|
||||
} else if (attrType == AttribType::INT16) {
|
||||
return 2;
|
||||
} else if (attrType == AttribType::UINT16) {
|
||||
return 2;
|
||||
} else if (attrType == AttribType::INT32) {
|
||||
return 4;
|
||||
} else if (attrType == AttribType::UINT32) {
|
||||
return 4;
|
||||
} else if (attrType == AttribType::FLOAT32) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
RENDERER_LOGW("Unknown ATTR_TYPE: %u", (uint32_t)attrType);
|
||||
return 0;
|
||||
}
|
||||
|
||||
VertexFormat* VertexFormat::XY_UV_Two_Color = new VertexFormat(std::vector<Info>({
|
||||
Info(ATTRIB_NAME_POSITION, AttribType::FLOAT32, 2),
|
||||
Info(ATTRIB_NAME_UV0, AttribType::FLOAT32, 2),
|
||||
Info(ATTRIB_NAME_COLOR, AttribType::UINT8, 4, true),
|
||||
Info(ATTRIB_NAME_COLOR0, AttribType::UINT8, 4, true)
|
||||
}));
|
||||
|
||||
VertexFormat* VertexFormat::XY_UV_Color = new VertexFormat(std::vector<Info>({
|
||||
Info(ATTRIB_NAME_POSITION, AttribType::FLOAT32, 2),
|
||||
Info(ATTRIB_NAME_UV0, AttribType::FLOAT32, 2),
|
||||
Info(ATTRIB_NAME_COLOR, AttribType::UINT8, 4, true)
|
||||
}));
|
||||
|
||||
VertexFormat* VertexFormat::XY_Color = new VertexFormat(std::vector<Info>({
|
||||
Info(ATTRIB_NAME_POSITION, AttribType::FLOAT32, 2),
|
||||
Info(ATTRIB_NAME_COLOR, AttribType::UINT8, 4, true)
|
||||
}));
|
||||
|
||||
VertexFormat::VertexFormat()
|
||||
{
|
||||
}
|
||||
|
||||
VertexFormat::VertexFormat(const std::vector<Info>& infos)
|
||||
{
|
||||
_bytes = 0;
|
||||
#if GFX_DEBUG > 0
|
||||
std::vector<Element*> _elements;
|
||||
std::vector<Element*>& elements = _elements;
|
||||
#else
|
||||
std::vector<Element*> elements;
|
||||
#endif
|
||||
|
||||
uint32_t offset = 0;
|
||||
for (size_t i = 0, len = infos.size(); i < len; ++i)
|
||||
{
|
||||
const auto& info = infos[i];
|
||||
Element el;
|
||||
el.name = info._name;
|
||||
el.offset = offset;
|
||||
el.stride = 0;
|
||||
el.stream = -1;
|
||||
el.type = info._type;
|
||||
el.num = info._num;
|
||||
el.normalize = info._normalize;
|
||||
el.bytes = info._num * attrTypeBytes(info._type);
|
||||
|
||||
_names.push_back(el.name);
|
||||
_attr2el[std::hash<std::string>{}(el.name)] = el;
|
||||
elements.push_back(&_attr2el[std::hash<std::string>{}(el.name)]);
|
||||
|
||||
_bytes += el.bytes;
|
||||
offset += el.bytes;
|
||||
}
|
||||
|
||||
for (size_t i = 0, len = elements.size(); i < len; ++i)
|
||||
{
|
||||
auto& el = elements[i];
|
||||
el->stride = _bytes;
|
||||
}
|
||||
}
|
||||
|
||||
VertexFormat::VertexFormat(const VertexFormat& o)
|
||||
{
|
||||
if (this != &o)
|
||||
*this = o;
|
||||
}
|
||||
|
||||
VertexFormat::VertexFormat(VertexFormat&& o)
|
||||
{
|
||||
if (this != &o)
|
||||
*this = std::move(o);
|
||||
}
|
||||
|
||||
VertexFormat& VertexFormat::operator=(const VertexFormat& o)
|
||||
{
|
||||
if (this != &o)
|
||||
{
|
||||
_names = o._names;
|
||||
_attr2el = o._attr2el;
|
||||
#if GFX_DEBUG > 0
|
||||
_elements = o._elements;
|
||||
_bytes = o._bytes;
|
||||
#endif
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
VertexFormat& VertexFormat::operator=(VertexFormat&& o)
|
||||
{
|
||||
if (this != &o)
|
||||
{
|
||||
_names = std::move(o._names);
|
||||
_attr2el = std::move(o._attr2el);
|
||||
#if GFX_DEBUG > 0
|
||||
_elements = std::move(o._elements);
|
||||
_bytes = o._bytes;
|
||||
o._bytes = 0;
|
||||
#endif
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const VertexFormat::Element* VertexFormat::getElement(size_t hashName) const
|
||||
{
|
||||
static const Element* INVALID_ELEMENT_VALUE = nullptr;
|
||||
const auto& iter = _attr2el.find(hashName);
|
||||
if (iter != _attr2el.end())
|
||||
{
|
||||
return &iter->second;
|
||||
}
|
||||
return INVALID_ELEMENT_VALUE;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
197
cocos2d-x/cocos/renderer/gfx/VertexFormat.h
Normal file
197
cocos2d-x/cocos/renderer/gfx/VertexFormat.h
Normal file
@@ -0,0 +1,197 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "base/CCRef.h"
|
||||
#include "../Types.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup gfx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The vertex format defines the attributes and their data layout in the VertexBuffer\n
|
||||
* JS API: gfx.VertexFormat
|
||||
@code
|
||||
let vertexFmt = new gfx.VertexFormat([
|
||||
{ name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 3 },
|
||||
{ name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
|
||||
{ name: gfx.ATTR_COLOR, type: gfx.ATTR_TYPE_FLOAT32, num: 4, normalize: true },
|
||||
]);
|
||||
@endcode
|
||||
*/
|
||||
class VertexFormat : public Ref
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* Informations used to define an attribute in vertex data layout.
|
||||
* @struct Info
|
||||
*/
|
||||
struct Info
|
||||
{
|
||||
/*
|
||||
* Constructor
|
||||
* @param[in] name Attribute name
|
||||
* @param[in] type Data type of each component
|
||||
* @param[in] num Number of components per attribute
|
||||
* @param[in] normalized Whether integer data values should be normalized into a certain range when being casted to a float
|
||||
*/
|
||||
Info(const std::string& name, AttribType type, uint32_t num, bool normalize = false)
|
||||
: _name(name)
|
||||
, _num(num)
|
||||
, _type(type)
|
||||
, _normalize(normalize)
|
||||
{
|
||||
}
|
||||
std::string _name;
|
||||
uint32_t _num;
|
||||
AttribType _type;
|
||||
bool _normalize;
|
||||
};
|
||||
|
||||
static Info INFO_END;
|
||||
|
||||
/*
|
||||
* Element describes informations of an attribute
|
||||
* @struct Info
|
||||
*/
|
||||
struct Element
|
||||
{
|
||||
Element()
|
||||
: offset(0)
|
||||
, stride(0)
|
||||
, stream(-1)
|
||||
, num(0)
|
||||
, bytes(0)
|
||||
, type(AttribType::INVALID)
|
||||
, normalize(false)
|
||||
{}
|
||||
|
||||
inline bool isValid() const
|
||||
{
|
||||
return type != AttribType::INVALID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Name of the attribute
|
||||
*/
|
||||
std::string name;
|
||||
/*
|
||||
* Byte offset in each vertex data
|
||||
*/
|
||||
size_t offset;
|
||||
/*
|
||||
* Specifies the offset in bytes between the beginning of consecutive vertex attributes
|
||||
*/
|
||||
uint32_t stride;
|
||||
int32_t stream;
|
||||
/*
|
||||
* Number of components per attribute unit
|
||||
*/
|
||||
uint32_t num;
|
||||
/*
|
||||
* Total bytes per attribute unit
|
||||
*/
|
||||
uint32_t bytes;
|
||||
/*
|
||||
* Data type of each component
|
||||
*/
|
||||
AttribType type;
|
||||
/*
|
||||
* Specifies whether integer data values should be normalized into a certain range when being casted to a float
|
||||
*/
|
||||
bool normalize;
|
||||
};
|
||||
|
||||
/*
|
||||
* Default constructor
|
||||
*/
|
||||
VertexFormat();
|
||||
/**
|
||||
* Constructor with specific attribute informations
|
||||
* @param[in] infos Array of all elements informations
|
||||
*/
|
||||
VertexFormat(const std::vector<Info>& infos);
|
||||
/*
|
||||
* Copy constructor
|
||||
*/
|
||||
VertexFormat(const VertexFormat& o);
|
||||
/*
|
||||
* Move constructor
|
||||
*/
|
||||
VertexFormat(VertexFormat&& o);
|
||||
|
||||
VertexFormat& operator=(const VertexFormat& o);
|
||||
VertexFormat& operator=(VertexFormat&& o);
|
||||
|
||||
/**
|
||||
* Gets all attribute names
|
||||
*/
|
||||
const std::vector<std::string>& getAttributeNames() const { return _names; };
|
||||
/**
|
||||
* Getes an attribute element by name
|
||||
*/
|
||||
const Element* getElement(size_t hashName) const;
|
||||
|
||||
/**
|
||||
* Gets total byte size of a vertex
|
||||
*/
|
||||
uint32_t getBytes() const { return _bytes; };
|
||||
|
||||
/*
|
||||
* Builtin VertexFormat with 2d position, uv, color, color0 attributes
|
||||
*/
|
||||
static VertexFormat* XY_UV_Two_Color;
|
||||
/*
|
||||
* Builtin VertexFormat with 2d position, uv, color attributes
|
||||
*/
|
||||
static VertexFormat* XY_UV_Color;
|
||||
/*
|
||||
* Builtin VertexFormat with 2d position, color attributes
|
||||
*/
|
||||
static VertexFormat* XY_Color;
|
||||
|
||||
private:
|
||||
std::vector<std::string> _names;
|
||||
std::unordered_map<size_t, Element> _attr2el;
|
||||
#if GFX_DEBUG > 0
|
||||
std::vector<Element> _elements;
|
||||
#endif
|
||||
uint32_t _bytes;
|
||||
|
||||
friend class VertexBuffer;
|
||||
};
|
||||
|
||||
// end of gfx group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
128
cocos2d-x/cocos/renderer/memop/RecyclePool.hpp
Normal file
128
cocos2d-x/cocos/renderer/memop/RecyclePool.hpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef RecyclePool_hpp
|
||||
#define RecyclePool_hpp
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../Macro.h"
|
||||
#include "../base/CCVector.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
template<typename T>
|
||||
class RecyclePool
|
||||
{
|
||||
public:
|
||||
typedef std::function<T*()> RecycleFunc;
|
||||
|
||||
RecyclePool(RecycleFunc func, int size)
|
||||
: _data()
|
||||
{
|
||||
_count = 0;
|
||||
_func = func;
|
||||
_data.resize(size);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
_data[i] = func();
|
||||
}
|
||||
}
|
||||
|
||||
~RecyclePool()
|
||||
{
|
||||
for (size_t i = 0, len = _data.size(); i < len; i++)
|
||||
{
|
||||
delete _data[i];
|
||||
}
|
||||
|
||||
_data.clear();
|
||||
}
|
||||
|
||||
T* getData(size_t index) const
|
||||
{
|
||||
if (index >= _count)
|
||||
{
|
||||
RENDERER_LOGW("Failed to get data %zu, index not found.", index);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return _data[index];
|
||||
}
|
||||
|
||||
const size_t getLength() const
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
T* add()
|
||||
{
|
||||
int size = (int)_data.size();
|
||||
if (_count >= size)
|
||||
{
|
||||
resize(size * 2);
|
||||
}
|
||||
|
||||
return _data[_count++];
|
||||
}
|
||||
|
||||
void resize(int size)
|
||||
{
|
||||
if (size > _data.size())
|
||||
{
|
||||
for (int i = (int)_data.size(); i < size; i++)
|
||||
{
|
||||
T* data = _func();
|
||||
_data.push_back(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void remove(int index)
|
||||
{
|
||||
if (index >= _count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int last = _count - 1;
|
||||
T tmp = _data[index];
|
||||
_data[index] = _data[last];
|
||||
_data[last] = tmp;
|
||||
_count -= 1;
|
||||
}
|
||||
private:
|
||||
size_t _count = 0;
|
||||
RecycleFunc _func;
|
||||
std::vector<T*> _data;
|
||||
|
||||
|
||||
};
|
||||
RENDERER_END
|
||||
|
||||
#endif /* RecyclePool_hpp */
|
||||
392
cocos2d-x/cocos/renderer/renderer/BaseRenderer.cpp
Normal file
392
cocos2d-x/cocos/renderer/renderer/BaseRenderer.cpp
Normal file
@@ -0,0 +1,392 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "BaseRenderer.h"
|
||||
#include <new>
|
||||
#include "gfx/DeviceGraphics.h"
|
||||
#include "gfx/Texture2D.h"
|
||||
#include "ProgramLib.h"
|
||||
#include "View.h"
|
||||
#include "Scene.h"
|
||||
#include "Effect.h"
|
||||
#include "Light.h"
|
||||
#include "InputAssembler.h"
|
||||
#include "Pass.h"
|
||||
#include "Camera.h"
|
||||
#include "Model.h"
|
||||
#include "math/MathUtil.h"
|
||||
#include "Program.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
const size_t BaseRenderer::cc_lightDirection = std::hash<std::string>{}("cc_lightDirection");
|
||||
const size_t BaseRenderer::cc_lightColor = std::hash<std::string>{}("cc_lightColor");
|
||||
const size_t BaseRenderer::cc_lightPositionAndRange = std::hash<std::string>{}("cc_lightPositionAndRange");
|
||||
const size_t BaseRenderer::cc_shadow_map_lightViewProjMatrix = std::hash<std::string>{}("cc_shadow_map_lightViewProjMatrix");
|
||||
const size_t BaseRenderer::cc_shadow_map_info = std::hash<std::string>{}("cc_shadow_map_info");
|
||||
const size_t BaseRenderer::cc_shadow_map_bias = std::hash<std::string>{}("cc_shadow_map_bias");
|
||||
const size_t BaseRenderer::cc_shadow_lightViewProjMatrix = std::hash<std::string>{}("cc_shadow_lightViewProjMatrix");
|
||||
const size_t BaseRenderer::cc_shadow_info = std::hash<std::string>{}("cc_shadow_info");
|
||||
const size_t BaseRenderer::cc_matView = std::hash<std::string>{}("cc_matView");
|
||||
const size_t BaseRenderer::cc_matViewInv = std::hash<std::string>{}("cc_matViewInv");
|
||||
const size_t BaseRenderer::cc_matWorld = std::hash<std::string>{}("cc_matWorld");
|
||||
const size_t BaseRenderer::cc_matWorldIT = std::hash<std::string>{}("cc_matWorldIT");
|
||||
const size_t BaseRenderer::cc_matProj = std::hash<std::string>{}("cc_matProj");
|
||||
const size_t BaseRenderer::cc_matViewProj = std::hash<std::string>{}("cc_matViewProj");
|
||||
const size_t BaseRenderer::cc_cameraPos = std::hash<std::string>{}("cc_cameraPos");
|
||||
const size_t BaseRenderer::cc_time = std::hash<std::string>{}("cc_time");
|
||||
|
||||
const size_t BaseRenderer::cc_shadow_map[4] = {
|
||||
std::hash<std::string>{}("cc_shadow_map_0"),
|
||||
std::hash<std::string>{}("cc_shadow_map_1"),
|
||||
std::hash<std::string>{}("cc_shadow_map_2"),
|
||||
std::hash<std::string>{}("cc_shadow_map_3"),
|
||||
};
|
||||
|
||||
BaseRenderer::BaseRenderer()
|
||||
{
|
||||
_drawItems = new RecyclePool<DrawItem>([]()mutable->DrawItem*{return new DrawItem();},100);
|
||||
_stageInfos = new RecyclePool<StageInfo>([]()mutable->StageInfo*{return new StageInfo();}, 10);
|
||||
_views = new RecyclePool<View>([]()mutable->View*{return new View();}, 8);
|
||||
|
||||
_tmpMat4 = new cocos2d::Mat4();
|
||||
}
|
||||
|
||||
BaseRenderer::~BaseRenderer()
|
||||
{
|
||||
_device->release();
|
||||
_device = nullptr;
|
||||
|
||||
delete _programLib;
|
||||
_programLib = nullptr;
|
||||
|
||||
RENDERER_SAFE_RELEASE(_defaultTexture);
|
||||
_defaultTexture = nullptr;
|
||||
|
||||
delete _drawItems;
|
||||
_drawItems = nullptr;
|
||||
|
||||
delete _stageInfos;
|
||||
_stageInfos = nullptr;
|
||||
|
||||
delete _views;
|
||||
_views = nullptr;
|
||||
|
||||
delete _tmpMat4;
|
||||
_tmpMat4 = nullptr;
|
||||
}
|
||||
|
||||
bool BaseRenderer::init(DeviceGraphics* device, std::vector<ProgramLib::Template>& programTemplates)
|
||||
{
|
||||
_device = device;
|
||||
_device->retain();
|
||||
_programLib = new (std::nothrow) ProgramLib(_device, programTemplates);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseRenderer::init(DeviceGraphics* device, std::vector<ProgramLib::Template>& programTemplates, Texture2D* defaultTexture)
|
||||
{
|
||||
_device = device;
|
||||
_device->retain();
|
||||
_defaultTexture = defaultTexture;
|
||||
RENDERER_SAFE_RETAIN(_defaultTexture);
|
||||
_programLib = new (std::nothrow) ProgramLib(_device, programTemplates);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BaseRenderer::registerStage(const std::string& name, const StageCallback& callback)
|
||||
{
|
||||
_stage2fn.emplace(std::make_pair(name, callback));
|
||||
}
|
||||
|
||||
// protected functions
|
||||
|
||||
void BaseRenderer::render(const View& view, const Scene* scene)
|
||||
{
|
||||
// setup framebuffer
|
||||
_device->setFrameBuffer(view.frameBuffer);
|
||||
|
||||
// setup viewport
|
||||
_device->setViewport(view.rect.x,
|
||||
view.rect.y,
|
||||
view.rect.w,
|
||||
view.rect.h);
|
||||
|
||||
// setup clear
|
||||
Color4F clearColor;
|
||||
if (ClearFlag::COLOR & view.clearFlags)
|
||||
clearColor = view.color;
|
||||
_device->clear(view.clearFlags, &clearColor, view.depth, view.stencil);
|
||||
|
||||
// get all draw items
|
||||
_drawItems->reset();
|
||||
for (const auto& model : scene->getModels())
|
||||
{
|
||||
int modelMask = model->getCullingMask();
|
||||
if ((modelMask & view.cullingMask) == 0)
|
||||
continue;
|
||||
|
||||
DrawItem* drawItem = _drawItems->add();
|
||||
model->extractDrawItem(*drawItem);
|
||||
}
|
||||
|
||||
// dispatch draw items to different stage
|
||||
_stageInfos->reset();
|
||||
StageItem stageItem;
|
||||
for (const auto& stage : view.stages)
|
||||
{
|
||||
StageInfo* stageInfo = _stageInfos->add();
|
||||
stageInfo->stage = stage;
|
||||
stageInfo->items.clear();
|
||||
for (size_t i = 0, len = _drawItems->getLength(); i < len; i++)
|
||||
{
|
||||
const DrawItem* item = _drawItems->getData(i);
|
||||
|
||||
stageItem.passes.clear();
|
||||
for (const Pass* p : item->effect->getPasses())
|
||||
{
|
||||
if (p->getStage() == stage)
|
||||
{
|
||||
stageItem.passes.push_back(p);
|
||||
}
|
||||
}
|
||||
if (stageItem.passes.size() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
stageItem.model = item->model;
|
||||
stageItem.ia = item->ia;
|
||||
stageItem.effect = item->effect;
|
||||
stageItem.sortKey = -1;
|
||||
|
||||
stageInfo->items.push_back(stageItem);
|
||||
}
|
||||
}
|
||||
|
||||
// render stages
|
||||
std::unordered_map<std::string, const StageCallback>::iterator foundIter;
|
||||
for (size_t i = 0, len = _stageInfos->getLength(); i < len; i++)
|
||||
{
|
||||
StageInfo* stageInfo = _stageInfos->getData(i);
|
||||
foundIter = _stage2fn.find(stageInfo->stage);
|
||||
if (_stage2fn.end() != foundIter)
|
||||
{
|
||||
auto& fn = foundIter->second;
|
||||
fn(view, stageInfo->items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseRenderer::setProperty (const Effect::Property* prop)
|
||||
{
|
||||
Technique::Parameter::Type propType = prop->getType();
|
||||
auto& propName = prop->getName();
|
||||
auto propHashName = prop->getHashName();
|
||||
if (Effect::Property::Type::UNKNOWN == propType)
|
||||
{
|
||||
RENDERER_LOGW("Failed to set technique property, type unknown");
|
||||
return;
|
||||
}
|
||||
|
||||
if (nullptr == prop->getValue())
|
||||
{
|
||||
Effect::Property tmp(propName, propType);
|
||||
prop = &tmp;
|
||||
if (Effect::Property::Type::TEXTURE_2D == propType)
|
||||
{
|
||||
tmp.setTexture(_defaultTexture);
|
||||
}
|
||||
}
|
||||
|
||||
if (nullptr == prop->getValue())
|
||||
{
|
||||
RENDERER_LOGW("Failed to set technique property %s, value not found", propName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (Effect::Property::Type::TEXTURE_2D == propType ||
|
||||
Effect::Property::Type::TEXTURE_CUBE == propType)
|
||||
{
|
||||
if (1 == prop->getCount())
|
||||
{
|
||||
_device->setTexture(propHashName,
|
||||
(renderer::Texture *)(prop->getValue()),
|
||||
allocTextureUnit());
|
||||
}
|
||||
else if (0 < prop->getCount())
|
||||
{
|
||||
std::vector<int> slots;
|
||||
slots.reserve(10);
|
||||
for (int i = 0; i < prop->getCount(); ++i)
|
||||
{
|
||||
slots.push_back(allocTextureUnit());
|
||||
}
|
||||
|
||||
_device->setTextureArray(propHashName,
|
||||
prop->getTextureArray(),
|
||||
slots);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t bytes = prop->getBytes();
|
||||
if (Effect::Property::Type::INT == propType ||
|
||||
Effect::Property::Type::INT2 == propType ||
|
||||
Effect::Property::Type::INT4 == propType)
|
||||
{
|
||||
_device->setUniformiv(propHashName, bytes / sizeof(int), (const int*)prop->getValue(), prop->getCount());
|
||||
}
|
||||
else
|
||||
{
|
||||
_device->setUniformfv(propHashName, bytes / sizeof(float), (const float*)prop->getValue(), prop->getCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<const OrderedValueMap*> BaseRenderer::__tmp_defines__;
|
||||
void BaseRenderer::draw(const StageItem& item)
|
||||
{
|
||||
const Mat4& worldMatrix = item.model->getWorldMatrix();
|
||||
_device->setUniformMat4(cc_matWorld, worldMatrix);
|
||||
|
||||
_tmpMat4->set(worldMatrix);
|
||||
_tmpMat4->inverse();
|
||||
_tmpMat4->transpose();
|
||||
_device->setUniformMat4(cc_matWorldIT, *_tmpMat4);
|
||||
|
||||
auto ia = item.ia;
|
||||
// for each pass
|
||||
for (const auto& pass : item.passes)
|
||||
{
|
||||
// set vertex buffer
|
||||
_device->setVertexBuffer(0, ia->getVertexBuffer());
|
||||
|
||||
// set index buffer
|
||||
if (ia->_indexBuffer)
|
||||
_device->setIndexBuffer(ia->_indexBuffer);
|
||||
|
||||
// set primitive type
|
||||
_device->setPrimitiveType(ia->_primitiveType);
|
||||
|
||||
// get program
|
||||
__tmp_defines__.clear();
|
||||
size_t definesHash = _definesHash;
|
||||
pass->extractDefines(definesHash, __tmp_defines__);
|
||||
__tmp_defines__.push_back(&_defines);
|
||||
_program = _programLib->switchProgram(pass->getHashName(), definesHash, __tmp_defines__);
|
||||
_device->setProgram(_program);
|
||||
|
||||
for (auto& uniform : _program->getUniforms())
|
||||
{
|
||||
auto prop = pass->getProperty(uniform.hashName);
|
||||
if (prop) {
|
||||
setProperty(prop);
|
||||
}
|
||||
}
|
||||
|
||||
// cull mode
|
||||
_device->setCullMode(pass->getCullMode());
|
||||
|
||||
// blend
|
||||
if (pass->isBlend())
|
||||
{
|
||||
_device->enableBlend();
|
||||
_device->setBlendFuncSeparate(pass->getBlendSrc(),
|
||||
pass->getBlendDst(),
|
||||
pass->getBlendSrcAlpha(),
|
||||
pass->getBlendDstAlpha());
|
||||
_device->setBlendEquationSeparate(pass->getBlendEq(), pass->getBlendAlphaEq());
|
||||
_device->setBlendColor(pass->getBlendColor());
|
||||
}
|
||||
|
||||
// depth test & write
|
||||
if (pass->isDepthTest())
|
||||
{
|
||||
_device->enableDepthTest();
|
||||
_device->setDepthFunc(pass->getDepthFunc());
|
||||
}
|
||||
if (pass->isDepthWrite())
|
||||
_device->enableDepthWrite();
|
||||
|
||||
// setencil
|
||||
if (pass->isStencilTest())
|
||||
{
|
||||
_device->enableStencilTest();
|
||||
|
||||
// front
|
||||
_device->setStencilFuncFront(pass->getStencilFuncFront(),
|
||||
pass->getStencilRefFront(),
|
||||
pass->getStencilMaskFront());
|
||||
_device->setStencilOpFront(pass->getStencilFailOpFront(),
|
||||
pass->getStencilZFailOpFront(),
|
||||
pass->getStencilZPassOpFront(),
|
||||
pass->getStencilWriteMaskFront());
|
||||
|
||||
// back
|
||||
_device->setStencilFuncBack(pass->getStencilFuncBack(),
|
||||
pass->getStencilRefBack(),
|
||||
pass->getStencilMaskBack());
|
||||
_device->setStencilOpBack(pass->getStencilFailOpBack(),
|
||||
pass->getStencilZFailOpBack(),
|
||||
pass->getStencilZPassOpBack(),
|
||||
pass->getStencilWriteMaskBack());
|
||||
}
|
||||
|
||||
// draw pass
|
||||
_device->draw(ia->_start, ia->getPrimitiveCount());
|
||||
|
||||
resetTextureUint();
|
||||
}
|
||||
}
|
||||
|
||||
// private functions
|
||||
|
||||
void BaseRenderer::resetTextureUint()
|
||||
{
|
||||
_usedTextureUnits = 0;
|
||||
}
|
||||
|
||||
int BaseRenderer::allocTextureUnit()
|
||||
{
|
||||
int maxTexureUnits = _device->getCapacity().maxTextureUnits;
|
||||
if (_usedTextureUnits >= maxTexureUnits)
|
||||
RENDERER_LOGW("Trying to use %d texture uints while this GPU only supports %d", _usedTextureUnits, maxTexureUnits);
|
||||
|
||||
return _usedTextureUnits++;
|
||||
}
|
||||
|
||||
void BaseRenderer::reset()
|
||||
{
|
||||
_views->reset();
|
||||
_stageInfos->reset();
|
||||
}
|
||||
|
||||
View* BaseRenderer::requestView()
|
||||
{
|
||||
return _views->add();
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
161
cocos2d-x/cocos/renderer/renderer/BaseRenderer.h
Normal file
161
cocos2d-x/cocos/renderer/renderer/BaseRenderer.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include "../Macro.h"
|
||||
#include "ProgramLib.h"
|
||||
#include "Model.h"
|
||||
#include "Effect.h"
|
||||
#include "../memop/RecyclePool.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class DeviceGraphics;
|
||||
class View;
|
||||
class Scene;
|
||||
class ProgramLib;
|
||||
class Model;
|
||||
class InputAssembler;
|
||||
class Effect;
|
||||
class Technique;
|
||||
class Texture2D;
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Base renderer implements the basic render process.
|
||||
*/
|
||||
class BaseRenderer : public Ref
|
||||
{
|
||||
public:
|
||||
struct StageItem
|
||||
{
|
||||
Model* model = nullptr;
|
||||
InputAssembler *ia = nullptr;
|
||||
EffectVariant* effect = nullptr;
|
||||
std::vector<const Pass*> passes;
|
||||
int sortKey = -1;
|
||||
};
|
||||
typedef std::function<void(const View&, std::vector<StageItem>&)> StageCallback;
|
||||
/**
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
BaseRenderer();
|
||||
|
||||
/**
|
||||
* @brief Initializes the base renderer.
|
||||
* @param[in] device DeviceGraphics pointer.
|
||||
* @param[in] programTemplates All linked programs.
|
||||
*/
|
||||
bool init(DeviceGraphics* device, std::vector<ProgramLib::Template>& programTemplates);
|
||||
/**
|
||||
* @brief Initializes the base renderer.
|
||||
* @param[in] device DeviceGraphics pointer.
|
||||
* @param[in] programTemplates All programs.
|
||||
* @param[in] defaultTexture Default texture pointer.
|
||||
*/
|
||||
bool init(DeviceGraphics* device, std::vector<ProgramLib::Template>& programTemplates, Texture2D* defaultTexture);
|
||||
/**
|
||||
* @brief The default destructor.
|
||||
*/
|
||||
virtual ~BaseRenderer();
|
||||
/**
|
||||
* @brief Register a new render stage.
|
||||
* @param[in] name Stage name.
|
||||
* @param[in] call Stage handle callback.
|
||||
*/
|
||||
void registerStage(const std::string& name, const StageCallback& callback);
|
||||
/**
|
||||
* @brief Gets the program library pointer.
|
||||
* @return Program library pointer.
|
||||
*/
|
||||
ProgramLib* getProgramLib() const { return _programLib; };
|
||||
|
||||
protected:
|
||||
void render(const View&, const Scene* scene);
|
||||
void draw(const StageItem& item);
|
||||
void setProperty (const Effect::Property* prop);
|
||||
|
||||
struct StageInfo
|
||||
{
|
||||
public:
|
||||
std::vector<StageItem> items;
|
||||
std::string stage = "";
|
||||
};
|
||||
|
||||
void resetTextureUint();
|
||||
int allocTextureUnit();
|
||||
void reset();
|
||||
View* requestView();
|
||||
|
||||
int _usedTextureUnits = 0;
|
||||
DeviceGraphics* _device = nullptr;
|
||||
ProgramLib* _programLib = nullptr;
|
||||
Program* _program = nullptr;
|
||||
Texture2D* _defaultTexture = nullptr;
|
||||
std::unordered_map<std::string, const StageCallback> _stage2fn;
|
||||
RecyclePool<DrawItem>* _drawItems = nullptr;
|
||||
RecyclePool<StageInfo>* _stageInfos = nullptr;
|
||||
RecyclePool<View>* _views = nullptr;
|
||||
|
||||
cocos2d::Mat4* _tmpMat4 = nullptr;
|
||||
|
||||
CC_DISALLOW_COPY_ASSIGN_AND_MOVE(BaseRenderer);
|
||||
|
||||
OrderedValueMap _defines;
|
||||
size_t _definesHash = 0;
|
||||
std::string _definesKey = "";
|
||||
|
||||
static const size_t cc_lightDirection;
|
||||
static const size_t cc_lightColor;
|
||||
static const size_t cc_lightPositionAndRange;
|
||||
static const size_t cc_shadow_map[4];
|
||||
static const size_t cc_shadow_map_lightViewProjMatrix;
|
||||
static const size_t cc_shadow_map_info;
|
||||
static const size_t cc_shadow_map_bias;
|
||||
static const size_t cc_shadow_lightViewProjMatrix;
|
||||
static const size_t cc_shadow_info;
|
||||
static const size_t cc_matView;
|
||||
static const size_t cc_matViewInv;
|
||||
static const size_t cc_matWorld;
|
||||
static const size_t cc_matWorldIT;
|
||||
static const size_t cc_matProj;
|
||||
static const size_t cc_matViewProj;
|
||||
static const size_t cc_cameraPos;
|
||||
static const size_t cc_time;
|
||||
|
||||
static std::vector<const OrderedValueMap*> __tmp_defines__;
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
RENDERER_END
|
||||
232
cocos2d-x/cocos/renderer/renderer/Camera.cpp
Normal file
232
cocos2d-x/cocos/renderer/renderer/Camera.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Camera.h"
|
||||
#include "gfx/FrameBuffer.h"
|
||||
#include "math/MathUtil.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
}
|
||||
|
||||
Camera::~Camera()
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_framebuffer);
|
||||
RENDERER_SAFE_RELEASE(_node);
|
||||
}
|
||||
|
||||
void Camera::setFrameBuffer(FrameBuffer* framebuffer)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_framebuffer);
|
||||
_framebuffer = framebuffer;
|
||||
RENDERER_SAFE_RETAIN(_framebuffer);
|
||||
}
|
||||
|
||||
void Camera::setWorldMatrix(const Mat4& worldMatrix)
|
||||
{
|
||||
Quaternion rotation;
|
||||
worldMatrix.decompose(nullptr, &rotation, &_worldPos);
|
||||
|
||||
Mat4::createTranslation(_worldPos, &_worldRTInv);
|
||||
_worldRTInv.rotate(rotation);
|
||||
_worldRTInv.inverse();
|
||||
}
|
||||
|
||||
void Camera::setColor(float r, float g, float b, float a)
|
||||
{
|
||||
_color.set(r, g, b, a);
|
||||
}
|
||||
|
||||
void Camera::setDepth(float depth)
|
||||
{
|
||||
_depth = depth;
|
||||
}
|
||||
|
||||
void Camera::setStencil(int stencil)
|
||||
{
|
||||
_stencil = stencil;
|
||||
}
|
||||
|
||||
void Camera::setClearFlags(uint8_t flags )
|
||||
{
|
||||
_clearFlags = flags;
|
||||
}
|
||||
|
||||
void Camera::setRect(float x, float y, float w, float h)
|
||||
{
|
||||
_rect.set(x, y, w, h);
|
||||
}
|
||||
|
||||
void Camera::setStages(const std::vector<std::string>& stages)
|
||||
{
|
||||
_stages = stages;
|
||||
}
|
||||
|
||||
|
||||
void Camera::setNode(NodeProxy* node)
|
||||
{
|
||||
if (_node != nullptr)
|
||||
{
|
||||
_node->release();
|
||||
}
|
||||
_node = node;
|
||||
if (_node != nullptr)
|
||||
{
|
||||
_node->retain();
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::calcMatrices(const int width, const int height)
|
||||
{
|
||||
// view matrix
|
||||
//REFINE:
|
||||
_node->getWorldRT(&_worldRTInv);
|
||||
_matView.set(_worldRTInv);
|
||||
_matView.inverse();
|
||||
|
||||
// projecton matrix
|
||||
float aspect = (float)width / height;
|
||||
if (ProjectionType::PERSPECTIVE == _projection)
|
||||
Mat4::createPerspective(_fov / 3.1415926 * 180, aspect, _near, _far, &_matProj);
|
||||
else
|
||||
{
|
||||
float x = _orthoHeight * aspect;
|
||||
float y = _orthoHeight;
|
||||
Mat4::createOrthographicOffCenter(-x, x, -y, y, _near, _far, &_matProj);
|
||||
}
|
||||
|
||||
// view projection
|
||||
Mat4::multiply(_matProj, _matView, &_matViewProj);
|
||||
_matInvViewProj.set(_matViewProj.getInversed());
|
||||
}
|
||||
|
||||
void Camera::extractView(View& out, int width, int height)
|
||||
{
|
||||
if (_framebuffer != nullptr) {
|
||||
width = _framebuffer->getWidth();
|
||||
height = _framebuffer->getHeight();
|
||||
}
|
||||
|
||||
// rect
|
||||
out.rect.set(_rect.x * width,
|
||||
_rect.y * height,
|
||||
_rect.w * width,
|
||||
_rect.h * height);
|
||||
|
||||
// clear opts
|
||||
out.color.set(_color.r, _color.g, _color.b, _color.a);
|
||||
out.depth = _depth;
|
||||
out.stencil = _stencil;
|
||||
out.clearFlags = _clearFlags;
|
||||
|
||||
calcMatrices(width, height);
|
||||
out.matView.set(_matView);
|
||||
out.matViewInv.set(_worldRTInv);
|
||||
out.matProj.set(_matProj);
|
||||
out.matViewProj.set(_matViewProj);
|
||||
out.matInvViewProj.set(_matInvViewProj);
|
||||
|
||||
// stages & framebuffer
|
||||
out.stages = _stages;
|
||||
out.frameBuffer = _framebuffer;
|
||||
|
||||
// culling mask
|
||||
out.cullingMask = _cullingMask;
|
||||
out.cullingByID = true;
|
||||
}
|
||||
|
||||
Vec3& Camera::screenToWorld(Vec3& out, const Vec3& screenPos, int width, int height)
|
||||
{
|
||||
calcMatrices(width, height);
|
||||
|
||||
float cx = _rect.x * width;
|
||||
float cy = _rect.y * height;
|
||||
float cw = _rect.w * width;
|
||||
float ch = _rect.h * height;
|
||||
|
||||
if (ProjectionType::PERSPECTIVE == _projection)
|
||||
{
|
||||
// Caculate screen pos in far clip plane.
|
||||
out.set((screenPos.x - cx) * 2.0f / cw - 1.0f,
|
||||
(screenPos.y - cy) * 2.0f / ch - 1.0f,
|
||||
1.0f);
|
||||
|
||||
// Transform to world position.
|
||||
out.transformMat4(out, _matInvViewProj);
|
||||
|
||||
_node->getWorldPosition(&_worldPos);
|
||||
_temp_v3.set(_worldPos);
|
||||
out = _temp_v3.lerp(out, MathUtil::lerp(_near / _far, 1, screenPos.z));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.set((screenPos.x - cx) * 2.0f / cw - 1.0f,
|
||||
(screenPos.y - cy) * 2.0f / ch - 1.0f,
|
||||
screenPos.z * 2.0f - 1.0f);
|
||||
|
||||
// Transform to world position.
|
||||
out.transformMat4(out, _matInvViewProj);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
Vec3& Camera::worldToScreen(Vec3& out, const Vec3& worldPos, int width, int height)
|
||||
{
|
||||
calcMatrices(width, height);
|
||||
|
||||
float cx = _rect.x * width;
|
||||
float cy = _rect.y * height;
|
||||
float cw = _rect.w * width;
|
||||
float ch = _rect.h * height;
|
||||
|
||||
out.transformMat4(worldPos, _matViewProj);
|
||||
out.x = cx + (out.x + 1) * 0.5f * cw;
|
||||
out.y = cy + (out.y + 1) * 0.5f * ch;
|
||||
out.z = out.z * 0.5 + 0.5;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
Mat4& Camera::worldMatrixToScreen(Mat4& out, const Mat4& worldMatrix, int width, int height)
|
||||
{
|
||||
calcMatrices(width, height);
|
||||
|
||||
Mat4::multiply(_matViewProj, worldMatrix, &out);
|
||||
|
||||
float halfWidth = width / 2;
|
||||
float halfHeight = height / 2;
|
||||
|
||||
_temp_mat4.set(Mat4::IDENTITY);
|
||||
_temp_mat4.translate(halfWidth, halfHeight, 0, &_temp_mat4);
|
||||
_temp_mat4.scale(halfWidth, halfHeight, 1, &_temp_mat4);
|
||||
|
||||
Mat4::multiply(_temp_mat4, out, &out);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
252
cocos2d-x/cocos/renderer/renderer/Camera.h
Normal file
252
cocos2d-x/cocos/renderer/renderer/Camera.h
Normal file
@@ -0,0 +1,252 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "base/ccTypes.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
#include "View.h"
|
||||
#include "../scene/NodeProxy.hpp"
|
||||
|
||||
#ifdef near
|
||||
#undef near
|
||||
#endif
|
||||
|
||||
#ifdef far
|
||||
#undef far
|
||||
#endif
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class FrameBuffer;
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Manage scene camera.
|
||||
*/
|
||||
class Camera : public Ref
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
Camera();
|
||||
/**
|
||||
* @brief The default destructor.
|
||||
*/
|
||||
~Camera();
|
||||
|
||||
/**
|
||||
* @brief Gets the camera type.
|
||||
*/
|
||||
ProjectionType getType() const { return _projection; }
|
||||
/**
|
||||
* @brief Sets the camera type.
|
||||
*/
|
||||
inline void setType(ProjectionType value) { _projection = value; }
|
||||
/**
|
||||
* @brief Gets the view height for orthographic camera.
|
||||
*/
|
||||
inline float getOrthoHeight() const { return _orthoHeight; }
|
||||
/**
|
||||
* @brief Sets the view height for orthographic camera.
|
||||
*/
|
||||
inline void setOrthoHeight(float value) { _orthoHeight = value; }
|
||||
/**
|
||||
* @brief Gets the field of view for the camera.
|
||||
*/
|
||||
inline float getFov() const { return _fov; }
|
||||
/**
|
||||
* @brief Sets the field of view for the camera.
|
||||
*/
|
||||
inline void setFov(float fov) { _fov = fov; }
|
||||
/**
|
||||
* @brief Gets the near clip plane.
|
||||
*/
|
||||
inline float getNear() const { return _near; }
|
||||
/**
|
||||
* @brief Sets the near clip plane.
|
||||
*/
|
||||
inline void setNear(float near) { _near = near; }
|
||||
/**
|
||||
* @brief Gets the far clip plane.
|
||||
*/
|
||||
inline float getFar() const { return _far; }
|
||||
/**
|
||||
* @brief Sets the far clip plane.
|
||||
*/
|
||||
inline void setFar(float far) { _far = far; }
|
||||
/**
|
||||
* @brief Gets the clear color.
|
||||
*/
|
||||
inline void getColor(Color4F& out) const { out = _color; }
|
||||
/**
|
||||
* @brief Sets the clear color.
|
||||
*/
|
||||
void setColor(float r, float g, float b, float a);
|
||||
/**
|
||||
* @brief Gets the depth of the camera, camera of smaller depth gets rendered earlier.
|
||||
*/
|
||||
inline float getDepth() const { return _depth; }
|
||||
/**
|
||||
* @brief Sets the depth of the camera, camera of smaller depth gets rendered earlier
|
||||
*/
|
||||
void setDepth(float depth);
|
||||
/**
|
||||
* @brief Gets the culling mask.
|
||||
*/
|
||||
inline int getCullingMask() const { return _cullingMask; }
|
||||
/**
|
||||
* @brief Sets the culling mask.
|
||||
*/
|
||||
inline void setCullingMask(int mask) { _cullingMask = mask; }
|
||||
/**
|
||||
* @brief Gets the stencil value to clear
|
||||
*/
|
||||
inline int getStencil() const { return _stencil; }
|
||||
/**
|
||||
* @brief Sets the stencil value to clear
|
||||
*/
|
||||
void setStencil(int stencil);
|
||||
/**
|
||||
* @brief Gets the clear flags including color, stencil and depth.
|
||||
*/
|
||||
inline uint8_t getClearFlags() const { return _clearFlags; }
|
||||
/**
|
||||
* @brief Sets the clear flags including color, stencil and depth.
|
||||
*/
|
||||
void setClearFlags(uint8_t flags );
|
||||
/**
|
||||
* @brief Gets rect.
|
||||
*/
|
||||
inline Rect* getRect(Rect& out) const { out = _rect; return &out; }
|
||||
/**
|
||||
* @brief Sets rect.
|
||||
*/
|
||||
void setRect(float x, float y, float w, float h);
|
||||
/**
|
||||
* @brief Gets stages.
|
||||
*/
|
||||
inline const std::vector<std::string>& getStages() const { return _stages; }
|
||||
/**
|
||||
* @brief Sets stages.
|
||||
*/
|
||||
void setStages(const std::vector<std::string>& stages);
|
||||
/**
|
||||
* @brief Gets the frame buffer as render target.
|
||||
*/
|
||||
inline FrameBuffer* getFrameBuffer() const { return _framebuffer; }
|
||||
/**
|
||||
* @brief Sets the frame buffer as render target.
|
||||
*/
|
||||
void setFrameBuffer(FrameBuffer* framebuffer);
|
||||
/**
|
||||
* @brief Sets the world matrix.
|
||||
*/
|
||||
void setWorldMatrix(const Mat4& worldMatrix);
|
||||
/**
|
||||
* @brief Extracts the camera info to view.
|
||||
*/
|
||||
void extractView(View& view, int width, int height);
|
||||
/**
|
||||
* @brief Transform a screen position to world in the current camera projection.
|
||||
*/
|
||||
Vec3& screenToWorld(Vec3& out, const Vec3& screenPos, int width, int height);
|
||||
/**
|
||||
* @brief Transform a world position to screen in the current camera projection.
|
||||
*/
|
||||
Vec3& worldToScreen(Vec3& out, const Vec3& worldPos, int width, int height);
|
||||
/**
|
||||
* @brief Transform a screen position to world space
|
||||
*/
|
||||
Mat4& worldMatrixToScreen(Mat4& out, const Mat4& worldMatrix, int width, int height);
|
||||
/**
|
||||
* @brief Sets the related node proxy which provids model matrix for camera.
|
||||
*/
|
||||
void setNode(NodeProxy* node);
|
||||
/**
|
||||
* @brief Gets the related node proxy which provids model matrix for camera.
|
||||
*/
|
||||
inline NodeProxy* getNode() const { return _node; }
|
||||
/**
|
||||
* @brief Sets the camera render priority.
|
||||
*/
|
||||
void setPriority(int priority) { _priority = priority; }
|
||||
/**
|
||||
* @brief Gets the camera render priority.
|
||||
*/
|
||||
int getPriority() const { return _priority; }
|
||||
private:
|
||||
void calcMatrices(const int width, const int height);
|
||||
private:
|
||||
NodeProxy* _node = nullptr;
|
||||
ProjectionType _projection = ProjectionType::PERSPECTIVE;
|
||||
|
||||
// clear options
|
||||
Color4F _color = {0.2f, 0.3f, 0.47f, 1.f};
|
||||
float _depth = 1.f;
|
||||
int _stencil = 1;
|
||||
int _cullingMask = 1;
|
||||
uint8_t _clearFlags = ClearFlag::COLOR | ClearFlag::DEPTH;
|
||||
|
||||
// stage & framebuffer
|
||||
std::vector<std::string> _stages;
|
||||
FrameBuffer* _framebuffer = nullptr;
|
||||
|
||||
// projection properties
|
||||
float _near = 0.01f;
|
||||
float _far = 1000.0f;
|
||||
float _fov = RENDERER_PI / 4.0f;
|
||||
Rect _rect = {0, 0, 1, 1};
|
||||
|
||||
// ortho properties
|
||||
float _orthoHeight = 10.f;
|
||||
|
||||
Mat4 _worldRTInv;
|
||||
Vec3 _worldPos;
|
||||
|
||||
Mat4 _matView;
|
||||
Mat4 _matProj;
|
||||
Mat4 _matViewProj;
|
||||
Mat4 _matInvViewProj;
|
||||
|
||||
Vec3 _temp_v3;
|
||||
Mat4 _temp_mat4;
|
||||
|
||||
int _priority = 0;
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
68
cocos2d-x/cocos/renderer/renderer/Config.cpp
Normal file
68
cocos2d-x/cocos/renderer/renderer/Config.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
unsigned int Config::_stageOffset = 0;
|
||||
std::unordered_map<std::string, unsigned int> Config::_name2stageID;
|
||||
|
||||
void Config::addStage(const std::string& name)
|
||||
{
|
||||
if (Config::_name2stageID.end() != Config::_name2stageID.find(name))
|
||||
return;
|
||||
|
||||
unsigned int stageID = 1 << Config::_stageOffset;
|
||||
Config::_name2stageID[name] = stageID;
|
||||
|
||||
++Config::_stageOffset;
|
||||
}
|
||||
|
||||
int Config::getStageID(const std::string &name)
|
||||
{
|
||||
auto foundIter = Config::_name2stageID.find(name);
|
||||
if (Config::_name2stageID.end() == foundIter)
|
||||
return -1;
|
||||
|
||||
return (int)foundIter->second;
|
||||
}
|
||||
|
||||
unsigned int Config::getStageIDs(const std::vector<std::string>& nameList)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
|
||||
std::unordered_map<std::string, unsigned int>::iterator foundIter;
|
||||
std::unordered_map<std::string, unsigned int>::iterator endIter = Config::_name2stageID.end();
|
||||
for (const auto& name : nameList)
|
||||
{
|
||||
foundIter = Config::_name2stageID.find(name);
|
||||
if (endIter != foundIter)
|
||||
ret |= foundIter->second;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
71
cocos2d-x/cocos/renderer/renderer/Config.h
Normal file
71
cocos2d-x/cocos/renderer/renderer/Config.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include "../Macro.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Stage config which use to store stageID.
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Adds stage id by name.
|
||||
* @param[in] name Stage name.
|
||||
*/
|
||||
static void addStage(const std::string& name);
|
||||
/**
|
||||
* @brief Gets stage id by name.
|
||||
* @param[in] name Stage name.
|
||||
* @return Stage id.
|
||||
*/
|
||||
static int getStageID(const std::string& name);
|
||||
/**
|
||||
* @brief Gets all stage id by a list of names and store in uint32 value by AND operation.
|
||||
* @param[in] nameList Stage name list.
|
||||
* @return A uint32 represents all stages.
|
||||
*/
|
||||
static unsigned int getStageIDs(const std::vector<std::string>& nameList);
|
||||
|
||||
private:
|
||||
static unsigned int _stageOffset;
|
||||
static std::unordered_map<std::string, unsigned int> _name2stageID;
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
74
cocos2d-x/cocos/renderer/renderer/Effect.cpp
Normal file
74
cocos2d-x/cocos/renderer/renderer/Effect.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Effect.h"
|
||||
#include "Config.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
Effect::Effect()
|
||||
{}
|
||||
|
||||
void Effect::init(const Vector<Technique*>& techniques)
|
||||
{
|
||||
_techniques = techniques;
|
||||
switchTechnique(0);
|
||||
}
|
||||
|
||||
Effect::~Effect()
|
||||
{
|
||||
// RENDERER_LOGD("Effect destruction: %p", this);
|
||||
clear();
|
||||
}
|
||||
|
||||
void Effect::clear()
|
||||
{
|
||||
_techniques.clear();
|
||||
}
|
||||
|
||||
void Effect::copy(const Effect* effect)
|
||||
{
|
||||
auto& otherTech = effect->_techniques;
|
||||
for (auto it = otherTech.begin(); it != otherTech.end(); it ++)
|
||||
{
|
||||
auto tech = new Technique();
|
||||
tech->autorelease();
|
||||
tech->copy(**it);
|
||||
_techniques.pushBack(tech);
|
||||
}
|
||||
|
||||
switchTechnique(0);
|
||||
}
|
||||
|
||||
void Effect::switchTechnique(int techniqueIndex)
|
||||
{
|
||||
if (techniqueIndex >= _techniques.size())
|
||||
{
|
||||
CCLOGINFO("Can not switch to technique with index [%d]", techniqueIndex);
|
||||
return;
|
||||
}
|
||||
_technique = _techniques.at(techniqueIndex);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
121
cocos2d-x/cocos/renderer/renderer/Effect.h
Normal file
121
cocos2d-x/cocos/renderer/renderer/Effect.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include "base/CCRef.h"
|
||||
#include "base/CCValue.h"
|
||||
#include "../Macro.h"
|
||||
#include "Technique.h"
|
||||
#include "Pass.h"
|
||||
#include "EffectBase.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fundamental class of material system, contains techniques, shader template define settings and uniform properties.\n
|
||||
* JS API: renderer.Effect
|
||||
* @code
|
||||
* let pass = new renderer.Pass('sprite');
|
||||
* pass.setDepth(false, false);
|
||||
* pass.setCullMode(gfx.CULL_NONE);
|
||||
* let mainTech = new renderer.Technique(
|
||||
* ['transparent'],
|
||||
* [
|
||||
* { name: 'texture', type: renderer.PARAM_TEXTURE_2D },
|
||||
* { name: 'color', type: renderer.PARAM_COLOR4 }
|
||||
* ],
|
||||
* [
|
||||
* pass
|
||||
* ]
|
||||
* );
|
||||
* let effect = new renderer.Effect(
|
||||
* [
|
||||
* mainTech
|
||||
* ],
|
||||
* {
|
||||
* 'color': {r: 1, g: 1, b: 1, a: 1}
|
||||
* },
|
||||
* [
|
||||
* { name: 'useTexture', value: true },
|
||||
* { name: 'useModel', value: false },
|
||||
* { name: 'alphaTest', value: false },
|
||||
* { name: 'useColor', value: true }
|
||||
* ]
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
class Effect : public EffectBase
|
||||
{
|
||||
public:
|
||||
using Property = Technique::Parameter;
|
||||
|
||||
/*
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
Effect();
|
||||
/*
|
||||
* @brief The default destructor.
|
||||
*/
|
||||
~Effect();
|
||||
|
||||
/*
|
||||
* @brief Initialize with techniques, properties and define settings.
|
||||
* @param[in] techniques All techniques in an array
|
||||
* @param[in] properties All properties in a map
|
||||
* @param[in] defineTemplates All defines and their value in a map
|
||||
*/
|
||||
void init(const Vector<Technique*>& techniques);
|
||||
/**
|
||||
* @brief Clears techniques and define list.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* @brief Deep copy from other effect.
|
||||
*/
|
||||
void copy(const Effect* effect);
|
||||
|
||||
Vector<Pass*>& getPasses() { return _technique->getPasses(); }
|
||||
const Vector<Pass*>& getPasses() const { return _technique->getPasses(); }
|
||||
|
||||
void switchTechnique(int techniqueIndex);
|
||||
private:
|
||||
Vector<Technique*> _techniques;
|
||||
Technique* _technique;
|
||||
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
234
cocos2d-x/cocos/renderer/renderer/EffectBase.cpp
Normal file
234
cocos2d-x/cocos/renderer/renderer/EffectBase.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "EffectBase.h"
|
||||
#include "Config.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
EffectBase::EffectBase()
|
||||
{}
|
||||
|
||||
EffectBase::~EffectBase()
|
||||
{
|
||||
}
|
||||
|
||||
const Value* EffectBase::getDefine(const std::string& name, int passIdx) const
|
||||
{
|
||||
auto& passes = getPasses();
|
||||
size_t start = 0, end = passes.size();
|
||||
if (passIdx != -1) {
|
||||
if (passIdx >= passes.size()) {
|
||||
RENDERER_LOGD("EffectBase::getDefine error passIdx [%d]", passIdx);
|
||||
return nullptr;
|
||||
}
|
||||
start = passIdx; end = passIdx + 1;
|
||||
}
|
||||
for (size_t i = start; i < end; i++)
|
||||
{
|
||||
const auto& pass = passes.at(i);
|
||||
auto value = pass->getDefine(name);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EffectBase::define(const std::string& name, const Value& value, int passIdx)
|
||||
{
|
||||
auto& passes = getPasses();
|
||||
size_t start = 0, end = passes.size();
|
||||
if (passIdx != -1) {
|
||||
if (passIdx >= passes.size()) {
|
||||
RENDERER_LOGD("EffectBase::define error passIdx [%d]", passIdx);
|
||||
return;
|
||||
}
|
||||
start = passIdx; end = passIdx + 1;
|
||||
}
|
||||
for (size_t i = start; i < end; i++)
|
||||
{
|
||||
const auto& pass = passes.at(i);
|
||||
pass->define(name, value);
|
||||
}
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
const EffectBase::Property* EffectBase::getProperty(const std::string& name, int passIdx) const
|
||||
{
|
||||
auto& passes = getPasses();
|
||||
size_t start = 0, end = passes.size();
|
||||
if (passIdx != -1) {
|
||||
if (passIdx >= passes.size()) {
|
||||
RENDERER_LOGD("EffectBase::getProperty error passIdx [%d]", passIdx);
|
||||
return nullptr;
|
||||
}
|
||||
start = passIdx; end = passIdx + 1;
|
||||
}
|
||||
for (size_t i = start; i < end; i++)
|
||||
{
|
||||
const auto& pass = passes.at(i);
|
||||
auto value = pass->getProperty(name);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EffectBase::setProperty(const std::string& name, const Property& property, int passIdx)
|
||||
{
|
||||
auto& passes = getPasses();
|
||||
size_t start = 0, end = passes.size();
|
||||
if (passIdx != -1) {
|
||||
if (passIdx >= passes.size()) {
|
||||
RENDERER_LOGD("EffectBase::setProperty error passIdx [%d]", passIdx);
|
||||
return;
|
||||
}
|
||||
start = passIdx; end = passIdx + 1;
|
||||
}
|
||||
for (size_t i = start; i < end; i++)
|
||||
{
|
||||
const auto& pass = passes.at(i);
|
||||
pass->setProperty(name, property);
|
||||
}
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
void EffectBase::setProperty(const std::string& name, void* value, int passIdx)
|
||||
{
|
||||
auto& passes = getPasses();
|
||||
size_t start = 0, end = passes.size();
|
||||
if (passIdx != -1) {
|
||||
if (passIdx >= passes.size()) {
|
||||
RENDERER_LOGD("EffectBase::setProperty error passIdx [%d]", passIdx);
|
||||
return;
|
||||
}
|
||||
start = passIdx; end = passIdx + 1;
|
||||
}
|
||||
for (size_t i = start; i < end; i++)
|
||||
{
|
||||
const auto& pass = passes.at(i);
|
||||
pass->setProperty(name, value);
|
||||
}
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
void EffectBase::setCullMode(CullMode cullMode, int passIdx)
|
||||
{
|
||||
auto& passes = getPasses();
|
||||
size_t start = 0, end = passes.size();
|
||||
if (passIdx != -1) {
|
||||
if (passIdx >= passes.size()) {
|
||||
RENDERER_LOGD("EffectBase::setCullMode error passIdx [%d]", passIdx);
|
||||
return;
|
||||
}
|
||||
start = passIdx; end = passIdx + 1;
|
||||
}
|
||||
for (size_t i = start; i < end; i++)
|
||||
{
|
||||
const auto& pass = passes.at(i);
|
||||
pass->setCullMode(cullMode);
|
||||
}
|
||||
}
|
||||
|
||||
void EffectBase::setBlend(bool blendTest, BlendOp blendEq, BlendFactor blendSrc, BlendFactor blendDst, BlendOp blendAlphaEq, BlendFactor blendSrcAlpha, BlendFactor blendDstAlpha, uint32_t blendColor, int passIdx)
|
||||
{
|
||||
auto& passes = getPasses();
|
||||
size_t start = 0, end = passes.size();
|
||||
if (passIdx != -1) {
|
||||
if (passIdx >= passes.size()) {
|
||||
RENDERER_LOGD("EffectBase::setBlend error passIdx [%d]", passIdx);
|
||||
return;
|
||||
}
|
||||
start = passIdx; end = passIdx + 1;
|
||||
}
|
||||
for (size_t i = start; i < end; i++)
|
||||
{
|
||||
const auto& pass = passes.at(i);
|
||||
pass->setBlend(blendTest, blendEq, blendSrc, blendDst, blendAlphaEq, blendSrcAlpha, blendDstAlpha, blendColor);
|
||||
}
|
||||
}
|
||||
|
||||
void EffectBase::setStencilTest(bool value, int passIdx)
|
||||
{
|
||||
auto& passes = getPasses();
|
||||
size_t start = 0, end = passes.size();
|
||||
if (passIdx != -1) {
|
||||
if (passIdx >= passes.size()) {
|
||||
RENDERER_LOGD("EffectBase::setStencilTest error passIdx [%d]", passIdx);
|
||||
return;
|
||||
}
|
||||
start = passIdx; end = passIdx + 1;
|
||||
}
|
||||
for (size_t i = start; i < end; i++)
|
||||
{
|
||||
const auto& pass = passes.at(i);
|
||||
pass->setStencilTest(value);
|
||||
}
|
||||
}
|
||||
|
||||
void EffectBase::setStencil(StencilFunc stencilFunc, uint32_t stencilRef, uint8_t stencilMask, StencilOp stencilFailOp, StencilOp stencilZFailOp, StencilOp stencilZPassOp, uint8_t stencilWriteMask, int passIdx)
|
||||
{
|
||||
auto& passes = getPasses();
|
||||
size_t start = 0, end = passes.size();
|
||||
if (passIdx != -1) {
|
||||
if (passIdx >= passes.size()) {
|
||||
RENDERER_LOGD("EffectBase::setStencil error passIdx [%d]", passIdx);
|
||||
return;
|
||||
}
|
||||
start = passIdx; end = passIdx + 1;
|
||||
}
|
||||
for (size_t i = start; i < end; i++)
|
||||
{
|
||||
const auto& pass = passes.at(i);
|
||||
pass->setStencilFront(stencilFunc, stencilRef, stencilMask, stencilFailOp, stencilZFailOp, stencilZPassOp, stencilWriteMask);
|
||||
pass->setStencilBack(stencilFunc, stencilRef, stencilMask, stencilFailOp, stencilZFailOp, stencilZPassOp, stencilWriteMask);
|
||||
}
|
||||
}
|
||||
|
||||
void EffectBase::setDepth(bool depthTest, bool depthWrite, DepthFunc depthFunc, int passIdx)
|
||||
{
|
||||
auto& passes = getPasses();
|
||||
size_t start = 0, end = passes.size();
|
||||
if (passIdx != -1) {
|
||||
if (passIdx >= passes.size()) {
|
||||
RENDERER_LOGD("EffectBase::setDepth error passIdx [%d]", passIdx);
|
||||
return;
|
||||
}
|
||||
start = passIdx; end = passIdx + 1;
|
||||
}
|
||||
for (size_t i = start; i < end; i++)
|
||||
{
|
||||
const auto& pass = passes.at(i);
|
||||
pass->setDepth(depthTest, depthWrite, depthFunc);
|
||||
}
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
126
cocos2d-x/cocos/renderer/renderer/EffectBase.h
Normal file
126
cocos2d-x/cocos/renderer/renderer/EffectBase.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include "base/CCRef.h"
|
||||
#include "base/CCValue.h"
|
||||
#include "../Macro.h"
|
||||
#include "Technique.h"
|
||||
#include "Pass.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class EffectBase : public Ref
|
||||
{
|
||||
public:
|
||||
using Property = Technique::Parameter;
|
||||
|
||||
/*
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
EffectBase();
|
||||
/*
|
||||
* @brief The default destructor.
|
||||
*/
|
||||
virtual ~EffectBase();
|
||||
|
||||
virtual Vector<Pass*>& getPasses() = 0;
|
||||
virtual const Vector<Pass*>& getPasses() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Gets define property value by name.
|
||||
*/
|
||||
const Value* getDefine(const std::string& name, int passIdx = -1) const;
|
||||
/**
|
||||
* @brief Sets a define's value.
|
||||
*/
|
||||
void define(const std::string& name, const Value& value, int passIdx = -1);
|
||||
/**
|
||||
* @brief Gets uniform property value by name.
|
||||
*/
|
||||
const Property* getProperty(const std::string& name, int passIdx = -1) const;
|
||||
/**
|
||||
* @brief Sets uniform property value by name.
|
||||
*/
|
||||
void setProperty(const std::string& name, const Property& property, int passIdx = -1);
|
||||
void setProperty(const std::string& name, void* value, int passIdx = -1);
|
||||
/**
|
||||
* @brief Sets cull mode.
|
||||
* @param[in] cullMode Cull front or back or both.
|
||||
*/
|
||||
void setCullMode(CullMode cullMode, int passIdx = -1);
|
||||
/**
|
||||
* @brief Sets blend mode.
|
||||
* @param[in] blendEq RGB blend equation.
|
||||
* @param[in] blendSrc Src RGB blend factor.
|
||||
* @param[in] blendDst Dst RGB blend factor.
|
||||
* @param[in] blendAlphaEq Alpha blend equation.
|
||||
* @param[in] blendSrcAlpha Src Alpha blend equation.
|
||||
* @param[in] blendDstAlpha Dst Alpha blend equation.
|
||||
* @param[in] blendColor Blend constant color value.
|
||||
*/
|
||||
void setBlend(
|
||||
bool blendTest = false,
|
||||
BlendOp blendEq = BlendOp::ADD,
|
||||
BlendFactor blendSrc = BlendFactor::ONE,
|
||||
BlendFactor blendDst = BlendFactor::ZERO,
|
||||
BlendOp blendAlphaEq = BlendOp::ADD,
|
||||
BlendFactor blendSrcAlpha = BlendFactor::ONE,
|
||||
BlendFactor blendDstAlpha = BlendFactor::ZERO,
|
||||
uint32_t blendColor = 0xffffffff,
|
||||
int passIdx = -1
|
||||
);
|
||||
/**
|
||||
* @brief Sets stencil front-facing function, reference, mask, fail operation, write mask.
|
||||
*/
|
||||
void setStencil(
|
||||
StencilFunc stencilFunc = StencilFunc::ALWAYS,
|
||||
uint32_t stencilRef = 0,
|
||||
uint8_t stencilMask = 0xff,
|
||||
StencilOp stencilFailOp = StencilOp::KEEP,
|
||||
StencilOp stencilZFailOp = StencilOp::KEEP,
|
||||
StencilOp stencilZPassOp = StencilOp::KEEP,
|
||||
uint8_t stencilWriteMask = 0xff,
|
||||
int passIdx = -1
|
||||
);
|
||||
/*
|
||||
* @brief Sets stencil test enabled or not.
|
||||
*/
|
||||
void setStencilTest(bool value, int passIdx = -1);
|
||||
|
||||
void setDepth(
|
||||
bool depthTest = false,
|
||||
bool depthWrite = false,
|
||||
DepthFunc depthFunc = DepthFunc::LESS,
|
||||
int passIdx = -1
|
||||
);
|
||||
protected:
|
||||
bool _dirty = true;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
70
cocos2d-x/cocos/renderer/renderer/EffectVariant.cpp
Normal file
70
cocos2d-x/cocos/renderer/renderer/EffectVariant.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "EffectVariant.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
EffectVariant::EffectVariant(Effect* effect)
|
||||
{
|
||||
setEffect(effect);
|
||||
}
|
||||
EffectVariant::EffectVariant()
|
||||
{
|
||||
}
|
||||
|
||||
EffectVariant::~EffectVariant()
|
||||
{
|
||||
}
|
||||
|
||||
void EffectVariant::setEffect(Effect *effect)
|
||||
{
|
||||
_effect = effect;
|
||||
_dirty = true;
|
||||
|
||||
auto& passes = effect->getPasses();
|
||||
_passes.clear();
|
||||
for (size_t i = 0, l = passes.size(); i < l; i++) {
|
||||
Pass* pass = passes.at(i);
|
||||
Pass* newPass = new Pass(pass->getProgramName(), pass);
|
||||
newPass->autorelease();
|
||||
_passes.pushBack(newPass);
|
||||
}
|
||||
}
|
||||
|
||||
void EffectVariant::copy(const EffectVariant* effect)
|
||||
{
|
||||
_effect = effect->_effect;
|
||||
_dirty = true;
|
||||
|
||||
auto& passes = effect->getPasses();
|
||||
_passes.clear();
|
||||
for (size_t i = 0, l = passes.size(); i < l; i++) {
|
||||
Pass* pass = new Pass();
|
||||
pass->autorelease();
|
||||
pass->copy(*passes.at(i));
|
||||
_passes.pushBack(pass);
|
||||
}
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
62
cocos2d-x/cocos/renderer/renderer/EffectVariant.hpp
Normal file
62
cocos2d-x/cocos/renderer/renderer/EffectVariant.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../Macro.h"
|
||||
#include "Technique.h"
|
||||
#include "base/CCValue.h"
|
||||
#include "Effect.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class EffectVariant : public EffectBase
|
||||
{
|
||||
public:
|
||||
using Property = Technique::Parameter;
|
||||
|
||||
EffectVariant(Effect* effect);
|
||||
EffectVariant();
|
||||
~EffectVariant();
|
||||
|
||||
void updateHash(double hash) { _hash = hash; };
|
||||
const double getHash() const {return _hash; };
|
||||
|
||||
const Effect* getEffect () const { return _effect; }
|
||||
void setEffect (Effect* effect);
|
||||
|
||||
Vector<Pass*>& getPasses() { return _passes; }
|
||||
const Vector<Pass*>& getPasses() const { return _passes; }
|
||||
|
||||
void copy(const EffectVariant* effect);
|
||||
private:
|
||||
double _hash = 0;
|
||||
bool _dirty = false;
|
||||
|
||||
Effect* _effect;
|
||||
Vector<Pass*> _passes;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
387
cocos2d-x/cocos/renderer/renderer/ForwardRenderer.cpp
Normal file
387
cocos2d-x/cocos/renderer/renderer/ForwardRenderer.cpp
Normal file
@@ -0,0 +1,387 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "ForwardRenderer.h"
|
||||
|
||||
#include "gfx/DeviceGraphics.h"
|
||||
#include "gfx/Texture2D.h"
|
||||
#include "gfx/VertexBuffer.h"
|
||||
#include "gfx/IndexBuffer.h"
|
||||
#include "gfx/FrameBuffer.h"
|
||||
#include "ProgramLib.h"
|
||||
#include "View.h"
|
||||
#include "Scene.h"
|
||||
#include "Effect.h"
|
||||
#include "InputAssembler.h"
|
||||
#include "Pass.h"
|
||||
#include "Camera.h"
|
||||
#include "Light.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include "CCApplication.h"
|
||||
|
||||
#include "math/MathUtil.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
#define CC_MAX_LIGHTS 4
|
||||
#define CC_MAX_SHADOW_LIGHTS 2
|
||||
|
||||
ForwardRenderer::ForwardRenderer()
|
||||
{
|
||||
_arrayPool = new RecyclePool<float>([]()mutable->float*{return new float[16];}, 8);
|
||||
|
||||
_defines["CC_NUM_LIGHTS"] = Value(0);
|
||||
_defines["CC_NUM_SHADOW_LIGHTS"] = Value(0);
|
||||
|
||||
_definesHash = 0;
|
||||
}
|
||||
|
||||
ForwardRenderer::~ForwardRenderer()
|
||||
{
|
||||
_lights.clear();
|
||||
_shadowLights.clear();
|
||||
_defines.clear();
|
||||
|
||||
delete _arrayPool;
|
||||
_arrayPool = nullptr;
|
||||
}
|
||||
|
||||
bool ForwardRenderer::init(DeviceGraphics* device, std::vector<ProgramLib::Template>& programTemplates, Texture2D* defaultTexture, int width, int height)
|
||||
{
|
||||
BaseRenderer::init(device, programTemplates, defaultTexture);
|
||||
registerStage("opaque", std::bind(&ForwardRenderer::opaqueStage, this, std::placeholders::_1, std::placeholders::_2));
|
||||
registerStage("shadowcast", std::bind(&ForwardRenderer::shadowStage, this, std::placeholders::_1, std::placeholders::_2));
|
||||
registerStage("transparent", std::bind(&ForwardRenderer::transparentStage, this, std::placeholders::_1, std::placeholders::_2));
|
||||
return true;
|
||||
}
|
||||
|
||||
void ForwardRenderer::resetData()
|
||||
{
|
||||
_arrayPool->reset();
|
||||
reset();
|
||||
}
|
||||
|
||||
void ForwardRenderer::render(Scene* scene, float deltaTime)
|
||||
{
|
||||
resetData();
|
||||
|
||||
|
||||
_time[0] += deltaTime;
|
||||
_time[1] = deltaTime;
|
||||
_time[2] ++;
|
||||
_device->setUniformfv(cc_time, 4, _time, 4);
|
||||
|
||||
updateLights(scene);
|
||||
scene->sortCameras();
|
||||
auto& cameras = scene->getCameras();
|
||||
auto &viewSize = Application::getInstance()->getViewSize();
|
||||
for (auto& camera : cameras)
|
||||
{
|
||||
View* view = requestView();
|
||||
camera->extractView(*view, viewSize.x, viewSize.y);
|
||||
}
|
||||
|
||||
for (size_t i = 0, len = _views->getLength(); i < len; ++i) {
|
||||
const View* view = _views->getData(i);
|
||||
BaseRenderer::render(*view, scene);
|
||||
}
|
||||
|
||||
scene->removeModels();
|
||||
}
|
||||
|
||||
void ForwardRenderer::renderCamera(Camera* camera, Scene* scene)
|
||||
{
|
||||
resetData();
|
||||
updateLights(scene);
|
||||
|
||||
auto &viewSize = Application::getInstance()->getViewSize();
|
||||
View* cameraView = requestView();
|
||||
camera->extractView(*cameraView, viewSize.x, viewSize.y);
|
||||
|
||||
for (size_t i = 0, len = _views->getLength(); i < len; ++i) {
|
||||
const View* view = _views->getData(i);
|
||||
BaseRenderer::render(*view, scene);
|
||||
}
|
||||
|
||||
scene->removeModels();
|
||||
}
|
||||
|
||||
void ForwardRenderer::updateLights(Scene* scene)
|
||||
{
|
||||
_lights.clear();
|
||||
_shadowLights.clear();
|
||||
|
||||
const Vector<Light*> lights = scene->getLights();
|
||||
for (const auto& light : lights)
|
||||
{
|
||||
light->update(_device);
|
||||
if (light->getShadowType() != Light::ShadowType::NONE)
|
||||
{
|
||||
if (_shadowLights.size() < CC_MAX_SHADOW_LIGHTS) {
|
||||
_shadowLights.insert(0, light);
|
||||
}
|
||||
|
||||
View* view = requestView();
|
||||
std::vector<std::string> stages;
|
||||
stages.push_back("shadowcast");
|
||||
light->extractView(*view, stages);
|
||||
|
||||
_lights.insert(0, light);
|
||||
}
|
||||
else {
|
||||
_lights.pushBack(light);
|
||||
}
|
||||
}
|
||||
|
||||
if (lights.size() > 0)
|
||||
{
|
||||
updateDefines();
|
||||
}
|
||||
|
||||
_numLights = lights.size();
|
||||
}
|
||||
|
||||
void ForwardRenderer::updateDefines()
|
||||
{
|
||||
_definesKey = "";
|
||||
for (size_t i = 0; i < _lights.size(); i++)
|
||||
{
|
||||
Light* light = _lights.at(i);
|
||||
|
||||
_defines["CC_LIGHT_" + std::to_string(i)+ "_TYPE"] = (int)light->getType();
|
||||
_defines["CC_SHADOW_" + std::to_string(i)+ "_TYPE"] = (int)light->getShadowType();
|
||||
|
||||
_definesKey += std::to_string((int)light->getType());
|
||||
_definesKey += std::to_string((int)light->getShadowType());
|
||||
}
|
||||
|
||||
_defines["CC_NUM_LIGHTS"] = std::min(CC_MAX_LIGHTS, (int)_lights.size());
|
||||
_defines["CC_NUM_SHADOW_LIGHTS"] = std::min(CC_MAX_LIGHTS, (int)_shadowLights.size());
|
||||
|
||||
_definesKey += std::to_string(_lights.size());
|
||||
_definesKey += std::to_string(_shadowLights.size());
|
||||
|
||||
_definesHash = std::hash<std::string>{}(_definesKey);
|
||||
}
|
||||
|
||||
void ForwardRenderer::submitLightsUniforms()
|
||||
{
|
||||
size_t lCount = _lights.size();
|
||||
if (lCount > 0)
|
||||
{
|
||||
size_t count = std::min(CC_MAX_LIGHTS, (int)lCount);
|
||||
float* directions = _arrayPool->add();
|
||||
float* colors = _arrayPool->add();
|
||||
float* positionAndRanges = _arrayPool->add();
|
||||
Vec3 lightVec3;
|
||||
Vec3 colorVec3;
|
||||
Vec3 posVec3;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
int index = i * 4;
|
||||
auto* light = _lights.at(i);
|
||||
lightVec3.set(light->getDirectionUniform());
|
||||
*(directions + index) = lightVec3.x;
|
||||
*(directions + index + 1) = lightVec3.y;
|
||||
*(directions + index + 2) = lightVec3.z;
|
||||
|
||||
colorVec3.set(light->getColorUniform());
|
||||
*(colors + index) = colorVec3.x;
|
||||
*(colors + index + 1) = colorVec3.y;
|
||||
*(colors + index + 2) = colorVec3.z;
|
||||
|
||||
posVec3.set(light->getPositionUniform());
|
||||
*(positionAndRanges + index) = posVec3.x;
|
||||
*(positionAndRanges + index + 1) = posVec3.y;
|
||||
*(positionAndRanges + index + 2) = posVec3.z;
|
||||
*(positionAndRanges + index + 3) = light->getRange();
|
||||
|
||||
if (light->getType() == Light::LightType::SPOT) {
|
||||
*(directions + index + 3) = light->getSpotAngleUniform();
|
||||
*(colors + index + 3) = light->getSpotExp();
|
||||
}
|
||||
else {
|
||||
*(directions + index + 3) = 0;
|
||||
*(colors + index + 3) = 0;
|
||||
}
|
||||
}
|
||||
_device->setUniformfv(cc_lightDirection, count * 4, directions, count);
|
||||
_device->setUniformfv(cc_lightColor, count * 4, colors, count);
|
||||
_device->setUniformfv(cc_lightPositionAndRange, count * 4, positionAndRanges, count);
|
||||
}
|
||||
}
|
||||
|
||||
void ForwardRenderer::submitShadowStageUniforms(const View& view)
|
||||
{
|
||||
static float* shadowInfo = new float[4];
|
||||
shadowInfo[0] = view.shadowLight->getShadowMinDepth();
|
||||
shadowInfo[1] = view.shadowLight->getShadowMaxDepth();
|
||||
shadowInfo[2] = view.shadowLight->getShadowDepthScale();
|
||||
shadowInfo[3] = view.shadowLight->getShadowDarkness();
|
||||
|
||||
_device->setUniformMat4(cc_shadow_map_lightViewProjMatrix, view.matViewProj);
|
||||
_device->setUniformfv(cc_shadow_map_info, 4, shadowInfo, 1);
|
||||
_device->setUniformf(cc_shadow_map_bias, view.shadowLight->getShadowBias());
|
||||
}
|
||||
|
||||
void ForwardRenderer::submitOtherStagesUniforms()
|
||||
{
|
||||
size_t count = _shadowLights.size();
|
||||
float* shadowLightInfo = _arrayPool->add();
|
||||
static float* shadowLightProjs = new float[4 * 16];
|
||||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
Light* light = _shadowLights.at(i);
|
||||
const Mat4& view = light->getViewProjMatrix();
|
||||
memcpy(shadowLightProjs + i * 16, view.m, sizeof(float) * 16);
|
||||
|
||||
int index = (int)i * 4;
|
||||
*(shadowLightInfo + index) = light->getShadowMinDepth();
|
||||
*(shadowLightInfo + index + 1) = light->getShadowMaxDepth();
|
||||
*(shadowLightInfo + index + 2) = light->getShadowResolution();
|
||||
*(shadowLightInfo + index + 3) = light->getShadowDarkness();
|
||||
}
|
||||
|
||||
_device->setUniformfv(cc_shadow_lightViewProjMatrix, count * 16, shadowLightProjs, count);
|
||||
_device->setUniformfv(cc_shadow_info, count * 4, shadowLightInfo, count);
|
||||
}
|
||||
|
||||
bool ForwardRenderer::compareItems(const StageItem &a, const StageItem &b)
|
||||
{
|
||||
size_t pa = a.passes.size();
|
||||
size_t pb = b.passes.size();
|
||||
|
||||
if (pa != pb) {
|
||||
return pa > pb;
|
||||
}
|
||||
|
||||
return a.sortKey > b.sortKey;
|
||||
}
|
||||
|
||||
void ForwardRenderer::sortItems(std::vector<StageItem>& items)
|
||||
{
|
||||
std::sort(items.begin(), items.end(), compareItems);
|
||||
}
|
||||
|
||||
void ForwardRenderer::drawItems(const std::vector<StageItem>& items)
|
||||
{
|
||||
size_t count = _shadowLights.size();
|
||||
if (count == 0 && _numLights == 0)
|
||||
{
|
||||
for (size_t i = 0, l = items.size(); i < l; i++)
|
||||
{
|
||||
draw(items.at(i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& item : items)
|
||||
{
|
||||
for(size_t i = 0; i < count; i++)
|
||||
{
|
||||
Light* light = _shadowLights.at(i);
|
||||
_device->setTexture(cc_shadow_map[i], light->getShadowMap(), allocTextureUnit());
|
||||
}
|
||||
draw(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ForwardRenderer::opaqueStage(const View& view, std::vector<StageItem>& items)
|
||||
{
|
||||
// update uniforms
|
||||
_device->setUniformMat4(cc_matView, view.matView);
|
||||
_device->setUniformMat4(cc_matViewInv,view.matViewInv);
|
||||
_device->setUniformMat4(cc_matProj, view.matProj);
|
||||
_device->setUniformMat4(cc_matViewProj, view.matViewProj);
|
||||
static Vec3 cameraPos3;
|
||||
static Vec4 cameraPos4;
|
||||
view.getPosition(cameraPos3);
|
||||
cameraPos4.set(cameraPos3.x, cameraPos3.y, cameraPos3.z, 0);
|
||||
_device->setUniformVec4(cc_cameraPos, cameraPos4);
|
||||
submitLightsUniforms();
|
||||
submitOtherStagesUniforms();
|
||||
drawItems(items);
|
||||
}
|
||||
|
||||
void ForwardRenderer::shadowStage(const View& view, std::vector<StageItem>& items)
|
||||
{
|
||||
// update rendering
|
||||
submitShadowStageUniforms(view);
|
||||
|
||||
for (auto& item : items)
|
||||
{
|
||||
const Value* def = item.effect->getDefine("CC_CASTING_SHADOW");
|
||||
if (def && def->asBool()) {
|
||||
draw(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ForwardRenderer::transparentStage(const View& view, const std::vector<StageItem>& items)
|
||||
{
|
||||
// update uniforms
|
||||
_device->setUniformMat4(cc_matView, view.matView);
|
||||
_device->setUniformMat4(cc_matViewInv,view.matViewInv);
|
||||
_device->setUniformMat4(cc_matProj, view.matProj);
|
||||
_device->setUniformMat4(cc_matViewProj, view.matViewProj);
|
||||
static Vec3 cameraPos3;
|
||||
static Vec4 cameraPos4;
|
||||
view.getPosition(cameraPos3);
|
||||
cameraPos4.set(cameraPos3.x, cameraPos3.y, cameraPos3.z, 0);
|
||||
_device->setUniformVec4(cc_cameraPos, cameraPos4);
|
||||
|
||||
static Vec3 camFwd;
|
||||
static Vec3 tmpVec3;
|
||||
view.getForward(camFwd);
|
||||
|
||||
submitLightsUniforms();
|
||||
submitOtherStagesUniforms();
|
||||
|
||||
NodeProxy* node;
|
||||
// calculate zdist
|
||||
for (auto& item : const_cast<std::vector<StageItem>&>(items))
|
||||
{
|
||||
// TODO: we should use mesh center instead!
|
||||
node = const_cast<NodeProxy*>(item.model->getNode());
|
||||
if (node != nullptr)
|
||||
{
|
||||
node->getWorldPosition(&tmpVec3);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpVec3.set(0, 0, 0);
|
||||
}
|
||||
|
||||
Vec3::subtract(tmpVec3, tmpVec3, &cameraPos3);
|
||||
item.sortKey = -Vec3::dot(tmpVec3, camFwd);
|
||||
}
|
||||
|
||||
sortItems(const_cast<std::vector<StageItem>&>(items));
|
||||
drawItems(items);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
92
cocos2d-x/cocos/renderer/renderer/ForwardRenderer.h
Normal file
92
cocos2d-x/cocos/renderer/renderer/ForwardRenderer.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BaseRenderer.h"
|
||||
#include "Camera.h"
|
||||
#include "../memop/RecyclePool.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief A builtin forward renderer implementation
|
||||
*/
|
||||
class ForwardRenderer final : public BaseRenderer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
ForwardRenderer();
|
||||
~ForwardRenderer();
|
||||
/**
|
||||
* @brief Initializes the forward renderer.
|
||||
* @param[in] device DeviceGraphics pointer.
|
||||
* @param[in] programTemplates All linked programs.
|
||||
* @param[in] defaultTexture Default texture pointer.
|
||||
* @param[in] width.
|
||||
* @param[in] height.
|
||||
*/
|
||||
bool init(DeviceGraphics* device, std::vector<ProgramLib::Template>& programTemplates, Texture2D* defaultTexture, int width, int height);
|
||||
/**
|
||||
* @brief Renders the given render scene.
|
||||
*/
|
||||
void render(Scene* scene, float deltaTime = 0);
|
||||
/**
|
||||
* @brief Renders the given render scene with a given camera setting.
|
||||
*/
|
||||
void renderCamera(Camera* camera, Scene* scene);
|
||||
private:
|
||||
void updateLights(Scene* scene);
|
||||
void updateDefines();
|
||||
void submitLightsUniforms();
|
||||
void submitShadowStageUniforms(const View& view);
|
||||
void submitOtherStagesUniforms();
|
||||
void sortItems(std::vector<StageItem>& items);
|
||||
void drawItems(const std::vector<StageItem>& items);
|
||||
void opaqueStage(const View& view, std::vector<StageItem>& items);
|
||||
void shadowStage(const View& view, std::vector<StageItem>& items);
|
||||
void transparentStage(const View& view, const std::vector<StageItem>& items);
|
||||
void resetData();
|
||||
static bool compareItems(const StageItem& a, const StageItem& b);
|
||||
|
||||
Vector<Light*> _lights;
|
||||
Vector<Light*> _shadowLights;
|
||||
|
||||
float _time[4] = { 0, 0, 0, 0 };
|
||||
|
||||
RecyclePool<float>* _arrayPool = nullptr;
|
||||
std::size_t _numLights = 0;
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
42
cocos2d-x/cocos/renderer/renderer/INode.h
Normal file
42
cocos2d-x/cocos/renderer/renderer/INode.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "math/Vec3.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class INode
|
||||
{
|
||||
public:
|
||||
virtual ~INode() {}
|
||||
virtual Mat4 getWorldMatrix() const = 0;
|
||||
virtual Mat4 getWorldRT() const = 0;
|
||||
virtual Vec3 getWorldPos() const = 0;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
144
cocos2d-x/cocos/renderer/renderer/InputAssembler.cpp
Normal file
144
cocos2d-x/cocos/renderer/renderer/InputAssembler.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "InputAssembler.h"
|
||||
#include "gfx/VertexBuffer.h"
|
||||
#include "gfx/IndexBuffer.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
InputAssembler::InputAssembler()
|
||||
{
|
||||
}
|
||||
|
||||
InputAssembler::InputAssembler(const InputAssembler& o)
|
||||
{
|
||||
*this = o;
|
||||
}
|
||||
|
||||
InputAssembler::InputAssembler(InputAssembler&& o)
|
||||
{
|
||||
*this = std::move(o);
|
||||
}
|
||||
|
||||
InputAssembler::~InputAssembler()
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_vertexBuffer);
|
||||
RENDERER_SAFE_RELEASE(_indexBuffer);
|
||||
}
|
||||
|
||||
void InputAssembler::clear()
|
||||
{
|
||||
CC_SAFE_RELEASE(_vertexBuffer);
|
||||
CC_SAFE_RELEASE(_indexBuffer);
|
||||
|
||||
_vertexBuffer = nullptr;
|
||||
_indexBuffer = nullptr;
|
||||
_primitiveType = PrimitiveType::TRIANGLES;
|
||||
_start = 0;
|
||||
_count = -1;
|
||||
}
|
||||
|
||||
InputAssembler& InputAssembler::operator=(const InputAssembler& o)
|
||||
{
|
||||
CC_SAFE_RELEASE(_vertexBuffer);
|
||||
CC_SAFE_RELEASE(_indexBuffer);
|
||||
|
||||
_vertexBuffer = o._vertexBuffer;
|
||||
_indexBuffer = o._indexBuffer;
|
||||
_start = o._start;
|
||||
_count = o._count;
|
||||
_primitiveType = o._primitiveType;
|
||||
|
||||
CC_SAFE_RETAIN(_vertexBuffer);
|
||||
CC_SAFE_RETAIN(_indexBuffer);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputAssembler& InputAssembler::operator=(InputAssembler&& o)
|
||||
{
|
||||
CC_SAFE_RELEASE(_vertexBuffer);
|
||||
CC_SAFE_RELEASE(_indexBuffer);
|
||||
|
||||
_vertexBuffer = o._vertexBuffer;
|
||||
_indexBuffer = o._indexBuffer;
|
||||
_start = o._start;
|
||||
_count = o._count;
|
||||
_primitiveType = o._primitiveType;
|
||||
|
||||
o._indexBuffer = nullptr;
|
||||
o._vertexBuffer = nullptr;
|
||||
o._start = 0;
|
||||
o._count = -1;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool InputAssembler::init(VertexBuffer* vb,
|
||||
IndexBuffer* ib,
|
||||
PrimitiveType pt/* = PrimitiveType::TRIANGLES*/)
|
||||
{
|
||||
setVertexBuffer(vb);
|
||||
setIndexBuffer(ib);
|
||||
_primitiveType = pt;
|
||||
return true;
|
||||
}
|
||||
|
||||
void InputAssembler::setVertexBuffer(VertexBuffer* vb)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_vertexBuffer);
|
||||
_vertexBuffer = vb;
|
||||
RENDERER_SAFE_RETAIN(_vertexBuffer);
|
||||
}
|
||||
|
||||
void InputAssembler::setIndexBuffer(IndexBuffer* ib)
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_indexBuffer);
|
||||
_indexBuffer = ib;
|
||||
RENDERER_SAFE_RETAIN(_indexBuffer);
|
||||
}
|
||||
|
||||
uint32_t InputAssembler::getPrimitiveCount() const
|
||||
{
|
||||
if (-1 != _count)
|
||||
return _count;
|
||||
|
||||
if (_indexBuffer)
|
||||
return _indexBuffer->getCount();
|
||||
|
||||
assert(_vertexBuffer);
|
||||
return _vertexBuffer->getCount();
|
||||
}
|
||||
|
||||
bool InputAssembler::isMergeable(const InputAssembler& ia) const
|
||||
{
|
||||
if (_indexBuffer != ia._indexBuffer || _vertexBuffer != ia._vertexBuffer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (_start + _count) == ia._start;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
126
cocos2d-x/cocos/renderer/renderer/InputAssembler.h
Normal file
126
cocos2d-x/cocos/renderer/renderer/InputAssembler.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Types.h"
|
||||
#include "../Macro.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class VertexBuffer;
|
||||
class IndexBuffer;
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief InputAssembler is an fundamental data structure to store vertex buffer and index buffer.
|
||||
*/
|
||||
class InputAssembler
|
||||
{
|
||||
public:
|
||||
InputAssembler();
|
||||
InputAssembler(const InputAssembler& o);
|
||||
InputAssembler(InputAssembler&& o);
|
||||
~InputAssembler();
|
||||
|
||||
InputAssembler& operator=(const InputAssembler& o);
|
||||
InputAssembler& operator=(InputAssembler&& o);
|
||||
|
||||
/**
|
||||
* @brief Initializes with vertex buffer, index buffer and primitive type.
|
||||
*/
|
||||
bool init(VertexBuffer* vb,
|
||||
IndexBuffer* ib,
|
||||
PrimitiveType pt = PrimitiveType::TRIANGLES);
|
||||
/**
|
||||
* @brief Gets the primitive count.
|
||||
*/
|
||||
uint32_t getPrimitiveCount() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the vertex buffer.
|
||||
*/
|
||||
void setVertexBuffer(VertexBuffer* vb);
|
||||
/**
|
||||
* @brief Gets the vertex buffer.
|
||||
*/
|
||||
inline VertexBuffer* getVertexBuffer() const { return _vertexBuffer; }
|
||||
/**
|
||||
* @brief Sets the index buffer.
|
||||
*/
|
||||
void setIndexBuffer(IndexBuffer* ib);
|
||||
/**
|
||||
* @brief Gets the index buffer.
|
||||
*/
|
||||
inline IndexBuffer* getIndexBuffer() const { return _indexBuffer; }
|
||||
|
||||
/**
|
||||
* @brief Sets the index offset in buffer.
|
||||
*/
|
||||
inline void setStart(int start) { _start = start; }
|
||||
/**
|
||||
* @brief Gets the index offset in buffer.
|
||||
*/
|
||||
inline int getStart() const { return _start; }
|
||||
/**
|
||||
* @brief Sets the count of indices.
|
||||
*/
|
||||
inline void setCount(int count) { _count = count; }
|
||||
/**
|
||||
* @brief Gets the count of indices.
|
||||
*/
|
||||
inline int getCount() const { return _count; }
|
||||
/**
|
||||
* @brief Gets the primitive type.
|
||||
*/
|
||||
inline PrimitiveType getPrimitiveType() const { return _primitiveType; }
|
||||
/**
|
||||
* @brief Sets the primitive type.
|
||||
*/
|
||||
inline void setPrimitiveType(PrimitiveType type) { _primitiveType = type; }
|
||||
/**
|
||||
* @brief Clears all field.
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* @brief Can be merge.
|
||||
*/
|
||||
bool isMergeable(const InputAssembler& ia) const;
|
||||
private:
|
||||
friend class BaseRenderer;
|
||||
|
||||
VertexBuffer* _vertexBuffer = nullptr;
|
||||
IndexBuffer* _indexBuffer = nullptr;
|
||||
PrimitiveType _primitiveType = PrimitiveType::TRIANGLES;
|
||||
int _start = 0;
|
||||
int _count = -1;
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
RENDERER_END
|
||||
289
cocos2d-x/cocos/renderer/renderer/Light.cpp
Normal file
289
cocos2d-x/cocos/renderer/renderer/Light.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Light.h"
|
||||
#include <new>
|
||||
#include "gfx/DeviceGraphics.h"
|
||||
#include "gfx/Texture2D.h"
|
||||
#include "gfx/RenderBuffer.h"
|
||||
#include "gfx/FrameBuffer.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
Light::Light()
|
||||
{
|
||||
_worldRT = Mat4();
|
||||
}
|
||||
|
||||
Light::~Light()
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_shadowFrameBuffer);
|
||||
RENDERER_SAFE_RELEASE(_shadowDepthBuffer);
|
||||
RENDERER_SAFE_RELEASE(_node);
|
||||
RENDERER_SAFE_RELEASE(_shadowMap);
|
||||
}
|
||||
|
||||
void Light::setColor(float r, float g, float b)
|
||||
{
|
||||
_color.set(r, g, b);
|
||||
_colorUniform.set(r * _intensity, g * _intensity, b * _intensity);
|
||||
}
|
||||
|
||||
void Light::setIntensity(float val)
|
||||
{
|
||||
_intensity = val;
|
||||
_colorUniform.set(_color.r * _intensity,
|
||||
_color.g * _intensity,
|
||||
_color.b * _intensity);
|
||||
}
|
||||
|
||||
void Light::setSpotAngle(float val)
|
||||
{
|
||||
_spotAngle = val;
|
||||
_spotUniform[0] = std::cos(_spotAngle * 0.5f);
|
||||
}
|
||||
|
||||
void Light::setSpotExp(float val)
|
||||
{
|
||||
_spotExp = val;
|
||||
_spotUniform[1] = _spotExp;
|
||||
}
|
||||
|
||||
void Light::setShadowType(ShadowType val)
|
||||
{
|
||||
if (ShadowType::NONE == _shadowType &&
|
||||
ShadowType::NONE != val)
|
||||
{
|
||||
_shadowMapDirty = true;
|
||||
}
|
||||
|
||||
_shadowType = val;
|
||||
}
|
||||
|
||||
void Light::setShadowResolution(uint32_t val)
|
||||
{
|
||||
if (_shadowResolution != val)
|
||||
{
|
||||
_shadowMapDirty = true;
|
||||
_shadowResolution = val;
|
||||
}
|
||||
}
|
||||
|
||||
float Light::getShadowMinDepth() const
|
||||
{
|
||||
if (LightType::DIRECTIONAL == _type)
|
||||
return 1.0f;
|
||||
else
|
||||
return _shadowMinDepth;
|
||||
}
|
||||
|
||||
float Light::getShadowMaxDepth() const
|
||||
{
|
||||
if (LightType::DIRECTIONAL == _type)
|
||||
return 1.0f;
|
||||
else
|
||||
return _shadowMaxDepth;
|
||||
}
|
||||
|
||||
void Light::setWorldMatrix(const Mat4& worldMatrix)
|
||||
{
|
||||
_worldMatrix = worldMatrix;
|
||||
Quaternion rotation;
|
||||
Vec3 translation;
|
||||
_worldMatrix.decompose(nullptr, &rotation, &translation);
|
||||
Mat4::createRotation(rotation, &_worldRT);
|
||||
_worldRT.translate(translation);
|
||||
}
|
||||
|
||||
void Light::setNode(NodeProxy* node)
|
||||
{
|
||||
if (_node == node)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_node != nullptr)
|
||||
{
|
||||
_node->release();
|
||||
}
|
||||
_node = node;
|
||||
if (_node != nullptr)
|
||||
{
|
||||
_node->retain();
|
||||
}
|
||||
}
|
||||
|
||||
void Light::extractView(View& out, const std::vector<std::string>& stages)
|
||||
{
|
||||
out.shadowLight = const_cast<Light*>(this);
|
||||
out.rect = { 0, 0, (float)_shadowResolution, (float)_shadowResolution };
|
||||
|
||||
// clear options
|
||||
out.color.set(1.f, 1.f, 1.f, 1.f);
|
||||
out.depth = 1;
|
||||
out.stencil = 1;
|
||||
out.clearFlags = ClearFlag::COLOR | ClearFlag::DEPTH;
|
||||
|
||||
// stage & framebuffer
|
||||
out.stages = stages;
|
||||
out.frameBuffer = _shadowFrameBuffer;
|
||||
|
||||
// view projection matrix
|
||||
switch (_type)
|
||||
{
|
||||
case LightType::SPOT:
|
||||
computeSpotLightViewProjMatrix(out.matView, out.matProj);
|
||||
break;
|
||||
case LightType::DIRECTIONAL:
|
||||
computeDirectionalLightViewProjMatrix(out.matView, out.matProj);
|
||||
break;
|
||||
case LightType::POINT:
|
||||
computePointLightViewProjMatrix(out.matView, out.matProj);
|
||||
break;
|
||||
case LightType::AMBIENT:
|
||||
break;
|
||||
default:
|
||||
RENDERER_LOGW("Shadow of this light type is not supported");
|
||||
break;
|
||||
}
|
||||
|
||||
// view-porjection
|
||||
Mat4::multiply(out.matProj, out.matView, &out.matViewProj);
|
||||
out.matInvViewProj = out.matViewProj.getInversed();
|
||||
|
||||
_viewProjMatrix.set(out.matViewProj);
|
||||
|
||||
out.cullingMask = 0xffffffff;
|
||||
}
|
||||
|
||||
void Light::update(DeviceGraphics* device)
|
||||
{
|
||||
updateLightPositionAndDirection();
|
||||
|
||||
if (ShadowType::NONE == _shadowType)
|
||||
destroyShadowMap();
|
||||
else
|
||||
{
|
||||
destroyShadowMap();
|
||||
generateShadowMap(device);
|
||||
_shadowMapDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
// private functions
|
||||
|
||||
void Light::updateLightPositionAndDirection()
|
||||
{
|
||||
_worldMatrix = _node->getWorldMatrix();
|
||||
_worldMatrix.transformVector(_forward, &_directionUniform);
|
||||
_positionUniform.set(_worldMatrix.m[12], _worldMatrix.m[13], _worldMatrix.m[14]);
|
||||
}
|
||||
|
||||
void Light::generateShadowMap(DeviceGraphics* device)
|
||||
{
|
||||
_shadowMap = new (std::nothrow) Texture2D();
|
||||
if (!_shadowMap)
|
||||
return;
|
||||
|
||||
_shadowDepthBuffer = new (std::nothrow) RenderBuffer();
|
||||
if (!_shadowDepthBuffer)
|
||||
{
|
||||
_shadowMap->release();
|
||||
_shadowMap = nullptr;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_shadowFrameBuffer = new (std::nothrow) FrameBuffer();
|
||||
if (!_shadowFrameBuffer)
|
||||
{
|
||||
_shadowMap->release();
|
||||
_shadowDepthBuffer->release();
|
||||
_shadowMap = nullptr;
|
||||
_shadowDepthBuffer = nullptr;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Texture2D::Options options;
|
||||
options.width = _shadowResolution;
|
||||
options.height = _shadowResolution;
|
||||
options.glFormat = GL_RGBA;
|
||||
options.wrapS = Texture2D::WrapMode::CLAMP;
|
||||
options.wrapT = Texture2D::WrapMode::CLAMP;
|
||||
_shadowMap->init(device, options);
|
||||
|
||||
_shadowDepthBuffer->init(device, RenderBuffer::Format::D16, _shadowResolution, _shadowResolution);
|
||||
|
||||
_shadowFrameBuffer->init(device, _shadowResolution, _shadowResolution);
|
||||
_shadowFrameBuffer->setColorBuffer(_shadowMap, 0);
|
||||
_shadowFrameBuffer->setDepthBuffer(_shadowDepthBuffer);
|
||||
}
|
||||
|
||||
void Light::destroyShadowMap()
|
||||
{
|
||||
if (_shadowMap)
|
||||
{
|
||||
_shadowMap->release();
|
||||
_shadowMap = nullptr;
|
||||
|
||||
RENDERER_SAFE_RELEASE(_shadowDepthBuffer);
|
||||
_shadowDepthBuffer = nullptr;
|
||||
|
||||
RENDERER_SAFE_RELEASE(_shadowFrameBuffer);
|
||||
_shadowFrameBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Light::computeSpotLightViewProjMatrix(Mat4& matView, Mat4& matProj) const
|
||||
{
|
||||
// view matrix
|
||||
_node->getWorldRT(&(const_cast<Light*>(this)->_worldRT));
|
||||
matView = _worldRT.getInversed();
|
||||
|
||||
// proj matrix
|
||||
Mat4::createPerspective(_spotAngle * _spotAngleScale / 3.1415926 * 180,
|
||||
1,
|
||||
_shadowMinDepth,
|
||||
_shadowMaxDepth,
|
||||
&matProj);
|
||||
}
|
||||
|
||||
void Light::computeDirectionalLightViewProjMatrix(Mat4& matView, Mat4& matProj) const
|
||||
{
|
||||
// view matrix
|
||||
_node->getWorldRT(&(const_cast<Light*>(this)->_worldRT));
|
||||
matView = _worldRT.getInversed();
|
||||
|
||||
// proj matrix
|
||||
float halfSize = _shadowFustumSize / 2;
|
||||
Mat4::createOrthographic(-halfSize, halfSize, -halfSize, halfSize, _shadowMinDepth, _shadowMaxDepth, &matProj);
|
||||
}
|
||||
|
||||
void Light::computePointLightViewProjMatrix(Mat4& matView, Mat4& matProj) const
|
||||
{
|
||||
//REFINE
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
320
cocos2d-x/cocos/renderer/renderer/Light.h
Normal file
320
cocos2d-x/cocos/renderer/renderer/Light.h
Normal file
@@ -0,0 +1,320 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "base/ccTypes.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
#include "View.h"
|
||||
#include "../scene/NodeProxy.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class FrameBuffer;
|
||||
class Texture2D;
|
||||
class RenderBuffer;
|
||||
class DeviceGraphics;
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Manage scene light.
|
||||
*/
|
||||
class Light : public Ref
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Light type.
|
||||
*/
|
||||
enum class LightType
|
||||
{
|
||||
/**
|
||||
* Directional light
|
||||
*/
|
||||
DIRECTIONAL,
|
||||
/**
|
||||
* Point light
|
||||
*/
|
||||
POINT,
|
||||
/**
|
||||
* Spot light
|
||||
*/
|
||||
SPOT,
|
||||
/**
|
||||
* Ambient light
|
||||
*/
|
||||
AMBIENT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Shadow type.
|
||||
*/
|
||||
enum class ShadowType
|
||||
{
|
||||
/**
|
||||
* No shadow
|
||||
*/
|
||||
NONE,
|
||||
/**
|
||||
* Hard shadow
|
||||
*/
|
||||
HARD,
|
||||
/**
|
||||
* Soft shadow
|
||||
*/
|
||||
SOFT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
Light();
|
||||
~Light();
|
||||
|
||||
/**
|
||||
* @brief Sets the light color.
|
||||
*/
|
||||
void setColor(float r, float g, float b);
|
||||
/**
|
||||
* @brief Gets the light color.
|
||||
*/
|
||||
inline Color3F getColor() const { return _color; }
|
||||
/**
|
||||
* @brief Sets the light intensity.
|
||||
*/
|
||||
void setIntensity(float val);
|
||||
/**
|
||||
* @brief Gets the light intensity.
|
||||
*/
|
||||
inline float getIntensity() const { return _intensity; }
|
||||
/**
|
||||
* @brief Sets the light type.
|
||||
*/
|
||||
inline void setType(LightType type) { _type = type; }
|
||||
/**
|
||||
* @brief Gets the light type.
|
||||
*/
|
||||
inline LightType getType() const { return _type; }
|
||||
/**
|
||||
* @brief Sets the spot light angle.
|
||||
*/
|
||||
void setSpotAngle(float val);
|
||||
/**
|
||||
* @brief Gets the spot light angle.
|
||||
*/
|
||||
inline float getSpotAngle() const { return _spotAngle; }
|
||||
/**
|
||||
* @brief Gets the spot light angle uniform float value.
|
||||
*/
|
||||
inline float getSpotAngleUniform() const { return _spotUniform[0]; };
|
||||
|
||||
/**
|
||||
* @brief Sets the light attenuation exponent.
|
||||
*/
|
||||
void setSpotExp(float val);
|
||||
/**
|
||||
* @brief Gets the light attenuation exponent.
|
||||
*/
|
||||
inline float getSpotExp() const { return _spotExp; }
|
||||
/**
|
||||
* @brief Sets spot or point light range.
|
||||
*/
|
||||
inline void setRange(float val) { _range = val; }
|
||||
/**
|
||||
* @brief Gets spot or point light range.
|
||||
*/
|
||||
inline float getRange() const { return _range; }
|
||||
/**
|
||||
* @brief Gets the shadow type.
|
||||
*/
|
||||
void setShadowType(ShadowType val);
|
||||
/**
|
||||
* @brief Gets the shadow type.
|
||||
*/
|
||||
inline ShadowType getShadowType() const { return _shadowType; }
|
||||
/**
|
||||
* @brief Gets the shadow map texture.
|
||||
*/
|
||||
inline Texture2D* getShadowMap() const { return _shadowMap; }
|
||||
/**
|
||||
* @brief Gets the view projection matrix.
|
||||
*/
|
||||
inline Mat4 getViewPorjMatrix() const { return _viewProjMatrix; }
|
||||
/**
|
||||
* @brief Gets the view projection matrix.
|
||||
*/
|
||||
inline const Mat4& getViewProjMatrix() const { return _viewProjMatrix; }
|
||||
/**
|
||||
* @brief Gets the direction uniform.
|
||||
*/
|
||||
inline const Vec3& getDirectionUniform() const { return _directionUniform; }
|
||||
/**
|
||||
* @brief Gets the color uniform.
|
||||
*/
|
||||
inline const Vec3& getColorUniform() const { return _colorUniform; }
|
||||
/**
|
||||
* @brief Gets the position uniform.
|
||||
*/
|
||||
inline const Vec3& getPositionUniform() const { return _positionUniform; }
|
||||
/**
|
||||
* @brief Sets the resolution of shadow
|
||||
*/
|
||||
void setShadowResolution(uint32_t val);
|
||||
/**
|
||||
* @brief Gets the resolution of shadow
|
||||
*/
|
||||
inline uint32_t getShadowResolution() const { return _shadowResolution; }
|
||||
|
||||
/**
|
||||
* @brief Sets the shadow bias setting.
|
||||
*/
|
||||
inline void setShadowBias(float val) { _shadowBias = val; }
|
||||
/**
|
||||
* @brief Gets the shadow bias setting.
|
||||
*/
|
||||
inline float getShadowBias() const { return _shadowBias; }
|
||||
/**
|
||||
* @brief Sets the shadow darkness setting.
|
||||
*/
|
||||
inline void setShadowDarkness(float val) { _shadowDarkness = val; }
|
||||
/**
|
||||
* @brief Gets the shadow darkness setting.
|
||||
*/
|
||||
inline float getShadowDarkness() const { return _shadowDarkness; }
|
||||
|
||||
/**
|
||||
* @brief Sets the min depth of shadow.
|
||||
*/
|
||||
inline void setShadowMinDepth(float val) { _shadowMinDepth = val; }
|
||||
/**
|
||||
* @brief Gets the min depth of shadow.
|
||||
*/
|
||||
float getShadowMinDepth() const;
|
||||
/**
|
||||
* @brief Sets the max depth of shadow.
|
||||
*/
|
||||
inline void setShadowMaxDepth(float val) { _shadowMaxDepth = val; }
|
||||
/**
|
||||
* @brief Gets the max depth of shadow.
|
||||
*/
|
||||
float getShadowMaxDepth() const;
|
||||
/**
|
||||
* @brief Sets the shadow scale.
|
||||
*/
|
||||
inline void setShadowDepthScale(float val) { _shadowScale = val; }
|
||||
/**
|
||||
* @brief Gets the shadow scale.
|
||||
*/
|
||||
inline float getShadowDepthScale() const { return _shadowScale; }
|
||||
/**
|
||||
* @brief Sets the frustum edge fall off.
|
||||
*/
|
||||
inline void setFrustumEdgeFalloff(uint32_t val) { _frustumEdgeFalloff = val; }
|
||||
/**
|
||||
* @brief Gets the frustum edge fall off.
|
||||
*/
|
||||
inline uint32_t getFrustumEdgeFalloff() const { return _frustumEdgeFalloff; }
|
||||
/**
|
||||
* @brief Sets the world matrix.
|
||||
*/
|
||||
void setWorldMatrix(const Mat4& worldMatrix);
|
||||
/**
|
||||
* @brief Gets the world matrix.
|
||||
*/
|
||||
inline const Mat4& getWorldMatrix() const { return _node->getWorldMatrix(); }
|
||||
/**
|
||||
* @brief Extract light informations to view.
|
||||
*/
|
||||
void extractView(View& out, const std::vector<std::string>& stages);
|
||||
/**
|
||||
* @brief Update light and generate new shadow map.
|
||||
*/
|
||||
void update(DeviceGraphics* device);
|
||||
/**
|
||||
* @brief Sets the shadow frustum size.
|
||||
*/
|
||||
inline void setShadowFrustumSize(float val) {_shadowFustumSize = val;};
|
||||
/**
|
||||
* @brief Sets the related node proxy which provids model matrix for light.
|
||||
*/
|
||||
void setNode(NodeProxy* node);
|
||||
private:
|
||||
void updateLightPositionAndDirection();
|
||||
void generateShadowMap(DeviceGraphics* device);
|
||||
void destroyShadowMap();
|
||||
void computeSpotLightViewProjMatrix(Mat4& matView, Mat4& matProj) const;
|
||||
void computeDirectionalLightViewProjMatrix(Mat4& matView, Mat4& matProj) const;
|
||||
void computePointLightViewProjMatrix(Mat4& matView, Mat4& matProj) const;
|
||||
|
||||
LightType _type = LightType::DIRECTIONAL;
|
||||
Color3F _color = {1.f, 1.f, 1.f};
|
||||
float _intensity = 1.f;
|
||||
|
||||
// used for spot and point light
|
||||
float _range = 1.f;
|
||||
// used for spot light, default to 60 degrees
|
||||
float _spotAngle = RENDERER_PI / 3;
|
||||
float _spotExp = 1.f;
|
||||
// cached for uniform
|
||||
Vec3 _directionUniform;
|
||||
Vec3 _positionUniform;
|
||||
Vec3 _colorUniform = {_color.r * _intensity, _color.g * _intensity, _color.b * _intensity};
|
||||
float _spotUniform[2] = { std::cos(_spotAngle) * 0.5f, _spotExp};
|
||||
|
||||
// shadow params
|
||||
ShadowType _shadowType = ShadowType::NONE;
|
||||
FrameBuffer* _shadowFrameBuffer = nullptr;
|
||||
Texture2D* _shadowMap = nullptr;
|
||||
bool _shadowMapDirty = false;
|
||||
RenderBuffer* _shadowDepthBuffer = nullptr;
|
||||
uint32_t _shadowResolution = 1024;
|
||||
float _shadowBias = 0.0005f;
|
||||
float _shadowDarkness = 1.f;
|
||||
float _shadowMinDepth = 1;
|
||||
float _shadowMaxDepth = 1000;
|
||||
float _shadowScale = 50; // maybe need to change it if the distance between shadowMaxDepth and shadowMinDepth is small.
|
||||
uint32_t _frustumEdgeFalloff = 0; // used by directional and spot light.
|
||||
Mat4 _viewProjMatrix;
|
||||
float _spotAngleScale = 1; // used for spot light.
|
||||
float _shadowFustumSize = 50; // used for directional light.
|
||||
|
||||
Mat4 _worldMatrix;
|
||||
Mat4 _worldRT;
|
||||
|
||||
NodeProxy* _node = nullptr;
|
||||
|
||||
Vec3 _forward = Vec3(0, 0, -1.f);
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
122
cocos2d-x/cocos/renderer/renderer/Model.cpp
Normal file
122
cocos2d-x/cocos/renderer/renderer/Model.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Model.h"
|
||||
#include "Effect.h"
|
||||
#include "InputAssembler.h"
|
||||
#include "../scene/NodeProxy.hpp"
|
||||
#include "../gfx/VertexBuffer.h"
|
||||
#include "math/MathUtil.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
// Implementation of Model pool.
|
||||
|
||||
ccCArray* ModelPool::_pool = ccCArrayNew(500);
|
||||
|
||||
Model* ModelPool::getOrCreateModel()
|
||||
{
|
||||
Model* model = nullptr;
|
||||
if (0 != _pool->num)
|
||||
{
|
||||
model = static_cast<Model*>(ModelPool::_pool->arr[ModelPool::_pool->num - 1]);
|
||||
ccCArrayRemoveValueAtIndex(ModelPool::_pool, ModelPool::_pool->num - 1);
|
||||
}
|
||||
else
|
||||
model = new Model();
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
void ModelPool::returnModel(Model *model)
|
||||
{
|
||||
if (ModelPool::_pool->num < ModelPool::_pool->max)
|
||||
{
|
||||
model->reset();
|
||||
ccCArrayAppendValue(ModelPool::_pool, model);
|
||||
}
|
||||
else
|
||||
delete model;
|
||||
}
|
||||
|
||||
// Implementation of Model
|
||||
|
||||
Model::Model()
|
||||
{
|
||||
}
|
||||
|
||||
Model::~Model()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void Model::setInputAssembler(const InputAssembler& ia)
|
||||
{
|
||||
_inputAssembler = ia;
|
||||
}
|
||||
|
||||
void Model::setEffect(EffectVariant* effect)
|
||||
{
|
||||
if (_effect != effect)
|
||||
{
|
||||
CC_SAFE_RELEASE(_effect);
|
||||
_effect = effect;
|
||||
CC_SAFE_RETAIN(_effect);
|
||||
}
|
||||
}
|
||||
|
||||
void Model::setNode(NodeProxy* node)
|
||||
{
|
||||
if (_node != node)
|
||||
{
|
||||
CC_SAFE_RELEASE(_node);
|
||||
_node = node;
|
||||
CC_SAFE_RETAIN(_node);
|
||||
}
|
||||
}
|
||||
|
||||
void Model::extractDrawItem(DrawItem& out) const
|
||||
{
|
||||
if (_dynamicIA)
|
||||
{
|
||||
out.model = const_cast<Model*>(this);
|
||||
out.ia = nullptr;
|
||||
out.effect = _effect;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
out.model = const_cast<Model*>(this);
|
||||
out.ia = const_cast<InputAssembler*>(&_inputAssembler);
|
||||
out.effect = _effect;
|
||||
}
|
||||
|
||||
void Model::reset()
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(_effect);
|
||||
CC_SAFE_RELEASE_NULL(_node);
|
||||
_inputAssembler.clear();
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
143
cocos2d-x/cocos/renderer/renderer/Model.h
Normal file
143
cocos2d-x/cocos/renderer/renderer/Model.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include "base/CCVector.h"
|
||||
#include "base/CCValue.h"
|
||||
#include "base/ccCArray.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "../Macro.h"
|
||||
#include "InputAssembler.h"
|
||||
#include "../gfx/DeviceGraphics.h"
|
||||
#include "EffectVariant.hpp"
|
||||
#include "../scene/NodeProxy.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class Effect;
|
||||
class InputAssembler;
|
||||
class Model;
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct DrawItem
|
||||
{
|
||||
Model* model = nullptr;
|
||||
InputAssembler* ia = nullptr;
|
||||
EffectVariant* effect = nullptr;
|
||||
};
|
||||
|
||||
class Model;
|
||||
|
||||
class ModelPool
|
||||
{
|
||||
public:
|
||||
static Model* getOrCreateModel();
|
||||
static void returnModel(Model*);
|
||||
|
||||
private:
|
||||
static ccCArray* _pool;;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Model contains InputAssembler, effect, culling mask and model matrix.
|
||||
*/
|
||||
class Model
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
Model();
|
||||
/**
|
||||
* @brief The default destructor.
|
||||
*/
|
||||
~Model();
|
||||
/**
|
||||
* @brief Sets model matrix.
|
||||
*/
|
||||
inline void setWorldMatix(const Mat4& matrix) { _worldMatrix = matrix; }
|
||||
/**
|
||||
* @brief Gets mode matrix.
|
||||
*/
|
||||
inline const Mat4& getWorldMatrix() const { return _worldMatrix; }
|
||||
/**
|
||||
* @brief Sets culling mask.
|
||||
*/
|
||||
inline void setCullingMask(int val) { _cullingMask = val; }
|
||||
/**
|
||||
* @brief Gets culling mask.
|
||||
*/
|
||||
inline int getCullingMask() const { return _cullingMask; }
|
||||
/**
|
||||
* @brief Adds a input assembler.
|
||||
*/
|
||||
void setInputAssembler(const InputAssembler& ia);
|
||||
/**
|
||||
* @brief Adds an effect.
|
||||
*/
|
||||
void setEffect(EffectVariant* effect);
|
||||
/**
|
||||
* @brief Set user key.
|
||||
*/
|
||||
inline void setUserKey(int key) { _userKey = key; };
|
||||
/**
|
||||
* @brief Set node.
|
||||
*/
|
||||
void setNode(NodeProxy* node);
|
||||
/**
|
||||
* @brief Get node.
|
||||
*/
|
||||
inline const NodeProxy* getNode() const { return _node; };
|
||||
/**
|
||||
* @brief Extract draw item for the given index during rendering process.
|
||||
*/
|
||||
void extractDrawItem(DrawItem& out) const;
|
||||
/**
|
||||
* @brief Resets models.
|
||||
*/
|
||||
void reset();
|
||||
private:
|
||||
friend class ModelPool;
|
||||
|
||||
NodeProxy* _node = nullptr;
|
||||
Mat4 _worldMatrix;
|
||||
EffectVariant* _effect = nullptr;
|
||||
|
||||
InputAssembler _inputAssembler;
|
||||
bool _dynamicIA = false;
|
||||
int _cullingMask = -1;
|
||||
int _userKey = -1;
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
314
cocos2d-x/cocos/renderer/renderer/Pass.cpp
Normal file
314
cocos2d-x/cocos/renderer/renderer/Pass.cpp
Normal file
@@ -0,0 +1,314 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Pass.h"
|
||||
#include "math/MathUtil.h"
|
||||
#include "Texture2D.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
uint32_t* Pass::DEFAULT_STATES = new uint32_t[PASS_VALUE_LENGTH] {
|
||||
// cull
|
||||
(uint32_t)GL_BACK, // 0 cullMode
|
||||
|
||||
// blend
|
||||
(uint32_t)false, // 1 blend
|
||||
(uint32_t)BlendOp::ADD, // 2 blendEq
|
||||
(uint32_t)BlendFactor::SRC_ALPHA, // 3 blendSrc
|
||||
(uint32_t)BlendFactor::ONE_MINUS_SRC_ALPHA, // 4 blendDst
|
||||
(uint32_t)BlendOp::ADD, // 5 blendAlphaEq
|
||||
(uint32_t)BlendFactor::SRC_ALPHA, // 6 blendSrcAlpha
|
||||
(uint32_t)BlendFactor::ONE_MINUS_SRC_ALPHA, // 7 blendDstAlpha
|
||||
(uint32_t)0xffffffff, // 8 blendColor
|
||||
|
||||
// depth
|
||||
(uint32_t)false, // 9 depthTest
|
||||
(uint32_t)false, // 10 depthWrite
|
||||
(uint32_t)DepthFunc::LESS, // 11 depthFunc
|
||||
|
||||
// stencil
|
||||
(uint32_t)2, // 12 stencilTest inherit
|
||||
// stencil front
|
||||
(uint32_t)StencilFunc::ALWAYS, // 13 stencilFuncFront
|
||||
(uint32_t)0, // 14 stencilRefFront
|
||||
(uint32_t)0xff, // 15 stencilMaskFront
|
||||
(uint32_t)StencilOp::KEEP, // 16 stencilFailOpFront
|
||||
(uint32_t)StencilOp::KEEP, // 17 stencilZFailOpFront
|
||||
(uint32_t)StencilOp::KEEP, // 18 stencilZPassOpFront
|
||||
(uint32_t)0xff, // 19 stencilWriteMaskFront
|
||||
|
||||
// stencil back
|
||||
(uint32_t)StencilFunc::ALWAYS, // 20 stencilFuncBack
|
||||
(uint32_t)0, // 21 stencilRefBack
|
||||
(uint32_t)0xff, // 22 stencilMaskBack
|
||||
(uint32_t)StencilOp::KEEP, // 23 stencilFailOpBack
|
||||
(uint32_t)StencilOp::KEEP, // 24 stencilZFailOpBack
|
||||
(uint32_t)StencilOp::KEEP, // 25 stencilZPassOpBack
|
||||
(uint32_t)0xff, // 26 stencilWriteMaskBack
|
||||
|
||||
};
|
||||
|
||||
|
||||
Pass::Pass(const std::string& programName, Pass* parent)
|
||||
: _programName(programName),
|
||||
_parent(parent)
|
||||
{
|
||||
_hashName = std::hash<std::string>{}(programName);
|
||||
reset();
|
||||
}
|
||||
|
||||
Pass::Pass(
|
||||
const std::string& programName,
|
||||
std::unordered_map<size_t, Technique::Parameter>& properties,
|
||||
ValueMap& defines
|
||||
): _programName(programName)
|
||||
{
|
||||
_hashName = std::hash<std::string>{}(programName);
|
||||
_properties = properties;
|
||||
_defines.insert(defines.begin(), defines.end());
|
||||
generateDefinesKey();
|
||||
reset();
|
||||
}
|
||||
|
||||
Pass::~Pass()
|
||||
{
|
||||
}
|
||||
|
||||
void Pass::generateDefinesKey()
|
||||
{
|
||||
std::string key = "";
|
||||
for (auto& def : _defines) {
|
||||
key += def.first + std::to_string(def.second.asUnsignedInt());
|
||||
}
|
||||
|
||||
_definesHash = 0;
|
||||
MathUtil::combineHash(_definesHash, std::hash<std::string>{}(key));
|
||||
}
|
||||
|
||||
void Pass::extractDefines(size_t& hash, std::vector<const OrderedValueMap*>& defines) const
|
||||
{
|
||||
if (_parent) {
|
||||
_parent->extractDefines(hash, defines);
|
||||
}
|
||||
|
||||
MathUtil::combineHash(hash, _definesHash);
|
||||
defines.push_back(&_defines);
|
||||
}
|
||||
|
||||
void Pass::setCullMode(CullMode cullMode)
|
||||
{
|
||||
_states[0] = (uint32_t)cullMode;
|
||||
}
|
||||
|
||||
void Pass::setBlend(bool blendTest,
|
||||
BlendOp blendEq,
|
||||
BlendFactor blendSrc,
|
||||
BlendFactor blendDst,
|
||||
BlendOp blendAlphaEq,
|
||||
BlendFactor blendSrcAlpha,
|
||||
BlendFactor blendDstAlpha,
|
||||
uint32_t blendColor)
|
||||
{
|
||||
_states[1] = (uint32_t)blendTest;
|
||||
_states[2] = (uint32_t)blendEq;
|
||||
_states[3] = (uint32_t)blendSrc;
|
||||
_states[4] = (uint32_t)blendDst;
|
||||
_states[5] = (uint32_t)blendAlphaEq;
|
||||
_states[6] = (uint32_t)blendSrcAlpha;
|
||||
_states[7] = (uint32_t)blendDstAlpha;
|
||||
_states[8] = (uint32_t)blendColor;
|
||||
}
|
||||
|
||||
void Pass::setDepth(bool depthTest, bool depthWrite, DepthFunc depthFunc)
|
||||
{
|
||||
_states[9] = (uint32_t)depthTest;
|
||||
_states[10] = (uint32_t)depthWrite;
|
||||
_states[11] = (uint32_t)depthFunc;
|
||||
}
|
||||
|
||||
void Pass::setStencilFront(StencilFunc stencilFunc,
|
||||
uint32_t stencilRef,
|
||||
uint8_t stencilMask,
|
||||
StencilOp stencilFailOp,
|
||||
StencilOp stencilZFailOp,
|
||||
StencilOp stencilZPassOp,
|
||||
uint8_t stencilWriteMask)
|
||||
{
|
||||
_states[12] = true;
|
||||
_states[13] = (uint32_t)stencilFunc;
|
||||
_states[14] = (uint32_t)stencilRef;
|
||||
_states[15] = (uint32_t)stencilMask;
|
||||
_states[16] = (uint32_t)stencilFailOp;
|
||||
_states[17] = (uint32_t)stencilZFailOp;
|
||||
_states[18] = (uint32_t)stencilZPassOp;
|
||||
_states[19] = (uint32_t)stencilWriteMask;
|
||||
}
|
||||
|
||||
void Pass::setStencilBack(StencilFunc stencilFunc,
|
||||
uint32_t stencilRef,
|
||||
uint8_t stencilMask,
|
||||
StencilOp stencilFailOp,
|
||||
StencilOp stencilZFailOp,
|
||||
StencilOp stencilZPassOp,
|
||||
uint8_t stencilWriteMask)
|
||||
{
|
||||
_states[12] = true;
|
||||
_states[20] = (uint32_t)stencilFunc;
|
||||
_states[21] = (uint32_t)stencilRef;
|
||||
_states[22] = (uint32_t)stencilMask;
|
||||
_states[23] = (uint32_t)stencilFailOp;
|
||||
_states[24] = (uint32_t)stencilZFailOp;
|
||||
_states[25] = (uint32_t)stencilZPassOp;
|
||||
_states[26] = (uint32_t)stencilWriteMask;
|
||||
}
|
||||
|
||||
uint32_t Pass::getState(uint32_t index) const {
|
||||
const Pass* parent = this;
|
||||
while (parent) {
|
||||
if (parent->_states[index] != (uint32_t)-1) {
|
||||
return parent->_states[index];
|
||||
}
|
||||
parent = parent->_parent;
|
||||
}
|
||||
|
||||
return DEFAULT_STATES[index];
|
||||
}
|
||||
|
||||
const std::string& Pass::getStage() const {
|
||||
const Pass* parent = this;
|
||||
while (parent) {
|
||||
if (parent->_stage != "") {
|
||||
return parent->_stage;
|
||||
}
|
||||
parent = parent->_parent;
|
||||
}
|
||||
|
||||
return _stage;
|
||||
}
|
||||
|
||||
void Pass::copy(const Pass& pass)
|
||||
{
|
||||
_programName = pass._programName;
|
||||
_hashName = pass._hashName;
|
||||
_parent = pass._parent;
|
||||
|
||||
_stage = pass._stage;
|
||||
|
||||
_defines = pass._defines;
|
||||
_properties = pass._properties;
|
||||
_definesHash = pass._definesHash;
|
||||
|
||||
memcpy(_states, pass._states, PASS_VALUE_LENGTH * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
const Technique::Parameter* Pass::getProperty(const std::string& name) const
|
||||
{
|
||||
return getProperty(std::hash<std::string>{}(name));
|
||||
}
|
||||
|
||||
const Technique::Parameter* Pass::getProperty(const size_t hashName) const
|
||||
{
|
||||
const auto& iter = _properties.find(hashName);
|
||||
if (_properties.end() == iter) {
|
||||
if (_parent) {
|
||||
return _parent->getProperty(hashName);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
return &iter->second;
|
||||
}
|
||||
|
||||
const Value* Pass::getDefine(const std::string& name) const
|
||||
{
|
||||
const auto& iter = _defines.find(name);
|
||||
if (_defines.end() == iter) {
|
||||
if (_parent) {
|
||||
return _parent->getDefine(name);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
return &iter->second;
|
||||
}
|
||||
|
||||
void Pass::setProperty(size_t hashName, const Technique::Parameter& property)
|
||||
{
|
||||
_properties[hashName] = property;
|
||||
}
|
||||
|
||||
void Pass::setProperty(size_t hashName, void* value)
|
||||
{
|
||||
Technique::Parameter* prop = nullptr;
|
||||
const auto& iter = _properties.find(hashName);
|
||||
if (_properties.end() == iter)
|
||||
{
|
||||
if (!_parent) return;
|
||||
auto parentProp = _parent->getProperty(hashName);
|
||||
if (!parentProp) return;
|
||||
prop = &_properties[hashName];
|
||||
*prop = *parentProp;
|
||||
}
|
||||
else
|
||||
{
|
||||
prop = &iter->second;
|
||||
}
|
||||
|
||||
prop->setValue(value);
|
||||
|
||||
if (prop->getType() == Technique::Parameter::Type::TEXTURE_2D) {
|
||||
if (prop->getTexture()) {
|
||||
bool isAlphaAtlas = prop->getTexture()->isAlphaAtlas();
|
||||
auto key = "CC_USE_ALPHA_ATLAS_" + prop->getName();
|
||||
auto def = getDefine(key);
|
||||
if (isAlphaAtlas || def) {
|
||||
define(key, Value(isAlphaAtlas));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Pass::setProperty(const std::string& name, const Technique::Parameter& property)
|
||||
{
|
||||
setProperty(std::hash<std::string>{}(name), property);
|
||||
}
|
||||
|
||||
void Pass::setProperty(const std::string& name, void* value)
|
||||
{
|
||||
setProperty(std::hash<std::string>{}(name), value);
|
||||
}
|
||||
|
||||
void Pass::define(const std::string& name, const Value& value)
|
||||
{
|
||||
if (_defines[name] == value)
|
||||
{
|
||||
return;
|
||||
};
|
||||
|
||||
_defines[name] = value;
|
||||
|
||||
generateDefinesKey();
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
192
cocos2d-x/cocos/renderer/renderer/Pass.h
Normal file
192
cocos2d-x/cocos/renderer/renderer/Pass.h
Normal file
@@ -0,0 +1,192 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <base/CCRef.h>
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
#include "Technique.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Pass describes base render pass configurations, including program, cull face, blending, depth testing and stencil testing configs.\n
|
||||
* JS API: renderer.Pass
|
||||
* @code
|
||||
* let pass = new renderer.Pass('sprite');
|
||||
* pass.setDepth(false, false);
|
||||
* pass.setCullMode(gfx.CULL_NONE);
|
||||
* pass.setBlend(
|
||||
* gfx.BLEND_FUNC_ADD,
|
||||
* gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA,
|
||||
* gfx.BLEND_FUNC_ADD,
|
||||
* gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
class Pass : public Ref
|
||||
{
|
||||
public:
|
||||
|
||||
Pass(const std::string& programName, Pass* parent = nullptr);
|
||||
Pass(const std::string& programName,
|
||||
std::unordered_map<size_t, Technique::Parameter>& properties,
|
||||
ValueMap& defines
|
||||
);
|
||||
Pass() {};
|
||||
~Pass();
|
||||
|
||||
inline void setProgramName(const std::string& programName) { _programName = programName; }
|
||||
inline const std::string& getProgramName() const { return _programName; }
|
||||
|
||||
inline size_t getHashName() const { return _hashName; }
|
||||
|
||||
void copy(const Pass& pass);
|
||||
|
||||
// cull mode
|
||||
CullMode getCullMode() const { return (CullMode)getState(0); }
|
||||
|
||||
void setCullMode(CullMode cullMode);
|
||||
|
||||
// blending
|
||||
inline bool isBlend () const { return getState(1); };
|
||||
inline BlendOp getBlendEq () const { return (BlendOp)getState(2); };
|
||||
inline BlendFactor getBlendSrc () const { return (BlendFactor)getState(3); };
|
||||
inline BlendFactor getBlendDst () const { return (BlendFactor)getState(4); };
|
||||
inline BlendOp getBlendAlphaEq () const { return (BlendOp)getState(5); };
|
||||
inline BlendFactor getBlendSrcAlpha () const { return (BlendFactor)getState(6); };
|
||||
inline BlendFactor getBlendDstAlpha () const { return (BlendFactor)getState(7); };
|
||||
inline uint32_t getBlendColor () const { return getState(8); };
|
||||
|
||||
void setBlend(bool blendTest = false,
|
||||
BlendOp blendEq = BlendOp::ADD,
|
||||
BlendFactor blendSrc = BlendFactor::ONE,
|
||||
BlendFactor blendDst = BlendFactor::ZERO,
|
||||
BlendOp blendAlphaEq = BlendOp::ADD,
|
||||
BlendFactor blendSrcAlpha = BlendFactor::ONE,
|
||||
BlendFactor blendDstAlpha = BlendFactor::ZERO,
|
||||
uint32_t blendColor = 0xffffffff);
|
||||
|
||||
// depth
|
||||
inline bool isDepthTest () const { return getState(9); };
|
||||
inline bool isDepthWrite () const { return getState(10); };
|
||||
inline DepthFunc getDepthFunc () const { return (DepthFunc)getState(11); };
|
||||
|
||||
void setDepth(bool depthTest = false,
|
||||
bool depthWrite = false,
|
||||
DepthFunc depthFunc = DepthFunc::LESS);
|
||||
|
||||
// stencil
|
||||
inline void setStencilTest(bool value) { _states[12] = value; }
|
||||
inline void disableStencilTest() { _states[12] = false; }
|
||||
inline bool isStencilTest() const { return getState(12); }
|
||||
|
||||
// stencil front
|
||||
inline StencilFunc getStencilFuncFront() const { return (StencilFunc)getState(13); }
|
||||
inline uint32_t getStencilRefFront() const { return getState(14); }
|
||||
inline uint8_t getStencilMaskFront() const { return getState(15); }
|
||||
inline StencilOp getStencilFailOpFront() const { return (StencilOp)getState(16); }
|
||||
inline StencilOp getStencilZFailOpFront() const { return (StencilOp)getState(17); }
|
||||
inline StencilOp getStencilZPassOpFront() const { return (StencilOp)getState(18); }
|
||||
inline uint8_t getStencilWriteMaskFront() const { return getState(19); }
|
||||
|
||||
void setStencilFront(StencilFunc stencilFunc = StencilFunc::ALWAYS,
|
||||
uint32_t stencilRef = 0,
|
||||
uint8_t stencilMask = 0xff,
|
||||
StencilOp stencilFailOp = StencilOp::KEEP,
|
||||
StencilOp stencilZFailOp = StencilOp::KEEP,
|
||||
StencilOp stencilZPassOp = StencilOp::KEEP,
|
||||
uint8_t stencilWriteMask = 0xff);
|
||||
|
||||
// stencil back
|
||||
inline StencilFunc getStencilFuncBack() const { return (StencilFunc)getState(20); }
|
||||
inline uint32_t getStencilRefBack() const { return getState(21); }
|
||||
inline uint8_t getStencilMaskBack() const { return getState(22); }
|
||||
inline StencilOp getStencilFailOpBack() const { return (StencilOp)getState(23); }
|
||||
inline StencilOp getStencilZFailOpBack() const { return (StencilOp)getState(24); }
|
||||
inline StencilOp getStencilZPassOpBack() const { return (StencilOp)getState(25); }
|
||||
inline uint8_t getStencilWriteMaskBack() const { return getState(26); }
|
||||
|
||||
void setStencilBack(StencilFunc stencilFunc = StencilFunc::ALWAYS,
|
||||
uint32_t stencilRef = 0,
|
||||
uint8_t stencilMask = 0xff,
|
||||
StencilOp stencilFailOp = StencilOp::KEEP,
|
||||
StencilOp stencilZFailOp = StencilOp::KEEP,
|
||||
StencilOp stencilZPassOp = StencilOp::KEEP,
|
||||
uint8_t stencilWriteMask = 0xff);
|
||||
|
||||
uint32_t getState(uint32_t index) const;
|
||||
|
||||
// stage
|
||||
void setStage (const std::string& stage) { _stage = stage; }
|
||||
const std::string& getStage() const;
|
||||
|
||||
inline void reset () { memset(_states, -1, PASS_VALUE_LENGTH * sizeof(uint32_t)); }
|
||||
|
||||
inline void setParent(Pass* parent) { _parent = parent; }
|
||||
inline const Pass* getParent() { return _parent; }
|
||||
|
||||
void extractDefines (size_t& hash, std::vector<const OrderedValueMap*>& defines) const;
|
||||
|
||||
void generateDefinesKey ();
|
||||
inline size_t getDefinesHash() const {return _definesHash;}
|
||||
|
||||
const Technique::Parameter* getProperty(const std::string& name) const;
|
||||
void setProperty(const std::string& name, const Technique::Parameter& property);
|
||||
void setProperty(const std::string& name, void* value);
|
||||
|
||||
const Technique::Parameter* getProperty(size_t hashName) const;
|
||||
void setProperty(size_t hashName, const Technique::Parameter& property);
|
||||
void setProperty(size_t hashName, void* value);
|
||||
|
||||
const Value* getDefine(const std::string& name) const;
|
||||
void define(const std::string& name, const Value& value);
|
||||
private:
|
||||
std::string _programName = "";
|
||||
size_t _hashName = 0;
|
||||
|
||||
Pass* _parent = nullptr;
|
||||
|
||||
std::unordered_map<size_t, Technique::Parameter> _properties;
|
||||
OrderedValueMap _defines;
|
||||
size_t _definesHash = 0;
|
||||
|
||||
static const int PASS_VALUE_LENGTH = 27;
|
||||
|
||||
uint32_t _states[PASS_VALUE_LENGTH];
|
||||
static uint32_t* DEFAULT_STATES;
|
||||
|
||||
std::string _stage = "";
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
RENDERER_END
|
||||
311
cocos2d-x/cocos/renderer/renderer/ProgramLib.cpp
Normal file
311
cocos2d-x/cocos/renderer/renderer/ProgramLib.cpp
Normal file
@@ -0,0 +1,311 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
#include "ProgramLib.h"
|
||||
#include "../gfx/Program.h"
|
||||
#include "gfx/DeviceGraphics.h"
|
||||
|
||||
#include "math/MathUtil.h"
|
||||
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
uint32_t _shdID = 0;
|
||||
|
||||
std::string generateDefines(const std::vector<const cocos2d::OrderedValueMap*>& definesList)
|
||||
{
|
||||
std::string ret;
|
||||
std::string v;
|
||||
cocos2d::ValueMap cache;
|
||||
for (int i = (int)definesList.size() - 1; i >= 0; i--)
|
||||
{
|
||||
const cocos2d::OrderedValueMap* defMap = definesList[i];
|
||||
for (const auto& def : *defMap)
|
||||
{
|
||||
if (cache.find(def.first) != cache.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (def.second.getType() == cocos2d::Value::Type::BOOLEAN)
|
||||
{
|
||||
v = def.second.asBool() ? "1" : "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
v = std::to_string(def.second.asUnsignedInt());
|
||||
}
|
||||
|
||||
ret += "#define " + def.first + " " + v + "\n";
|
||||
|
||||
cache.emplace(def.first, def.second);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string replaceMacroNums(const std::string str, const std::vector<const cocos2d::OrderedValueMap*>& definesList)
|
||||
{
|
||||
cocos2d::OrderedValueMap cache;
|
||||
std::string tmp = str;
|
||||
for (int i = (int)definesList.size() - 1; i >= 0; i--)
|
||||
{
|
||||
const cocos2d::OrderedValueMap* defMap = definesList[i];
|
||||
|
||||
for (const auto& def : *defMap)
|
||||
{
|
||||
if (cache.find(def.first) != cache.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (def.second.getType() == cocos2d::Value::Type::INTEGER || def.second.getType() == cocos2d::Value::Type::UNSIGNED)
|
||||
{
|
||||
cache.emplace(def.first, def.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& def : cache)
|
||||
{
|
||||
std::regex pattern(def.first);
|
||||
tmp = std::regex_replace(tmp, pattern, def.second.asString());
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
using RegexReplaceCallback = std::function<std::string(const std::match_results<std::string::const_iterator>&)>;
|
||||
|
||||
static std::string regexReplaceString(const std::string& text, const std::string& pattern, const RegexReplaceCallback& replaceCallback)
|
||||
{
|
||||
std::string ret = text;
|
||||
std::regex re(pattern);
|
||||
|
||||
std::string::const_iterator text_iter = text.cbegin();
|
||||
std::match_results<std::string::const_iterator> results;
|
||||
|
||||
size_t start = 0;
|
||||
size_t offset = 0;
|
||||
while (std::regex_search(text_iter, text.end(), results, re))
|
||||
{
|
||||
offset = start + results.position();
|
||||
std::string replacement = replaceCallback(results);
|
||||
ret = ret.replace(offset, results.length(), replacement);
|
||||
start = offset + replacement.length();
|
||||
|
||||
text_iter = results[0].second;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string unrollLoops(const std::string& text)
|
||||
{
|
||||
auto func = [](const std::match_results<std::string::const_iterator>& results) -> std::string {
|
||||
assert(results.size() == 5);
|
||||
std::string snippet = results[4].str();
|
||||
std::string replacePatternStr = "\\{" + results[1].str() + "\\}";
|
||||
std::regex replacePattern(replacePatternStr);
|
||||
|
||||
int32_t parsedBegin = atoi(results[2].str().c_str());
|
||||
int32_t parsedEnd = atoi(results[3].str().c_str());
|
||||
if (parsedBegin < 0 || parsedEnd < 0)
|
||||
{
|
||||
RENDERER_LOGE("Unroll For Loops Error: begin and end of range must be an int num.");
|
||||
}
|
||||
|
||||
std::string unroll;
|
||||
char tmp[256] = {0};
|
||||
for (int32_t i = parsedBegin; i < parsedEnd; ++i)
|
||||
{
|
||||
snprintf(tmp, 256, "%d", i);
|
||||
std::string replaceFormat(tmp);
|
||||
unroll += std::regex_replace(snippet, replacePattern, replaceFormat);
|
||||
}
|
||||
return unroll;
|
||||
};
|
||||
|
||||
return regexReplaceString(text, "#pragma for (\\w+) in range\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)([\\s\\S]+?)#pragma endFor", func);
|
||||
}
|
||||
}
|
||||
|
||||
std::string test_unrollLoops(const std::string& text)
|
||||
{
|
||||
return unrollLoops(text);
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
ProgramLib::ProgramLib(DeviceGraphics* device, std::vector<Template>& templates)
|
||||
: _device(device)
|
||||
{
|
||||
RENDERER_SAFE_RETAIN(_device);
|
||||
|
||||
for (auto& templ : templates)
|
||||
define(templ.name, templ.vert, templ.frag, templ.defines);
|
||||
}
|
||||
|
||||
ProgramLib::~ProgramLib()
|
||||
{
|
||||
for (auto it = _cache.begin(); it != _cache.end(); it++)
|
||||
{
|
||||
if (it->second)
|
||||
{
|
||||
it->second->release();
|
||||
}
|
||||
}
|
||||
_cache.clear();
|
||||
|
||||
RENDERER_SAFE_RELEASE(_device);
|
||||
_device = nullptr;
|
||||
}
|
||||
|
||||
void ProgramLib::define(const std::string& name, const std::string& vert, const std::string& frag, ValueVector& defines)
|
||||
{
|
||||
size_t hash = std::hash<std::string>{}(name);
|
||||
auto iter = _templates.find(hash);
|
||||
if (iter != _templates.end())
|
||||
{
|
||||
RENDERER_LOGW("Failed to define shader %s: already exists.", name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t id = ++_shdID;
|
||||
|
||||
// calculate option mask offset
|
||||
uint32_t offset = 0;
|
||||
for (auto& def : defines)
|
||||
{
|
||||
ValueMap& oneDefMap = def.asValueMap();
|
||||
uint32_t cnt = 1;
|
||||
|
||||
//IDEA: currently we don't use min, max.
|
||||
// if (def.min != -1 && def.max != -1) {
|
||||
// cnt = (uint32_t)std::ceil((def.max - def.min) * 0.5);
|
||||
//
|
||||
// def._map = std::bind(&Option::_map_1, def, std::placeholders::_1);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// def._map = std::bind(&Option::_map_2, def, std::placeholders::_1);
|
||||
// }
|
||||
|
||||
offset += cnt;
|
||||
|
||||
oneDefMap["_offset"] = offset;
|
||||
}
|
||||
|
||||
std::string newVert = vert;
|
||||
std::string newFrag = frag;
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
||||
static const std::regex precision("precision\\s+(lowp|mediump|highp).*?;");
|
||||
static const std::regex accuracy("(lowp|mediump|highp)\\s");
|
||||
newVert = std::regex_replace(newVert, precision, "");
|
||||
newVert = std::regex_replace(newVert, accuracy, "");
|
||||
newFrag = std::regex_replace(newFrag, precision, "");
|
||||
newFrag = std::regex_replace(newFrag, accuracy, "");
|
||||
#endif
|
||||
|
||||
// store it
|
||||
auto& templ = _templates[hash];
|
||||
templ.id = id;
|
||||
templ.name = name;
|
||||
templ.vert = newVert;
|
||||
templ.frag = newFrag;
|
||||
templ.defines = defines;
|
||||
}
|
||||
|
||||
Program* ProgramLib::switchProgram(const size_t programNameHash, const size_t definesKeyHash, const std::vector<const OrderedValueMap*>& definesList)
|
||||
{
|
||||
size_t programHash = 0;
|
||||
MathUtil::combineHash(programHash, programNameHash);
|
||||
MathUtil::combineHash(programHash, definesKeyHash);
|
||||
|
||||
if (_current && _current->getHash() == programHash) {
|
||||
return _current;
|
||||
}
|
||||
|
||||
auto iter = _cache.find(programHash);
|
||||
if (iter != _cache.end()) {
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
Program* program = nullptr;
|
||||
// get template
|
||||
auto templIter = _templates.find(programNameHash);
|
||||
if (templIter != _templates.end())
|
||||
{
|
||||
const auto& tmpl = templIter->second;
|
||||
std::string customDef = generateDefines(definesList) + "\n";
|
||||
std::string vert = replaceMacroNums(tmpl.vert, definesList);
|
||||
vert = customDef + unrollLoops(vert);
|
||||
std::string frag = replaceMacroNums(tmpl.frag, definesList);
|
||||
frag = customDef + unrollLoops(frag);
|
||||
|
||||
program = new Program();
|
||||
program->init(_device, vert.c_str(), frag.c_str());
|
||||
program->link();
|
||||
_cache.emplace(programHash, program);
|
||||
|
||||
program->setHash(programHash);
|
||||
}
|
||||
|
||||
_current = program;
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
const Value* ProgramLib::getValueFromDefineList(const std::string& name, const std::vector<const ValueMap*>& definesList)
|
||||
{
|
||||
for (int i = (int)definesList.size() - 1; i >= 0; i--)
|
||||
{
|
||||
const ValueMap* defines = definesList[i];
|
||||
auto iter = defines->find(name);
|
||||
if (iter != defines->end())
|
||||
{
|
||||
return &iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t ProgramLib::getValueKey(const Value *v)
|
||||
{
|
||||
if (v->getType() == Value::Type::BOOLEAN)
|
||||
{
|
||||
return v->asBool() ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return v->asUnsignedInt();
|
||||
}
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
98
cocos2d-x/cocos/renderer/renderer/ProgramLib.h
Normal file
98
cocos2d-x/cocos/renderer/renderer/ProgramLib.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "base/CCValue.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class DeviceGraphics;
|
||||
class Program;
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This class manages shader template and linked programs, material can customize shader by setting different defines.
|
||||
*/
|
||||
class ProgramLib final
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Program template
|
||||
*/
|
||||
struct Template
|
||||
{
|
||||
uint32_t id = 0;
|
||||
std::string name;
|
||||
std::string vert;
|
||||
std::string frag;
|
||||
ValueVector defines;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor with device and all initial templates.
|
||||
*/
|
||||
ProgramLib(DeviceGraphics* device, std::vector<Template>& templates);
|
||||
/**
|
||||
* @brief The default destructor.
|
||||
*/
|
||||
~ProgramLib();
|
||||
|
||||
/**
|
||||
* @brief Define a new program with name, vertex shader name, fragement shader name and template define settings.
|
||||
*/
|
||||
void define(const std::string& name, const std::string& vert, const std::string& frag, ValueVector& defines);
|
||||
|
||||
/**
|
||||
* @brief Gets program by template name, define settings and defines key.
|
||||
* @note The return value needs to be released by its 'release' method.
|
||||
*/
|
||||
Program* switchProgram(const size_t programNameHash, const size_t definesKeyHash, const std::vector<const OrderedValueMap*>& definesList);
|
||||
|
||||
const Value* getValueFromDefineList(const std::string& name, const std::vector<const ValueMap*>& definesList);
|
||||
|
||||
private:
|
||||
uint32_t getValueKey(const Value* v);
|
||||
|
||||
private:
|
||||
DeviceGraphics* _device = nullptr;
|
||||
std::unordered_map<size_t, Template> _templates;
|
||||
std::unordered_map<uint64_t, Program*> _cache;
|
||||
|
||||
Program* _current = nullptr;
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
40
cocos2d-x/cocos/renderer/renderer/Renderer.h
Normal file
40
cocos2d-x/cocos/renderer/renderer/Renderer.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ForwardRenderer.h"
|
||||
#include "Camera.h"
|
||||
#include "Config.h"
|
||||
#include "Effect.h"
|
||||
#include "InputAssembler.h"
|
||||
#include "Light.h"
|
||||
#include "Model.h"
|
||||
#include "Pass.h"
|
||||
#include "ProgramLib.h"
|
||||
#include "Renderer.h"
|
||||
#include "Scene.h"
|
||||
#include "Technique.h"
|
||||
#include "RendererUtils.h"
|
||||
#include "View.h"
|
||||
91
cocos2d-x/cocos/renderer/renderer/RendererUtils.cpp
Normal file
91
cocos2d-x/cocos/renderer/renderer/RendererUtils.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "RendererUtils.h"
|
||||
|
||||
#include "gfx/VertexFormat.h"
|
||||
#include "gfx/VertexBuffer.h"
|
||||
#include "gfx/IndexBuffer.h"
|
||||
|
||||
#include "InputAssembler.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
InputAssembler* createIA(DeviceGraphics* device, const IAData& data)
|
||||
{
|
||||
if (data.positions.empty())
|
||||
{
|
||||
RENDERER_LOGD("The data must have positions field!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<float> verts;
|
||||
verts.reserve(data.positions.size() + data.normals.size() + data.uvs.size());
|
||||
size_t vcount = data.positions.size() / 3;
|
||||
|
||||
for (size_t i = 0; i < vcount; ++i) {
|
||||
verts.push_back(data.positions[3 * i]);
|
||||
verts.push_back(data.positions[3 * i + 1]);
|
||||
verts.push_back(data.positions[3 * i + 2]);
|
||||
|
||||
if (!data.normals.empty()) {
|
||||
verts.push_back(data.normals[3 * i]);
|
||||
verts.push_back(data.normals[3 * i + 1]);
|
||||
verts.push_back(data.normals[3 * i + 2]);
|
||||
}
|
||||
|
||||
if (!data.uvs.empty()) {
|
||||
verts.push_back(data.uvs[2 * i]);
|
||||
verts.push_back(data.uvs[2 * i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<VertexFormat::Info> vfmt;
|
||||
vfmt.push_back({ ATTRIB_NAME_POSITION, AttribType::FLOAT32, 3});
|
||||
|
||||
if (!data.normals.empty())
|
||||
vfmt.push_back({ ATTRIB_NAME_NORMAL, AttribType::FLOAT32, 3});
|
||||
|
||||
if (!data.uvs.empty())
|
||||
vfmt.push_back({ ATTRIB_NAME_UV0, AttribType::FLOAT32, 2});
|
||||
|
||||
VertexFormat* fmt = new VertexFormat(vfmt);
|
||||
auto vb = new VertexBuffer();
|
||||
vb->init(device, fmt, Usage::STATIC, verts.data(), verts.size() * sizeof(float), (uint32_t)vcount);
|
||||
fmt->release();
|
||||
|
||||
IndexBuffer* ib = nullptr;
|
||||
|
||||
if (!data.indices.empty())
|
||||
{
|
||||
ib = new IndexBuffer();
|
||||
ib->init(device, IndexFormat::UINT16, Usage::STATIC, data.indices.data(), data.indices.size() * sizeof(uint16_t), (uint32_t)data.indices.size());
|
||||
}
|
||||
|
||||
auto ia = new InputAssembler();
|
||||
ia->init(vb, ib);
|
||||
return ia;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
47
cocos2d-x/cocos/renderer/renderer/RendererUtils.h
Normal file
47
cocos2d-x/cocos/renderer/renderer/RendererUtils.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class InputAssembler;
|
||||
class DeviceGraphics;
|
||||
|
||||
struct IAData
|
||||
{
|
||||
std::vector<float> positions;
|
||||
std::vector<float> normals;
|
||||
std::vector<float> uvs;
|
||||
std::vector<uint16_t> indices;
|
||||
};
|
||||
|
||||
InputAssembler* createIA(DeviceGraphics* device, const IAData& data);
|
||||
|
||||
RENDERER_END
|
||||
127
cocos2d-x/cocos/renderer/renderer/Scene.cpp
Normal file
127
cocos2d-x/cocos/renderer/renderer/Scene.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Scene.h"
|
||||
#include "Camera.h"
|
||||
#include "Light.h"
|
||||
#include "Model.h"
|
||||
#include "View.h"
|
||||
#include "InputAssembler.h"
|
||||
#include "Effect.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
Scene::Scene()
|
||||
{
|
||||
_models.reserve(500);
|
||||
}
|
||||
|
||||
void Scene::reset()
|
||||
{
|
||||
for (auto& model : _models)
|
||||
model->setCullingMask(-1);
|
||||
}
|
||||
|
||||
void Scene::setDebugCamera(Camera* debugCamera)
|
||||
{
|
||||
if (_debugCamera == debugCamera)
|
||||
return;
|
||||
|
||||
RENDERER_SAFE_RELEASE(_debugCamera);
|
||||
RENDERER_SAFE_RETAIN(debugCamera);
|
||||
_debugCamera = debugCamera;
|
||||
}
|
||||
|
||||
Camera* Scene::getCamera(uint32_t index) const
|
||||
{
|
||||
return _cameras.at(index);
|
||||
}
|
||||
|
||||
void Scene::sortCameras()
|
||||
{
|
||||
std::sort(_cameras.begin(), _cameras.end(), [=](const Camera* a, const Camera* b){
|
||||
return a->getPriority() < b->getPriority();
|
||||
});
|
||||
}
|
||||
|
||||
void Scene::addCamera(Camera* camera)
|
||||
{
|
||||
_cameras.pushBack(camera);
|
||||
}
|
||||
|
||||
void Scene::removeCamera(Camera* camera)
|
||||
{
|
||||
_cameras.eraseObject(camera);
|
||||
}
|
||||
|
||||
Model* Scene::getModel(uint32_t index)
|
||||
{
|
||||
return _models.at(index);
|
||||
}
|
||||
|
||||
void Scene::addModel(Model* model)
|
||||
{
|
||||
_models.push_back(model);
|
||||
}
|
||||
|
||||
void Scene::removeModel(Model* model)
|
||||
{
|
||||
auto iter = std::find(_models.begin(), _models.end(), model);
|
||||
if (_models.end() != iter)
|
||||
{
|
||||
_models.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::removeModels()
|
||||
{
|
||||
_models.clear();
|
||||
}
|
||||
|
||||
Light* Scene::getLight(uint32_t index)
|
||||
{
|
||||
return _lights.at(index);
|
||||
}
|
||||
|
||||
void Scene::addLight(Light* light)
|
||||
{
|
||||
_lights.pushBack(light);
|
||||
}
|
||||
|
||||
void Scene::removeLight(Light* light)
|
||||
{
|
||||
_lights.eraseObject(light);
|
||||
}
|
||||
|
||||
void Scene::addView(View* view)
|
||||
{
|
||||
_views.pushBack(view);
|
||||
}
|
||||
|
||||
void Scene::removeView(View* view)
|
||||
{
|
||||
_views.eraseObject(view);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
176
cocos2d-x/cocos/renderer/renderer/Scene.h
Normal file
176
cocos2d-x/cocos/renderer/renderer/Scene.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "base/CCVector.h"
|
||||
#include "base/ccCArray.h"
|
||||
#include "../Macro.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class Camera;
|
||||
class Light;
|
||||
class Model;
|
||||
class View;
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Render scene.
|
||||
*/
|
||||
class Scene
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
Scene();
|
||||
|
||||
/**
|
||||
* @brief Resets all model culling mask.
|
||||
*/
|
||||
void reset();
|
||||
/**
|
||||
* @brief Sets debug camera.
|
||||
* @param[in] debugCamera Debug camera pointer.
|
||||
*/
|
||||
void setDebugCamera(Camera* debugCamera);
|
||||
|
||||
/**
|
||||
* @brief Gets cameras count.
|
||||
* @return Cameras count.
|
||||
*/
|
||||
inline uint32_t getCameraCount() const { return (uint32_t)_cameras.size(); }
|
||||
|
||||
/**
|
||||
* @brief Gets camera by index.
|
||||
* @return camera pointer.
|
||||
*/
|
||||
Camera* getCamera(uint32_t index) const;
|
||||
/**
|
||||
* @brief Adds camera.
|
||||
* @param[in] camera Camera pointer.
|
||||
*/
|
||||
void addCamera(Camera* camera);
|
||||
/**
|
||||
* @brief Removes camera.
|
||||
* @param[in] camera Camera pointer.
|
||||
*/
|
||||
void removeCamera(Camera* camera);
|
||||
/**
|
||||
* @brief Gets all cameras.
|
||||
* @return All Cameras container.
|
||||
*/
|
||||
inline const Vector<Camera*>& getCameras() const { return _cameras; }
|
||||
/**
|
||||
* @brief Sorts all cameras.
|
||||
*/
|
||||
void sortCameras();
|
||||
|
||||
/**
|
||||
* @brief Gets all models count.
|
||||
* @return All models count.
|
||||
*/
|
||||
inline uint32_t getModelCount() const { return (uint32_t)_models.size(); }
|
||||
/**
|
||||
* @brief Gets model by index.
|
||||
* @param[in] index Model index.
|
||||
* @return Model pointer.
|
||||
*/
|
||||
Model* getModel(uint32_t index);
|
||||
/**
|
||||
* @brief Adds model.
|
||||
* @param[in] model Model pointer.
|
||||
*/
|
||||
void addModel(Model* model);
|
||||
/**
|
||||
* @brief Removes model.
|
||||
* @param[in] model Model pointer.
|
||||
*/
|
||||
void removeModel(Model* model);
|
||||
/**
|
||||
* @brief Removes all models.
|
||||
*/
|
||||
void removeModels();
|
||||
/**
|
||||
* @brief Gets all models.
|
||||
* @return Models container.
|
||||
*/
|
||||
inline const std::vector<Model*>& getModels() const { return _models; }
|
||||
|
||||
/**
|
||||
* @brief Gets light count.
|
||||
* @return Lights count.
|
||||
*/
|
||||
inline uint32_t getLightCount() const { return (uint32_t)_lights.size(); }
|
||||
/**
|
||||
* @brief Gets light by index.
|
||||
* @param[in] index Light index.
|
||||
* @return Light pointer.
|
||||
*/
|
||||
Light* getLight(uint32_t index);
|
||||
/**
|
||||
* @brief Adds light.
|
||||
* @param[in] light Light pointer.
|
||||
*/
|
||||
void addLight(Light* light);
|
||||
/**
|
||||
* @brief Removes light.
|
||||
* @param[in] light Light pointer.
|
||||
*/
|
||||
void removeLight(Light* light);
|
||||
|
||||
/**
|
||||
* @brief Adds view.
|
||||
* @param[in] view View pointer.
|
||||
*/
|
||||
void addView(View* view);
|
||||
/**
|
||||
* @brief Removes view.
|
||||
* @param[in] view View pointer.
|
||||
*/
|
||||
void removeView(View* view);
|
||||
/**
|
||||
* @brief Gets all lights.
|
||||
* @return Lights container.
|
||||
*/
|
||||
inline const Vector<Light*> getLights() const { return _lights; };
|
||||
private:
|
||||
//REFINE: optimize speed.
|
||||
Vector<Camera*> _cameras;
|
||||
Vector<Light*> _lights;
|
||||
std::vector<Model*> _models;
|
||||
Vector<View*> _views;
|
||||
Camera* _debugCamera = nullptr;
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
502
cocos2d-x/cocos/renderer/renderer/Technique.cpp
Normal file
502
cocos2d-x/cocos/renderer/renderer/Technique.cpp
Normal file
@@ -0,0 +1,502 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Technique.h"
|
||||
#include "Config.h"
|
||||
#include "Pass.h"
|
||||
#include "gfx/Texture.h"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
// implementation of Parameter
|
||||
|
||||
uint8_t Technique::Parameter::getElements(Type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Type::INT:
|
||||
return 1;
|
||||
case Type::INT2:
|
||||
return 2;
|
||||
case Type::INT3:
|
||||
return 3;
|
||||
case Type::INT4:
|
||||
return 4;
|
||||
case Type::FLOAT:
|
||||
return 1;
|
||||
case Type::FLOAT2:
|
||||
return 2;
|
||||
case Type::FLOAT3:
|
||||
return 3;
|
||||
case Type::FLOAT4:
|
||||
return 4;
|
||||
case Type::COLOR3:
|
||||
return 3;
|
||||
case Type::COLOR4:
|
||||
return 4;
|
||||
case Type::MAT2:
|
||||
return 4;
|
||||
case Type::MAT3:
|
||||
return 9;
|
||||
case Type::MAT4:
|
||||
return 16;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Technique::Parameter::Parameter()
|
||||
{
|
||||
}
|
||||
|
||||
Technique::Parameter::Parameter(const std::string& name, Type type)
|
||||
: _name(name)
|
||||
, _type(type)
|
||||
, _count(1)
|
||||
{
|
||||
_hashName = std::hash<std::string>{}(name);
|
||||
|
||||
if (Type::TEXTURE_2D == _type ||
|
||||
Type::TEXTURE_CUBE == _type ||
|
||||
Type::UNKNOWN == _type)
|
||||
return;
|
||||
|
||||
uint8_t elements = Parameter::getElements(type);
|
||||
switch (type)
|
||||
{
|
||||
case Type::INT:
|
||||
case Type::INT2:
|
||||
case Type::INT3:
|
||||
case Type::INT4:
|
||||
_bytes = sizeof(int) * elements;
|
||||
break;
|
||||
case Type::FLOAT:
|
||||
case Type::FLOAT2:
|
||||
case Type::FLOAT3:
|
||||
case Type::FLOAT4:
|
||||
case Type::COLOR3:
|
||||
case Type::COLOR4:
|
||||
case Type::MAT2:
|
||||
case Type::MAT3:
|
||||
case Type::MAT4:
|
||||
_bytes = sizeof(float) * elements;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_value = malloc(_bytes);
|
||||
memset(_value, 0, _bytes);
|
||||
if (Type::COLOR4 == _type)
|
||||
*((float*)(_value) + 3) = 1.0f;
|
||||
}
|
||||
|
||||
Technique::Parameter::Parameter(const std::string& name, Type type, int* value, uint8_t count)
|
||||
: _name(name)
|
||||
, _type(type)
|
||||
, _count(count)
|
||||
{
|
||||
_hashName = std::hash<std::string>{}(name);
|
||||
|
||||
uint8_t bytes = sizeof(int);
|
||||
switch (_type)
|
||||
{
|
||||
case Type::INT:
|
||||
bytes *= _count;
|
||||
break;
|
||||
case Type::INT2:
|
||||
bytes *= 2 * _count;
|
||||
break;
|
||||
case Type::INT3:
|
||||
bytes *= 3 * _count;
|
||||
break;
|
||||
case Type::INT4:
|
||||
bytes *= 4 * _count;
|
||||
break;
|
||||
default:
|
||||
RENDERER_LOGW("This constructor only supports INT/INT2/INT3/INT4.");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
_value = malloc(bytes);
|
||||
if (_value)
|
||||
memcpy(_value, value, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
Technique::Parameter::Parameter(const std::string& name, Type type, float* value, uint8_t count)
|
||||
: _name(name)
|
||||
, _type(type)
|
||||
, _count(count)
|
||||
{
|
||||
_hashName = std::hash<std::string>{}(name);
|
||||
|
||||
uint16_t bytes = sizeof(float);
|
||||
switch (_type)
|
||||
{
|
||||
case Type::FLOAT:
|
||||
bytes *= _count;
|
||||
break;
|
||||
case Type::FLOAT2:
|
||||
bytes *= 2 * _count;
|
||||
break;
|
||||
case Type::FLOAT3:
|
||||
bytes *= 3 * _count;
|
||||
break;
|
||||
case Type::FLOAT4:
|
||||
bytes *= 4 * _count;
|
||||
break;
|
||||
case Type::MAT2:
|
||||
bytes *= 4 * _count;
|
||||
break;
|
||||
case Type::MAT3:
|
||||
bytes *= 9 * _count;
|
||||
break;
|
||||
case Type::MAT4:
|
||||
bytes *= 16 * _count;
|
||||
break;
|
||||
case Type::COLOR4:
|
||||
bytes *= 4 * _count;
|
||||
break;
|
||||
case Type::COLOR3:
|
||||
bytes *= 3 * _count;
|
||||
break;
|
||||
|
||||
default:
|
||||
RENDERER_LOGW("This constructor only supports FLAOT/FLOAT2/FLOAT3/FLOAT4/MAT2/MAT3/MAT4/COLOR3/COLOR4.");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
_bytes = bytes;
|
||||
_value = malloc(_bytes);
|
||||
if (_value)
|
||||
memcpy(_value, value, _bytes);
|
||||
}
|
||||
}
|
||||
|
||||
Technique::Parameter::Parameter(const std::string& name, Type type, se::Object* jsValue, uint8_t count)
|
||||
:_name(name)
|
||||
,_count(count)
|
||||
,_type(type)
|
||||
{
|
||||
_hashName = std::hash<std::string>{}(name);
|
||||
|
||||
se::ScriptEngine::getInstance()->clearException();
|
||||
se::AutoHandleScope hs;
|
||||
|
||||
setShareValue(jsValue);
|
||||
}
|
||||
|
||||
Technique::Parameter::Parameter(const std::string& name, Type type, Texture* value)
|
||||
: _name(name)
|
||||
, _count(1)
|
||||
, _type(type)
|
||||
{
|
||||
_hashName = std::hash<std::string>{}(name);
|
||||
|
||||
assert(_type == Type::TEXTURE_2D || _type == Type::TEXTURE_CUBE);
|
||||
if (value)
|
||||
{
|
||||
_value = value;
|
||||
value->retain();
|
||||
}
|
||||
}
|
||||
|
||||
Technique::Parameter::Parameter(const std::string& name, Type type, const std::vector<Texture*>& textures)
|
||||
: _name(name)
|
||||
, _count(textures.size())
|
||||
, _type(type)
|
||||
{
|
||||
_hashName = std::hash<std::string>{}(name);
|
||||
|
||||
assert(_type == Type::TEXTURE_2D || _type == Type::TEXTURE_CUBE);
|
||||
if (textures.empty())
|
||||
return;
|
||||
|
||||
size_t size = textures.size();
|
||||
_value = malloc(sizeof(void*) * size);
|
||||
void** valArr = (void**)_value;
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
Texture* tex = textures[i];
|
||||
valArr[i] = tex;
|
||||
if (tex)
|
||||
tex->retain();
|
||||
}
|
||||
}
|
||||
|
||||
Technique::Parameter::Parameter(Parameter&& rh)
|
||||
{
|
||||
if (this == &rh)
|
||||
return;
|
||||
|
||||
freeValue();
|
||||
|
||||
_name = rh._name;
|
||||
_type = rh._type;
|
||||
_value = rh._value;
|
||||
_count = rh._count;
|
||||
_bytes = rh._bytes;
|
||||
_hashName = rh._hashName;
|
||||
|
||||
rh._value = nullptr;
|
||||
}
|
||||
|
||||
Technique::Parameter::Parameter(const Parameter& rh)
|
||||
{
|
||||
freeValue();
|
||||
copyValue(rh);
|
||||
}
|
||||
|
||||
Technique::Parameter::~Parameter()
|
||||
{
|
||||
freeValue();
|
||||
}
|
||||
|
||||
Technique::Parameter& Technique::Parameter::operator=(const Parameter& rh)
|
||||
{
|
||||
if (this == &rh)
|
||||
return *this;
|
||||
|
||||
freeValue();
|
||||
copyValue(rh);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Technique::Parameter::operator==(const Parameter& rh)
|
||||
{
|
||||
if (this == &rh)
|
||||
return true;
|
||||
|
||||
if (_type == rh.getType() && _value == rh.getValue())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Texture*> Technique::Parameter::getTextureArray() const
|
||||
{
|
||||
std::vector<Texture*> ret;
|
||||
if (Type::TEXTURE_2D != _type &&
|
||||
Type::TEXTURE_CUBE != _type)
|
||||
return ret;
|
||||
|
||||
Texture** texture = (Texture**)_value;
|
||||
for (int i = 0; i < _count; ++i)
|
||||
{
|
||||
ret.push_back(texture[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Texture* Technique::Parameter::getTexture() const
|
||||
{
|
||||
assert(_type == Technique::Parameter::Type::TEXTURE_2D || _type == Technique::Parameter::Type::TEXTURE_CUBE);
|
||||
assert(_count == 1);
|
||||
return static_cast<Texture*>(_value);
|
||||
}
|
||||
|
||||
void Technique::Parameter::setTexture(renderer::Texture *texture)
|
||||
{
|
||||
if (_value == texture)
|
||||
return;
|
||||
|
||||
freeValue();
|
||||
_value = texture;
|
||||
RENDERER_SAFE_RETAIN(texture);
|
||||
|
||||
_type = Type::TEXTURE_2D;
|
||||
_count = 1;
|
||||
}
|
||||
|
||||
void Technique::Parameter::copyValue(const Parameter& rh)
|
||||
{
|
||||
_name = rh._name;
|
||||
_type = rh._type;
|
||||
_count = rh._count;
|
||||
_bytes = rh._bytes;
|
||||
_hashName = rh._hashName;
|
||||
|
||||
if (Type::TEXTURE_2D == _type ||
|
||||
Type::TEXTURE_CUBE == _type)
|
||||
{
|
||||
if (_count == 1)
|
||||
{
|
||||
_value = rh._value;
|
||||
RENDERER_SAFE_RETAIN((Texture*)_value);
|
||||
}
|
||||
else if (_count > 0)
|
||||
{
|
||||
_value = malloc(_count * sizeof(void*));
|
||||
memcpy(_value, rh._value, _count * sizeof(void*));
|
||||
Texture** texture = (Texture**)_value;
|
||||
for (uint8_t i = 0; i < _count; ++i)
|
||||
{
|
||||
RENDERER_SAFE_RETAIN(texture[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_count > 0)
|
||||
{
|
||||
if (rh._jsValue != nullptr)
|
||||
{
|
||||
setShareValue(rh._jsValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
_value = malloc(_bytes);
|
||||
memcpy(_value, rh._value, _bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Technique::Parameter::setShareValue(se::Object *jsValue)
|
||||
{
|
||||
if (!jsValue || jsValue == _jsValue)
|
||||
return;
|
||||
if (_jsValue)
|
||||
{
|
||||
_jsValue->unroot();
|
||||
_jsValue->decRef();
|
||||
}
|
||||
_jsValue = jsValue;
|
||||
_jsValue->root();
|
||||
_jsValue->incRef();
|
||||
_shareValue = nullptr;
|
||||
_bytes = 0;
|
||||
_jsValue->getTypedArrayData(&_shareValue, (std::size_t*)&_bytes);
|
||||
}
|
||||
|
||||
void Technique::Parameter::setValue(void* value)
|
||||
{
|
||||
switch (_type) {
|
||||
case Type::TEXTURE_2D:
|
||||
setTexture((Texture*)value);
|
||||
break;
|
||||
default:
|
||||
RENDERER_LOGD("Not support Parameter::setValue with type : %d", (int)_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Technique::Parameter::freeValue()
|
||||
{
|
||||
if (_value)
|
||||
{
|
||||
if (Type::TEXTURE_2D == _type ||
|
||||
Type::TEXTURE_CUBE == _type)
|
||||
{
|
||||
if (_count == 1)
|
||||
{
|
||||
CC_SAFE_RELEASE((Texture*)_value);
|
||||
_value = nullptr;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Texture** textures = static_cast<Texture**>(_value);
|
||||
for (int i = 0; i < _count; ++i)
|
||||
{
|
||||
Texture* texture = textures[i];
|
||||
RENDERER_SAFE_RELEASE(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(_value);
|
||||
_value = nullptr;
|
||||
}
|
||||
|
||||
if(_jsValue)
|
||||
{
|
||||
_jsValue->unroot();
|
||||
_jsValue->decRef();
|
||||
_jsValue = nullptr;
|
||||
_shareValue = nullptr;
|
||||
_bytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of Technique
|
||||
|
||||
uint32_t Technique::_genID = 0;
|
||||
|
||||
Technique::Technique(const std::string& name, const Vector<Pass*>& passes)
|
||||
: _id(_genID++)
|
||||
, _passes(passes)
|
||||
{
|
||||
// RENDERER_LOGD("Technique construction: %p", this);
|
||||
}
|
||||
|
||||
Technique::Technique()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Technique::~Technique()
|
||||
{
|
||||
// RENDERER_LOGD("Technique destruction: %p", this);
|
||||
}
|
||||
|
||||
void Technique::setStages(const std::vector<std::string>& stages)
|
||||
{
|
||||
_stageIDs = Config::getStageIDs(stages);
|
||||
}
|
||||
|
||||
void Technique::setPass(int index, Pass* pass)
|
||||
{
|
||||
_passes.insert(index, pass);
|
||||
}
|
||||
|
||||
void Technique::copy(const Technique& tech)
|
||||
{
|
||||
_id = tech._id;
|
||||
_stageIDs = tech._stageIDs;
|
||||
_layer = tech._layer;
|
||||
_passes.clear();
|
||||
auto& otherPasses = tech._passes;
|
||||
for (auto it = otherPasses.begin(); it != otherPasses.end(); it++)
|
||||
{
|
||||
auto newPass = new Pass();
|
||||
newPass->autorelease();
|
||||
newPass->copy(**it);
|
||||
_passes.pushBack(newPass);
|
||||
}
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
264
cocos2d-x/cocos/renderer/renderer/Technique.h
Normal file
264
cocos2d-x/cocos/renderer/renderer/Technique.h
Normal file
@@ -0,0 +1,264 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "platform/CCGL.h"
|
||||
#include "base/CCVector.h"
|
||||
#include "base/CCRef.h"
|
||||
#include "../Macro.h"
|
||||
|
||||
namespace se {
|
||||
class Object;
|
||||
class HandleObject;
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class Pass;
|
||||
class Texture;
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Technique is a important part of Effect, it contains a selective uniform parameters and all passes of effect.\n
|
||||
* JS API: renderer.Technique
|
||||
* @code
|
||||
* let pass = new renderer.Pass('sprite');
|
||||
* pass.setDepth(false, false);
|
||||
* pass.setCullMode(gfx.CULL_NONE);
|
||||
* let technique = new renderer.Technique(
|
||||
* ['transparent'],
|
||||
* [
|
||||
* { name: 'texture', type: renderer.PARAM_TEXTURE_2D },
|
||||
* { name: 'color', type: renderer.PARAM_COLOR4 }
|
||||
* ],
|
||||
* [
|
||||
* pass
|
||||
* ]
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
class Technique : public Ref
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* @brief Uniform parameter of Technique, defines the uniform name and type
|
||||
*/
|
||||
class Parameter final
|
||||
{
|
||||
public:
|
||||
enum class Type : uint8_t
|
||||
{
|
||||
INT = 5,
|
||||
INT2 = 6,
|
||||
INT3 = 7,
|
||||
INT4 = 8,
|
||||
FLOAT = 13,
|
||||
FLOAT2 = 14,
|
||||
FLOAT3 = 15,
|
||||
FLOAT4 = 16,
|
||||
COLOR3 = 99,
|
||||
COLOR4 = 100,
|
||||
MAT2 = 18,
|
||||
MAT3 = 22,
|
||||
MAT4 = 26,
|
||||
TEXTURE_2D = 29,
|
||||
TEXTURE_CUBE = 31,
|
||||
UNKNOWN = 0
|
||||
};
|
||||
|
||||
// How many elements of each type, for example:
|
||||
// INT -> 1
|
||||
// INT2 -> 2
|
||||
// MAT4 -> 16
|
||||
static uint8_t getElements(Type type);
|
||||
|
||||
/*
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
Parameter();
|
||||
/*
|
||||
* @brief Constructor with integer.
|
||||
*/
|
||||
Parameter(const std::string& name, Type type, int* value, uint8_t count = 1);
|
||||
/*
|
||||
* @brief Constructor with float.
|
||||
*/
|
||||
Parameter(const std::string& name, Type type, float* value, uint8_t count = 1);
|
||||
/*
|
||||
* @brief Constructor with Object.
|
||||
*/
|
||||
Parameter(const std::string& name, Type type, se::Object* value, uint8_t count = 1);
|
||||
/*
|
||||
* @brief Constructor with texture.
|
||||
*/
|
||||
Parameter(const std::string& name, Type type, Texture* texture);
|
||||
/*
|
||||
* @brief Constructor with texture array.
|
||||
*/
|
||||
Parameter(const std::string& name, Type type, const std::vector<Texture*>& textures);
|
||||
Parameter(const std::string& name, Type type);
|
||||
Parameter(const Parameter& rh);
|
||||
Parameter(Parameter&& rh);
|
||||
~Parameter();
|
||||
|
||||
Parameter& operator=(const Parameter& rh);
|
||||
bool operator==(const Parameter& rh);
|
||||
|
||||
/*
|
||||
* @brief Gets the uniform type.
|
||||
*/
|
||||
inline Type getType() const { return _type; }
|
||||
/*
|
||||
* @brief Gets the uniform name.
|
||||
*/
|
||||
inline const std::string& getName() const { return _name; }
|
||||
inline const size_t getHashName() const { return _hashName; }
|
||||
/*
|
||||
* @brief Gets the counts of uniform components.
|
||||
*/
|
||||
inline uint8_t getCount() const { return _count; }
|
||||
/*
|
||||
* @brief Gets parameter value.
|
||||
*/
|
||||
inline void* getValue() const
|
||||
{
|
||||
if(_jsValue != nullptr)
|
||||
{
|
||||
return _shareValue;
|
||||
}
|
||||
return _value;
|
||||
};
|
||||
/*
|
||||
* @brief Gets bytes occupied by primitive uniform parameter.
|
||||
*/
|
||||
inline uint16_t getBytes() const { return _bytes; };
|
||||
/*
|
||||
* @brief Gets directly value.
|
||||
*/
|
||||
inline bool getDirectly() const { return _directly; }
|
||||
/*
|
||||
* @brief Sets directly value.
|
||||
*/
|
||||
inline void setDirectly(bool value) { _directly = value; };
|
||||
/*
|
||||
* @brief Gets the texture array.
|
||||
*/
|
||||
std::vector<Texture*> getTextureArray() const;
|
||||
/*
|
||||
* @brief Set the typed array.
|
||||
*/
|
||||
void setShareValue(se::Object* jsValue);
|
||||
void setValue(void* value);
|
||||
/*
|
||||
* @brief Sets the texture pointer.
|
||||
*/
|
||||
void setTexture(Texture* texture);
|
||||
/*
|
||||
* @brief Gets the texture pointer.
|
||||
*/
|
||||
Texture* getTexture() const;
|
||||
|
||||
uint8_t* _shareValue = nullptr;
|
||||
se::Object* _jsValue = nullptr;
|
||||
private:
|
||||
|
||||
void freeValue();
|
||||
void copyValue(const Parameter& rh);
|
||||
|
||||
std::string _name = "";
|
||||
size_t _hashName = 0;
|
||||
|
||||
// how many elements, for example, how many INT2 or how many MAT2
|
||||
uint8_t _count = 0;
|
||||
Type _type = Type::UNKNOWN;
|
||||
void* _value = nullptr;
|
||||
|
||||
// It is meaningful if type is not Texture2D or TEXTURE_CUBE.
|
||||
uint16_t _bytes = 0;
|
||||
bool _directly = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param[in] stages All stages it belongs to.
|
||||
* @param[in] parameters All uniform parameters.
|
||||
* @param[in] passes All passes.
|
||||
*/
|
||||
Technique(const std::string& name, const Vector<Pass*>& passes);
|
||||
|
||||
/*
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
Technique();
|
||||
/*
|
||||
* @brief The default destructor.
|
||||
*/
|
||||
~Technique();
|
||||
|
||||
/**
|
||||
* @brief Sets the stages it belongs to.
|
||||
*/
|
||||
void setStages(const std::vector<std::string>& stages);
|
||||
/*
|
||||
* @brief Sets the pass to the given index.
|
||||
*/
|
||||
void setPass(int index, Pass* pass);
|
||||
/*
|
||||
* @brief Gets all passes.
|
||||
*/
|
||||
const Vector<Pass*>& getPasses() const { return _passes; }
|
||||
Vector<Pass*>& getPasses() { return _passes; }
|
||||
/*
|
||||
* @brief Gets all stageID.
|
||||
*/
|
||||
uint32_t getStageIDs() const { return _stageIDs; }
|
||||
/**
|
||||
* @brief Deep copy from other techique.
|
||||
*/
|
||||
void copy(const Technique& tech);
|
||||
/**
|
||||
* @brief Get layer.
|
||||
*/
|
||||
inline const int getLayer() const {return _layer; };
|
||||
|
||||
private:
|
||||
static uint32_t _genID;
|
||||
|
||||
uint32_t _id = 0;
|
||||
uint32_t _stageIDs = 0;
|
||||
int _layer = 0;
|
||||
Vector<Pass*> _passes;
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
49
cocos2d-x/cocos/renderer/renderer/View.cpp
Normal file
49
cocos2d-x/cocos/renderer/renderer/View.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "View.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
namespace
|
||||
{
|
||||
uint32_t g_genID = 0;
|
||||
}
|
||||
|
||||
View::View()
|
||||
: id(g_genID++)
|
||||
{
|
||||
}
|
||||
|
||||
void View::getForward(Vec3& out) const
|
||||
{
|
||||
out.set(matView.m[2], matView.m[6], matView.m[10]);
|
||||
}
|
||||
|
||||
void View::getPosition(Vec3& out) const
|
||||
{
|
||||
matView.getInversed().getTranslation(&out);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
93
cocos2d-x/cocos/renderer/renderer/View.h
Normal file
93
cocos2d-x/cocos/renderer/renderer/View.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "base/ccTypes.h"
|
||||
#include "../Macro.h"
|
||||
#include "../Types.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class Light;
|
||||
class FrameBuffer;
|
||||
|
||||
/**
|
||||
* @addtogroup renderer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief View defines a specific camera view and Light settings
|
||||
*/
|
||||
class View : public Ref
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
View();
|
||||
/**
|
||||
* @brief Gets the forward direction.
|
||||
*/
|
||||
void getForward(Vec3& out) const;
|
||||
/**
|
||||
* @brief Gets the position.
|
||||
*/
|
||||
void getPosition(Vec3& out) const;
|
||||
|
||||
uint32_t id;
|
||||
|
||||
// viewport
|
||||
Rect rect = {0, 0, 1.f, 1.f};
|
||||
|
||||
// clear options
|
||||
Color4F color = {0.3f, 0.3f, 0.3f, 1.f};
|
||||
int depth = 1;
|
||||
int stencil = 1;
|
||||
unsigned int cullingMask = 1;
|
||||
uint8_t clearFlags = ClearFlag::COLOR | ClearFlag::DEPTH;
|
||||
|
||||
// matrix
|
||||
Mat4 matView;
|
||||
Mat4 matViewInv;
|
||||
Mat4 matProj;
|
||||
Mat4 matViewProj;
|
||||
Mat4 matInvViewProj;
|
||||
|
||||
// stages & framebuffer
|
||||
std::vector<std::string> stages;
|
||||
bool cullingByID = false;
|
||||
FrameBuffer* frameBuffer = nullptr;
|
||||
|
||||
Light* shadowLight = nullptr;
|
||||
};
|
||||
|
||||
// end of renderer group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
179
cocos2d-x/cocos/renderer/scene/MemPool.cpp
Normal file
179
cocos2d-x/cocos/renderer/scene/MemPool.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "MemPool.hpp"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
UnitBase::UnitBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UnitBase::~UnitBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UnitBase::set(se::Object** dataObj, uint8_t** data, std::size_t* dataLen, se::Object* jsData)
|
||||
{
|
||||
if (*dataObj == jsData) return;
|
||||
|
||||
if (*dataObj)
|
||||
{
|
||||
(*dataObj)->unroot();
|
||||
(*dataObj)->decRef();
|
||||
*dataObj = nullptr;
|
||||
}
|
||||
|
||||
if (jsData == nullptr) return;
|
||||
|
||||
*dataObj = jsData;
|
||||
(*dataObj)->root();
|
||||
(*dataObj)->incRef();
|
||||
*data = nullptr;
|
||||
*dataLen = 0;
|
||||
(*dataObj)->getTypedArrayData(data, dataLen);
|
||||
}
|
||||
|
||||
void UnitBase::unset(se::Object** dataObj, uint8_t** data, std::size_t* dataLen)
|
||||
{
|
||||
if (*dataObj)
|
||||
{
|
||||
(*dataObj)->unroot();
|
||||
(*dataObj)->decRef();
|
||||
*dataObj = nullptr;
|
||||
}
|
||||
|
||||
*data = nullptr;
|
||||
*dataLen = 0;
|
||||
}
|
||||
|
||||
UnitCommon::UnitCommon()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UnitCommon::~UnitCommon()
|
||||
{
|
||||
unset(&dataObj, (uint8_t**)&data, &dataLen);
|
||||
unset(&signDataObj, (uint8_t**)&signData, &signDataLen);
|
||||
}
|
||||
|
||||
void UnitCommon::setData(se::Object* jsData)
|
||||
{
|
||||
set(&dataObj, (uint8_t**)&data, &dataLen, jsData);
|
||||
}
|
||||
|
||||
void UnitCommon::setSignData(se::Object* jsSignData)
|
||||
{
|
||||
set(&signDataObj, (uint8_t**)&signData, &signDataLen, jsSignData);
|
||||
}
|
||||
|
||||
MemPool::MemPool()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MemPool::~MemPool()
|
||||
{
|
||||
for(auto it = _commonPool.begin(); it != _commonPool.end(); it++)
|
||||
{
|
||||
if (*it)
|
||||
{
|
||||
delete (*it);
|
||||
}
|
||||
}
|
||||
_commonPool.clear();
|
||||
}
|
||||
|
||||
void MemPool::removeCommonData(std::size_t unitID)
|
||||
{
|
||||
CCASSERT(unitID < _commonPool.size(), "MemPool removeCommonData unitID can not be rather than pool size");
|
||||
auto unit = _commonPool[unitID];
|
||||
if (unit)
|
||||
{
|
||||
for (auto it = _commonList.begin(); it != _commonList.end(); it++)
|
||||
{
|
||||
if ((*it)->unitID == unitID)
|
||||
{
|
||||
_commonList.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete unit;
|
||||
_commonPool[unitID] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MemPool::updateCommonData(std::size_t unitID, se_object_ptr dataObj, se_object_ptr signDataObj)
|
||||
{
|
||||
CCASSERT(unitID <= _commonPool.size(), "MemPool updateData unitID can not be rather than pool size");
|
||||
|
||||
UnitCommon* unit = nullptr;
|
||||
if (unitID == _commonPool.size())
|
||||
{
|
||||
unit = new UnitCommon;
|
||||
_commonPool.push_back(unit);
|
||||
_commonList.push_back(unit);
|
||||
}
|
||||
else if (unitID < _commonPool.size())
|
||||
{
|
||||
unit = _commonPool[unitID];
|
||||
if (!unit)
|
||||
{
|
||||
unit = new UnitCommon;
|
||||
_commonPool[unitID] = unit;
|
||||
_commonList.push_back(unit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unit->unitID = unitID;
|
||||
unit->setData(dataObj);
|
||||
unit->setSignData(signDataObj);
|
||||
}
|
||||
|
||||
const std::vector<UnitCommon*>& MemPool::getCommonPool() const
|
||||
{
|
||||
return _commonPool;
|
||||
}
|
||||
|
||||
const std::vector<UnitCommon*>& MemPool::getCommonList() const
|
||||
{
|
||||
return _commonList;
|
||||
}
|
||||
|
||||
UnitCommon* MemPool::getCommonUnit(std::size_t unitID)
|
||||
{
|
||||
CCASSERT(unitID < _commonPool.size(), "MemPool getCommonUnit unitID can not be rather than pool size");
|
||||
return _commonPool[unitID];
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
99
cocos2d-x/cocos/renderer/scene/MemPool.hpp
Normal file
99
cocos2d-x/cocos/renderer/scene/MemPool.hpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include <vector>
|
||||
#include "scripting/js-bindings/jswrapper/Object.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class UnitBase
|
||||
{
|
||||
public:
|
||||
UnitBase();
|
||||
virtual ~UnitBase();
|
||||
|
||||
void set(se::Object** dataObj, uint8_t** data, std::size_t* dataLen, se::Object* jsData);
|
||||
void unset(se::Object** dataObj, uint8_t** data, std::size_t* dataLen);
|
||||
|
||||
std::size_t unitID = 0;
|
||||
};
|
||||
|
||||
struct Sign
|
||||
{
|
||||
uint16_t nextFreeIndex;
|
||||
uint16_t freeFlag;
|
||||
};
|
||||
|
||||
class UnitCommon: public UnitBase
|
||||
{
|
||||
public:
|
||||
UnitCommon();
|
||||
virtual ~UnitCommon();
|
||||
|
||||
void setData(se::Object* jsData);
|
||||
void setSignData(se::Object* jsSignData);
|
||||
|
||||
uint16_t getUsingNum()
|
||||
{
|
||||
return data[1];
|
||||
}
|
||||
|
||||
Sign* getSignData(std::size_t index)
|
||||
{
|
||||
return (Sign*)signData + index;
|
||||
}
|
||||
|
||||
std::size_t getContentNum()
|
||||
{
|
||||
return signDataLen / (sizeof(uint16_t) * 2);
|
||||
}
|
||||
protected:
|
||||
se::Object* dataObj = nullptr;
|
||||
uint16_t* data = nullptr;
|
||||
std::size_t dataLen = 0;
|
||||
|
||||
se::Object* signDataObj = nullptr;
|
||||
uint16_t* signData = nullptr;
|
||||
std::size_t signDataLen = 0;
|
||||
};
|
||||
|
||||
class MemPool {
|
||||
public:
|
||||
MemPool();
|
||||
virtual ~MemPool();
|
||||
|
||||
void removeCommonData(std::size_t unitID);
|
||||
void updateCommonData(std::size_t unitID, se_object_ptr dataObj, se_object_ptr signDataObj);
|
||||
UnitCommon* getCommonUnit(std::size_t unitID);
|
||||
const std::vector<UnitCommon*>& getCommonPool() const;
|
||||
const std::vector<UnitCommon*>& getCommonList() const;
|
||||
private:
|
||||
std::vector<UnitCommon*> _commonPool;
|
||||
std::vector<UnitCommon*> _commonList;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
227
cocos2d-x/cocos/renderer/scene/MeshBuffer.cpp
Normal file
227
cocos2d-x/cocos/renderer/scene/MeshBuffer.cpp
Normal file
@@ -0,0 +1,227 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "MeshBuffer.hpp"
|
||||
#include "../Types.h"
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "RenderFlow.hpp"
|
||||
#include "../gfx/DeviceGraphics.h"
|
||||
|
||||
#define MAX_VERTEX_COUNT 65535
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
MeshBuffer::MeshBuffer(ModelBatcher* batcher, VertexFormat* fmt)
|
||||
: _vertexFmt(fmt)
|
||||
, _batcher(batcher)
|
||||
{
|
||||
_bytesPerVertex = _vertexFmt->getBytes();
|
||||
|
||||
DeviceGraphics* device = _batcher->getFlow()->getDevice();
|
||||
_vb = VertexBuffer::create(device, _vertexFmt, Usage::DYNAMIC, nullptr, 0, 0);
|
||||
_vbArr.pushBack(_vb);
|
||||
|
||||
_ib = IndexBuffer::create(device, IndexFormat::UINT16, Usage::STATIC, nullptr, 0, 0);
|
||||
_ibArr.pushBack(_ib);
|
||||
|
||||
_vDataCount = MeshBuffer::INIT_VERTEX_COUNT * 4 * _bytesPerVertex / sizeof(float);
|
||||
_iDataCount = MeshBuffer::INIT_VERTEX_COUNT * 6;
|
||||
|
||||
reallocVBuffer();
|
||||
reallocIBuffer();
|
||||
}
|
||||
|
||||
MeshBuffer::~MeshBuffer()
|
||||
{
|
||||
for (std::size_t i = 0, n = _vbArr.size(); i < n; i++)
|
||||
{
|
||||
_vbArr.at(i)->destroy();
|
||||
}
|
||||
_vbArr.clear();
|
||||
|
||||
for (std::size_t i = 0, n = _ibArr.size(); i < n; i++)
|
||||
{
|
||||
_ibArr.at(i)->destroy();
|
||||
}
|
||||
_ibArr.clear();
|
||||
|
||||
if (iData)
|
||||
{
|
||||
delete[] iData;
|
||||
iData = nullptr;
|
||||
}
|
||||
|
||||
if (vData)
|
||||
{
|
||||
delete[] vData;
|
||||
vData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MeshBuffer::reallocVBuffer()
|
||||
{
|
||||
auto oldVData = vData;
|
||||
vData = new float[_vDataCount];
|
||||
if (oldVData)
|
||||
{
|
||||
memcpy(vData, oldVData, sizeof(float) * _oldVDataCount);
|
||||
delete[] oldVData;
|
||||
oldVData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MeshBuffer::reallocIBuffer()
|
||||
{
|
||||
auto oldIData = iData;
|
||||
iData = new uint16_t[_iDataCount];
|
||||
if (oldIData)
|
||||
{
|
||||
memcpy(iData, oldIData, sizeof(uint16_t) * _oldIDataCount);
|
||||
delete[] oldIData;
|
||||
oldIData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const MeshBuffer::OffsetInfo& MeshBuffer::request(uint32_t vertexCount, uint32_t indexCount)
|
||||
{
|
||||
if (_batcher->getCurrentBuffer() != this)
|
||||
{
|
||||
_batcher->flush();
|
||||
_batcher->setCurrentBuffer(this);
|
||||
}
|
||||
_offsetInfo.vByte = _byteOffset;
|
||||
_offsetInfo.index = _indexOffset;
|
||||
_offsetInfo.vertex = _vertexOffset;
|
||||
return requestStatic(vertexCount, indexCount);
|
||||
}
|
||||
|
||||
const MeshBuffer::OffsetInfo& MeshBuffer::requestStatic(uint32_t vertexCount, uint32_t indexCount)
|
||||
{
|
||||
checkAndSwitchBuffer(vertexCount);
|
||||
|
||||
uint32_t byteOffset = _byteOffset + vertexCount * _bytesPerVertex;
|
||||
uint32_t indexOffset = _indexOffset + indexCount;
|
||||
uint32_t vBytes = _vDataCount * VDATA_BYTE;
|
||||
|
||||
if (byteOffset > vBytes)
|
||||
{
|
||||
_oldVDataCount = _vDataCount;
|
||||
|
||||
while (vBytes < byteOffset)
|
||||
{
|
||||
_vDataCount *= 2;
|
||||
vBytes = _vDataCount * VDATA_BYTE;
|
||||
}
|
||||
|
||||
reallocVBuffer();
|
||||
}
|
||||
|
||||
if (indexOffset > _iDataCount)
|
||||
{
|
||||
_oldIDataCount = _iDataCount;
|
||||
|
||||
while (_iDataCount < indexOffset)
|
||||
{
|
||||
_iDataCount *= 2;
|
||||
}
|
||||
|
||||
reallocIBuffer();
|
||||
}
|
||||
|
||||
updateOffset(vertexCount, indexCount, byteOffset);
|
||||
|
||||
return _offsetInfo;
|
||||
}
|
||||
|
||||
void MeshBuffer::uploadData()
|
||||
{
|
||||
_vb->update(0, vData, _byteOffset);
|
||||
_ib->update(0, iData, _indexOffset * IDATA_BYTE);
|
||||
_dirty = false;
|
||||
}
|
||||
|
||||
void MeshBuffer::switchBuffer(uint32_t vertexCount)
|
||||
{
|
||||
std::size_t offset = ++_vbPos;
|
||||
|
||||
_byteOffset = 0;
|
||||
_vertexOffset = 0;
|
||||
_indexOffset = 0;
|
||||
_indexStart = 0;
|
||||
|
||||
if (offset < _vbArr.size())
|
||||
{
|
||||
_vb = _vbArr.at(offset);
|
||||
_ib = _ibArr.at(offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceGraphics* device = _batcher->getFlow()->getDevice();
|
||||
_vb = VertexBuffer::create(device, _vertexFmt, Usage::DYNAMIC, nullptr, 0, 0);
|
||||
_vbArr.pushBack(_vb);
|
||||
|
||||
_ib = IndexBuffer::create(device, IndexFormat::UINT16, Usage::STATIC, nullptr, 0, 0);
|
||||
_ibArr.pushBack(_ib);
|
||||
}
|
||||
}
|
||||
|
||||
void MeshBuffer::checkAndSwitchBuffer(uint32_t vertexCount)
|
||||
{
|
||||
if (_vertexOffset + vertexCount > MAX_VERTEX_COUNT)
|
||||
{
|
||||
uploadData();
|
||||
_batcher->flush();
|
||||
switchBuffer(vertexCount);
|
||||
}
|
||||
}
|
||||
|
||||
void MeshBuffer::updateOffset (uint32_t vertexCount, uint32_t indiceCount, uint32_t byteOffset)
|
||||
{
|
||||
_offsetInfo.vertex = _vertexOffset;
|
||||
_vertexOffset += vertexCount;
|
||||
|
||||
_offsetInfo.index = _indexOffset;
|
||||
_indexOffset += indiceCount;
|
||||
|
||||
_offsetInfo.vByte = _byteOffset;
|
||||
_byteOffset = byteOffset;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
void MeshBuffer::reset()
|
||||
{
|
||||
_vbPos = 0;
|
||||
_vb = _vbArr.at(0);
|
||||
_ib = _ibArr.at(0);
|
||||
_byteStart = 0;
|
||||
_byteOffset = 0;
|
||||
_vertexStart = 0;
|
||||
_vertexOffset = 0;
|
||||
_indexStart = 0;
|
||||
_indexOffset = 0;
|
||||
_dirty = false;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
189
cocos2d-x/cocos/renderer/scene/MeshBuffer.hpp
Normal file
189
cocos2d-x/cocos/renderer/scene/MeshBuffer.hpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "../gfx/VertexFormat.h"
|
||||
#include "../gfx/VertexBuffer.h"
|
||||
#include "../gfx/IndexBuffer.h"
|
||||
#include "base/CCVector.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class ModelBatcher;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief The buffer which stores mesh render datas, including the vertices data and the indices data.
|
||||
* It can be used as a global buffer shared by multiple render handles and eventually shared by Models
|
||||
*/
|
||||
class MeshBuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief It describes a range of buffer in the global buffer, it contains result when you request the buffer.
|
||||
*/
|
||||
struct OffsetInfo
|
||||
{
|
||||
/** bytes count of the requested buffer */
|
||||
uint32_t vByte = 0;
|
||||
/** offset in index buffer */
|
||||
uint32_t index = 0;
|
||||
/** offset in vertex buffer */
|
||||
uint32_t vertex = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] batcher The ModelBatcher which creates the current buffer
|
||||
* @param[in] fmt The vertex format of vertex data
|
||||
*/
|
||||
MeshBuffer(ModelBatcher* batcher, VertexFormat* fmt);
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~MeshBuffer();
|
||||
|
||||
/**
|
||||
* @brief Requests a range of buffer for the given count of vertices and indices
|
||||
* @param[in] vertexCount Requested count of vertices
|
||||
* @param[in] indexCount Requested count of indices
|
||||
* @param[out] offset The result indicates the allocated buffer range
|
||||
*/
|
||||
const OffsetInfo& request(uint32_t vertexCount, uint32_t indexCount);
|
||||
const OffsetInfo& requestStatic(uint32_t vertexCount, uint32_t indexCount);
|
||||
|
||||
/**
|
||||
* @brief Upload data to GPU memory
|
||||
*/
|
||||
void uploadData();
|
||||
/**
|
||||
* @brief Reset all states.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* @brief Gets the current byte offset which indicates the start of empty range
|
||||
* @return Byte offset.
|
||||
*/
|
||||
uint32_t getByteOffset() const { return _byteOffset; };
|
||||
/**
|
||||
* @brief Gets the current vertex start offset since last time updateOffset is invoked
|
||||
* @return Vertex start.
|
||||
*/
|
||||
uint32_t getVertexStart() const { return _vertexStart; };
|
||||
/**
|
||||
* @brief Gets the current vertex offset, which should equals to total allocated vertex count.
|
||||
* @return Vertex offset.
|
||||
*/
|
||||
uint32_t getVertexOffset() const { return _vertexOffset; };
|
||||
/**
|
||||
* @brief Gets the current index start offset since last time updateOffset is invoked
|
||||
* @return Index start.
|
||||
*/
|
||||
uint32_t getIndexStart() const { return _indexStart; };
|
||||
/**
|
||||
* @brief Gets the current index offset, which should equals to total allocated index count.
|
||||
* @return Index offset.
|
||||
*/
|
||||
uint32_t getIndexOffset() const { return _indexOffset; };
|
||||
|
||||
/**
|
||||
* @brief Update the current allocated offsets to the start offsets.
|
||||
*/
|
||||
void updateOffset()
|
||||
{
|
||||
_byteStart = _byteOffset;
|
||||
_vertexStart = _vertexOffset;
|
||||
_indexStart = _indexOffset;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Gets the vertex buffer.
|
||||
*/
|
||||
VertexBuffer* getVertexBuffer() const { return _vb; };
|
||||
/**
|
||||
* @brief Gets the index buffer.
|
||||
*/
|
||||
IndexBuffer* getIndexBuffer() const { return _ib; };
|
||||
|
||||
/**
|
||||
* @brief The vertex data storage in memory
|
||||
*/
|
||||
float* vData = nullptr;
|
||||
/**
|
||||
* @brief The index data storage in memory
|
||||
*/
|
||||
uint16_t* iData = nullptr;
|
||||
/**
|
||||
* @brief Vertex format of the vertex data.
|
||||
*/
|
||||
VertexFormat* _vertexFmt;
|
||||
|
||||
static const int INIT_VERTEX_COUNT = 4096;
|
||||
static const uint8_t VDATA_BYTE = sizeof(float);
|
||||
static const uint8_t IDATA_BYTE = sizeof(uint16_t);
|
||||
protected:
|
||||
void reallocVBuffer();
|
||||
void reallocIBuffer();
|
||||
void checkAndSwitchBuffer(uint32_t vertexCount);
|
||||
void switchBuffer(uint32_t vertexCount);
|
||||
void updateOffset(uint32_t vertexCount, uint32_t indiceCount, uint32_t byteOffset);
|
||||
private:
|
||||
uint32_t _byteStart = 0;
|
||||
uint32_t _byteOffset = 0;
|
||||
uint32_t _indexStart = 0;
|
||||
uint32_t _indexOffset = 0;
|
||||
uint32_t _vertexStart = 0;
|
||||
uint32_t _vertexOffset = 0;
|
||||
uint32_t _bytesPerVertex = 0;
|
||||
|
||||
uint32_t _vDataCount = 0;
|
||||
uint32_t _iDataCount = 0;
|
||||
|
||||
uint32_t _oldVDataCount = 0;
|
||||
uint32_t _oldIDataCount = 0;
|
||||
|
||||
bool _dirty = false;
|
||||
|
||||
ModelBatcher* _batcher = nullptr;
|
||||
std::size_t _vbPos = 0;
|
||||
cocos2d::Vector<VertexBuffer*> _vbArr;
|
||||
cocos2d::Vector<IndexBuffer*> _ibArr;
|
||||
VertexBuffer* _vb = nullptr;
|
||||
IndexBuffer* _ib = nullptr;
|
||||
OffsetInfo _offsetInfo;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
380
cocos2d-x/cocos/renderer/scene/ModelBatcher.cpp
Normal file
380
cocos2d-x/cocos/renderer/scene/ModelBatcher.cpp
Normal file
@@ -0,0 +1,380 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "RenderFlow.hpp"
|
||||
#include "StencilManager.hpp"
|
||||
#include "assembler/RenderDataList.hpp"
|
||||
#include "NodeProxy.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
#define INIT_MODEL_LENGTH 16
|
||||
|
||||
ModelBatcher::ModelBatcher(RenderFlow* flow)
|
||||
: _flow(flow)
|
||||
, _modelOffset(0)
|
||||
, _cullingMask(0)
|
||||
, _walking(false)
|
||||
, _currEffect(nullptr)
|
||||
, _buffer(nullptr)
|
||||
, _useModel(false)
|
||||
, _node(nullptr)
|
||||
{
|
||||
for (int i = 0; i < INIT_MODEL_LENGTH; i++)
|
||||
{
|
||||
_modelPool.push_back(new Model());
|
||||
}
|
||||
|
||||
_stencilMgr = StencilManager::getInstance();
|
||||
}
|
||||
|
||||
ModelBatcher::~ModelBatcher()
|
||||
{
|
||||
setCurrentEffect(nullptr);
|
||||
setNode(nullptr);
|
||||
|
||||
for (int i = 0; i < _modelPool.size(); i++)
|
||||
{
|
||||
auto model = _modelPool[i];
|
||||
delete model;
|
||||
}
|
||||
_modelPool.clear();
|
||||
|
||||
for (auto iter = _buffers.begin(); iter != _buffers.end(); ++iter)
|
||||
{
|
||||
MeshBuffer *buffer = iter->second;
|
||||
delete buffer;
|
||||
}
|
||||
_buffers.clear();
|
||||
}
|
||||
|
||||
void ModelBatcher::reset()
|
||||
{
|
||||
for (int i = 0; i < _modelOffset; ++i)
|
||||
{
|
||||
Model* model = _modelPool[i];
|
||||
model->reset();
|
||||
}
|
||||
_flow->getRenderScene()->removeModels();
|
||||
_modelOffset = 0;
|
||||
|
||||
for (auto iter : _buffers)
|
||||
{
|
||||
iter.second->reset();
|
||||
}
|
||||
_buffer = nullptr;
|
||||
|
||||
_commitState = CommitState::None;
|
||||
setCurrentEffect(nullptr);
|
||||
setNode(nullptr);
|
||||
_ia.clear();
|
||||
_cullingMask = 0;
|
||||
_walking = false;
|
||||
_useModel = false;
|
||||
|
||||
_modelMat.set(Mat4::IDENTITY);
|
||||
_stencilMgr->reset();
|
||||
}
|
||||
|
||||
void ModelBatcher::changeCommitState(CommitState state)
|
||||
{
|
||||
if (_commitState == state) return;
|
||||
switch(_commitState)
|
||||
{
|
||||
case CommitState::Custom:
|
||||
flushIA();
|
||||
break;
|
||||
case CommitState::Common:
|
||||
flush();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
setCurrentEffect(nullptr);
|
||||
_commitState = state;
|
||||
}
|
||||
|
||||
void ModelBatcher::commit(NodeProxy* node, Assembler* assembler, int cullingMask)
|
||||
{
|
||||
changeCommitState(CommitState::Common);
|
||||
|
||||
bool useModel = assembler->getUseModel();
|
||||
bool ignoreWorldMatrix = assembler->isIgnoreWorldMatrix();
|
||||
|
||||
auto customWorldMat = assembler->getCustomWorldMatrix();
|
||||
customWorldMat = customWorldMat ? customWorldMat : &node->getWorldMatrix();
|
||||
const Mat4& worldMat = useModel && !ignoreWorldMatrix ? *customWorldMat : Mat4::IDENTITY;
|
||||
|
||||
auto asmDirty = assembler->isDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
auto nodeDirty = node->isDirty(RenderFlow::NODE_OPACITY_CHANGED);
|
||||
auto needUpdateOpacity = (asmDirty || nodeDirty) && !assembler->isIgnoreOpacityFlag();
|
||||
|
||||
for (std::size_t i = 0, l = assembler->getIACount(); i < l; ++i)
|
||||
{
|
||||
assembler->beforeFillBuffers(i);
|
||||
|
||||
EffectVariant* effect = assembler->getEffect(i);
|
||||
if (!effect) continue;
|
||||
|
||||
if (_currEffect == nullptr ||
|
||||
_currEffect->getHash() != effect->getHash() ||
|
||||
_cullingMask != cullingMask || useModel)
|
||||
{
|
||||
// Break auto batch
|
||||
flush();
|
||||
|
||||
setNode(_useModel ? node : nullptr);
|
||||
setCurrentEffect(effect);
|
||||
_modelMat.set(worldMat);
|
||||
_useModel = useModel;
|
||||
_cullingMask = cullingMask;
|
||||
}
|
||||
|
||||
if (needUpdateOpacity)
|
||||
{
|
||||
assembler->updateOpacity(i, node->getRealOpacity());
|
||||
}
|
||||
|
||||
assembler->fillBuffers(node, this, i);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelBatcher::commitIA(NodeProxy* node, CustomAssembler* assembler, int cullingMask)
|
||||
{
|
||||
changeCommitState(CommitState::Custom);
|
||||
|
||||
EffectVariant* effect = assembler->getEffect(0);
|
||||
if (!effect) return;
|
||||
|
||||
auto customIA = assembler->getIA(0);
|
||||
if (!customIA) return;
|
||||
|
||||
std::size_t iaCount = assembler->getIACount();
|
||||
bool useModel = assembler->getUseModel();
|
||||
auto customWorldMat = assembler->getCustomWorldMatrix();
|
||||
customWorldMat = customWorldMat ? customWorldMat : &node->getWorldMatrix();
|
||||
const Mat4& worldMat = useModel ? *customWorldMat : Mat4::IDENTITY;
|
||||
|
||||
if (_currEffect == nullptr ||
|
||||
_currEffect->getHash() != effect->getHash() ||
|
||||
_cullingMask != cullingMask || useModel ||
|
||||
!_ia.isMergeable(*customIA))
|
||||
{
|
||||
flushIA();
|
||||
|
||||
setNode(_useModel ? node : nullptr);
|
||||
setCurrentEffect(effect);
|
||||
_modelMat.set(worldMat);
|
||||
_useModel = useModel;
|
||||
_cullingMask = cullingMask;
|
||||
|
||||
_ia.setVertexBuffer(customIA->getVertexBuffer());
|
||||
_ia.setIndexBuffer(customIA->getIndexBuffer());
|
||||
_ia.setStart(customIA->getStart());
|
||||
_ia.setCount(0);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < iaCount; i++ )
|
||||
{
|
||||
customIA = assembler->getIA(i);
|
||||
effect = assembler->getEffect(i);
|
||||
if (!effect) continue;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
flushIA();
|
||||
|
||||
setNode(_useModel ? node : nullptr);
|
||||
setCurrentEffect(effect);
|
||||
_modelMat.set(worldMat);
|
||||
_useModel = useModel;
|
||||
_cullingMask = cullingMask;
|
||||
|
||||
_ia.setVertexBuffer(customIA->getVertexBuffer());
|
||||
_ia.setIndexBuffer(customIA->getIndexBuffer());
|
||||
_ia.setStart(customIA->getStart());
|
||||
_ia.setCount(0);
|
||||
}
|
||||
|
||||
_ia.setCount(_ia.getCount() + customIA->getCount());
|
||||
}
|
||||
}
|
||||
|
||||
void ModelBatcher::flushIA()
|
||||
{
|
||||
if (_commitState != CommitState::Custom)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_walking || !_currEffect || _ia.getCount() <= 0)
|
||||
{
|
||||
_ia.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Stencil manager process
|
||||
_stencilMgr->handleEffect(_currEffect);
|
||||
|
||||
// Generate model
|
||||
Model* model = nullptr;
|
||||
if (_modelOffset >= _modelPool.size())
|
||||
{
|
||||
model = new Model();
|
||||
_modelPool.push_back(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
model = _modelPool[_modelOffset];
|
||||
}
|
||||
_modelOffset++;
|
||||
model->setWorldMatix(_modelMat);
|
||||
model->setCullingMask(_cullingMask);
|
||||
model->setEffect(_currEffect);
|
||||
model->setNode(_node);
|
||||
model->setInputAssembler(_ia);
|
||||
|
||||
_ia.clear();
|
||||
|
||||
_flow->getRenderScene()->addModel(model);
|
||||
}
|
||||
|
||||
void ModelBatcher::flush()
|
||||
{
|
||||
if (_commitState != CommitState::Common)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_walking || !_currEffect || !_buffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int indexStart = _buffer->getIndexStart();
|
||||
int indexOffset = _buffer->getIndexOffset();
|
||||
int indexCount = indexOffset - indexStart;
|
||||
if (indexCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ia.setVertexBuffer(_buffer->getVertexBuffer());
|
||||
_ia.setIndexBuffer(_buffer->getIndexBuffer());
|
||||
_ia.setStart(indexStart);
|
||||
_ia.setCount(indexCount);
|
||||
|
||||
// Stencil manager process
|
||||
_stencilMgr->handleEffect(_currEffect);
|
||||
|
||||
// Generate model
|
||||
Model* model = nullptr;
|
||||
if (_modelOffset >= _modelPool.size())
|
||||
{
|
||||
model = new Model();
|
||||
_modelPool.push_back(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
model = _modelPool[_modelOffset];
|
||||
}
|
||||
_modelOffset++;
|
||||
model->setWorldMatix(_modelMat);
|
||||
model->setCullingMask(_cullingMask);
|
||||
model->setEffect(_currEffect);
|
||||
model->setNode(_node);
|
||||
model->setInputAssembler(_ia);
|
||||
|
||||
_ia.clear();
|
||||
|
||||
_flow->getRenderScene()->addModel(model);
|
||||
|
||||
_buffer->updateOffset();
|
||||
}
|
||||
|
||||
void ModelBatcher::startBatch()
|
||||
{
|
||||
reset();
|
||||
_walking = true;
|
||||
}
|
||||
|
||||
void ModelBatcher::terminateBatch()
|
||||
{
|
||||
flush();
|
||||
flushIA();
|
||||
|
||||
for (auto iter : _buffers)
|
||||
{
|
||||
iter.second->uploadData();
|
||||
}
|
||||
|
||||
_walking = false;
|
||||
}
|
||||
|
||||
void ModelBatcher::setNode(NodeProxy* node)
|
||||
{
|
||||
if (_node == node)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CC_SAFE_RELEASE(_node);
|
||||
_node = node;
|
||||
CC_SAFE_RETAIN(_node);
|
||||
}
|
||||
|
||||
void ModelBatcher::setCurrentEffect(EffectVariant* effect)
|
||||
{
|
||||
if (_currEffect == effect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CC_SAFE_RELEASE(_currEffect);
|
||||
_currEffect = effect;
|
||||
CC_SAFE_RETAIN(_currEffect);
|
||||
};
|
||||
|
||||
MeshBuffer* ModelBatcher::getBuffer(VertexFormat* fmt)
|
||||
{
|
||||
if (_buffer != nullptr && fmt == _buffer->_vertexFmt)
|
||||
{
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
MeshBuffer* buffer = nullptr;
|
||||
auto iter = _buffers.find(fmt);
|
||||
if (iter == _buffers.end())
|
||||
{
|
||||
buffer = new MeshBuffer(this, fmt);
|
||||
_buffers.emplace(fmt, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = iter->second;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
157
cocos2d-x/cocos/renderer/scene/ModelBatcher.hpp
Normal file
157
cocos2d-x/cocos/renderer/scene/ModelBatcher.hpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "assembler/Assembler.hpp"
|
||||
#include "assembler/CustomAssembler.hpp"
|
||||
#include "MeshBuffer.hpp"
|
||||
#include "../renderer/Renderer.h"
|
||||
#include "math/CCMath.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class RenderFlow;
|
||||
class StencilManager;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief ModelBatcher is responsible for transforming node's render handles into final render datas.
|
||||
* It collects render data, batches different render handle together into Models and submits to render Scene.
|
||||
*/
|
||||
class ModelBatcher
|
||||
{
|
||||
public:
|
||||
|
||||
enum CommitState {
|
||||
None,
|
||||
Common,
|
||||
Custom,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The constructor.
|
||||
*/
|
||||
ModelBatcher(RenderFlow* flow);
|
||||
/**
|
||||
* @brief The destructor.
|
||||
*/
|
||||
~ModelBatcher();
|
||||
/**
|
||||
* @brief Reset all render buffer.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* @brief Commit a render handle to the model batcher
|
||||
* @param[in] node The node which owns the render handle
|
||||
* @param[in] handle The render handle contains render datas
|
||||
*/
|
||||
void commit(NodeProxy* node, Assembler* handle, int cullingMask);
|
||||
/**
|
||||
* @brief Commit a custom render handle to the model batcher
|
||||
* @param[in] node The node which owns the render handle
|
||||
* @param[in] handle The custom render handle contains render datas
|
||||
*/
|
||||
void commitIA(NodeProxy* node, CustomAssembler* handle, int cullingMask);
|
||||
|
||||
/**
|
||||
* @brief This method should be invoked before commit any render handles each frame.
|
||||
* It notifies the model batcher to get ready for constructing Models
|
||||
*/
|
||||
void startBatch();
|
||||
/**
|
||||
* @brief Flush all cached render data into a new Model and add the Model to render Scene.
|
||||
*/
|
||||
void flush();
|
||||
/**
|
||||
* @brief Finished Custom input assmebler batch and add the Model to render Scene.
|
||||
*/
|
||||
void flushIA();
|
||||
/**
|
||||
* @brief Add new input assembler into current input assembler.
|
||||
*/
|
||||
void flushIA(InputAssembler* customIA);
|
||||
/**
|
||||
* @brief This method should be invoked after committed all render handles each frame.
|
||||
*/
|
||||
void terminateBatch();
|
||||
|
||||
/**
|
||||
* @brief Gets a suitable MeshBuffer for the given VertexFormat.
|
||||
* Render datas arranged in different VertexFormat can't share the same buffer.
|
||||
* @param[in] fmt The VertexFormat
|
||||
*/
|
||||
MeshBuffer* getBuffer(VertexFormat* fmt);
|
||||
/**
|
||||
* @brief Gets the current MeshBuffer.
|
||||
*/
|
||||
const MeshBuffer* getCurrentBuffer() const { return _buffer; };
|
||||
/**
|
||||
* @brief Sets the current MeshBuffer.
|
||||
* @param[in] buffer
|
||||
*/
|
||||
void setCurrentBuffer(MeshBuffer* buffer) { _buffer = buffer; };
|
||||
/**
|
||||
* @brief Gets the global RenderFlow pointer.
|
||||
*/
|
||||
RenderFlow* getFlow() const { return _flow; };
|
||||
|
||||
void setNode(NodeProxy* node);
|
||||
void setCullingMask(int cullingMask) { _cullingMask = cullingMask; }
|
||||
void setCurrentEffect(EffectVariant* effect);
|
||||
void setUseModel(bool useModel) { _useModel = useModel; }
|
||||
void changeCommitState(CommitState state);
|
||||
private:
|
||||
int _modelOffset = 0;
|
||||
int _cullingMask = 0;
|
||||
bool _useModel = false;
|
||||
bool _walking = false;
|
||||
cocos2d::Mat4 _modelMat;
|
||||
CommitState _commitState = CommitState::None;
|
||||
|
||||
NodeProxy* _node = nullptr;
|
||||
|
||||
MeshBuffer* _buffer = nullptr;
|
||||
EffectVariant* _currEffect = nullptr;
|
||||
RenderFlow* _flow = nullptr;
|
||||
|
||||
StencilManager* _stencilMgr = nullptr;
|
||||
|
||||
InputAssembler _ia;
|
||||
std::vector<Model*> _modelPool;
|
||||
std::unordered_map<VertexFormat*, MeshBuffer*> _buffers;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
186
cocos2d-x/cocos/renderer/scene/NodeMemPool.cpp
Normal file
186
cocos2d-x/cocos/renderer/scene/NodeMemPool.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "NodeMemPool.hpp"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
UnitNode::UnitNode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UnitNode::~UnitNode()
|
||||
{
|
||||
unset(&dirty, (uint8_t**)&dirtyData, &dirtyLen);
|
||||
unset(&trs, (uint8_t**)&trsData, &trsLen);
|
||||
unset(&localMat, (uint8_t**)&localMatData, &localMatLen);
|
||||
unset(&worldMat, (uint8_t**)&worldMatData, &worldMatLen);
|
||||
unset(&parent, (uint8_t**)&parentData, &parentLen);
|
||||
unset(&zOrder, (uint8_t**)&zOrderData, &zOrderLen);
|
||||
unset(&cullingMask, (uint8_t**)&cullingMaskData, &cullingMaskLen);
|
||||
unset(&opacity, (uint8_t**)&opacityData, &opacityLen);
|
||||
unset(&is3D, (uint8_t**)&is3DData, &is3DLen);
|
||||
unset(&node, (uint8_t**)&nodeData, &nodeLen);
|
||||
unset(&skew, (uint8_t**)&skewData, &skewLen);
|
||||
}
|
||||
|
||||
void UnitNode::setDirty(se::Object* jsData)
|
||||
{
|
||||
set(&dirty, (uint8_t**)&dirtyData, &dirtyLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setTRS(se::Object* jsData)
|
||||
{
|
||||
set(&trs, (uint8_t**)&trsData, &trsLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setLocalMat(se::Object* jsData)
|
||||
{
|
||||
set(&localMat, (uint8_t**)&localMatData, &localMatLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setWorldMat(se::Object* jsData)
|
||||
{
|
||||
set(&worldMat, (uint8_t**)&worldMatData, &worldMatLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setParent(se::Object* jsData)
|
||||
{
|
||||
set(&parent, (uint8_t**)&parentData, &parentLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setZOrder(se::Object* jsData)
|
||||
{
|
||||
set(&zOrder, (uint8_t**)&zOrderData, &zOrderLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setCullingMask(se::Object* jsData)
|
||||
{
|
||||
set(&cullingMask, (uint8_t**)&cullingMaskData, &cullingMaskLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setOpacity(se::Object* jsData)
|
||||
{
|
||||
set(&opacity, (uint8_t**)&opacityData, &opacityLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setIs3D(se::Object* jsData)
|
||||
{
|
||||
set(&is3D, (uint8_t**)&is3DData, &is3DLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setNode(se::Object *jsData)
|
||||
{
|
||||
set(&node, (uint8_t**)&nodeData, &nodeLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setSkew(se::Object* jsData)
|
||||
{
|
||||
set(&skew, (uint8_t**)&skewData, &skewLen, jsData);
|
||||
}
|
||||
|
||||
NodeMemPool* NodeMemPool::_instance = nullptr;
|
||||
|
||||
NodeMemPool::NodeMemPool()
|
||||
{
|
||||
_instance = this;
|
||||
}
|
||||
|
||||
NodeMemPool::~NodeMemPool()
|
||||
{
|
||||
for(auto it = _nodePool.begin(); it != _nodePool.end(); it++)
|
||||
{
|
||||
if (*it)
|
||||
{
|
||||
delete (*it);
|
||||
}
|
||||
}
|
||||
_nodePool.clear();
|
||||
_instance = nullptr;
|
||||
}
|
||||
|
||||
const std::vector<UnitNode*>& NodeMemPool::getNodePool() const
|
||||
{
|
||||
return _nodePool;
|
||||
}
|
||||
|
||||
void NodeMemPool::removeNodeData(std::size_t unitID)
|
||||
{
|
||||
CCASSERT(unitID < _nodePool.size(), "NodeMemPool removeNodeData unitID can not be rather than pool size");
|
||||
auto unit = _nodePool[unitID];
|
||||
if (unit)
|
||||
{
|
||||
delete unit;
|
||||
_nodePool[unitID] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
UnitNode* NodeMemPool::getUnit(std::size_t unitID) const
|
||||
{
|
||||
CCASSERT(unitID < _nodePool.size(), "NodeMemPool getUnit unitID can not be rather than pool size");
|
||||
return _nodePool[unitID];
|
||||
}
|
||||
|
||||
void NodeMemPool::updateNodeData(std::size_t unitID, se_object_ptr dirty, se_object_ptr trs, se_object_ptr localMat, se_object_ptr worldMat, se_object_ptr parent, se_object_ptr zOrder, se_object_ptr cullingMask, se_object_ptr opacity, se_object_ptr is3D, se_object_ptr node, se_object_ptr skew)
|
||||
{
|
||||
// UnitID may equal to node pool size, then node pool must increase size.
|
||||
CCASSERT(unitID <= _nodePool.size(), "NodeMemPool updateNodeData unitID can not be rather than pool size");
|
||||
|
||||
UnitNode* unit = nullptr;
|
||||
if (unitID == _nodePool.size())
|
||||
{
|
||||
unit = new UnitNode;
|
||||
_nodePool.push_back(unit);
|
||||
}
|
||||
else if (unitID < _nodePool.size())
|
||||
{
|
||||
unit = _nodePool[unitID];
|
||||
if(!unit)
|
||||
{
|
||||
unit = new UnitNode;
|
||||
_nodePool[unitID] = unit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unit->unitID = unitID;
|
||||
unit->setDirty(dirty);
|
||||
unit->setTRS(trs);
|
||||
unit->setLocalMat(localMat);
|
||||
unit->setWorldMat(worldMat);
|
||||
unit->setParent(parent);
|
||||
unit->setZOrder(zOrder);
|
||||
unit->setCullingMask(cullingMask);
|
||||
unit->setOpacity(opacity);
|
||||
unit->setIs3D(is3D);
|
||||
unit->setNode(node);
|
||||
unit->setSkew(skew);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
196
cocos2d-x/cocos/renderer/scene/NodeMemPool.hpp
Normal file
196
cocos2d-x/cocos/renderer/scene/NodeMemPool.hpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MemPool.hpp"
|
||||
#include "math/Mat4.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class NodeProxy;
|
||||
|
||||
struct TRS {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
float qx = 0.0f;
|
||||
float qy = 0.0f;
|
||||
float qz = 0.0f;
|
||||
float qw = 0.0f;
|
||||
float sx = 0.0f;
|
||||
float sy = 0.0f;
|
||||
float sz = 0.0f;
|
||||
};
|
||||
|
||||
#define PARENT_INVALID 0xffffffff
|
||||
struct ParentInfo {
|
||||
uint32_t unitID = 0;
|
||||
uint32_t index = 0;
|
||||
};
|
||||
|
||||
struct Skew {
|
||||
float_t x = 0.0f;
|
||||
float_t y = 0.0f;
|
||||
};
|
||||
|
||||
class UnitNode: public UnitBase {
|
||||
public:
|
||||
UnitNode();
|
||||
virtual ~UnitNode();
|
||||
void setDirty(se::Object* jsData);
|
||||
void setTRS(se::Object* jsData);
|
||||
void setLocalMat(se::Object* jsData);
|
||||
void setWorldMat(se::Object* jsData);
|
||||
void setParent(se::Object* jsData);
|
||||
void setZOrder(se::Object* jsData);
|
||||
void setCullingMask(se::Object* jsData);
|
||||
void setOpacity(se::Object* jsData);
|
||||
void setIs3D(se::Object* jsData);
|
||||
void setNode(se::Object* jsData);
|
||||
void setLevel(se::Object* jsData);
|
||||
void setSkew(se::Object* jsData);
|
||||
|
||||
uint32_t* getDirty(std::size_t index) const
|
||||
{
|
||||
return dirtyData + index;
|
||||
}
|
||||
|
||||
TRS* getTRS(std::size_t index) const
|
||||
{
|
||||
return (TRS*)trsData + index;
|
||||
}
|
||||
|
||||
cocos2d::Mat4* getLocalMat(std::size_t index) const
|
||||
{
|
||||
return (cocos2d::Mat4*)localMatData + index;
|
||||
}
|
||||
|
||||
cocos2d::Mat4* getWorldMat(std::size_t index) const
|
||||
{
|
||||
return (cocos2d::Mat4*)worldMatData + index;
|
||||
}
|
||||
|
||||
ParentInfo* getParent(std::size_t index) const
|
||||
{
|
||||
return (ParentInfo*)parentData + index;
|
||||
}
|
||||
|
||||
int32_t* getZOrder(std::size_t index) const
|
||||
{
|
||||
return zOrderData + index;
|
||||
}
|
||||
|
||||
int32_t* getCullingMask(std::size_t index) const
|
||||
{
|
||||
return cullingMaskData + index;
|
||||
}
|
||||
|
||||
uint8_t* getOpacity(std::size_t index) const
|
||||
{
|
||||
return opacityData + index;
|
||||
}
|
||||
|
||||
uint8_t* getIs3D(std::size_t index) const
|
||||
{
|
||||
return is3DData + index;
|
||||
}
|
||||
|
||||
uint64_t* getNode(std::size_t index) const
|
||||
{
|
||||
return nodeData + index;
|
||||
}
|
||||
|
||||
Skew* getSkew(std::size_t index) const
|
||||
{
|
||||
return (Skew*)skewData + index;
|
||||
}
|
||||
protected:
|
||||
se::Object* dirty = nullptr;
|
||||
uint32_t* dirtyData = nullptr;
|
||||
std::size_t dirtyLen = 0;
|
||||
|
||||
se::Object* trs = nullptr;
|
||||
float_t* trsData = nullptr;
|
||||
std::size_t trsLen = 0;
|
||||
|
||||
se::Object* localMat = nullptr;
|
||||
float_t* localMatData = nullptr;
|
||||
std::size_t localMatLen = 0;
|
||||
|
||||
se::Object* worldMat = nullptr;
|
||||
float_t* worldMatData = nullptr;
|
||||
std::size_t worldMatLen = 0;
|
||||
|
||||
se::Object* parent = nullptr;
|
||||
uint32_t* parentData = nullptr;
|
||||
std::size_t parentLen = 0;
|
||||
|
||||
se::Object* zOrder = nullptr;
|
||||
int32_t* zOrderData = nullptr;
|
||||
std::size_t zOrderLen = 0;
|
||||
|
||||
se::Object* cullingMask = nullptr;
|
||||
int32_t* cullingMaskData = nullptr;
|
||||
std::size_t cullingMaskLen = 0;
|
||||
|
||||
se::Object* opacity = nullptr;
|
||||
uint8_t* opacityData = nullptr;
|
||||
std::size_t opacityLen = 0;
|
||||
|
||||
se::Object* is3D = nullptr;
|
||||
uint8_t* is3DData = nullptr;
|
||||
std::size_t is3DLen = 0;
|
||||
|
||||
se::Object* node = nullptr;
|
||||
uint64_t* nodeData = nullptr;
|
||||
std::size_t nodeLen = 0;
|
||||
|
||||
se::Object* skew = nullptr;
|
||||
float_t* skewData = nullptr;
|
||||
std::size_t skewLen = 0;
|
||||
};
|
||||
|
||||
class NodeMemPool: public MemPool {
|
||||
public:
|
||||
NodeMemPool();
|
||||
virtual ~NodeMemPool();
|
||||
|
||||
static NodeMemPool* getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void removeNodeData(std::size_t unitID);
|
||||
|
||||
void updateNodeData(std::size_t unitID, se_object_ptr dirty, se_object_ptr trs, se_object_ptr localMat, se_object_ptr worldMat, se_object_ptr parent, se_object_ptr zOrder, se_object_ptr cullingMask, se_object_ptr opacity, se_object_ptr is3D, se_object_ptr node, se_object_ptr skew);
|
||||
|
||||
UnitNode* getUnit(std::size_t unitID) const;
|
||||
const std::vector<UnitNode*>& getNodePool() const;
|
||||
private:
|
||||
static NodeMemPool* _instance;
|
||||
std::vector<UnitNode*> _nodePool;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
587
cocos2d-x/cocos/renderer/scene/NodeProxy.cpp
Normal file
587
cocos2d-x/cocos/renderer/scene/NodeProxy.cpp
Normal file
@@ -0,0 +1,587 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "NodeProxy.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "../renderer/Scene.h"
|
||||
#include "base/ccMacros.h"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
|
||||
#include "cocos/scripting/js-bindings/auto/jsb_renderer_auto.hpp"
|
||||
#include "NodeMemPool.hpp"
|
||||
#include <math.h>
|
||||
#include "RenderFlow.hpp"
|
||||
#include "assembler/AssemblerSprite.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
uint32_t NodeProxy::_globalRenderOrder = 0;
|
||||
|
||||
NodeProxy::NodeProxy(std::size_t unitID, std::size_t index, const std::string& id, const std::string& name)
|
||||
{
|
||||
traverseHandle = render;
|
||||
|
||||
_id = id;
|
||||
_unitID = unitID;
|
||||
_index = index;
|
||||
_name = name;
|
||||
|
||||
NodeMemPool* pool = NodeMemPool::getInstance();
|
||||
CCASSERT(pool, "NodeProxy constructor NodeMemPool is null");
|
||||
UnitNode* unit = pool->getUnit(unitID);
|
||||
CCASSERT(unit, "NodeProxy constructor unit is null");
|
||||
|
||||
UnitCommon* common = pool->getCommonUnit(unitID);
|
||||
_signData = common->getSignData(_index);
|
||||
|
||||
_dirty = unit->getDirty(index);
|
||||
*_dirty &= ~RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
|
||||
_trs = unit->getTRS(index);
|
||||
_localMat = unit->getLocalMat(index);
|
||||
_worldMat = unit->getWorldMat(index);
|
||||
_parentInfo = unit->getParent(index);
|
||||
_parentInfo->unitID = PARENT_INVALID;
|
||||
_parentInfo->index = PARENT_INVALID;
|
||||
_localZOrder = unit->getZOrder(index);
|
||||
_cullingMask = unit->getCullingMask(index);
|
||||
_opacity = unit->getOpacity(index);
|
||||
_is3DNode = unit->getIs3D(index);
|
||||
_skew = unit->getSkew(index);
|
||||
|
||||
uint64_t* self = unit->getNode(index);
|
||||
*self = (uint64_t)this;
|
||||
}
|
||||
|
||||
NodeProxy::~NodeProxy()
|
||||
{
|
||||
for (auto& child : _children)
|
||||
{
|
||||
child->_parent = nullptr;
|
||||
}
|
||||
|
||||
CC_SAFE_RELEASE(_assembler);
|
||||
}
|
||||
|
||||
void NodeProxy::destroyImmediately()
|
||||
{
|
||||
if (_parent)
|
||||
{
|
||||
_parent->removeChild(this);
|
||||
}
|
||||
RenderFlow::getInstance()->removeNodeLevel(_level, _worldMat);
|
||||
CC_SAFE_RELEASE_NULL(_assembler);
|
||||
_level = NODE_LEVEL_INVALID;
|
||||
_dirty = nullptr;
|
||||
_trs = nullptr;
|
||||
_localMat = nullptr;
|
||||
_worldMat = nullptr;
|
||||
_parentInfo = nullptr;
|
||||
_localZOrder = nullptr;
|
||||
_cullingMask = nullptr;
|
||||
_opacity = nullptr;
|
||||
_is3DNode = nullptr;
|
||||
_skew = nullptr;
|
||||
}
|
||||
|
||||
// lazy allocs
|
||||
void NodeProxy::childrenAlloc()
|
||||
{
|
||||
_children.reserve(4);
|
||||
}
|
||||
|
||||
void NodeProxy::addChild(NodeProxy* child)
|
||||
{
|
||||
if (child == nullptr)
|
||||
{
|
||||
CCLOGWARN("Argument must be non-nil");
|
||||
return;
|
||||
}
|
||||
if (child->_parent != nullptr)
|
||||
{
|
||||
CCLOGWARN("child already added. It can't be added again");
|
||||
return;
|
||||
}
|
||||
auto assertNotSelfChild
|
||||
( [ this, child ]() -> bool
|
||||
{
|
||||
for ( NodeProxy* parent( this ); parent != nullptr;
|
||||
parent = parent->getParent() )
|
||||
if ( parent == child )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} );
|
||||
(void)assertNotSelfChild;
|
||||
|
||||
if (!assertNotSelfChild())
|
||||
{
|
||||
CCLOGWARN("A node cannot be the child of his own children" );
|
||||
return;
|
||||
}
|
||||
|
||||
if (_children.empty())
|
||||
{
|
||||
this->childrenAlloc();
|
||||
}
|
||||
_children.pushBack(child);
|
||||
child->setParent(this);
|
||||
}
|
||||
|
||||
void NodeProxy::detachChild(NodeProxy *child, ssize_t childIndex)
|
||||
{
|
||||
// set parent nil at the end
|
||||
child->setParent(nullptr);
|
||||
_children.erase(childIndex);
|
||||
}
|
||||
|
||||
void NodeProxy::removeChild(NodeProxy* child)
|
||||
{
|
||||
// explicit nil handling
|
||||
if (_children.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ssize_t index = _children.getIndex(child);
|
||||
if( index != CC_INVALID_INDEX )
|
||||
this->detachChild( child, index );
|
||||
}
|
||||
|
||||
void NodeProxy::removeAllChildren()
|
||||
{
|
||||
// not using detachChild improves speed here
|
||||
for (const auto& child : _children)
|
||||
{
|
||||
// set parent nil at the end
|
||||
child->setParent(nullptr);
|
||||
}
|
||||
|
||||
_children.clear();
|
||||
}
|
||||
|
||||
NodeProxy* NodeProxy::getChildByName(std::string childName)
|
||||
{
|
||||
for (auto child : _children)
|
||||
{
|
||||
if (child->_name == childName)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NodeProxy* NodeProxy::getChildByID(std::string id)
|
||||
{
|
||||
for (auto child : _children)
|
||||
{
|
||||
if (child->_id == id)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NodeProxy::notifyUpdateParent()
|
||||
{
|
||||
if (_parentInfo->index == PARENT_INVALID)
|
||||
{
|
||||
if (_parent)
|
||||
{
|
||||
_parent->removeChild(this);
|
||||
}
|
||||
updateLevel();
|
||||
return;
|
||||
}
|
||||
|
||||
NodeMemPool* pool = NodeMemPool::getInstance();
|
||||
CCASSERT(pool, "NodeProxy updateParent NodeMemPool is null");
|
||||
UnitNode* unit = pool->getUnit(_parentInfo->unitID);
|
||||
CCASSERT(unit, "NodeProxy updateParent unit is null");
|
||||
uint64_t* parentAddrs = unit->getNode(_parentInfo->index);
|
||||
NodeProxy* parent = (NodeProxy*)*parentAddrs;
|
||||
CCASSERT(parent, "NodeProxy updateParent parent is null");
|
||||
|
||||
if (parent != _parent) {
|
||||
if (_parent)
|
||||
{
|
||||
_parent->removeChild(this);
|
||||
}
|
||||
parent->addChild(this);
|
||||
updateLevel();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateLevel()
|
||||
{
|
||||
static RenderFlow::LevelInfo levelInfo;
|
||||
auto renderFlow = RenderFlow::getInstance();
|
||||
|
||||
renderFlow->removeNodeLevel(_level, _worldMat);
|
||||
|
||||
levelInfo.dirty = _dirty;
|
||||
levelInfo.localMat = _localMat;
|
||||
levelInfo.worldMat = _worldMat;
|
||||
levelInfo.opacity = _opacity;
|
||||
levelInfo.realOpacity = &_realOpacity;
|
||||
|
||||
if (_parent)
|
||||
{
|
||||
_level = _parent->_level + 1;
|
||||
levelInfo.parentWorldMat = _parent->_worldMat;
|
||||
levelInfo.parentDirty = _parent->_dirty;
|
||||
levelInfo.parentRealOpacity = &_parent->_realOpacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
_level = 0;
|
||||
levelInfo.parentWorldMat = nullptr;
|
||||
levelInfo.parentDirty = nullptr;
|
||||
levelInfo.parentRealOpacity = nullptr;
|
||||
}
|
||||
renderFlow->insertNodeLevel(_level, levelInfo);
|
||||
|
||||
for (auto it = _children.begin(); it != _children.end(); it++)
|
||||
{
|
||||
(*it)->updateLevel();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::setLocalZOrder(int zOrder)
|
||||
{
|
||||
if (*_localZOrder != zOrder)
|
||||
{
|
||||
*_localZOrder = zOrder;
|
||||
if (_parent != nullptr)
|
||||
{
|
||||
*_parent->_dirty |= RenderFlow::REORDER_CHILDREN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::reorderChildren()
|
||||
{
|
||||
if (*_dirty & RenderFlow::REORDER_CHILDREN)
|
||||
{
|
||||
#if CC_64BITS
|
||||
std::sort(std::begin(_children), std::end(_children), [](NodeProxy* n1, NodeProxy* n2) {
|
||||
return (*n1->_localZOrder < *n2->_localZOrder);
|
||||
});
|
||||
#else
|
||||
std::stable_sort(std::begin(_children), std::end(_children), [](NodeProxy* n1, NodeProxy* n2) {
|
||||
return *n1->_localZOrder < *n2->_localZOrder;
|
||||
});
|
||||
#endif
|
||||
*_dirty &= ~RenderFlow::REORDER_CHILDREN;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::setAssembler(AssemblerBase* assembler)
|
||||
{
|
||||
if (assembler == _assembler) return;
|
||||
CC_SAFE_RELEASE(_assembler);
|
||||
_assembler = assembler;
|
||||
CC_SAFE_RETAIN(_assembler);
|
||||
|
||||
auto assemblerSprite = dynamic_cast<AssemblerSprite*>(_assembler);
|
||||
if (assemblerSprite)
|
||||
{
|
||||
*_dirty |= RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
}
|
||||
else
|
||||
{
|
||||
*_dirty &= ~RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::clearAssembler()
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(_assembler);
|
||||
*_dirty &= ~RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
}
|
||||
|
||||
AssemblerBase* NodeProxy::getAssembler() const
|
||||
{
|
||||
return _assembler;
|
||||
}
|
||||
|
||||
void NodeProxy::getPosition(cocos2d::Vec3* out) const
|
||||
{
|
||||
out->x = _trs->x;
|
||||
out->y = _trs->y;
|
||||
out->z = _trs->z;
|
||||
}
|
||||
|
||||
void NodeProxy::getRotation(cocos2d::Quaternion* out) const
|
||||
{
|
||||
out->x = _trs->qx;
|
||||
out->y = _trs->qy;
|
||||
out->z = _trs->qz;
|
||||
out->w = _trs->qw;
|
||||
}
|
||||
|
||||
void NodeProxy::getScale(cocos2d::Vec3* out) const
|
||||
{
|
||||
out->x = _trs->sx;
|
||||
out->y = _trs->sy;
|
||||
out->z = _trs->sz;
|
||||
}
|
||||
|
||||
void NodeProxy::getWorldRotation(cocos2d::Quaternion* out) const
|
||||
{
|
||||
getRotation(out);
|
||||
|
||||
cocos2d::Quaternion rot;
|
||||
NodeProxy* curr = _parent;
|
||||
while (curr != nullptr)
|
||||
{
|
||||
curr->getRotation(&rot);
|
||||
Quaternion::multiply(rot, *out, out);
|
||||
curr = curr->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::getWorldPosition(cocos2d::Vec3* out) const
|
||||
{
|
||||
getPosition(out);
|
||||
|
||||
cocos2d::Vec3 pos;
|
||||
cocos2d::Quaternion rot;
|
||||
cocos2d::Vec3 scale;
|
||||
NodeProxy* curr = _parent;
|
||||
while (curr != nullptr)
|
||||
{
|
||||
curr->getPosition(&pos);
|
||||
curr->getRotation(&rot);
|
||||
curr->getScale(&scale);
|
||||
|
||||
out->multiply(scale);
|
||||
out->transformQuat(rot);
|
||||
out->add(pos);
|
||||
curr = curr->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::getWorldRT(cocos2d::Mat4* out) const
|
||||
{
|
||||
cocos2d::Vec3 opos(_trs->x, _trs->y, _trs->z);
|
||||
cocos2d::Quaternion orot(_trs->qx, _trs->qy, _trs->qz, _trs->qw);
|
||||
|
||||
cocos2d::Vec3 pos;
|
||||
cocos2d::Quaternion rot;
|
||||
cocos2d::Vec3 scale;
|
||||
NodeProxy* curr = _parent;
|
||||
while (curr != nullptr)
|
||||
{
|
||||
curr->getPosition(&pos);
|
||||
curr->getRotation(&rot);
|
||||
curr->getScale(&scale);
|
||||
|
||||
opos.multiply(scale);
|
||||
opos.transformQuat(rot);
|
||||
opos.add(pos);
|
||||
Quaternion::multiply(rot, orot, &orot);
|
||||
curr = curr->getParent();
|
||||
}
|
||||
out->setIdentity();
|
||||
out->translate(opos);
|
||||
cocos2d::Mat4 quatMat;
|
||||
cocos2d::Mat4::createRotation(orot, &quatMat);
|
||||
out->multiply(quatMat);
|
||||
}
|
||||
|
||||
void NodeProxy::setOpacity(uint8_t opacity)
|
||||
{
|
||||
if (*_opacity != opacity)
|
||||
{
|
||||
*_opacity = opacity;
|
||||
*_dirty |= RenderFlow::OPACITY;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateRealOpacity()
|
||||
{
|
||||
bool selfOpacityDirty = *_dirty & RenderFlow::OPACITY;
|
||||
if (_parent)
|
||||
{
|
||||
if (selfOpacityDirty || *_parent->_dirty & RenderFlow::NODE_OPACITY_CHANGED)
|
||||
{
|
||||
_realOpacity = *_opacity * _parent->getRealOpacity() / 255.0f;
|
||||
*_dirty &= ~RenderFlow::OPACITY;
|
||||
*_dirty |= RenderFlow::NODE_OPACITY_CHANGED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selfOpacityDirty)
|
||||
{
|
||||
_realOpacity = *_opacity;
|
||||
*_dirty &= ~RenderFlow::OPACITY;
|
||||
*_dirty |= RenderFlow::NODE_OPACITY_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateWorldMatrix()
|
||||
{
|
||||
if (!_updateWorldMatrix) return;
|
||||
|
||||
bool selfWorldDirty = *_dirty & RenderFlow::WORLD_TRANSFORM;
|
||||
if (_parent)
|
||||
{
|
||||
if (selfWorldDirty || *_parent->_dirty & RenderFlow::WORLD_TRANSFORM_CHANGED)
|
||||
{
|
||||
cocos2d::Mat4::multiply(_parent->getWorldMatrix(), *_localMat, _worldMat);
|
||||
*_dirty &= ~RenderFlow::WORLD_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM_CHANGED;
|
||||
}
|
||||
}
|
||||
else if (selfWorldDirty)
|
||||
{
|
||||
*_worldMat = *_localMat;
|
||||
*_dirty &= ~RenderFlow::WORLD_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM_CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateWorldMatrix(const cocos2d::Mat4& worldMatrix)
|
||||
{
|
||||
*_worldMat = worldMatrix;
|
||||
*_dirty &= ~RenderFlow::WORLD_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM_CHANGED;
|
||||
}
|
||||
|
||||
void NodeProxy::updateLocalMatrix()
|
||||
{
|
||||
bool skew = std::abs(_skew->x - 0.0f) > MATH_EPSILON || std::abs(_skew->y - 0.0f) > MATH_EPSILON;
|
||||
if (*_dirty & RenderFlow::LOCAL_TRANSFORM || skew)
|
||||
{
|
||||
_localMat->setIdentity();
|
||||
|
||||
// Transform = Translate * Rotation * Scale;
|
||||
cocos2d::Quaternion q(_trs->qx, _trs->qy, _trs->qz, _trs->qw);
|
||||
if (*_is3DNode)
|
||||
{
|
||||
_localMat->translate(_trs->x, _trs->y, _trs->z);
|
||||
_localMat->rotate(q);
|
||||
_localMat->scale(_trs->sx, _trs->sy, _trs->sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
_localMat->translate(_trs->x, _trs->y, 0);
|
||||
_localMat->rotate(q);
|
||||
_localMat->scale(_trs->sx, _trs->sy, 1);
|
||||
}
|
||||
|
||||
if (skew)
|
||||
{
|
||||
auto& m = _localMat->m;
|
||||
auto a = m[0];
|
||||
auto b = m[1];
|
||||
auto c = m[4];
|
||||
auto d = m[5];
|
||||
auto skx = (float)tanf(CC_DEGREES_TO_RADIANS(_skew->x));
|
||||
auto sky = (float)tanf(CC_DEGREES_TO_RADIANS(_skew->y));
|
||||
m[0] = a + c * sky;
|
||||
m[1] = b + d * sky;
|
||||
m[4] = c + a * skx;
|
||||
m[5] = d + b * skx;
|
||||
}
|
||||
|
||||
*_dirty &= ~RenderFlow::LOCAL_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::render(NodeProxy* node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
node->_renderOrder = _globalRenderOrder++;
|
||||
|
||||
if (!node->_needVisit || node->_realOpacity == 0) return;
|
||||
|
||||
bool needRender = *node->_dirty & RenderFlow::RENDER;
|
||||
if (node->_needRender != needRender)
|
||||
{
|
||||
if (node->_assembler) node->_assembler->enableDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
node->_needRender = needRender;
|
||||
}
|
||||
|
||||
// pre render
|
||||
if (node->_assembler && needRender) node->_assembler->handle(node, batcher, scene);
|
||||
|
||||
node->reorderChildren();
|
||||
for (const auto& child : node->_children)
|
||||
{
|
||||
auto traverseHandle = child->traverseHandle;
|
||||
traverseHandle(child, batcher, scene);
|
||||
}
|
||||
|
||||
// post render
|
||||
bool needPostRender = *(node->_dirty) & RenderFlow::POST_RENDER;
|
||||
if (node->_assembler && needPostRender) node->_assembler->postHandle(node, batcher, scene);
|
||||
}
|
||||
|
||||
void NodeProxy::visit(NodeProxy* node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
node->_renderOrder = _globalRenderOrder++;
|
||||
|
||||
if (!node->_needVisit) return;
|
||||
|
||||
node->updateRealOpacity();
|
||||
|
||||
if (node->_realOpacity == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
node->updateLocalMatrix();
|
||||
node->updateWorldMatrix();
|
||||
|
||||
bool needRender = *(node->_dirty) & RenderFlow::RENDER;
|
||||
if (node->_needRender != needRender)
|
||||
{
|
||||
if (node->_assembler) node->_assembler->enableDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
node->_needRender = needRender;
|
||||
}
|
||||
|
||||
// pre render
|
||||
if (node->_assembler && needRender) node->_assembler->handle(node, batcher, scene);
|
||||
|
||||
node->reorderChildren();
|
||||
for (const auto& child : node->_children)
|
||||
{
|
||||
visit(child, batcher, scene);
|
||||
}
|
||||
|
||||
// post render
|
||||
bool needPostRender = *(node->_dirty) & RenderFlow::POST_RENDER;
|
||||
if (node->_assembler && needPostRender) node->_assembler->postHandle(node, batcher, scene);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
369
cocos2d-x/cocos/renderer/scene/NodeProxy.hpp
Normal file
369
cocos2d-x/cocos/renderer/scene/NodeProxy.hpp
Normal file
@@ -0,0 +1,369 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "base/CCRef.h"
|
||||
#include "base/ccTypes.h"
|
||||
#include "base/CCVector.h"
|
||||
#include "base/CCMap.h"
|
||||
#include "math/CCMath.h"
|
||||
#include "assembler/AssemblerBase.hpp"
|
||||
#include "MemPool.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace se {
|
||||
class Object;
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class ModelBatcher;
|
||||
class Scene;
|
||||
struct TRS;
|
||||
struct ParentInfo;
|
||||
struct Skew;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief NodeProxy is a cpp delegator of js Node.\n
|
||||
* It synchronize the hierarchy from js node tree, update the transform each frame, and manages assembler which represent the render component.\n
|
||||
* JS API: renderer.NodeProxy
|
||||
@code
|
||||
let node = new cc.Node();
|
||||
// NodeProxy is automatically created by cc.Node
|
||||
let proxy = node._proxy;
|
||||
@endcode
|
||||
*/
|
||||
class NodeProxy : public Ref
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(NodeProxy*, ModelBatcher*, Scene*)> TraverseFunc;
|
||||
|
||||
/*
|
||||
* @brief Visit the node but do not transform position.
|
||||
*/
|
||||
static void render(NodeProxy* node, ModelBatcher* batcher, Scene* scene);
|
||||
/*
|
||||
* @brief Visit the node as a ordinary node but not a root node.
|
||||
*/
|
||||
static void visit(NodeProxy* node, ModelBatcher* batcher, Scene* scene);
|
||||
/*
|
||||
* @brief Reset global render order.
|
||||
*/
|
||||
static void resetGlobalRenderOrder() { _globalRenderOrder = 0; }
|
||||
|
||||
/*
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
NodeProxy(std::size_t unitID, std::size_t index, const std::string& id, const std::string& name);
|
||||
/*
|
||||
* @brief The destructor.
|
||||
*/
|
||||
~NodeProxy();
|
||||
/*
|
||||
* @brief destroy node data immediately .
|
||||
*/
|
||||
void destroyImmediately();
|
||||
|
||||
/*
|
||||
* @brief If js node has been destroy.
|
||||
*/
|
||||
bool isValid() { return _trs != nullptr; }
|
||||
|
||||
/// @{
|
||||
/// @name Hierarchy
|
||||
|
||||
/**
|
||||
* @brief Adds child node proxy to the node proxy.
|
||||
* @param[in] child A child node proxy pointer.
|
||||
*/
|
||||
void addChild(NodeProxy * child);
|
||||
/**
|
||||
* @brief Removes child node proxy from the node proxy.
|
||||
* @param[in] child A child node proxy pointer.
|
||||
*/
|
||||
void removeChild(NodeProxy* child);
|
||||
/**
|
||||
* @brief Removes all child node proxies from the current one.
|
||||
*/
|
||||
void removeAllChildren();
|
||||
/**
|
||||
* @brief Update parent by parent unitId and index.
|
||||
*/
|
||||
void notifyUpdateParent();
|
||||
|
||||
/**
|
||||
* @brief Sets the node proxy parent.
|
||||
* @param[in] parent.
|
||||
*/
|
||||
inline void setParent(NodeProxy* parent) { _parent = parent; };
|
||||
/**
|
||||
* @brief Gets the node proxy parent.
|
||||
* @return Parent.
|
||||
*/
|
||||
inline NodeProxy* getParent() const { return _parent; };
|
||||
/**
|
||||
* @brief Gets the node proxy all children.
|
||||
* @return Children container.
|
||||
*/
|
||||
inline const Vector<NodeProxy*>& getChildren() const { return _children; };
|
||||
/**
|
||||
* @brief Gets the node proxy child count.
|
||||
* @return Child count.
|
||||
*/
|
||||
inline size_t getChildrenCount() const { return _children.size(); };
|
||||
/**
|
||||
* @brief Gets a child node by name.
|
||||
* @return Child node.
|
||||
*/
|
||||
NodeProxy* getChildByName(std::string childName);
|
||||
/**
|
||||
* @brief Gets a child node by runtime id.
|
||||
* @return Child node.
|
||||
*/
|
||||
NodeProxy* getChildByID(std::string id);
|
||||
/**
|
||||
* @brief Sets the node proxy's local zorder.
|
||||
* @param[in] zOrder The value of zorder.
|
||||
*/
|
||||
void setLocalZOrder(int zOrder);
|
||||
|
||||
/// @} end of Hierarchy
|
||||
|
||||
/*
|
||||
* @brief Gets the world matrix.
|
||||
* @return World matrix.
|
||||
*/
|
||||
inline const cocos2d::Mat4& getWorldMatrix() const { return *_worldMat; };
|
||||
|
||||
/*
|
||||
* @brief Gets the local matrix.
|
||||
* @return Local matrix.
|
||||
*/
|
||||
inline const cocos2d::Mat4& getLocalMatrix() const { return *_localMat; };
|
||||
|
||||
/*
|
||||
* @brief Gets the position.
|
||||
* @param[out] out The position vector
|
||||
*/
|
||||
void getPosition(cocos2d::Vec3* out) const;
|
||||
/*
|
||||
* @brief Gets the rotation.
|
||||
* @param[out] out The rotation quaternion.
|
||||
*/
|
||||
void getRotation(cocos2d::Quaternion* out) const;
|
||||
/*
|
||||
* @brief Gets the scale.
|
||||
* @param[out] out The scale vector.
|
||||
*/
|
||||
void getScale(cocos2d::Vec3* out) const;
|
||||
/*
|
||||
* @brief Gets world rotation.
|
||||
* @param[out] out The rotation quaternion.
|
||||
*/
|
||||
void getWorldRotation(cocos2d::Quaternion* out) const;
|
||||
/*
|
||||
* @brief Gets the position in world coordinates.
|
||||
* @param[out] out The world position vector.
|
||||
*/
|
||||
void getWorldPosition(cocos2d::Vec3* out) const;
|
||||
/*
|
||||
* @brief Gets the matrix contains the world rotation and translation.
|
||||
* @param[out] out The matrix to store datas.
|
||||
*/
|
||||
void getWorldRT(cocos2d::Mat4* out) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the node's opacity.
|
||||
*/
|
||||
inline uint8_t getOpacity() const { return *_opacity; };
|
||||
/**
|
||||
* @brief Sets the node's opacity.
|
||||
*/
|
||||
void setOpacity(uint8_t opacity);
|
||||
/**
|
||||
* @brief Updates opacity from parent.
|
||||
*/
|
||||
void updateRealOpacity();
|
||||
/**
|
||||
* @brief Gets the node's realOpacity.
|
||||
*/
|
||||
inline const uint8_t getRealOpacity() const {return _realOpacity;};
|
||||
/**
|
||||
* @brief Gets the node's group id, this controls which camera can see the node.
|
||||
*/
|
||||
inline int getCullingMask() const { return *_cullingMask; };
|
||||
/**
|
||||
* @brief Sets the node's group id.
|
||||
* @param[in] groupID The group id
|
||||
*/
|
||||
inline void setCullingMask(int cullingMask) { *_cullingMask = cullingMask; };
|
||||
|
||||
/**
|
||||
* @brief Gets the node's name.
|
||||
* This equals to the one in JS node, helps to debug in cpp.
|
||||
* @return name
|
||||
*/
|
||||
inline const std::string& getName() const { return _name; };
|
||||
/**
|
||||
* @brief Sets the node's name.
|
||||
* The name should be updated once JS node's name changes.
|
||||
* @param[in] name
|
||||
*/
|
||||
inline void setName(const std::string& name) { _name = name; };
|
||||
|
||||
/**
|
||||
* @brief Sets the node's 3D state.
|
||||
* @param[in] is3DNode
|
||||
*/
|
||||
inline void set3DNode(bool is3DNode) { *_is3DNode = is3DNode ? 0x1 : 0x0; };
|
||||
|
||||
/**
|
||||
* @brief Sets a system handle to the node proxy, system handle will be invoked during node's visit process.
|
||||
* @param[in] handle The system handle pointer.
|
||||
*/
|
||||
void setAssembler(AssemblerBase* assembler);
|
||||
/**
|
||||
* @brief Removes a system handle from node proxy by system id.
|
||||
* @param[in] sysid The system id.
|
||||
*/
|
||||
void clearAssembler();
|
||||
/**
|
||||
* @brief Gets the system handle by system id.
|
||||
* @param[in] sysid The system id.
|
||||
* @return The system handle object or nullptr if not exist
|
||||
*/
|
||||
AssemblerBase* getAssembler() const;
|
||||
/*
|
||||
* @brief Enables visit.
|
||||
*/
|
||||
void enableVisit(bool value) { _needVisit = value; }
|
||||
|
||||
/*
|
||||
* @brief Disables visit.
|
||||
*/
|
||||
void disableVisit() { _needVisit = false; }
|
||||
|
||||
/*
|
||||
* @brief Updates local matrix.
|
||||
*/
|
||||
void updateLocalMatrix();
|
||||
/*
|
||||
* @brief Updates world matrix.
|
||||
*/
|
||||
void updateWorldMatrix();
|
||||
/*
|
||||
* @brief Updates world matrix with provide matrix.
|
||||
*/
|
||||
void updateWorldMatrix(const cocos2d::Mat4& worldMatrix);
|
||||
/*
|
||||
* @brief Enables calc world matrix.
|
||||
*/
|
||||
void enableUpdateWorldMatrix(bool value) { _updateWorldMatrix = value; }
|
||||
|
||||
/*
|
||||
* @brief Gets node runtime id
|
||||
*/
|
||||
const std::string& getID() const { return _id; }
|
||||
|
||||
/*
|
||||
* @brief Gets node dirty
|
||||
*/
|
||||
uint32_t* getDirty() const { return _dirty; }
|
||||
|
||||
/*
|
||||
* @brief Is node flag dirty
|
||||
*/
|
||||
bool isDirty(uint32_t flag) const { return *_dirty & flag; }
|
||||
|
||||
/*
|
||||
* @brief Gets render order
|
||||
*/
|
||||
uint32_t getRenderOrder () { return _renderOrder; }
|
||||
|
||||
/*
|
||||
* @brief switch traverse interface to visit
|
||||
*/
|
||||
void switchTraverseToVisit() { traverseHandle = visit; }
|
||||
/*
|
||||
* @brief switch traverse interface to render
|
||||
*/
|
||||
void switchTraverseToRender() { traverseHandle = render; }
|
||||
|
||||
/*
|
||||
* @brief traverse handle
|
||||
*/
|
||||
TraverseFunc traverseHandle = nullptr;
|
||||
protected:
|
||||
void updateLevel();
|
||||
void childrenAlloc();
|
||||
void detachChild(NodeProxy* child, ssize_t childIndex);
|
||||
void reorderChildren();
|
||||
private:
|
||||
bool _needVisit = true;
|
||||
bool _updateWorldMatrix = true;
|
||||
bool _needRender = false;
|
||||
|
||||
uint8_t _realOpacity = 255;
|
||||
std::string _id = "";
|
||||
std::string _name = "";
|
||||
std::size_t _level = 0;
|
||||
|
||||
uint32_t* _dirty = nullptr;
|
||||
TRS* _trs = nullptr;
|
||||
cocos2d::Mat4* _localMat = nullptr;
|
||||
cocos2d::Mat4* _worldMat = nullptr;
|
||||
ParentInfo* _parentInfo = nullptr;
|
||||
int32_t* _localZOrder = nullptr;
|
||||
int32_t* _cullingMask = nullptr;
|
||||
uint8_t* _opacity = nullptr;
|
||||
uint8_t* _is3DNode = nullptr;
|
||||
Skew* _skew = nullptr;
|
||||
|
||||
std::size_t _unitID = 0;
|
||||
std::size_t _index = 0;
|
||||
|
||||
Sign* _signData = nullptr;
|
||||
NodeProxy* _parent = nullptr; ///< weak reference to parent node
|
||||
cocos2d::Vector<NodeProxy*> _children; ///< array of children nodes
|
||||
|
||||
AssemblerBase* _assembler = nullptr;
|
||||
|
||||
uint32_t _renderOrder = 0;
|
||||
static uint32_t _globalRenderOrder;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
176
cocos2d-x/cocos/renderer/scene/ParallelTask.cpp
Normal file
176
cocos2d-x/cocos/renderer/scene/ParallelTask.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "ParallelTask.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
ParallelTask::ParallelTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ParallelTask::~ParallelTask()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void ParallelTask::init(int threadNum)
|
||||
{
|
||||
_finished = false;
|
||||
_threadNum = threadNum;
|
||||
|
||||
_tasks.resize(_threadNum);
|
||||
_threads.resize(_threadNum);
|
||||
_runFlags = new uint8_t[_threadNum];
|
||||
memset(_runFlags, RunFlag::Stop, sizeof(uint8_t) * _threadNum);
|
||||
|
||||
for(auto i = 0; i < _threadNum; i++)
|
||||
{
|
||||
setThread(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelTask::pushTask(int tid, const Task& task)
|
||||
{
|
||||
if (tid >= 0 && tid < _tasks.size())
|
||||
{
|
||||
_tasks[tid].push_back(task);
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelTask::clearTasks()
|
||||
{
|
||||
for(std::size_t i = 0, n = _tasks.size(); i < n; i++)
|
||||
{
|
||||
_tasks[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* ParallelTask::getRunFlag()
|
||||
{
|
||||
return _runFlags;
|
||||
}
|
||||
|
||||
void ParallelTask::destroy()
|
||||
{
|
||||
_finished = true;
|
||||
beginAllThreads();
|
||||
for (int i = 0, n = (int)_threads.size(); i < n; ++i)
|
||||
{
|
||||
joinThread(i);
|
||||
}
|
||||
_tasks.clear();
|
||||
_threads.clear();
|
||||
delete _runFlags;
|
||||
_runFlags = nullptr;
|
||||
_threadNum = 0;
|
||||
}
|
||||
|
||||
void ParallelTask::stopAllThreads()
|
||||
{
|
||||
if (!_runFlags) return;
|
||||
memset(_runFlags, RunFlag::Stop, sizeof(uint8_t) * _threadNum);
|
||||
}
|
||||
|
||||
void ParallelTask::beginAllThreads()
|
||||
{
|
||||
if (!_runFlags) return;
|
||||
memset(_runFlags, RunFlag::Begin, sizeof(uint8_t) * _threadNum);
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cv.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelTask::waitAllThreads()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cv.wait(lock, [this]() {
|
||||
if (!_runFlags) return true;
|
||||
for (auto i = 0; i < _threadNum; i++)
|
||||
{
|
||||
if (_runFlags[i] == RunFlag::Begin) return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void ParallelTask::joinThread(int tid)
|
||||
{
|
||||
if (tid < 0 || tid >= (int)_threads.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_threads[tid]->joinable())
|
||||
{
|
||||
_threads[tid]->join();
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelTask::setThread(int tid)
|
||||
{
|
||||
auto f = [this, tid]() {
|
||||
uint8_t& runFlag = _runFlags[tid];
|
||||
if (!runFlag) return;
|
||||
|
||||
auto& taskQueue = _tasks[tid];
|
||||
std::size_t idx = 0;
|
||||
std::size_t taskCount = 0;
|
||||
|
||||
while (!_finished)
|
||||
{
|
||||
switch (runFlag)
|
||||
{
|
||||
case RunFlag::Begin:
|
||||
for (idx = 0, taskCount = taskQueue.size(); idx < taskCount; idx++)
|
||||
{
|
||||
const Task& task = taskQueue[idx];
|
||||
task(tid);
|
||||
}
|
||||
runFlag = RunFlag::Stop;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cv.notify_all();
|
||||
}
|
||||
break;
|
||||
case RunFlag::Stop:
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cv.wait(lock, [this, &runFlag]()
|
||||
{
|
||||
return runFlag == RunFlag::Begin || _finished;
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
_threads[tid].reset(new(std::nothrow) std::thread(f));
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
78
cocos2d-x/cocos/renderer/scene/ParallelTask.hpp
Normal file
78
cocos2d-x/cocos/renderer/scene/ParallelTask.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class ParallelTask
|
||||
{
|
||||
public:
|
||||
|
||||
enum RunFlag{
|
||||
Begin = 0x00,
|
||||
Stop = 0x01,
|
||||
};
|
||||
|
||||
typedef std::function<void(int)> Task;
|
||||
|
||||
ParallelTask();
|
||||
virtual ~ParallelTask();
|
||||
|
||||
void pushTask(int tid, const Task& task);
|
||||
void clearTasks();
|
||||
|
||||
uint8_t* getRunFlag();
|
||||
|
||||
void init(int threadNum);
|
||||
void destroy();
|
||||
|
||||
void waitAllThreads();
|
||||
void stopAllThreads();
|
||||
void beginAllThreads();
|
||||
private:
|
||||
void joinThread(int tid);
|
||||
void setThread(int tid);
|
||||
private:
|
||||
std::vector<std::vector<Task>> _tasks;
|
||||
std::vector<std::unique_ptr<std::thread>> _threads;
|
||||
|
||||
uint8_t* _runFlags = nullptr;
|
||||
bool _finished = false;
|
||||
int _threadNum = 0;
|
||||
|
||||
std::mutex _mutex;
|
||||
std::condition_variable _cv;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
379
cocos2d-x/cocos/renderer/scene/RenderFlow.cpp
Normal file
379
cocos2d-x/cocos/renderer/scene/RenderFlow.cpp
Normal file
@@ -0,0 +1,379 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "RenderFlow.hpp"
|
||||
#include "NodeMemPool.hpp"
|
||||
#include "assembler/AssemblerSprite.hpp"
|
||||
|
||||
#if USE_MIDDLEWARE
|
||||
#include "MiddlewareManager.h"
|
||||
#endif
|
||||
|
||||
#define SUB_RENDER_THREAD_COUNT 1
|
||||
#define RENDER_THREAD_COUNT (SUB_RENDER_THREAD_COUNT + 1)
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
const uint32_t InitLevelCount = 3;
|
||||
const uint32_t InitLevelNodeCount = 100;
|
||||
|
||||
const uint32_t LocalMat_Use_Thread_Unit_Count = 5;
|
||||
const uint32_t WorldMat_Use_Thread_Node_count = 500;
|
||||
|
||||
RenderFlow* RenderFlow::_instance = nullptr;
|
||||
|
||||
RenderFlow::RenderFlow(DeviceGraphics* device, Scene* scene, ForwardRenderer* forward)
|
||||
: _device(device)
|
||||
, _scene(scene)
|
||||
, _forward(forward)
|
||||
{
|
||||
_instance = this;
|
||||
|
||||
_batcher = new ModelBatcher(this);
|
||||
|
||||
#if SUB_RENDER_THREAD_COUNT > 0
|
||||
_paralleTask = new ParallelTask();
|
||||
_paralleTask->init(SUB_RENDER_THREAD_COUNT);
|
||||
|
||||
for (uint32_t i = 0; i < SUB_RENDER_THREAD_COUNT; i++)
|
||||
{
|
||||
_paralleTask->pushTask(i, [this](int tid){
|
||||
switch(_parallelStage)
|
||||
{
|
||||
case ParallelStage::LOCAL_MAT:
|
||||
calculateLocalMatrix(tid);
|
||||
break;
|
||||
case ParallelStage::WORLD_MAT:
|
||||
calculateLevelWorldMatrix(tid, _parallelStage);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
_levelInfoArr.resize(InitLevelCount);
|
||||
for (auto i = 0; i < InitLevelCount; i++)
|
||||
{
|
||||
_levelInfoArr[i].reserve(InitLevelNodeCount);
|
||||
}
|
||||
}
|
||||
|
||||
RenderFlow::~RenderFlow()
|
||||
{
|
||||
CC_SAFE_DELETE(_paralleTask);
|
||||
CC_SAFE_DELETE(_batcher);
|
||||
}
|
||||
|
||||
void RenderFlow::removeNodeLevel(std::size_t level, cocos2d::Mat4* worldMat)
|
||||
{
|
||||
if (level >= _levelInfoArr.size()) return;
|
||||
auto& levelInfos = _levelInfoArr[level];
|
||||
for(auto it = levelInfos.begin(); it != levelInfos.end(); it++)
|
||||
{
|
||||
if (it->worldMat == worldMat)
|
||||
{
|
||||
levelInfos.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::insertNodeLevel(std::size_t level, const LevelInfo& levelInfo)
|
||||
{
|
||||
if (level >= _levelInfoArr.size())
|
||||
{
|
||||
_levelInfoArr.resize(level + 1);
|
||||
}
|
||||
auto& levelInfos = _levelInfoArr[level];
|
||||
levelInfos.push_back(levelInfo);
|
||||
}
|
||||
|
||||
void RenderFlow::calculateLocalMatrix(int tid)
|
||||
{
|
||||
const uint16_t SPACE_FREE_FLAG = 0x0;
|
||||
cocos2d::Mat4 matTemp;
|
||||
|
||||
NodeMemPool* instance = NodeMemPool::getInstance();
|
||||
CCASSERT(instance, "RenderFlow calculateLocalMatrix NodeMemPool is null");
|
||||
auto& commonList = instance->getCommonList();
|
||||
auto& nodePool = instance->getNodePool();
|
||||
|
||||
UnitCommon* commonUnit = nullptr;
|
||||
uint16_t usingNum = 0;
|
||||
std::size_t contentNum = 0;
|
||||
Sign* signData = nullptr;
|
||||
UnitNode* nodeUnit = nullptr;
|
||||
uint32_t* dirty = nullptr;
|
||||
cocos2d::Mat4* localMat = nullptr;
|
||||
TRS* trs = nullptr;
|
||||
uint8_t* is3D = nullptr;
|
||||
cocos2d::Quaternion* quat = nullptr;
|
||||
float trsZ = 0.0f, trsSZ = 0.0f;
|
||||
|
||||
std::size_t begin = 0, end = commonList.size();
|
||||
std::size_t fieldSize = end / RENDER_THREAD_COUNT;
|
||||
if (tid >= 0)
|
||||
{
|
||||
begin = tid * fieldSize;
|
||||
if (tid < RENDER_THREAD_COUNT - 1)
|
||||
{
|
||||
end = (tid + 1) * fieldSize;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto i = begin; i < end; i++)
|
||||
{
|
||||
commonUnit = commonList[i];
|
||||
if (!commonUnit) continue;
|
||||
usingNum = commonUnit->getUsingNum();
|
||||
if (usingNum == 0) continue;
|
||||
|
||||
contentNum = commonUnit->getContentNum();
|
||||
signData = commonUnit->getSignData(0);
|
||||
|
||||
nodeUnit = nodePool[commonUnit->unitID];
|
||||
|
||||
dirty = nodeUnit->getDirty(0);
|
||||
localMat = nodeUnit->getLocalMat(0);
|
||||
trs = nodeUnit->getTRS(0);
|
||||
is3D = nodeUnit->getIs3D(0);
|
||||
|
||||
NodeProxy** nodeProxy = (NodeProxy**)nodeUnit->getNode(0);
|
||||
|
||||
for (auto j = 0; j < contentNum; j++, localMat ++, trs ++, is3D ++, signData++, dirty++, nodeProxy++)
|
||||
{
|
||||
if (signData->freeFlag == SPACE_FREE_FLAG) continue;
|
||||
|
||||
// reset world transform changed flag
|
||||
*dirty &= ~(WORLD_TRANSFORM_CHANGED | NODE_OPACITY_CHANGED);
|
||||
if (!(*dirty & LOCAL_TRANSFORM)) continue;
|
||||
|
||||
localMat->setIdentity();
|
||||
trsZ = *is3D ? trs->z : 0;
|
||||
localMat->translate(trs->x, trs->y, trsZ);
|
||||
|
||||
quat = (cocos2d::Quaternion*)&(trs->qx);
|
||||
cocos2d::Mat4::createRotation(*quat, &matTemp);
|
||||
cocos2d::Mat4::multiply(*localMat, matTemp, localMat);
|
||||
|
||||
trsSZ = *is3D ? trs->sz : 1;
|
||||
cocos2d::Mat4::createScale(trs->sx, trs->sy, trsSZ, &matTemp);
|
||||
cocos2d::Mat4::multiply(*localMat, matTemp, localMat);
|
||||
|
||||
*dirty &= ~LOCAL_TRANSFORM;
|
||||
*dirty |= WORLD_TRANSFORM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::calculateLevelWorldMatrix(int tid, int stage)
|
||||
{
|
||||
if (_curLevel >= _levelInfoArr.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& levelInfos = _levelInfoArr[_curLevel];
|
||||
|
||||
std::size_t begin = 0, end = levelInfos.size();
|
||||
std::size_t fieldSize = end / RENDER_THREAD_COUNT;
|
||||
if (tid >= 0)
|
||||
{
|
||||
begin = tid * fieldSize;
|
||||
if (tid < RENDER_THREAD_COUNT - 1)
|
||||
{
|
||||
end = (tid + 1) * fieldSize;
|
||||
}
|
||||
}
|
||||
|
||||
for(std::size_t index = begin; index < end; index++)
|
||||
{
|
||||
auto& info = levelInfos[index];
|
||||
auto dirty = info.dirty;
|
||||
auto parentDirty = info.parentDirty;
|
||||
auto selfWorldDirty = *dirty & WORLD_TRANSFORM;
|
||||
auto selfOpacityDirty = *dirty & OPACITY;
|
||||
|
||||
if (parentDirty)
|
||||
{
|
||||
if ((*parentDirty & WORLD_TRANSFORM_CHANGED) || selfWorldDirty)
|
||||
{
|
||||
cocos2d::Mat4::multiply(*info.parentWorldMat, *info.localMat, info.worldMat);
|
||||
*dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if ((*parentDirty & NODE_OPACITY_CHANGED) || selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity * *info.parentRealOpacity / 255.0f;
|
||||
*dirty |= NODE_OPACITY_CHANGED;
|
||||
*dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selfWorldDirty)
|
||||
{
|
||||
*info.worldMat = *info.localMat;
|
||||
*dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if (selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity;
|
||||
*dirty |= NODE_OPACITY_CHANGED;
|
||||
*dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::calculateWorldMatrix()
|
||||
{
|
||||
for(std::size_t level = 0, n = _levelInfoArr.size(); level < n; level++)
|
||||
{
|
||||
auto& levelInfos = _levelInfoArr[level];
|
||||
for(std::size_t index = 0, count = levelInfos.size(); index < count; index++)
|
||||
{
|
||||
auto& info = levelInfos[index];
|
||||
auto selfWorldDirty = *info.dirty & WORLD_TRANSFORM;
|
||||
auto selfOpacityDirty = *info.dirty & OPACITY;
|
||||
|
||||
if (info.parentDirty)
|
||||
{
|
||||
if ((*info.parentDirty & WORLD_TRANSFORM_CHANGED) || selfWorldDirty)
|
||||
{
|
||||
cocos2d::Mat4::multiply(*info.parentWorldMat, *info.localMat, info.worldMat);
|
||||
*info.dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*info.dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if ((*info.parentDirty & NODE_OPACITY_CHANGED) || selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity * *info.parentRealOpacity / 255.0f;
|
||||
*info.dirty |= NODE_OPACITY_CHANGED;
|
||||
*info.dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selfWorldDirty)
|
||||
{
|
||||
*info.worldMat = *info.localMat;
|
||||
*info.dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*info.dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if (selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity;
|
||||
*info.dirty |= NODE_OPACITY_CHANGED;
|
||||
*info.dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::render(NodeProxy* scene, float deltaTime, Camera *camera)
|
||||
{
|
||||
if (scene != nullptr)
|
||||
{
|
||||
|
||||
#if USE_MIDDLEWARE
|
||||
// udpate middleware before render
|
||||
middleware::MiddlewareManager::getInstance()->update(deltaTime);
|
||||
#endif
|
||||
|
||||
#if SUB_RENDER_THREAD_COUNT > 0
|
||||
|
||||
int mainThreadTid = RENDER_THREAD_COUNT - 1;
|
||||
|
||||
NodeMemPool* instance = NodeMemPool::getInstance();
|
||||
auto& commonList = instance->getCommonList();
|
||||
if (commonList.size() < LocalMat_Use_Thread_Unit_Count)
|
||||
{
|
||||
_parallelStage = ParallelStage::NONE;
|
||||
calculateLocalMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
_parallelStage = ParallelStage::LOCAL_MAT;
|
||||
_paralleTask->beginAllThreads();
|
||||
calculateLocalMatrix(mainThreadTid);
|
||||
_paralleTask->waitAllThreads();
|
||||
}
|
||||
|
||||
_curLevel = 0;
|
||||
for(auto count = _levelInfoArr.size(); _curLevel < count; _curLevel++)
|
||||
{
|
||||
auto& levelInfos = _levelInfoArr[_curLevel];
|
||||
if (levelInfos.size() < WorldMat_Use_Thread_Node_count)
|
||||
{
|
||||
_parallelStage = ParallelStage::NONE;
|
||||
calculateLevelWorldMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
_parallelStage = ParallelStage::WORLD_MAT;
|
||||
_paralleTask->beginAllThreads();
|
||||
calculateLevelWorldMatrix(mainThreadTid);
|
||||
_paralleTask->waitAllThreads();
|
||||
}
|
||||
}
|
||||
#else
|
||||
calculateLocalMatrix();
|
||||
calculateWorldMatrix();
|
||||
#endif
|
||||
|
||||
_batcher->startBatch();
|
||||
|
||||
#if USE_MIDDLEWARE
|
||||
// render middleware
|
||||
middleware::MiddlewareManager::getInstance()->render(deltaTime);
|
||||
#endif
|
||||
scene->resetGlobalRenderOrder();
|
||||
|
||||
auto traverseHandle = scene->traverseHandle;
|
||||
traverseHandle(scene, _batcher, _scene);
|
||||
_batcher->terminateBatch();
|
||||
|
||||
if (camera) {
|
||||
_forward->renderCamera(camera, _scene);
|
||||
}
|
||||
else {
|
||||
_forward->render(_scene, deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::visit(NodeProxy* rootNode)
|
||||
{
|
||||
NodeProxy::visit(rootNode, _batcher, _scene);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
180
cocos2d-x/cocos/renderer/scene/RenderFlow.hpp
Normal file
180
cocos2d-x/cocos/renderer/scene/RenderFlow.hpp
Normal file
@@ -0,0 +1,180 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "NodeProxy.hpp"
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "../renderer/Scene.h"
|
||||
#include "../renderer/ForwardRenderer.h"
|
||||
#include "../gfx/DeviceGraphics.h"
|
||||
#include "ParallelTask.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This class is responsible for the rendering process.\n
|
||||
* It visits the node tree, let nodes commit their render handles, starts the device level rendering process with ForwardRenderer.\n
|
||||
* JS API: renderer.RenderFlow
|
||||
@code
|
||||
// You actually shouldn't create RenderFlow by yourself, you can
|
||||
let renderFlow = cc.RenderFlow._nativeFlow;
|
||||
@endcode
|
||||
*/
|
||||
|
||||
#define NODE_LEVEL_INVALID 0xffffffff
|
||||
|
||||
class RenderFlow
|
||||
{
|
||||
public:
|
||||
|
||||
enum RenderFlowFlag {
|
||||
// sync js render flag
|
||||
|
||||
DONOTHING = 1 << 0,
|
||||
BREAK_FLOW = 1 << 1,
|
||||
LOCAL_TRANSFORM = 1 << 2,
|
||||
WORLD_TRANSFORM = 1 << 3,
|
||||
TRANSFORM = LOCAL_TRANSFORM | WORLD_TRANSFORM,
|
||||
UPDATE_RENDER_DATA = 1 << 4,
|
||||
OPACITY = 1 << 5,
|
||||
COLOR = 1 << 6,
|
||||
RENDER = 1 << 7,
|
||||
CHILDREN = 1 << 8,
|
||||
POST_RENDER = 1 << 9,
|
||||
FINAL = 1 << 10,
|
||||
|
||||
PRE_CALCULATE_VERTICES = 1 << 28,
|
||||
// native render flag
|
||||
REORDER_CHILDREN = 1 << 29,
|
||||
// world matrix changed
|
||||
WORLD_TRANSFORM_CHANGED = 1 << 30,
|
||||
// cascade opacity changed
|
||||
NODE_OPACITY_CHANGED = 1 << 31,
|
||||
};
|
||||
|
||||
enum ParallelStage {
|
||||
NONE = 1 << 0,
|
||||
LOCAL_MAT = 1 << 1,
|
||||
WORLD_MAT = 1 << 2,
|
||||
CALC_VERTICES = 1 << 3,
|
||||
};
|
||||
|
||||
struct LevelInfo{
|
||||
uint32_t* dirty = nullptr;
|
||||
uint32_t* parentDirty = nullptr;
|
||||
cocos2d::Mat4* parentWorldMat = nullptr;
|
||||
uint8_t* parentRealOpacity = nullptr;
|
||||
cocos2d::Mat4* localMat = nullptr;
|
||||
cocos2d::Mat4* worldMat = nullptr;
|
||||
uint8_t* opacity = nullptr;
|
||||
uint8_t* realOpacity = nullptr;
|
||||
};
|
||||
|
||||
static RenderFlow *getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief The constructor.
|
||||
* @param[in] device
|
||||
* @param[in] scene
|
||||
* @param[in] forward
|
||||
*/
|
||||
RenderFlow(DeviceGraphics* device, Scene* scene, ForwardRenderer* forward);
|
||||
/*
|
||||
* @brief The destructor.
|
||||
*/
|
||||
~RenderFlow();
|
||||
|
||||
/*
|
||||
* @brief Gets the ModelBatcher which is responsible for collecting render Models.
|
||||
*/
|
||||
ModelBatcher* getModelBatcher() const { return _batcher; };
|
||||
/*
|
||||
* @brief Gets the DeviceGraphics using by the current RenderFlow.
|
||||
*/
|
||||
DeviceGraphics* getDevice() const { return _device; };
|
||||
/*
|
||||
* @brief Gets the render Scene which manages all render Models.
|
||||
*/
|
||||
Scene* getRenderScene() const { return _scene; };
|
||||
/**
|
||||
* @brief Render the scene specified by its root node.
|
||||
* @param[in] scene The root node.
|
||||
*/
|
||||
void render(NodeProxy* scene, float deltaTime, Camera *camera = nullptr);
|
||||
/**
|
||||
* @brief Visit a node tree.
|
||||
*/
|
||||
void visit(NodeProxy* rootNode);
|
||||
/**
|
||||
* @brief Calculate local matrix.
|
||||
* @param[in] tid It must rather than -1 if enable multiple thread.
|
||||
*/
|
||||
void calculateLocalMatrix(int tid = -1);
|
||||
/**
|
||||
* @brief Calculate world matrix.
|
||||
*/
|
||||
void calculateWorldMatrix();
|
||||
/**
|
||||
* @brief Calculate world matrix by level.
|
||||
* @param[in] tid Thread id.
|
||||
* @param[level] level Node level.
|
||||
*/
|
||||
void calculateLevelWorldMatrix(int tid = -1, int stage = -1);
|
||||
/**
|
||||
* @brief remove node level
|
||||
*/
|
||||
void removeNodeLevel(std::size_t level, cocos2d::Mat4* worldMat);
|
||||
/**
|
||||
* @brief insert node level
|
||||
*/
|
||||
void insertNodeLevel(std::size_t level, const LevelInfo& levelInfo);
|
||||
private:
|
||||
|
||||
static RenderFlow *_instance;
|
||||
|
||||
ModelBatcher* _batcher = nullptr;
|
||||
Scene* _scene = nullptr;
|
||||
DeviceGraphics* _device = nullptr;
|
||||
ForwardRenderer* _forward = nullptr;
|
||||
std::size_t _curLevel = 0;
|
||||
std::vector<std::vector<LevelInfo>> _levelInfoArr;
|
||||
|
||||
ParallelStage _parallelStage = ParallelStage::NONE;
|
||||
ParallelTask* _paralleTask = nullptr;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
184
cocos2d-x/cocos/renderer/scene/StencilManager.cpp
Normal file
184
cocos2d-x/cocos/renderer/scene/StencilManager.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "StencilManager.hpp"
|
||||
#include "../Types.h"
|
||||
#include "../renderer/Technique.h"
|
||||
#include "../renderer/Pass.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
static const std::string techStage = "opaque";
|
||||
StencilManager* StencilManager::_instance = nullptr;
|
||||
|
||||
StencilManager::StencilManager ()
|
||||
: _stage(Stage::DISABLED)
|
||||
{
|
||||
}
|
||||
|
||||
StencilManager::~StencilManager ()
|
||||
{
|
||||
}
|
||||
|
||||
void StencilManager::reset ()
|
||||
{
|
||||
// reset stack and stage
|
||||
_maskStack.clear();
|
||||
_stage = Stage::DISABLED;
|
||||
}
|
||||
|
||||
EffectVariant* StencilManager::handleEffect (EffectVariant* effect)
|
||||
{
|
||||
Vector<Pass*>& passes = (Vector<Pass*>&)effect->getPasses();
|
||||
if (_stage == Stage::DISABLED)
|
||||
{
|
||||
for (const auto& pass : passes)
|
||||
{
|
||||
if (pass->isStencilTest()) {
|
||||
pass->disableStencilTest();
|
||||
}
|
||||
}
|
||||
return effect;
|
||||
}
|
||||
|
||||
auto size = _maskStack.size();
|
||||
if (size == 0 || size == size_t(-1))
|
||||
{
|
||||
return effect;
|
||||
}
|
||||
|
||||
uint32_t ref;
|
||||
uint8_t stencilMask, writeMask;
|
||||
bool mask;
|
||||
StencilFunc func;
|
||||
StencilOp failOp = StencilOp::KEEP;
|
||||
const StencilOp& zFailOp = StencilOp::KEEP;
|
||||
const StencilOp& zPassOp = StencilOp::KEEP;
|
||||
|
||||
if (_stage == Stage::ENABLED)
|
||||
{
|
||||
mask = _maskStack.back();
|
||||
func = StencilFunc::EQUAL;
|
||||
failOp = StencilOp::KEEP;
|
||||
ref = getStencilRef();
|
||||
stencilMask = ref;
|
||||
writeMask = getWriteMask();
|
||||
}
|
||||
else {
|
||||
if (_stage == Stage::CLEAR) {
|
||||
mask = _maskStack.back();
|
||||
func = StencilFunc::NEVER;
|
||||
failOp = mask ? StencilOp::REPLACE : StencilOp::ZERO;
|
||||
ref = getWriteMask();
|
||||
stencilMask = ref;
|
||||
writeMask = ref;
|
||||
}
|
||||
else if (_stage == Stage::ENTER_LEVEL) {
|
||||
mask = _maskStack.back();
|
||||
// Fill stencil mask
|
||||
func = StencilFunc::NEVER;
|
||||
failOp = mask ? StencilOp::ZERO : StencilOp::REPLACE;
|
||||
ref = getWriteMask();
|
||||
stencilMask = ref;
|
||||
writeMask = ref;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& pass : passes) {
|
||||
pass->setStencilFront(func, ref, stencilMask, failOp, zFailOp, zPassOp, writeMask);
|
||||
pass->setStencilBack(func, ref, stencilMask, failOp, zFailOp, zPassOp, writeMask);
|
||||
}
|
||||
return effect;
|
||||
}
|
||||
|
||||
void StencilManager::pushMask (bool mask)
|
||||
{
|
||||
if (_maskStack.size() + 1 > _maxLevel)
|
||||
{
|
||||
cocos2d::log("StencilManager:pushMask _maxLevel:%d is out of range", _maxLevel);
|
||||
}
|
||||
_maskStack.push_back(mask);
|
||||
}
|
||||
|
||||
void StencilManager::clear ()
|
||||
{
|
||||
_stage = Stage::CLEAR;
|
||||
}
|
||||
|
||||
void StencilManager::enterLevel ()
|
||||
{
|
||||
_stage = Stage::ENTER_LEVEL;
|
||||
}
|
||||
|
||||
void StencilManager::enableMask ()
|
||||
{
|
||||
_stage = Stage::ENABLED;
|
||||
}
|
||||
|
||||
void StencilManager::exitMask ()
|
||||
{
|
||||
if (_maskStack.size() == 0) {
|
||||
cocos2d::log("StencilManager:exitMask _maskStack:%zu size is 0", _maskStack.size());
|
||||
}
|
||||
_maskStack.pop_back();
|
||||
if (_maskStack.size() == 0) {
|
||||
_stage = Stage::DISABLED;
|
||||
}
|
||||
else {
|
||||
_stage = Stage::ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t StencilManager::getWriteMask ()
|
||||
{
|
||||
return 0x01 << (_maskStack.size() - 1);
|
||||
}
|
||||
|
||||
uint8_t StencilManager::getExitWriteMask ()
|
||||
{
|
||||
return 0x01 << _maskStack.size();
|
||||
}
|
||||
|
||||
uint32_t StencilManager::getStencilRef ()
|
||||
{
|
||||
int32_t result = 0;
|
||||
size_t size = _maskStack.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
result += (0x01 << i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t StencilManager::getInvertedRef ()
|
||||
{
|
||||
int32_t result = 0;
|
||||
size_t size = _maskStack.size();
|
||||
for (int i = 0; i < size - 1; ++i)
|
||||
{
|
||||
result += (0x01 << i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
113
cocos2d-x/cocos/renderer/scene/StencilManager.hpp
Normal file
113
cocos2d-x/cocos/renderer/scene/StencilManager.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/****************************************************************************
|
||||
LICENSING AGREEMENT
|
||||
|
||||
Xiamen Yaji Software Co., Ltd., (the “Licensor”) grants the user (the “Licensee”) non-exclusive and non-transferable rights to use the software according to the following conditions:
|
||||
a. The Licensee shall pay royalties to the Licensor, and the amount of those royalties and the payment method are subject to separate negotiations between the parties.
|
||||
b. The software is licensed for use rather than sold, and the Licensor reserves all rights over the software that are not expressly granted (whether by implication, reservation or prohibition).
|
||||
c. The open source codes contained in the software are subject to the MIT Open Source Licensing Agreement (see the attached for the details);
|
||||
d. The Licensee acknowledges and consents to the possibility that errors may occur during the operation of the software for one or more technical reasons, and the Licensee shall take precautions and prepare remedies for such events. In such circumstance, the Licensor shall provide software patches or updates according to the agreement between the two parties. The Licensor will not assume any liability beyond the explicit wording of this Licensing Agreement.
|
||||
e. Where the Licensor must assume liability for the software according to relevant laws, the Licensor’s entire liability is limited to the annual royalty payable by the Licensee.
|
||||
f. The Licensor owns the portions listed in the root directory and subdirectory (if any) in the software and enjoys the intellectual property rights over those portions. As for the portions owned by the Licensor, the Licensee shall not:
|
||||
- i. Bypass or avoid any relevant technical protection measures in the products or services;
|
||||
- ii. Release the source codes to any other parties;
|
||||
- iii. Disassemble, decompile, decipher, attack, emulate, exploit or reverse-engineer these portion of code;
|
||||
- iv. Apply it to any third-party products or services without Licensor’s permission;
|
||||
- v. Publish, copy, rent, lease, sell, export, import, distribute or lend any products containing these portions of code;
|
||||
- vi. Allow others to use any services relevant to the technology of these codes;
|
||||
- vii. Conduct any other act beyond the scope of this Licensing Agreement.
|
||||
g. This Licensing Agreement terminates immediately if the Licensee breaches this Agreement. The Licensor may claim compensation from the Licensee where the Licensee’s breach causes any damage to the Licensor.
|
||||
h. The laws of the People's Republic of China apply to this Licensing Agreement.
|
||||
i. This Agreement is made in both Chinese and English, and the Chinese version shall prevail the event of conflict.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include "../../base/CCVector.h"
|
||||
#include "renderer/EffectVariant.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
// Stage types
|
||||
enum class Stage{
|
||||
// Stencil disabled
|
||||
DISABLED = 0,
|
||||
// Clear stencil buffer
|
||||
CLEAR = 1,
|
||||
// Entering a new level, should handle new stencil
|
||||
ENTER_LEVEL = 2,
|
||||
// In content
|
||||
ENABLED = 3,
|
||||
// Exiting a level, should restore old stencil or disable
|
||||
EXIT_LEVEL = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* The stencil manager post process the Effect in Model to make them apply correct stencil states
|
||||
* After activated a stencil mask and before desactivated it, all Models committed in between should apply the stencil's states in the Pass of Effect.
|
||||
* This is a singleton class mainly used by ModelBatcher.
|
||||
*/
|
||||
class StencilManager
|
||||
{
|
||||
public:
|
||||
StencilManager();
|
||||
~StencilManager();
|
||||
/**
|
||||
* Reset all states
|
||||
*/
|
||||
void reset();
|
||||
/**
|
||||
* Apply correct stencil states to the Effect
|
||||
*/
|
||||
EffectVariant* handleEffect(EffectVariant* effect);
|
||||
/**
|
||||
* Add a mask to the stack
|
||||
*/
|
||||
void pushMask(bool mask);
|
||||
/**
|
||||
* Stage for clearing the stencil buffer for the last mask
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* Enters a new mask level, this stage is for drawing the stencil ref to the stencil buffer.
|
||||
*/
|
||||
void enterLevel();
|
||||
/**
|
||||
* Enables the current mask, this stage is for applying stencil states defined by the current mask.
|
||||
*/
|
||||
void enableMask();
|
||||
/**
|
||||
* Exits a mask level
|
||||
*/
|
||||
void exitMask();
|
||||
uint8_t getWriteMask();
|
||||
uint8_t getExitWriteMask();
|
||||
uint32_t getStencilRef();
|
||||
uint32_t getInvertedRef();
|
||||
|
||||
static StencilManager* getInstance()
|
||||
{
|
||||
if (_instance == nullptr)
|
||||
{
|
||||
_instance = new StencilManager;
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
private:
|
||||
const int _maxLevel = 8;
|
||||
std::vector<bool> _maskStack;
|
||||
Stage _stage;
|
||||
static StencilManager* _instance;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
285
cocos2d-x/cocos/renderer/scene/assembler/Assembler.cpp
Normal file
285
cocos2d-x/cocos/renderer/scene/assembler/Assembler.cpp
Normal file
@@ -0,0 +1,285 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Assembler.hpp"
|
||||
|
||||
#include "../NodeProxy.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
#include "../MeshBuffer.hpp"
|
||||
#include "../../renderer/Scene.h"
|
||||
#include "math/CCMath.h"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
|
||||
#include "cocos/scripting/js-bindings/auto/jsb_renderer_auto.hpp"
|
||||
#include "../RenderFlow.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
Assembler::IARenderData::IARenderData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Assembler::IARenderData::IARenderData(const IARenderData& o)
|
||||
{
|
||||
meshIndex = o.meshIndex;
|
||||
verticesStart = o.verticesStart;
|
||||
verticesCount = o.verticesCount;
|
||||
indicesStart = o.indicesStart;
|
||||
indicesCount = o.indicesCount;
|
||||
setEffect(o.getEffect());
|
||||
}
|
||||
|
||||
Assembler::IARenderData::~IARenderData()
|
||||
{
|
||||
CC_SAFE_RELEASE(_effect);
|
||||
}
|
||||
|
||||
void Assembler::IARenderData::setEffect(EffectVariant* effect)
|
||||
{
|
||||
if (effect == _effect) return;
|
||||
CC_SAFE_RELEASE(_effect);
|
||||
_effect = effect;
|
||||
CC_SAFE_RETAIN(_effect);
|
||||
}
|
||||
|
||||
EffectVariant* Assembler::IARenderData::getEffect() const
|
||||
{
|
||||
return _effect;
|
||||
}
|
||||
|
||||
Assembler::Assembler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Assembler::~Assembler()
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(_datas);
|
||||
CC_SAFE_RELEASE(_vfmt);
|
||||
}
|
||||
|
||||
void Assembler::updateMeshIndex(std::size_t iaIndex, int meshIndex)
|
||||
{
|
||||
if (iaIndex >= _iaDatas.size())
|
||||
{
|
||||
_iaDatas.resize(iaIndex + 1);
|
||||
}
|
||||
IARenderData& ia = _iaDatas[iaIndex];
|
||||
ia.meshIndex = meshIndex;
|
||||
}
|
||||
|
||||
void Assembler::updateIndicesRange(std::size_t iaIndex, int start, int count)
|
||||
{
|
||||
if (iaIndex >= _iaDatas.size())
|
||||
{
|
||||
_iaDatas.resize(iaIndex + 1);
|
||||
}
|
||||
IARenderData& ia = _iaDatas[iaIndex];
|
||||
ia.indicesStart = start;
|
||||
ia.indicesCount = count;
|
||||
}
|
||||
|
||||
void Assembler::updateVerticesRange(std::size_t iaIndex, int start, int count)
|
||||
{
|
||||
if (iaIndex >= _iaDatas.size())
|
||||
{
|
||||
_iaDatas.resize(iaIndex + 1);
|
||||
}
|
||||
IARenderData& ia = _iaDatas[iaIndex];
|
||||
ia.verticesStart = start;
|
||||
ia.verticesCount = count;
|
||||
|
||||
enableDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
}
|
||||
|
||||
void Assembler::updateEffect(std::size_t iaIndex, EffectVariant* effect)
|
||||
{
|
||||
if (iaIndex >= _iaDatas.size())
|
||||
{
|
||||
_iaDatas.resize(iaIndex + 1);
|
||||
}
|
||||
IARenderData& ia = _iaDatas[iaIndex];
|
||||
ia.setEffect(effect);
|
||||
}
|
||||
|
||||
void Assembler::reset()
|
||||
{
|
||||
_iaDatas.clear();
|
||||
}
|
||||
|
||||
void Assembler::handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
batcher->commit(node, this, node->getCullingMask());
|
||||
}
|
||||
|
||||
void Assembler::fillBuffers(NodeProxy* node, ModelBatcher* batcher, std::size_t index)
|
||||
{
|
||||
if(!_datas || !_vfmt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MeshBuffer* buffer = batcher->getBuffer(_vfmt);
|
||||
|
||||
const IARenderData& ia = _iaDatas[index];
|
||||
std::size_t meshIndex = ia.meshIndex >= 0 ? ia.meshIndex : index;
|
||||
|
||||
RenderData* data = _datas->getRenderData(meshIndex);
|
||||
if (!data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CCASSERT(data->getVBytes() % _bytesPerVertex == 0, "Assembler::fillBuffers vertices data doesn't follow vertex format");
|
||||
uint32_t vertexCount = ia.verticesCount >= 0 ? (uint32_t)ia.verticesCount : (uint32_t)data->getVBytes() / _bytesPerVertex;
|
||||
uint32_t indexCount = ia.indicesCount >= 0 ? (uint32_t)ia.indicesCount : (uint32_t)data->getIBytes() / sizeof(unsigned short);
|
||||
uint32_t vertexStart = (uint32_t)ia.verticesStart;
|
||||
|
||||
// must retrieve offset before request
|
||||
auto& bufferOffset = buffer->request(vertexCount, indexCount);
|
||||
uint32_t vBufferOffset = bufferOffset.vByte / sizeof(float);
|
||||
uint32_t indexId = bufferOffset.index;
|
||||
uint32_t vertexId = bufferOffset.vertex;
|
||||
uint32_t vertexOffset = vertexId - vertexStart;
|
||||
uint32_t num = _vfPos->num;
|
||||
|
||||
float* worldVerts = buffer->vData + vBufferOffset;
|
||||
memcpy(worldVerts, data->getVertices() + vertexStart * _bytesPerVertex, vertexCount * _bytesPerVertex);
|
||||
|
||||
// Calculate vertices world positions
|
||||
if (!_useModel && !_ignoreWorldMatrix)
|
||||
{
|
||||
size_t dataPerVertex = _bytesPerVertex / sizeof(float);
|
||||
float* ptrPos = worldVerts + _posOffset;
|
||||
auto& worldMat = node->getWorldMatrix();
|
||||
|
||||
switch (num) {
|
||||
// Vertex is X Y Z Format
|
||||
case 3:
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
((cocos2d::Vec3*)ptrPos)->transformMat4(*((cocos2d::Vec3*)ptrPos), worldMat);
|
||||
ptrPos += dataPerVertex;
|
||||
}
|
||||
break;
|
||||
// Vertex is X Y Format
|
||||
case 2:
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
float z = ptrPos[2];
|
||||
ptrPos[2] = 0;
|
||||
worldMat.transformPoint((cocos2d::Vec3*)ptrPos);
|
||||
ptrPos[2] = z;
|
||||
ptrPos += dataPerVertex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy index buffer with vertex offset
|
||||
uint16_t* indices = (uint16_t*)data->getIndices();
|
||||
uint16_t* dst = buffer->iData;
|
||||
for (auto i = 0, j = ia.indicesStart; i < indexCount; ++i, ++j)
|
||||
{
|
||||
dst[indexId++] = vertexOffset + indices[j];
|
||||
}
|
||||
}
|
||||
|
||||
void Assembler::setVertexFormat(VertexFormat* vfmt)
|
||||
{
|
||||
if (_vfmt == vfmt) return;
|
||||
CC_SAFE_RETAIN(vfmt);
|
||||
CC_SAFE_RELEASE(_vfmt);
|
||||
_vfmt = vfmt;
|
||||
if (_vfmt)
|
||||
{
|
||||
_bytesPerVertex = _vfmt->getBytes();
|
||||
_vfPos = _vfmt->getElement(ATTRIB_NAME_POSITION_HASH);
|
||||
_posOffset = _vfPos->offset / 4;
|
||||
_vfColor = _vfmt->getElement(ATTRIB_NAME_COLOR_HASH);
|
||||
if (_vfColor != nullptr)
|
||||
{
|
||||
_alphaOffset = _vfColor->offset + 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Assembler::setRenderDataList(RenderDataList* datas)
|
||||
{
|
||||
if (_datas == datas) return;
|
||||
CC_SAFE_RELEASE(_datas);
|
||||
_datas = datas;
|
||||
CC_SAFE_RETAIN(_datas);
|
||||
}
|
||||
|
||||
void Assembler::updateOpacity(std::size_t index, uint8_t opacity)
|
||||
{
|
||||
// has no color info in vertex buffer
|
||||
if(!_vfColor || !_datas || !_vfmt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const IARenderData& ia = _iaDatas[index];
|
||||
std::size_t meshIndex = ia.meshIndex >= 0 ? ia.meshIndex : index;
|
||||
|
||||
RenderData* data = _datas->getRenderData(meshIndex);
|
||||
if (!data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CCASSERT(data->getVBytes() % _bytesPerVertex == 0, "Assembler::updateOpacity vertices data doesn't follow vertex format");
|
||||
uint32_t vertexCount = (uint32_t)data->getVBytes() / _bytesPerVertex;
|
||||
|
||||
size_t dataPerVertex = _bytesPerVertex / sizeof(uint8_t);
|
||||
uint8_t* ptrAlpha = (uint8_t*)data->getVertices() + _alphaOffset;
|
||||
const Vector<Pass*>& passes = ia.getEffect()->getPasses();
|
||||
if (passes.at(0)->getBlendSrc() == BlendFactor::ONE)
|
||||
{
|
||||
float alpha = opacity / 255.0;
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
*(ptrAlpha-1) *= alpha;
|
||||
*(ptrAlpha-2) *= alpha;
|
||||
*(ptrAlpha-3) *= alpha;
|
||||
|
||||
*ptrAlpha = opacity;
|
||||
ptrAlpha += dataPerVertex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
*ptrAlpha = opacity;
|
||||
ptrAlpha += dataPerVertex;
|
||||
}
|
||||
}
|
||||
|
||||
*_dirty &= ~VERTICES_OPACITY_CHANGED;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
202
cocos2d-x/cocos/renderer/scene/assembler/Assembler.hpp
Normal file
202
cocos2d-x/cocos/renderer/scene/assembler/Assembler.hpp
Normal file
@@ -0,0 +1,202 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include "AssemblerBase.hpp"
|
||||
#include "../MeshBuffer.hpp"
|
||||
#include "math/CCMath.h"
|
||||
#include "../../renderer/Effect.h"
|
||||
#include "RenderDataList.hpp"
|
||||
#include "../../renderer/EffectVariant.hpp"
|
||||
|
||||
namespace se {
|
||||
class Object;
|
||||
class HandleObject;
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class NodeProxy;
|
||||
class ModelBatcher;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
class Assembler : public AssemblerBase
|
||||
{
|
||||
public:
|
||||
|
||||
class IARenderData {
|
||||
public:
|
||||
IARenderData();
|
||||
IARenderData(const IARenderData& o);
|
||||
~IARenderData();
|
||||
void setEffect(EffectVariant* effect);
|
||||
EffectVariant* getEffect() const;
|
||||
private:
|
||||
EffectVariant* _effect = nullptr;
|
||||
public:
|
||||
int meshIndex = -1;
|
||||
int verticesStart = 0;
|
||||
int verticesCount = -1;
|
||||
int indicesStart = 0;
|
||||
int indicesCount = -1;
|
||||
};
|
||||
|
||||
Assembler();
|
||||
virtual ~Assembler();
|
||||
/*
|
||||
* @brief Commit the current render handle to ModelBatcher
|
||||
*/
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
/*
|
||||
* @brief Do nothing
|
||||
*/
|
||||
virtual void postHandle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override {}
|
||||
/*
|
||||
* @brief before fill buffers handle
|
||||
*/
|
||||
virtual void beforeFillBuffers(std::size_t index) {}
|
||||
/*
|
||||
* @brief Fills render data in given index to the MeshBuffer
|
||||
* @param[in] buffer The shared mesh buffer
|
||||
* @param[in] index The index of render data to be updated
|
||||
* @param[in] node
|
||||
*/
|
||||
virtual void fillBuffers(NodeProxy* node, ModelBatcher* batcher, std::size_t index);
|
||||
|
||||
/**
|
||||
* @brief Sets IArenderDataList
|
||||
*/
|
||||
virtual void setRenderDataList(RenderDataList* datas);
|
||||
|
||||
/**
|
||||
* @brief Gets the vertex format.
|
||||
*/
|
||||
VertexFormat* getVertexFormat() const { return _vfmt; };
|
||||
/**
|
||||
* @brief Sets the vertex format.
|
||||
*/
|
||||
virtual void setVertexFormat(VertexFormat* vfmt);
|
||||
|
||||
/*
|
||||
* @brief Update local render buffer opacity
|
||||
* @param[in] index The index of render data to be updated
|
||||
* @param[in] opacity Inherit opacity
|
||||
*/
|
||||
virtual void updateOpacity(std::size_t index, uint8_t opacity);
|
||||
|
||||
/**
|
||||
* @brief ignore opacity flag, it will always not update vertices opacity
|
||||
*/
|
||||
void ignoreOpacityFlag() { _ignoreOpacityFlag = true; }
|
||||
|
||||
/**
|
||||
* @brief Is ignore opacity.
|
||||
* @return _ignoreOpacityFlag
|
||||
*/
|
||||
bool isIgnoreOpacityFlag() { return _ignoreOpacityFlag; }
|
||||
|
||||
/**
|
||||
* @brief Enable ignore world matrix.
|
||||
*/
|
||||
void ignoreWorldMatrix() { _ignoreWorldMatrix = true; }
|
||||
|
||||
/**
|
||||
* @brief Is ignore world matrix.
|
||||
* @return _opacityAlwaysDirty
|
||||
*/
|
||||
bool isIgnoreWorldMatrix() { return _ignoreWorldMatrix; }
|
||||
|
||||
/**
|
||||
* @brief Updates mesh index
|
||||
*/
|
||||
void updateMeshIndex(std::size_t iaIndex, int meshIndex);
|
||||
/**
|
||||
* @brief Updates indices range
|
||||
*/
|
||||
void updateIndicesRange(std::size_t iaIndex, int start, int count);
|
||||
|
||||
/**
|
||||
* @brief Updates vertices range
|
||||
*/
|
||||
void updateVerticesRange(std::size_t iaIndex, int start, int count);
|
||||
|
||||
/**
|
||||
* @brief Update the material for the given index.
|
||||
* @param[in] iaIndex Render data index.
|
||||
* @param[in] effect Effect pointer.
|
||||
*/
|
||||
virtual void updateEffect(std::size_t iaIndex, EffectVariant* effect);
|
||||
|
||||
/**
|
||||
* @brief Resets ia data.
|
||||
*/
|
||||
virtual void reset() override;
|
||||
|
||||
/**
|
||||
* @brief Gets the material for the given index.
|
||||
* @param[in] index Render data index.
|
||||
* @return Effect pointer.
|
||||
*/
|
||||
inline EffectVariant* getEffect(std::size_t index) const
|
||||
{
|
||||
if (index >= _iaDatas.size())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return _iaDatas[index].getEffect();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets Effect count.
|
||||
* @return Count.
|
||||
*/
|
||||
inline std::size_t getIACount() const
|
||||
{
|
||||
return _iaDatas.size();
|
||||
}
|
||||
protected:
|
||||
RenderDataList* _datas = nullptr;
|
||||
std::vector<IARenderData> _iaDatas;
|
||||
|
||||
uint32_t _bytesPerVertex = 0;
|
||||
size_t _posOffset = 0;
|
||||
size_t _alphaOffset = 0;
|
||||
VertexFormat* _vfmt = nullptr;
|
||||
const VertexFormat::Element* _vfPos = nullptr;
|
||||
const VertexFormat::Element* _vfColor = nullptr;
|
||||
|
||||
bool _ignoreWorldMatrix = false;
|
||||
bool _ignoreOpacityFlag = false;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
69
cocos2d-x/cocos/renderer/scene/assembler/AssemblerBase.cpp
Normal file
69
cocos2d-x/cocos/renderer/scene/assembler/AssemblerBase.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "AssemblerBase.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
AssemblerBase::AssemblerBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AssemblerBase::~AssemblerBase()
|
||||
{
|
||||
if (_jsDirty)
|
||||
{
|
||||
_jsDirty->unroot();
|
||||
_jsDirty->decRef();
|
||||
_jsDirty = nullptr;
|
||||
}
|
||||
_dirty = nullptr;
|
||||
_dirtyLen = 0;
|
||||
|
||||
clearCustomWorldMatirx();
|
||||
}
|
||||
|
||||
void AssemblerBase::setDirty(se_object_ptr jsDirty)
|
||||
{
|
||||
if (_jsDirty == jsDirty) return;
|
||||
|
||||
if (_jsDirty)
|
||||
{
|
||||
_jsDirty->unroot();
|
||||
_jsDirty->decRef();
|
||||
_jsDirty = nullptr;
|
||||
}
|
||||
|
||||
if (jsDirty == nullptr) return;
|
||||
|
||||
_jsDirty = jsDirty;
|
||||
_jsDirty->root();
|
||||
_jsDirty->incRef();
|
||||
_dirty = nullptr;
|
||||
_dirtyLen = 0;
|
||||
_jsDirty->getTypedArrayData((uint8_t**)&_dirty, &_dirtyLen);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
180
cocos2d-x/cocos/renderer/scene/assembler/AssemblerBase.hpp
Normal file
180
cocos2d-x/cocos/renderer/scene/assembler/AssemblerBase.hpp
Normal file
@@ -0,0 +1,180 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include <stdint.h>
|
||||
#include "base/CCVector.h"
|
||||
#include "../../renderer/Effect.h"
|
||||
#include "scripting/js-bindings/jswrapper/Object.hpp"
|
||||
#include "math/Mat4.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class NodeProxy;
|
||||
class ModelBatcher;
|
||||
class Scene;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Base class for all assembler
|
||||
* A assembler could take actions during node visit process, before and after all children visit.
|
||||
*/
|
||||
class AssemblerBase: public cocos2d::Ref
|
||||
{
|
||||
public:
|
||||
|
||||
enum AssemblerFlag {
|
||||
VERTICES_OPACITY_CHANGED = 1 << 0,
|
||||
VERTICES_DIRTY = 1 << 1,
|
||||
};
|
||||
|
||||
AssemblerBase();
|
||||
|
||||
virtual ~AssemblerBase();
|
||||
|
||||
/**
|
||||
* @brief Callback which will be invoked before visiting child nodes.
|
||||
* @param[in] node The node being processed.
|
||||
* @param[in] batcher
|
||||
* @param[in] scene
|
||||
*/
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) {}
|
||||
/**
|
||||
* @brief Callback which will be invoked after visiting child nodes.
|
||||
* @param[in] node The node being processed.
|
||||
* @param[in] batcher
|
||||
* @param[in] scene
|
||||
*/
|
||||
virtual void postHandle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) {}
|
||||
|
||||
/**
|
||||
* @brief Gets whether the current handle should use model matrix uniform during rendering
|
||||
*/
|
||||
bool getUseModel() const
|
||||
{
|
||||
return _useModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets whether the current handle should use model matrix uniform during rendering
|
||||
*/
|
||||
void setUseModel(bool useModel)
|
||||
{
|
||||
_useModel = useModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets custom world matrix
|
||||
*/
|
||||
const cocos2d::Mat4* getCustomWorldMatrix() const
|
||||
{
|
||||
return _worldMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets custom world matrix
|
||||
*/
|
||||
void setCustomWorldMatrix(const cocos2d::Mat4& matrix)
|
||||
{
|
||||
if (!_worldMatrix)
|
||||
{
|
||||
_worldMatrix = new cocos2d::Mat4();
|
||||
}
|
||||
*_worldMatrix = matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear custom world matrix
|
||||
*/
|
||||
void clearCustomWorldMatirx()
|
||||
{
|
||||
if (_worldMatrix)
|
||||
{
|
||||
delete _worldMatrix;
|
||||
_worldMatrix = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sync script dirty flag.
|
||||
*/
|
||||
void setDirty(se_object_ptr jsDirty);
|
||||
|
||||
/**
|
||||
* @brief Changes dirty flag.
|
||||
*/
|
||||
void enableDirty(uint32_t flag)
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
*_dirty |= flag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Changes dirty flag.
|
||||
*/
|
||||
void disableDirty(uint32_t flag)
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
*_dirty &= ~flag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Is flag dirty.
|
||||
*/
|
||||
bool isDirty(uint32_t flag)
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
return *_dirty & flag;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets data.
|
||||
*/
|
||||
virtual void reset() {}
|
||||
protected:
|
||||
se::Object* _jsDirty = nullptr;
|
||||
uint32_t* _dirty = nullptr;
|
||||
std::size_t _dirtyLen = 0;
|
||||
|
||||
bool _useModel = false;
|
||||
cocos2d::Mat4* _worldMatrix = nullptr;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
160
cocos2d-x/cocos/renderer/scene/assembler/AssemblerSprite.cpp
Normal file
160
cocos2d-x/cocos/renderer/scene/assembler/AssemblerSprite.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "AssemblerSprite.hpp"
|
||||
#include "../RenderFlow.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
AssemblerSprite::AssemblerSprite()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AssemblerSprite::~AssemblerSprite()
|
||||
{
|
||||
if(_localObj != nullptr)
|
||||
{
|
||||
_localObj->unroot();
|
||||
_localObj->decRef();
|
||||
_localObj = nullptr;
|
||||
_localData = nullptr;
|
||||
_localLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblerSprite::setLocalData(se_object_ptr localData)
|
||||
{
|
||||
if (!localData || localData == _localObj) return;
|
||||
if (_localObj)
|
||||
{
|
||||
_localObj->unroot();
|
||||
_localObj->decRef();
|
||||
}
|
||||
_localObj = localData;
|
||||
_localObj->root();
|
||||
_localObj->incRef();
|
||||
_localData = nullptr;
|
||||
_localLen = 0;
|
||||
_localObj->getTypedArrayData((uint8_t**)&_localData, (std::size_t*)&_localLen);
|
||||
}
|
||||
|
||||
void AssemblerSprite::fillBuffers(NodeProxy* node, ModelBatcher* batcher, std::size_t index)
|
||||
{
|
||||
if(!_datas || !_vfmt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= _iaDatas.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MeshBuffer* buffer = batcher->getBuffer(_vfmt);
|
||||
|
||||
const IARenderData& ia = _iaDatas[index];
|
||||
std::size_t meshIndex = ia.meshIndex >= 0 ? ia.meshIndex : index;
|
||||
|
||||
RenderData* data = _datas->getRenderData(meshIndex);
|
||||
if (!data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CCASSERT(data->getVBytes() % _bytesPerVertex == 0, "AssemblerSprite::fillBuffers vertices data doesn't follow vertex format");
|
||||
uint32_t vertexCount = ia.verticesCount >= 0 ? (uint32_t)ia.verticesCount : (uint32_t)data->getVBytes() / _bytesPerVertex;
|
||||
uint32_t indexCount = ia.indicesCount >= 0 ? (uint32_t)ia.indicesCount : (uint32_t)data->getIBytes() / sizeof(unsigned short);
|
||||
uint32_t vertexStart = (uint32_t)ia.verticesStart;
|
||||
|
||||
// must retrieve offset before request
|
||||
auto& bufferOffset = buffer->request(vertexCount, indexCount);
|
||||
uint32_t vBufferOffset = bufferOffset.vByte / sizeof(float);
|
||||
uint32_t indexId = bufferOffset.index;
|
||||
uint32_t vertexId = bufferOffset.vertex;
|
||||
uint32_t vertexOffset = vertexId - vertexStart;
|
||||
|
||||
if (*_dirty & VERTICES_DIRTY || node->isDirty(RenderFlow::WORLD_TRANSFORM_CHANGED | RenderFlow::NODE_OPACITY_CHANGED))
|
||||
{
|
||||
generateWorldVertices();
|
||||
calculateWorldVertices(node->getWorldMatrix());
|
||||
}
|
||||
|
||||
float* dstWorldVerts = buffer->vData + vBufferOffset;
|
||||
memcpy(dstWorldVerts, data->getVertices() + vertexStart * _bytesPerVertex, vertexCount * _bytesPerVertex);
|
||||
|
||||
// Copy index buffer with vertex offset
|
||||
uint16_t* srcIndices = (uint16_t*)data->getIndices();
|
||||
uint16_t* dstIndices = buffer->iData;
|
||||
for (auto i = 0, j = ia.indicesStart; i < indexCount; ++i, ++j)
|
||||
{
|
||||
dstIndices[indexId++] = vertexOffset + srcIndices[j];
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblerSprite::calculateWorldVertices(const Mat4& worldMat)
|
||||
{
|
||||
if(!_datas || !_vfmt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t num = _vfPos->num;
|
||||
size_t dataPerVertex = _bytesPerVertex / sizeof(float);
|
||||
|
||||
for (std::size_t iaIdx = 0, iaCount = _iaDatas.size(); iaIdx < iaCount; iaIdx++)
|
||||
{
|
||||
const IARenderData& ia = _iaDatas[iaIdx];
|
||||
std::size_t meshIndex = ia.meshIndex >= 0 ? ia.meshIndex : iaIdx;
|
||||
RenderData* data = _datas->getRenderData(meshIndex);
|
||||
if (!data) continue;
|
||||
|
||||
uint32_t vertexCount = ia.verticesCount >= 0 ? (uint32_t)ia.verticesCount : (uint32_t)data->getVBytes() / _bytesPerVertex;
|
||||
uint32_t vertexStart = (uint32_t)ia.verticesStart;
|
||||
float* srcWorldVerts = (float*)(data->getVertices() + vertexStart * _bytesPerVertex) + _posOffset;
|
||||
|
||||
switch (num) {
|
||||
case 3:
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
((cocos2d::Vec3*)srcWorldVerts)->transformMat4(*((cocos2d::Vec3*)srcWorldVerts), worldMat);
|
||||
srcWorldVerts += dataPerVertex;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
float z = srcWorldVerts[2];
|
||||
srcWorldVerts[2] = 0;
|
||||
worldMat.transformPoint((cocos2d::Vec3*)srcWorldVerts);
|
||||
srcWorldVerts[2] = z;
|
||||
srcWorldVerts += dataPerVertex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*_dirty &= ~VERTICES_DIRTY;
|
||||
}
|
||||
RENDERER_END
|
||||
48
cocos2d-x/cocos/renderer/scene/assembler/AssemblerSprite.hpp
Normal file
48
cocos2d-x/cocos/renderer/scene/assembler/AssemblerSprite.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include "scripting/js-bindings/jswrapper/Object.hpp"
|
||||
#include "Assembler.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class AssemblerSprite: public Assembler
|
||||
{
|
||||
public:
|
||||
AssemblerSprite();
|
||||
virtual ~AssemblerSprite();
|
||||
virtual void setLocalData(se_object_ptr localData);
|
||||
virtual void fillBuffers(NodeProxy* node, ModelBatcher* batcher, std::size_t index) override;
|
||||
virtual void calculateWorldVertices(const Mat4& worldMat);
|
||||
virtual void generateWorldVertices() {};
|
||||
protected:
|
||||
se::Object* _localObj = nullptr;
|
||||
float* _localData = nullptr;
|
||||
std::size_t _localLen = 0;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
133
cocos2d-x/cocos/renderer/scene/assembler/CustomAssembler.cpp
Normal file
133
cocos2d-x/cocos/renderer/scene/assembler/CustomAssembler.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "CustomAssembler.hpp"
|
||||
#include "../NodeProxy.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
#include "../../renderer/Scene.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
CustomAssembler::CustomAssembler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CustomAssembler::~CustomAssembler()
|
||||
{
|
||||
for (std::size_t i = 0, n = _iaPool.size(); i < n; i++)
|
||||
{
|
||||
auto ia = _iaPool[i];
|
||||
delete ia;
|
||||
}
|
||||
_iaPool.clear();
|
||||
}
|
||||
|
||||
void CustomAssembler::handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
batcher->commitIA(node, this, node->getCullingMask());
|
||||
}
|
||||
|
||||
void CustomAssembler::reset()
|
||||
{
|
||||
_iaCount = 0;
|
||||
for (auto it = _iaPool.begin(); it != _iaPool.end(); it++)
|
||||
{
|
||||
(*it)->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void CustomAssembler::updateIARange(std::size_t index, int start, int count)
|
||||
{
|
||||
auto ia = adjustIA(index);
|
||||
if (!ia) return;
|
||||
|
||||
ia->setCount(count);
|
||||
ia->setStart(start);
|
||||
}
|
||||
|
||||
void CustomAssembler::updateIABuffer(std::size_t index, VertexBuffer* vb, IndexBuffer* ib)
|
||||
{
|
||||
auto ia = adjustIA(index);
|
||||
if (!ia) return;
|
||||
|
||||
ia->setVertexBuffer(vb);
|
||||
ia->setIndexBuffer(ib);
|
||||
}
|
||||
|
||||
InputAssembler* CustomAssembler::adjustIA(std::size_t index)
|
||||
{
|
||||
auto size = _iaPool.size();
|
||||
InputAssembler* ia = nullptr;
|
||||
if (index == size)
|
||||
{
|
||||
ia = new InputAssembler();
|
||||
_iaPool.push_back(ia);
|
||||
}
|
||||
else if (index < size)
|
||||
{
|
||||
ia = _iaPool[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
cocos2d::log("CustomAssembler:updateIA index:%zu is out of range", index);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto newIACount = index + 1;
|
||||
if (_iaCount < newIACount)
|
||||
{
|
||||
_iaCount = newIACount;
|
||||
}
|
||||
|
||||
return ia;
|
||||
}
|
||||
|
||||
InputAssembler* CustomAssembler::getIA(std::size_t index) const
|
||||
{
|
||||
if (index >= _iaCount)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return _iaPool[index];
|
||||
}
|
||||
|
||||
void CustomAssembler::updateEffect(std::size_t index, EffectVariant* effect)
|
||||
{
|
||||
auto size = _effects.size();
|
||||
if (index == size)
|
||||
{
|
||||
_effects.pushBack(effect);
|
||||
return;
|
||||
}
|
||||
else if (index < size)
|
||||
{
|
||||
_effects.replace(index, effect);
|
||||
return;
|
||||
}
|
||||
cocos2d::log("CustomAssembler:updateEffect index:%zu out of range", index);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
134
cocos2d-x/cocos/renderer/scene/assembler/CustomAssembler.hpp
Normal file
134
cocos2d-x/cocos/renderer/scene/assembler/CustomAssembler.hpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AssemblerBase.hpp"
|
||||
#include <vector>
|
||||
#include "../../renderer/InputAssembler.h"
|
||||
#include "../../renderer/EffectVariant.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Custom render handle base class
|
||||
* Render components that manages render buffer directly like spine, dragonBones should extend from this handle type.
|
||||
*/
|
||||
class CustomAssembler : public AssemblerBase
|
||||
{
|
||||
public:
|
||||
CustomAssembler();
|
||||
virtual ~CustomAssembler();
|
||||
|
||||
/**
|
||||
* @brief Updates InputAssembler indices range
|
||||
* @param[in] index InputAssembler index.
|
||||
* @param[in] start Indices buffer start pos
|
||||
* @param[in] count Indices count
|
||||
*/
|
||||
virtual void updateIARange(std::size_t index, int start, int count);
|
||||
/**
|
||||
* @brief Updates InputAssembler indices and vertices buffer
|
||||
* @param[in] index InputAssembler index.
|
||||
* @param[in] vb Vertices buffer pointer
|
||||
* @param[in] ib Indices buffer pointer
|
||||
*/
|
||||
virtual void updateIABuffer(std::size_t index, cocos2d::renderer::VertexBuffer* vb, cocos2d::renderer::IndexBuffer* ib);
|
||||
|
||||
/**
|
||||
* @brief Gets input assembler by index
|
||||
* @param[in] index.
|
||||
*/
|
||||
InputAssembler* getIA(std::size_t index) const;
|
||||
|
||||
/**
|
||||
* @brief Gets input assembler count.
|
||||
* @return Count.
|
||||
*/
|
||||
virtual inline std::size_t getIACount() const
|
||||
{
|
||||
return _iaCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Commit the current render handle to ModelBatcher
|
||||
*/
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
/**
|
||||
* @brief Do nothing
|
||||
*/
|
||||
virtual void postHandle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override {}
|
||||
/**
|
||||
* @brief Resets ia data.
|
||||
*/
|
||||
virtual void reset() override;
|
||||
/**
|
||||
* @brief Adjusts ia data.
|
||||
*/
|
||||
virtual InputAssembler* adjustIA(std::size_t index);
|
||||
|
||||
/**
|
||||
* @brief Update the material for the given index.
|
||||
* @param[in] index Render data index.
|
||||
* @param[in] effect Effect pointer.
|
||||
*/
|
||||
virtual void updateEffect(std::size_t index, EffectVariant* effect);
|
||||
|
||||
/**
|
||||
* @brief Gets the material for the given index.
|
||||
* @param[in] index Render data index.
|
||||
* @return Effect pointer.
|
||||
*/
|
||||
inline EffectVariant* getEffect(std::size_t index) const
|
||||
{
|
||||
if (index >= _effects.size())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return _effects.at(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears all effect.
|
||||
* @return Count.
|
||||
*/
|
||||
virtual void clearEffect()
|
||||
{
|
||||
_effects.clear();
|
||||
}
|
||||
protected:
|
||||
std::vector<cocos2d::renderer::InputAssembler*> _iaPool;
|
||||
cocos2d::Vector<EffectVariant*> _effects;
|
||||
std::size_t _iaCount = 0;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
91
cocos2d-x/cocos/renderer/scene/assembler/MaskAssembler.cpp
Normal file
91
cocos2d-x/cocos/renderer/scene/assembler/MaskAssembler.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "MaskAssembler.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
#include "../StencilManager.hpp"
|
||||
#include "../../Macro.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
MaskAssembler::MaskAssembler()
|
||||
{
|
||||
}
|
||||
|
||||
MaskAssembler::~MaskAssembler()
|
||||
{
|
||||
CC_SAFE_RELEASE(_renderSubHandle);
|
||||
CC_SAFE_RELEASE(_clearSubHandle);
|
||||
}
|
||||
|
||||
void MaskAssembler::setRenderSubHandle(Assembler* renderSubHandle)
|
||||
{
|
||||
if (_renderSubHandle == renderSubHandle) return;
|
||||
CC_SAFE_RELEASE(_renderSubHandle);
|
||||
_renderSubHandle = renderSubHandle;
|
||||
CC_SAFE_RETAIN(_renderSubHandle);
|
||||
}
|
||||
|
||||
void MaskAssembler::setClearSubHandle(Assembler* clearSubHandle)
|
||||
{
|
||||
if (_clearSubHandle == clearSubHandle) return;
|
||||
CC_SAFE_RELEASE(_clearSubHandle);
|
||||
_clearSubHandle = clearSubHandle;
|
||||
CC_SAFE_RETAIN(_clearSubHandle);
|
||||
}
|
||||
|
||||
void MaskAssembler::handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
batcher->flush();
|
||||
batcher->flushIA();
|
||||
|
||||
StencilManager* instance = StencilManager::getInstance();
|
||||
instance->pushMask(_inverted);
|
||||
instance->clear();
|
||||
batcher->commit(node, _clearSubHandle, node->getCullingMask());
|
||||
batcher->flush();
|
||||
instance->enterLevel();
|
||||
|
||||
if (_imageStencil)
|
||||
{
|
||||
batcher->commit(node, this, node->getCullingMask());
|
||||
}
|
||||
else if (_renderSubHandle)
|
||||
{
|
||||
_renderSubHandle->handle(node, batcher, scene);
|
||||
}
|
||||
|
||||
batcher->flush();
|
||||
instance->enableMask();
|
||||
}
|
||||
|
||||
void MaskAssembler::postHandle(NodeProxy *node, ModelBatcher *batcher, Scene *scene)
|
||||
{
|
||||
batcher->flush();
|
||||
batcher->flushIA();
|
||||
batcher->setCurrentEffect(getEffect(0));
|
||||
StencilManager::getInstance()->exitMask();
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
62
cocos2d-x/cocos/renderer/scene/assembler/MaskAssembler.hpp
Normal file
62
cocos2d-x/cocos/renderer/scene/assembler/MaskAssembler.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Assembler.hpp"
|
||||
#include "../MeshBuffer.hpp"
|
||||
#include "math/CCMath.h"
|
||||
#include "SimpleSprite2D.hpp"
|
||||
|
||||
class ModelBatcher;
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class MaskAssembler: public SimpleSprite2D
|
||||
{
|
||||
public:
|
||||
MaskAssembler();
|
||||
virtual ~MaskAssembler();
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
virtual void postHandle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
|
||||
void setMaskInverted(bool inverted) { _inverted = inverted; };
|
||||
bool getMaskInverted() { return _inverted; };
|
||||
|
||||
void setRenderSubHandle(Assembler* renderSubHandle);
|
||||
void setClearSubHandle(Assembler* clearSubHandle);
|
||||
|
||||
void setImageStencil(bool isImageStencil) { _imageStencil = isImageStencil; };
|
||||
|
||||
protected:
|
||||
bool _inverted = false;
|
||||
bool _imageStencil = false;
|
||||
|
||||
private:
|
||||
Assembler* _renderSubHandle = nullptr;
|
||||
Assembler* _clearSubHandle = nullptr;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
111
cocos2d-x/cocos/renderer/scene/assembler/MeshAssembler.cpp
Normal file
111
cocos2d-x/cocos/renderer/scene/assembler/MeshAssembler.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "MeshAssembler.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
MeshAssembler::MeshAssembler()
|
||||
{
|
||||
_useModel = true;
|
||||
}
|
||||
|
||||
MeshAssembler::~MeshAssembler()
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_renderNode);
|
||||
}
|
||||
|
||||
void MeshAssembler::handle(NodeProxy *node, ModelBatcher *batcher, Scene *scene)
|
||||
{
|
||||
if (_renderNode != nullptr)
|
||||
{
|
||||
batcher->commitIA(_renderNode, this, node->getCullingMask());
|
||||
}
|
||||
else
|
||||
{
|
||||
batcher->commitIA(node, this, node->getCullingMask());
|
||||
}
|
||||
|
||||
batcher->flushIA();
|
||||
}
|
||||
|
||||
void MeshAssembler::setNode(NodeProxy* node)
|
||||
{
|
||||
if (_renderNode == node)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_renderNode != nullptr)
|
||||
{
|
||||
_renderNode->release();
|
||||
}
|
||||
_renderNode = node;
|
||||
if (_renderNode != nullptr)
|
||||
{
|
||||
_renderNode->retain();
|
||||
}
|
||||
}
|
||||
|
||||
void MeshAssembler::updateIAData(std::size_t index, VertexFormat* vfmt, se_object_ptr vertices, se_object_ptr indices)
|
||||
{
|
||||
_datas.updateMesh(index, vertices, indices);
|
||||
auto data = _datas.getRenderData(index);
|
||||
|
||||
auto ia = adjustIA(index);
|
||||
|
||||
auto ib = ia->getIndexBuffer();
|
||||
if (!ib) {
|
||||
ib = new IndexBuffer();
|
||||
ib->autorelease();
|
||||
ib->init(DeviceGraphics::getInstance(), IndexFormat::UINT16, Usage::STATIC, data->getIndices(), data->getIBytes(), (uint32_t)data->getIBytes() / sizeof(unsigned short));
|
||||
ia->setIndexBuffer(ib);
|
||||
}
|
||||
else {
|
||||
ib->update(0, data->getIndices(), data->getIBytes());
|
||||
}
|
||||
|
||||
auto vb = ia->getVertexBuffer();
|
||||
if (!vb) {
|
||||
vb = new VertexBuffer();
|
||||
vb->autorelease();
|
||||
vb->init(DeviceGraphics::getInstance(), vfmt, Usage::STATIC, data->getVertices(), data->getVBytes(), (uint32_t)data->getVBytes() / vfmt->getBytes());
|
||||
ia->setVertexBuffer(vb);
|
||||
}
|
||||
else {
|
||||
vb->update(0, data->getVertices(), data->getVBytes());
|
||||
}
|
||||
|
||||
ia->setCount(ib->getCount());
|
||||
}
|
||||
|
||||
void MeshAssembler::reset()
|
||||
{
|
||||
CustomAssembler::reset();
|
||||
|
||||
_datas.clear();
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
54
cocos2d-x/cocos/renderer/scene/assembler/MeshAssembler.hpp
Normal file
54
cocos2d-x/cocos/renderer/scene/assembler/MeshAssembler.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include "CustomAssembler.hpp"
|
||||
#include "../NodeProxy.hpp"
|
||||
#include "../../gfx/VertexFormat.h"
|
||||
#include "RenderDataList.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class MeshAssembler: public CustomAssembler
|
||||
{
|
||||
public:
|
||||
MeshAssembler();
|
||||
virtual ~MeshAssembler();
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
/**
|
||||
* @brief Sets the related node proxy which provids model matrix for render.
|
||||
*/
|
||||
void setNode(NodeProxy* node);
|
||||
void updateIAData(std::size_t index, VertexFormat* vfmt, se_object_ptr vertices, se_object_ptr indices);
|
||||
|
||||
virtual void reset() override;
|
||||
protected:
|
||||
NodeProxy* _renderNode = nullptr;
|
||||
RenderDataList _datas;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
|
||||
136
cocos2d-x/cocos/renderer/scene/assembler/Particle3DAssembler.cpp
Normal file
136
cocos2d-x/cocos/renderer/scene/assembler/Particle3DAssembler.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Particle3DAssembler.hpp"
|
||||
#include "../NodeProxy.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
Particle3DAssembler::Particle3DAssembler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Particle3DAssembler::~Particle3DAssembler()
|
||||
{
|
||||
CC_SAFE_RELEASE(_trailVfmt);
|
||||
}
|
||||
|
||||
void Particle3DAssembler::setTrailVertexFormat(VertexFormat *vfmt)
|
||||
{
|
||||
if (_trailVfmt == vfmt) return;
|
||||
CC_SAFE_RETAIN(vfmt);
|
||||
CC_SAFE_RELEASE(_trailVfmt);
|
||||
_trailVfmt = vfmt;
|
||||
if (_trailVfmt)
|
||||
{
|
||||
_trailVertexBytes = _trailVfmt->getBytes();
|
||||
const VertexFormat::Element* vfPos = _vfmt->getElement(ATTRIB_NAME_POSITION_HASH);
|
||||
_trailPosOffset = vfPos->offset / 4;
|
||||
}
|
||||
}
|
||||
|
||||
void Particle3DAssembler::fillBuffer(NodeProxy *node, MeshBuffer *buffer, const IARenderData& ia, RenderData* data)
|
||||
{
|
||||
CCASSERT(data->getVBytes() % _bytesPerVertex == 0, "Assembler::fillBuffers vertices data doesn't follow vertex format");
|
||||
uint32_t vertexCount = ia.verticesCount >= 0 ? (uint32_t)ia.verticesCount : (uint32_t)data->getVBytes() / _bytesPerVertex;
|
||||
uint32_t indexCount = ia.indicesCount >= 0 ? (uint32_t)ia.indicesCount : (uint32_t)data->getIBytes() / sizeof(unsigned short);
|
||||
uint32_t vertexStart = (uint32_t)ia.verticesStart;
|
||||
|
||||
// must retrieve offset before request
|
||||
auto& bufferOffset = buffer->request(vertexCount, indexCount);
|
||||
uint32_t vBufferOffset = bufferOffset.vByte / sizeof(float);
|
||||
uint32_t indexId = bufferOffset.index;
|
||||
uint32_t vertexId = bufferOffset.vertex;
|
||||
uint32_t vertexOffset = vertexId - vertexStart;
|
||||
|
||||
float* worldVerts = buffer->vData + vBufferOffset;
|
||||
memcpy(worldVerts, data->getVertices() + vertexStart * _bytesPerVertex, vertexCount * _bytesPerVertex);
|
||||
|
||||
// Copy index buffer with vertex offset
|
||||
uint16_t* indices = (uint16_t*)data->getIndices();
|
||||
uint16_t* dst = buffer->iData;
|
||||
for (auto i = 0, j = ia.indicesStart; i < indexCount; ++i, ++j)
|
||||
{
|
||||
dst[indexId++] = vertexOffset + indices[j];
|
||||
}
|
||||
}
|
||||
|
||||
void Particle3DAssembler::fillTrailBuffer(NodeProxy *node, MeshBuffer *buffer, const IARenderData& ia, RenderData* data)
|
||||
{
|
||||
CCASSERT(data->getVBytes() % _trailVertexBytes == 0, "Assembler::fillBuffers vertices data doesn't follow vertex format");
|
||||
uint32_t vertexCount = ia.verticesCount >= 0 ? (uint32_t)ia.verticesCount : (uint32_t)data->getVBytes() / _trailVertexBytes;
|
||||
uint32_t indexCount = ia.indicesCount >= 0 ? (uint32_t)ia.indicesCount : (uint32_t)data->getIBytes() / sizeof(unsigned short);
|
||||
uint32_t vertexStart = (uint32_t)ia.verticesStart;
|
||||
|
||||
// must retrieve offset before request
|
||||
auto& bufferOffset = buffer->request(vertexCount, indexCount);
|
||||
uint32_t vBufferOffset = bufferOffset.vByte / sizeof(float);
|
||||
uint32_t indexId = bufferOffset.index;
|
||||
uint32_t vertexId = bufferOffset.vertex;
|
||||
uint32_t vertexOffset = vertexId - vertexStart;
|
||||
|
||||
float* worldVerts = buffer->vData + vBufferOffset;
|
||||
memcpy(worldVerts, data->getVertices() + vertexStart * _trailVertexBytes, vertexCount * _trailVertexBytes);
|
||||
|
||||
// Copy index buffer with vertex offset
|
||||
uint16_t* indices = (uint16_t*)data->getIndices();
|
||||
uint16_t* dst = buffer->iData;
|
||||
for (auto i = 0, j = ia.indicesStart; i < indexCount; ++i, ++j)
|
||||
{
|
||||
dst[indexId++] = vertexOffset + indices[j];
|
||||
}
|
||||
}
|
||||
|
||||
void Particle3DAssembler::fillBuffers(NodeProxy *node, ModelBatcher *batcher, std::size_t index)
|
||||
{
|
||||
VertexFormat* vfmt = index == 0 ? _vfmt : _trailVfmt;
|
||||
|
||||
if (!_datas || !vfmt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MeshBuffer* buffer = batcher->getBuffer(vfmt);
|
||||
|
||||
const IARenderData& ia = _iaDatas[index];
|
||||
std::size_t meshIndex = ia.meshIndex >= 0 ? ia.meshIndex : index;
|
||||
|
||||
RenderData* data = _datas->getRenderData(meshIndex);
|
||||
if (!data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (index != 0)
|
||||
{
|
||||
fillTrailBuffer(node, buffer, ia, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
fillBuffer(node, buffer, ia, data);
|
||||
}
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Assembler.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class NodeProxy;
|
||||
class ModelBatcher;
|
||||
|
||||
enum class Space: uint8_t
|
||||
{
|
||||
WORLD = 0,
|
||||
LOCAL = 1,
|
||||
CUSTOM = 2
|
||||
};
|
||||
|
||||
class Particle3DAssembler: public Assembler
|
||||
{
|
||||
public:
|
||||
Particle3DAssembler();
|
||||
~Particle3DAssembler();
|
||||
|
||||
virtual void fillBuffers(NodeProxy *node, ModelBatcher *batcher, std::size_t index) override;
|
||||
void setTrailVertexFormat(VertexFormat* vfmt);
|
||||
void setTrailModuleEnable(bool enable) {_trailModuleEnable = enable;};
|
||||
|
||||
void setParticleSpace(Space space) {_particleSpace = space;};
|
||||
void setTrailSpace(Space space) {_trailSpace = space;};
|
||||
private:
|
||||
void fillBuffer(NodeProxy *node, MeshBuffer *buffer, const IARenderData& ia, RenderData* data);
|
||||
void fillTrailBuffer(NodeProxy *node, MeshBuffer *buffer, const IARenderData& ia, RenderData* data);
|
||||
|
||||
private:
|
||||
Space _particleSpace = Space::LOCAL;
|
||||
Space _trailSpace = Space::LOCAL;
|
||||
|
||||
uint32_t _trailVertexBytes = 0;
|
||||
size_t _trailPosOffset = 0;
|
||||
bool _trailModuleEnable = false;
|
||||
|
||||
VertexFormat* _trailVfmt = nullptr;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
126
cocos2d-x/cocos/renderer/scene/assembler/RenderData.cpp
Normal file
126
cocos2d-x/cocos/renderer/scene/assembler/RenderData.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "RenderData.hpp"
|
||||
#include "../../renderer/Effect.h"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
RenderData::RenderData ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RenderData::RenderData (const RenderData& o)
|
||||
{
|
||||
setVertices(o._jsVertices);
|
||||
setIndices(o._jsIndices);
|
||||
}
|
||||
|
||||
RenderData::~RenderData ()
|
||||
{
|
||||
if(_jsVertices != nullptr)
|
||||
{
|
||||
_jsVertices->unroot();
|
||||
_jsVertices->decRef();
|
||||
_jsVertices = nullptr;
|
||||
_vertices = nullptr;
|
||||
_vBytes = 0;
|
||||
}
|
||||
|
||||
if(_jsIndices != nullptr)
|
||||
{
|
||||
_jsIndices->unroot();
|
||||
_jsIndices->decRef();
|
||||
_jsIndices = nullptr;
|
||||
_indices = nullptr;
|
||||
_iBytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderData::setVertices (se::Object* jsVertices)
|
||||
{
|
||||
if (!jsVertices || jsVertices == _jsVertices) return;
|
||||
if (_jsVertices)
|
||||
{
|
||||
_jsVertices->unroot();
|
||||
_jsVertices->decRef();
|
||||
}
|
||||
_jsVertices = jsVertices;
|
||||
_jsVertices->root();
|
||||
_jsVertices->incRef();
|
||||
_vertices = nullptr;
|
||||
_vBytes = 0;
|
||||
_jsVertices->getTypedArrayData(&_vertices, (std::size_t*)&_vBytes);
|
||||
}
|
||||
|
||||
void RenderData::setIndices (se::Object* jsIndices)
|
||||
{
|
||||
if (!jsIndices || jsIndices == _jsIndices) return;
|
||||
if (_jsIndices)
|
||||
{
|
||||
_jsIndices->unroot();
|
||||
_jsIndices->decRef();
|
||||
}
|
||||
_jsIndices = jsIndices;
|
||||
_jsIndices->root();
|
||||
_jsIndices->incRef();
|
||||
_indices = nullptr;
|
||||
_iBytes = 0;
|
||||
_jsIndices->getTypedArrayData(&_indices, (std::size_t*)&_iBytes);
|
||||
}
|
||||
|
||||
uint8_t* RenderData::getVertices () const
|
||||
{
|
||||
return _vertices;
|
||||
}
|
||||
|
||||
uint8_t* RenderData::getIndices () const
|
||||
{
|
||||
return _indices;
|
||||
}
|
||||
|
||||
void RenderData::clear()
|
||||
{
|
||||
if(_jsVertices != nullptr)
|
||||
{
|
||||
_jsVertices->unroot();
|
||||
_jsVertices->decRef();
|
||||
_jsVertices = nullptr;
|
||||
}
|
||||
|
||||
if(_jsIndices != nullptr)
|
||||
{
|
||||
_jsIndices->unroot();
|
||||
_jsIndices->decRef();
|
||||
_jsIndices = nullptr;
|
||||
}
|
||||
|
||||
_vBytes = 0;
|
||||
_iBytes = 0;
|
||||
_vertices = nullptr;
|
||||
_indices = nullptr;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
66
cocos2d-x/cocos/renderer/scene/assembler/RenderData.hpp
Normal file
66
cocos2d-x/cocos/renderer/scene/assembler/RenderData.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include "base/CCRef.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace se {
|
||||
class Object;
|
||||
class HandleObject;
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class Effect;
|
||||
|
||||
class RenderData {
|
||||
public:
|
||||
RenderData ();
|
||||
RenderData (const RenderData& o);
|
||||
virtual ~RenderData ();
|
||||
|
||||
void setVertices (se::Object* jsVertices);
|
||||
void setIndices (se::Object* jsIndices);
|
||||
|
||||
uint8_t* getVertices () const;
|
||||
uint8_t* getIndices () const;
|
||||
|
||||
unsigned long getVBytes () { return _vBytes; }
|
||||
unsigned long getIBytes () { return _iBytes; }
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
unsigned long _vBytes = 0;
|
||||
unsigned long _iBytes = 0;
|
||||
uint8_t* _vertices = nullptr;
|
||||
uint8_t* _indices = nullptr;
|
||||
se::Object* _jsVertices = nullptr;
|
||||
se::Object* _jsIndices = nullptr;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
63
cocos2d-x/cocos/renderer/scene/assembler/RenderDataList.cpp
Normal file
63
cocos2d-x/cocos/renderer/scene/assembler/RenderDataList.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "RenderDataList.hpp"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
void RenderDataList::updateMesh(std::size_t index, se_object_ptr vertices, se_object_ptr indices)
|
||||
{
|
||||
if (index >= _datas.size())
|
||||
{
|
||||
_datas.resize(index + 1);
|
||||
}
|
||||
|
||||
se::ScriptEngine::getInstance()->clearException();
|
||||
se::AutoHandleScope hs;
|
||||
|
||||
RenderData& data = _datas[index];
|
||||
data.setVertices(vertices);
|
||||
data.setIndices(indices);
|
||||
}
|
||||
|
||||
RenderData* RenderDataList::getRenderData(std::size_t index)
|
||||
{
|
||||
if (index >= _datas.size())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return &_datas[index];
|
||||
}
|
||||
|
||||
void RenderDataList::clear()
|
||||
{
|
||||
for (auto it = _datas.begin(); it != _datas.end(); it++)
|
||||
{
|
||||
it->clear();
|
||||
}
|
||||
_datas.clear();
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
68
cocos2d-x/cocos/renderer/scene/assembler/RenderDataList.hpp
Normal file
68
cocos2d-x/cocos/renderer/scene/assembler/RenderDataList.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base/CCRef.h"
|
||||
#include <vector>
|
||||
#include "RenderData.hpp"
|
||||
#include "scripting/js-bindings/jswrapper/Object.hpp"
|
||||
|
||||
namespace se {
|
||||
class Object;
|
||||
class HandleObject;
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class RenderDataList: public cocos2d::Ref {
|
||||
public:
|
||||
RenderDataList () {}
|
||||
virtual ~RenderDataList() {}
|
||||
/**
|
||||
* @brief Update the mesh data for the given index.
|
||||
* @param[in] index Render data index.
|
||||
* @param[in] vertices Vertex data.
|
||||
* @param[in] indices Index data.
|
||||
*/
|
||||
void updateMesh(std::size_t index, se_object_ptr vertices, se_object_ptr indices);
|
||||
/**
|
||||
* @brief Gets the count of render datas
|
||||
* @return Count.
|
||||
*/
|
||||
std::size_t getMeshCount() const { return _datas.size(); };
|
||||
/**
|
||||
* @brief Gets IARenderData.
|
||||
* @return IARenderData.
|
||||
*/
|
||||
RenderData* getRenderData(std::size_t index);
|
||||
/**
|
||||
* @brief Resets all IARenderData.
|
||||
*/
|
||||
void clear();
|
||||
private:
|
||||
std::vector<RenderData> _datas;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user