fixed #1164: 1. Add the render mode which uses VBO without VAO in CCParticleSystemQuad.

2. delete some unused codes for win32 port.
3. Add CC_REBIND_INDICES_BUFFER macro.
This commit is contained in:
James Chen 2012-04-13 17:24:50 +08:00
parent 74c7c0d356
commit 3c0653ffa7
11 changed files with 106 additions and 136 deletions

View File

@ -53,7 +53,10 @@ protected:
ccV3F_C4B_T2F_Quad *m_pQuads; // quads to be rendered
GLushort *m_pIndices; // indices
#if CC_TEXTURE_ATLAS_USE_VAO
GLuint m_uVAOname;
#endif
GLuint m_pBuffersVBO[2]; //0: vertex 1: indices
public:
@ -66,7 +69,7 @@ public:
static CCParticleSystemQuad * particleWithFile(const char *plistFile);
/** initialices the indices for the vertices*/
void initIndices();
void setupIndices();
/** initilizes the texture with a rectangle measured Points */
void initTexCoordsWithRect(const CCRect& rect);
@ -90,7 +93,11 @@ public:
virtual void setBatchNode(CCParticleBatchNode* batchNode);
virtual void setTotalParticles(unsigned int tp);
private:
void initVAO();
#if CC_TEXTURE_ATLAS_USE_VAO
void setupVBOandVAO();
#else
void setupVBO();
#endif
bool allocMemory();
};

View File

