void Shader::extractShaderUniforms() { GLuint pId = getProgramID(); const int BUFF_SIZE = 255; int count; glGetProgramiv(pId, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &count); for (int i = 0; i < count; ++i) { char name[BUFF_SIZE]; // for holding the variable name GLint size = BUFF_SIZE; GLenum type; GLsizei length; GLsizei bufSize = BUFF_SIZE; glGetActiveUniform(pId, i, bufSize, &length, &size, &type, name); int location = glGetUniformLocation(pId, name); Uniform* uniform = UniformFactory::createUniform(name, type); uniform->addOwner(this,location); uniforms.insert(std::make_pair(uniform->getName(), uniform)); //Borrar const char* uni_types[6] = { "Error", "FLOAT", "FLOAT_VEC3", "FLOAT_VEC4", "FLOAT_MAT3", "FLOAT_MAT4" }; printf("Uniform name: %s. Type: %s.\n", uniform->getName().c_str(), uni_types[uniform->getType()]); } printf("---------------\n"); }
Uniform* Effect::getUniform(const char* name) const { std::map<std::string, Uniform*>::const_iterator itr = _uniforms.find(name); if (itr != _uniforms.end()) { // Return cached uniform variable return itr->second; } GLint uniformLocation; GL_ASSERT( uniformLocation = glGetUniformLocation(_program, name) ); if (uniformLocation > -1) { // Check for array uniforms ("u_directionalLightColor[0]" -> "u_directionalLightColor") char* parentname = new char[strlen(name)+1]; strcpy(parentname, name); if (strtok(parentname, "[") != NULL) { std::map<std::string, Uniform*>::const_iterator itr = _uniforms.find(parentname); if (itr != _uniforms.end()) { Uniform* puniform = itr->second; Uniform* uniform = new Uniform(); uniform->_effect = const_cast<Effect*>(this); uniform->_name = name; uniform->_location = uniformLocation; uniform->_index = 0; uniform->_type = puniform->getType(); _uniforms[name] = uniform; delete parentname; return uniform; } } delete parentname; } // No uniform variable found - return NULL return NULL; }
void UniformRegistry::setUniform(const Uniform & uniform, bool warnIfUnused, bool forced){ entry_t * & entry = uniforms[uniform.getNameId()]; if(entry==nullptr){ // new entry entry = new entry_t( uniform,warnIfUnused,getNewGlobalStep() ); orderedList.push_front(entry); entry->positionInUpdateList=orderedList.begin(); } // if an entry exists and appliance is forced or (uniform is valid and value has changed) else if( forced || (entry->valid && !(uniform==entry->uniform)) ){ //! \note This warning should do no harm - otherwise remove it. if(entry->uniform.getType()!=uniform.getType() ){ WARN("Type of Uniform changed; this may be a problem. "+entry->uniform.toString()+" -> "+uniform.toString()); } // move entry to the front of the orderedList orderedList.erase(entry->positionInUpdateList); orderedList.push_front(entry); entry->reset(uniform,getNewGlobalStep(),warnIfUnused,orderedList.begin()); } // else: if the value of an uniform has not changed or the uniform could not be set (= invalid), nothing needs to be done. }
int lua_Uniform_getType(lua_State* state) { // Get the number of parameters. int paramCount = lua_gettop(state); // Attempt to match the parameters to a valid binding. switch (paramCount) { case 1: { if ((lua_type(state, 1) == LUA_TUSERDATA)) { Uniform* instance = getInstance(state); GLenum result = instance->getType(); // Push the return value onto the stack. GP_WARN("Attempting to return value with unrecognized type GLenum as an unsigned integer."); lua_pushunsigned(state, result); return 1; } else { lua_pushstring(state, "lua_Uniform_getType - Failed to match the given parameters to a valid function signature."); lua_error(state); } break; } default: { lua_pushstring(state, "Invalid number of parameters (expected 1)."); lua_error(state); break; } } return 0; }
void Shader::setUniform(const Uniform& uniform) { switch(uniform.getType()) { case Graphics::Uniform::UniformTypes::FLOAT: setUniform(uniform.getName(), uniform.getData<float>()); break; case Graphics::Uniform::UniformTypes::VEC2: setUniform(uniform.getName(), uniform.getData<glm::vec2>()); break; case Graphics::Uniform::UniformTypes::VEC3: setUniform(uniform.getName(), uniform.getData<glm::vec2>()); break; case Graphics::Uniform::UniformTypes::VEC4: setUniform(uniform.getName(), uniform.getData<glm::vec4>()); break; case Graphics::Uniform::UniformTypes::INT: setUniform(uniform.getName(), uniform.getData<int>()); break; case Graphics::Uniform::UniformTypes::IVEC2: setUniform(uniform.getName(), uniform.getData<glm::ivec2>()); break; case Graphics::Uniform::UniformTypes::IVEC3: setUniform(uniform.getName(), uniform.getData<glm::ivec3>()); break; case Graphics::Uniform::UniformTypes::IVEC4: setUniform(uniform.getName(), uniform.getData<glm::ivec4>()); break; case Graphics::Uniform::UniformTypes::UINT: setUniform(uniform.getName(), uniform.getData<unsigned int>()); break; case Graphics::Uniform::UniformTypes::UVEC2: setUniform(uniform.getName(), uniform.getData<glm::uvec2>()); break; case Graphics::Uniform::UniformTypes::UVEC3: setUniform(uniform.getName(), uniform.getData<glm::uvec3>()); break; case Graphics::Uniform::UniformTypes::UVEC4: setUniform(uniform.getName(), uniform.getData<glm::uvec4>()); break; case Graphics::Uniform::UniformTypes::BOOL: setUniform(uniform.getName(), uniform.getData<bool>()); break; case Graphics::Uniform::UniformTypes::BVEC2: setUniform(uniform.getName(), uniform.getData<glm::bvec2>()); break; case Graphics::Uniform::UniformTypes::BVEC3: setUniform(uniform.getName(), uniform.getData<glm::bvec3>()); break; case Graphics::Uniform::UniformTypes::BVEC4: setUniform(uniform.getName(), uniform.getData<glm::bvec4>()); break; case Graphics::Uniform::UniformTypes::MAT2: setUniform(uniform.getName(), uniform.getData<glm::mat2>()); break; case Graphics::Uniform::UniformTypes::MAT3: setUniform(uniform.getName(), uniform.getData<glm::mat3>()); break; case Graphics::Uniform::UniformTypes::MAT4: setUniform(uniform.getName(), uniform.getData<glm::mat4>()); break; case Graphics::Uniform::UniformTypes::MAT23: setUniform(uniform.getName(), uniform.getData<glm::mat2x3>()); break; case Graphics::Uniform::UniformTypes::MAT32: setUniform(uniform.getName(), uniform.getData<glm::mat3x2>()); break; case Graphics::Uniform::UniformTypes::MAT24: setUniform(uniform.getName(), uniform.getData<glm::mat2x4>()); break; case Graphics::Uniform::UniformTypes::MAT42: setUniform(uniform.getName(), uniform.getData<glm::mat4x2>()); break; case Graphics::Uniform::UniformTypes::MAT34: setUniform(uniform.getName(), uniform.getData<glm::mat3x4>()); break; case Graphics::Uniform::UniformTypes::MAT43: setUniform(uniform.getName(), uniform.getData<glm::mat4x3>()); break; default: break; } }
SpriteBatch* SpriteBatch::create(Texture* texture, Effect* effect, unsigned int initialCapacity) { GP_ASSERT(texture != NULL); bool customEffect = (effect != NULL); if (!customEffect) { // Create our static sprite effect. if (__spriteEffect == NULL) { __spriteEffect = Effect::createFromFile(SPRITE_VSH, SPRITE_FSH); if (__spriteEffect == NULL) { GP_ERROR("Unable to load sprite effect."); return NULL; } effect = __spriteEffect; } else { effect = __spriteEffect; __spriteEffect->addRef(); } } // Search for the first sampler uniform in the effect. Uniform* samplerUniform = NULL; for (unsigned int i = 0, count = effect->getUniformCount(); i < count; ++i) { Uniform* uniform = effect->getUniform(i); if (uniform && uniform->getType() == GL_SAMPLER_2D) { samplerUniform = uniform; break; } } if (!samplerUniform) { GP_ERROR("No uniform of type GL_SAMPLER_2D found in sprite effect."); SAFE_RELEASE(effect); return NULL; } // Wrap the effect in a material Material* material = Material::create(effect); // +ref effect // Set initial material state material->getStateBlock()->setBlend(true); material->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA); material->getStateBlock()->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA); //material->getStateBlock()->setDepthFunction(RenderState::DEPTH_LEQUAL); // Bind the texture to the material as a sampler Texture::Sampler* sampler = Texture::Sampler::create(texture); // +ref texture material->getParameter(samplerUniform->getName())->setValue(sampler); // Define the vertex format for the batch VertexFormat::Element vertexElements[] = { VertexFormat::Element(VertexFormat::POSITION, 3), VertexFormat::Element(VertexFormat::TEXCOORD0, 2), VertexFormat::Element(VertexFormat::COLOR, 4) }; VertexFormat vertexFormat(vertexElements, 3); // Create the mesh batch MeshBatch* meshBatch = MeshBatch::create(vertexFormat, Mesh::TRIANGLE_STRIP, material, true, initialCapacity > 0 ? initialCapacity : SPRITE_BATCH_DEFAULT_SIZE); material->release(); // don't call SAFE_RELEASE since material is used below // Create the batch SpriteBatch* batch = new SpriteBatch(); batch->_sampler = sampler; batch->_customEffect = customEffect; batch->_batch = meshBatch; batch->_textureWidthRatio = 1.0f / (float)texture->getWidth(); batch->_textureHeightRatio = 1.0f / (float)texture->getHeight(); // Bind an ortho projection to the material by default (user can override with setProjectionMatrix) Game* game = Game::getInstance(); Matrix::createOrthographicOffCenter(0, game->getViewport().width, game->getViewport().height, 0, 0, 1, &batch->_projectionMatrix); material->getParameter("u_projectionMatrix")->bindValue(batch, &SpriteBatch::getProjectionMatrix); return batch; }
Material *gamehsp::makeMaterialTex2D( char *fname, int matopt ) { bool mipmap; mipmap = (matopt & GPOBJ_MATOPT_NOMIPMAP ) == 0; Texture* texture = Texture::create(fname); if ( texture == NULL ) { Alertf("Texture not found.(%s)",fname); return NULL; } _tex_width = texture->getWidth(); _tex_height = texture->getHeight(); // Search for the first sampler uniform in the effect. Uniform* samplerUniform = NULL; for (unsigned int i = 0, count = _spriteEffect->getUniformCount(); i < count; ++i) { Uniform* uniform = _spriteEffect->getUniform(i); if (uniform && uniform->getType() == GL_SAMPLER_2D) { samplerUniform = uniform; break; } } if (!samplerUniform) { GP_ERROR("No uniform of type GL_SAMPLER_2D found in sprite effect."); return NULL; } RenderState::StateBlock *state; // Wrap the effect in a material Material* mesh_material = Material::create(_spriteEffect); // +ref effect // Bind the texture to the material as a sampler Texture::Sampler* sampler = Texture::Sampler::create(texture); // +ref texture mesh_material->getParameter(samplerUniform->getName())->setValue(sampler); /* Material* mesh_material = Material::create( SPRITE_VSH, SPRITE_FSH, NULL ); if ( mesh_material == NULL ) { GP_ERROR("2D initalize failed."); return NULL; } mesh_material->getParameter("u_diffuseTexture")->setValue( fname, mipmap ); */ mesh_material->getParameter("u_projectionMatrix")->setValue(_projectionMatrix2D); state = mesh_material->getStateBlock(); state->setCullFace(false); state->setDepthTest(false); state->setDepthWrite(false); state->setBlend(true); state->setBlendSrc(RenderState::BLEND_SRC_ALPHA); state->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA); SAFE_RELEASE( texture ); return mesh_material; }