/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
#ifndef R1_RENDER_API_HH
#define R1_RENDER_API_HH
#include "tex_id.hh"
#include "video/display.hh"
#include "r1_vert.hh"
#include "tnode.hh"
typedef struct
{
i4_float r,g,b;
} r1_color_tint;
typedef w32 r1_color_tint_handle;
enum r1_alpha_type
{
R1_ALPHA_DISABLED,
R1_ALPHA_CONSTANT, // use the constant color's alpha
R1_ALPHA_LINEAR // use the alpha specified in the verts
};
enum r1_shading_type
{
R1_SHADE_DISABLED, // routines will not light
R1_CONSTANT_SHADING, // routines will use the constant color
R1_WHITE_SHADING, // routines will use only the red component (as white)
R1_COLORED_SHADING // routines will use r,g, and b
};
enum
{
R1_WRITE_COLOR = 1, // write pixels to frame buffer
R1_WRITE_W = 2, // write w values to depth buffer
R1_COMPARE_W = 4 // if compare is off w then the depth buffer is not consulted
};
typedef w32 r1_write_mask_type;
enum r1_filter_type
{
R1_NO_FILTERING,
R1_BILINEAR_FILTERING
};
enum r1_expand_type
{
R1_COPY_1x1, // 1 - 1 pixel copy (render size = w,h)
R1_COPY_2x2, // 2 - 1 pixel blow up (render size = w/2, h/2)
R1_COPY_1x1_SCANLINE_SKIP // skips a scan line on each row (render size = w, h/2)
};
enum r1_render_flags
{
R1_SOFTWARE=1
};
enum r1_feature_flags
{
R1_SPANS=1,
R1_PERSPECTIVE_CORRECT=2,
R1_LOCK_CHEAT=4,
R1_Z_BIAS=8, //everything drawn after this is turned on is more likely to be drawn
//in front of things drawn before it was turned on
R1_ALL_FEATURES = R1_SPANS | R1_PERSPECTIVE_CORRECT | R1_LOCK_CHEAT | R1_Z_BIAS
};
class r1_last_node;
class r1_texture_manager_class;
class r1_miplevel_t;
class r1_texture_manager;
class g1_texture_node_struct;
class r1_render_window_class; // defined in r1_win.hh
class r1_render_api_class
{
protected:
friend r1_render_api_class *r1_get_api(i4_display_class *for_display);
friend r1_render_api_class *r1_create_api(i4_display_class *for_display, char *name);
friend void r1_destroy_api(r1_render_api_class *r);
r1_texture_manager_class *tmanager;
// make these global so they can be accessed without pointer indirection (faster)
static r1_miplevel_t *last_node;
static r1_shading_type shade_mode;
static r1_alpha_type alpha_mode;
static r1_write_mask_type write_mask;
static w32 const_color;
static r1_filter_type filter_mode;
static r1_render_api_class *first;
static i4_float r_tint_mul;
static i4_float g_tint_mul;
static i4_float b_tint_mul;
static i4_bool color_tint_on;
enum { MAX_COLOR_TINTS = 32 };
static r1_color_tint color_tint_list[MAX_COLOR_TINTS];
static sw8 num_color_tints;
r1_render_api_class *next;
//currently the only flag is R1_SOFTWARE
w32 render_device_flags;
// returns false if display is not compatible with render_api, i.e. if you pass
// the directx display to the glide render api it return false
// init will create the texture manager, which can be used after this call
// text_mem_size if size of buffer to hold compressed textures (in system memory)
virtual i4_bool init(i4_display_class *display);
// this will delete the texture manager (and free textures associated with) created by init
virtual void uninit();
virtual void copy_part(i4_image_class *im,
int x, int y, // position on screen
int x1, int y1, // area of image to copy
int x2, int y2) = 0;
public:
w32 get_render_device_flags() { return render_device_flags; }
r1_shading_type get_shade_mode() { return shade_mode; }
r1_alpha_type get_alpha_mode() { return alpha_mode; }
r1_write_mask_type get_write_mask() { return write_mask; }
w32 get_constant_color() { return const_color; }
r1_filter_type get_filter_mode() { return filter_mode; }
r1_render_api_class()
{
tmanager=0;
render_device_flags=0;
next=first;
first=this;
}
static i4_draw_context_class *context;
virtual i4_bool pixel_double() { return i4_F; }
r1_texture_manager_class *get_tmanager() { return tmanager; } // created by init()
// texture handle is obtained from the texture manager, this is enables texture mapping
virtual void use_texture(r1_texture_handle material_ref,
sw32 desired_width,
w32 frame) = 0;
// drawing will the constant color to render with if textures are disabled
virtual void disable_texture() = 0;
//tints all r g b values (multiplies)
virtual r1_color_tint_handle register_color_tint(i4_float r, i4_float g, i4_float b);
//calling this with a handle of 0 disables tinting
virtual void set_color_tint(r1_color_tint_handle color_tint_handle);
// constant color is used by line drawing, and poly draws-if disable_texture
virtual void set_constant_color(w32 color) { const_color=color; }
virtual void set_shading_mode(r1_shading_type type) { shade_mode=type; }
virtual void set_alpha_mode(r1_alpha_type type) { alpha_mode=type; }
virtual void set_write_mode(r1_write_mask_type mask) { write_mask=mask; }
virtual void set_filter_mode(r1_filter_type type) { filter_mode=type; }
// api will scale all z's (or w's) to reflect this range with best percision
// near_z must be greater than 0
virtual void set_z_range(float near_z, float far_z) = 0;
// make sure this updates the following variables:
// r1_near_clip_z
// r1_far_clip_z
virtual void render_poly(int t_verts, r1_vert *verts) = 0;
virtual void render_poly(int t_verts, r1_vert *verts, int *vertex_index);
virtual void render_poly(int t_verts, r1_vert *verts, w16 *vertex_index);
//this had better be a rectangle
virtual void render_sprite(r1_vert *verts);
virtual void render_pixel(r1_vert *pixel) = 0;
virtual void render_lines(int t_lines, r1_vert *verts ) = 0;
// color is standard argb, (z should be within range specifed by set_z_range)
virtual void clear_area(int x1, int y1, int x2, int y2, w32 color, float z);
// creates an image of the same bit depth and palette of screen (for use with put_image)
virtual i4_image_class *create_compatible_image(w16 w, w16 h) = 0;
// these should be called for an image before drawing to them
virtual void lock_image(i4_image_class *im) { ; }
virtual void unlock_image(i4_image_class *im) { ; }
// this function does clipping (based on context) and calls copy_part
virtual void put_image(i4_image_class *im,
int x, int y, // position on screen
int x1, int y1, // area of image to copy
int x2, int y2);
virtual r1_vert *clip_poly(sw32 *num_clip_verts, //how many verts in this polygon
r1_vert *t_vertices, //pointer to the vertices
w16 *indices, //pointer to the indices
r1_vert *clip_buf_1, //pointer to clip buffer 1
r1_vert *clip_buf_2, //pointer to clip buffer 2
w8 flags); //flags to be considered when clipping
virtual r1_vert *clip_poly(sw32 *num_clip_verts, //how many verts in this polygon
r1_vert *t_vertices, //pointer to the vertices
w32 *indices, //pointer to the indices
r1_vert *clip_buf_1, //pointer to clip buffer 1
r1_vert *clip_buf_2, //pointer to clip buffer 2
w8 flags); //flags to be considered when clipping
// creates a window that rendering can occur in
// visable_w and & h is the area the window takes up on the actual screen
// expand type will determine the size you can actually render to
virtual r1_render_window_class *create_render_window(int visable_w, int visable_h,
r1_expand_type type=R1_COPY_1x1) = 0;
virtual i4_bool expand_type_supported(r1_expand_type type)
{ return (i4_bool)(type==R1_COPY_1x1); }
virtual void modify_features(w32 feature_bits, int on) { ; }
virtual i4_bool is_feature_on(w32 feature_bits) { return i4_F; }
virtual void default_state()
{
disable_texture();
set_constant_color(0xffffff);
set_z_range(0.001,10000);
set_shading_mode(R1_COLORED_SHADING);
set_write_mode(R1_WRITE_COLOR | R1_WRITE_W | R1_COMPARE_W);
set_alpha_mode(R1_ALPHA_DISABLED);
set_filter_mode(R1_NO_FILTERING);
set_color_tint(0);
modify_features(R1_ALL_FEATURES, 0); // turn off these other features
modify_features(R1_SPANS, 1);
modify_features(R1_PERSPECTIVE_CORRECT, 1);
}
virtual char *name() = 0;
};
extern r1_render_api_class *r1_render_api_class_instance;
r1_render_api_class *r1_create_api(i4_display_class *for_display, char *api_name=0);
void r1_destroy_api(r1_render_api_class *render_api);
inline i4_float r1_ooz(i4_float z) { return 0.9999/z; }
#endif