Panda3D
dxGraphicsStateGuardian9.h
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file dxGraphicsStateGuardian9.h
10  * @author mike
11  * @date 1999-02-02
12  * @author fperazzi, PandaSE
13  * @date 2010-05-05
14  */
15 
16 #ifndef DXGRAPHICSSTATEGUARDIAN9_H
17 #define DXGRAPHICSSTATEGUARDIAN9_H
18 
19 #include "dxgsg9base.h"
20 #include "dxTextureContext9.h"
21 #include "config_dxgsg9.h"
22 
23 #include "graphicsStateGuardian.h"
24 #include "texture.h"
25 #include "samplerState.h"
26 #include "displayRegion.h"
27 #include "material.h"
28 #include "depthTestAttrib.h"
29 #include "cullFaceAttrib.h"
30 #include "renderModeAttrib.h"
31 #include "colorBlendAttrib.h"
32 #include "fog.h"
33 #include "pointerToArray.h"
34 
35 #include "vertexElementArray.h"
36 #include "dxShaderContext9.h"
37 
38 enum GsgPageType {
39  GPT_Texture,
40  GPT_VertexBuffer,
41  GPT_IndexBuffer,
42 
43  GPT_TotalPageTypes
44 };
45 
46 class Light;
47 
48 class DXTextureContext9;
51 
52 class wdxGraphicsBuffer9;
53 
54 /**
55  * A GraphicsStateGuardian for rendering into DirectX9 contexts.
56  */
57 class EXPCL_PANDADX DXGraphicsStateGuardian9 : public GraphicsStateGuardian {
58 public:
61 
63  calc_fb_properties(DWORD cformat, DWORD dformat,
64  DWORD multisampletype, DWORD multisamplequality);
65 
66  virtual TextureContext *prepare_texture(Texture *tex, int view);
67  void apply_texture(int i, TextureContext *tc, const SamplerState &sampler);
68  virtual bool update_texture(TextureContext *tc, bool force);
69  bool upload_texture(DXTextureContext9 *dtc, bool force);
70  virtual void release_texture(TextureContext *tc);
71  virtual bool extract_texture_data(Texture *tex);
72 
74  void release_shader(ShaderContext *sc);
75 
77  bool apply_vertex_buffer(VertexBufferContext *vbc,
78  const GeomVertexArrayDataHandle *reader,
79  bool force);
80  virtual void release_vertex_buffer(VertexBufferContext *vbc);
81 
82  bool setup_array_data(DXVertexBufferContext9 *&vbc,
83  const GeomVertexArrayDataHandle* data,
84  bool force);
85 
87  bool apply_index_buffer(IndexBufferContext *ibc,
88  const GeomPrimitivePipelineReader *reader, bool force);
89  virtual void release_index_buffer(IndexBufferContext *ibc);
90 
91  virtual void begin_occlusion_query();
92  virtual PT(OcclusionQueryContext) end_occlusion_query();
93 
94  virtual PT(GeomMunger) make_geom_munger(const RenderState *state,
95  Thread *current_thread);
96 
97  virtual void clear(DrawableRegion *clearable);
98 
100  virtual CPT(TransformState) calc_projection_mat(const Lens *lens);
101  virtual bool prepare_lens();
102 
103  virtual bool begin_frame(Thread *current_thread);
104  virtual bool begin_scene();
105  virtual void end_scene();
106  virtual void end_frame(Thread *current_thread);
107 
108  virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
109  const GeomVertexDataPipelineReader *data_reader,
110  bool force);
111  virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader,
112  bool force);
113  virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader,
114  bool force);
115  virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader,
116  bool force);
117  virtual bool draw_lines(const GeomPrimitivePipelineReader *reader,
118  bool force);
119  virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader,
120  bool force);
121  virtual bool draw_points(const GeomPrimitivePipelineReader *reader,
122  bool force);
123  virtual void end_draw_primitives();
124 
125  virtual bool framebuffer_copy_to_texture(Texture *tex, int view, int z,
126  const DisplayRegion *dr,
127  const RenderBuffer &rb);
128  virtual bool framebuffer_copy_to_ram(Texture *tex, int view, int z,
129  const DisplayRegion *dr,
130  const RenderBuffer &rb);
131  bool do_framebuffer_copy_to_ram(Texture *tex, int view, int z,
132  const DisplayRegion *dr,
133  const RenderBuffer &rb,
134  bool inverted);
135 
136  void reset_render_states (void);
137  virtual void reset();
138 
139  virtual void apply_fog(Fog *fog);
140 
141  virtual void bind_light(PointLight *light_obj, const NodePath &light,
142  int light_id);
143  virtual void bind_light(DirectionalLight *light_obj, const NodePath &light,
144  int light_id);
145  virtual void bind_light(Spotlight *light_obj, const NodePath &light,
146  int light_id);
147 
148  static D3DFORMAT get_index_type(Geom::NumericType numeric_type);
149  INLINE static DWORD LColor_to_D3DCOLOR(const LColor &cLColor);
150 
151  virtual void set_state_and_transform(const RenderState *state,
152  const TransformState *transform);
153 
154  bool check_dx_allocation (HRESULT result, int allocation_size, int attempts);
155 
156  INLINE HRESULT set_render_state (D3DRENDERSTATETYPE state, DWORD value);
157  INLINE HRESULT set_texture_stage_state (DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value);
158  INLINE HRESULT set_sampler_state (DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value);
159 
160  INLINE bool get_supports_render_texture() const;
161 
162  static bool get_gamma_table(void);
163  static bool static_set_gamma(bool restore, PN_stdfloat gamma);
164  bool set_gamma(PN_stdfloat gamma);
165  void restore_gamma();
166  static void atexit_function(void);
167 
168  static void set_cg_device(LPDIRECT3DDEVICE9 cg_device);
169  virtual bool get_supports_cg_profile(const std::string &name) const;
170 
171  LPDIRECT3DVERTEXBUFFER9 get_white_vbuffer();
172 
173 protected:
174  void do_issue_transform();
175  void do_issue_alpha_test();
176  void do_issue_shader();
177  void do_issue_render_mode();
178  void do_issue_rescale_normal();
179  void do_issue_color_write();
180  void do_issue_depth_test();
181  void do_issue_depth_write();
182  void do_issue_cull_face();
183  void do_issue_fog();
184  void do_issue_depth_offset();
185  void do_issue_tex_gen();
186  void do_issue_shade_model();
187  void do_issue_material();
188  void do_issue_texture();
189  void do_issue_blending();
190  void do_issue_stencil();
191  void do_issue_scissor();
192 
193  virtual void reissue_transforms();
194 
195  virtual void enable_lighting(bool enable);
196  virtual void set_ambient_light(const LColor &color);
197  virtual void enable_light(int light_id, bool enable);
198 
199  virtual void enable_clip_plane(int plane_id, bool enable);
200  virtual void bind_clip_plane(const NodePath &plane, int plane_id);
201 
202  virtual void close_gsg();
203  void free_nondx_resources();
204  void free_d3d_device();
205 
206  void set_draw_buffer(const RenderBuffer &rb);
207  void set_read_buffer(const RenderBuffer &rb);
208 
209  void disable_standard_vertex_arrays();
210  bool update_standard_vertex_arrays(bool force);
211  void disable_standard_texture_bindings();
212  void update_standard_texture_bindings();
213 
214 protected:
215  INLINE static D3DTEXTUREADDRESS get_texture_wrap_mode(SamplerState::WrapMode wm);
216  INLINE static D3DFOGMODE get_fog_mode_type(Fog::Mode m);
217  const D3DCOLORVALUE &get_light_color(Light *light) const;
218  INLINE static D3DTRANSFORMSTATETYPE get_tex_mat_sym(int stage_index);
219 
220  static D3DBLENDOP get_blend_mode(ColorBlendAttrib::Mode mode);
221  static D3DBLEND get_blend_func(ColorBlendAttrib::Operand operand);
222  void report_texmgr_stats();
223 
224  void set_context(DXScreenData *new_context);
225  void set_render_target();
226 
227  void set_texture_blend_mode(int i, const TextureStage *stage);
228 
229  void dx_cleanup();
230  HRESULT reset_d3d_device(D3DPRESENT_PARAMETERS *p_presentation_params,
231  DXScreenData **screen = nullptr);
232 
233  bool check_cooperative_level();
234 
235  void show_frame();
236 
237  bool create_swap_chain (DXScreenData *new_context);
238  bool release_swap_chain (DXScreenData *new_context);
239  void copy_pres_reset(DXScreenData *new_context);
240 
241  static D3DTEXTUREFILTERTYPE get_d3d_min_type(SamplerState::FilterType filter_type);
242  static D3DTEXTUREFILTERTYPE get_d3d_mip_type(SamplerState::FilterType filter_type);
243  static D3DTEXTUREOP get_texture_operation(TextureStage::CombineMode mode, int scale);
244  DWORD get_texture_argument(TextureStage::CombineSource source,
245  TextureStage::CombineOperand operand) const;
246  static DWORD get_texture_argument_modifier(TextureStage::CombineOperand operand);
247 
248  void draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
249  unsigned int primitive_count,
250  unsigned int first_vertex,
251  unsigned int num_vertices,
252  const unsigned char *buffer, size_t stride);
253  void draw_indexed_primitive_up(D3DPRIMITIVETYPE primitive_type,
254  unsigned int min_index, unsigned int max_index,
255  unsigned int num_primitives,
256  const unsigned char *index_data,
257  D3DFORMAT index_type,
258  const unsigned char *buffer, size_t stride);
259 
260  INLINE static unsigned char *get_safe_buffer_start();
261 
262 public:
263  DXScreenData *_screen;
264 
265 protected:
266  LPDIRECT3DDEVICE9 _d3d_device; // same as _screen->_d3d_device, cached for spd
267  IDirect3DSwapChain9 *_swap_chain;
268  D3DPRESENT_PARAMETERS _presentation_reset; // This is built during reset device
269 
270  bool _dx_is_ready;
271  HRESULT _last_testcooplevel_result;
272 
273  bool _vertex_blending_enabled;
274  bool _supports_render_texture;
275 
276  RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation
277 
278  enum DxgsgFogType {
279  None,
280  PerVertexFog=D3DRS_FOGVERTEXMODE,
281  PerPixelFog=D3DRS_FOGTABLEMODE
282  };
283  DxgsgFogType _do_fog_type;
284 
285  D3DVIEWPORT9 _current_viewport;
286  bool _supports_depth_bias;
287 
288  DWORD _clip_plane_bits;
289  CullFaceAttrib::Mode _cull_face_mode;
290  RenderModeAttrib::Mode _current_fill_mode; //point/wireframe/solid
291 
292  PT(Shader) _current_shader;
293  DXShaderContext9 *_current_shader_context;
294  PT(Shader) _vertex_array_shader;
295  DXShaderContext9 *_vertex_array_shader_context;
296  PT(Shader) _texture_binding_shader;
297  DXShaderContext9 *_texture_binding_shader_context;
298 
299  const DXIndexBufferContext9 *_active_ibuffer;
300 
301  bool _overlay_windows_supported;
302  bool _tex_stats_retrieval_impossible;
303  bool _supports_texture_constant_color;
304  DWORD _constant_color_operand;
305 
306  static D3DMATRIX _d3d_ident_mat;
307 
308  static unsigned char *_temp_buffer;
309  static unsigned char *_safe_buffer_start;
310 
311  int _gsg_managed_textures;
312  int _gsg_managed_vertex_buffers;
313  int _gsg_managed_index_buffers;
314  UINT _available_texture_memory;
315 
316  DWORD _last_fvf;
317  int _num_bound_streams;
318  LPDIRECT3DVERTEXBUFFER9 _white_vbuffer;
319 
320  // Cache the data necessary to bind each particular light each frame, so if
321  // we bind a given light multiple times, we only have to compute its data
322  // once.
324  DirectionalLights _dlights;
325 
326  #define MAXIMUM_TEXTURES 16
327 
328 
329  // from D3DRENDERSTATETYPE + pad
330  #define MAXIMUM_RENDER_STATES 256
331 
332  // from D3DTEXTURESTAGESTATETYPE + pad
333  #define MAXIMUM_TEXTURE_STAGE_STATES 40
334  typedef struct {
335  DWORD state_array [MAXIMUM_TEXTURE_STAGE_STATES];
336  }
337  TextureStageStates;
338 
339  // from D3DSAMPLERSTATETYPE + pad
340  #define MAXIMUM_TEXTURE_RENDER_STATES 16
341  typedef struct {
342  DWORD state_array [MAXIMUM_TEXTURE_RENDER_STATES];
343  }
344  TextureRenderStates;
345 
346  // from D3DRENDERSTATETYPE
347  DWORD _render_state_array [MAXIMUM_RENDER_STATES];
348  TextureStageStates _texture_stage_states_array [D3D_MAXTEXTURESTAGES];
349  TextureRenderStates _texture_render_states_array [MAXIMUM_TEXTURES];
350 
351  int _num_active_texture_stages;
352 
353  int _vertex_shader_version_major;
354  int _vertex_shader_version_minor;
355  int _pixel_shader_version_major;
356  int _pixel_shader_version_minor;
357 
358  char *_vertex_shader_profile;
359  char *_pixel_shader_profile;
360 
361  int _vertex_shader_maximum_constants;
362 
363  bool _supports_stream_offset;
364 
365  std::list <wdxGraphicsBuffer9 **> _graphics_buffer_list;
366 
367  int _supports_gamma_calibration;
368 
369 #ifdef HAVE_CG
370  CGcontext _cg_context;
371  static LPDIRECT3DDEVICE9 _cg_device;
372 #endif
373 
374 public:
375  virtual TypeHandle get_type() const {
376  return get_class_type();
377  }
378  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
379 
380  static TypeHandle get_class_type() {
381  return _type_handle;
382  }
383 
384 public:
385  static void init_type() {
386  GraphicsStateGuardian::init_type();
387  register_type(_type_handle, "DXGraphicsStateGuardian9",
388  GraphicsStateGuardian::get_class_type());
389  }
390 
391 private:
392  static TypeHandle _type_handle;
393 
394  friend class wdxGraphicsWindow9;
395  friend class wdxGraphicsPipe9;
396  friend class wdxGraphicsWindowGroup9;
397  friend class DXTextureContext9;
398  friend class wdxGraphicsBuffer9;
399  friend class DXVertexBufferContext9;
400  friend class DXIndexBufferContext9;
401  friend class DXShaderContext9;
402 };
403 
405 
406 #endif
A GraphicsStateGuardian for rendering into DirectX9 contexts.
A light shining from infinitely far away in a particular direction, like sunlight.
The abstract interface to all kinds of lights.
Definition: light.h:38
virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected points.
virtual bool framebuffer_copy_to_ram(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into system memory,...
virtual void end_frame(Thread *current_thread)
Called after each frame is rendered, to allow the GSG a chance to do any internal cleanup after rende...
Encapsulates the data from a DisplayRegion, pre-fetched for one stage of the pipeline.
Indicates a coordinate-system transform on vertices.
virtual void release_shader(ShaderContext *sc)
Releases the resources allocated by prepare_shader.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a base class for GraphicsWindow (actually, GraphicsOutput) and DisplayRegion,...
virtual void release_index_buffer(IndexBufferContext *ibc)
Frees the resources previously allocated via a call to prepare_data(), including deleting the IndexBu...
virtual void clear(DrawableRegion *clearable)
Clears the framebuffer within the current DisplayRegion, according to the flags indicated by the give...
A base class for any number of different kinds of lenses, linear and otherwise.
Definition: lens.h:41
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool update_texture(TextureContext *tc, bool force)
Ensures that the current Texture data is refreshed onto the GSG.
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Makes the specified DisplayRegion current.
virtual void end_draw_primitives()
Called after a sequence of draw_primitive() functions are called, this should do whatever cleanup is ...
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
Definition: geomMunger.h:50
This is a special class object that holds all the information returned by a particular GSG to indicat...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:71
Caches a GeomVertexArrayData in the DirectX device as a vertex buffer.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition: register_type.I:22
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:56
Definition: shader.h:49
This is a special class object that holds all the information returned by a particular GSG to indicat...
virtual void restore_gamma()
Restore original gamma setting.
Caches a GeomPrimitive in the DirectX device as an index buffer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void release_vertex_buffer(VertexBufferContext *vbc)
Frees the resources previously allocated via a call to prepare_data(), including deleting the VertexB...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
Definition: geom.h:405
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The ShaderContext is meant to contain the compiled version of a shader string.
Definition: shaderContext.h:31
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomVertexDataPipelineReader *data_reader, bool force)
Called before a sequence of draw_primitive() functions are called, this should prepare the vertex dat...
virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle strips.
virtual void set_state_and_transform(const RenderState *state, const TransformState *transform)
Simultaneously resets the render state and the transform state.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An offscreen render buffer.
Specifies how atmospheric fog effects are applied to geometry.
Definition: fog.h:41
An object to create GraphicsOutputs that share a particular 3-D API.
Definition: graphicsPipe.h:52
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected triangles.
virtual void begin_occlusion_query()
Begins a new occlusion query.
virtual void release_texture(TextureContext *tc)
Frees the resources previously allocated via a call to prepare_texture(), including deleting the Text...
virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected line segments.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A light originating from a single point in space, and shining in a particular direction,...
Definition: spotlight.h:32
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual ShaderContext * prepare_shader(Shader *shader)
Compile a vertex/fragment shader body.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
Represents a set of settings that indicate how a texture is sampled.
Definition: samplerState.h:36
A single graphics window for rendering DirectX under Microsoft Windows.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle fans.
A thread; that is, a lightweight process.
Definition: thread.h:46
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a special class object that holds all the information returned by a particular GSG to indicat...
Encapsulates all the communication with a particular instance of a given rendering backend.
virtual void end_scene()
Called between begin_frame() and end_frame() to mark the end of drawing commands for a "scene" (usual...
virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of line strips.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual VertexBufferContext * prepare_vertex_buffer(GeomVertexArrayData *data)
Prepares the indicated buffer for retained-mode rendering.
A rectangular subregion within a window for rendering into.
Definition: displayRegion.h:57
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
This graphics pipe represents the interface for creating DirectX9 graphics windows.
virtual bool get_supports_cg_profile(const std::string &name) const
Returns true if this particular GSG supports the specified Cg Shader Profile.
Returned from a GSG in response to begin_occlusion_query() .
This class is the main interface to controlling the render process.
virtual void reset()
Resets all internal state as if the gsg were newly created.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool framebuffer_copy_to_texture(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into texture memory.
virtual bool begin_frame(Thread *current_thread)
Called before each frame is rendered, to allow the GSG a chance to do any internal cleanup before beg...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
virtual IndexBufferContext * prepare_index_buffer(GeomPrimitive *data)
Prepares the indicated buffer for retained-mode rendering.
virtual TextureContext * prepare_texture(Texture *tex, int view)
Creates whatever structures the GSG requires to represent the texture internally, and returns a newly...
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
virtual bool prepare_lens()
Makes the current lens (whichever lens was most recently specified with set_scene()) active,...
Defines the properties of a named stage of the multitexture pipeline.
Definition: textureStage.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer,...
Definition: renderBuffer.h:27
virtual bool extract_texture_data(Texture *tex)
This method should only be called by the GraphicsEngine.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
A light originating from a single point in space, and shining in all directions.
Definition: pointLight.h:25
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the data for one array of a GeomVertexData structure.
virtual bool begin_scene()
Called between begin_frame() and end_frame() to mark the beginning of drawing commands for a "scene" ...
virtual void bind_light(PointLight *light_obj, const NodePath &light, int light_id)
Called the first time a particular light has been bound to a given id within a frame,...