note
	description: "An object which does all the image rendering on a GAME_WINDOW"
	author: "Louis Marchand"
	date: "Thu, 02 Apr 2015 02:40:10 +0000"
	revision: "2.0"

class interface
	GAME_RENDERER

create {GAME_WINDOW_RENDERED}
	make (a_window: GAME_WINDOW_RENDERED)
			-- Initialization for Current targeting a_window and
			-- using the first {RENDERER_DRIVER} found
		ensure
			is_created: has_error or exists

	make_with_flags (a_window: GAME_WINDOW_RENDERED; a_must_support_target_texture, a_must_sync_update, a_must_be_software_rendering, a_must_be_hardware_accelerated: BOOLEAN)
			-- Initialization for Current. If a_must_support_target_texture is True,
			-- the rendering context must permit to target to a texture instead of Current.
			-- If a_must_sync_update is True, the present will wait for vsync before finishing.
			-- If a_must_be_software_rendering is True, the renderer will always
		ensure
			is_created: has_error or exists

	make_with_renderer_driver (a_window: GAME_WINDOW_RENDERED; a_renderer_driver: GAME_RENDERER_DRIVER)
			-- Initialization for Current targeting a_window using a specific a_renderer_driver
		ensure
			is_created: has_error or exists

feature -- Access

	clear
			-- Fill the target with
			-- the drawing_color
		require
			renderer_exists: exists

	clip_rectangle: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
			-- Indicate what rectangle must be drawed when a draw is
			-- use. Every drawing outside of the rectangle will be
			-- ignored
		require
			renderer_exists: exists

	disable_blending
			-- Disable every blending mode to use for drawing operations.
			-- No blending mode:	dstRGBA = srcRGBA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists

	disable_clip_rectangle
			-- Remove every clip rectangle from Current
		require
			renderer_exists: exists

	draw_connected_lines (a_points: CHAIN [TUPLE [x: INTEGER_32; y: INTEGER_32]])
			-- Draw connected lines using all (x, y) in a_points
		require
			renderer_exists: exists

	draw_filled_rectangle (a_x, a_y, a_width, a_height: INTEGER_32)
			-- Drawing a filled rectangle of dimension
			-- a_widthxa_height that has it's left frontier at
			-- a_x, it's top frontier at a_y.
		require
			renderer_exists: exists

	draw_filled_rectangles (a_rectangles: CHAIN [TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]])
			-- Drawing every wire rectangle in a_rectangles
			-- that has it's left frontier at
			-- x, it's top frontier at y, with
			-- dimension widthxheight
		require
			renderer_exists: exists

	draw_line (a_x1, a_y1, a_x2, a_y2: INTEGER_32)
			-- Draw a line from (a_x1, a_y1) to (a_x2, a_y2)
		require
			renderer_exists: exists

	draw_point (a_x, a_y: INTEGER_32)
			-- Draw a point at (a_x, a_y)
		require
			renderer_exists: exists

	draw_points (a_points: CHAIN [TUPLE [x: INTEGER_32; y: INTEGER_32]])
			-- Draw points using all (x, y) in a_points
		require
			renderer_exists: exists

	draw_rectangle (a_x, a_y, a_width, a_height: INTEGER_32)
			-- Drawing a wire rectangle of dimension
			-- a_widthxa_height that has it's left frontier at
			-- a_x, it's top frontier at a_y.
		require
			renderer_exists: exists

	draw_rectangles (a_rectangles: CHAIN [TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]])
			-- Drawing every wire rectangle in a_rectangles
			-- that has it's left frontier at
			-- x, it's top frontier at y, with
			-- dimension widthxheight
		require
			renderer_exists: exists

	draw_sub_texture (a_texture: GAME_TEXTURE; a_x_source, a_y_source, a_width, a_height, a_x_destination, a_y_destination: INTEGER_32)
			-- Draw the part of a_texture from (a_x_source,a_y_source)
			-- of size a_widthxa_height on Current at (a_x_destination,a_y_destination)
		require
			renderer_exists: exists

	draw_sub_texture_with_mirror (a_texture: GAME_TEXTURE; a_x_source, a_y_source, a_width_source, a_height_source, a_x_destination, a_y_destination: INTEGER_32; a_vertical_mirror, a_horizontal_mirror: BOOLEAN)
			-- Draw the part of a_texture from (a_x_source,a_y_source)
			-- of size a_width_sourcexa_height_source on the part of Current
			-- at (a_x_destination,a_y_destination) of size
			-- a_width_destinationxa_height_destination.
			-- Also, use a vertical mirror on the drawed image if a_vertical_mirror
			-- is True and an horizontal one if a_horizontal_mirror is True.
		require
			renderer_exists: exists

	draw_sub_texture_with_rotation (a_texture: GAME_TEXTURE; a_x_source, a_y_source, a_width_source, a_height_source, a_x_destination, a_y_destination, a_x_rotation_center, a_y_rotation_center: INTEGER_32; a_rotation_angle: REAL_64)
			-- Draw the part of a_texture from (a_x_source,a_y_source)
			-- of size a_width_sourcexa_height_source on the part of Current
			-- at (a_x_destination,a_y_destination) of size
			-- a_width_destinationxa_height_destination.
			-- Also, rotate the draw of a_rotation_angle degree using the rotation center
			-- (a_x_rotation_center,a_y_rotation_center)
		require
			renderer_exists: exists

	draw_sub_texture_with_scale (a_texture: GAME_TEXTURE; a_x_source, a_y_source, a_width_source, a_height_source, a_x_destination, a_y_destination, a_width_destination, a_height_destination: INTEGER_32)
			-- Draw the part of a_texture from (a_x_source,a_y_source)
			-- of size a_width_sourcexa_height_source on the part of Current
			-- at (a_x_destination,a_y_destination) of size
			-- a_width_destinationxa_height_destination
		require
			renderer_exists: exists

	draw_sub_texture_with_scale_rotation_and_mirror (a_texture: GAME_TEXTURE; a_x_source, a_y_source, a_width_source, a_height_source, a_x_destination, a_y_destination, a_width_destination, a_height_destination, a_x_rotation_center, a_y_rotation_center: INTEGER_32; a_rotation_angle: REAL_64; a_vertical_mirror, a_horizontal_mirror: BOOLEAN)
			-- Draw the part of a_texture from (a_x_source,a_y_source)
			-- of size a_width_sourcexa_height_source on the part of Current
			-- at (a_x_destination,a_y_destination) of size
			-- a_width_destinationxa_height_destination.
			-- Also, rotate the draw of a_rotation_angle degree using the rotation center
			-- (a_x_rotation_center,a_y_rotation_center). Finally, use a vertical mirror on
			-- the drawed image if a_vertical_mirror is True and an horizontal one if
			-- a_horizontal_mirror is True.
		require
			renderer_exists: exists

	draw_texture (a_texture: GAME_TEXTURE; a_x, a_y: INTEGER_32)
			-- Draw the whole a_texture on Current at (a_x,a_y)
		require
			renderer_exists: exists

	draw_texture_with_mirror (a_texture: GAME_TEXTURE; a_x, a_y: INTEGER_32; a_vertical_mirror, a_horizontal_mirror: BOOLEAN)
			-- Draw the whole a_texture on Current at (a_x,a_y)
			-- Also, use a vertical mirror on the drawed image if a_vertical_mirror
			-- is True and an horizontal one if a_horizontal_mirror is True.
		require
			renderer_exists: exists

	draw_texture_with_rotation (a_texture: GAME_TEXTURE; a_x, a_y: INTEGER_32; a_x_rotation_center, a_y_rotation_center: INTEGER_32; a_rotation_angle: REAL_64)
			-- Draw the whole a_texture on Current at (a_x,a_y) rotate
			-- of a_rotation_angle degree with the rotation center at
			-- (a_x_rotation_center,a_y_rotation_center)
		require
			renderer_exists: exists

	drawing_color: GAME_COLOR_READABLE assign set_drawing_color
			-- All performed drawing on Current is done
			-- using this color (including clear)
		require
			renderer_exists: exists

	driver: GAME_RENDERER_DRIVER
			-- The driver used to render Current

	enable_additive_blending
			-- Set the additive blending mode to use for drawing operations.
			-- Additive blending:	dstRGB = (srcRGB * srcA) + dstRGB
			--						dstA = dstA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists

	enable_alpha_blending
			-- Set the alpha blending mode to use for drawing operations.
			-- Alpha blending:	dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA))
			--					dstA = srcA + (dstA * (1-srcA))
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists

	enable_modulate_blending
			-- Set the color modulate blending mode to use for drawing operations.
			-- Color modulate:	dstRGB = srcRGB * dstRGB
			--					dstA = dstA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists

	exists: BOOLEAN
			-- Is item a valid pointer to be used as blenderable

	generating_type: TYPE [detachable GAME_RENDERER]
			-- Type of current object
			-- (type of which it is a direct instance)
			-- (from ANY)
		ensure -- from ANY
			generating_type_not_void: Result /= Void

	generator: STRING_8
			-- Name of current object's generating class
			-- (base class of the type of which it is a direct instance)
			-- (from ANY)
		ensure -- from ANY
			generator_not_void: Result /= Void
			generator_not_empty: not Result.is_empty

	has_error: BOOLEAN
			-- Is the library has generate an error
			-- (from GAME_ERROR_MANAGER)

	is_additive_blending_enabled: BOOLEAN
			-- True if the blending mode for drawing operation is additive blending.
			-- Additive blending:	dstRGB = (srcRGB * srcA) + dstRGB
			--						dstA = dstA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists

	is_alpha_blending_enabled: BOOLEAN
			-- True if the blending mode for drawing operation is alpha blending.
			-- Alpha blending:	dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA))
			--					dstA = srcA + (dstA * (1-srcA))
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists

	is_blending_disabled: BOOLEAN
			-- True if no blending mode is used for drawing operations.
			-- No blending mode:	dstRGBA = srcRGBA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists

	is_modulate_blending_enabled: BOOLEAN
			-- True if the blending mode for drawing operation is color modulate blending.
			-- Color modulate:	dstRGB = srcRGB * dstRGB
			--					dstA = dstA
			-- (from GAME_BLENDABLE)
		require -- from GAME_BLENDABLE
			blendable_is_valid: exists

	last_error: READABLE_STRING_GENERAL
			-- The last error generate by the library
			-- (from GAME_SDL_ANY)

	logical_size: TUPLE [width: INTEGER_32; height: INTEGER_32]
			-- Get the device independant logical size of the output of Current
			-- [0,0] if never set..
			-- Modifying this value may change the scale and viewport values.
		require
			renderer_exists: exists

	original_target: GAME_WINDOW_RENDERED
			-- The window that will be targetted
			-- (if no set_target has been called)
			-- command

	output_size: TUPLE [width: INTEGER_32; height: INTEGER_32]
			-- Get the size of the output of Current
		require
			renderer_exists: exists

	present
			-- Show the last drawed modification
		require
			renderer_exists: exists

	scale: TUPLE [x: REAL_32; y: REAL_32]
			-- Get the scale x and y that Current have to do when drawing.
			-- Note: For better performance, use integer scaling factor
		require
			renderer_exists: exists

	set_clip_rectangle (a_x, a_y, a_width, a_height: INTEGER_32)
			-- Assign clip_rectangle with the values of a_x, a_y,
			-- a_width and a_height
		require
			renderer_exists: exists
		ensure
			is_set: (attached clip_rectangle as la_clip_rectangle and attached normalize_rectangle (a_x, a_y, a_width, a_height) as la_normalized_rectangle) implies (la_clip_rectangle.x = la_normalized_rectangle.x and la_clip_rectangle.y = la_normalized_rectangle.y and la_clip_rectangle.width = la_normalized_rectangle.width and la_clip_rectangle.height = la_normalized_rectangle.height)

	set_drawing_color (a_drawing_color: GAME_COLOR_READABLE)
			-- Assign the value of the drawing_color
		require
			renderer_exists: exists

	set_logical_size (a_width, a_height: INTEGER_32)
			-- Assign logical_size using values in a_width and a_height.
			-- Using this feature may change the scale and viewport values.
		require
			renderer_exists: exists
			width_valid: a_width > 0
			height_valid: a_height > 0
		ensure
			is_set: attached logical_size as la_logical_size implies (la_logical_size.width = a_width and la_logical_size.height = a_height)

	set_original_target
			-- Put back the original_target as
			-- the target
		require
			renderer_exists: exists

	set_scale (a_x, a_y: REAL_32)
			-- Assign scale using values in a_x and a_y
		require
			renderer_exists: exists
		ensure
			is_set: attached scale as la_scale implies (la_scale.x = a_x and la_scale.y = a_y)

	set_target (a_target: GAME_RENDER_TARGET)
			-- Assign what GAME_RENDER_TARGET to use when using the present
			-- command
		require
			renderer_exists: exists
		ensure
			is_set: not has_error implies target = a_target

	set_viewport (a_x, a_y, a_width, a_height: INTEGER_32)
			-- Assign viewport using values in a_x, a_y, a_width
			-- and a_height. Note that depending on the scale values,
			-- the viewport may be round to another close value.
		require
			renderer_exists: exists
		ensure
			is_set: (attached viewport as la_viewport and attached scale as la_scale and attached normalize_rectangle (a_x, a_y, a_width, a_height) as la_normalized_rectangle) implies (la_viewport.x.to_double >= la_normalized_rectangle.x.to_double - (1.0 / la_scale.x.to_double) and la_viewport.x.to_double <= la_normalized_rectangle.x.to_double + (1.0 / la_scale.x.to_double) and la_viewport.y.to_double >= la_normalized_rectangle.y.to_double - (1.0 / la_scale.y.to_double) and la_viewport.y.to_double <= la_normalized_rectangle.y.to_double + (1.0 / la_scale.y.to_double) and la_viewport.width.to_double >= la_normalized_rectangle.width.to_double - (1.0 / la_scale.x.to_double) and la_viewport.width.to_double <= la_normalized_rectangle.width.to_double + (1.0 / la_scale.x.to_double) and la_viewport.height.to_double >= la_normalized_rectangle.height.to_double - (1.0 / la_scale.y.to_double) and la_viewport.height.to_double <= la_normalized_rectangle.height.to_double + (1.0 / la_scale.y.to_double))

	target: GAME_RENDER_TARGET assign set_target
			-- What GAME_RENDER_TARGET to use when using the present

	viewport: TUPLE [x: INTEGER_32; y: INTEGER_32; width: INTEGER_32; height: INTEGER_32]
			-- The position and size of the drawing area in Current
		require
			renderer_exists: exists
	
