Panda3D
Loading...
Searching...
No Matches
osxGraphicsBuffer.cxx
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 osxGraphicsBuffer.cxx
10 */
11
12#include "osxGraphicsBuffer.h"
14#include "config_osxdisplay.h"
15#include "osxGraphicsPipe.h"
16
17#include "graphicsPipe.h"
18#include "glgsg.h"
19#include "pStatTimer.h"
20
21TypeHandle osxGraphicsBuffer::_type_handle;
22
23/**
24 *
25 */
26osxGraphicsBuffer::
27osxGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
28 const std::string &name,
29 const FrameBufferProperties &fb_prop,
30 const WindowProperties &win_prop,
31 int flags,
33 GraphicsOutput *host) :
34 GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
35{
36 osxGraphicsPipe *osx_pipe;
37 DCAST_INTO_V(osx_pipe, _pipe);
38
39 _pbuffer = nullptr;
40
41 // Since the pbuffer never gets flipped, we get screenshots from the same
42 // buffer we draw into.
43 _screenshot_buffer_type = _draw_buffer_type;
44}
45
46/**
47 *
48 */
49osxGraphicsBuffer::
50~osxGraphicsBuffer() {
51 nassertv(_pbuffer == nullptr);
52}
53
54/**
55 * This function will be called within the draw thread before beginning
56 * rendering for a given frame. It should do whatever setup is required, and
57 * return true if the frame should be rendered, or false if it should be
58 * skipped.
59 */
61begin_frame(FrameMode mode, Thread *current_thread) {
62 PStatTimer timer(_make_current_pcollector);
63
64 begin_frame_spam(mode);
65 if (_gsg == nullptr) {
66 return false;
67 }
68 nassertr(_pbuffer != nullptr, false);
69
71 DCAST_INTO_R(osxgsg, _gsg, false);
72 if (!aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0)) {
73 report_agl_error("aglSetPBuffer");
74 return false;
75 }
76
77 if (!aglSetCurrentContext(osxgsg->get_context())) {
78 report_agl_error("aglSetCurrentContext");
79 return false;
80 }
81
82 osxgsg->reset_if_new();
83
84 if (mode == FM_render) {
85 CDLockedReader cdata(_cycler);
86 for (size_t i = 0; i != cdata->_textures.size(); ++i) {
87 const RenderTexture &rt = cdata->_textures[i];
88 RenderTextureMode rtm_mode = rt._rtm_mode;
89 if (rtm_mode == RTM_bind_or_copy) {
90 CDWriter cdataw(_cycler, cdata, false);
91 nassertr(cdata->_textures.size() == cdataw->_textures.size(), false);
92 cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
93 }
94 }
95 clear_cube_map_selection();
96 }
97 _gsg->set_current_properties(&get_fb_properties());
98 return _gsg->begin_frame(current_thread);
99}
100
101/**
102 * This function will be called within the draw thread after rendering is
103 * completed for a given frame. It should do whatever finalization is
104 * required.
105 */
107end_frame(FrameMode mode, Thread *current_thread) {
108 end_frame_spam(mode);
109 nassertv(_gsg != nullptr);
110
111 if (mode == FM_render) {
112 copy_to_textures();
113 }
114
115 _gsg->end_frame(current_thread);
116
117 if (mode == FM_render) {
118 trigger_flip();
119 clear_cube_map_selection();
120 }
121}
122
123/**
124 * Closes the buffer right now. Called from the window thread.
125 */
126void osxGraphicsBuffer::
127close_buffer() {
128 if (_gsg != nullptr) {
129 // aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0);
130 _gsg.clear();
131 }
132 if (_pbuffer != nullptr) {
133 aglDestroyPBuffer(_pbuffer);
134 _pbuffer = nullptr;
135 }
136 _is_valid = false;
137}
138
139/**
140 * Opens the buffer right now. Called from the window thread. Returns true
141 * if the buffer is successfully opened, or false if there was a problem.
142 */
143bool osxGraphicsBuffer::
144open_buffer() {
145 if (_gsg == 0) {
146 _gsg = new osxGraphicsStateGuardian(_engine, _pipe, nullptr);
147 }
148
149 if (_pbuffer == nullptr) {
150 GLenum target = GL_TEXTURE_RECTANGLE_ARB;
151 if (_size[0] == Texture::up_to_power_2(_size[0]) &&
152 _size[1] == Texture::up_to_power_2(_size[1])) {
153 // It's a power-of-two size, so we can use GL_TEXTURE_2D as the target.
154 // Dunno, but maybe this will be more likely to work on some hardware.
155 target = GL_TEXTURE_2D;
156 }
157 if (!aglCreatePBuffer(_size.get_x(), _size.get_y(), target, GL_RGBA, 0, &_pbuffer)) {
158 report_agl_error("aglCreatePBuffer");
159 close_buffer();
160 return false;
161 }
162 }
163
165 DCAST_INTO_R(osxgsg, _gsg, false);
166
167 OSStatus stat = osxgsg->build_gl(false, true, _fb_properties);
168 if (stat != noErr) {
169 return false;
170 }
171
172 if (!aglSetPBuffer(osxgsg->get_context(), _pbuffer, 0, 0, 0)) {
173 report_agl_error("aglSetPBuffer");
174 close_buffer();
175 return false;
176 }
177
178 if (!aglSetCurrentContext(osxgsg->get_context())) {
179 report_agl_error("aglSetCurrentContext");
180 return false;
181 }
182
183 osxgsg->reset_if_new();
184 if (!osxgsg->is_valid()) {
185 close_buffer();
186 return false;
187 }
188
189 /*
190 if (!osxgsg->get_fb_properties().verify_hardware_software
191 (_fb_properties, osxgsg->get_gl_renderer())) {
192 close_buffer();
193 return false;
194 }
195 _fb_properties = osxgsg->get_fb_properties();
196 */
197
198 _is_valid = true;
199 return true;
200}
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...
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
An offscreen buffer for rendering into.
This class is the main interface to controlling the render process.
This is a base class for the various different classes that represent the result of a frame of render...
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.
An object to create GraphicsOutputs that share a particular 3-D API.
Encapsulates all the communication with a particular instance of a given rendering backend.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition pStatTimer.h:30
static int up_to_power_2(int value)
Returns the smallest power of 2 greater than or equal to value.
Definition texture.cxx:2008
A thread; that is, a lightweight process.
Definition thread.h:46
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
A container for the various kinds of properties we might ask to have on a graphics window before we o...
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.
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.
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.
OSStatus build_gl(bool full_screen, bool pbuffer, FrameBufferProperties &fb_props)
This function will build up a context for a gsg.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.