issue #1056: Update CCGLProgram.

This commit is contained in:
James Chen 2012-03-15 10:54:07 +08:00
parent 9e89171557
commit 303818ef6d
2 changed files with 58 additions and 60 deletions

View File

@ -45,12 +45,12 @@ typedef struct _hashUniformEntry
} tHashUniformEntry; } tHashUniformEntry;
CCGLProgram::CCGLProgram() CCGLProgram::CCGLProgram()
: program_(0) : m_uProgram(0)
, vertShader_(0) , m_uVertShader(0)
, fragShader_(0) , m_uFragShader(0)
, hashForUniforms_(NULL) , m_pHashForUniforms(NULL)
{ {
memset(uniforms_, 0, sizeof(uniforms_)); memset(m_uUniforms, 0, sizeof(m_uUniforms));
} }
CCGLProgram::~CCGLProgram() CCGLProgram::~CCGLProgram()
@ -58,19 +58,19 @@ CCGLProgram::~CCGLProgram()
CCLOGINFO("cocos2d: deallocing 0x%X", this); CCLOGINFO("cocos2d: deallocing 0x%X", this);
// there is no need to delete the shaders. They should have been already deleted. // there is no need to delete the shaders. They should have been already deleted.
CCAssert( vertShader_ == 0, "Vertex Shaders should have been already deleted"); CCAssert( m_uVertShader == 0, "Vertex Shaders should have been already deleted");
CCAssert( fragShader_ == 0, "Vertex Shaders should have been already deleted"); CCAssert( m_uFragShader == 0, "Vertex Shaders should have been already deleted");
if (program_) if (m_uProgram)
{ {
ccGLDeleteProgram(program_); ccGLDeleteProgram(m_uProgram);
} }
tHashUniformEntry *current_element, *tmp; tHashUniformEntry *current_element, *tmp;
// Purge uniform hash // Purge uniform hash
HASH_ITER(hh, hashForUniforms_, current_element, tmp) { HASH_ITER(hh, m_pHashForUniforms, current_element, tmp) {
HASH_DEL(hashForUniforms_, current_element); HASH_DEL(m_pHashForUniforms, current_element);
free(current_element->value); free(current_element->value);
free(current_element); free(current_element);
} }
@ -78,13 +78,13 @@ CCGLProgram::~CCGLProgram()
bool CCGLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray) bool CCGLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{ {
program_ = glCreateProgram(); m_uProgram = glCreateProgram();
vertShader_ = fragShader_ = 0; m_uVertShader = m_uFragShader = 0;
if( vShaderByteArray ) { if( vShaderByteArray ) {
if (!compileShader(&vertShader_, GL_VERTEX_SHADER, vShaderByteArray)) { if (!compileShader(&m_uVertShader, GL_VERTEX_SHADER, vShaderByteArray)) {
CCLOG("cocos2d: ERROR: Failed to compile vertex shader"); CCLOG("cocos2d: ERROR: Failed to compile vertex shader");
} }
@ -93,19 +93,19 @@ bool CCGLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray,
// Create and compile fragment shader // Create and compile fragment shader
if( fShaderByteArray ) { if( fShaderByteArray ) {
if (!compileShader(&fragShader_, GL_FRAGMENT_SHADER, fShaderByteArray)) { if (!compileShader(&m_uFragShader, GL_FRAGMENT_SHADER, fShaderByteArray)) {
CCLOG("cocos2d: ERROR: Failed to compile fragment shader"); CCLOG("cocos2d: ERROR: Failed to compile fragment shader");
} }
} }
if( vertShader_ ) { if( m_uVertShader ) {
glAttachShader(program_, vertShader_); glAttachShader(m_uProgram, m_uVertShader);
} }
if( fragShader_ ) { if( m_uFragShader ) {
glAttachShader(program_, fragShader_); glAttachShader(m_uProgram, m_uFragShader);
} }
hashForUniforms_ = NULL; m_pHashForUniforms = NULL;
return true; return true;
} }
@ -121,7 +121,7 @@ bool CCGLProgram::initWithVertexShaderFilename(const char* vShaderFilename, cons
const char* CCGLProgram::description() const char* CCGLProgram::description()
{ {
static char strDescription[100] = {0}; static char strDescription[100] = {0};
sprintf(strDescription, "<CCGLProgram = %08X | Program = %i, VertexShader = %i, FragmentShader = %i>", this, program_, vertShader_, fragShader_); sprintf(strDescription, "<CCGLProgram = %08X | Program = %i, VertexShader = %i, FragmentShader = %i>", this, m_uProgram, m_uVertShader, m_uFragShader);
return strDescription; return strDescription;
} }
@ -150,7 +150,7 @@ bool CCGLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* sour
void CCGLProgram::addAttribute(const char* attributeName, GLuint index) void CCGLProgram::addAttribute(const char* attributeName, GLuint index)
{ {
glBindAttribLocation(program_, glBindAttribLocation(m_uProgram,
index, index,
attributeName); attributeName);
} }
@ -159,48 +159,48 @@ void CCGLProgram::updateUniforms()
{ {
// Since sample most probably won't change, set it to 0 now. // Since sample most probably won't change, set it to 0 now.
uniforms_[kCCUniformMVPMatrix] = glGetUniformLocation(program_, kCCUniformMVPMatrix_s); m_uUniforms[kCCUniformMVPMatrix] = glGetUniformLocation(m_uProgram, kCCUniformMVPMatrix_s);
uniforms_[kCCUniformSampler] = glGetUniformLocation(program_, kCCUniformSampler_s); m_uUniforms[kCCUniformSampler] = glGetUniformLocation(m_uProgram, kCCUniformSampler_s);
this->use(); this->use();
this->setUniformLocationWith1i( uniforms_[kCCUniformSampler], 0 ); this->setUniformLocationWith1i( m_uUniforms[kCCUniformSampler], 0 );
} }
bool CCGLProgram::link() bool CCGLProgram::link()
{ {
glLinkProgram(program_); glLinkProgram(m_uProgram);
#if DEBUG #if DEBUG
GLint status; GLint status;
glValidateProgram(program_); glValidateProgram(m_uProgram);
glGetProgramiv(program_, GL_LINK_STATUS, &status); glGetProgramiv(m_uProgram, GL_LINK_STATUS, &status);
if (status == GL_FALSE) { if (status == GL_FALSE) {
CCLOG("cocos2d: ERROR: Failed to link program: %i", program_); CCLOG("cocos2d: ERROR: Failed to link program: %i", m_uProgram);
if( vertShader_ ) if( m_uVertShader )
glDeleteShader( vertShader_ ); glDeleteShader( m_uVertShader );
if( fragShader_ ) if( m_uFragShader )
glDeleteShader( fragShader_ ); glDeleteShader( m_uFragShader );
ccGLDeleteProgram( program_ ); ccGLDeleteProgram( m_uProgram );
vertShader_ = fragShader_ = program_ = 0; m_uVertShader = m_uFragShader = m_uProgram = 0;
return false; return false;
} }
#endif #endif
if (vertShader_) if (m_uVertShader)
glDeleteShader(vertShader_); glDeleteShader(m_uVertShader);
if (fragShader_) if (m_uFragShader)
glDeleteShader(fragShader_); glDeleteShader(m_uFragShader);
vertShader_ = fragShader_ = 0; m_uVertShader = m_uFragShader = 0;
return true; return true;
} }
void CCGLProgram::use() void CCGLProgram::use()
{ {
ccGLUseProgram(program_); ccGLUseProgram(m_uProgram);
} }
const char* CCGLProgram::logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc) const char* CCGLProgram::logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc)
@ -223,17 +223,17 @@ const char* CCGLProgram::logForOpenGLObject(GLuint object, GLInfoFunction infoFu
const char* CCGLProgram::vertexShaderLog() const char* CCGLProgram::vertexShaderLog()
{ {
return this->logForOpenGLObject(vertShader_, (GLInfoFunction)&glGetShaderiv, (GLLogFunction)&glGetShaderInfoLog); return this->logForOpenGLObject(m_uVertShader, (GLInfoFunction)&glGetShaderiv, (GLLogFunction)&glGetShaderInfoLog);
} }
const char* CCGLProgram::fragmentShaderLog() const char* CCGLProgram::fragmentShaderLog()
{ {
return this->logForOpenGLObject(fragShader_, (GLInfoFunction)&glGetShaderiv, (GLLogFunction)&glGetShaderInfoLog); return this->logForOpenGLObject(m_uFragShader, (GLInfoFunction)&glGetShaderiv, (GLLogFunction)&glGetShaderInfoLog);
} }
const char* CCGLProgram::programLog() const char* CCGLProgram::programLog()
{ {
return this->logForOpenGLObject(program_, (GLInfoFunction)&glGetProgramiv, (GLLogFunction)&glGetProgramInfoLog); return this->logForOpenGLObject(m_uProgram, (GLInfoFunction)&glGetProgramiv, (GLLogFunction)&glGetProgramInfoLog);
} }
// Uniform cache // Uniform cache
@ -242,7 +242,7 @@ bool CCGLProgram::updateUniformLocation(unsigned int location, GLvoid* data, uns
{ {
bool updated = true; bool updated = true;
tHashUniformEntry *element = NULL; tHashUniformEntry *element = NULL;
HASH_FIND_INT(hashForUniforms_, &location, element); HASH_FIND_INT(m_pHashForUniforms, &location, element);
if( ! element ) { if( ! element ) {
@ -255,7 +255,7 @@ bool CCGLProgram::updateUniformLocation(unsigned int location, GLvoid* data, uns
element->value = malloc( bytes ); element->value = malloc( bytes );
memcpy(element->value, data, bytes ); memcpy(element->value, data, bytes );
HASH_ADD_INT(hashForUniforms_, location, element); HASH_ADD_INT(m_pHashForUniforms, location, element);
} }
else else
{ {
@ -355,7 +355,7 @@ void CCGLProgram::setUniformForModelViewProjectionMatrix()
kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV); kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV);
setUniformLocationwithMatrix4fv(uniforms_[kCCUniformMVPMatrix], matrixMVP.mat, 1); setUniformLocationwithMatrix4fv(m_uUniforms[kCCUniformMVPMatrix], matrixMVP.mat, 1);
} }
NS_CC_END NS_CC_END

View File

@ -68,13 +68,8 @@ enum {
struct _hashUniformEntry; struct _hashUniformEntry;
typedef void (*GLInfoFunction)(GLuint program, typedef void (*GLInfoFunction)(GLuint program, GLenum pname, GLint* params);
GLenum pname, typedef void (*GLLogFunction) (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
GLint* params);
typedef void (*GLLogFunction) (GLuint program,
GLsizei bufsize,
GLsizei* length,
GLchar* infolog);
/** CCGLProgram /** CCGLProgram
Class that implements a glProgram Class that implements a glProgram
@ -85,6 +80,8 @@ typedef void (*GLLogFunction) (GLuint program,
class CC_DLL CCGLProgram : public CCObject class CC_DLL CCGLProgram : public CCObject
{ {
public: public:
CCGLProgram(); CCGLProgram();
virtual ~CCGLProgram(); virtual ~CCGLProgram();
/** Initializes the CCGLProgram with a vertex and fragment with bytes array */ /** Initializes the CCGLProgram with a vertex and fragment with bytes array */
@ -143,19 +140,20 @@ public:
/** returns the program error log */ /** returns the program error log */
const char* programLog(); const char* programLog();
private: private:
bool updateUniformLocation(unsigned int location, GLvoid* data, unsigned int bytes); bool updateUniformLocation(unsigned int location, GLvoid* data, unsigned int bytes);
const char* description(); const char* description();
bool compileShader(GLuint * shader, GLenum type, const GLchar* source); bool compileShader(GLuint * shader, GLenum type, const GLchar* source);
const char* logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc); const char* logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc);
public: CC_SYNTHESIZE_READONLY(GLuint, m_uProgram, Program);
GLuint program_;
GLuint vertShader_;
GLuint fragShader_;
GLint uniforms_[kCCUniform_MAX];
private: private:
struct _hashUniformEntry* hashForUniforms_; GLuint m_uVertShader;
GLuint m_uFragShader;
GLint m_uUniforms[kCCUniform_MAX];
struct _hashUniformEntry* m_pHashForUniforms;
}; };
NS_CC_END NS_CC_END