void WaterRenderer::Draw() { ShaderSet* currentShaderSet = FRAMEWORK->GetOpenGLWrapper()->GetCurrentShaderSet(); if (currentShaderSet->HasHandle(SHADER_VARIABLE_VARIABLENAME_scrolling_uv_offset)) { GLint scrolling_uv_offset_handle = currentShaderSet->GetHandle(SHADER_VARIABLE_VARIABLENAME_scrolling_uv_offset); GLCALL(glUniform1f, scrolling_uv_offset_handle, this->scrollingUVsOffset); } if (this->secondaryTexture) { this->secondaryTexture->Draw(2); } MeshRenderer::Draw(); }
// SDL wants main() to have this exact signature extern "C" int main(int argc, char* argv[]) { // Initialize SDL if (SDL_Init(SDL_INIT_VIDEO)) { fprintf(stderr, "SDL_Init: %s\n", SDL_GetError()); return 1; } // Plain 32-bit RGBA8 pixel format SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); // Don't need built-in depth buffer, we use our own. //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); // Select OpenGL version SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); #ifdef _DEBUG SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); #endif // Create the window SDL_Window* window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL); if (!window) { fprintf(stderr, "SDL_CreateWindow: %s\n", SDL_GetError()); return 1; } // Create the OpenGL context SDL_GLContext context = SDL_GL_CreateContext(window); if (!context) { fprintf(stderr, "SDL_GL_CreateContext: %s\n", SDL_GetError()); return 1; } // Initialize OpenGL (must be called before calling any OpenGL functions) OpenGL_Init(); // DEBUG: print OpenGL version const GLubyte* version = glGetString(GL_VERSION); fprintf(stdout, "OpenGL Version: %s\n", version); //======================== VAO =============================== // Hook up the vertex and index buffers to a "vertex array object" (VAO) // VAOs are the closest thing OpenGL has to a "mesh" object. // VAOs are used to feed data from buffers to thgle inputs of a vertex shader. //============================================================ //===================== VBO/EBO =============================== Skybox skyBox = Skybox(); skyBox.load(); TerrainMesh terrainMesh = TerrainMesh(64, 64, 0.0); terrainMesh.load(); //============================================================ //===================== TEXTURES ============================= //============================================================ //======================= SHADERS ============================ // init terrain shader ShaderSet terrainShaderSet; terrainShaderSet.SetVersion("330"); // set uniforms (use preambles here or define them in the shader file, but NOT both) terrainShaderSet.SetPreamble( "uniform mat4 iModelViewProjection;\n" "uniform mat4 iModel;\n" "uniform mat4 iView;\n" "uniform vec3 iLightPosition_worldspace;\n" "uniform sampler2DArray iTextureArray;\n" ); GLuint* terrainShaderId = terrainShaderSet.AddProgramFromExts({ "a3.vert", "a3.frag" }); // init skybox shader ShaderSet skyboxShaderSet; skyboxShaderSet.SetVersion("330"); // set uniforms (use preambles here or define them in the shader file, but NOT both) skyboxShaderSet.SetPreamble( "uniform mat4 iProjection;\n" "uniform mat4 iView;\n" "uniform samplerCube iSkyBoxCubeTexture;\n" ); GLuint* skyboxShaderId = skyboxShaderSet.AddProgramFromExts({ "skybox.vert", "skybox.frag" }); //============================================================ //======================== LIGHTS ============================ glm::vec3 light = glm::vec3(4, 40, 4); //============================================================ //================== BEZIER CURVES =========================== glm::vec3 xzLength = glm::vec3(32.0, 0.0, 32.0); glm::vec3 yPull = glm::vec3(0.0, 20.0, 0.0); glm::vec3 xPull = glm::vec3(20.0, 0.0, 0.0); CubicBezierCurve bezierCurve1 = CubicBezierCurve(light, xzLength, yPull, yPull); CubicBezierCurve bezierCurve2 = CubicBezierCurve(bezierCurve1.p3, xzLength, -yPull, -yPull); CubicBezierCurve bezierCurve3 = CubicBezierCurve(bezierCurve2.p3, -xzLength, xPull, xPull); CubicBezierCurve bezierCurve4 = CubicBezierCurve(bezierCurve3.p3, -xzLength, -xPull, -xPull); BezierPath bezierPath = BezierPath(std::vector<CubicBezierCurve>{ bezierCurve1, bezierCurve2, bezierCurve3, bezierCurve4 }); //============================================================ // Begin main loop double lastTime = 0; InputHandler inputHandler = InputHandler(window); Camera camera = Camera(4, 40, 4); float bezierTime = 0.0; const float bezierSpeed = 0.001; while (1) { //================= UPDATE USER INPUT ======================== double currentTime = SDL_GetTicks() / 1000.0; float deltaTime = float(currentTime - lastTime); if (inputHandler.updateInput(deltaTime) == -1) { goto quit; } camera.update(inputHandler.getInputData(), deltaTime); lastTime = currentTime; //============================================================ //================= COMPUTE MATRICES ========================= // move camera position along bezier curve glm::vec3 bezPos = bezierPath.getPointAt(bezierTime); bezierTime += bezierSpeed; bezierTime = (bezierTime > 1.0) ? 0.0 : bezierTime; camera.position = bezPos; // Projection matrix glm::mat4 Projection = glm::perspective( camera.FoV, camera.aspectRatio, camera.nearClip, camera.farClip ); // Or, for an ortho camera : //glm::mat4 Projection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,0.0f,100.0f); // In world coordinates // Camera matrix glm::mat4 View = glm::lookAt( camera.position, camera.position + camera.direction, camera.up ); // Model matrix : an identity matrix (model will be at the origin) glm::mat4 Model = glm::mat4(1.0f); // Our ModelViewProjection : multiplication of our 3 matrices glm::mat4 ModelViewProjection = Projection * View * Model; // Remember, matrix multiplication is the other way around //glm::mat4 ModelViewProjection = MVP; //============================================================ //================== UPDATE SHADERS ========================== // Set the color to clear with //glClearColor(100.0f / 255.0f, 149.0f / 255.0f, 237.0f / 255.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //===================== Z-BUFFER ============================= // Enable depth test glEnable(GL_DEPTH_TEST); // Accept fragment if it closer to the camera than the former one glDepthFunc(GL_LESS); // TERRAIN ====================================================== // Recompile/relink any programs that changed (must be called) terrainShaderSet.UpdatePrograms(); // set OpenGL's shader program (must be called in loop) glUseProgram(*terrainShaderId); // get uniform handles GLuint iModelViewProjectionLoc = glGetUniformLocation(*terrainShaderId, "iModelViewProjection"); GLuint iModelLoc = glGetUniformLocation(*terrainShaderId, "iModel"); GLuint iViewLoc = glGetUniformLocation(*terrainShaderId, "iView"); GLuint iLightPosition_worldspaceLoc = glGetUniformLocation(*terrainShaderId, "iLightPosition_worldspace"); // send matrix uniforms to shader if (iModelViewProjectionLoc != -1) { glUniformMatrix4fv(iModelViewProjectionLoc, 1, GL_FALSE, &ModelViewProjection[0][0]); } if (iModelLoc != -1) { glUniformMatrix4fv(iModelLoc, 1, GL_FALSE, &Model[0][0]); } if (iViewLoc != -1) { glUniformMatrix4fv(iViewLoc, 1, GL_FALSE, &View[0][0]); } // pass light position uniform to shader if (iLightPosition_worldspaceLoc != -1) { glUniform3f(iLightPosition_worldspaceLoc, light.x, light.y, light.z); } terrainMesh.generateTextureUniform(terrainShaderId, "iTextureArray"); terrainMesh.attachToVAO(0, 1, 2, 3); terrainMesh.draw(); // SKYBOX ======================================================== // Recompile/relink any programs that changed (must be called) skyboxShaderSet.UpdatePrograms(); // set OpenGL's shader program (must be called in loop) glUseProgram(*skyboxShaderId); // get skybox shader uniform handles GLuint iSkyBoxViewLoc = glGetUniformLocation(*skyboxShaderId, "iView"); GLuint iSkyBoxProjectionLoc = glGetUniformLocation(*skyboxShaderId, "iProjection"); if (iSkyBoxViewLoc != -1) { // remove the translation component of the view matrix // to make sure the skybox's origin is always at the camera glm::mat4 newView = glm::mat4(glm::mat3(View)); glUniformMatrix4fv(iSkyBoxViewLoc, 1, GL_FALSE, &newView[0][0]); } if (iSkyBoxProjectionLoc != -1) { glUniformMatrix4fv(iSkyBoxProjectionLoc, 1, GL_FALSE, &Projection[0][0]); } // generate uniforms for object textures skyBox.generateTextureUniform(skyboxShaderId, "iSkyBoxCubeTexture"); skyBox.attachToVAO(4); skyBox.draw(); // draw wireframe of mesh //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // check for errors GLenum err2; while ((err2 = glGetError()) != GL_NO_ERROR) { std::cerr << "OpenGL error: " << err2 << std::endl; } // disable the depth buffer glDisable(GL_DEPTH_TEST); // SDL docs: "On Mac OS X make sure you bind 0 to the draw framebuffer before swapping the window, otherwise nothing will happen." glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Display the frame of rendering to the window SDL_GL_SwapWindow(window); } quit: SDL_Quit(); return 0; }
int main(int argc, char** argv) { Display d; d.Initialize(800, 600, 24, "Sample 03"); if( d.Show() == false ) { std::cout << "Failed to open window, exiting." << std::endl; return 1; } d.ClearColor( Color::White() ); VertexBuffer<VertexColor> vbo(3); vbo.AddElement( VertexColor( Vector3(0.0f, 0.5f, -2.0f), Color::Red())); vbo.AddElement( VertexColor( Vector3(0.5f, -0.5f, -2.0f), Color::Green())); vbo.AddElement( VertexColor( Vector3(-0.5f, -0.5f, -2.0f), Color::Blue())); vbo.Generate(); //load shaders ShaderSet* ss = new ShaderSet(); Shader* vert = new Shader("../../data/Shader.vert", shader::Vertex); Shader* frag = new Shader("../../data/Shader.frag", shader::Fragment); ss->AddShader(vert); ss->AddShader(frag); ss->Finalize(); GLint uniformId = ss->GetUniformId("translate"); float transY = 0.0f; uint time = Timer::GetCurrentGameTime(); while(d.Listener()->Update()) { d.ClearScreen(); d.SetupPerspective(45.0f, 0.1f, 100.0f); ss->Bind(); // update the shader translation transY += ((float)(Timer::GetCurrentGameTime() - time)) / 200.0f; time = Timer::GetCurrentGameTime(); glUniform1f(uniformId, transY); vbo.Bind(); glDrawArrays(GL_TRIANGLES, 0, 3); vbo.Unbind(); ss->Unbind(); d.SwapBuffers(); } return 0; }
int Init() { ovr_Initialize(); HMD = ovrHmd_Create(0); if (!HMD) { MessageBox(NULL, "Oculus Rift not detected.", "", MB_OK); return 1; } if (HMD->ProductName[0] == '\0') { MessageBox(NULL, "Rift detected, display not enabled.", "", MB_OK); } //Setup Window and Graphics - use window frame if relying on Oculus driver const int backBufferMultisample = 1; bool UseAppWindowFrame = true; HWND window = Util_InitWindowAndGraphics(Recti(HMD->WindowsPos, HMD->Resolution), FullScreen, backBufferMultisample, UseAppWindowFrame, &pRender); if (!window) return 1; ovrHmd_AttachToWindow(HMD, window, NULL, NULL); Sizei recommenedTex0Size = ovrHmd_GetFovTextureSize(HMD, ovrEye_Left, HMD->DefaultEyeFov[0], 1.0f); Sizei recommenedTex1Size = ovrHmd_GetFovTextureSize(HMD, ovrEye_Right, HMD->DefaultEyeFov[1], 1.0f); Sizei RenderTargetSize; RenderTargetSize.w = recommenedTex0Size.w + recommenedTex1Size.w; RenderTargetSize.h = max(recommenedTex0Size.h, recommenedTex1Size.h); RenderTargetSize.w = HMD->Resolution.w; RenderTargetSize.h = HMD->Resolution.h; //const int eyeRenderMultisample = 1; pRendertargetTexture = pRender->CreateRenderTarget(RenderTargetSize.w/2, RenderTargetSize.h/2); //pRendertargetTexture = pRender->CreateRenderTarget(512, 512); RenderTargetSize.w = pRendertargetTexture->Width; RenderTargetSize.h = pRendertargetTexture->Height; IDirect3DSurface9 *zb = 0; pRender->Device->GetDepthStencilSurface(&zb); D3DSURFACE_DESC d; zb->GetDesc(&d); // Initialize eye rendering information. // The viewport sizes are re-computed in case RenderTargetSize due to HW limitations. ovrFovPort eyeFov[2] = { HMD->DefaultEyeFov[0], HMD->DefaultEyeFov[1] }; EyeRenderViewport[0].Pos = Vector2i(0, 0); EyeRenderViewport[0].Size = Sizei(RenderTargetSize.w / 2, RenderTargetSize.h); EyeRenderViewport[1].Pos = Vector2i((RenderTargetSize.w + 1) / 2, 0); EyeRenderViewport[1].Size = EyeRenderViewport[0].Size; // --------------------- DistortionShaders = pRender->CreateShaderSet(); DistortionShaders->SetShader(pRender->LoadBuiltinShader(Shader_Vertex, VShader_Distortion)); DistortionShaders->SetShader(pRender->LoadBuiltinShader(Shader_Pixel, PShader_Distortion)); DistortionDecl = VertexDecl::GetDecl(VertexType_Distortion); for (int eyeNum = 0; eyeNum < 2; ++eyeNum) { ovrDistortionMesh meshData; ovrHmd_CreateDistortionMesh(HMD, (ovrEyeType)eyeNum, eyeFov[eyeNum], ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp, &meshData); MeshVBs[eyeNum] = pRender->CreateVertexBuffer(); MeshVBs[eyeNum]->Data(meshData.pVertexData, sizeof(ovrDistortionVertex)*meshData.VertexCount); MeshIBs[eyeNum] = pRender->CreateIndexBuffer(); MeshIBs[eyeNum]->Data(meshData.pIndexData, sizeof(unsigned short)*meshData.IndexCount); MeshVBCnts[eyeNum] = meshData.VertexCount; MeshIBCnts[eyeNum] = meshData.IndexCount; ovrHmd_DestroyDistortionMesh(&meshData); EyeRenderDesc[eyeNum] = ovrHmd_GetRenderDesc(HMD, (ovrEyeType)eyeNum, eyeFov[eyeNum]); ovrHmd_GetRenderScaleAndOffset(eyeFov[eyeNum], RenderTargetSize, EyeRenderViewport[eyeNum], UVScaleOffset[eyeNum]); } ovrHmd_SetEnabledCaps(HMD, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction); ovrHmd_ConfigureTracking(HMD, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, 0); // --------------------- pRoomScene = new Scene; PopulateRoomScene(pRoomScene, pRender); // texture model ShaderSet* ss = pRender->CreateShaderSet(); ss->SetShader(pRender->LoadBuiltinShader(Shader_Vertex, VShader_MVP_UV)); ss->SetShader(pRender->LoadBuiltinShader(Shader_Pixel, PShader_UV)); Model<VertexXYZUV> *pModel2 = new Model<VertexXYZUV>(); pModel2->Decl = VertexDecl::GetDecl(VertexType_XYZUV); pModel2->Fill = new ShaderFill(ss); //Texture* ttt = new Texture(pRender); //ttt->LoadFromFile("face.tga"); pModel2->Fill->SetTexture(0, pRendertargetTexture); pModel2->AddVertex(VertexXYZUV(0.5f, -1.0f, 0.0f, 0.0f, 0.0f)); pModel2->AddVertex(VertexXYZUV(2.5f, -1.0f, 0.0f, 1.0f, 0.0f)); pModel2->AddVertex(VertexXYZUV(0.5f, 1.0f, 0.0f, 0.0f, 1.0f)); pModel2->AddVertex(VertexXYZUV(2.5f, 1.0f, 0.0f, 1.0f, 1.0f)); pModel2->AddVertex(VertexXYZUV(-1.0f, -1.5f, -1.0f, 0.0f, 0.0f)); pModel2->AddVertex(VertexXYZUV(1.0f, -1.5f, -1.0f, 1.0f, 0.0f)); pModel2->AddVertex(VertexXYZUV(-1.0f, -1.5f, 1.0f, 0.0f, 1.0f)); pModel2->AddVertex(VertexXYZUV(1.0f, -1.5f, 1.0f, 1.0f, 1.0f)); pModel2->AddTriangle(0, 1, 2); pModel2->AddTriangle(2, 1, 3); pModel2->AddTriangle(4, 5, 6); pModel2->AddTriangle(6, 5, 7); pScene = new Scene; pScene->World.Add(pModel2); return (0); }
void MaterialInstance::createForConfiguration (const std::string& configuration) { bool res = mMaterial->createConfiguration(configuration); if (!res) return; // listener was false positive if (mListener) mListener->requestedConfiguration (this, configuration); mFactory->setActiveConfiguration (configuration); bool allowFixedFunction = true; if (!mShadersEnabled && hasProperty("allow_fixed_function")) { allowFixedFunction = retrieveValue<BooleanValue>(getProperty("allow_fixed_function"), NULL).get(); } // get passes of the top-most parent PassVector passes = getPasses(); for (PassVector::iterator it = passes.begin(); it != passes.end(); ++it) { boost::shared_ptr<Pass> pass = mMaterial->createPass (configuration); it->copyAll (pass.get(), this); // texture samplers used in the shaders std::vector<std::string> usedTextureSamplersVertex; std::vector<std::string> usedTextureSamplersFragment; PropertySetGet* context = this; // create or retrieve shaders if (mShadersEnabled || !allowFixedFunction) { it->setContext(context); it->mShaderProperties.setContext(context); if (it->hasProperty("vertex_program")) { ShaderSet* vertex = mFactory->getShaderSet(retrieveValue<StringValue>(it->getProperty("vertex_program"), context).get()); ShaderInstance* v = vertex->getInstance(&it->mShaderProperties); if (v) { pass->assignProgram (GPT_Vertex, v->getName()); v->setUniformParameters (pass, &it->mShaderProperties); std::vector<std::string> sharedParams = v->getSharedParameters (); for (std::vector<std::string>::iterator it = sharedParams.begin(); it != sharedParams.end(); ++it) { pass->addSharedParameter (GPT_Vertex, *it); } std::vector<std::string> vector = v->getUsedSamplers (); usedTextureSamplersVertex.insert(usedTextureSamplersVertex.end(), vector.begin(), vector.end()); } } if (it->hasProperty("fragment_program")) { ShaderSet* fragment = mFactory->getShaderSet(retrieveValue<StringValue>(it->getProperty("fragment_program"), context).get()); ShaderInstance* f = fragment->getInstance(&it->mShaderProperties); if (f) { pass->assignProgram (GPT_Fragment, f->getName()); f->setUniformParameters (pass, &it->mShaderProperties); std::vector<std::string> sharedParams = f->getSharedParameters (); for (std::vector<std::string>::iterator it = sharedParams.begin(); it != sharedParams.end(); ++it) { pass->addSharedParameter (GPT_Fragment, *it); } std::vector<std::string> vector = f->getUsedSamplers (); usedTextureSamplersFragment.insert(usedTextureSamplersFragment.end(), vector.begin(), vector.end()); } } } // create texture units std::vector<MaterialInstanceTextureUnit> texUnits = it->getTexUnits(); int i=0; for (std::vector<MaterialInstanceTextureUnit>::iterator texIt = texUnits.begin(); texIt != texUnits.end(); ++texIt ) { // only create those that are needed by the shader, OR those marked to be created in fixed function pipeline if shaders are disabled bool foundVertex = std::find(usedTextureSamplersVertex.begin(), usedTextureSamplersVertex.end(), texIt->getName()) != usedTextureSamplersVertex.end(); bool foundFragment = std::find(usedTextureSamplersFragment.begin(), usedTextureSamplersFragment.end(), texIt->getName()) != usedTextureSamplersFragment.end(); if ( (foundVertex || foundFragment) || ((!mShadersEnabled && allowFixedFunction) && texIt->hasProperty("create_in_ffp") && retrieveValue<BooleanValue>(texIt->getProperty("create_in_ffp"), this).get())) { boost::shared_ptr<TextureUnitState> texUnit = pass->createTextureUnitState (); texIt->copyAll (texUnit.get(), context); mTexUnits.push_back(texUnit); // set texture unit indices (required by GLSL) if (mShadersEnabled && mFactory->getCurrentLanguage () == Language_GLSL) { pass->setTextureUnitIndex (foundVertex ? GPT_Vertex : GPT_Fragment, texIt->getName(), i); ++i; } } } } }
bool MaterialInstance::createForConfiguration (const std::string& configuration, unsigned short lodIndex) { if (mFailedToCreate) return false; try{ mMaterial->ensureLoaded(); bool res = mMaterial->createConfiguration(configuration, lodIndex); if (!res) return false; // listener was false positive if (mListener) mListener->requestedConfiguration (this, configuration); mFactory->setActiveConfiguration (configuration); mFactory->setActiveLodLevel (lodIndex); bool allowFixedFunction = true; if (!mShadersEnabled && hasProperty("allow_fixed_function")) { allowFixedFunction = retrieveValue<BooleanValue>(getProperty("allow_fixed_function"), NULL).get(); } bool useShaders = mShadersEnabled || !allowFixedFunction; // get passes of the top-most parent PassVector* passes = getParentPasses(); if (passes->empty()) throw std::runtime_error ("material \"" + mName + "\" does not have any passes"); for (PassVector::iterator it = passes->begin(); it != passes->end(); ++it) { boost::shared_ptr<Pass> pass = mMaterial->createPass (configuration, lodIndex); it->copyAll (pass.get(), this); // texture samplers used in the shaders std::vector<std::string> usedTextureSamplersVertex; std::vector<std::string> usedTextureSamplersFragment; PropertySetGet* context = this; // create or retrieve shaders bool hasVertex = it->hasProperty("vertex_program") && !retrieveValue<StringValue>(it->getProperty("vertex_program"), context).get().empty(); bool hasFragment = it->hasProperty("fragment_program") && !retrieveValue<StringValue>(it->getProperty("fragment_program"), context).get().empty(); if (useShaders) { it->setContext(context); it->mShaderProperties.setContext(context); if (hasVertex) { ShaderSet* vertex = mFactory->getShaderSet(retrieveValue<StringValue>(it->getProperty("vertex_program"), context).get()); ShaderInstance* v = vertex->getInstance(&it->mShaderProperties); if (v) { pass->assignProgram (GPT_Vertex, v->getName()); v->setUniformParameters (pass, &it->mShaderProperties); std::vector<std::string> sharedParams = v->getSharedParameters (); for (std::vector<std::string>::iterator it2 = sharedParams.begin(); it2 != sharedParams.end(); ++it2) { pass->addSharedParameter (GPT_Vertex, *it2); } std::vector<std::string> vector = v->getUsedSamplers (); usedTextureSamplersVertex.insert(usedTextureSamplersVertex.end(), vector.begin(), vector.end()); } } if (hasFragment) { ShaderSet* fragment = mFactory->getShaderSet(retrieveValue<StringValue>(it->getProperty("fragment_program"), context).get()); ShaderInstance* f = fragment->getInstance(&it->mShaderProperties); if (f) { pass->assignProgram (GPT_Fragment, f->getName()); f->setUniformParameters (pass, &it->mShaderProperties); std::vector<std::string> sharedParams = f->getSharedParameters (); for (std::vector<std::string>::iterator it2 = sharedParams.begin(); it2 != sharedParams.end(); ++it2) { pass->addSharedParameter (GPT_Fragment, *it2); } std::vector<std::string> vector = f->getUsedSamplers (); usedTextureSamplersFragment.insert(usedTextureSamplersFragment.end(), vector.begin(), vector.end()); } } } // create texture units std::vector<MaterialInstanceTextureUnit>* texUnits = &it->mTexUnits; int i=0; for (std::vector<MaterialInstanceTextureUnit>::iterator texIt = texUnits->begin(); texIt != texUnits->end(); ++texIt ) { // only create those that are needed by the shader, OR those marked to be created in fixed function pipeline if shaders are disabled bool foundVertex = std::find(usedTextureSamplersVertex.begin(), usedTextureSamplersVertex.end(), texIt->getName()) != usedTextureSamplersVertex.end(); bool foundFragment = std::find(usedTextureSamplersFragment.begin(), usedTextureSamplersFragment.end(), texIt->getName()) != usedTextureSamplersFragment.end(); if ( (foundVertex || foundFragment) || (((!useShaders || (!hasVertex || !hasFragment)) && allowFixedFunction) && texIt->hasProperty("create_in_ffp") && retrieveValue<BooleanValue>(texIt->getProperty("create_in_ffp"), this).get())) { boost::shared_ptr<TextureUnitState> texUnit = pass->createTextureUnitState (texIt->getName()); texIt->copyAll (texUnit.get(), context); mTexUnits.push_back(texUnit); // set texture unit indices (required by GLSL) if (useShaders && ((hasVertex && foundVertex) || (hasFragment && foundFragment)) && mFactory->getCurrentLanguage () == Language_GLSL) { pass->setTextureUnitIndex (foundVertex ? GPT_Vertex : GPT_Fragment, texIt->getName(), i); ++i; } } } } if (mListener) mListener->createdConfiguration (this, configuration); return true; } catch (std::runtime_error& e) { destroyAll(); mFailedToCreate = true; std::stringstream msg; msg << "Error while creating material " << mName << ": " << e.what(); std::cerr << msg.str() << std::endl; mFactory->logError(msg.str()); return false; } }