// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_sg_state #define tools_sg_state #include #include "../lina/rotf" //m_camera_orientation #include "../lina/mat4f" #include "../lina/vec3f" #include "../lina/vec4f" #include "../colorf" #ifdef TOOLS_MEM #include "../mem" #include "../S_STRING" #endif #include "enums" namespace tools { namespace sg { class state { #ifdef TOOLS_MEM TOOLS_SCLASS(tools::sg::state) #endif public: state() //must be consistent with exlib::sg::viewer::render. :m_ww(0) ,m_wh(0) ,m_GL_DEPTH_TEST(true) ,m_GL_LIGHTING(false) ,m_GL_CULL_FACE(true) ,m_GL_POLYGON_OFFSET_FILL(false) ,m_GL_TEXTURE_2D(false) ,m_GL_POINT_SMOOTH(false) ,m_GL_LINE_SMOOTH(false) ,m_GL_BLEND(false) ,m_use_gsto(false) ,m_winding(winding_ccw) ,m_color(1,1,1,1) ,m_normal(0,0,1) ,m_light(0) ,m_draw_type(sg::draw_filled) ,m_shade_model(sg::shade_flat) ,m_line_width(1) ,m_line_pattern(sg::line_solid) ,m_point_size(1) ,m_camera_ortho(true) ,m_camera_znear(1) ,m_camera_zfar(10) ,m_camera_position(vec3f(0,0,1)) ,m_camera_orientation(rotf(vec3f(0,0,1),0)) //,m_camera_near_height(0) ,m_camera_lrbt(0,0,0,0) { #ifdef TOOLS_MEM mem::increment(s_class().c_str()); #endif //m_proj.set_identity(); //m_model.set_identity(); } virtual ~state(){ #ifdef TOOLS_MEM mem::decrement(s_class().c_str()); #endif } public: state(const state& a_from) :m_ww(a_from.m_ww) ,m_wh(a_from.m_wh) ,m_proj(a_from.m_proj) ,m_model(a_from.m_model) ,m_GL_DEPTH_TEST(a_from.m_GL_DEPTH_TEST) ,m_GL_LIGHTING(a_from.m_GL_LIGHTING) ,m_GL_CULL_FACE(a_from.m_GL_CULL_FACE) ,m_GL_POLYGON_OFFSET_FILL(a_from.m_GL_POLYGON_OFFSET_FILL) ,m_GL_TEXTURE_2D(a_from.m_GL_TEXTURE_2D) ,m_GL_POINT_SMOOTH(a_from.m_GL_POINT_SMOOTH) ,m_GL_LINE_SMOOTH(a_from.m_GL_LINE_SMOOTH) ,m_GL_BLEND(a_from.m_GL_BLEND) ,m_use_gsto(a_from.m_use_gsto) ,m_winding(a_from.m_winding) ,m_color(a_from.m_color) ,m_normal(a_from.m_normal) ,m_light(a_from.m_light) ,m_draw_type(a_from.m_draw_type) ,m_shade_model(a_from.m_shade_model) ,m_line_width(a_from.m_line_width) ,m_line_pattern(a_from.m_line_pattern) ,m_point_size(a_from.m_point_size) ,m_camera_ortho(a_from.m_camera_ortho) ,m_camera_znear(a_from.m_camera_znear) ,m_camera_zfar(a_from.m_camera_zfar) ,m_camera_position(a_from.m_camera_position) ,m_camera_orientation(a_from.m_camera_orientation) //,m_camera_near_height(a_from.m_camera_near_height) ,m_camera_lrbt(a_from.m_camera_lrbt) { #ifdef TOOLS_MEM mem::increment(s_class().c_str()); #endif } state& operator=(const state& a_from){ m_ww = a_from.m_ww; m_wh = a_from.m_wh; m_proj = a_from.m_proj; m_model = a_from.m_model; m_GL_DEPTH_TEST = a_from.m_GL_DEPTH_TEST; m_GL_LIGHTING = a_from.m_GL_LIGHTING; m_GL_CULL_FACE = a_from.m_GL_CULL_FACE; m_GL_POLYGON_OFFSET_FILL = a_from.m_GL_POLYGON_OFFSET_FILL; m_GL_TEXTURE_2D = a_from.m_GL_TEXTURE_2D; m_GL_POINT_SMOOTH = a_from.m_GL_POINT_SMOOTH; m_GL_LINE_SMOOTH = a_from.m_GL_LINE_SMOOTH; m_GL_BLEND = a_from.m_GL_BLEND; m_use_gsto = a_from.m_use_gsto; m_winding = a_from.m_winding; m_color = a_from.m_color; m_normal = a_from.m_normal; m_light = a_from.m_light; m_draw_type = a_from.m_draw_type; m_shade_model = a_from.m_shade_model; m_line_width = a_from.m_line_width; m_line_pattern = a_from.m_line_pattern; m_point_size = a_from.m_point_size; m_camera_ortho = a_from.m_camera_ortho; m_camera_znear = a_from.m_camera_znear; m_camera_zfar = a_from.m_camera_zfar; m_camera_position = a_from.m_camera_position; m_camera_orientation = a_from.m_camera_orientation; //m_camera_near_height = a_from.m_camera_near_height; m_camera_lrbt = a_from.m_camera_lrbt; return *this; } public: bool project_point(float& a_x,float& a_y,float& a_z,float& a_w) const { a_w = 1; m_model.mul_4f(a_x,a_y,a_z,a_w); m_proj.mul_4f(a_x,a_y,a_z,a_w); if(a_w==0.0F) return false; a_x /= a_w; a_y /= a_w; a_z /= a_w; return true; } void screen2ndc(int a_x,int a_y, //signed because of wall. float& a_wcx,float& a_wcy,float& a_wcz,float& a_wcw) const { // a proj point in near plane has (z,w) : // ortho -1,1 -> z/w = -1 and xy in [-1,1][-1,1] // persp -n,n -> z/w = -1 and xy in [-n,n][-n,n] a_wcx = 2*(float(a_x)/float(m_ww)-0.5f); //in [-1,1] a_wcy = 2*(float(a_y)/float(m_wh)-0.5f); a_wcz = -1; if(m_camera_ortho) { a_wcw = 1; } else { float t = m_camera_znear; a_wcx *= t; a_wcy *= t; a_wcz *= t; a_wcw = t; } } bool screen2wc(int a_x,int a_y, //signed because of wall. float& a_wcx,float& a_wcy,float& a_wcz) const { mat4f mtx = m_proj; mtx.mul_mtx(m_model); mat4f inv; if(!mtx.invert(inv)) {a_wcx = 0;a_wcy = 0;a_wcz = 0;return false;} float w; screen2ndc(a_x,a_y,a_wcx,a_wcy,a_wcz,w); inv.mul_4f(a_wcx,a_wcy,a_wcz,w); if(w==0.0F) return false; a_wcx /= w; a_wcy /= w; a_wcz /= w; return true; } bool screen2pwc(int a_x,int a_y, //signed because of wall. float& a_wcx,float& a_wcy,float& a_wcz) const { mat4f mtx = m_proj; //mtx.mul_mtx(m_model); mat4f inv; if(!mtx.invert(inv)) {a_wcx = 0;a_wcy = 0;a_wcz = 0;return false;} float w; screen2ndc(a_x,a_y,a_wcx,a_wcy,a_wcz,w); inv.mul_4f(a_wcx,a_wcy,a_wcz,w); if(w==0.0F) return false; a_wcx /= w; a_wcy /= w; a_wcz /= w; return true; } void camera_proj_only(mat4f& a_mtx) const { float l = m_camera_lrbt[0]; float r = m_camera_lrbt[1]; float b = m_camera_lrbt[2]; float t = m_camera_lrbt[3]; float n = m_camera_znear; float f = m_camera_zfar; if(m_camera_ortho) { a_mtx.set_ortho(l,r,b,t,n,f); } else { a_mtx.set_frustum(l,r,b,t,n,f); } } public: unsigned int m_ww; //window width unsigned int m_wh; //window height mat4f m_proj; mat4f m_model; bool m_GL_DEPTH_TEST; bool m_GL_LIGHTING; bool m_GL_CULL_FACE; bool m_GL_POLYGON_OFFSET_FILL; bool m_GL_TEXTURE_2D; bool m_GL_POINT_SMOOTH; bool m_GL_LINE_SMOOTH; bool m_GL_BLEND; bool m_use_gsto; winding_type m_winding; colorf m_color; vec3f m_normal; unsigned int m_light; draw_type m_draw_type; shade_type m_shade_model; float m_line_width; unsigned short m_line_pattern; float m_point_size; //camera (see base_camera::set_state()) : bool m_camera_ortho; float m_camera_znear; float m_camera_zfar; vec3f m_camera_position; rotf m_camera_orientation; //used by head_light //float m_camera_near_height; vec4f m_camera_lrbt; }; }} #endif