private IEnumerable <IdleStatus> createRender(int finalWidth, int finalHeight, int aaMode, bool showWatermark, bool transparentBG, Engine.Color backColor, Camera cloneCamera, Vector3 position, Vector3 lookAt, float minNearDistance, float nearPlaneWorld, float nearFarLength, ImageRendererProperties properties, Action <FreeImageBitmap> renderingCompletedCallback) { FreeImageBitmap bitmap = null; OgreSceneManager sceneManager = controller.CurrentScene.getDefaultSubScene().getSimElementManager <OgreSceneManager>(); if (sceneManager != null) { bool doGridRender; int backBufferWidth; int backBufferHeight; using (TexturePtr texture = createOgreTexture(finalWidth, finalHeight, aaMode, out doGridRender, out backBufferWidth, out backBufferHeight)) { if (texture != null) { using (HardwarePixelBufferSharedPtr pixelBuffer = texture.Value.getBuffer()) { RenderTexture renderTexture = pixelBuffer.Value.getRenderTarget(); Camera camera = sceneManager.SceneManager.createCamera("__PictureCamera"); camera.setLodBias(cloneCamera.getLodBias()); camera.setUseRenderingDistance(cloneCamera.getUseRenderingDistance()); camera.setNearClipDistance(cloneCamera.getNearClipDistance()); camera.setFarClipDistance(cloneCamera.getFarClipDistance()); camera.setPolygonMode(cloneCamera.getPolygonMode()); camera.setRenderingDistance(cloneCamera.getRenderingDistance()); camera.setProjectionType(cloneCamera.getProjectionType()); camera.setFOVy(cloneCamera.getFOVy()); camera.setAutoAspectRatio(false); camera.setAspectRatio((float)finalWidth / finalHeight); SceneNode node = sceneManager.SceneManager.createSceneNode("__PictureCameraNode"); node.attachObject(camera); node.setPosition(position); sceneManager.SceneManager.getRootSceneNode().addChild(node); camera.lookAt(lookAt); Viewport viewport = renderTexture.addViewport(camera, 1, 0.0f, 0.0f, 1.0f, 1.0f); if (properties.UseIncludePoint) { Matrix4x4 viewMatrix = camera.getViewMatrix(); Matrix4x4 projectionMatrix = camera.getProjectionMatrix(); float aspect = camera.getAspectRatio(); float fovy = camera.getFOVy() * 0.5f; float distance = SceneViewWindow.computeOffsetToIncludePoint(viewMatrix, projectionMatrix, properties.IncludePoint, aspect, fovy); Vector3 direction = (position - lookAt).normalized(); node.setPosition(position - (direction * distance)); camera.lookAt(lookAt); } if (transparentBG) { backColor.a = 0.0f; } ViewportBackground bgViewport = null; if (background != null) { bgViewport = new ViewportBackground("ImageRenderer", 0, background, renderTexture, false); bgViewport.BackgroundColor = backColor; bgViewport.Camera.setAutoAspectRatio(false); bgViewport.Camera.setAspectRatio((float)finalWidth / finalHeight); } viewport.setBackgroundColor(backColor); viewport.setOverlaysEnabled(false); viewport.setClearEveryFrame(false); if (properties.CustomizeCameraPosition != null) { properties.CustomizeCameraPosition(camera, viewport); } float near = CameraPositioner.computeNearClipDistance(camera.getDerivedPosition().length(), minNearDistance, nearPlaneWorld); camera.setNearClipDistance(near); camera.setFarClipDistance(near + nearFarLength); if (doGridRender) { IEnumerable <IdleStatus> process = gridRender(finalWidth * aaMode, finalHeight * aaMode, backBufferWidth, backBufferHeight, aaMode, renderTexture, camera, bgViewport != null ? bgViewport.Camera : null, transparentBG, backColor, (product) => { bitmap = product; }); foreach (IdleStatus idleStatus in process) { yield return(idleStatus); } } else { bitmap = simpleRender(backBufferWidth, backBufferHeight, aaMode, transparentBG, backColor, renderTexture); } if (showWatermark && LoadLogo != null) { using (FreeImageBitmap logo = LoadLogo()) { float imageFinalHeight = bitmap.Height * 0.0447f; float scale = imageFinalHeight / logo.Height; float imageFinalWidth = logo.Width * scale; if (imageFinalWidth > bitmap.Width) { imageFinalWidth = bitmap.Width; scale = imageFinalWidth / logo.Width; imageFinalHeight = logo.Height * scale; } logo.Rescale((int)imageFinalWidth, (int)imageFinalHeight, FREE_IMAGE_FILTER.FILTER_BILINEAR); //Have to composite the logo image first. using (FreeImageBitmap fullImageCorner = bitmap.Copy(0, bitmap.Height - (int)imageFinalHeight, (int)imageFinalWidth, bitmap.Height)) { fullImageCorner.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP); logo.Composite(false, null, fullImageCorner); } bitmap.Paste(logo, 0, bitmap.Height - (int)imageFinalHeight, int.MaxValue); } } renderTexture.destroyViewport(viewport); if (bgViewport != null) { bgViewport.Dispose(); } sceneManager.SceneManager.getRootSceneNode().removeChild(node); sceneManager.SceneManager.destroySceneNode(node); sceneManager.SceneManager.destroyCamera(camera); TextureManager.getInstance().remove(texture); } } else { //An error making the render texture. Log it and return the error image. Log.Error("Could not render image. Returning placeholder image. Reason: Could not create valid render to texture target."); bitmap = new FreeImageBitmap(finalWidth, finalHeight); bitmap.FillBackground(new RGBQUAD() { rgbRed = 255 }); } } } renderingCompletedCallback(bitmap); yield break; }