diff --git a/cocos2dx/draw_nodes/CCDrawingPrimitives.cpp b/cocos2dx/draw_nodes/CCDrawingPrimitives.cpp index c590640d90..50be8ff5a3 100644 --- a/cocos2dx/draw_nodes/CCDrawingPrimitives.cpp +++ b/cocos2dx/draw_nodes/CCDrawingPrimitives.cpp @@ -60,6 +60,33 @@ static ccColor4F s_tColor = {1.0f,1.0f,1.0f,1.0f}; static int s_nPointSizeLocation = -1; static GLfloat s_fPointSize = 1.0f; +#ifdef EMSCRIPTEN +static GLuint s_bufferObject = 0; +static GLuint s_bufferSize = 0; + +static void setGLBufferData(void *buf, GLuint bufSize) +{ + if(s_bufferSize < bufSize) + { + if(s_bufferObject) + { + glDeleteBuffers(1, &s_bufferObject); + } + glGenBuffers(1, &s_bufferObject); + s_bufferSize = bufSize; + + glBindBuffer(GL_ARRAY_BUFFER, s_bufferObject); + glBufferData(GL_ARRAY_BUFFER, bufSize, buf, GL_DYNAMIC_DRAW); + } + else + { + glBindBuffer(GL_ARRAY_BUFFER, s_bufferObject); + glBufferSubData(GL_ARRAY_BUFFER, 0, bufSize, buf); + } +} + +#endif // EMSCRIPTEN + static void lazy_init( void ) { if( ! s_bInitialized ) { @@ -106,11 +133,13 @@ void ccDrawPoint( const CCPoint& point ) s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1); s_pShader->setUniformLocationWith1f(s_nPointSizeLocation, s_fPointSize); - glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, &p); - #ifdef EMSCRIPTEN - printf("WARNING: %s does not have client-side buffer fix for Emscripten\n", __func__); + setGLBufferData(&p, 8); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, &p); #endif // EMSCRIPTEN + glDrawArrays(GL_POINTS, 0, 1); CC_INCREMENT_GL_DRAWS(1); @@ -132,7 +161,12 @@ void ccDrawPoints( const CCPoint *points, unsigned int numberOfPoints ) // iPhone and 32-bit machines optimization if( sizeof(CCPoint) == sizeof(ccVertex2F) ) { +#ifdef EMSCRIPTEN + setGLBufferData((void*) points, numberOfPoints * sizeof(CCPoint)); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, points); +#endif // EMSCRIPTEN } else { @@ -141,12 +175,17 @@ void ccDrawPoints( const CCPoint *points, unsigned int numberOfPoints ) newPoints[i].x = points[i].x; newPoints[i].y = points[i].y; } - glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, newPoints); - } #ifdef EMSCRIPTEN - printf("WARNING: %s does not have client-side buffer fix for Emscripten\n", __func__); + // Suspect Emscripten won't be emitting 64-bit code for a while yet, + // but want to make sure this continues to work even if they do. + setGLBufferData(newPoints, numberOfPoints * sizeof(ccVertex2F)); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, newPoints); #endif // EMSCRIPTEN + } + glDrawArrays(GL_POINTS, 0, (GLsizei) numberOfPoints); CC_SAFE_DELETE_ARRAY(newPoints); @@ -169,9 +208,11 @@ void ccDrawLine( const CCPoint& origin, const CCPoint& destination ) s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1); ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); - glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); #ifdef EMSCRIPTEN - printf("WARNING: %s does not have client-side buffer fix for Emscripten\n", __func__); + setGLBufferData(vertices, 16); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); #endif // EMSCRIPTEN glDrawArrays(GL_LINES, 0, 2); @@ -208,13 +249,15 @@ void ccDrawPoly( const CCPoint *poli, unsigned int numberOfPoints, bool closePol ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); -#ifdef EMSCRIPTEN - printf("WARNING: %s does not have client-side buffer fix for Emscripten\n", __func__); -#endif // EMSCRIPTEN // iPhone and 32-bit machines optimization if( sizeof(CCPoint) == sizeof(ccVertex2F) ) { +#ifdef EMSCRIPTEN + setGLBufferData((void*) poli, numberOfPoints * sizeof(CCPoint)); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, poli); +#endif // EMSCRIPTEN if( closePolygon ) glDrawArrays(GL_LINE_LOOP, 0, (GLsizei) numberOfPoints); @@ -230,7 +273,12 @@ void ccDrawPoly( const CCPoint *poli, unsigned int numberOfPoints, bool closePol newPoli[i].x = poli[i].x; newPoli[i].y = poli[i].y; } +#ifdef EMSCRIPTEN + setGLBufferData(newPoli, numberOfPoints * sizeof(ccVertex2F)); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, newPoli); +#endif // EMSCRIPTEN if( closePolygon ) glDrawArrays(GL_LINE_LOOP, 0, (GLsizei) numberOfPoints); @@ -259,7 +307,12 @@ void ccDrawSolidPoly( const CCPoint *poli, unsigned int numberOfPoints, ccColor4 // iPhone and 32-bit machines optimization if( sizeof(CCPoint) == sizeof(ccVertex2F) ) { +#ifdef EMSCRIPTEN + setGLBufferData((void*) poli, numberOfPoints * sizeof(CCPoint)); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, poli); +#endif // EMSCRIPTEN } else { @@ -268,12 +321,14 @@ void ccDrawSolidPoly( const CCPoint *poli, unsigned int numberOfPoints, ccColor4 { newPoli[i] = vertex2( poli[i].x, poli[i].y ); } +#ifdef EMSCRIPTEN + setGLBufferData(newPoli, numberOfPoints * sizeof(ccVertex2F)); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, newPoli); +#endif // EMSCRIPTEN } -#ifdef EMSCRIPTEN - printf("WARNING: %s does not have client-side buffer fix for Emscripten\n", __func__); -#endif // EMSCRIPTEN glDrawArrays(GL_TRIANGLE_FAN, 0, (GLsizei) numberOfPoints); CC_SAFE_DELETE_ARRAY(newPoli); @@ -311,9 +366,11 @@ void ccDrawCircle( const CCPoint& center, float radius, float angle, unsigned in ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); - glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); #ifdef EMSCRIPTEN - printf("WARNING: %s does not have client-side buffer fix for Emscripten\n", __func__); + setGLBufferData(vertices, sizeof(GLfloat)*2*(segments+2)); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); #endif // EMSCRIPTEN glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segments+additionalSegment); @@ -349,9 +406,11 @@ void ccDrawQuadBezier(const CCPoint& origin, const CCPoint& control, const CCPoi ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); - glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); #ifdef EMSCRIPTEN - printf("WARNING: %s does not have client-side buffer fix for Emscripten\n", __func__); + setGLBufferData(vertices, (segments + 1) * sizeof(ccVertex2F)); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); #endif // EMSCRIPTEN glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segments + 1); CC_SAFE_DELETE_ARRAY(vertices); @@ -404,9 +463,11 @@ void ccDrawCardinalSpline( CCPointArray *config, float tension, unsigned int se ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); - glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); #ifdef EMSCRIPTEN - printf("WARNING: %s does not have client-side buffer fix for Emscripten\n", __func__); + setGLBufferData(vertices, (segments + 1) * sizeof(ccVertex2F)); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); #endif // EMSCRIPTEN glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segments + 1); @@ -436,9 +497,11 @@ void ccDrawCubicBezier(const CCPoint& origin, const CCPoint& control1, const CCP ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); - glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); #ifdef EMSCRIPTEN - printf("WARNING: %s does not have client-side buffer fix for Emscripten\n", __func__); + setGLBufferData(vertices, (segments + 1) * sizeof(ccVertex2F)); + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0); +#else + glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); #endif // EMSCRIPTEN glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segments + 1); CC_SAFE_DELETE_ARRAY(vertices);