2012-04-19 14:35:52 +08:00
|
|
|
/****************************************************************************
|
2012-09-24 21:22:20 +08:00
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
2012-04-19 14:35:52 +08:00
|
|
|
Copyright (c) 2008-2010 Ricardo Quesada
|
|
|
|
Copyright (c) 2011 Zynga Inc.
|
|
|
|
|
|
|
|
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.
|
|
|
|
****************************************************************************/
|
|
|
|
|
2012-11-14 18:05:15 +08:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* IMPORTANT IMPORTANT IMPORTANT IMPORTANT
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* LEGACY FUNCTIONS
|
|
|
|
*
|
2013-06-20 14:13:12 +08:00
|
|
|
* USE DrawNode instead
|
2012-11-14 18:05:15 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
#include "CCDrawingPrimitives.h"
|
|
|
|
#include "ccTypes.h"
|
|
|
|
#include "ccMacros.h"
|
|
|
|
#include "CCGL.h"
|
|
|
|
#include "CCDirector.h"
|
2012-06-19 16:20:46 +08:00
|
|
|
#include "shaders/ccGLStateCache.h"
|
|
|
|
#include "shaders/CCShaderCache.h"
|
|
|
|
#include "shaders/CCGLProgram.h"
|
|
|
|
#include "actions/CCActionCatmullRom.h"
|
2012-04-19 14:35:52 +08:00
|
|
|
#include <string.h>
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
#ifndef M_PI
|
|
|
|
#define M_PI 3.14159265358979323846
|
|
|
|
#endif
|
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
static bool s_bInitialized = false;
|
2013-06-20 14:13:12 +08:00
|
|
|
static GLProgram* s_pShader = NULL;
|
2012-06-27 14:21:29 +08:00
|
|
|
static int s_nColorLocation = -1;
|
2013-07-07 21:08:14 +08:00
|
|
|
static Color4F s_tColor(1.0f,1.0f,1.0f,1.0f);
|
2012-06-27 14:21:29 +08:00
|
|
|
static int s_nPointSizeLocation = -1;
|
|
|
|
static GLfloat s_fPointSize = 1.0f;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-04-23 09:08:25 +08:00
|
|
|
#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
|
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
static void lazy_init( void )
|
|
|
|
{
|
2012-06-27 14:21:29 +08:00
|
|
|
if( ! s_bInitialized ) {
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
//
|
2012-09-16 05:19:14 +08:00
|
|
|
// Position and 1 color passed as a uniform (to simulate glColor4ub )
|
2012-04-19 14:35:52 +08:00
|
|
|
//
|
2013-07-25 17:48:22 +08:00
|
|
|
s_pShader = ShaderCache::getInstance()->programForKey(GLProgram::SHADER_NAME_POSITION_U_COLOR);
|
2013-02-27 09:38:30 +08:00
|
|
|
s_pShader->retain();
|
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
s_nColorLocation = glGetUniformLocation( s_pShader->getProgram(), "u_color");
|
2012-04-19 14:35:52 +08:00
|
|
|
CHECK_GL_ERROR_DEBUG();
|
2012-06-27 14:21:29 +08:00
|
|
|
s_nPointSizeLocation = glGetUniformLocation( s_pShader->getProgram(), "u_pointSize");
|
2012-04-19 14:35:52 +08:00
|
|
|
CHECK_GL_ERROR_DEBUG();
|
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
s_bInitialized = true;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-16 10:18:06 +08:00
|
|
|
// When switching from backround to foreground on android, we want the params to be initialized again
|
2012-04-19 14:35:52 +08:00
|
|
|
void ccDrawInit()
|
|
|
|
{
|
2013-02-27 09:38:30 +08:00
|
|
|
lazy_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ccDrawFree()
|
|
|
|
{
|
|
|
|
CC_SAFE_RELEASE_NULL(s_pShader);
|
|
|
|
s_bInitialized = false;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void ccDrawPoint( const Point& point )
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
lazy_init();
|
|
|
|
|
2013-07-05 16:49:22 +08:00
|
|
|
Vertex2F p;
|
2012-04-19 14:35:52 +08:00
|
|
|
p.x = point.x;
|
|
|
|
p.y = point.y;
|
|
|
|
|
2013-07-25 15:04:13 +08:00
|
|
|
ccGLEnableVertexAttribs( VERTEX_ATTRIB_FLAG_POSITION );
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->use();
|
2012-11-09 12:08:18 +08:00
|
|
|
s_pShader->setUniformsForBuiltins();
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
|
|
|
s_pShader->setUniformLocationWith1f(s_nPointSizeLocation, s_fPointSize);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-04-09 12:06:36 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-04-23 09:08:25 +08:00
|
|
|
setGLBufferData(&p, 8);
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, &p);
|
2013-04-09 12:06:36 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2013-04-23 09:08:25 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
glDrawArrays(GL_POINTS, 0, 1);
|
|
|
|
|
|
|
|
CC_INCREMENT_GL_DRAWS(1);
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void ccDrawPoints( const Point *points, unsigned int numberOfPoints )
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
lazy_init();
|
|
|
|
|
2013-07-25 15:04:13 +08:00
|
|
|
ccGLEnableVertexAttribs( VERTEX_ATTRIB_FLAG_POSITION );
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->use();
|
2012-11-09 12:08:18 +08:00
|
|
|
s_pShader->setUniformsForBuiltins();
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
|
|
|
s_pShader->setUniformLocationWith1f(s_nPointSizeLocation, s_fPointSize);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// XXX: Mac OpenGL error. arrays can't go out of scope before draw is executed
|
2013-07-05 16:49:22 +08:00
|
|
|
Vertex2F* newPoints = new Vertex2F[numberOfPoints];
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// iPhone and 32-bit machines optimization
|
2013-07-05 16:49:22 +08:00
|
|
|
if( sizeof(Point) == sizeof(Vertex2F) )
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-04-23 09:08:25 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-06-20 14:13:12 +08:00
|
|
|
setGLBufferData((void*) points, numberOfPoints * sizeof(Point));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, points);
|
2013-04-23 09:08:25 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Mac on 64-bit
|
|
|
|
for( unsigned int i=0; i<numberOfPoints;i++) {
|
|
|
|
newPoints[i].x = points[i].x;
|
|
|
|
newPoints[i].y = points[i].y;
|
|
|
|
}
|
2013-04-09 12:06:36 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-04-23 09:08:25 +08:00
|
|
|
// 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.
|
2013-07-05 16:49:22 +08:00
|
|
|
setGLBufferData(newPoints, numberOfPoints * sizeof(Vertex2F));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, newPoints);
|
2013-04-09 12:06:36 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2013-04-23 09:08:25 +08:00
|
|
|
}
|
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
glDrawArrays(GL_POINTS, 0, (GLsizei) numberOfPoints);
|
|
|
|
|
|
|
|
CC_SAFE_DELETE_ARRAY(newPoints);
|
|
|
|
|
|
|
|
CC_INCREMENT_GL_DRAWS(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void ccDrawLine( const Point& origin, const Point& destination )
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
lazy_init();
|
|
|
|
|
2013-07-05 16:49:22 +08:00
|
|
|
Vertex2F vertices[2] = {
|
2013-07-07 21:08:14 +08:00
|
|
|
Vertex2F(origin.x, origin.y),
|
|
|
|
Vertex2F(destination.x, destination.y)
|
2012-04-19 14:35:52 +08:00
|
|
|
};
|
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->use();
|
2012-11-09 12:08:18 +08:00
|
|
|
s_pShader->setUniformsForBuiltins();
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-07-25 15:04:13 +08:00
|
|
|
ccGLEnableVertexAttribs( VERTEX_ATTRIB_FLAG_POSITION );
|
2013-04-09 12:06:36 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-04-23 09:08:25 +08:00
|
|
|
setGLBufferData(vertices, 16);
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
2013-04-09 12:06:36 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2012-04-19 14:35:52 +08:00
|
|
|
glDrawArrays(GL_LINES, 0, 2);
|
|
|
|
|
|
|
|
CC_INCREMENT_GL_DRAWS(1);
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void ccDrawRect( Point origin, Point destination )
|
2012-06-12 01:43:07 +08:00
|
|
|
{
|
2013-07-12 14:30:26 +08:00
|
|
|
ccDrawLine(Point(origin.x, origin.y), Point(destination.x, origin.y));
|
|
|
|
ccDrawLine(Point(destination.x, origin.y), Point(destination.x, destination.y));
|
|
|
|
ccDrawLine(Point(destination.x, destination.y), Point(origin.x, destination.y));
|
|
|
|
ccDrawLine(Point(origin.x, destination.y), Point(origin.x, origin.y));
|
2012-06-12 01:43:07 +08:00
|
|
|
}
|
|
|
|
|
2013-07-05 16:49:22 +08:00
|
|
|
void ccDrawSolidRect( Point origin, Point destination, Color4F color )
|
2012-06-12 01:43:07 +08:00
|
|
|
{
|
2013-06-20 14:13:12 +08:00
|
|
|
Point vertices[] = {
|
2012-06-12 01:43:07 +08:00
|
|
|
origin,
|
2013-07-12 14:11:55 +08:00
|
|
|
Point(destination.x, origin.y),
|
2012-06-12 01:43:07 +08:00
|
|
|
destination,
|
2013-07-12 14:11:55 +08:00
|
|
|
Point(origin.x, destination.y)
|
2012-06-12 01:43:07 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
ccDrawSolidPoly(vertices, 4, color );
|
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void ccDrawPoly( const Point *poli, unsigned int numberOfPoints, bool closePolygon )
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
lazy_init();
|
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->use();
|
2012-11-09 12:08:18 +08:00
|
|
|
s_pShader->setUniformsForBuiltins();
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-07-25 15:04:13 +08:00
|
|
|
ccGLEnableVertexAttribs( VERTEX_ATTRIB_FLAG_POSITION );
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// iPhone and 32-bit machines optimization
|
2013-07-05 16:49:22 +08:00
|
|
|
if( sizeof(Point) == sizeof(Vertex2F) )
|
2012-09-14 17:54:53 +08:00
|
|
|
{
|
2013-04-23 09:08:25 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-06-20 14:13:12 +08:00
|
|
|
setGLBufferData((void*) poli, numberOfPoints * sizeof(Point));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, poli);
|
2013-04-23 09:08:25 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2012-09-14 17:54:53 +08:00
|
|
|
if( closePolygon )
|
|
|
|
glDrawArrays(GL_LINE_LOOP, 0, (GLsizei) numberOfPoints);
|
|
|
|
else
|
|
|
|
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) numberOfPoints);
|
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// Mac on 64-bit
|
2012-09-14 17:54:53 +08:00
|
|
|
// XXX: Mac OpenGL error. arrays can't go out of scope before draw is executed
|
2013-07-05 16:49:22 +08:00
|
|
|
Vertex2F* newPoli = new Vertex2F[numberOfPoints];
|
2012-04-19 14:35:52 +08:00
|
|
|
for( unsigned int i=0; i<numberOfPoints;i++) {
|
|
|
|
newPoli[i].x = poli[i].x;
|
|
|
|
newPoli[i].y = poli[i].y;
|
|
|
|
}
|
2013-04-23 09:08:25 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-07-05 16:49:22 +08:00
|
|
|
setGLBufferData(newPoli, numberOfPoints * sizeof(Vertex2F));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, newPoli);
|
2013-04-23 09:08:25 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2012-09-14 17:54:53 +08:00
|
|
|
if( closePolygon )
|
|
|
|
glDrawArrays(GL_LINE_LOOP, 0, (GLsizei) numberOfPoints);
|
|
|
|
else
|
|
|
|
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) numberOfPoints);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2012-09-14 17:54:53 +08:00
|
|
|
CC_SAFE_DELETE_ARRAY(newPoli);
|
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
CC_INCREMENT_GL_DRAWS(1);
|
|
|
|
}
|
|
|
|
|
2013-07-05 16:49:22 +08:00
|
|
|
void ccDrawSolidPoly( const Point *poli, unsigned int numberOfPoints, Color4F color )
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
lazy_init();
|
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->use();
|
2012-11-09 12:08:18 +08:00
|
|
|
s_pShader->setUniformsForBuiltins();
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &color.r, 1);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-07-25 15:04:13 +08:00
|
|
|
ccGLEnableVertexAttribs( VERTEX_ATTRIB_FLAG_POSITION );
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// XXX: Mac OpenGL error. arrays can't go out of scope before draw is executed
|
2013-07-05 16:49:22 +08:00
|
|
|
Vertex2F* newPoli = new Vertex2F[numberOfPoints];
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// iPhone and 32-bit machines optimization
|
2013-07-05 16:49:22 +08:00
|
|
|
if( sizeof(Point) == sizeof(Vertex2F) )
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-04-23 09:08:25 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-06-20 14:13:12 +08:00
|
|
|
setGLBufferData((void*) poli, numberOfPoints * sizeof(Point));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, poli);
|
2013-04-23 09:08:25 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Mac on 64-bit
|
|
|
|
for( unsigned int i=0; i<numberOfPoints;i++)
|
|
|
|
{
|
2013-07-05 16:49:22 +08:00
|
|
|
newPoli[i] = Vertex2F( poli[i].x, poli[i].y );
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-04-23 09:08:25 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-07-05 16:49:22 +08:00
|
|
|
setGLBufferData(newPoli, numberOfPoints * sizeof(Vertex2F));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, newPoli);
|
2013-04-23 09:08:25 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, (GLsizei) numberOfPoints);
|
|
|
|
|
|
|
|
CC_SAFE_DELETE_ARRAY(newPoli);
|
|
|
|
CC_INCREMENT_GL_DRAWS(1);
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void ccDrawCircle( const Point& center, float radius, float angle, unsigned int segments, bool drawLineToCenter, float scaleX, float scaleY)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
lazy_init();
|
|
|
|
|
|
|
|
int additionalSegment = 1;
|
|
|
|
if (drawLineToCenter)
|
|
|
|
additionalSegment++;
|
|
|
|
|
|
|
|
const float coef = 2.0f * (float)M_PI/segments;
|
|
|
|
|
|
|
|
GLfloat *vertices = (GLfloat*)calloc( sizeof(GLfloat)*2*(segments+2), 1);
|
|
|
|
if( ! vertices )
|
|
|
|
return;
|
|
|
|
|
|
|
|
for(unsigned int i = 0;i <= segments; i++) {
|
|
|
|
float rads = i*coef;
|
2012-09-14 18:00:11 +08:00
|
|
|
GLfloat j = radius * cosf(rads + angle) * scaleX + center.x;
|
|
|
|
GLfloat k = radius * sinf(rads + angle) * scaleY + center.y;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
vertices[i*2] = j;
|
|
|
|
vertices[i*2+1] = k;
|
|
|
|
}
|
|
|
|
vertices[(segments+1)*2] = center.x;
|
|
|
|
vertices[(segments+1)*2+1] = center.y;
|
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->use();
|
2012-11-09 12:08:18 +08:00
|
|
|
s_pShader->setUniformsForBuiltins();
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-07-25 15:04:13 +08:00
|
|
|
ccGLEnableVertexAttribs( VERTEX_ATTRIB_FLAG_POSITION );
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-04-09 12:06:36 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-04-23 09:08:25 +08:00
|
|
|
setGLBufferData(vertices, sizeof(GLfloat)*2*(segments+2));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
2013-04-09 12:06:36 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2012-04-19 14:35:52 +08:00
|
|
|
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segments+additionalSegment);
|
|
|
|
|
|
|
|
free( vertices );
|
|
|
|
|
|
|
|
CC_INCREMENT_GL_DRAWS(1);
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void CC_DLL ccDrawCircle( const Point& center, float radius, float angle, unsigned int segments, bool drawLineToCenter)
|
2012-09-20 11:55:12 +08:00
|
|
|
{
|
|
|
|
ccDrawCircle(center, radius, angle, segments, drawLineToCenter, 1.0f, 1.0f);
|
|
|
|
}
|
|
|
|
|
2013-07-03 04:39:16 +08:00
|
|
|
void ccDrawSolidCircle( const Point& center, float radius, float angle, unsigned int segments, float scaleX, float scaleY)
|
|
|
|
{
|
|
|
|
lazy_init();
|
|
|
|
|
|
|
|
const float coef = 2.0f * (float)M_PI/segments;
|
|
|
|
|
|
|
|
GLfloat *vertices = (GLfloat*)calloc( sizeof(GLfloat)*2*(segments+2), 1);
|
|
|
|
if( ! vertices )
|
|
|
|
return;
|
|
|
|
|
|
|
|
for(unsigned int i = 0;i <= segments; i++) {
|
|
|
|
float rads = i*coef;
|
|
|
|
GLfloat j = radius * cosf(rads + angle) * scaleX + center.x;
|
|
|
|
GLfloat k = radius * sinf(rads + angle) * scaleY + center.y;
|
|
|
|
|
|
|
|
vertices[i*2] = j;
|
|
|
|
vertices[i*2+1] = k;
|
|
|
|
}
|
|
|
|
vertices[(segments+1)*2] = center.x;
|
|
|
|
vertices[(segments+1)*2+1] = center.y;
|
|
|
|
|
|
|
|
s_pShader->use();
|
|
|
|
s_pShader->setUniformsForBuiltins();
|
|
|
|
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
|
|
|
|
2013-07-25 15:04:13 +08:00
|
|
|
ccGLEnableVertexAttribs( VERTEX_ATTRIB_FLAG_POSITION );
|
2013-07-03 04:39:16 +08:00
|
|
|
|
|
|
|
#ifdef EMSCRIPTEN
|
|
|
|
setGLBufferData(vertices, sizeof(GLfloat)*2*(segments+2));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-07-03 04:39:16 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
2013-07-03 04:39:16 +08:00
|
|
|
#endif // EMSCRIPTEN
|
|
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, (GLsizei) segments+1);
|
|
|
|
|
|
|
|
free( vertices );
|
|
|
|
|
|
|
|
CC_INCREMENT_GL_DRAWS(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CC_DLL ccDrawSolidCircle( const Point& center, float radius, float angle, unsigned int segments)
|
|
|
|
{
|
|
|
|
ccDrawSolidCircle(center, radius, angle, segments, 1.0f, 1.0f);
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void ccDrawQuadBezier(const Point& origin, const Point& control, const Point& destination, unsigned int segments)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
lazy_init();
|
|
|
|
|
2013-07-05 16:49:22 +08:00
|
|
|
Vertex2F* vertices = new Vertex2F[segments + 1];
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
float t = 0.0f;
|
|
|
|
for(unsigned int i = 0; i < segments; i++)
|
|
|
|
{
|
|
|
|
vertices[i].x = powf(1 - t, 2) * origin.x + 2.0f * (1 - t) * t * control.x + t * t * destination.x;
|
|
|
|
vertices[i].y = powf(1 - t, 2) * origin.y + 2.0f * (1 - t) * t * control.y + t * t * destination.y;
|
|
|
|
t += 1.0f / segments;
|
|
|
|
}
|
|
|
|
vertices[segments].x = destination.x;
|
|
|
|
vertices[segments].y = destination.y;
|
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->use();
|
2012-11-09 12:08:18 +08:00
|
|
|
s_pShader->setUniformsForBuiltins();
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-07-25 15:04:13 +08:00
|
|
|
ccGLEnableVertexAttribs( VERTEX_ATTRIB_FLAG_POSITION );
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-04-09 12:06:36 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-07-05 16:49:22 +08:00
|
|
|
setGLBufferData(vertices, (segments + 1) * sizeof(Vertex2F));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
2013-04-09 12:06:36 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2012-04-19 14:35:52 +08:00
|
|
|
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segments + 1);
|
|
|
|
CC_SAFE_DELETE_ARRAY(vertices);
|
|
|
|
|
|
|
|
CC_INCREMENT_GL_DRAWS(1);
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void ccDrawCatmullRom( PointArray *points, unsigned int segments )
|
2012-06-12 01:43:07 +08:00
|
|
|
{
|
|
|
|
ccDrawCardinalSpline( points, 0.5f, segments );
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void ccDrawCardinalSpline( PointArray *config, float tension, unsigned int segments )
|
2012-06-12 01:43:07 +08:00
|
|
|
{
|
|
|
|
lazy_init();
|
|
|
|
|
2013-07-05 16:49:22 +08:00
|
|
|
Vertex2F* vertices = new Vertex2F[segments + 1];
|
2012-06-12 01:43:07 +08:00
|
|
|
|
|
|
|
unsigned int p;
|
2012-08-01 15:30:12 +08:00
|
|
|
float lt;
|
|
|
|
float deltaT = 1.0f / config->count();
|
2012-06-12 01:43:07 +08:00
|
|
|
|
|
|
|
for( unsigned int i=0; i < segments+1;i++) {
|
|
|
|
|
2012-08-01 15:30:12 +08:00
|
|
|
float dt = (float)i / segments;
|
2012-06-12 01:43:07 +08:00
|
|
|
|
|
|
|
// border
|
|
|
|
if( dt == 1 ) {
|
|
|
|
p = config->count() - 1;
|
|
|
|
lt = 1;
|
|
|
|
} else {
|
|
|
|
p = dt / deltaT;
|
2012-08-01 15:30:12 +08:00
|
|
|
lt = (dt - deltaT * (float)p) / deltaT;
|
2012-06-12 01:43:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Interpolate
|
2013-06-20 14:13:12 +08:00
|
|
|
Point pp0 = config->getControlPointAtIndex(p-1);
|
|
|
|
Point pp1 = config->getControlPointAtIndex(p+0);
|
|
|
|
Point pp2 = config->getControlPointAtIndex(p+1);
|
|
|
|
Point pp3 = config->getControlPointAtIndex(p+2);
|
2012-06-12 01:43:07 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Point newPos = ccCardinalSplineAt( pp0, pp1, pp2, pp3, tension, lt);
|
2012-06-12 01:43:07 +08:00
|
|
|
vertices[i].x = newPos.x;
|
|
|
|
vertices[i].y = newPos.y;
|
|
|
|
}
|
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->use();
|
2012-11-09 12:08:18 +08:00
|
|
|
s_pShader->setUniformsForBuiltins();
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*)&s_tColor.r, 1);
|
2012-06-12 01:43:07 +08:00
|
|
|
|
2013-07-25 15:04:13 +08:00
|
|
|
ccGLEnableVertexAttribs( VERTEX_ATTRIB_FLAG_POSITION );
|
2012-06-12 01:43:07 +08:00
|
|
|
|
2013-04-09 12:06:36 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-07-05 16:49:22 +08:00
|
|
|
setGLBufferData(vertices, (segments + 1) * sizeof(Vertex2F));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
2013-04-09 12:06:36 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2012-06-12 01:43:07 +08:00
|
|
|
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segments + 1);
|
|
|
|
|
|
|
|
CC_SAFE_DELETE_ARRAY(vertices);
|
|
|
|
CC_INCREMENT_GL_DRAWS(1);
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void ccDrawCubicBezier(const Point& origin, const Point& control1, const Point& control2, const Point& destination, unsigned int segments)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
lazy_init();
|
|
|
|
|
2013-07-05 16:49:22 +08:00
|
|
|
Vertex2F* vertices = new Vertex2F[segments + 1];
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
float t = 0;
|
|
|
|
for(unsigned int i = 0; i < segments; i++)
|
|
|
|
{
|
|
|
|
vertices[i].x = powf(1 - t, 3) * origin.x + 3.0f * powf(1 - t, 2) * t * control1.x + 3.0f * (1 - t) * t * t * control2.x + t * t * t * destination.x;
|
|
|
|
vertices[i].y = powf(1 - t, 3) * origin.y + 3.0f * powf(1 - t, 2) * t * control1.y + 3.0f * (1 - t) * t * t * control2.y + t * t * t * destination.y;
|
|
|
|
t += 1.0f / segments;
|
|
|
|
}
|
|
|
|
vertices[segments].x = destination.x;
|
|
|
|
vertices[segments].y = destination.y;
|
|
|
|
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->use();
|
2012-11-09 12:08:18 +08:00
|
|
|
s_pShader->setUniformsForBuiltins();
|
2012-06-27 14:21:29 +08:00
|
|
|
s_pShader->setUniformLocationWith4fv(s_nColorLocation, (GLfloat*) &s_tColor.r, 1);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-07-25 15:04:13 +08:00
|
|
|
ccGLEnableVertexAttribs( VERTEX_ATTRIB_FLAG_POSITION );
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-04-09 12:06:36 +08:00
|
|
|
#ifdef EMSCRIPTEN
|
2013-07-05 16:49:22 +08:00
|
|
|
setGLBufferData(vertices, (segments + 1) * sizeof(Vertex2F));
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
2013-04-23 09:08:25 +08:00
|
|
|
#else
|
2013-07-25 17:48:22 +08:00
|
|
|
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
2013-04-09 12:06:36 +08:00
|
|
|
#endif // EMSCRIPTEN
|
2012-04-19 14:35:52 +08:00
|
|
|
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segments + 1);
|
|
|
|
CC_SAFE_DELETE_ARRAY(vertices);
|
|
|
|
|
|
|
|
CC_INCREMENT_GL_DRAWS(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ccDrawColor4F( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
|
|
|
|
{
|
2012-06-27 14:21:29 +08:00
|
|
|
s_tColor.r = r;
|
|
|
|
s_tColor.g = g;
|
|
|
|
s_tColor.b = b;
|
|
|
|
s_tColor.a = a;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ccPointSize( GLfloat pointSize )
|
|
|
|
{
|
2012-06-27 14:21:29 +08:00
|
|
|
s_fPointSize = pointSize * CC_CONTENT_SCALE_FACTOR();
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
//TODO :glPointSize( pointSize );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void ccDrawColor4B( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
|
|
|
|
{
|
2012-06-27 14:21:29 +08:00
|
|
|
s_tColor.r = r/255.0f;
|
|
|
|
s_tColor.g = g/255.0f;
|
|
|
|
s_tColor.b = b/255.0f;
|
|
|
|
s_tColor.a = a/255.0f;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_CC_END
|