@ -175,7 +175,7 @@ Only valid for cocos2d-mac. Not supported on cocos2d-ios.
*/
#ifndef CC_TEXTURE_ATLAS_USE_VAO
#define CC_TEXTURE_ATLAS_USE_VAO 1
#define CC_TEXTURE_ATLAS_USE_VAO 0
#endif
/** @def CC_TEXTURE_NPOT_SUPPORT

View File

@ -57,8 +57,12 @@ bool CCParticleSystemQuad::initWithTotalParticles(unsigned int numberOfParticles
return false;
}
initIndices();
initVAO();
setupIndices();
#if CC_TEXTURE_ATLAS_USE_VAO
setupVBOandVAO();
#else
setupVBO();
#endif
setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));
return true;
@ -69,7 +73,9 @@ bool CCParticleSystemQuad::initWithTotalParticles(unsigned int numberOfParticles
CCParticleSystemQuad::CCParticleSystemQuad()
:m_pQuads(NULL)
,m_pIndices(NULL)
#if CC_TEXTURE_ATLAS_USE_VAO
,m_uVAOname(0)
#endif
{
memset(m_pBuffersVBO, 0, sizeof(m_pBuffersVBO));
}
@ -81,7 +87,9 @@ CCParticleSystemQuad::~CCParticleSystemQuad()
CC_SAFE_FREE(m_pQuads);
CC_SAFE_FREE(m_pIndices);
glDeleteBuffers(2, &m_pBuffersVBO[0]);
#if CC_TEXTURE_ATLAS_USE_VAO
glDeleteVertexArrays(1, &m_uVAOname);
#endif
}
}
@ -189,7 +197,8 @@ void CCParticleSystemQuad::setDisplayFrame(CCSpriteFrame *spriteFrame)
this->setTexture(spriteFrame->getTexture());
}
}
void CCParticleSystemQuad::initIndices()
void CCParticleSystemQuad::setupIndices()
{
for(unsigned int i = 0; i < m_uTotalParticles; ++i)
{
@ -204,6 +213,7 @@ void CCParticleSystemQuad::initIndices()
m_pIndices[i6+3] = (GLushort) i4+3;
}
}
void CCParticleSystemQuad::updateQuadWithParticle(tCCParticle* particle, const CCPoint& newPosition)
{
ccV3F_C4B_T2F_Quad *quad;
@ -302,23 +312,50 @@ void CCParticleSystemQuad::draw()
CCAssert( m_uParticleIdx == m_uParticleCount, "Abnormal error in particle quad");
#if CC_TEXTURE_ATLAS_USE_VAO
//
// Using VBO and VAO
//
glBindVertexArray( m_uVAOname );
/* Application will crash in glDrawElements function on some win32 computers which use Integrated Graphics.
Indices should be bound again to avoid this bug.
*/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#if CC_REBIND_INDICES_BUFFER
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
#endif
glDrawElements(GL_TRIANGLES, (GLsizei) m_uParticleIdx*6, GL_UNSIGNED_SHORT, 0);
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#if CC_REBIND_INDICES_BUFFER
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif
glBindVertexArray( 0 );
#else
//
// Using VBO without VAO
//
#define kQuadSize sizeof(m_pQuads[0].bl)
ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex );
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]);
// vertices
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices));
// colors
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors));
// tex coords
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
glDrawElements(GL_TRIANGLES, (GLsizei) m_uParticleIdx*6, GL_UNSIGNED_SHORT, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif
CC_INCREMENT_GL_DRAWS(1);
CHECK_GL_ERROR_DEBUG();
}
@ -374,8 +411,12 @@ void CCParticleSystemQuad::setTotalParticles(unsigned int tp)
}
}
initIndices();
initVAO();
setupIndices();
#if CC_TEXTURE_ATLAS_USE_VAO
setupVBOandVAO();
#else
setupVBO();
#endif
}
else
{
@ -383,7 +424,8 @@ void CCParticleSystemQuad::setTotalParticles(unsigned int tp)
}
}
void CCParticleSystemQuad::initVAO()
#if CC_TEXTURE_ATLAS_USE_VAO
void CCParticleSystemQuad::setupVBOandVAO()
{
glGenVertexArrays(1, &m_uVAOname);
glBindVertexArray(m_uVAOname);
@ -416,12 +458,33 @@ void CCParticleSystemQuad::initVAO()
CHECK_GL_ERROR_DEBUG();
}
#else
void CCParticleSystemQuad::setupVBO()
{
glGenBuffers(2, &m_pBuffersVBO[0]);
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uTotalParticles, m_pQuads, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uTotalParticles * 6, m_pIndices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
CHECK_GL_ERROR_DEBUG();
}
#endif
bool CCParticleSystemQuad::allocMemory()
{
CCAssert( ( !m_pQuads && !m_pIndices), "Memory already alloced");
CCAssert( !m_pBatchNode, "Memory should not be alloced when not using batchNode");
CC_SAFE_FREE(m_pQuads);
CC_SAFE_FREE(m_pIndices);
m_pQuads = (ccV3F_C4B_T2F_Quad*)malloc(m_uTotalParticles * sizeof(ccV3F_C4B_T2F_Quad));
m_pIndices = (GLushort*)malloc(m_uTotalParticles * 6 * sizeof(GLushort));
@ -452,9 +515,13 @@ void CCParticleSystemQuad::setBatchNode(CCParticleBatchNode * batchNode)
if( ! batchNode )
{
allocMemory();
initIndices();
setupIndices();
setTexture(oldBatch->getTexture());
initVAO();
#if CC_TEXTURE_ATLAS_USE_VAO
setupVBOandVAO();
#else
setupVBO();
#endif
}
// OLD: was it self render ? cleanup
else if( !oldBatch )
@ -468,7 +535,9 @@ void CCParticleSystemQuad::setBatchNode(CCParticleBatchNode * batchNode)
CC_SAFE_FREE(m_pIndices);
glDeleteBuffers(2, &m_pBuffersVBO[0]);
#if CC_TEXTURE_ATLAS_USE_VAO
glDeleteVertexArrays(1, &m_uVAOname);
#endif
}
}
}

View File

@ -45,6 +45,14 @@ It's new in cocos2d-x since v0.99.5
#define CC_ENABLE_CACHE_TEXTTURE_DATA 0
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
/* Application will crash in glDrawElements function on some win32 computers and some android devices.
Indices should be bound again while drawing to avoid this bug.
*/
#define CC_REBIND_INDICES_BUFFER 1
#else
#define CC_REBIND_INDICES_BUFFER 0
#endif
// generic macros
@ -219,15 +227,6 @@ public: virtual void set##funName(varType var) \
#endif // CC_PLATFORM_WIN32
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE && defined(_TRANZDA_VM_))
#undef CC_DLL
#if defined(SS_MAKEDLL)
#define CC_DLL __declspec(dllexport)
#else /* use a DLL library */
#define CC_DLL __declspec(dllimport)
#endif
#endif // wophone VM
#endif // __CC_PLATFORM_MACROS_H__

