/* 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