Initial multitexturing support

This commit is contained in:
Ricardo Quesada 2014-05-12 23:51:37 -07:00
parent a3aed414fa
commit 71848aca93
6 changed files with 76 additions and 32 deletions

View File

@ -328,7 +328,7 @@ void GLProgram::parseUniforms()
glGetActiveUniform(_program, i, length, NULL, &uniform.size, &uniform.type, uniformName);
uniformName[length] = '\0';
// Only add uniforms that are not build-in.
// Only add uniforms that are not built-in.
// The ones that start with 'CC_' are built-ins
if(strncmp("CC_", uniformName, 3) != 0) {
@ -617,7 +617,7 @@ GLint GLProgram::getUniformLocationForName(const char* name) const
void GLProgram::setUniformLocationWith1i(GLint location, GLint i1)
{
bool updated = updateUniformLocation(location, &i1, sizeof(i1)*1);
bool updated = updateUniformLocation(location, &i1, sizeof(i1)*1);
if( updated )
{
@ -628,7 +628,7 @@ void GLProgram::setUniformLocationWith1i(GLint location, GLint i1)
void GLProgram::setUniformLocationWith2i(GLint location, GLint i1, GLint i2)
{
GLint ints[2] = {i1,i2};
bool updated = updateUniformLocation(location, ints, sizeof(ints));
bool updated = updateUniformLocation(location, ints, sizeof(ints));
if( updated )
{
@ -639,7 +639,7 @@ void GLProgram::setUniformLocationWith2i(GLint location, GLint i1, GLint i2)
void GLProgram::setUniformLocationWith3i(GLint location, GLint i1, GLint i2, GLint i3)
{
GLint ints[3] = {i1,i2,i3};
bool updated = updateUniformLocation(location, ints, sizeof(ints));
bool updated = updateUniformLocation(location, ints, sizeof(ints));
if( updated )
{
@ -650,7 +650,7 @@ void GLProgram::setUniformLocationWith3i(GLint location, GLint i1, GLint i2, GLi
void GLProgram::setUniformLocationWith4i(GLint location, GLint i1, GLint i2, GLint i3, GLint i4)
{
GLint ints[4] = {i1,i2,i3,i4};
bool updated = updateUniformLocation(location, ints, sizeof(ints));
bool updated = updateUniformLocation(location, ints, sizeof(ints));
if( updated )
{
@ -660,7 +660,7 @@ void GLProgram::setUniformLocationWith4i(GLint location, GLint i1, GLint i2, GLi
void GLProgram::setUniformLocationWith2iv(GLint location, GLint* ints, unsigned int numberOfArrays)
{
bool updated = updateUniformLocation(location, ints, sizeof(int)*2*numberOfArrays);
bool updated = updateUniformLocation(location, ints, sizeof(int)*2*numberOfArrays);
if( updated )
{
@ -670,7 +670,7 @@ void GLProgram::setUniformLocationWith2iv(GLint location, GLint* ints, unsigned
void GLProgram::setUniformLocationWith3iv(GLint location, GLint* ints, unsigned int numberOfArrays)
{
bool updated = updateUniformLocation(location, ints, sizeof(int)*3*numberOfArrays);
bool updated = updateUniformLocation(location, ints, sizeof(int)*3*numberOfArrays);
if( updated )
{
@ -680,7 +680,7 @@ void GLProgram::setUniformLocationWith3iv(GLint location, GLint* ints, unsigned
void GLProgram::setUniformLocationWith4iv(GLint location, GLint* ints, unsigned int numberOfArrays)
{
bool updated = updateUniformLocation(location, ints, sizeof(int)*4*numberOfArrays);
bool updated = updateUniformLocation(location, ints, sizeof(int)*4*numberOfArrays);
if( updated )
{
@ -690,7 +690,7 @@ void GLProgram::setUniformLocationWith4iv(GLint location, GLint* ints, unsigned
void GLProgram::setUniformLocationWith1f(GLint location, GLfloat f1)
{
bool updated = updateUniformLocation(location, &f1, sizeof(f1)*1);
bool updated = updateUniformLocation(location, &f1, sizeof(f1)*1);
if( updated )
{
@ -712,7 +712,7 @@ void GLProgram::setUniformLocationWith2f(GLint location, GLfloat f1, GLfloat f2)
void GLProgram::setUniformLocationWith3f(GLint location, GLfloat f1, GLfloat f2, GLfloat f3)
{
GLfloat floats[3] = {f1,f2,f3};
bool updated = updateUniformLocation(location, floats, sizeof(floats));
bool updated = updateUniformLocation(location, floats, sizeof(floats));
if( updated )
{
@ -723,7 +723,7 @@ void GLProgram::setUniformLocationWith3f(GLint location, GLfloat f1, GLfloat f2,
void GLProgram::setUniformLocationWith4f(GLint location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4)
{
GLfloat floats[4] = {f1,f2,f3,f4};
bool updated = updateUniformLocation(location, floats, sizeof(floats));
bool updated = updateUniformLocation(location, floats, sizeof(floats));
if( updated )
{
@ -733,7 +733,7 @@ void GLProgram::setUniformLocationWith4f(GLint location, GLfloat f1, GLfloat f2,
void GLProgram::setUniformLocationWith2fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays)
{
bool updated = updateUniformLocation(location, floats, sizeof(float)*2*numberOfArrays);
bool updated = updateUniformLocation(location, floats, sizeof(float)*2*numberOfArrays);
if( updated )
{
@ -743,7 +743,7 @@ void GLProgram::setUniformLocationWith2fv(GLint location, const GLfloat* floats,
void GLProgram::setUniformLocationWith3fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays)
{
bool updated = updateUniformLocation(location, floats, sizeof(float)*3*numberOfArrays);
bool updated = updateUniformLocation(location, floats, sizeof(float)*3*numberOfArrays);
if( updated )
{
@ -753,7 +753,7 @@ void GLProgram::setUniformLocationWith3fv(GLint location, const GLfloat* floats,
void GLProgram::setUniformLocationWith4fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays)
{
bool updated = updateUniformLocation(location, floats, sizeof(float)*4*numberOfArrays);
bool updated = updateUniformLocation(location, floats, sizeof(float)*4*numberOfArrays);
if( updated )
{
@ -762,7 +762,7 @@ void GLProgram::setUniformLocationWith4fv(GLint location, const GLfloat* floats,
}
void GLProgram::setUniformLocationWithMatrix2fv(GLint location, const GLfloat* matrixArray, unsigned int numberOfMatrices) {
bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*4*numberOfMatrices);
bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*4*numberOfMatrices);
if( updated )
{
@ -771,7 +771,7 @@ void GLProgram::setUniformLocationWithMatrix2fv(GLint location, const GLfloat* m
}
void GLProgram::setUniformLocationWithMatrix3fv(GLint location, const GLfloat* matrixArray, unsigned int numberOfMatrices) {
bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*9*numberOfMatrices);
bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*9*numberOfMatrices);
if( updated )
{
@ -782,7 +782,7 @@ void GLProgram::setUniformLocationWithMatrix3fv(GLint location, const GLfloat* m
void GLProgram::setUniformLocationWithMatrix4fv(GLint location, const GLfloat* matrixArray, unsigned int numberOfMatrices)
{
bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*16*numberOfMatrices);
bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*16*numberOfMatrices);
if( updated )
{

View File

@ -31,6 +31,7 @@ THE SOFTWARE.
#include "renderer/CCGLProgramStateCache.h"
#include "renderer/CCGLProgramCache.h"
#include "renderer/ccGLStateCache.h"
#include "2d/CCTexture2D.h"
NS_CC_BEGIN
@ -68,15 +69,20 @@ void UniformValue::apply()
else
{
switch (_uniform->type) {
case GL_FLOAT:
_glprogram->setUniformLocationWith1f(_uniform->location, _value.floatValue);
case GL_SAMPLER_2D:
_glprogram->setUniformLocationWith1i(_uniform->location, _value.tex.textureUnit);
GL::activeTexture(_value.tex.textureUnit);
GL::bindTexture2DN(_value.tex.textureUnit, _value.tex.textureId);
break;
case GL_INT:
case GL_SAMPLER_2D:
_glprogram->setUniformLocationWith1i(_uniform->location, _value.intValue);
break;
case GL_FLOAT:
_glprogram->setUniformLocationWith1f(_uniform->location, _value.floatValue);
break;
case GL_FLOAT_VEC2:
_glprogram->setUniformLocationWith2f(_uniform->location, _value.v2Value[0], _value.v2Value[1]);
break;
@ -122,9 +128,16 @@ void UniformValue::setFloat(float value)
_useCallback = false;
}
void UniformValue::setTexture(GLuint textureId, GLuint textureUnit)
{
CCASSERT(_uniform->type == GL_SAMPLER_2D, "Wrong type. expecting GL_SAMPLER_2D");
_value.tex.textureId = textureId;
_value.tex.textureUnit = textureUnit;
_useCallback = false;
}
void UniformValue::setInt(int value)
{
CCASSERT ((_uniform->type == GL_INT || _uniform->type == GL_SAMPLER_2D), "");
CCASSERT(_uniform->type == GL_INT, "Wrong type: expecting GL_INT");
_value.intValue = value;
_useCallback = false;
}
@ -255,6 +268,7 @@ GLProgramState* GLProgramState::getOrCreate(GLProgram *glprogram)
GLProgramState::GLProgramState()
: _vertexAttribsFlags(0)
, _glprogram(nullptr)
, _textureUnitIndex(1)
{
}
@ -288,6 +302,8 @@ void GLProgramState::resetGLProgram()
CC_SAFE_RELEASE(_glprogram);
_uniforms.clear();
_attributes.clear();
// first texture is GL_TEXTURE1
_textureUnitIndex = 1;
}
void GLProgramState::apply(const Matrix& modelView)
@ -296,12 +312,10 @@ void GLProgramState::apply(const Matrix& modelView)
// set shader
_glprogram->use();
_glprogram->setUniformsForBuiltins(modelView);
// quick hack:
// Don't deal with attributes if they were set
// Don't set attributes if they weren't set
// Use Case: Auto-batching
if(_vertexAttribsFlags) {
// enable/disable vertex attribs
GL::enableVertexAttribs(_vertexAttribsFlags);
@ -320,7 +334,7 @@ void GLProgramState::apply(const Matrix& modelView)
void GLProgramState::setGLProgram(GLProgram *glprogram)
{
CCASSERT(glprogram, "invalid GLProgram");
CCASSERT(glprogram, "invalid GLProgram");
if( _glprogram != glprogram) {
resetGLProgram();
@ -439,4 +453,22 @@ void GLProgramState::setUniformMat4(const std::string &uniformName, const Matrix
CCLOG("cocos2d: warning: Uniform not found: %s", uniformName.c_str());
}
// Textures
void GLProgramState::setUniformTexture(const std::string &uniformName, Texture2D *texture)
{
CCASSERT(texture, "Invalid texture");
setUniformTexture(uniformName, texture->getName());
}
void GLProgramState::setUniformTexture(const std::string &uniformName, GLuint textureId)
{
auto v = getUniformValue(uniformName);
if (v)
v->setTexture(textureId, _textureUnitIndex++);
else
CCLOG("cocos2d: warning: Uniform not found: %s", uniformName.c_str());
}
NS_CC_END

View File

@ -32,10 +32,13 @@ THE SOFTWARE.
#include "math/Vector4.h"
#include <unordered_map>
#include <vector>
NS_CC_BEGIN
class GLProgram;
class Texture2D;
struct Uniform;
struct VertexAttrib;
@ -60,6 +63,7 @@ public:
void setVec4(const Vector4& value);
void setMat4(const Matrix& value);
void setCallback(const std::function<void(Uniform*)> &callback);
void setTexture(GLuint textureId, GLuint activeTexture);
void apply();
@ -75,6 +79,10 @@ protected:
float v3Value[3];
float v4Value[4];
float matrixValue[16];
struct {
GLuint textureId;
GLuint textureUnit;
} tex;
std::function<void(Uniform*)> *callback;
U() { memset( this, 0, sizeof(*this) ); }
@ -154,20 +162,23 @@ public:
void setGLProgram(GLProgram* glprogram);
GLProgram* getGLProgram() const { return _glprogram; }
// vertex attribs
uint32_t getVertexAttribsFlags() const { return _vertexAttribsFlags; }
ssize_t getVertexAttribCount() const { return _attributes.size(); }
void setVertexAttribCallback(const std::string &name, const std::function<void(VertexAttrib*)> &callback);
void setVertexAttribPointer(const std::string &name, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLvoid *pointer);
// user defined uniforms
ssize_t getUniformCount() const { return _uniforms.size(); }
void setUniformFloat(const std::string &uniformName, float value);
void setUniformInt(const std::string &uniformName, int value);
void setUniformFloat(const std::string &uniformName, float value);
void setUniformVec2(const std::string &uniformName, const Vector2& value);
void setUniformVec3(const std::string &uniformName, const Vector3& value);
void setUniformVec4(const std::string &uniformName, const Vector4& value);
void setUniformMat4(const std::string &uniformName, const Matrix& value);
void setUniformCallback(const std::string &uniformName, const std::function<void(Uniform*)> &callback);
void setUniformTexture(const std::string &uniformName, Texture2D *texture);
void setUniformTexture(const std::string &uniformName, GLuint textureId);
protected:
GLProgramState();
@ -180,6 +191,7 @@ protected:
std::unordered_map<std::string, UniformValue> _uniforms;
std::unordered_map<std::string, VertexAttribValue> _attributes;
int _textureUnitIndex;
uint32_t _vertexAttribsFlags;
GLProgram *_glprogram;
};

View File

@ -72,9 +72,9 @@ QuadCommand::~QuadCommand()
void QuadCommand::generateMaterialID()
{
if( _glProgramState->getUniformCount() > 0 )
if(_glProgramState->getUniformCount() > 0)
{
_materialID = QuadCommand::MATERIAL_ID_IGNORE;
_materialID = QuadCommand::MATERIAL_ID_DO_NOT_BATCH;
}
else
{

View File

@ -35,7 +35,7 @@ NS_CC_BEGIN
class QuadCommand : public RenderCommand
{
public:
static const int MATERIAL_ID_IGNORE = 0;
static const int MATERIAL_ID_DO_NOT_BATCH = 0;
QuadCommand();
~QuadCommand();

View File

@ -453,7 +453,7 @@ void Renderer::drawBatchedQuads()
for(const auto& cmd : _batchedQuadCommands)
{
auto newMaterialID = cmd->getMaterialID();
if(_lastMaterialID != newMaterialID || newMaterialID == QuadCommand::MATERIAL_ID_IGNORE)
if(_lastMaterialID != newMaterialID || newMaterialID == QuadCommand::MATERIAL_ID_DO_NOT_BATCH)
{
//Draw quads
if(quadsToDraw > 0)