/** * PANDA 3D SOFTWARE * Copyright (c) Carnegie Mellon University. All rights reserved. * * All use of this software is subject to the terms of the revised BSD * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * * @file dxGraphicsStateGuardian9.h * @author mike * @date 1999-02-02 * @author fperazzi, PandaSE * @date 2010-05-05 */ #ifndef DXGRAPHICSSTATEGUARDIAN9_H #define DXGRAPHICSSTATEGUARDIAN9_H #include "dxgsg9base.h" #include "dxTextureContext9.h" #include "config_dxgsg9.h" #include "graphicsStateGuardian.h" #include "texture.h" #include "samplerState.h" #include "displayRegion.h" #include "material.h" #include "depthTestAttrib.h" #include "cullFaceAttrib.h" #include "renderModeAttrib.h" #include "colorBlendAttrib.h" #include "fog.h" #include "pointerToArray.h" #include "vertexElementArray.h" #include "dxShaderContext9.h" enum GsgPageType { GPT_Texture, GPT_VertexBuffer, GPT_IndexBuffer, GPT_TotalPageTypes }; class Light; class DXTextureContext9; class DXVertexBufferContext9; class DXIndexBufferContext9; class wdxGraphicsBuffer9; /** * A GraphicsStateGuardian for rendering into DirectX9 contexts. */ class EXPCL_PANDADX DXGraphicsStateGuardian9 : public GraphicsStateGuardian { public: DXGraphicsStateGuardian9(GraphicsEngine *engine, GraphicsPipe *pipe); ~DXGraphicsStateGuardian9(); FrameBufferProperties calc_fb_properties(DWORD cformat, DWORD dformat, DWORD multisampletype, DWORD multisamplequality); virtual TextureContext *prepare_texture(Texture *tex, int view); void apply_texture(int i, TextureContext *tc, const SamplerState &sampler); virtual bool update_texture(TextureContext *tc, bool force); bool upload_texture(DXTextureContext9 *dtc, bool force); virtual void release_texture(TextureContext *tc); virtual bool extract_texture_data(Texture *tex); ShaderContext *prepare_shader(Shader *se); void release_shader(ShaderContext *sc); virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data); bool apply_vertex_buffer(VertexBufferContext *vbc, const GeomVertexArrayDataHandle *reader, bool force); virtual void release_vertex_buffer(VertexBufferContext *vbc); bool setup_array_data(DXVertexBufferContext9 *&vbc, const GeomVertexArrayDataHandle* data, bool force); virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data); bool apply_index_buffer(IndexBufferContext *ibc, const GeomPrimitivePipelineReader *reader, bool force); virtual void release_index_buffer(IndexBufferContext *ibc); virtual void begin_occlusion_query(); virtual PT(OcclusionQueryContext) end_occlusion_query(); virtual PT(GeomMunger) make_geom_munger(const RenderState *state, Thread *current_thread); virtual void clear(DrawableRegion *clearable); virtual void prepare_display_region(DisplayRegionPipelineReader *dr); virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual bool prepare_lens(); virtual bool begin_frame(Thread *current_thread); virtual bool begin_scene(); virtual void end_scene(); virtual void end_frame(Thread *current_thread); virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomVertexDataPipelineReader *data_reader, bool force); virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force); virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force); virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, bool force); virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, bool force); virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force); virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force); virtual void end_draw_primitives(); virtual bool framebuffer_copy_to_texture(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb); virtual bool framebuffer_copy_to_ram(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb); bool do_framebuffer_copy_to_ram(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb, bool inverted); void reset_render_states (void); virtual void reset(); virtual void apply_fog(Fog *fog); virtual void bind_light(PointLight *light_obj, const NodePath &light, int light_id); virtual void bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id); virtual void bind_light(Spotlight *light_obj, const NodePath &light, int light_id); static D3DFORMAT get_index_type(Geom::NumericType numeric_type); INLINE static DWORD LColor_to_D3DCOLOR(const LColor &cLColor); virtual void set_state_and_transform(const RenderState *state, const TransformState *transform); bool check_dx_allocation (HRESULT result, int allocation_size, int attempts); INLINE HRESULT set_render_state (D3DRENDERSTATETYPE state, DWORD value); INLINE HRESULT set_texture_stage_state (DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value); INLINE HRESULT set_sampler_state (DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value); INLINE bool get_supports_render_texture() const; static bool get_gamma_table(void); static bool static_set_gamma(bool restore, PN_stdfloat gamma); bool set_gamma(PN_stdfloat gamma); void restore_gamma(); static void atexit_function(void); static void set_cg_device(LPDIRECT3DDEVICE9 cg_device); virtual bool get_supports_cg_profile(const std::string &name) const; LPDIRECT3DVERTEXBUFFER9 get_white_vbuffer(); protected: void do_issue_transform(); void do_issue_alpha_test(); void do_issue_shader(); void do_issue_render_mode(); void do_issue_rescale_normal(); void do_issue_color_write(); void do_issue_depth_test(); void do_issue_depth_write(); void do_issue_cull_face(); void do_issue_fog(); void do_issue_depth_offset(); void do_issue_tex_gen(); void do_issue_shade_model(); void do_issue_material(); void do_issue_texture(); void do_issue_blending(); void do_issue_stencil(); void do_issue_scissor(); virtual void reissue_transforms(); virtual void enable_lighting(bool enable); virtual void set_ambient_light(const LColor &color); virtual void enable_light(int light_id, bool enable); virtual void enable_clip_plane(int plane_id, bool enable); virtual void bind_clip_plane(const NodePath &plane, int plane_id); virtual void close_gsg(); void free_nondx_resources(); void free_d3d_device(); void set_draw_buffer(const RenderBuffer &rb); void set_read_buffer(const RenderBuffer &rb); void disable_standard_vertex_arrays(); bool update_standard_vertex_arrays(bool force); void disable_standard_texture_bindings(); void update_standard_texture_bindings(); protected: INLINE static D3DTEXTUREADDRESS get_texture_wrap_mode(SamplerState::WrapMode wm); INLINE static D3DFOGMODE get_fog_mode_type(Fog::Mode m); const D3DCOLORVALUE &get_light_color(Light *light) const; INLINE static D3DTRANSFORMSTATETYPE get_tex_mat_sym(int stage_index); static D3DBLENDOP get_blend_mode(ColorBlendAttrib::Mode mode); static D3DBLEND get_blend_func(ColorBlendAttrib::Operand operand); void report_texmgr_stats(); void set_context(DXScreenData *new_context); void set_render_target(); void set_texture_blend_mode(int i, const TextureStage *stage); void dx_cleanup(); HRESULT reset_d3d_device(D3DPRESENT_PARAMETERS *p_presentation_params, DXScreenData **screen = nullptr); bool check_cooperative_level(); void show_frame(); bool create_swap_chain (DXScreenData *new_context); bool release_swap_chain (DXScreenData *new_context); void copy_pres_reset(DXScreenData *new_context); static D3DTEXTUREFILTERTYPE get_d3d_min_type(SamplerState::FilterType filter_type); static D3DTEXTUREFILTERTYPE get_d3d_mip_type(SamplerState::FilterType filter_type); static D3DTEXTUREOP get_texture_operation(TextureStage::CombineMode mode, int scale); DWORD get_texture_argument(TextureStage::CombineSource source, TextureStage::CombineOperand operand) const; static DWORD get_texture_argument_modifier(TextureStage::CombineOperand operand); void draw_primitive_up(D3DPRIMITIVETYPE primitive_type, unsigned int primitive_count, unsigned int first_vertex, unsigned int num_vertices, const unsigned char *buffer, size_t stride); void draw_indexed_primitive_up(D3DPRIMITIVETYPE primitive_type, unsigned int min_index, unsigned int max_index, unsigned int num_primitives, const unsigned char *index_data, D3DFORMAT index_type, const unsigned char *buffer, size_t stride); INLINE static unsigned char *get_safe_buffer_start(); public: DXScreenData *_screen; protected: LPDIRECT3DDEVICE9 _d3d_device; // same as _screen->_d3d_device, cached for spd IDirect3DSwapChain9 *_swap_chain; D3DPRESENT_PARAMETERS _presentation_reset; // This is built during reset device bool _dx_is_ready; HRESULT _last_testcooplevel_result; bool _vertex_blending_enabled; bool _supports_render_texture; RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation enum DxgsgFogType { None, PerVertexFog=D3DRS_FOGVERTEXMODE, PerPixelFog=D3DRS_FOGTABLEMODE }; DxgsgFogType _do_fog_type; D3DVIEWPORT9 _current_viewport; bool _supports_depth_bias; DWORD _clip_plane_bits; CullFaceAttrib::Mode _cull_face_mode; RenderModeAttrib::Mode _current_fill_mode; //point/wireframe/solid PT(Shader) _current_shader; DXShaderContext9 *_current_shader_context; PT(Shader) _vertex_array_shader; DXShaderContext9 *_vertex_array_shader_context; PT(Shader) _texture_binding_shader; DXShaderContext9 *_texture_binding_shader_context; const DXIndexBufferContext9 *_active_ibuffer; bool _overlay_windows_supported; bool _tex_stats_retrieval_impossible; bool _supports_texture_constant_color; DWORD _constant_color_operand; static D3DMATRIX _d3d_ident_mat; static unsigned char *_temp_buffer; static unsigned char *_safe_buffer_start; int _gsg_managed_textures; int _gsg_managed_vertex_buffers; int _gsg_managed_index_buffers; UINT _available_texture_memory; DWORD _last_fvf; int _num_bound_streams; LPDIRECT3DVERTEXBUFFER9 _white_vbuffer; // Cache the data necessary to bind each particular light each frame, so if // we bind a given light multiple times, we only have to compute its data // once. typedef pmap DirectionalLights; DirectionalLights _dlights; #define MAXIMUM_TEXTURES 16 // from D3DRENDERSTATETYPE + pad #define MAXIMUM_RENDER_STATES 256 // from D3DTEXTURESTAGESTATETYPE + pad #define MAXIMUM_TEXTURE_STAGE_STATES 40 typedef struct { DWORD state_array [MAXIMUM_TEXTURE_STAGE_STATES]; } TextureStageStates; // from D3DSAMPLERSTATETYPE + pad #define MAXIMUM_TEXTURE_RENDER_STATES 16 typedef struct { DWORD state_array [MAXIMUM_TEXTURE_RENDER_STATES]; } TextureRenderStates; // from D3DRENDERSTATETYPE DWORD _render_state_array [MAXIMUM_RENDER_STATES]; TextureStageStates _texture_stage_states_array [D3D_MAXTEXTURESTAGES]; TextureRenderStates _texture_render_states_array [MAXIMUM_TEXTURES]; int _num_active_texture_stages; int _vertex_shader_version_major; int _vertex_shader_version_minor; int _pixel_shader_version_major; int _pixel_shader_version_minor; char *_vertex_shader_profile; char *_pixel_shader_profile; int _vertex_shader_maximum_constants; bool _supports_stream_offset; std::list _graphics_buffer_list; int _supports_gamma_calibration; #ifdef HAVE_CG CGcontext _cg_context; static LPDIRECT3DDEVICE9 _cg_device; #endif public: virtual TypeHandle get_type() const { return get_class_type(); } virtual TypeHandle force_init_type() {init_type(); return get_class_type();} static TypeHandle get_class_type() { return _type_handle; } public: static void init_type() { GraphicsStateGuardian::init_type(); register_type(_type_handle, "DXGraphicsStateGuardian9", GraphicsStateGuardian::get_class_type()); } private: static TypeHandle _type_handle; friend class wdxGraphicsWindow9; friend class wdxGraphicsPipe9; friend class wdxGraphicsWindowGroup9; friend class DXTextureContext9; friend class wdxGraphicsBuffer9; friend class DXVertexBufferContext9; friend class DXIndexBufferContext9; friend class DXShaderContext9; }; #include "dxGraphicsStateGuardian9.I" #endif