Merge branch 'newV3' into improved_glprogram

Conflicts:
	cocos/2d/CCGLProgram.cpp
	cocos/2d/CCGLProgram.h
This commit is contained in:
Trace 2014-05-06 12:07:42 -07:00
commit cf9e8ff0bd
8 changed files with 460 additions and 93 deletions

View File

@ -33,6 +33,7 @@ THE SOFTWARE.
#include "2d/platform/CCFileUtils.h"
#include "2d/uthash.h"
#include "deprecated/CCString.h"
#include "CCGL.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
#include "CCPrecompiledShaders.h"
@ -88,9 +89,10 @@ GLProgram::GLProgram()
, _fragShader(0)
, _hashForUniforms(nullptr)
, _flags()
,_isTight(false)
{
memset(_uniforms, 0, sizeof(_uniforms));
_programDate = new GLProgramData();
_programData = new GLProgramData();
}
GLProgram::~GLProgram()
@ -116,7 +118,7 @@ GLProgram::~GLProgram()
free(current_element);
}
CC_SAFE_DELETE(_programDate);
CC_SAFE_DELETE(_programData);
}
bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
@ -208,8 +210,6 @@ bool GLProgram::initWithFilenames(const std::string &vShaderFilename, const std:
return initWithByteArrays(vertexSource.c_str(), fragmentSource.c_str());
}
void GLProgram::setUniformsForUserDef()
{
Director* director = Director::getInstance();
@ -220,28 +220,68 @@ void GLProgram::setUniformsForUserDef()
Matrix matrixP = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
// Set Uniform value
}
void GLProgram::setVertexAttrib(const GLvoid* vertex)
void GLProgram::setAttribForUserDef()
{
GLint vertexsize = _programDate->getVertexSize();
for(unsigned int i = 0, count = _programDate->getAttribCount(); i < count; ++i)
for(unsigned int i = 0, count = _programData->getAttribCount(); i < count; ++i)
{
GLProgramData::VertexAttrib* attrib = _programData->getAttrib(i);
if(i == 0)
{
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
}
else if(attrib->_type == GL_FLOAT_VEC4)
{
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR);
}
else if(attrib->_type == GL_FLOAT_VEC2)
{
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORDS);
}
}
}
// have some questions.
void GLProgram::setVertexAttrib(const GLvoid* vertex, bool isTight)
{
static GLint vertexsize = 0;
if(vertexsize == 0)
{
for(unsigned int i = 0, count = _programData->getAttribCount(); i < count; ++i)
{
GLProgramData::VertexAttrib* _attrib = _programData->getAttrib(i);
if(_attrib->_type == GL_UNSIGNED_BYTE)
vertexsize += _attrib->_size ;
else
vertexsize += _attrib->_size * 4;
}
}
if(isTight)
vertexsize = 0;
size_t offset = 0;
for(unsigned int i = 0, count = _programData->getAttribCount(); i < count; ++i)
{
GLProgramData::VertexAttib* _attrib = _programDate->getAttrib(i);
GLProgramData::VertexAttrib* _attrib = _programData->getAttrib(i);
std::string name = _attrib->_name;
GLint size = _attrib->_size;
GLenum type = _attrib->_type;
bool normalized = GL_FALSE;
glVertexAttribPointer(i, size, type, GL_FALSE, vertexsize, vertex);
glVertexAttribPointer(i, size, type, normalized, vertexsize, (size_t*)(vertex)+ offset);
if(_attrib->_type != GL_UNSIGNED_BYTE)
offset += size * 4 ;
else
offset += size;
}
// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 2, vertex);
}
void GLProgram::autoParse()
{
// Link program
GLint status = GL_TRUE;
glLinkProgram(_program);
@ -327,24 +367,22 @@ void GLProgram::autoParse()
break;
}
GLProgramData::_VertexAttib* attrib = new GLProgramData::_VertexAttib();
GLProgramData::_VertexAttrib* attrib = new GLProgramData::_VertexAttrib();
attrib->_name = name;
attrib->_size = size;
attrib->_type = attribType;
attrib->_index = attribLocation;
vertexsize +=size;
attrib->_index = i;
//vertexsize +=size;
_programDate->addAttrib(name, attrib);
_programData->addAttrib(name, attrib);
//_user_vertAttributes[attribName] = attribLocation;
// bindAttribLocation(attribName,attribLocation);
}
_programDate->setVertexSize(vertexsize);
CC_SAFE_DELETE_ARRAY(attribName);
}
}
// Query and store uniforms from the program.
GLint activeUniforms;
glGetProgramiv(_program, GL_ACTIVE_UNIFORMS, &activeUniforms);
@ -388,19 +426,33 @@ void GLProgram::autoParse()
uniform->_uniformvalue = uniformvalue;
uniformvalue->init(this, uniform);
_programDate->addUniform(name, uniform);
_programData->addUniform(name, uniform);
}
CC_SAFE_DELETE_ARRAY(uniformName);
}
}
for(unsigned int i = 0, count = _programData->getAttribCount(); i < count; ++i)
{
GLProgramData::VertexAttrib* _attrib = _programData->getAttrib(i);
std::string name = _attrib->_name;
GLint attribLocation = getAttribLocation(name.c_str());
bindAttribLocation( name.c_str(),attribLocation);
}
}
UniformValue* GLProgram::getUniformValue(const std::string &name)
{
GLProgramData::Uniform* uniform = _programDate->getUniform(name);
GLProgramData::Uniform* uniform = _programData->getUniform(name);
return uniform->_uniformvalue;
}
GLProgramData::VertexAttrib* GLProgram::getAttrib(std::string &name)
{
GLProgramData::VertexAttrib* attrib = _programData->getAttrib(name);
return attrib;
}
std::string GLProgram::getDescription() const
{
@ -903,18 +955,18 @@ GLProgramData::~GLProgramData()
CC_SAFE_DELETE(itr->second);
}
for(std::map<std::string, VertexAttib*>::iterator itr = _vertAttributes.begin(); itr != _vertAttributes.end(); itr++)
for(std::map<std::string, VertexAttrib*>::iterator itr = _vertAttributes.begin(); itr != _vertAttributes.end(); itr++)
{
CC_SAFE_DELETE(itr->second);
}
}
void GLProgramData::addUniform(std::string &name, Uniform* uniform)
void GLProgramData::addUniform(const std::string &name, Uniform* uniform)
{
_uniforms[name] = uniform;
}
void GLProgramData::addAttrib(std::string &name, VertexAttib* attrib)
void GLProgramData::addAttrib(const std::string &name, VertexAttrib* attrib)
{
_vertAttributes[name] = attrib;
}
@ -941,12 +993,12 @@ GLProgramData::Uniform* GLProgramData::getUniform(const std::string& name)
return NULL;
}
GLProgramData::VertexAttib* GLProgramData::getAttrib(unsigned int index)
GLProgramData::VertexAttrib* GLProgramData::getAttrib(unsigned int index)
{
unsigned int i = 0;
for (std::map<std::string, VertexAttib*>::const_iterator itr = _vertAttributes.begin(); itr != _vertAttributes.end(); itr++, i++)
//unsigned int i = 0;
for (std::map<std::string, VertexAttrib*>::const_iterator itr = _vertAttributes.begin(); itr != _vertAttributes.end(); itr++)
{
if (i == index)
if (itr->second->_index == index)
{
return itr->second;
}
@ -954,9 +1006,9 @@ GLProgramData::VertexAttib* GLProgramData::getAttrib(unsigned int index)
return NULL;
}
std::vector<GLProgramData::VertexAttib*> GLProgramData::getVertexAttributes(const std::string* attrNames, int count)
std::vector<GLProgramData::VertexAttrib*> GLProgramData::getVertexAttributes(const std::string* attrNames, int count)
{
std::vector<GLProgramData::VertexAttib*> attribs;
std::vector<GLProgramData::VertexAttrib*> attribs;
for (auto i = 0; i < count; i++) {
auto it = _vertAttributes.find(attrNames[i]);
CCASSERT(it != _vertAttributes.end(), "attribute not find");
@ -965,6 +1017,15 @@ std::vector<GLProgramData::VertexAttib*> GLProgramData::getVertexAttributes(cons
return attribs;
}
GLProgramData::VertexAttrib* GLProgramData::getAttrib(const std::string& name)
{
std::map<std::string, VertexAttrib*>::const_iterator itr = _vertAttributes.find(name);
if(itr != _vertAttributes.end())
return itr->second;
else
return NULL;
}
unsigned int GLProgramData::getUniformCount()
{
return _uniforms.size();
@ -976,7 +1037,9 @@ unsigned int GLProgramData::getAttribCount()
}
UniformValue::UniformValue(): _uniform(nullptr), _program(nullptr)
UniformValue::UniformValue()
:_uniform(nullptr)
,_program(nullptr)
{
}

View File

@ -48,10 +48,66 @@ USING_NS_CC_MATH;
struct _hashUniformEntry;
class GLProgramData;
class UniformValue;
struct VertexAttrib;
typedef void (*GLInfoFunction)(GLuint program, GLenum pname, GLint* params);
typedef void (*GLLogFunction) (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
/** GLProgramData
Class store user defined vertexAttributes and uniforms
*/
class GLProgramData
{
public:
typedef struct _VertexAttrib
{
GLuint _index;
GLint _size;
GLenum _type;
std::string _name;
} VertexAttrib;
typedef struct _Uniform
{
GLint _location;
GLint _size;
std::string _name;
GLenum _type;
UniformValue* _uniformvalue;
} Uniform;
public:
GLProgramData();
~GLProgramData();
void addUniform(const std::string &name, Uniform* uniform);
void addAttrib(const std::string &name, VertexAttrib* attrib);
Uniform* getUniform(unsigned int index);
Uniform* getUniform(const std::string& name);
VertexAttrib* getAttrib(unsigned int index);
VertexAttrib* getAttrib(const std::string& name);
std::vector<GLProgramData::VertexAttrib*> getVertexAttributes(const std::string* attrNames, int count);
unsigned int getUniformCount();
unsigned int getAttribCount();
void setVertexSize(GLint size) { _vertexsize = size;}
GLint getVertexSize() {return _vertexsize;}
private:
GLint _vertexsize;
std::map<std::string, Uniform*> _uniforms;
std::map<std::string, VertexAttrib*> _vertAttributes;
};
/** GLProgram
Class that implements a glProgram
@ -151,12 +207,16 @@ public:
//void bindAttirbForUserdef();
void setUniformsForUserDef();
void setVertexAttrib(const GLvoid* vertex);
void setAttribForUserDef();
void setVertexAttrib(const GLvoid* vertex, bool isTight);
void autoParse();
//void bindUniformValue(std::string uniformName, int value);
UniformValue* getUniformValue(const std::string &name);
GLProgramData::VertexAttrib* getAttrib(std::string& name);
void bindAllAttrib();
/** It will add a new attribute to the shader by calling glBindAttribLocation */
void bindAttribLocation(const char* attributeName, GLuint index) const;
@ -272,7 +332,7 @@ public:
inline const GLuint getProgram() const { return _program; }
GLProgramData* getProgramData() { return _programDate; }
GLProgramData* getProgramData() { return _programData; }
// DEPRECATED
CC_DEPRECATED_ATTRIBUTE bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{ return initWithByteArrays(vShaderByteArray, fShaderByteArray); }
@ -297,8 +357,9 @@ private:
GLint _uniforms[UNIFORM_MAX];
struct _hashUniformEntry* _hashForUniforms;
bool _hasShaderCompiler;
bool _isTight;
GLProgramData* _programDate;
GLProgramData* _programData;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
std::string _shaderId;
@ -322,56 +383,6 @@ public:
/// @}
/** GLProgramData
Class store user defined vertexAttributes and uniforms
*/
class GLProgramData
{
public:
typedef struct _VertexAttib
{
GLuint _index;
GLint _size;
GLenum _type;
std::string _name;
} VertexAttib;
typedef struct _Uniform
{
GLint _location;
GLint _size;
std::string _name;
GLenum _type;
UniformValue* _uniformvalue;
} Uniform;
public:
GLProgramData();
~GLProgramData();
void addUniform(std::string &name, Uniform* uniform);
void addAttrib(std::string &name, VertexAttib* attrib);
Uniform* getUniform(unsigned int index);
Uniform* getUniform(const std::string& name);
VertexAttib* getAttrib(unsigned int index);
std::vector<GLProgramData::VertexAttib*> getVertexAttributes(const std::string* attrNames, int count);
unsigned int getUniformCount();
unsigned int getAttribCount();
void setVertexSize(GLint size) { _vertexsize = size;}
GLint getVertexSize() {return _vertexsize;}
private:
GLint _vertexsize;
std::map<std::string, Uniform*> _uniforms;
std::map<std::string, VertexAttib*> _vertAttributes;
};
class UniformValue
{

View File

@ -89,7 +89,7 @@ VertexAttribBind::VertexAttribBind(const std::vector<VertexAttribType>& elems)
setVertexAttribElems(&elems[0], elems.size());
}
VertexAttribBind::VertexAttribBind(const std::vector<GLProgramData::VertexAttib*>& attribs)
VertexAttribBind::VertexAttribBind(const std::vector<GLProgramData::VertexAttrib*>& attribs)
{
std::vector<VertexAttribType> elems;
for (auto it = attribs.begin(); it != attribs.end(); it++) {

View File

@ -63,7 +63,7 @@ public:
VertexAttribBind(const std::vector<VertexAttribType>& elems);
VertexAttribBind(const std::vector<GLProgramData::VertexAttib*>& attribs);
VertexAttribBind(const std::vector<GLProgramData::VertexAttrib*>& attribs);
virtual ~VertexAttribBind();

View File

@ -1,6 +1,8 @@
#include "ShaderTest.h"
#include "../testResource.h"
#include "cocos2d.h"
#include "renderer/CCCustomCommand.h"
#include "renderer/CCRenderer.h"
static int sceneIdx = -1;

View File

@ -1,4 +1,4 @@
#include "ShaderTest2.h"
#include "ShaderTest2.h"
#include "ShaderTest.h"
#include "../testResource.h"
#include "cocos2d.h"
@ -9,6 +9,7 @@ namespace ShaderTest2
{
static std::function<Layer*()> createFunctions[] =
{
CL(AttribShaderTest),
CL(NormalSpriteTest),
CL(GreyScaleSpriteTest),
CL(BlurSpriteTest),
@ -17,7 +18,11 @@ namespace ShaderTest2
CL(BloomSpriteTest),
CL(CelShadingSpriteTest),
CL(LensFlareSpriteTest),
CL(OutlineShadingSpriteTest)
CL(OutlineShadingSpriteTest),
CL(UniformShaderTest),
CL(UniformAttribShaderTest)
};
static unsigned int TEST_CASE_COUNT = sizeof(ShaderTest2::createFunctions) / sizeof(ShaderTest2::createFunctions[0]);
@ -693,10 +698,252 @@ OutlineShadingSpriteTest::OutlineShadingSpriteTest()
if (ShaderTestDemo2::init()) {
auto s = Director::getInstance()->getWinSize();
OutlineSprite* sprite = OutlineSprite::createSprite("Images/grossini_dance_10.png");
sprite->setPosition(Vector2(s.width * 0.75, s.height/2));
sprite->setPosition(Point(s.width * 0.75, s.height/2));
auto sprite2 = Sprite::create("Images/grossini_dance_10.png");
sprite2->setPosition(Vector2(s.width * 0.25, s.height/2));
sprite2->setPosition(Point(s.width * 0.25, s.height/2));
addChild(sprite);
addChild(sprite2);
}
}
class UniformSprite : public Sprite
{
public:
UniformSprite();
~UniformSprite();
CREATE_FUNC(UniformSprite);
virtual void initShader();
// void setBackgroundNotification();
virtual void draw(Renderer *renderer, const Matrix &transform, bool transformUpdated) override;
// void listenBackToForeground(Ref *obj);
protected:
// virtual void buildCustomUniforms();
virtual void setCustomUniforms();
protected:
std::string _fragSourceFile;
std::string _vertSourceFile;
protected:
CustomCommand _renderCommand;
void onDraw(const Matrix &transform, bool transformUpdated);
};
UniformSprite::UniformSprite()
{
_vertSourceFile = "Shaders/example_Heart.vsh";
_fragSourceFile = "Shaders/example_Heart.fsh";
}
UniformSprite::~UniformSprite()
{
}
void UniformSprite::initShader()
{
auto shader = new GLProgram();
shader->initWithFilenames(_vertSourceFile, _fragSourceFile);
shader->autoParse();
//shader->link();
shader->updateUniforms();
this->setShaderProgram(shader);
std::string attribname ="a_position";
shader->getAttrib(attribname)->_size = 2;
shader->release();
}
void UniformSprite::draw(Renderer *renderer, const Matrix &transform, bool transformUpdated)
{
_renderCommand.init(_globalZOrder);
_renderCommand.func = CC_CALLBACK_0(UniformSprite::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_renderCommand);
}
void UniformSprite::setCustomUniforms()
{
std::string name = "center";
_shaderProgram->getUniformValue(name)->setValue(Vector2(480,320));
name = "resolution";
_shaderProgram->getUniformValue(name)->setValue(Vector2(256,256));
_shaderProgram->setUniformsForUserDef();
}
void UniformSprite::onDraw(const Matrix &transform, bool transformUpdated)
{
// Set Shader GLProgram
auto program = getShaderProgram();
program->use();
program->setUniformsForBuiltins(transform);
setCustomUniforms();
//GL::bindTexture2D( getTexture()->getName());
program->setAttribForUserDef();
float w = 256, h = 256;
GLfloat vertices[12] = {0,0, w,0, w,h, 0,0, 0,h, w,h};
program->setVertexAttrib(vertices, true);
// Draw Call Test
glDrawArrays(GL_TRIANGLES, 0, 6);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,6);
CHECK_GL_ERROR_DEBUG();
}
UniformShaderTest::UniformShaderTest()
{
if (ShaderTestDemo2::init()) {
auto s = Director::getInstance()->getWinSize();
UniformSprite* sprite = UniformSprite::create();
setContentSize(Size(256, 256));
setAnchorPoint(Vector2(0.5f, 0.5f));
sprite->initShader();
sprite->setPosition(64,64);
addChild(sprite);
}
}
class AttribSprite : public Sprite
{
public:
AttribSprite();
~AttribSprite();
CREATE_FUNC(AttribSprite);
virtual void initShader();
// void setBackgroundNotification();
virtual void draw(Renderer *renderer, const Matrix &transform, bool transformUpdated) override;
// void listenBackToForeground(Ref *obj);
protected:
// virtual void buildCustomUniforms();
virtual void setCustomUniforms();
protected:
std::string _fragSourceFile;
std::string _vertSourceFile;
protected:
CustomCommand _renderCommand;
void onDraw(const Matrix &transform, bool transformUpdated);
};
AttribSprite::AttribSprite()
{
_fragSourceFile = "Shaders/example_normal.fsh";
_vertSourceFile = "Shaders/example_normal.vsh";
}
AttribSprite::~AttribSprite()
{
}
void AttribSprite::initShader()
{
auto shader = new GLProgram();
shader->initWithFilenames(_vertSourceFile, _fragSourceFile);
shader->autoParse();
shader->updateUniforms();
this->setShaderProgram(shader);
shader->release();
std::string attribname ="a_position";
shader->getAttrib(attribname)->_size = 3;
shader->getAttrib(attribname)->_index = 0;
attribname ="a_color";
shader->getAttrib(attribname)->_type = GL_UNSIGNED_BYTE;
shader->getAttrib(attribname)->_index = 1;
attribname ="a_texCoord";
shader->getAttrib(attribname)->_index = 2;
}
void AttribSprite::draw(Renderer *renderer, const Matrix &transform, bool transformUpdated)
{
_renderCommand.init(_globalZOrder);
_renderCommand.func = CC_CALLBACK_0(AttribSprite::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_renderCommand);
}
void AttribSprite::setCustomUniforms()
{
}
void AttribSprite::onDraw(const Matrix &transform, bool transformUpdated)
{
// Set Shader GLProgram
auto program = getShaderProgram();
program->use();
program->setUniformsForBuiltins(transform);
setCustomUniforms();
// Set
//glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
//GL::enableVertexAttribs(cocos2d::GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
GL::bindTexture2D( getTexture()->getName());
//
// Attributes
//
#define kQuadSize sizeof(_quad.bl)
size_t offset = (size_t)&_quad;
size_t stride = kQuadSize;
/*
// vertex
int diff = offsetof( V3F_C4B_T2F, vertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));
// texCoods
diff = offsetof( V3F_C4B_T2F, texCoords);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));
// color
diff = offsetof( V3F_C4B_T2F, colors);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));
*/
program->setVertexAttrib((void*)offset, false);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 4);
CHECK_GL_ERROR_DEBUG();
}
AttribShaderTest::AttribShaderTest()
{
if (ShaderTestDemo2::init())
{
auto s = Director::getInstance()->getWinSize();
AttribSprite* sprite = AttribSprite::create();
sprite->setTexture("Images/powered.png");
sprite->initShader();
sprite->setPosition(Vector2(s.width/2, s.height/2));
addChild(sprite);
}
}
UniformAttribShaderTest::UniformAttribShaderTest()
{
}

View File

@ -102,4 +102,28 @@ public:
virtual std::string subtitle() const {return "OutlineShadingSpriteTest";}
};
class UniformShaderTest : public ShaderTestDemo2
{
public:
CREATE_FUNC(UniformShaderTest);
UniformShaderTest();
virtual std::string subtitle() const {return "UniformShaderTest";}
};
class AttribShaderTest : public ShaderTestDemo2
{
public:
CREATE_FUNC(AttribShaderTest);
AttribShaderTest();
virtual std::string subtitle() const {return "AttribShaderTest";}
};
class UniformAttribShaderTest : public ShaderTestDemo2
{
public:
CREATE_FUNC(UniformAttribShaderTest);
UniformAttribShaderTest();
virtual std::string subtitle() const {return "UniformAndShaderTest";}
};
#endif

View File

@ -0,0 +1,20 @@
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_MVPMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}