void load( IECore::Object::LoadContextPtr context ) { unsigned int v = g_ioVersion; ConstIndexedIOPtr container = context->container( staticTypeName(), v ); ConstIndexedIOPtr shaders = container->subdirectory( "shaders" ); IndexedIO::EntryIDList handles; shaders->entryIds( handles, IndexedIO::Directory ); for( const auto &handle : handles ) { ShaderPtr shader = context->load<Shader>( shaders.get(), handle ); setShader( handle, shader.get() ); } ConstIndexedIOPtr connections = container->subdirectory( "connections" ); IndexedIO::EntryIDList connectionIndices; for( const auto &connectionIndex : connectionIndices ) { InternedString c[4]; InternedString *cp = c; connections->read( connectionIndex, cp, 4 ); addConnection( Connection( Parameter( cp[0], cp[1] ), Parameter( cp[2], cp[3] ) ) ); } InternedString o[2]; InternedString *op = o; container->read( "output", op, 2 ); m_output = Parameter( op[0], op[1] ); }
bool GLProgram::removeShader(ShaderPtr shader) { if (!m_shaders.contains(shader)) return false; disconnect(shader.get(), SIGNAL(changed(ShaderPtr)), this, SIGNAL(shaderChanged(ShaderPtr))); m_shaders.remove(shader); if (m_prog) glRun(glDetachShader(m_prog, shader->id())); shader->setProgram(ProgramPtr()); m_compiled = false; m_relink = true; emit changed(); return true; }
void GLProgram::addShader(ShaderPtr shader) { if (!shader->program()) shader->setProgram(shared_from_this()); assert(shader->program() == shared_from_this()); assert(!m_shaders.contains(shader)); m_shaders << shader; connect(shader.get(), SIGNAL(changed(ShaderPtr)), this, SIGNAL(shaderChanged(ShaderPtr))); emit changed(); }
void DemoSceneManager::drawModel2(const std::string &name, GLenum mode) { Model::GroupMap &groups = getModel(name)->getGroups(); for (auto i = groups.begin(); i != groups.end(); ++i) { Geometry &geometry = i->second; MaterialPtr material = geometry.getMaterial(); ShaderPtr shader = material->getShader(); if (shader.get()) { vmml::frustum<float> _projectionMatrix(-1.0f,1.0f,-1.0f,1.0f,0.2f,100.0f); // vmml::frustum<float> _projectionMatrix(vmml::frustum<float>::DEFAULT); _projectionMatrix.set_perspective(0.0f, _projectionMatrix.get_width()/_projectionMatrix.get_height(), _projectionMatrix.near_plane(), _projectionMatrix.far_plane()); std::cout << _projectionMatrix.compute_matrix(); // shader->setUniform("ProjectionMatrix", vmml::mat4f::IDENTITY); shader->setUniform("ProjectionMatrix", _projectionMatrix.compute_matrix()); shader->setUniform("ViewMatrix", _viewMatrix); shader->setUniform("ModelMatrix", _modelMatrix); vmml::mat3f normalMatrix; vmml::compute_inverse(vmml::transpose(vmml::mat3f(_modelMatrix)), normalMatrix); shader->setUniform("NormalMatrix", normalMatrix); shader->setUniform("EyePos", _eyePos); shader->setUniform("LightPos", vmml::vec4f(0.0f, 1.f, .5f, 1.f)); shader->setUniform("Ia", vmml::vec3f(1.f)); shader->setUniform("Id", vmml::vec3f(1.f)); shader->setUniform("Is", vmml::vec3f(1.f)); } else { util::log("No shader available.", util::LM_WARNING); } geometry.draw(mode); } }
Scene::Scene(string XmlSrc, ShaderPtr& sPtr, Camera& cam){ XMLDocument doc; doc.LoadFile(XmlSrc.c_str()); // Get the root (Scene) element XMLElement * elScene = doc.FirstChildElement("Scene"); if (!elScene){ cout << "XML Root not found. " << endl; exit(5); } // Get and verify that important things are there XMLElement * elCam = check("Camera", elScene); XMLElement * elShade = check("Shader", elScene); XMLElement * elGeom = check("Geom", elScene); XMLElement * elLight = check("Light", elScene); // First create host assets // Init Camera Camera::Type camType = getCamera(*elCam, cam); if (camType == Camera::Type::NIL){ cout << "Error creating Camera" << endl; exit(7); } // Init Geometry for (XMLElement * el = elGeom->FirstChildElement(); el; el = el->NextSiblingElement()) m_vGeometry.push_back(getGeom(el)); // Set up the lights, arbitrarily assigning pre-existing geometry as its representation for (auto el = elLight->FirstChildElement(); el; el = el->NextSiblingElement()) m_vLights.push_back(getLight(el)); // Init shader // The material count == #geom + # of point lights int nMaterials = m_vGeometry.size() + std::count_if( m_vLights.begin(), m_vLights.end(), [](const Light& l){ return l.getType() == Light::Type::POINT; }); IqmTypeMap iqmTypes = getShader(elShade, sPtr, nMaterials, m_vLights.size()); // Sort so overlapping geometry is adjacent std::sort(m_vGeometry.begin(), m_vGeometry.end()); // Create all GPU assets, starting by binding the shader auto sBind = sPtr->ScopeBind(); // Create Geometry for (auto it = m_vGeometry.begin(); it != m_vGeometry.end();){ // For the first instance, create the assets createGPUAssets(iqmTypes, *it); // For all remaining instances, just copy VAO and nIdx int count = std::count(m_vGeometry.begin(), m_vGeometry.end(), *it); auto cloneIt = it; for (int i = 1; i < count; i++){ (it + i)->setNumIndices(it->getNumIdx()); (it + i)->setVAO(it->getVAO()); } it += count; } // Set up material shader access Shader * s = sPtr.get(); auto fixMaterial = [s](Geometry& G, int i){ string m = "MatArr[i]."; m[m.length() - 3] = '0' + i; Material M = G.getMaterial(); // Material handles aren't static M.SetReflectHandle(s->getHandle(m + "Reflectivity")); M.setShinyHandle(s->getHandle(m + "Shininess")); M.setDiffHandle(s->getHandle(m + "Diffuse")); M.setSpecHandle(s->getHandle(m + "Specular")); createGPUAssets(M); G.setMaterial(M); }; // Upload all geometry materials for (int i = 0; i < m_vGeometry.size(); i++) fixMaterial(m_vGeometry[i], i); // Create lights for (int i = 0; i < m_vLights.size(); i++){ // Upload to shader (Must be accessed like "TheLights[i].Type, GL3) string s = "LightArr[i]."; s[s.length() - 3] = '0' + i; // Store handles per light, since they could move m_vLights[i].SetTypeHandle(sPtr->getHandle(s + "Type")); m_vLights[i].SetPosOrHalfHandle(sPtr->getHandle(s + "PosOrHalf")); m_vLights[i].SetDirOrAttenHandle(sPtr->getHandle(s + "DirOrAtten")); m_vLights[i].SetIntensityHandle(sPtr->getHandle(s + "Intensity")); // Put light data on GPU createGPUAssets(m_vLights[i]); // Give point lights some geometry if (m_vLights[i].getType() == Light::Type::POINT){ Geometry lightGeom = m_vGeometry[0]; lightGeom.identity(); // Maybe scale it somehow? mat4 light_T = glm::translate(m_vLights[i].getPos()); lightGeom.leftMultM(light_T); Material lightMat(10.f, 0.f, vec4(glm::linearRand(vec3(0), vec3(1)), 0.5f), vec4(1)); lightGeom.setMaterial(lightMat); fixMaterial(lightGeom, i + m_vGeometry.size() ); m_vLights[i].SetGeometry(lightGeom); } //// Set up point light materials //if (m_vLights[i].getType() == Light::Type::POINT){ // Geometry g = m_vLights[i].GetGeometry(); // I wish we didn't have to go back and forth like this // fixMaterial(g, i + m_vGeometry.size() - 1); // but returning a reference seems like overkill // m_vLights[i].SetGeometry(g); //} } setupMiscUniforms(sPtr); Scene::s_EnvMapHandle = sPtr->getHandle("u_EnvMap"); //// Find a better place for this, do XML std::string cubeFaces[6] = { "posX.png", "negX.png", "posY.png", "negY.png", "posZ.png", "negZ.png" }; m_EnvMap = Textures::CubeMap(cubeFaces); }
/*! * @brief Draws everything that is in the entities list with a sprite component * @param Entity the entity that is going to be drawn * @param camera the camera used to draw the objects to */ void GLGraphics::DrawEntity(const EntityPtr &Entity, const CameraPtr &camera) { ShaderPtr shader = _shaders.find(Entity->GET_COMPONENT(Sprite)->_shaderName)->second; TransformPtr transform = Entity->GET_COMPONENT(Transform); if (shader.get() != nullptr) { //constructing the matrix of the transform glm::mat4x4 object2world; object2world = glm::translate(object2world, glm::vec3( Entity->GET_COMPONENT(Transform)->position.x, Entity->GET_COMPONENT(Transform)->position.y, 0.0f ) ); object2world = glm::rotate( object2world, transform->rotation * 3.141592f / 180.f, // degrees to radians conversion glm::vec3(0.f, 0.f, 1.0f) ); object2world = glm::scale(object2world, glm::vec3(transform->scale.x, transform->scale.y, 0.f) ); //Updating the uniforms in the shader, has to happen every frame shader->UpdateUniforms("model", object2world); shader->UpdateUniforms("view", camera->_viewMatrix); //Switching the camera's projection matrix based on the flag switch (camera->viewtype) { case Camera::CV_ORTHOGRAPHIC: shader->UpdateUniforms("proj", camera->_ortho); break; case Camera::CV_PERSPECTIVE: shader->UpdateUniforms("proj", camera->_pespective); break; } shader->UpdateUniforms("color", Entity->GET_COMPONENT(Sprite)->_color); shader->Use(); switch (Entity->GET_COMPONENT(Sprite)->mesh) { case Sprite::QUAD: glBindVertexArray(_quadInfo.vao); glDrawElements( GL_TRIANGLE_STRIP, //Draw Type 6, //Number of points GL_UNSIGNED_SHORT, //Data that it is when being read nullptr); break; case Sprite::CIRCLE: glBindVertexArray(_circleInfo.vao); glDrawElements(GL_TRIANGLE_FAN, 30000, GL_UNSIGNED_SHORT, nullptr); break; default: glBindVertexArray(_quadInfo.vao); glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_SHORT, nullptr); break; } } }
ShaderPtr ShaderLibrary::CreateShader (const ShaderDesc& desc, const LogFunction& error_log) { try { //проверка корректности аргументов if (!desc.name) throw xtl::make_null_argument_exception ("", "desc.name"); if (!desc.source_code) throw xtl::make_null_argument_exception ("", "desc.source_code"); if (!desc.source_code_size) throw xtl::make_null_argument_exception ("", "desc.source_code_size"); if (!desc.profile) throw xtl::make_null_argument_exception ("", "desc.profile"); const char* options = desc.options ? desc.options : ""; ShaderType type = (ShaderType)-1; struct Profile2ShaderType { const char* profile; ShaderType type; const char* dx_profile; }; static const Profile2ShaderType type_map [] = { {"hlsl.vs", ShaderType_Vertex, "vs_4_0"}, {"hlsl.ps", ShaderType_Pixel, "ps_4_0"}, {"hlsl.gs", ShaderType_Geometry, "gs_4_0"}, {"hlsl.hs", ShaderType_Hull, "hs_4_0"}, {"hlsl.ds", ShaderType_Domain, "ds_4_0"}, {"hlsl.cs", ShaderType_Compute, "cs_4_0"}, }; static const size_t type_map_size = sizeof (type_map) / sizeof (*type_map); const char* dx_profile = ""; for (size_t i=0; i<type_map_size; i++) if (!strcmp (type_map [i].profile, desc.profile)) { type = type_map [i].type; dx_profile = type_map [i].dx_profile; break; } if (type == (ShaderType)-1) throw xtl::make_argument_exception ("", "desc.profile", desc.profile, "Unknown shader profile"); //формирование хэша для поиска в библиотеке size_t source_code_size = desc.source_code_size == (size_t)-1 ? strlen (desc.source_code) : desc.source_code_size, hash = common::crc32 (desc.source_code, source_code_size, common::strhash (options)); //поиск уже существующего шейдера ShaderMap::iterator iter = shaders.find (hash); if (iter != shaders.end ()) return iter->second; //создание нового шейдера ShaderCodePtr code (new ShaderCode (GetDeviceManager (), desc.name, dx_profile, desc.source_code, source_code_size, options, error_log), false); ShaderPtr shader (new Shader (type, code, *this), false); //регистрация шейдера в библиотеке shader->RegisterDestroyHandler (xtl::bind (&ShaderLibrary::RemoveShaderByHash, this, hash), GetTrackable ()); shaders.insert_pair (hash, shader.get ()); return shader; } catch (xtl::exception& e) { e.touch ("render::low_level::dx11::ShaderLibrary::CreateShader"); throw; } }