View File

@ -188,31 +188,6 @@ void CCAccelerometer::update( double x,double y,double z,double timestamp )
m_obAccelerationValue.z = z;
m_obAccelerationValue.timestamp = timestamp;
// Handle orientation changes
CCDirector *pDirector=CCDirector::sharedDirector();
const ccDeviceOrientation orientation=pDirector->getDeviceOrientation();
const double tmp=m_obAccelerationValue.x;
switch ( orientation )
{
case kCCDeviceOrientationLandscapeRight:
m_obAccelerationValue.x = -m_obAccelerationValue.y;
m_obAccelerationValue.y = tmp;
break;
case kCCDeviceOrientationLandscapeLeft:
m_obAccelerationValue.x = m_obAccelerationValue.y;
m_obAccelerationValue.y = -tmp;
break;
case kCCDeviceOrientationPortraitUpsideDown:
m_obAccelerationValue.x = -m_obAccelerationValue.y;
m_obAccelerationValue.y = -tmp;
break;
case kCCDeviceOrientationPortrait:
break;
}
// Delegate
m_pAccelDelegate->didAccelerate(&m_obAccelerationValue);
}

View File

@ -96,17 +96,6 @@ void CCApplication::setAnimationInterval(double interval)
m_nAnimationInterval.QuadPart = (LONGLONG)(interval * nFreq.QuadPart);
}
CCApplication::Orientation CCApplication::setOrientation(Orientation orientation)
{
// swap width and height
CCEGLView * pView = CCDirector::sharedDirector()->getOpenGLView();
if (pView)
{
return (Orientation)pView->setDeviceOrientation(orientation);
}
return (Orientation)CCDirector::sharedDirector()->getDeviceOrientation();
}
void CCApplication::statusBarFrame(CCRect * rect)
{
if (rect)

View File

@ -45,25 +45,6 @@ public:
*/
void setAnimationInterval(double interval);
typedef enum
{
/// Device oriented vertically, home button on the bottom
kOrientationPortrait = 0,
/// Device oriented vertically, home button on the top
kOrientationPortraitUpsideDown = 1,
/// Device oriented horizontally, home button on the right
kOrientationLandscapeLeft = 2,
/// Device oriented horizontally, home button on the left
kOrientationLandscapeRight = 3,
} Orientation;
/**
@brief Callback by CCDirector for change device orientation.
@orientation The defination of orientation which CCDirector want change to.
@return The actual orientation of the application.
*/
Orientation setOrientation(Orientation orientation);
/**
@brief Get status bar rectangle in EGLView window.
*/

View File

@ -182,12 +182,9 @@ static LRESULT CALLBACK _WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
CCEGLView::CCEGLView()
: m_bCaptured(false)
, m_bOrientationReverted(false)
, m_bOrientationInitVertical(false)
, m_pDelegate(NULL)
, m_pEGL(NULL)
, m_hWnd(NULL)
, m_eInitOrientation(CCDeviceOrientationPortrait)
, m_fScreenScaleFactor(1.0f)
, m_lpfnAccelerometerKeyHook(NULL)
{
@ -245,9 +242,6 @@ bool CCEGLView::Create(LPCTSTR pTitle, int w, int h)
CC_BREAK_IF(! m_hWnd);
m_eInitOrientation = CCDirector::sharedDirector()->getDeviceOrientation();
m_bOrientationInitVertical = (CCDeviceOrientationPortrait == m_eInitOrientation
|| kCCDeviceOrientationPortraitUpsideDown == m_eInitOrientation) ? true : false;
m_tSizeInPoints.cx = w;
m_tSizeInPoints.cy = h;
resize(w, h);
@ -407,10 +401,6 @@ void CCEGLView::setAccelerometerKeyHook( LPFN_ACCELEROMETER_KEYHOOK lpfnAccelero
CCSize CCEGLView::getSize()
{
if (m_bOrientationReverted)
{
return CCSize((float)(m_tSizeInPoints.cy), (float)(m_tSizeInPoints.cx));
}
return CCSize((float)(m_tSizeInPoints.cx), (float)(m_tSizeInPoints.cy));
}
@ -453,28 +443,6 @@ void CCEGLView::swapBuffers()
}
}
int CCEGLView::setDeviceOrientation(int eOritation)
{
do
{
bool bVertical = (CCDeviceOrientationPortrait == eOritation
|| kCCDeviceOrientationPortraitUpsideDown == eOritation) ? true : false;
CC_BREAK_IF(m_bOrientationReverted && bVertical != m_bOrientationInitVertical);
CC_BREAK_IF(! m_bOrientationReverted && bVertical == m_bOrientationInitVertical);
m_bOrientationReverted = (bVertical == m_bOrientationInitVertical) ? false : true;
// swap width and height
RECT rc;
GetClientRect(m_hWnd, &rc);
resize(rc.bottom - rc.top, rc.right - rc.left);
} while (0);
return m_eInitOrientation;
}
void CCEGLView::setViewPortInPoints(float x, float y, float w, float h)
{
if (m_pEGL)
@ -539,12 +507,7 @@ void CCEGLView::resize(int width, int height)
// calculate view port in pixels
int viewPortW = (int)(m_tSizeInPoints.cx * m_fScreenScaleFactor);
int viewPortH = (int)(m_tSizeInPoints.cy * m_fScreenScaleFactor);
if (m_bOrientationReverted)
{
int tmp = viewPortW;
viewPortW = viewPortH;
viewPortH = tmp;
}
GetClientRect(m_hWnd, &rcClient);
// calculate client new width and height
@ -603,14 +566,7 @@ bool CCEGLView::canSetContentScaleFactor()
void CCEGLView::setContentScaleFactor(float contentScaleFactor)
{
m_fScreenScaleFactor = contentScaleFactor;
if (m_bOrientationReverted)
{
resize((int)(m_tSizeInPoints.cy * contentScaleFactor), (int)(m_tSizeInPoints.cx * contentScaleFactor));
}
else
{
resize((int)(m_tSizeInPoints.cx * contentScaleFactor), (int)(m_tSizeInPoints.cy * contentScaleFactor));
}
resize((int)(m_tSizeInPoints.cx * contentScaleFactor), (int)(m_tSizeInPoints.cy * contentScaleFactor));
centerWindow();
}

View File

@ -59,7 +59,6 @@ public:
virtual bool Create(LPCTSTR pTitle, int w, int h);
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
int setDeviceOrientation(int eOritation);
void setViewPortInPoints(float x, float y, float w, float h);
void setScissorInPoints(float x, float y, float w, float h);
@ -85,8 +84,7 @@ protected:
private:
bool m_bCaptured;
bool m_bOrientationReverted;
bool m_bOrientationInitVertical;
CCSet * m_pSet;
CCTouch * m_pTouch;
EGLTouchDelegate * m_pDelegate;
@ -95,7 +93,6 @@ private:
HWND m_hWnd;
int m_eInitOrientation;
SIZE m_tSizeInPoints;
float m_fScreenScaleFactor;
RECT m_rcViewPort;

View File

@ -587,10 +587,7 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start)
glBindVertexArray( m_uVAOname );
/* Application will crash in glDrawElements function on some win32 computers which use Integrated Graphics.
Indices should be bound again to avoid this bug.
*/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#if CC_REBIND_INDICES_BUFFER
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
#endif
@ -600,7 +597,7 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start)
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#if CC_REBIND_INDICES_BUFFER
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif

View File

@ -233,7 +233,7 @@ void CCTMXLayer::parseInternalProperties()
void CCTMXLayer::setupTileSprite(CCSprite* sprite, CCPoint pos, unsigned int gid)
{
sprite->setPosition(positionAt(pos));
sprite->setVertexZ(vertexZForPos(pos));
sprite->setVertexZ((float)vertexZForPos(pos));
sprite->setAnchorPoint(CCPointZero);
sprite->setOpacity(m_cOpacity);