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"); }
int lua_Uniform_getName(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); const char* result = instance->getName(); // Push the return value onto the stack. lua_pushstring(state, result); return 1; } else { lua_pushstring(state, "lua_Uniform_getName - 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; }
bool buildCodeFromUniforms(IContainer* pCont) { std::string code; Uniform *pUniform; code = std::string("//nvFX-Generated\n"); // // Walk through uniform parameters in CstBuffers // ICstBuffer *pCstBuffer; for(int i=0; pCstBuffer = pCont->findCstBuffer(i); i++) { code += "cbuffer "; code += pCstBuffer->getName(); code += " {\n"; for(int i=0; pUniform = static_cast<Uniform*>(pCstBuffer->findUniform(i)); i++) { code += buildCodeForThisUniform(pCont, pUniform); } code += " };\n"; } // // Walk through uniform parameters in GLOBAL space // and add them to a special cbuffer named nvfx_global // NOTE: uniforms that aren't in any cbuffer are put by default to a cbuffer called $Globals // However I decided to not use it here by default to avoid problems when some effects didn't // put all global parameters outside of HLSL source code. // code += "cbuffer nvfx_globals {\n"; for(int i=0; pUniform = static_cast<Uniform*>(pCont->findUniform(i)); i++) { const char * name = pUniform->getName(); // IF the uniform has '.' : we declared a member of a struct. We can't append it to GLSL ! if(strchr(name, '.')) continue; code += buildCodeForThisUniform(pCont, pUniform); } code += "};\n"; // // here is a special case : HLSL can't work without cbuffers // even parameters outside of any cbuffer is in fact in a cbuffer called $Global // We need to copy these uniforms into this $Global cbuffer // On the other hand we kept the HLSL generated code without cbuffer // Container *pContainer = static_cast<Container*>(pCont); if(pContainer->findUniform(0)) // if at least one uniform outside of any cstbuffer { CstBuffer* pGlobalBuffer = static_cast<CstBuffer*>(pContainer->createCstBuffer("nvfx_globals")); pContainer->moveGlobalUniformsToBuffer(pGlobalBuffer); } // // Look for texture resources // resources are potentially created for scene-level management when a render target was needed for intermediate work // WARNING: this will run through ALL resources. Including ones that aren't declared in the current effect // Idea: look for resources; check if texture binding point is there. If not, create it // FOR NOW: NOT NECESSARY... Texture associated with resource can be created from nvFX // //IResourceRepository* pRep = getResourceRepositorySingleton(); //IResource *pRes; //for(int i=0; pRes = pRep->get(i); i++) //{ // const char * name = pRes->getName(); // #pragma MESSAGE("SHALL we check if the texture resource belongs to this effect ???") // // If not, this could allow to easily share rendered textures among effect... // //if(pRes->getContainerCreator() == pCont) // switch(pRes->getType()) // { // case RESTEX_1D : code += "Texture1D "; // code += name; // code += ";\n"; // break; // case RESTEX_2D : code += "Texture2D "; // code += name; // code += ";\n"; // break; // //case RESTEX_3D : code += "Texture3D "; // //case RESTEX_CUBE_MAP : code += "TextureCube "; // } //} // // Look for sampler states // ISamplerState *pSS; for(int i=0; pSS = pCont->findSamplerState(i); i++) { const char * name = pSS->getName(); code += "SamplerState "; code += name; code += ";\n"; // No need to append any state : they will be handled by the runtime } // // Now add this generated code as header to every Shader // Shader *pShader = static_cast<Shader*>(pContainer->createHLSL10Shader(NULL)); return pShader->loadShaderCode(code.c_str());//"#define INFX\n"); }