初始化

This commit is contained in:
SmallMain
2022-06-25 00:23:03 +08:00
commit ef0589e8e5
2264 changed files with 617829 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

View 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"

View 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"

View 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?>";
}

View 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);

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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"

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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