feature -- Comparison

	frozen deep_equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void
			-- or attached to isomorphic object structures?
			-- (from ANY)
		ensure -- from ANY
			instance_free: class
			shallow_implies_deep: standard_equal (a, b) implies Result
			both_or_none_void: (a = Void) implies (Result = (b = Void))
			same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b))
			symmetric: Result implies deep_equal (b, a)

	frozen equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void or attached
			-- to objects considered equal?
			-- (from ANY)
		ensure -- from ANY
			instance_free: class
			definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.is_equal (b))

	frozen is_deep_equal alias "≡≡≡" (other: GAME_RENDERER): BOOLEAN
			-- Are Current and other attached to isomorphic object structures?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		ensure -- from ANY
			shallow_implies_deep: standard_is_equal (other) implies Result
			same_type: Result implies same_type (other)
			symmetric: Result implies other.is_deep_equal (Current)

	is_equal (other: GAME_RENDERER): BOOLEAN
			-- Is other attached to an object considered
			-- equal to current object?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		ensure -- from ANY
			symmetric: Result implies other ~ Current
			consistent: standard_is_equal (other) implies Result

	frozen standard_equal (a: detachable ANY; b: like arg #1): BOOLEAN
			-- Are a and b either both void or attached to
			-- field-by-field identical objects of the same type?
			-- Always uses default object comparison criterion.
			-- (from ANY)
		ensure -- from ANY
			instance_free: class
			definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.standard_is_equal (b))

	frozen standard_is_equal alias "" (other: GAME_RENDERER): BOOLEAN
			-- Is other attached to an object of the same type
			-- as current object, and field-by-field identical to it?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		ensure -- from ANY
			same_type: Result implies same_type (other)
			symmetric: Result implies other.standard_is_equal (Current)
	
