Panda3D
 All Classes Functions Variables Enumerations
wglGraphicsBuffer.cxx
1 // Filename: wglGraphicsBuffer.cxx
2 // Created by: drose (08Feb04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "wglGraphicsBuffer.h"
16 #include "wglGraphicsPipe.h"
17 #include "config_wgldisplay.h"
18 #include "glgsg.h"
19 #include "pStatTimer.h"
20 
21 #include <wingdi.h>
22 
23 TypeHandle wglGraphicsBuffer::_type_handle;
24 
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: wglGraphicsBuffer::Constructor
28 // Access: Public
29 // Description:
30 ////////////////////////////////////////////////////////////////////
31 wglGraphicsBuffer::
32 wglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
33  const string &name,
34  const FrameBufferProperties &fb_prop,
35  const WindowProperties &win_prop,
36  int flags,
38  GraphicsOutput *host) :
39  GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
40 {
41  _pbuffer = (HPBUFFERARB)0;
42  _pbuffer_dc = (HDC)0;
43  release_pbuffer();
44 
45  // Since the pbuffer never gets flipped, we get screenshots from the
46  // same buffer we draw into.
47  _screenshot_buffer_type = _draw_buffer_type;
48 }
49 
50 ////////////////////////////////////////////////////////////////////
51 // Function: wglGraphicsBuffer::Destructor
52 // Access: Public, Virtual
53 // Description:
54 ////////////////////////////////////////////////////////////////////
55 wglGraphicsBuffer::
56 ~wglGraphicsBuffer() {
57 }
58 
59 ////////////////////////////////////////////////////////////////////
60 // Function: wglGraphicsBuffer::begin_frame
61 // Access: Public, Virtual
62 // Description: This function will be called within the draw thread
63 // before beginning rendering for a given frame. It
64 // should do whatever setup is required, and return true
65 // if the frame should be rendered, or false if it
66 // should be skipped.
67 ////////////////////////////////////////////////////////////////////
69 begin_frame(FrameMode mode, Thread *current_thread) {
70 
71  begin_frame_spam(mode);
72  if (_gsg == (GraphicsStateGuardian *)NULL) {
73  return false;
74  }
75 
77  DCAST_INTO_R(wglgsg, _gsg, false);
78 
79  HGLRC context = wglgsg->get_context(_pbuffer_dc);
80  if (context == 0) {
81  return false;
82  }
83 
84  if (_fb_properties.is_single_buffered()) {
85  wglgsg->_wglReleaseTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB);
86  } else {
87  wglgsg->_wglReleaseTexImageARB(_pbuffer, WGL_BACK_LEFT_ARB);
88  }
89 
90  if (!rebuild_bitplanes()) {
91  wglGraphicsPipe::wgl_make_current(0, 0, &_make_current_pcollector);
92  return false;
93  }
94 
95  wglGraphicsPipe::wgl_make_current(_pbuffer_dc, context,
96  &_make_current_pcollector);
97 
98  if (mode == FM_render) {
99  CDLockedReader cdata(_cycler);
100  for (size_t i = 0; i != cdata->_textures.size(); ++i) {
101  const RenderTexture &rt = cdata->_textures[i];
102  RenderTextureMode rtm_mode = rt._rtm_mode;
103  RenderTexturePlane plane = rt._plane;
104  if (rtm_mode == RTM_bind_or_copy && plane != RTP_color) {
105  CDWriter cdataw(_cycler, cdata, false);
106  nassertr(cdata->_textures.size() == cdataw->_textures.size(), false);
107  cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
108  }
109  }
110  clear_cube_map_selection();
111  }
112 
113  _gsg->set_current_properties(&get_fb_properties());
114  return _gsg->begin_frame(current_thread);
115 }
116 
117 ////////////////////////////////////////////////////////////////////
118 // Function: wglGraphicsBuffer::end_frame
119 // Access: Public, Virtual
120 // Description: This function will be called within the draw thread
121 // after rendering is completed for a given frame. It
122 // should do whatever finalization is required.
123 ////////////////////////////////////////////////////////////////////
125 end_frame(FrameMode mode, Thread *current_thread) {
126  end_frame_spam(mode);
127  nassertv(_gsg != (GraphicsStateGuardian *)NULL);
128 
129  if (mode == FM_render) {
130  copy_to_textures();
131  bind_texture_to_pbuffer();
132  }
133 
134  _gsg->end_frame(current_thread);
135 
136  if (mode == FM_render) {
137  trigger_flip();
138  clear_cube_map_selection();
139  }
140 }
141 
142 ////////////////////////////////////////////////////////////////////
143 // Function: GraphicsOutput::bind_texture_to_pbuffer
144 // Access: Private
145 // Description: Looks for the appropriate texture,
146 // and binds that texture to the pbuffer.
147 ////////////////////////////////////////////////////////////////////
148 void wglGraphicsBuffer::
149 bind_texture_to_pbuffer() {
150  wglGraphicsStateGuardian *wglgsg;
151  DCAST_INTO_V(wglgsg, _gsg);
152 
153  // Find the color texture, if there is one. That one can be bound to
154  // the framebuffer. All others must be marked RTM_copy_to_texture.
155 
156  int tex_index = -1;
157  CDLockedReader cdata(_cycler);
158  for (size_t i = 0; i != cdata->_textures.size(); ++i) {
159  const RenderTexture &rt = cdata->_textures[i];
160  RenderTexturePlane plane = rt._plane;
161  if (plane == RTP_color) {
162  tex_index = i;
163  break;
164  }
165  }
166 
167  if (tex_index >= 0) {
168  const RenderTexture &rt = cdata->_textures[tex_index];
169  Texture *tex = rt._texture;
170  if ((_pbuffer_bound != 0)&&(_pbuffer_bound != tex)) {
171  _pbuffer_bound->release(wglgsg->get_prepared_objects());
172  _pbuffer_bound = 0;
173  }
175 
176  if (tex->get_match_framebuffer_format()) {
177  if (_fb_properties.get_alpha_bits()) {
178  tex->set_format(Texture::F_rgba);
179  } else {
180  tex->set_format(Texture::F_rgb);
181  }
182  }
183  TextureContext *tc = tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg);
184  nassertv(tc != (TextureContext *)NULL);
185  CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
186  GLenum target = wglgsg->get_texture_target(tex->get_texture_type());
187  if (target == GL_NONE) {
188  CDWriter cdataw(_cycler, cdata, false);
189  nassertv(cdata->_textures.size() == cdataw->_textures.size());
190  cdataw->_textures[tex_index]._rtm_mode = RTM_copy_texture;
191  return;
192  }
193  GLP(BindTexture)(target, gtc->_index);
194  if (_fb_properties.is_single_buffered()) {
195  wglgsg->_wglBindTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB);
196  } else {
197  wglgsg->_wglBindTexImageARB(_pbuffer, WGL_BACK_LEFT_ARB);
198  }
199  _pbuffer_bound = tex;
200  } else {
201  if (_pbuffer_bound != 0) {
202  _pbuffer_bound->release(wglgsg->get_prepared_objects());
203  _pbuffer_bound = 0;
204  }
205  }
206 }
207 
208 ////////////////////////////////////////////////////////////////////
209 // Function: wglGraphicsBuffer::select_target_tex_page
210 // Access: Public, Virtual
211 // Description: Called internally when the window is in
212 // render-to-a-texture mode and we are in the process of
213 // rendering the six faces of a cube map. This should
214 // do whatever needs to be done to switch the buffer to
215 // the indicated face.
216 ////////////////////////////////////////////////////////////////////
219  wglGraphicsStateGuardian *wglgsg;
220  DCAST_INTO_V(wglgsg, _gsg);
221 
222  nassertv(wglgsg->_wglSetPbufferAttribARB != NULL);
223 
224  static const int max_attrib_list = 64;
225  int iattrib_list[max_attrib_list];
226  int ni = 0;
227 
228  iattrib_list[ni++] = WGL_CUBE_MAP_FACE_ARB;
229  iattrib_list[ni++] = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + page;
230 
231  // Terminate the list.
232  nassertv(ni <= max_attrib_list);
233  iattrib_list[ni] = 0;
234 
235  wglgsg->_wglSetPbufferAttribARB(_pbuffer, iattrib_list);
236 }
237 
238 ////////////////////////////////////////////////////////////////////
239 // Function: wglGraphicsBuffer::process_events
240 // Access: Public, Virtual
241 // Description: Do whatever processing is necessary to ensure that
242 // the window responds to user events. Also, honor any
243 // requests recently made via request_properties()
244 //
245 // This function is called only within the window
246 // thread.
247 ////////////////////////////////////////////////////////////////////
251 
252  MSG msg;
253 
254  // Handle all the messages on the queue in a row. Some of these
255  // might be for another window, but they will get dispatched
256  // appropriately.
257  while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
258  process_1_event();
259  }
260 }
261 
262 ////////////////////////////////////////////////////////////////////
263 // Function: wglGraphicsBuffer::get_supports_render_texture
264 // Access: Published, Virtual
265 // Description: Returns true if this particular GraphicsOutput can
266 // render directly into a texture, or false if it must
267 // always copy-to-texture at the end of each frame to
268 // achieve this effect.
269 ////////////////////////////////////////////////////////////////////
272  if (_gsg == (GraphicsStateGuardian *)NULL) {
273  return false;
274  }
275 
276  wglGraphicsStateGuardian *wglgsg;
277  DCAST_INTO_R(wglgsg, _gsg, false);
278  return wglgsg->get_supports_wgl_render_texture();
279 }
280 
281 ////////////////////////////////////////////////////////////////////
282 // Function: wglGraphicsBuffer::close_buffer
283 // Access: Protected, Virtual
284 // Description: Closes the buffer right now. Called from the window
285 // thread.
286 ////////////////////////////////////////////////////////////////////
287 void wglGraphicsBuffer::
288 close_buffer() {
289  if (_gsg != (GraphicsStateGuardian *)NULL) {
290  wglGraphicsStateGuardian *wglgsg;
291  DCAST_INTO_V(wglgsg, _gsg);
292 
293  _gsg.clear();
294  }
295 
296  release_pbuffer();
297 
298  _is_valid = false;
299 }
300 
301 ////////////////////////////////////////////////////////////////////
302 // Function: wglGraphicsBuffer::open_buffer
303 // Access: Protected, Virtual
304 // Description: Opens the window right now. Called from the window
305 // thread. Returns true if the window is successfully
306 // opened, or false if there was a problem.
307 ////////////////////////////////////////////////////////////////////
308 bool wglGraphicsBuffer::
309 open_buffer() {
310 
311  // pbuffers don't seem to work correctly in double-buffered
312  // mode. Besides, the back buffer is a pointless waste of space.
313  // So always use a single-buffered gsg.
314 
315  _fb_properties.set_back_buffers(0);
316  _draw_buffer_type = RenderBuffer::T_front;
317  _screenshot_buffer_type = RenderBuffer::T_front;
318 
319  // GSG creation/initialization.
320 
321  wglGraphicsStateGuardian *wglgsg;
322  if (_gsg == 0) {
323  // There is no old gsg. Create a new one.
324  wglgsg = new wglGraphicsStateGuardian(_engine, _pipe, NULL);
325  wglgsg->choose_pixel_format(_fb_properties, true);
326  _gsg = wglgsg;
327  } else {
328  // If the old gsg has the wrong pixel format, create a
329  // new one that shares with the old gsg.
330  DCAST_INTO_R(wglgsg, _gsg, false);
331  if ((!wglgsg->get_fb_properties().subsumes(_fb_properties))||
332  (!wglgsg->get_fb_properties().is_single_buffered())||
333  (!wglgsg->pfnum_supports_pbuffer())) {
334  wglgsg = new wglGraphicsStateGuardian(_engine, _pipe, wglgsg);
335  wglgsg->choose_pixel_format(_fb_properties, true);
336  _gsg = wglgsg;
337  }
338  }
339 
340  // Use the temp window to initialize the gsg.
341 
342  HDC twindow_dc = wglgsg->get_twindow_dc();
343  if (twindow_dc == 0) {
344  // If we couldn't make a window, we can't get a GL context.
345  _gsg = NULL;
346  return false;
347  }
348  HGLRC context = wglgsg->get_context(twindow_dc);
349  if (context == 0) {
350  _gsg = NULL;
351  return false;
352  }
353  wglGraphicsPipe::wgl_make_current(twindow_dc, context,
354  &_make_current_pcollector);
355  wglgsg->reset_if_new();
356  wglgsg->report_my_gl_errors();
358  (_fb_properties,wglgsg->get_gl_renderer())) {
359  _gsg = NULL;
360  return false;
361  }
362  _fb_properties = wglgsg->get_fb_properties();
363 
364  // Now that we have fully made a window and used that window to
365  // create a rendering context, we can attempt to create a pbuffer.
366  // This might fail if the pbuffer extensions are not supported.
367 
368  if (!rebuild_bitplanes()) {
369  wglGraphicsPipe::wgl_make_current(0, 0, &_make_current_pcollector);
370  _gsg = NULL;
371  return false;
372  }
373 
374  _is_valid = true;
375 
376  return true;
377 }
378 
379 ////////////////////////////////////////////////////////////////////
380 // Function: wglGraphicsBuffer::release_pbuffer
381 // Access: Private
382 // Description: Destroys the pbuffer if it has been created. The
383 // intent is that this may allow it to be recreated
384 // with different options.
385 ////////////////////////////////////////////////////////////////////
386 void wglGraphicsBuffer::
387 release_pbuffer() {
388  if (_gsg == 0) {
389  return;
390  }
391 
392  wglGraphicsStateGuardian *wglgsg;
393  DCAST_INTO_V(wglgsg, _gsg);
394 
395  if (_pbuffer_bound != 0) {
396  _pbuffer_bound->release(wglgsg->get_prepared_objects());
397  _pbuffer_bound = 0;
398  }
399  wglGraphicsPipe::wgl_make_current(0, 0, NULL);
400  if (_pbuffer_dc) {
401  wglgsg->_wglReleasePbufferDCARB(_pbuffer, _pbuffer_dc);
402  }
403  if (_pbuffer) {
404  wglgsg->_wglDestroyPbufferARB(_pbuffer);
405  }
406  _pbuffer = (HPBUFFERARB)0;
407  _pbuffer_dc = (HDC)0;
408  _pbuffer_mipmap = false;
409  _pbuffer_sizex = 0;
410  _pbuffer_sizey = 0;
411  _pbuffer_type = Texture::TT_2d_texture;
412 }
413 
414 ////////////////////////////////////////////////////////////////////
415 // Function: wglGraphicsBuffer::rebuild_bitplanes
416 // Access: Private
417 // Description: Once the GL context has been fully realized, attempts
418 // to create an offscreen pbuffer if the graphics API
419 // supports it. Returns true if successful, false on
420 // failure.
421 ////////////////////////////////////////////////////////////////////
422 bool wglGraphicsBuffer::
423 rebuild_bitplanes() {
424  wglGraphicsStateGuardian *wglgsg;
425  DCAST_INTO_R(wglgsg, _gsg, false);
426 
427  if (!wglgsg->_supports_pbuffer) {
428  wgldisplay_cat.info()
429  << "PBuffers not supported by GL implementation.\n";
430  return false;
431  }
432 
433  // Find the texture to bind to the color buffer.
434  Texture *bindtexture = NULL;
435  for (int i=0; i<count_textures(); i++) {
436  if ((get_rtm_mode(i) == RTM_bind_or_copy)&&
437  (get_texture(i)->get_format() != Texture::F_depth_stencil)) {
438  bindtexture = get_texture(i);
439  break;
440  }
441  }
442 
443  // If we already have a pbuffer, and if it's lost, then
444  // force the rebuild.
445 
446  if (_pbuffer_dc) {
447  int flag = 0;
448  wglgsg->_wglQueryPbufferARB(_pbuffer, WGL_PBUFFER_LOST_ARB, &flag);
449  if (flag != 0) {
450  release_pbuffer();
451  }
452  }
453 
454  // Determine what pbuffer attributes are needed
455  // for currently-applicable textures.
456 
457  if ((_host != 0)&&(_creation_flags & GraphicsPipe::BF_size_track_host)) {
458  if (_host->get_size() != _size) {
459  set_size_and_recalc(_host->get_x_size(),
460  _host->get_y_size());
461  }
462  }
463  int desired_x = get_x_size();
464  int desired_y = get_y_size();
465  if ((bindtexture != 0)&&(Texture::get_textures_power_2() != ATS_none)) {
466  desired_x = Texture::up_to_power_2(desired_x);
467  desired_y = Texture::up_to_power_2(desired_y);
468  }
469  bool desired_mipmap = false;
470  Texture::TextureType desired_type = Texture::TT_2d_texture;
471  if (bindtexture != 0) {
472  desired_mipmap = bindtexture->uses_mipmaps();
473  desired_type = bindtexture->get_texture_type();
474  }
475 
476  if ((_pbuffer != 0)&&
477  (_pbuffer_sizex == desired_x)&&
478  (_pbuffer_sizey == desired_y)&&
479  (_pbuffer_mipmap == desired_mipmap)&&
480  (_pbuffer_type == desired_type)) {
481  // the pbuffer we already have is fine. Do not rebuild.
482  return true;
483  }
484 
485  // Release the old pbuffer, if there was one.
486 
487  release_pbuffer();
488 
489  // Allocate the new pbuffer.
490 
491  int pfnum = wglgsg->get_pfnum();
492 
493  static const int max_attrib_list = 64;
494  int iattrib_list[max_attrib_list];
495  int ni = 0;
496 
497  if (_fb_properties.get_alpha_bits()) {
498  iattrib_list[ni++] = WGL_TEXTURE_FORMAT_ARB;
499  iattrib_list[ni++] = WGL_TEXTURE_RGBA_ARB;
500  } else {
501  iattrib_list[ni++] = WGL_TEXTURE_FORMAT_ARB;
502  iattrib_list[ni++] = WGL_TEXTURE_RGB_ARB;
503  }
504 
505  if (desired_mipmap) {
506  iattrib_list[ni++] = WGL_MIPMAP_TEXTURE_ARB;
507  iattrib_list[ni++] = 1;
508  }
509 
510  switch (desired_type) {
511  case Texture::TT_cube_map:
512  iattrib_list[ni++] = WGL_TEXTURE_TARGET_ARB;
513  iattrib_list[ni++] = WGL_TEXTURE_CUBE_MAP_ARB;
514  break;
515 
516  case Texture::TT_1d_texture:
517  iattrib_list[ni++] = WGL_TEXTURE_TARGET_ARB;
518  iattrib_list[ni++] = WGL_TEXTURE_1D_ARB;
519  break;
520 
521  default:
522  iattrib_list[ni++] = WGL_TEXTURE_TARGET_ARB;
523  iattrib_list[ni++] = WGL_TEXTURE_2D_ARB;
524  }
525 
526  // Terminate the list.
527  nassertr(ni <= max_attrib_list, false);
528  iattrib_list[ni] = 0;
529 
530  HDC twindow_dc = wglgsg->get_twindow_dc();
531  if (twindow_dc == 0) {
532  return false;
533  }
534 
535  HGLRC context = wglgsg->get_context(twindow_dc);
536  if (context == 0) {
537  return false;
538  }
539  wglGraphicsPipe::wgl_make_current(twindow_dc, context,
540  &_make_current_pcollector);
541 
542  _pbuffer = wglgsg->_wglCreatePbufferARB(twindow_dc, pfnum,
543  desired_x, desired_y, iattrib_list);
544 
545  if (_pbuffer == 0) {
546  wgldisplay_cat.info()
547  << "Attempt to create pbuffer failed.\n";
548  return false;
549  }
550 
551  _pbuffer_dc = wglgsg->_wglGetPbufferDCARB(_pbuffer);
552  _pbuffer_mipmap = desired_mipmap;
553  _pbuffer_type = desired_type;
554  _pbuffer_sizex = desired_x;
555  _pbuffer_sizey = desired_y;
556 
557  return true;
558 }
559 
560 ////////////////////////////////////////////////////////////////////
561 // Function: wglGraphicsBuffer::process_1_event
562 // Access: Private, Static
563 // Description: Handles one event from the message queue.
564 ////////////////////////////////////////////////////////////////////
565 void wglGraphicsBuffer::
566 process_1_event() {
567  MSG msg;
568 
569  if (!GetMessage(&msg, NULL, 0, 0)) {
570  // WM_QUIT received. We need a cleaner way to deal with this.
571  // DestroyAllWindows(false);
572  exit(msg.wParam); // this will invoke AtExitFn
573  }
574 
575  // Translate virtual key messages
576  TranslateMessage(&msg);
577  // Call window_proc
578  DispatchMessage(&msg);
579 }
580 
581 
Format get_format() const
Returns the format of the texture, which represents both the semantic meaning of the texels and...
Definition: texture.I:872
virtual bool begin_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread before beginning rendering for a given frame...
HDC get_twindow_dc()
Returns the DC associated with the temporary, invisible window that was created with the gsg to query...
void set_size_and_recalc(int x, int y)
Changes the x_size and y_size, then recalculates structures that depend on size.
virtual Texture * get_texture(int i=0) const
Returns the nth texture into which the GraphicsOutput renders.
virtual void end_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread after rendering is completed for a given frame...
bool pfnum_supports_pbuffer() const
Returns true if the gsg&#39;s pixel format is capable of supporting a pbuffer.
bool get_supports_wgl_render_texture() const
Returns true if this particular GSG can render from a wglGraphicsBuffer directly into a texture...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:75
void set_format(Format format)
Changes the format value for the texture components.
Definition: texture.I:2440
const FrameBufferProperties & get_fb_properties() const
Returns the properties of the pixel format that was chosen for this gsg.
This is a special class object that holds all the information returned by a particular GSG to indicat...
bool get_match_framebuffer_format() const
Returns true if the special flag was set that indicates to the GSG that the Texture&#39;s format should b...
Definition: texture.I:2522
int get_y_size() const
Returns the visible height of the window or buffer, if it is known.
virtual bool get_supports_render_texture() const
Returns true if this particular GraphicsOutput can render directly into a texture, or false if it must always copy-to-texture at the end of each frame to achieve this effect.
bool subsumes(const FrameBufferProperties &other) const
Returns true if this set of properties makes strictly greater or equal demands of the framebuffer tha...
bool uses_mipmaps() const
Returns true if the minfilter settings on this texture indicate the use of mipmapping, false otherwise.
Definition: texture.I:1319
A tiny specialization on GLGraphicsStateGuardian to add some wgl-specific information.
bool verify_hardware_software(const FrameBufferProperties &props, const string &renderer) const
Validates that the properties represent the desired kind of renderer (hardware or software)...
int get_pfnum() const
Returns the pixel format number chosen for windows that use this context.
bool release(PreparedGraphicsObjects *prepared_objects)
Frees the texture context only on the indicated object, if it exists there.
Definition: texture.cxx:1438
virtual void process_events()
Honor any requests recently made via request_open() or request_close().
void set_size_padded(int x=1, int y=1, int z=1)
Changes the size of the texture, padding if necessary, and setting the pad region as well...
Definition: texture.cxx:1752
static AutoTextureScale get_textures_power_2()
This flag returns ATS_none, ATS_up, or ATS_down and controls the scaling of textures in general...
Definition: texture.I:2232
A container for the various kinds of properties we might ask to have on a graphics window before we o...
An offscreen buffer for rendering into.
HGLRC get_context(HDC hdc)
Returns the GL context associated with the GSG.
void choose_pixel_format(const FrameBufferProperties &properties, bool need_pbuffer)
Selects a pixel format for all the windows and buffers that use this gsg.
virtual void process_events()
Do whatever processing is necessary to ensure that the window responds to user events.
An object to create GraphicsOutputs that share a particular 3-D API.
Definition: graphicsPipe.h:58
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
RenderTextureMode get_rtm_mode(int i=0) const
Returns the RenderTextureMode associated with the nth render-texture.
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
Definition: texture.I:859
This is a base class for the various different classes that represent the result of a frame of render...
TextureContext * prepare_now(int view, PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the texture on the particular GSG, if it does not already exist.
Definition: texture.cxx:1808
int count_textures() const
If the GraphicsOutput is set to render into a texture, returns the number of textures that are being ...
int get_x_size() const
Returns the visible width of the window or buffer, if it is known.
static int up_to_power_2(int value)
Returns the smallest power of 2 greater than or equal to value.
Definition: texture.cxx:1838
A thread; that is, a lightweight process.
Definition: thread.h:51
Encapsulates all the communication with a particular instance of a given rendering backend...
virtual void select_target_tex_page(int page)
Called internally when the window is in render-to-a-texture mode and we are in the process of renderi...
This class is the main interface to controlling the render process.
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...