mirror of https://github.com/axmolengine/axmol.git
issue #1555:add CCDrawNode
This commit is contained in:
parent
6159a8b592
commit
d2a5723973
|
@ -403,7 +403,6 @@ void CCDirector::setAlphaBlending(bool bOn)
|
|||
{
|
||||
if (bOn)
|
||||
{
|
||||
ccGLEnable(CC_GL_BLEND);
|
||||
ccGLBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -82,7 +82,7 @@ CCNode::CCNode(void)
|
|||
, m_nScriptHandler(0)
|
||||
, m_pShaderProgram(NULL)
|
||||
, m_nOrderOfArrival(0)
|
||||
, m_glServerState(CC_GL_BLEND)
|
||||
, m_glServerState(ccGLServerState(0))
|
||||
, m_bReorderChildDirty(false)
|
||||
{
|
||||
// set default scheduler and actionManager
|
||||
|
@ -537,9 +537,9 @@ void CCNode::addChild(CCNode *child)
|
|||
this->addChild(child, child->m_nZOrder, child->m_nTag);
|
||||
}
|
||||
|
||||
void CCNode::removeFromParent()
|
||||
{
|
||||
this->removeFromParentAndCleanup(true);
|
||||
void CCNode::removeFromParent()
|
||||
{
|
||||
this->removeFromParentAndCleanup(true);
|
||||
}
|
||||
|
||||
void CCNode::removeFromParentAndCleanup(bool cleanup)
|
||||
|
@ -1144,11 +1144,11 @@ CCPoint CCNode::convertTouchToNodeSpaceAR(CCTouch *touch)
|
|||
return this->convertToNodeSpaceAR(point);
|
||||
}
|
||||
|
||||
// MARMALADE ADDED
|
||||
void CCNode::updateTransform()
|
||||
{
|
||||
// Recursively iterate over children
|
||||
arrayMakeObjectsPerformSelector(m_pChildren, updateTransform, CCNode*);
|
||||
// MARMALADE ADDED
|
||||
void CCNode::updateTransform()
|
||||
{
|
||||
// Recursively iterate over children
|
||||
arrayMakeObjectsPerformSelector(m_pChildren, updateTransform, CCNode*);
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
/* Copyright (c) 2012 Scott Lembcke and Howling Moon Software
|
||||
* Copyright (c) 2012 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 "CCDrawNode.h"
|
||||
#include "support/CCPointExtension.h"
|
||||
#include "shaders/CCShaderCache.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
// ccVertex2F == CGPoint in 32-bits, but not in 64-bits (OS X)
|
||||
// that's why the "v2f" functions are needed
|
||||
static ccVertex2F v2fzero = (ccVertex2F){0,0};
|
||||
|
||||
static inline ccVertex2F v2f(float x, float y)
|
||||
{
|
||||
return (ccVertex2F){x,y};
|
||||
}
|
||||
|
||||
static inline ccVertex2F v2fadd(const ccVertex2F &v0, const ccVertex2F &v1)
|
||||
{
|
||||
return v2f(v0.x+v1.x, v0.y+v1.y);
|
||||
}
|
||||
|
||||
static inline ccVertex2F v2fsub(const ccVertex2F &v0, const ccVertex2F &v1)
|
||||
{
|
||||
return v2f(v0.x-v1.x, v0.y-v1.y);
|
||||
}
|
||||
|
||||
static inline ccVertex2F v2fmult(const ccVertex2F &v, float s)
|
||||
{
|
||||
return v2f(v.x * s, v.y * s);
|
||||
}
|
||||
|
||||
static inline ccVertex2F v2fperp(const ccVertex2F &p0)
|
||||
{
|
||||
return v2f(-p0.y, p0.x);
|
||||
}
|
||||
|
||||
static inline ccVertex2F v2fneg(const ccVertex2F &p0)
|
||||
{
|
||||
return v2f(-p0.x, - p0.y);
|
||||
}
|
||||
|
||||
static inline float v2fdot(const ccVertex2F &p0, const ccVertex2F &p1)
|
||||
{
|
||||
return p0.x * p1.x + p0.y * p1.y;
|
||||
}
|
||||
|
||||
static inline ccVertex2F v2fforangle(float _a_)
|
||||
{
|
||||
return v2f(cosf(_a_), sinf(_a_));
|
||||
}
|
||||
|
||||
static inline ccVertex2F v2fnormalize(const ccVertex2F &p)
|
||||
{
|
||||
CCPoint r = ccpNormalize(ccp(p.x, p.y));
|
||||
return v2f(r.x, r.y);
|
||||
}
|
||||
|
||||
static inline ccVertex2F __v2f(const CCPoint &v)
|
||||
{
|
||||
#ifdef __LP64__
|
||||
return v2f(v.x, v.y);
|
||||
#else
|
||||
return * ((ccVertex2F*) &v);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline ccTex2F __t(const ccVertex2F &v)
|
||||
{
|
||||
return *(ccTex2F*)&v;
|
||||
}
|
||||
|
||||
// implementation of CCDrawNode
|
||||
|
||||
CCDrawNode::CCDrawNode()
|
||||
: m_uVao(0)
|
||||
, m_uVbo(0)
|
||||
, m_uBufferCapacity(0)
|
||||
, m_nBufferCount(0)
|
||||
, m_pBuffer(NULL)
|
||||
, m_sBlendFunc((ccBlendFunc){CC_BLEND_SRC, CC_BLEND_DST})
|
||||
, m_bDirty(false)
|
||||
{}
|
||||
|
||||
CCDrawNode* CCDrawNode::create()
|
||||
{
|
||||
CCDrawNode* pRet = new CCDrawNode();
|
||||
if (pRet && pRet->init())
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
CC_SAFE_DELETE(pRet);
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
bool CCDrawNode::init()
|
||||
{
|
||||
m_sBlendFunc = (ccBlendFunc){CC_BLEND_SRC, CC_BLEND_DST};
|
||||
|
||||
setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionLengthTexureColor));
|
||||
|
||||
ensureCapacity(512);
|
||||
|
||||
glGenVertexArrays(1, &m_uVao);
|
||||
ccGLBindVAO(m_uVao);
|
||||
|
||||
glGenBuffers(1, &m_uVbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_uVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(ccV2F_C4B_T2F)* m_uBufferCapacity, m_pBuffer, GL_STREAM_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(kCCVertexAttrib_Position);
|
||||
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, vertices));
|
||||
|
||||
glEnableVertexAttribArray(kCCVertexAttrib_Color);
|
||||
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, colors));
|
||||
|
||||
glEnableVertexAttribArray(kCCVertexAttrib_TexCoords);
|
||||
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4B_T2F), (GLvoid *)offsetof(ccV2F_C4B_T2F, texCoords));
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
ccGLBindVAO(0);
|
||||
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
m_bDirty = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_CC_END
|
|
@ -0,0 +1,88 @@
|
|||
/* Copyright (c) 2012 Scott Lembcke and Howling Moon Software
|
||||
* Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Code copied & pasted from SpacePatrol game https://github.com/slembcke/SpacePatrol
|
||||
*
|
||||
* Renamed and added some changes for cocos2d
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CCDRAWNODES_CCDRAW_NODE_H__
|
||||
#define __CCDRAWNODES_CCDRAW_NODE_H__
|
||||
|
||||
#include "base_nodes/CCNode.h"
|
||||
#include "ccTypes.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
/** CCDrawNode
|
||||
Node that draws dots, segments and polygons.
|
||||
Faster than the "drawing primitives" since they it draws everything in one single batch.
|
||||
|
||||
@since v2.1
|
||||
*/
|
||||
class CC_DLL CCDrawNode : public CCNode
|
||||
{
|
||||
protected:
|
||||
GLuint m_uVao;
|
||||
GLuint m_uVbo;
|
||||
|
||||
unsigned int m_uBufferCapacity;
|
||||
GLsizei m_nBufferCount;
|
||||
ccV2F_C4B_T2F *m_pBuffer;
|
||||
|
||||
ccBlendFunc m_sBlendFunc;
|
||||
|
||||
bool m_bDirty;
|
||||
|
||||
public:
|
||||
static CCDrawNode* create();
|
||||
~CCDrawNode();
|
||||
|
||||
virtual bool init();
|
||||
virtual void draw();
|
||||
|
||||
/** draw a dot at a position, with a given radius and color */
|
||||
void drawDot(const CCPoint &pos, float radius, const ccColor4F &color) const;
|
||||
|
||||
/** draw a segment with a radius and color */
|
||||
void drawSegment(const CCPoint &from, const CCPoint &to, float radius, const ccColor4F &color) const;
|
||||
|
||||
/** draw a polygon with a fill color and line color */
|
||||
void drawPolygon(const CCPoint *verts, unsigned int count, const ccColor4F &fillColor, float borderWidth, const ccColor4F &borderColor) const;
|
||||
|
||||
/** Clear the geometry in the node's buffer. */
|
||||
void clear();
|
||||
|
||||
ccBlendFunc getBlendFunc() const;
|
||||
void setBlendFunc(const ccBlendFunc &blendFunc);
|
||||
|
||||
private:
|
||||
CCDrawNode();
|
||||
void ensureCapacity(unsigned int count);
|
||||
void render();
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
||||
#endif // __CCDRAWNODES_CCDRAW_NODE_H__
|
|
@ -83,7 +83,7 @@ void ccDrawPoint( const CCPoint& point )
|
|||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
|
||||
s_pShader->use();
|
||||
s_pShader->setUniformForModelViewProjectionMatrix();
|
||||
s_pShader->setUniformsForBuiltins();
|
||||
|
||||
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
||||
s_pShader->setUniformLocationWith1f(s_nPointSizeLocation, s_fPointSize);
|
||||
|
@ -101,7 +101,7 @@ void ccDrawPoints( const CCPoint *points, unsigned int numberOfPoints )
|
|||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
|
||||
s_pShader->use();
|
||||
s_pShader->setUniformForModelViewProjectionMatrix();
|
||||
s_pShader->setUniformsForBuiltins();
|
||||
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
||||
s_pShader->setUniformLocationWith1f(s_nPointSizeLocation, s_fPointSize);
|
||||
|
||||
|
@ -142,7 +142,7 @@ void ccDrawLine( const CCPoint& origin, const CCPoint& destination )
|
|||
|
||||
s_pShader->use();
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
s_pShader->setUniformForModelViewProjectionMatrix();
|
||||
s_pShader->setUniformsForBuiltins();
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
@ -181,7 +181,7 @@ void ccDrawPoly( const CCPoint *poli, unsigned int numberOfPoints, bool closePol
|
|||
lazy_init();
|
||||
|
||||
s_pShader->use();
|
||||
s_pShader->setUniformForModelViewProjectionMatrix();
|
||||
s_pShader->setUniformsForBuiltins();
|
||||
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
||||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
|
||||
|
@ -223,7 +223,7 @@ void ccDrawSolidPoly( const CCPoint *poli, unsigned int numberOfPoints, ccColor4
|
|||
lazy_init();
|
||||
|
||||
s_pShader->use();
|
||||
s_pShader->setUniformForModelViewProjectionMatrix();
|
||||
s_pShader->setUniformsForBuiltins();
|
||||
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &color.r, 1);
|
||||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
|
||||
|
@ -278,7 +278,7 @@ void ccDrawCircle( const CCPoint& center, float radius, float angle, unsigned in
|
|||
vertices[(segments+1)*2+1] = center.y;
|
||||
|
||||
s_pShader->use();
|
||||
s_pShader->setUniformForModelViewProjectionMatrix();
|
||||
s_pShader->setUniformsForBuiltins();
|
||||
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
||||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
|
||||
|
@ -313,7 +313,7 @@ void ccDrawQuadBezier(const CCPoint& origin, const CCPoint& control, const CCPoi
|
|||
vertices[segments].y = destination.y;
|
||||
|
||||
s_pShader->use();
|
||||
s_pShader->setUniformForModelViewProjectionMatrix();
|
||||
s_pShader->setUniformsForBuiltins();
|
||||
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
||||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
|
||||
|
@ -365,7 +365,7 @@ void ccDrawCardinalSpline( CCPointArray *config, float tension, unsigned int se
|
|||
}
|
||||
|
||||
s_pShader->use();
|
||||
s_pShader->setUniformForModelViewProjectionMatrix();
|
||||
s_pShader->setUniformsForBuiltins();
|
||||
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*)&s_tColor.r, 1);
|
||||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
|
||||
|
@ -394,7 +394,7 @@ void ccDrawCubicBezier(const CCPoint& origin, const CCPoint& control1, const CCP
|
|||
vertices[segments].y = destination.y;
|
||||
|
||||
s_pShader->use();
|
||||
s_pShader->setUniformForModelViewProjectionMatrix();
|
||||
s_pShader->setUniformsForBuiltins();
|
||||
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
||||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
|
|
@ -337,7 +337,7 @@ void CCGrid3D::blit(void)
|
|||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_TexCoords );
|
||||
m_pShaderProgram->use();
|
||||
m_pShaderProgram->setUniformForModelViewProjectionMatrix();;
|
||||
m_pShaderProgram->setUniformsForBuiltins();;
|
||||
|
||||
//
|
||||
// Attributes
|
||||
|
@ -542,7 +542,7 @@ void CCTiledGrid3D::blit(void)
|
|||
|
||||
|
||||
m_pShaderProgram->use();
|
||||
m_pShaderProgram->setUniformForModelViewProjectionMatrix();
|
||||
m_pShaderProgram->setUniformsForBuiltins();
|
||||
|
||||
//
|
||||
// Attributes
|
||||
|
|
|
@ -88,7 +88,7 @@ do { \
|
|||
CCAssert(getShaderProgram(), "No shader program set for this node"); \
|
||||
{ \
|
||||
getShaderProgram()->use(); \
|
||||
getShaderProgram()->setUniformForModelViewProjectionMatrix(); \
|
||||
getShaderProgram()->setUniformsForBuiltins(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@ THE SOFTWARE.
|
|||
#include "cocoa/CCNS.h"
|
||||
#include "cocoa/CCZone.h"
|
||||
|
||||
// draw nodes
|
||||
#include "draw_nodes/CCDrawingPrimitives.h"
|
||||
|
||||
// effects
|
||||
#include "effects/CCGrabber.h"
|
||||
#include "effects/CCGrid.h"
|
||||
|
|
|
@ -242,7 +242,7 @@ void CCLayer::setAccelerometerInterval(double interval) {
|
|||
{
|
||||
if (m_bIsRunning)
|
||||
{
|
||||
CCDirector* pDirector = CCDirector::sharedDirector();
|
||||
// CCDirector* pDirector = CCDirector::sharedDirector();
|
||||
// pDirector->getAccelerometer()->setAccelerometerInterval(interval);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "shaders/CCGLProgram.h"
|
||||
#include "shaders/CCShaderCache.h"
|
||||
#include "CCDirector.h"
|
||||
#include "support/CCPointExtension.h"
|
||||
#include "draw_nodes/CCDrawingPrimitives.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -358,4 +360,36 @@ void CCClippingNode::visit()
|
|||
layer--;
|
||||
}
|
||||
|
||||
CCNode* CCClippingNode::getStencil() const
|
||||
{
|
||||
return m_pStencil;
|
||||
}
|
||||
|
||||
void CCClippingNode::setStencil(CCNode *pStencil)
|
||||
{
|
||||
CC_SAFE_RELEASE(m_pStencil);
|
||||
m_pStencil = pStencil;
|
||||
CC_SAFE_RETAIN(m_pStencil);
|
||||
}
|
||||
|
||||
GLfloat CCClippingNode::getAlphaThreshold() const
|
||||
{
|
||||
return m_fAlphaThreshold;
|
||||
}
|
||||
|
||||
void CCClippingNode::setAlphaThreshold(GLfloat fAlphaThreshold)
|
||||
{
|
||||
m_fAlphaThreshold = fAlphaThreshold;
|
||||
}
|
||||
|
||||
bool CCClippingNode::isInverted() const
|
||||
{
|
||||
return m_bInverted;
|
||||
}
|
||||
|
||||
void CCClippingNode::setInverted(bool bInverted)
|
||||
{
|
||||
m_bInverted = bInverted;
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
The stencil node will be retained.
|
||||
This default to nil.
|
||||
*/
|
||||
CCNode* getStencil();
|
||||
CCNode* getStencil() const;
|
||||
void setStencil(CCNode *pStencil);
|
||||
|
||||
/** The alpha threshold.
|
||||
|
@ -84,15 +84,15 @@ public:
|
|||
Should be a float between 0 and 1.
|
||||
This default to 1 (so alpha test is disabled).
|
||||
*/
|
||||
GLfloat getAlphaThreshold();
|
||||
GLfloat getAlphaThreshold() const;
|
||||
void setAlphaThreshold(GLfloat fAlphaThreshold);
|
||||
|
||||
/** Inverted. If this is set to YES,
|
||||
the stencil is inverted, so the content is drawn where the stencil is NOT drawn.
|
||||
This default to NO.
|
||||
*/
|
||||
bool isInverted();
|
||||
bool setInverted(bool bInverted);
|
||||
bool isInverted() const;
|
||||
void setInverted(bool bInverted);
|
||||
|
||||
private:
|
||||
CCClippingNode();
|
||||
|
|
|
@ -1 +1 @@
|
|||
a63972a39f79cdc3fd02e88518f0e17da54554ae
|
||||
2ca5fe7b3dd190dca76cc6d572d7c910f560e9ff
|
|
@ -25,6 +25,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "CCDirector.h"
|
||||
#include "CCGLProgram.h"
|
||||
#include "ccGLStateCache.h"
|
||||
#include "ccMacros.h"
|
||||
|
@ -58,8 +59,8 @@ CCGLProgram::~CCGLProgram()
|
|||
CCLOGINFO("cocos2d: %s %d deallocing 0x%X", __FUNCTION__, __LINE__, this);
|
||||
|
||||
// there is no need to delete the shaders. They should have been already deleted.
|
||||
CCAssert( m_uVertShader == 0, "Vertex Shaders should have been already deleted");
|
||||
CCAssert( m_uFragShader == 0, "Vertex Shaders should have been already deleted");
|
||||
CCAssert(m_uVertShader == 0, "Vertex Shaders should have been already deleted");
|
||||
CCAssert(m_uFragShader == 0, "Fragment Shaders should have been already deleted");
|
||||
|
||||
if (m_uProgram)
|
||||
{
|
||||
|
@ -69,7 +70,8 @@ CCGLProgram::~CCGLProgram()
|
|||
tHashUniformEntry *current_element, *tmp;
|
||||
|
||||
// Purge uniform hash
|
||||
HASH_ITER(hh, m_pHashForUniforms, current_element, tmp) {
|
||||
HASH_ITER(hh, m_pHashForUniforms, current_element, tmp)
|
||||
{
|
||||
HASH_DEL(m_pHashForUniforms, current_element);
|
||||
free(current_element->value);
|
||||
free(current_element);
|
||||
|
@ -83,28 +85,34 @@ bool CCGLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray,
|
|||
|
||||
m_uVertShader = m_uFragShader = 0;
|
||||
|
||||
if( vShaderByteArray ) {
|
||||
if (vShaderByteArray)
|
||||
{
|
||||
|
||||
if (!compileShader(&m_uVertShader, GL_VERTEX_SHADER, vShaderByteArray)) {
|
||||
if (!compileShader(&m_uVertShader, GL_VERTEX_SHADER, vShaderByteArray))
|
||||
{
|
||||
CCLOG("cocos2d: ERROR: Failed to compile vertex shader");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create and compile fragment shader
|
||||
if( fShaderByteArray ) {
|
||||
if (fShaderByteArray)
|
||||
{
|
||||
|
||||
if (!compileShader(&m_uFragShader, GL_FRAGMENT_SHADER, fShaderByteArray)) {
|
||||
if (!compileShader(&m_uFragShader, GL_FRAGMENT_SHADER, fShaderByteArray))
|
||||
{
|
||||
CCLOG("cocos2d: ERROR: Failed to compile fragment shader");
|
||||
}
|
||||
}
|
||||
|
||||
if( m_uVertShader ) {
|
||||
if (m_uVertShader)
|
||||
{
|
||||
glAttachShader(m_uProgram, m_uVertShader);
|
||||
}
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
if( m_uFragShader ) {
|
||||
if (m_uFragShader)
|
||||
{
|
||||
glAttachShader(m_uProgram, m_uFragShader);
|
||||
}
|
||||
m_pHashForUniforms = NULL;
|
||||
|
@ -132,10 +140,27 @@ bool CCGLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* sour
|
|||
GLint status;
|
||||
|
||||
if (!source)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const GLchar *sources[] = {
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
(type == GL_VERTEX_SHADER ? "precision highp float;\n" : "precision mediump float;\n"),
|
||||
#endif
|
||||
"uniform mat4 CC_PMatrix;\n"
|
||||
"uniform mat4 CC_MVMatrix;\n"
|
||||
"uniform mat4 CC_MVPMatrix;\n"
|
||||
"uniform vec4 CC_Time;\n"
|
||||
"uniform vec4 CC_SinTime;\n"
|
||||
"uniform vec4 CC_CosTime;\n"
|
||||
"uniform vec4 CC_Random01;\n"
|
||||
"//CC INCLUDES END\n\n",
|
||||
source,
|
||||
};
|
||||
|
||||
*shader = glCreateShader(type);
|
||||
glShaderSource(*shader, 1, &source, NULL);
|
||||
glShaderSource(*shader, sizeof(sources)/sizeof(*sources), sources, NULL);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
glCompileShader(*shader);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
@ -143,64 +168,93 @@ bool CCGLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* sour
|
|||
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
if( ! status ) {
|
||||
if( type == GL_VERTEX_SHADER )
|
||||
CCLOG("cocos2d: %s", vertexShaderLog() );
|
||||
if (! status)
|
||||
{
|
||||
GLsizei length;
|
||||
glGetShaderiv(*shader, GL_SHADER_SOURCE_LENGTH, &length);
|
||||
GLchar src[length];
|
||||
|
||||
glGetShaderSource(*shader, length, NULL, src);
|
||||
CCLOG("cocos2d: ERROR: Failed to compile shader:\n%s", src);
|
||||
|
||||
if (type == GL_VERTEX_SHADER)
|
||||
{
|
||||
CCLOG("cocos2d: %s", vertexShaderLog());
|
||||
}
|
||||
else
|
||||
CCLOG("cocos2d: %s", fragmentShaderLog() );
|
||||
{
|
||||
CCLOG("cocos2d: %s", fragmentShaderLog());
|
||||
}
|
||||
|
||||
|
||||
abort();
|
||||
}
|
||||
return ( status == GL_TRUE );
|
||||
}
|
||||
|
||||
void CCGLProgram::addAttribute(const char* attributeName, GLuint index)
|
||||
{
|
||||
glBindAttribLocation(m_uProgram,
|
||||
index,
|
||||
attributeName);
|
||||
glBindAttribLocation(m_uProgram, index, attributeName);
|
||||
}
|
||||
|
||||
void CCGLProgram::updateUniforms()
|
||||
{
|
||||
// Since sample most probably won't change, set it to 0 now.
|
||||
|
||||
m_uUniforms[kCCUniformMVPMatrix] = glGetUniformLocation(m_uProgram, kCCUniformMVPMatrix_s);
|
||||
m_uUniforms[kCCUniformPMatrix] = glGetUniformLocation(m_uProgram, kCCUniformPMatrix_s);
|
||||
m_uUniforms[kCCUniformMVMatrix] = glGetUniformLocation(m_uProgram, kCCUniformMVMatrix_s);
|
||||
m_uUniforms[kCCUniformMVPMatrix] = glGetUniformLocation(m_uProgram, kCCUniformMVPMatrix_s);
|
||||
|
||||
m_uUniforms[kCCUniformTime] = glGetUniformLocation(m_uProgram, kCCUniformTime_s);
|
||||
m_uUniforms[kCCUniformSinTime] = glGetUniformLocation(m_uProgram, kCCUniformSinTime_s);
|
||||
m_uUniforms[kCCUniformCosTime] = glGetUniformLocation(m_uProgram, kCCUniformCosTime_s);
|
||||
|
||||
m_bUsesTime = (
|
||||
m_uUniforms[kCCUniformTime] != -1 ||
|
||||
m_uUniforms[kCCUniformSinTime] != -1 ||
|
||||
m_uUniforms[kCCUniformCosTime] != -1
|
||||
);
|
||||
|
||||
m_uUniforms[kCCUniformRandom01] = glGetUniformLocation(m_uProgram, kCCUniformRandom01_s);
|
||||
|
||||
m_uUniforms[kCCUniformSampler] = glGetUniformLocation(m_uProgram, kCCUniformSampler_s);
|
||||
|
||||
this->use();
|
||||
this->setUniformLocationWith1i( m_uUniforms[kCCUniformSampler], 0 );
|
||||
|
||||
// Since sample most probably won't change, set it to 0 now.
|
||||
this->setUniformLocationWith1i(m_uUniforms[kCCUniformSampler], 0);
|
||||
}
|
||||
|
||||
bool CCGLProgram::link()
|
||||
{
|
||||
CCAssert(m_uProgram != 0, "Cannot link invalid program");
|
||||
|
||||
GLint status = GL_TRUE;
|
||||
|
||||
glLinkProgram(m_uProgram);
|
||||
|
||||
if (m_uVertShader)
|
||||
{
|
||||
glDeleteShader(m_uVertShader);
|
||||
}
|
||||
|
||||
if (m_uFragShader)
|
||||
{
|
||||
glDeleteShader(m_uFragShader);
|
||||
}
|
||||
|
||||
m_uVertShader = m_uFragShader = 0;
|
||||
|
||||
#if DEBUG
|
||||
GLint status;
|
||||
glValidateProgram(m_uProgram);
|
||||
|
||||
glGetProgramiv(m_uProgram, GL_LINK_STATUS, &status);
|
||||
if (status == GL_FALSE) {
|
||||
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
CCLOG("cocos2d: ERROR: Failed to link program: %i", m_uProgram);
|
||||
if( m_uVertShader )
|
||||
glDeleteShader( m_uVertShader );
|
||||
if( m_uFragShader )
|
||||
glDeleteShader( m_uFragShader );
|
||||
ccGLDeleteProgram( m_uProgram );
|
||||
m_uVertShader = m_uFragShader = m_uProgram = 0;
|
||||
return false;
|
||||
ccGLDeleteProgram(m_uProgram);
|
||||
m_uProgram = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_uVertShader)
|
||||
glDeleteShader(m_uVertShader);
|
||||
if (m_uFragShader)
|
||||
glDeleteShader(m_uFragShader);
|
||||
|
||||
m_uVertShader = m_uFragShader = 0;
|
||||
|
||||
return true;
|
||||
|
||||
return (status == GL_TRUE);
|
||||
}
|
||||
|
||||
void CCGLProgram::use()
|
||||
|
@ -242,14 +296,19 @@ const char* CCGLProgram::programLog()
|
|||
|
||||
// Uniform cache
|
||||
|
||||
bool CCGLProgram::updateUniformLocation(unsigned int location, GLvoid* data, unsigned int bytes)
|
||||
bool CCGLProgram::updateUniformLocation(GLint location, GLvoid* data, unsigned int bytes)
|
||||
{
|
||||
if (location < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool updated = true;
|
||||
tHashUniformEntry *element = NULL;
|
||||
HASH_FIND_INT(m_pHashForUniforms, &location, element);
|
||||
|
||||
if( ! element ) {
|
||||
|
||||
if (! element)
|
||||
{
|
||||
element = (tHashUniformEntry*)malloc( sizeof(*element) );
|
||||
|
||||
// key
|
||||
|
@ -263,16 +322,20 @@ bool CCGLProgram::updateUniformLocation(unsigned int location, GLvoid* data, uns
|
|||
}
|
||||
else
|
||||
{
|
||||
if( memcmp( element->value, data, bytes) == 0 )
|
||||
if (memcmp(element->value, data, bytes) == 0)
|
||||
{
|
||||
updated = false;
|
||||
}
|
||||
else
|
||||
memcpy( element->value, data, bytes );
|
||||
{
|
||||
memcpy(element->value, data, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
void CCGLProgram::setUniformLocationWith1i(unsigned int location, GLint i1)
|
||||
void CCGLProgram::setUniformLocationWith1i(GLint location, GLint i1)
|
||||
{
|
||||
bool updated = updateUniformLocation(location, &i1, sizeof(i1)*1);
|
||||
|
||||
|
@ -282,7 +345,7 @@ void CCGLProgram::setUniformLocationWith1i(unsigned int location, GLint i1)
|
|||
}
|
||||
}
|
||||
|
||||
void CCGLProgram::setUniformLocationWith1f(unsigned int location, GLfloat f1)
|
||||
void CCGLProgram::setUniformLocationWith1f(GLint location, GLfloat f1)
|
||||
{
|
||||
bool updated = updateUniformLocation(location, &f1, sizeof(f1)*1);
|
||||
|
||||
|
@ -292,7 +355,7 @@ void CCGLProgram::setUniformLocationWith1f(unsigned int location, GLfloat f1)
|
|||
}
|
||||
}
|
||||
|
||||
void CCGLProgram::setUniformLocationWith2f(unsigned int location, GLfloat f1, GLfloat f2)
|
||||
void CCGLProgram::setUniformLocationWith2f(GLint location, GLfloat f1, GLfloat f2)
|
||||
{
|
||||
GLfloat floats[2] = {f1,f2};
|
||||
bool updated = updateUniformLocation(location, floats, sizeof(floats));
|
||||
|
@ -303,7 +366,7 @@ void CCGLProgram::setUniformLocationWith2f(unsigned int location, GLfloat f1, GL
|
|||
}
|
||||
}
|
||||
|
||||
void CCGLProgram::setUniformLocationWith3f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3)
|
||||
void CCGLProgram::setUniformLocationWith3f(GLint location, GLfloat f1, GLfloat f2, GLfloat f3)
|
||||
{
|
||||
GLfloat floats[3] = {f1,f2,f3};
|
||||
bool updated = updateUniformLocation(location, floats, sizeof(floats));
|
||||
|
@ -314,7 +377,7 @@ void CCGLProgram::setUniformLocationWith3f(unsigned int location, GLfloat f1, GL
|
|||
}
|
||||
}
|
||||
|
||||
void CCGLProgram::setUniformLocationWith4f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4)
|
||||
void CCGLProgram::setUniformLocationWith4f(GLint location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4)
|
||||
{
|
||||
GLfloat floats[4] = {f1,f2,f3,f4};
|
||||
bool updated = updateUniformLocation(location, floats, sizeof(floats));
|
||||
|
@ -325,7 +388,7 @@ void CCGLProgram::setUniformLocationWith4f(unsigned int location, GLfloat f1, GL
|
|||
}
|
||||
}
|
||||
|
||||
void CCGLProgram::setUniformLocationWith2fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays)
|
||||
void CCGLProgram::setUniformLocationWith2fv(GLint location, GLfloat* floats, unsigned int numberOfArrays)
|
||||
{
|
||||
bool updated = updateUniformLocation(location, floats, sizeof(float)*2*numberOfArrays);
|
||||
|
||||
|
@ -335,7 +398,7 @@ void CCGLProgram::setUniformLocationWith2fv(unsigned int location, GLfloat* floa
|
|||
}
|
||||
}
|
||||
|
||||
void CCGLProgram::setUniformLocationWith3fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays)
|
||||
void CCGLProgram::setUniformLocationWith3fv(GLint location, GLfloat* floats, unsigned int numberOfArrays)
|
||||
{
|
||||
bool updated = updateUniformLocation(location, floats, sizeof(float)*3*numberOfArrays);
|
||||
|
||||
|
@ -345,7 +408,7 @@ void CCGLProgram::setUniformLocationWith3fv(unsigned int location, GLfloat* floa
|
|||
}
|
||||
}
|
||||
|
||||
void CCGLProgram::setUniformLocationWith4fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays)
|
||||
void CCGLProgram::setUniformLocationWith4fv(GLint location, GLfloat* floats, unsigned int numberOfArrays)
|
||||
{
|
||||
bool updated = updateUniformLocation(location, floats, sizeof(float)*4*numberOfArrays);
|
||||
|
||||
|
@ -356,7 +419,7 @@ void CCGLProgram::setUniformLocationWith4fv(unsigned int location, GLfloat* floa
|
|||
}
|
||||
|
||||
|
||||
void CCGLProgram::setUniformLocationwithMatrix4fv(unsigned int location, GLfloat* matrixArray, unsigned int numberOfMatrices)
|
||||
void CCGLProgram::setUniformLocationwithMatrix4fv(GLint location, GLfloat* matrixArray, unsigned int numberOfMatrices)
|
||||
{
|
||||
bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*16*numberOfMatrices);
|
||||
|
||||
|
@ -366,18 +429,43 @@ void CCGLProgram::setUniformLocationwithMatrix4fv(unsigned int location, GLfloat
|
|||
}
|
||||
}
|
||||
|
||||
void CCGLProgram::setUniformForModelViewProjectionMatrix()
|
||||
void CCGLProgram::setUniformsForBuiltins()
|
||||
{
|
||||
kmMat4 matrixP;
|
||||
kmMat4 matrixMV;
|
||||
kmMat4 matrixMVP;
|
||||
kmMat4 matrixMV;
|
||||
kmMat4 matrixMVP;
|
||||
|
||||
kmGLGetMatrix(KM_GL_PROJECTION, &matrixP);
|
||||
kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV);
|
||||
|
||||
kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV);
|
||||
|
||||
setUniformLocationWith4fv(m_uUniforms[kCCUniformPMatrix], matrixP.mat, 1);
|
||||
setUniformLocationWith4fv(m_uUniforms[kCCUniformMVMatrix], matrixMV.mat, 1);
|
||||
setUniformLocationWith4fv(m_uUniforms[kCCUniformMVPMatrix], matrixMVP.mat, 1);
|
||||
|
||||
if(m_bUsesTime)
|
||||
{
|
||||
CCDirector *director = CCDirector::sharedDirector();
|
||||
// This doesn't give the most accurate global time value.
|
||||
// Cocos2D doesn't store a high precision time value, so this will have to do.
|
||||
// Getting Mach time per frame per shader using time could be extremely expensive.
|
||||
float time = director->getTotalFrames() * director->getAnimationInterval();
|
||||
|
||||
setUniformLocationWith4f(m_uUniforms[kCCUniformTime], time/10.0, time, time*2, time*4);
|
||||
setUniformLocationWith4f(m_uUniforms[kCCUniformSinTime], time/8.0, time/4.0, time/2.0, sinf(time));
|
||||
setUniformLocationWith4f(m_uUniforms[kCCUniformCosTime], time/8.0, time/4.0, time/2.0, cosf(time));
|
||||
}
|
||||
|
||||
if (m_uUniforms[kCCUniformRandom01] != -1)
|
||||
{
|
||||
setUniformLocationWith4f(m_uUniforms[kCCUniformRandom01], CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1());
|
||||
}
|
||||
}
|
||||
|
||||
kmGLGetMatrix(KM_GL_PROJECTION, &matrixP );
|
||||
kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV );
|
||||
|
||||
kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV);
|
||||
|
||||
setUniformLocationwithMatrix4fv(m_uUniforms[kCCUniformMVPMatrix], matrixMVP.mat, 1);
|
||||
void CCGLProgram::setUniformForModelViewProjectionMatrix()
|
||||
{
|
||||
setUniformsForBuiltins();
|
||||
}
|
||||
|
||||
void CCGLProgram::reset()
|
||||
|
|
|
@ -49,24 +49,37 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
kCCUniformMVPMatrix,
|
||||
kCCUniformSampler,
|
||||
|
||||
kCCUniform_MAX,
|
||||
kCCUniformPMatrix,
|
||||
kCCUniformMVMatrix,
|
||||
kCCUniformMVPMatrix,
|
||||
kCCUniformTime,
|
||||
kCCUniformSinTime,
|
||||
kCCUniformCosTime,
|
||||
kCCUniformRandom01,
|
||||
kCCUniformSampler,
|
||||
|
||||
kCCUniform_MAX,
|
||||
};
|
||||
|
||||
#define kCCShader_PositionTextureColor "ShaderPositionTextureColor"
|
||||
#define kCCShader_PositionTextureColorAlphaTest "ShaderPositionTextureColorAlphaTest"
|
||||
#define kCCShader_PositionColor "ShaderPositionColor"
|
||||
#define kCCShader_PositionTexture "ShaderPositionTexture"
|
||||
#define kCCShader_PositionTexture_uColor "ShaderPositionTexture_uColor"
|
||||
#define kCCShader_PositionTextureA8Color "ShaderPositionTextureA8Color"
|
||||
#define kCCShader_Position_uColor "ShaderPosition_uColor"
|
||||
#define kCCShader_PositionTextureColor "ShaderPositionTextureColor"
|
||||
#define kCCShader_PositionTextureColorAlphaTest "ShaderPositionTextureColorAlphaTest"
|
||||
#define kCCShader_PositionColor "ShaderPositionColor"
|
||||
#define kCCShader_PositionTexture "ShaderPositionTexture"
|
||||
#define kCCShader_PositionTexture_uColor "ShaderPositionTexture_uColor"
|
||||
#define kCCShader_PositionTextureA8Color "ShaderPositionTextureA8Color"
|
||||
#define kCCShader_Position_uColor "ShaderPosition_uColor"
|
||||
#define kCCShader_PositionLengthTexureColor "ShaderPositionLengthTextureColor"
|
||||
|
||||
// uniform names
|
||||
#define kCCUniformMVPMatrix_s "u_MVPMatrix"
|
||||
#define kCCUniformSampler_s "u_texture"
|
||||
#define kCCUniformAlphaTestValue "u_alpha_value"
|
||||
#define kCCUniformPMatrix_s "CC_PMatrix"
|
||||
#define kCCUniformMVMatrix_s "CC_MVMatrix"
|
||||
#define kCCUniformMVPMatrix_s "CC_MVPMatrix"
|
||||
#define kCCUniformTime_s "CC_Time"
|
||||
#define kCCUniformSinTime_s "CC_SinTime"
|
||||
#define kCCUniformCosTime_s "CC_CosTime"
|
||||
#define kCCUniformRandom01_s "CC_Random01"
|
||||
#define kCCUniformSampler_s "CC_Texture0"
|
||||
#define kCCUniformAlphaTestValue "CC_alpha_value"
|
||||
|
||||
// Attribute names
|
||||
#define kCCAttributeNameColor "a_color"
|
||||
|
@ -87,8 +100,6 @@ typedef void (*GLLogFunction) (GLuint program, GLsizei bufsize, GLsizei* length,
|
|||
class CC_DLL CCGLProgram : public CCObject
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
CCGLProgram();
|
||||
virtual ~CCGLProgram();
|
||||
/** Initializes the CCGLProgram with a vertex and fragment with bytes array */
|
||||
|
@ -101,9 +112,10 @@ public:
|
|||
bool link();
|
||||
/** it will call glUseProgram() */
|
||||
void use();
|
||||
/** It will create 3 uniforms:
|
||||
/** It will create 4 uniforms:
|
||||
- kCCUniformPMatrix
|
||||
- kCCUniformMVMatrix
|
||||
- kCCUniformMVPMatrix
|
||||
- kCCUniformSampler
|
||||
|
||||
And it will bind "kCCUniformSampler" to 0
|
||||
|
@ -111,34 +123,37 @@ public:
|
|||
*/
|
||||
void updateUniforms();
|
||||
/** calls glUniform1i only if the values are different than the previous call for this same shader program. */
|
||||
void setUniformLocationWith1i(unsigned int location, GLint i1);
|
||||
void setUniformLocationWith1i(GLint location, GLint i1);
|
||||
|
||||
/** calls glUniform1f only if the values are different than the previous call for this same shader program. */
|
||||
void setUniformLocationWith1f(unsigned int location, GLfloat f1);
|
||||
void setUniformLocationWith1f(GLint location, GLfloat f1);
|
||||
|
||||
/** calls glUniform2f only if the values are different than the previous call for this same shader program. */
|
||||
void setUniformLocationWith2f(unsigned int location, GLfloat f1, GLfloat f2);
|
||||
void setUniformLocationWith2f(GLint location, GLfloat f1, GLfloat f2);
|
||||
|
||||
/** calls glUniform3f only if the values are different than the previous call for this same shader program. */
|
||||
void setUniformLocationWith3f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3);
|
||||
void setUniformLocationWith3f(GLint location, GLfloat f1, GLfloat f2, GLfloat f3);
|
||||
|
||||
/** calls glUniform4f only if the values are different than the previous call for this same shader program. */
|
||||
void setUniformLocationWith4f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4);
|
||||
void setUniformLocationWith4f(GLint location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4);
|
||||
|
||||
/** calls glUniform2fv only if the values are different than the previous call for this same shader program. */
|
||||
void setUniformLocationWith2fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays);
|
||||
void setUniformLocationWith2fv(GLint location, GLfloat* floats, unsigned int numberOfArrays);
|
||||
|
||||
/** calls glUniform3fv only if the values are different than the previous call for this same shader program. */
|
||||
void setUniformLocationWith3fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays);
|
||||
void setUniformLocationWith3fv(GLint location, GLfloat* floats, unsigned int numberOfArrays);
|
||||
|
||||
/** calls glUniform4fv only if the values are different than the previous call for this same shader program. */
|
||||
void setUniformLocationWith4fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays);
|
||||
void setUniformLocationWith4fv(GLint location, GLfloat* floats, unsigned int numberOfArrays);
|
||||
|
||||
/** calls glUniformMatrix4fv only if the values are different than the previous call for this same shader program. */
|
||||
void setUniformLocationwithMatrix4fv(unsigned int location, GLfloat* matrixArray, unsigned int numberOfMatrices);
|
||||
void setUniformLocationwithMatrix4fv(GLint location, GLfloat* matrixArray, unsigned int numberOfMatrices);
|
||||
|
||||
/** will update the builtin uniforms if they are different than the previous call for this same shader program. */
|
||||
void setUniformsForBuiltins();
|
||||
|
||||
/** will update the MVP matrix on the MVP uniform if it is different than the previous call for this same shader program. */
|
||||
void setUniformForModelViewProjectionMatrix();
|
||||
/** Deprecated alias for setUniformsForBuiltins */
|
||||
CC_DEPRECATED_ATTRIBUTE void setUniformForModelViewProjectionMatrix();
|
||||
|
||||
/** returns the vertexShader error log */
|
||||
const char* vertexShaderLog();
|
||||
|
@ -154,7 +169,7 @@ public:
|
|||
inline const GLuint getProgram() { return m_uProgram; }
|
||||
|
||||
private:
|
||||
bool updateUniformLocation(unsigned int location, GLvoid* data, unsigned int bytes);
|
||||
bool updateUniformLocation(GLint location, GLvoid* data, unsigned int bytes);
|
||||
const char* description();
|
||||
bool compileShader(GLuint * shader, GLenum type, const GLchar* source);
|
||||
const char* logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc);
|
||||
|
@ -163,8 +178,9 @@ private:
|
|||
GLuint m_uProgram;
|
||||
GLuint m_uVertShader;
|
||||
GLuint m_uFragShader;
|
||||
GLint m_uUniforms[kCCUniform_MAX];
|
||||
GLint m_uUniforms[kCCUniform_MAX];
|
||||
struct _hashUniformEntry* m_pHashForUniforms;
|
||||
bool m_bUsesTime;
|
||||
};
|
||||
|
||||
// end of shaders group
|
||||
|
|
|
@ -47,11 +47,10 @@ static bool s_bVertexAttribTexCoords = false;
|
|||
|
||||
static GLuint s_uCurrentShaderProgram = -1;
|
||||
static GLuint s_uCurrentBoundTexture[kCCMaxActiveTexture] = {(GLuint)-1,(GLuint)-1,(GLuint)-1,(GLuint)-1, (GLuint)-1,(GLuint)-1,(GLuint)-1,(GLuint)-1, (GLuint)-1,(GLuint)-1,(GLuint)-1,(GLuint)-1, (GLuint)-1,(GLuint)-1,(GLuint)-1,(GLuint)-1, };
|
||||
static GLenum s_eCurrentActiveTexture = (GL_TEXTURE0 - GL_TEXTURE0);
|
||||
static GLenum s_eBlendingSource = -1;
|
||||
static GLenum s_eBlendingDest = -1;
|
||||
static int s_eGLServerState = 0;
|
||||
|
||||
static GLuint s_uVAO = 0;
|
||||
#endif // CC_ENABLE_GL_STATE_CACHE
|
||||
|
||||
// GL State Cache functions
|
||||
|
@ -69,7 +68,7 @@ void ccGLInvalidateStateCache( void )
|
|||
{
|
||||
s_uCurrentBoundTexture[i] = -1;
|
||||
}
|
||||
s_eCurrentActiveTexture = (GL_TEXTURE0 - GL_TEXTURE0);
|
||||
|
||||
s_eBlendingSource = -1;
|
||||
s_eBlendingDest = -1;
|
||||
s_eGLServerState = 0;
|
||||
|
@ -98,89 +97,112 @@ void ccGLUseProgram( GLuint program )
|
|||
#endif // CC_ENABLE_GL_STATE_CACHE
|
||||
}
|
||||
|
||||
static void SetBlending(GLenum sfactor, GLenum dfactor)
|
||||
{
|
||||
if (sfactor == GL_ONE && dfactor == GL_ZERO)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(sfactor, dfactor);
|
||||
}
|
||||
}
|
||||
|
||||
void ccGLBlendFunc(GLenum sfactor, GLenum dfactor)
|
||||
{
|
||||
#if CC_ENABLE_GL_STATE_CACHE
|
||||
if( sfactor != s_eBlendingSource || dfactor != s_eBlendingDest ) {
|
||||
if (sfactor != s_eBlendingSource || dfactor != s_eBlendingDest)
|
||||
{
|
||||
s_eBlendingSource = sfactor;
|
||||
s_eBlendingDest = dfactor;
|
||||
glBlendFunc( sfactor, dfactor );
|
||||
SetBlending(sfactor, dfactor);
|
||||
}
|
||||
#else
|
||||
glBlendFunc( sfactor, dfactor );
|
||||
SetBlending( sfactor, dfactor );
|
||||
#endif // CC_ENABLE_GL_STATE_CACHE
|
||||
}
|
||||
|
||||
GLenum ccGLGetActiveTexture( void )
|
||||
void ccGLBlendResetToCache(void)
|
||||
{
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
#if CC_ENABLE_GL_STATE_CACHE
|
||||
return s_eCurrentActiveTexture + GL_TEXTURE0;
|
||||
SetBlending(s_eBlendingSource, s_eBlendingDest);
|
||||
#else
|
||||
GLenum activeTexture;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&activeTexture);
|
||||
return activeTexture;
|
||||
#endif
|
||||
SetBlending(CC_BLEND_SRC, CC_BLEND_DST);
|
||||
#endif // CC_ENABLE_GL_STATE_CACHE
|
||||
}
|
||||
|
||||
void ccGLActiveTexture( GLenum textureEnum )
|
||||
void ccGLBindTexture2DN(GLuint textureUnit, GLuint textureId)
|
||||
{
|
||||
#if CC_ENABLE_GL_STATE_CACHE
|
||||
CCAssert( (textureEnum - GL_TEXTURE0) < kCCMaxActiveTexture, "cocos2d ERROR: Increase kCCMaxActiveTexture to kCCMaxActiveTexture!");
|
||||
if( (textureEnum - GL_TEXTURE0) != s_eCurrentActiveTexture ) {
|
||||
s_eCurrentActiveTexture = (textureEnum - GL_TEXTURE0);
|
||||
glActiveTexture( textureEnum );
|
||||
}
|
||||
#else
|
||||
glActiveTexture( textureEnum );
|
||||
#endif
|
||||
}
|
||||
|
||||
void ccGLBindTexture2D( GLuint textureId )
|
||||
{
|
||||
#if CC_ENABLE_GL_STATE_CACHE
|
||||
if( s_uCurrentBoundTexture[ s_eCurrentActiveTexture ] != textureId )
|
||||
CCAssert(textureUnit < kCCMaxActiveTexture, "textureUnit is too big");
|
||||
if( s_uCurrentBoundTexture[textureUnit] != textureId )
|
||||
{
|
||||
s_uCurrentBoundTexture[ s_eCurrentActiveTexture ] = textureId;
|
||||
s_uCurrentBoundTexture[textureUnit] = textureId;
|
||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, textureId );
|
||||
}
|
||||
#else
|
||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, textureId );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ccGLDeleteTexture( GLuint textureId )
|
||||
{
|
||||
ccGLDeleteTextureN(0, textureId);
|
||||
}
|
||||
|
||||
void ccGLDeleteTextureN(GLuint textureUnit, GLuint textureId)
|
||||
{
|
||||
#if CC_ENABLE_GL_STATE_CACHE
|
||||
if( textureId == s_uCurrentBoundTexture[ s_eCurrentActiveTexture ] )
|
||||
s_uCurrentBoundTexture[ s_eCurrentActiveTexture ] = -1;
|
||||
if (s_uCurrentBoundTexture[textureUnit] == textureId)
|
||||
{
|
||||
s_uCurrentBoundTexture[textureUnit] = -1;
|
||||
}
|
||||
#endif // CC_ENABLE_GL_STATE_CACHE
|
||||
|
||||
glDeleteTextures(1, &textureId );
|
||||
}
|
||||
|
||||
void ccGLBindVAO(GLuint vaoId)
|
||||
{
|
||||
#if CC_ENABLE_GL_STATE_CACHE
|
||||
if (s_uVAO != vaoId)
|
||||
{
|
||||
s_uVAO = vaoId;
|
||||
glBindVertexArray(vaoId);
|
||||
}
|
||||
#else
|
||||
glBindVertexArray(vaoId);
|
||||
#endif
|
||||
glDeleteTextures(1, &textureId );
|
||||
}
|
||||
|
||||
void ccGLEnable( ccGLServerState flags )
|
||||
{
|
||||
#if CC_ENABLE_GL_STATE_CACHE
|
||||
|
||||
int enabled = 0;
|
||||
|
||||
/* GL_BLEND */
|
||||
if( (enabled = (flags & CC_GL_BLEND)) != (s_eGLServerState & CC_GL_BLEND) ) {
|
||||
if( enabled ) {
|
||||
glEnable( GL_BLEND );
|
||||
s_eGLServerState |= CC_GL_BLEND;
|
||||
} else {
|
||||
glDisable( GL_BLEND );
|
||||
s_eGLServerState &= ~CC_GL_BLEND;
|
||||
}
|
||||
}
|
||||
// int enabled = 0;
|
||||
//
|
||||
// /* GL_BLEND */
|
||||
// if( (enabled = (flags & CC_GL_BLEND)) != (s_eGLServerState & CC_GL_BLEND) ) {
|
||||
// if( enabled ) {
|
||||
// glEnable( GL_BLEND );
|
||||
// s_eGLServerState |= CC_GL_BLEND;
|
||||
// } else {
|
||||
// glDisable( GL_BLEND );
|
||||
// s_eGLServerState &= ~CC_GL_BLEND;
|
||||
// }
|
||||
// }
|
||||
|
||||
#else
|
||||
if( flags & CC_GL_BLEND )
|
||||
glEnable( GL_BLEND );
|
||||
else
|
||||
glDisable( GL_BLEND );
|
||||
// if( flags & CC_GL_BLEND )
|
||||
// glEnable( GL_BLEND );
|
||||
// else
|
||||
// glDisable( GL_BLEND );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -188,6 +210,8 @@ void ccGLEnable( ccGLServerState flags )
|
|||
|
||||
void ccGLEnableVertexAttribs( unsigned int flags )
|
||||
{
|
||||
ccGLBindVAO(0);
|
||||
|
||||
/* Position */
|
||||
bool enablePosition = flags & kCCVertexAttribFlag_Position;
|
||||
|
||||
|
|
|
@ -55,11 +55,12 @@ typedef enum {
|
|||
// CC_GL_SCISSOR_TEST = 1 << 0,
|
||||
// CC_GL_STENCIL_TEST = 1 << 1,
|
||||
// CC_GL_DEPTH_TEST = 1 << 2,
|
||||
CC_GL_BLEND = 1 << 3,
|
||||
// CC_GL_BLEND = 1 << 3,
|
||||
// CC_GL_DITHER = 1 << 4,
|
||||
|
||||
// CC_GL_ALL = ( CC_GL_SCISSOR_TEST | CC_GL_STENCIL_TEST | CC_GL_DEPTH_TEST | CC_GL_BLEND | CC_GL_DITHER ),
|
||||
CC_GL_ALL = ( CC_GL_BLEND ),
|
||||
// CC_GL_ALL = ( CC_GL_BLEND ),
|
||||
CC_GL_ALL = 0,
|
||||
|
||||
} ccGLServerState;
|
||||
|
||||
|
@ -70,19 +71,19 @@ typedef enum {
|
|||
If CC_ENABLE_GL_STATE_CACHE it will reset the GL state cache.
|
||||
@since v2.0.0
|
||||
*/
|
||||
void CC_DLL ccGLInvalidateStateCache( void );
|
||||
void CC_DLL ccGLInvalidateStateCache(void);
|
||||
|
||||
/** Uses the GL program in case program is different than the current one.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will the glUseProgram() directly.
|
||||
@since v2.0.0
|
||||
*/
|
||||
void CC_DLL ccGLUseProgram( GLuint program );
|
||||
void CC_DLL ccGLUseProgram(GLuint program);
|
||||
|
||||
/** Deletes the GL program. If it is the one that is being used, it invalidates it.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will the glDeleteProgram() directly.
|
||||
@since v2.0.0
|
||||
*/
|
||||
void CC_DLL ccGLDeleteProgram( GLuint program );
|
||||
void CC_DLL ccGLDeleteProgram(GLuint program);
|
||||
|
||||
/** Uses a blending function in case it not already used.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will the glBlendFunc() directly.
|
||||
|
@ -90,10 +91,16 @@ void CC_DLL ccGLDeleteProgram( GLuint program );
|
|||
*/
|
||||
void CC_DLL ccGLBlendFunc(GLenum sfactor, GLenum dfactor);
|
||||
|
||||
/** Resets the blending mode back to the cached state in case you used glBlendFuncSeparate() or glBlendEquation().
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will just set the default blending mode using GL_FUNC_ADD.
|
||||
@since v2.0.0
|
||||
*/
|
||||
void ccGLBlendResetToCache(void);
|
||||
|
||||
/** sets the projection matrix as dirty
|
||||
@since v2.0.0
|
||||
*/
|
||||
void CC_DLL ccSetProjectionMatrixDirty( void );
|
||||
void CC_DLL ccSetProjectionMatrixDirty(void);
|
||||
|
||||
/** Will enable the vertex attribs that are passed as flags.
|
||||
Possible flags:
|
||||
|
@ -106,26 +113,20 @@ void CC_DLL ccSetProjectionMatrixDirty( void );
|
|||
|
||||
@since v2.0.0
|
||||
*/
|
||||
void CC_DLL ccGLEnableVertexAttribs( unsigned int flags );
|
||||
void CC_DLL ccGLEnableVertexAttribs(unsigned int flags);
|
||||
|
||||
/** If the active texture is not textureEnum, then it will active it.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glActiveTexture() directly.
|
||||
@since v2.0.0
|
||||
/** If the texture is not already bound to texture unit 0, it binds it.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glBindTexture() directly.
|
||||
@since v2.1.0
|
||||
*/
|
||||
void CC_DLL ccGLActiveTexture(GLenum textureEnum );
|
||||
|
||||
/** Returns the active texture.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glGetIntegerv(GL_ACTIVE_TEXTURE);
|
||||
@since v2.0.0
|
||||
*/
|
||||
GLenum CC_DLL ccGLGetActiveTexture( void );
|
||||
void ccGLBindTexture2D(GLuint textureId);
|
||||
|
||||
|
||||
/** If the texture is not already bound, it binds it.
|
||||
/** If the texture is not already bound to a given unit, it binds it.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glBindTexture() directly.
|
||||
@since v2.0.0
|
||||
*/
|
||||
void CC_DLL ccGLBindTexture2D(GLuint textureId );
|
||||
void CC_DLL ccGLBindTexture2DN(GLuint textureUnit, GLuint textureId);
|
||||
|
||||
/** It will delete a given texture. If the texture was bound, it will invalidate the cached.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glDeleteTextures() directly.
|
||||
|
@ -133,6 +134,18 @@ void CC_DLL ccGLBindTexture2D(GLuint textureId );
|
|||
*/
|
||||
void CC_DLL ccGLDeleteTexture(GLuint textureId);
|
||||
|
||||
/** It will delete a given texture. If the texture was bound, it will invalidate the cached for the given texture unit.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glDeleteTextures() directly.
|
||||
@since v2.1.0
|
||||
*/
|
||||
void ccGLDeleteTextureN(GLuint textureUnit, GLuint textureId);
|
||||
|
||||
/** If the vertex array is not already bound, it binds it.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glBindVertexArray() directly.
|
||||
@since v2.0.0
|
||||
*/
|
||||
void ccGLBindVAO(GLuint vaoId);
|
||||
|
||||
/** It will enable / disable the server side GL states.
|
||||
If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glEnable() directly.
|
||||
@since v2.0.0
|
||||
|
|
|
@ -480,7 +480,7 @@ void CCTexture2D::drawAtPoint(const CCPoint& point)
|
|||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_TexCoords );
|
||||
m_pShaderProgram->use();
|
||||
m_pShaderProgram->setUniformForModelViewProjectionMatrix();
|
||||
m_pShaderProgram->setUniformsForBuiltins();
|
||||
|
||||
ccGLBindTexture2D( m_uName );
|
||||
|
||||
|
@ -506,7 +506,7 @@ void CCTexture2D::drawInRect(const CCRect& rect)
|
|||
|
||||
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_TexCoords );
|
||||
m_pShaderProgram->use();
|
||||
m_pShaderProgram->setUniformForModelViewProjectionMatrix();
|
||||
m_pShaderProgram->setUniformsForBuiltins();
|
||||
|
||||
ccGLBindTexture2D( m_uName );
|
||||
|
||||
|
|
Loading…
Reference in New Issue