Panda3D
 All Classes Functions Variables Enumerations
osxGraphicsBuffer.cxx
1 ////////////////////////////////////////////////////////////////////
2 //
3 // PANDA 3D SOFTWARE
4 // Copyright (c) Carnegie Mellon University. All rights reserved.
5 //
6 // All use of this software is subject to the terms of the revised BSD
7 // license. You should have received a copy of this license along
8 // with this source code in a file named "LICENSE."
9 //
10 ////////////////////////////////////////////////////////////////////
11 
12 #include "osxGraphicsBuffer.h"
13 #include "osxGraphicsStateGuardian.h"
14 #include "config_osxdisplay.h"
15 #include "osxGraphicsPipe.h"
16 
17 #include "graphicsPipe.h"
18 #include "glgsg.h"
19 #include "pStatTimer.h"
20 
21 TypeHandle osxGraphicsBuffer::_type_handle;
22 
23 ////////////////////////////////////////////////////////////////////
24 // Function: osxGraphicsBuffer::Constructor
25 // Access: Public
26 // Description:
27 ////////////////////////////////////////////////////////////////////
28 osxGraphicsBuffer::
29 osxGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
30  const string &name,
31  const FrameBufferProperties &fb_prop,
32  const WindowProperties &win_prop,
33  int flags,
35  GraphicsOutput *host) :
36  GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
37 {
38  osxGraphicsPipe *osx_pipe;
39  DCAST_INTO_V(osx_pipe, _pipe);
40 
41  _pbuffer = NULL;
42 
43  // Since the pbuffer never gets flipped, we get screenshots from the
44  // same buffer we draw into.
45  _screenshot_buffer_type = _draw_buffer_type;
46 }
47 
48 ////////////////////////////////////////////////////////////////////
49 // Function: osxGraphicsBuffer::Destructor
50 // Access: Public, Virtual
51 // Description:
52 ////////////////////////////////////////////////////////////////////
53 osxGraphicsBuffer::
54 ~osxGraphicsBuffer() {
55  nassertv(_pbuffer == NULL);
56 }
57 
58 ////////////////////////////////////////////////////////////////////
59 // Function: osxGraphicsBuffer::begin_frame
60 // Access: Public, Virtual
61 // Description: This function will be called within the draw thread
62 // before beginning rendering for a given frame. It
63 // should do whatever setup is required, and return true
64 // if the frame should be rendered, or false if it
65 // should be skipped.
66 ////////////////////////////////////////////////////////////////////
68 begin_frame(FrameMode mode, Thread *current_thread) {
69  PStatTimer timer(_make_current_pcollector);
70 
71  begin_frame_spam(mode);
72  if (_gsg == (GraphicsStateGuardian *)NULL) {
73  return false;
74  }
75  nassertr(_pbuffer != NULL, false);
76 
78  DCAST_INTO_R(osxgsg, _gsg, false);
79  if (!aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0)) {
80  report_agl_error("aglSetPBuffer");
81  return false;
82  }
83 
84  if (!aglSetCurrentContext(osxgsg->get_context())) {
85  report_agl_error("aglSetCurrentContext");
86  return false;
87  }
88 
89  osxgsg->reset_if_new();
90 
91  if (mode == FM_render) {
92  CDLockedReader cdata(_cycler);
93  for (size_t i = 0; i != cdata->_textures.size(); ++i) {
94  const RenderTexture &rt = cdata->_textures[i];
95  RenderTextureMode rtm_mode = rt._rtm_mode;
96  if (rtm_mode == RTM_bind_or_copy) {
97  CDWriter cdataw(_cycler, cdata, false);
98  nassertr(cdata->_textures.size() == cdataw->_textures.size(), false);
99  cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
100  }
101  }
102  clear_cube_map_selection();
103  }
104  _gsg->set_current_properties(&get_fb_properties());
105  return _gsg->begin_frame(current_thread);
106 }
107 
108 ////////////////////////////////////////////////////////////////////
109 // Function: osxGraphicsBuffer::end_frame
110 // Access: Public, Virtual
111 // Description: This function will be called within the draw thread
112 // after rendering is completed for a given frame. It
113 // should do whatever finalization is required.
114 ////////////////////////////////////////////////////////////////////
116 end_frame(FrameMode mode, Thread *current_thread) {
117  end_frame_spam(mode);
118  nassertv(_gsg != (GraphicsStateGuardian *)NULL);
119 
120  if (mode == FM_render) {
121  copy_to_textures();
122  }
123 
124  _gsg->end_frame(current_thread);
125 
126  if (mode == FM_render) {
127  trigger_flip();
128  clear_cube_map_selection();
129  }
130 }
131 
132 ////////////////////////////////////////////////////////////////////
133 // Function: osxGraphicsBuffer::close_buffer
134 // Access: Protected, Virtual
135 // Description: Closes the buffer right now. Called from the window
136 // thread.
137 ////////////////////////////////////////////////////////////////////
138 void osxGraphicsBuffer::
139 close_buffer() {
140  if (_gsg != (GraphicsStateGuardian *)NULL) {
141  // aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0);
142  _gsg.clear();
143  }
144  if (_pbuffer != NULL) {
145  aglDestroyPBuffer(_pbuffer);
146  _pbuffer = NULL;
147  }
148  _is_valid = false;
149 }
150 
151 ////////////////////////////////////////////////////////////////////
152 // Function: osxGraphicsBuffer::open_buffer
153 // Access: Protected, Virtual
154 // Description: Opens the buffer right now. Called from the window
155 // thread. Returns true if the buffer is successfully
156 // opened, or false if there was a problem.
157 ////////////////////////////////////////////////////////////////////
158 bool osxGraphicsBuffer::
159 open_buffer() {
160  if (_gsg == 0) {
161  _gsg = new osxGraphicsStateGuardian(_engine, _pipe, NULL);
162  }
163 
164  if (_pbuffer == NULL) {
165  GLenum target = GL_TEXTURE_RECTANGLE_ARB;
166  if (_size[0] == Texture::up_to_power_2(_size[0]) &&
167  _size[1] == Texture::up_to_power_2(_size[1])) {
168  // It's a power-of-two size, so we can use GL_TEXTURE_2D as the
169  // target. Dunno, but maybe this will be more likely to work on
170  // some hardware.
171  target = GL_TEXTURE_2D;
172  }
173  if (!aglCreatePBuffer(_size.get_x(), _size.get_y(), target, GL_RGBA, 0, &_pbuffer)) {
174  report_agl_error("aglCreatePBuffer");
175  close_buffer();
176  return false;
177  }
178  }
179 
180  osxGraphicsStateGuardian *osxgsg;
181  DCAST_INTO_R(osxgsg, _gsg, false);
182 
183  OSStatus stat = osxgsg->build_gl(false, true, _fb_properties);
184  if (stat != noErr) {
185  return false;
186  }
187 
188  if (!aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0)) {
189  report_agl_error("aglSetPBuffer");
190  close_buffer();
191  return false;
192  }
193 
194  if (!aglSetCurrentContext(osxgsg->get_context())) {
195  report_agl_error("aglSetCurrentContext");
196  return false;
197  }
198 
199  osxgsg->reset_if_new();
200  if (!osxgsg->is_valid()) {
201  close_buffer();
202  return false;
203  }
204 
205  /*
206  if (!osxgsg->get_fb_properties().verify_hardware_software
207  (_fb_properties, osxgsg->get_gl_renderer())) {
208  close_buffer();
209  return false;
210  }
211  _fb_properties = osxgsg->get_fb_properties();
212  */
213 
214  _is_valid = true;
215  return true;
216 }
217 
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...
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...
This graphics pipe represents the interface for creating OpenGL graphics windows on the various OSX's...
A tiny specialization on GLGraphicsStateGuardian to add some wgl-specific information.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:34
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.
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(...
OSStatus build_gl(bool full_screen, bool pbuffer, FrameBufferProperties &fb_props)
This function will build up a context for a gsg.
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
This is a base class for the various different classes that represent the result of a frame of render...
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...
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...