/************************************************************************* Queues an area of the associated Texture the be drawn on the screen. Low-level routine not normally used! *************************************************************************/ void Imageset::draw(const Rect& source_rect, const Rect& dest_rect, float z, const Rect& clip_rect,const ColourRect& colours, QuadSplitMode quad_split_mode, const Image* image ) const { // get the rect area that we will actually draw to (i.e. perform clipping) Rect final_rect(dest_rect.getIntersection(clip_rect)); // check if rect was totally clipped if (final_rect.getWidth() != 0) { float x_scale = 1.0f / (float)d_texture->getWidth(); float y_scale = 1.0f / (float)d_texture->getHeight(); float tex_per_pix_x = source_rect.getWidth() / dest_rect.getWidth(); float tex_per_pix_y = source_rect.getHeight() / dest_rect.getHeight(); // calculate final, clipped, texture co-ordinates Rect tex_rect((source_rect.d_left + ((final_rect.d_left - dest_rect.d_left) * tex_per_pix_x)) * x_scale, (source_rect.d_top + ((final_rect.d_top - dest_rect.d_top) * tex_per_pix_y)) * y_scale, (source_rect.d_right + ((final_rect.d_right - dest_rect.d_right) * tex_per_pix_x)) * x_scale, (source_rect.d_bottom + ((final_rect.d_bottom - dest_rect.d_bottom) * tex_per_pix_y)) * y_scale); final_rect.d_left = PixelAligned(final_rect.d_left); final_rect.d_right = PixelAligned(final_rect.d_right); final_rect.d_top = PixelAligned(final_rect.d_top); final_rect.d_bottom = PixelAligned(final_rect.d_bottom); // queue a quad to be rendered d_texture->getRenderer()->addQuad(final_rect, z, d_texture, tex_rect, colours, quad_split_mode,image); } }
//----------------------------------------------------------------------------// std::vector<GeometryBuffer*> SVGImage::createRenderGeometry( const ImageRenderSettings& render_settings) const { Rectf dest(render_settings.d_destArea); // apply rendering offset to the destination Rect dest.offset(d_scaledOffset); const CEGUI::Rectf*const& clip_area = render_settings.d_clipArea; // Calculate the actual (clipped) area to which we want to render to Rectf final_rect(clip_area ? dest.getIntersection(*clip_area) : dest ); // check if our Image is totally clipped and return if it is if ((final_rect.getWidth() == 0) || (final_rect.getHeight() == 0)) return std::vector<GeometryBuffer*>(); // Calculate the scale factor for our Image which is the scaling of the Image // area to the destination area of our render call const glm::vec2 scale_factor(dest.getWidth() / d_imageArea.getWidth(), dest.getHeight() / d_imageArea.getHeight()); // URGENT FIXME: Shouldn't this be in the hands of the user? final_rect.d_min.x = CoordConverter::alignToPixels(final_rect.d_min.x); final_rect.d_min.y = CoordConverter::alignToPixels(final_rect.d_min.y); final_rect.d_max.x = CoordConverter::alignToPixels(final_rect.d_max.x); final_rect.d_max.y = CoordConverter::alignToPixels(final_rect.d_max.y); SVGImageRenderSettings svg_render_settings(render_settings, scale_factor, d_useGeometryAntialiasing); std::vector<GeometryBuffer*> geometryBuffers; const std::vector<SVGBasicShape*>& shapes = d_svgData->getShapes(); for(SVGBasicShape* currentShape : shapes) { std::vector<GeometryBuffer*> currentRenderGeometry = currentShape->createRenderGeometry(svg_render_settings); geometryBuffers.insert(geometryBuffers.end(), currentRenderGeometry.begin(), currentRenderGeometry.end()); } return geometryBuffers; }
/************************************************************************* Queue the blink txt to be drawn and create a runtime blink in runtime blink list. *************************************************************************/ void FontManager::addRuntimeBlink(const Image* img, unsigned long& quadID, const Vector3& position, const Size& size, const Rect& clip_rect, const ColourRect& col_rect) { FontBlinkRuntime runtime; runtime.d_texture = img->getImageset()->getTexture(); runtime.d_quadID = quadID; runtime.d_colorRect = col_rect; runtime.d_originalAlpha = col_rect.d_top_left.getAlpha(); Rect source_rect = img->getSourceTextureArea(); Rect dest_rect = Rect(position.d_x, position.d_y, position.d_x + size.d_width, position.d_y + size.d_height); Size sz = img->getSize(); Point pt = img->getOffsets(); // get the rect area that we will actually draw to (i.e. perform clipping) Rect final_rect(dest_rect.getIntersection(clip_rect)); Texture* pTex = img->getImageset()->getTexture(); float x_scale = 1.0f / (float)pTex->getWidth(); float y_scale = 1.0f / (float)pTex->getHeight(); float tex_per_pix_x = source_rect.getWidth() / dest_rect.getWidth(); float tex_per_pix_y = source_rect.getHeight() / dest_rect.getHeight(); // calculate final, clipped, texture co-ordinates Rect tex_rect((source_rect.d_left + ((final_rect.d_left - dest_rect.d_left) * tex_per_pix_x)) * x_scale, (source_rect.d_top + ((final_rect.d_top - dest_rect.d_top) * tex_per_pix_y)) * y_scale, (source_rect.d_right + ((final_rect.d_right - dest_rect.d_right) * tex_per_pix_x)) * x_scale, (source_rect.d_bottom + ((final_rect.d_bottom - dest_rect.d_bottom) * tex_per_pix_y)) * y_scale); runtime.d_textureRect = tex_rect; d_runtimeBlink.push_back(runtime); }
/************************************************************************* render a quad directly to the display *************************************************************************/ void DirectX9Renderer::renderQuadDirect(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode) { // ensure offset destination to ensure proper texel to pixel mapping from D3D. Rect final_rect(dest_rect); final_rect.offset(Point(-0.5f, -0.5f)); QuadVertex* buffmem; initPerFrameStates(); d_device->SetTexture(0, ((DirectX9Texture*)tex)->getD3DTexture()); if (SUCCEEDED(d_buffer->Lock(0, VERTEX_PER_QUAD * sizeof(QuadVertex), (void**)&buffmem, D3DLOCK_DISCARD))) { // setup Vertex 1... buffmem->x = final_rect.d_left; buffmem->y = final_rect.d_top; buffmem->z = z; buffmem->rhw = 1.0f; buffmem->diffuse = colours.d_top_left.getARGB(); buffmem->tu1 = texture_rect.d_left; buffmem->tv1 = texture_rect.d_top; ++buffmem; // setup Vertex 2... // top-left to bottom-right diagonal if (quad_split_mode == TopLeftToBottomRight) { buffmem->x = final_rect.d_right; buffmem->y = final_rect.d_bottom; buffmem->z = z; buffmem->rhw = 1.0f; buffmem->diffuse = colours.d_bottom_right.getARGB(); buffmem->tu1 = texture_rect.d_right; buffmem->tv1 = texture_rect.d_bottom; } // bottom-left to top-right diagonal else { buffmem->x = final_rect.d_right; buffmem->y = final_rect.d_top; buffmem->z = z; buffmem->rhw = 1.0f; buffmem->diffuse = colours.d_top_right.getARGB(); buffmem->tu1 = texture_rect.d_right; buffmem->tv1 = texture_rect.d_top; } ++buffmem; // setup Vertex 3... buffmem->x = final_rect.d_left; buffmem->y = final_rect.d_bottom; buffmem->z = z; buffmem->rhw = 1.0f; buffmem->diffuse = colours.d_bottom_left.getARGB(); buffmem->tu1 = texture_rect.d_left; buffmem->tv1 = texture_rect.d_bottom; ++buffmem; // setup Vertex 4... buffmem->x = final_rect.d_right; buffmem->y = final_rect.d_top; buffmem->z = z; buffmem->rhw = 1.0f; buffmem->diffuse = colours.d_top_right.getARGB(); buffmem->tu1 = texture_rect.d_right; buffmem->tv1 = texture_rect.d_top; ++buffmem; // setup Vertex 5... buffmem->x = final_rect.d_right; buffmem->y = final_rect.d_bottom; buffmem->z = z; buffmem->rhw = 1.0f; buffmem->diffuse = colours.d_bottom_right.getARGB(); buffmem->tu1 = texture_rect.d_right; buffmem->tv1 = texture_rect.d_bottom; ++buffmem; // setup Vertex 6... // top-left to bottom-right diagonal if (quad_split_mode == TopLeftToBottomRight) { buffmem->x = final_rect.d_left; buffmem->y = final_rect.d_top; buffmem->z = z; buffmem->rhw = 1.0f; buffmem->diffuse = colours.d_top_left.getARGB(); buffmem->tu1 = texture_rect.d_left; buffmem->tv1 = texture_rect.d_top; } // bottom-left to top-right diagonal else { buffmem->x = final_rect.d_left; buffmem->y = final_rect.d_bottom; buffmem->z = z; buffmem->rhw = 1.0f; buffmem->diffuse = colours.d_bottom_left.getARGB(); buffmem->tu1 = texture_rect.d_left; buffmem->tv1 = texture_rect.d_bottom; } d_buffer->Unlock(); d_bufferPos = VERTEX_PER_QUAD; renderVBuffer(); } }
/************************************************************************* Queues an area of the associated Texture the be drawn on the screen. Low-level routine not normally used! *************************************************************************/ void Imageset::draw(GeometryBuffer& buffer, const Rect& source_rect, const Rect& dest_rect, const Rect* clip_rect,const ColourRect& colours, QuadSplitMode quad_split_mode) const { // get the rect area that we will actually draw to (i.e. perform clipping) Rect final_rect(clip_rect ? dest_rect.getIntersection(*clip_rect) : dest_rect ); // check if rect was totally clipped if ((final_rect.getWidth() == 0) || (final_rect.getHeight() == 0)) return; // Fix bug #45 // Obtain correct scale values from the texture const float x_scale = d_texture->getTexelScaling().d_x; const float y_scale = d_texture->getTexelScaling().d_y; float tex_per_pix_x = source_rect.getWidth() / dest_rect.getWidth(); float tex_per_pix_y = source_rect.getHeight() / dest_rect.getHeight(); // calculate final, clipped, texture co-ordinates Rect tex_rect((source_rect.d_left + ((final_rect.d_left - dest_rect.d_left) * tex_per_pix_x)) * x_scale, (source_rect.d_top + ((final_rect.d_top - dest_rect.d_top) * tex_per_pix_y)) * y_scale, (source_rect.d_right + ((final_rect.d_right - dest_rect.d_right) * tex_per_pix_x)) * x_scale, (source_rect.d_bottom + ((final_rect.d_bottom - dest_rect.d_bottom) * tex_per_pix_y)) * y_scale); final_rect.d_left = PixelAligned(final_rect.d_left); final_rect.d_right = PixelAligned(final_rect.d_right); final_rect.d_top = PixelAligned(final_rect.d_top); final_rect.d_bottom = PixelAligned(final_rect.d_bottom); Vertex vbuffer[6]; // vertex 0 vbuffer[0].position = Vector3(final_rect.d_left, final_rect.d_top, 0.0f); vbuffer[0].colour_val = colours.d_top_left; vbuffer[0].tex_coords = Vector2(tex_rect.d_left, tex_rect.d_top); // vertex 1 vbuffer[1].position = Vector3(final_rect.d_left, final_rect.d_bottom, 0.0f); vbuffer[1].colour_val = colours.d_bottom_left; vbuffer[1].tex_coords = Vector2(tex_rect.d_left, tex_rect.d_bottom); // vertex 2 vbuffer[2].position.d_x = final_rect.d_right; vbuffer[2].position.d_z = 0.0f; vbuffer[2].colour_val = colours.d_bottom_right; vbuffer[2].tex_coords.d_x = tex_rect.d_right; // top-left to bottom-right diagonal if (quad_split_mode == TopLeftToBottomRight) { vbuffer[2].position.d_y = final_rect.d_bottom; vbuffer[2].tex_coords.d_y = tex_rect.d_bottom; } // bottom-left to top-right diagonal else { vbuffer[2].position.d_y = final_rect.d_top; vbuffer[2].tex_coords.d_y = tex_rect.d_top; } // vertex 3 vbuffer[3].position = Vector3(final_rect.d_right, final_rect.d_top, 0.0f); vbuffer[3].colour_val = colours.d_top_right; vbuffer[3].tex_coords = Vector2(tex_rect.d_right, tex_rect.d_top); // vertex 4 vbuffer[4].position.d_x = final_rect.d_left; vbuffer[4].position.d_z = 0.0f; vbuffer[4].colour_val = colours.d_top_left; vbuffer[4].tex_coords.d_x = tex_rect.d_left; // top-left to bottom-right diagonal if (quad_split_mode == TopLeftToBottomRight) { vbuffer[4].position.d_y = final_rect.d_top; vbuffer[4].tex_coords.d_y = tex_rect.d_top; } // bottom-left to top-right diagonal else { vbuffer[4].position.d_y = final_rect.d_bottom; vbuffer[4].tex_coords.d_y = tex_rect.d_bottom; } // vertex 5 vbuffer[5].position = Vector3(final_rect.d_right, final_rect.d_bottom, 0.0f); vbuffer[5].colour_val= colours.d_bottom_right; vbuffer[5].tex_coords = Vector2(tex_rect.d_right, tex_rect.d_bottom); // TODO: Remove cast when GeometryBuffer gets it's APIs fixed! buffer.setActiveTexture((Texture*)d_texture); buffer.appendGeometry(vbuffer, 6); }
//----------------------------------------------------------------------------// void BasicImage::render(GeometryBuffer& buffer, const Rectf& dest_area, const Rectf* clip_area, const ColourRect& colours) const { const QuadSplitMode quad_split_mode(TopLeftToBottomRight); Rectf dest(dest_area); // apply rendering offset to the destination Rect dest.offset(d_scaledOffset); // get the rect area that we will actually draw to (i.e. perform clipping) Rectf final_rect(clip_area ? dest.getIntersection(*clip_area) : dest ); // check if rect was totally clipped if ((final_rect.getWidth() == 0) || (final_rect.getHeight() == 0)) return; // Obtain correct scale values from the texture const Vector2f& scale = d_texture->getTexelScaling(); const Vector2f tex_per_pix(d_area.getWidth() / dest.getWidth(), d_area.getHeight() / dest.getHeight()); // calculate final, clipped, texture co-ordinates const Rectf tex_rect((d_area.d_min + ((final_rect.d_min - dest.d_min) * tex_per_pix)) * scale, (d_area.d_max + ((final_rect.d_max - dest.d_max) * tex_per_pix)) * scale); // URGENT FIXME: Shouldn't this be in the hands of the user? final_rect.d_min.d_x = CoordConverter::alignToPixels(final_rect.d_min.d_x); final_rect.d_min.d_y = CoordConverter::alignToPixels(final_rect.d_min.d_y); final_rect.d_max.d_x = CoordConverter::alignToPixels(final_rect.d_max.d_x); final_rect.d_max.d_y = CoordConverter::alignToPixels(final_rect.d_max.d_y); Vertex vbuffer[6]; // vertex 0 vbuffer[0].position = Vector3f(final_rect.left(), final_rect.top(), 0.0f); vbuffer[0].colour_val = colours.d_top_left; vbuffer[0].tex_coords = Vector2f(tex_rect.left(), tex_rect.top()); // vertex 1 vbuffer[1].position = Vector3f(final_rect.left(), final_rect.bottom(), 0.0f); vbuffer[1].colour_val = colours.d_bottom_left; vbuffer[1].tex_coords = Vector2f(tex_rect.left(), tex_rect.bottom()); // vertex 2 vbuffer[2].position.d_x = final_rect.right(); vbuffer[2].position.d_z = 0.0f; vbuffer[2].colour_val = colours.d_bottom_right; vbuffer[2].tex_coords.d_x = tex_rect.right(); // top-left to bottom-right diagonal if (quad_split_mode == TopLeftToBottomRight) { vbuffer[2].position.d_y = final_rect.bottom(); vbuffer[2].tex_coords.d_y = tex_rect.bottom(); } // bottom-left to top-right diagonal else { vbuffer[2].position.d_y = final_rect.top(); vbuffer[2].tex_coords.d_y = tex_rect.top(); } // vertex 3 vbuffer[3].position = Vector3f(final_rect.right(), final_rect.top(), 0.0f); vbuffer[3].colour_val = colours.d_top_right; vbuffer[3].tex_coords = Vector2f(tex_rect.right(), tex_rect.top()); // vertex 4 vbuffer[4].position.d_x = final_rect.left(); vbuffer[4].position.d_z = 0.0f; vbuffer[4].colour_val = colours.d_top_left; vbuffer[4].tex_coords.d_x = tex_rect.left(); // top-left to bottom-right diagonal if (quad_split_mode == TopLeftToBottomRight) { vbuffer[4].position.d_y = final_rect.top(); vbuffer[4].tex_coords.d_y = tex_rect.top(); } // bottom-left to top-right diagonal else { vbuffer[4].position.d_y = final_rect.bottom(); vbuffer[4].tex_coords.d_y = tex_rect.bottom(); } // vertex 5 vbuffer[5].position = Vector3f(final_rect.right(), final_rect.bottom(), 0.0f); vbuffer[5].colour_val= colours.d_bottom_right; vbuffer[5].tex_coords = Vector2f(tex_rect.right(), tex_rect.bottom()); buffer.setActiveTexture(d_texture); buffer.appendGeometry(vbuffer, 6); }