feature -- Status report

	conforms_to (other: ANY): BOOLEAN
			-- Does type of current object conform to type
			-- of other (as per Eiffel: The Language, chapter 13)?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void

	same_type (other: ANY): BOOLEAN
			-- Is type of current object identical to type of other?
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		ensure -- from ANY
			definition: Result = (conforms_to (other) and other.conforms_to (Current))
	
feature -- Duplication

	copy (other: GAME_RENDERER)
			-- Update current object using fields of object attached
			-- to other, so as to yield equal objects.
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
			type_identity: same_type (other)
		ensure -- from ANY
			is_equal: Current ~ other

	frozen deep_copy (other: GAME_RENDERER)
			-- Effect equivalent to that of:
			--		copy (other . deep_twin)
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
		ensure -- from ANY
			deep_equal: deep_equal (Current, other)

	frozen deep_twin: GAME_RENDERER
			-- New object structure recursively duplicated from Current.
			-- (from ANY)
		ensure -- from ANY
			deep_twin_not_void: Result /= Void
			deep_equal: deep_equal (Current, Result)

	frozen standard_copy (other: GAME_RENDERER)
			-- Copy every field of other onto corresponding field
			-- of current object.
			-- (from ANY)
		require -- from ANY
			other_not_void: other /= Void
			type_identity: same_type (other)
		ensure -- from ANY
			is_standard_equal: standard_is_equal (other)

	frozen standard_twin: GAME_RENDERER
			-- New object field-by-field identical to other.
			-- Always uses default copying semantics.
			-- (from ANY)
		ensure -- from ANY
			standard_twin_not_void: Result /= Void
			equal: standard_equal (Result, Current)

	frozen twin: GAME_RENDERER
			-- New object equal to Current
			-- twin calls copy; to change copying/twinning semantics, redefine copy.
			-- (from ANY)
		ensure -- from ANY
			twin_not_void: Result /= Void
			is_equal: Result ~ Current
	
