/**********************************************************************
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)
***********************************************************************/
#include "window/window.hh"
#include "app/app.hh"
#include "main/main.hh"
#include "r1_api.hh"
#include "r1_win.hh"
#include "window/style.hh"
#include "file/file.hh"
#include "loaders/load.hh"
#include "window/wmanager.hh"
#include "math/transform.hh"
#include "gui/text.hh"
#include "gui/button.hh"
#include "loaders/load.hh"
#include "tmanage.hh"
// merge test
// merge test 2.5
r1_render_api_class *api=0;
class test_win_class : public i4_window_class
{
public:
float xr,yr,zr; // rotation numbers for the cube
r1_texture_handle texture;
test_win_class(w16 w, w16 h)
: i4_window_class(w,h)
{
xr=yr=zr=0;
r1_texture_manager_class *tman=api->get_tmanager();
texture=tman->register_image(i4_load_image("texture.tga"));
}
void draw(i4_draw_context_class &context)
{
int i;
// initialize the rendering api to a "normal" state
api->default_state();
// the z range tells the api what range your vertexes will be in so it can scale
// them to fit it's own internal z buffer range
float far_z=1000;
api->set_z_range(0.01, far_z);
// clear the screen black, since frame buffer is initialized to far_z, the clear z
// bust be less than this to appear
w32 color=0;
api->clear_area(0,0,width()-1,height()-1, color, far_z-1);
// points on the cube
float cube_points[8*3]={-1, 1, -1, 1,1,-1, 1,-1,-1, -1, -1, -1,
-1, 1, 1, 1,1,1, 1,-1,1, -1, -1, 1};
// some colors red green blue white
float colors[4 * 3] = { 1,0,0, 0,1,0, 0,0,1, 1,1,1 };
int point_colors[8] = { 0,1,2,3,3,2,1,1 };
// faces on the cube
int verts[4 * 6] = { 0,1,2,3, 4,5,6,7, 3,2,6,7, 0,1,5,4, 1,5,6,2, 0,3,7,4 };
float tcoord_s[4] = { 0,1,1,0 };
float tcoord_t[4] = { 1,1,0,0 };
// setup of the transformation matrix
i4_transform_class matrix, tmp_matrix;
matrix.identity();
matrix.t.z=4; // move camera 5 units away from cube
tmp_matrix.rotate_x(xr);
matrix.multiply(tmp_matrix);
tmp_matrix.rotate_y(yr);
matrix.multiply(tmp_matrix);
tmp_matrix.rotate_y(zr);
matrix.multiply(tmp_matrix);
xr+=0.01; yr+=0.02; zr+=0.011; // change rotation for next draw
// transform the points into view spave
i4_3d_point_class transformed_points[8];
for (i=0; i<8; i++)
{
i4_3d_point_class p(cube_points[i*3], cube_points[i*3+1], cube_points[i*3+2]);
matrix.transform(p, transformed_points[i]);
}
api->use_texture(texture, 256, 0);
// now copy the points into an r1_vert and project them onto the scren
float center_x=width()/2, center_y=height()/2;
r1_vert v[4];
for (i=0; i<6; i++) // loop through the faces
{
for (int j=0; j<4; j++) // loop through the points on the face
{
int pn=verts[i*4+j]; //point number
// this stores the x,y,z of the point in world space (only x & y are actually needed,
// unless you clip the polygon - which we are not)
v[j].v=*((r1_3d_point_class *)&transformed_points[pn]);
// w is the homogenous coordinate (1/z)
v[j].w=1.0/v[j].v.z;
// project onto screen and scale to fit the camera view port
v[j].px=v[j].w * v[j].v.x * center_x + center_x;
v[j].py=v[j].w * v[j].v.y * center_y + center_y;
// set the color of the points
v[j].r=colors[point_colors[pn]*3]; // color values are [0..1] 1=brightest
v[j].g=colors[point_colors[pn]*3+1];
v[j].b=colors[point_colors[pn]*3+2];
// we don't need to set s & t (texture coordinates)
// because we aren't texture mapping, but just so you know they are there..
v[j].s = tcoord_s[j]; // texture coordinates are between 0..1, 0 is left or top
v[j].t = tcoord_t[j];
}
api->render_poly(4, v);
}
request_redraw();
}
char *name() { return "test_win"; }
};
class test_app : public i4_application_class
{
public:
enum { QUIT };
void init()
{
i4_application_class::init();
// create a rendering api (display comes from the application which was
// created by init)
// the second parameter is the suggested texture memory size
api=r1_create_api(display);
if (!api)
i4_error("could not find an rending api for this display");
// wm is the window manager, created by app::init()
// wm->width is the resolution of the screen
int w=wm->width()/2, h=wm->height()/2;
// wm has a "style" associated with it that controlls the way the gui looks
i4_graphical_style_class *style=wm->get_style();
// you can get the window manager's style by calling get_style()
// a mp_window (--meta physical--) is a framed draggable window
i4_parent_window_class *p1=style->create_mp_window(-1,-1, w,h,
i4_const_str("Test window 1"), 0);
// all rendering must reside in render_window so the render api can initialize
// the context before and after the drawing operations (like x/y window offset,
// clipping rectangles, etc).
r1_render_window_class *rwin = api->create_render_window(p1->width(), p1->height());
// render_area_width() & height may be different from width() if you are
// using double pixel or interlaced mode
i4_window_class *test_win;
test_win=new test_win_class(rwin->render_area_width(), rwin->render_area_height());
// this adds the test window into the render_api's render_window
rwin->add_child(0, 0, test_win);
// this adds the render_api's window into the mp_window (which is automatically added
// to your desktop by create_mp_window)
p1->add_child(0,0,rwin);
i4_button_class *quit=new i4_button_class(0,
new i4_text_window_class(i4_const_str("Quit"),
style),
style,
new i4_event_reaction_class(this, QUIT));
wm->add_child(0,0, quit);
}
void receive_event(i4_event *ev)
{
if (ev->type()==i4_event::USER_MESSAGE && ((i4_user_message_event_class *)ev)->sub_type==QUIT)
quit();
else
i4_application_class::receive_event(ev);
}
void uninit()
{
// cleanup the the render_api
r1_destroy_api(api);
// the application will close the display and cleanup memory here
i4_application_class::uninit();
}
char *name() { return "test_app"; }
};
void i4_main(w32 argc, i4_const_str *argv)
{
test_app test;
test.run();
}