feature -- Basic operations

	frozen default: detachable GAME_RENDERER
			-- Default value of object's type
			-- (from ANY)

	frozen default_pointer: POINTER
			-- Default value of type POINTER
			-- (Avoid the need to write p.default for
			-- some p of type POINTER.)
			-- (from ANY)
		ensure -- from ANY
			instance_free: class

	default_rescue
			-- Process exception for routines with no Rescue clause.
			-- (Default: do nothing.)
			-- (from ANY)

	frozen do_nothing
			-- Execute a null action.
			-- (from ANY)
		ensure -- from ANY
			instance_free: class
	
feature -- Output

	Io: STD_FILES
			-- Handle to standard file setup
			-- (from ANY)
		ensure -- from ANY
			instance_free: class
			io_not_void: Result /= Void

	out: STRING_8
			-- New string containing terse printable representation
			-- of current object
			-- (from ANY)
		ensure -- from ANY
			out_not_void: Result /= Void

	print (o: detachable ANY)
			-- Write terse external representation of o
			-- on standard output.
			-- (from ANY)
		ensure -- from ANY
			instance_free: class

	frozen tagged_out: STRING_8
			-- New string containing terse printable representation
			-- of current object
			-- (from ANY)
		ensure -- from ANY
			tagged_out_not_void: Result /= Void
	
feature -- Platform

	Operating_environment: OPERATING_ENVIRONMENT
			-- Objects available from the operating system
			-- (from ANY)
		ensure -- from ANY
			instance_free: class
			operating_environment_not_void: Result /= Void
	
invariant
		-- from ANY
	reflexive_equality: standard_is_equal (Current)
	reflexive_conformance: conforms_to (Current)

end -- class GAME_RENDERER

Generated by ISE EiffelStudio