*** empty log message ***
This commit is contained in:
parent
9d3d749a54
commit
6d0692fec6
|
|
@ -20,6 +20,8 @@ class BufferViewer(DirectObject):
|
|||
self.cullsort = 10000
|
||||
self.cards = []
|
||||
self.cardindex = 0
|
||||
self.cardmaker = CardMaker("cubemaker")
|
||||
self.cardmaker.setFrame(-1,1,-1,1)
|
||||
self.task = 0
|
||||
self.window = 0
|
||||
self.dirty = 1
|
||||
|
|
@ -39,7 +41,7 @@ class BufferViewer(DirectObject):
|
|||
# started.
|
||||
self.enable(self.enabled)
|
||||
|
||||
def isValidTextureSet(self, list):
|
||||
def isValidTextureSet(self, x):
|
||||
"""Access: private. Returns true if the parameter is a
|
||||
list of GraphicsOutput and Texture, or the keyword 'all'."""
|
||||
if (isinstance(x, list)):
|
||||
|
|
@ -270,10 +272,18 @@ class BufferViewer(DirectObject):
|
|||
for itex in range(win.countTextures()):
|
||||
tex = win.getTexture(itex)
|
||||
if (include.has_key(tex)) and (exclude.has_key(tex)==0):
|
||||
card = win.getTextureCard()
|
||||
card.setTexture(tex)
|
||||
cards.append(card)
|
||||
if (tex.getTextureType() == Texture.TTCubeMap):
|
||||
for face in range(6):
|
||||
self.cardmaker.setUvRangeCube(face)
|
||||
card = NodePath(self.cardmaker.generate())
|
||||
card.setTexture(tex)
|
||||
cards.append(card)
|
||||
else:
|
||||
card = win.getTextureCard()
|
||||
card.setTexture(tex)
|
||||
cards.append(card)
|
||||
wins.append(win)
|
||||
exclude[tex] = 1
|
||||
self.cards = cards
|
||||
if (len(cards)==0):
|
||||
self.task = 0
|
||||
|
|
|
|||
|
|
@ -88,3 +88,7 @@ egg-object-type-direct-widget <Scalar> collide-mask { 0x80000000 } <Collide> {
|
|||
# Define a new cull bin that will render on top of everything else.
|
||||
|
||||
cull-bin gui-popup 60 unsorted
|
||||
|
||||
# Paranoid clock. This fixes flaky hardware clocks.
|
||||
|
||||
paranoid-clock 1
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ PUBLISHED:
|
|||
INLINE bool has_mode(int bit) const;
|
||||
INLINE bool is_single_buffered() const;
|
||||
INLINE bool is_stereo() const;
|
||||
|
||||
bool subsumes(const FrameBufferProperties &prop) const;
|
||||
|
||||
INLINE void set_frame_buffer_mode(int frameBuffer_mode);
|
||||
|
|
|
|||
|
|
@ -450,7 +450,6 @@ remove_all_windows() {
|
|||
|
||||
_windows.clear();
|
||||
|
||||
_app.do_release(this);
|
||||
_app.do_close(this);
|
||||
terminate_threads();
|
||||
}
|
||||
|
|
@ -922,7 +921,6 @@ cull_and_draw_together(const GraphicsEngine::Windows &wlist) {
|
|||
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
|
||||
GraphicsOutput *win = (*wi);
|
||||
if (win->is_active() && win->get_gsg()->is_active()) {
|
||||
win->get_gsg()->set_current_properties(&win->get_fb_properties());
|
||||
if (win->begin_frame(GraphicsOutput::FM_render)) {
|
||||
win->clear();
|
||||
|
||||
|
|
@ -1088,7 +1086,6 @@ draw_bins(const GraphicsEngine::Windows &wlist) {
|
|||
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
|
||||
GraphicsOutput *win = (*wi);
|
||||
if (win->is_active() && win->get_gsg()->is_active()) {
|
||||
win->get_gsg()->set_current_properties(&win->get_fb_properties());
|
||||
if (win->begin_frame(GraphicsOutput::FM_render)) {
|
||||
win->clear();
|
||||
|
||||
|
|
@ -1149,7 +1146,6 @@ make_contexts(const GraphicsEngine::Windows &wlist) {
|
|||
Windows::const_iterator wi;
|
||||
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
|
||||
GraphicsOutput *win = (*wi);
|
||||
win->get_gsg()->set_current_properties(&win->get_fb_properties());
|
||||
if (win->begin_frame(GraphicsOutput::FM_refresh)) {
|
||||
win->end_frame(GraphicsOutput::FM_refresh);
|
||||
}
|
||||
|
|
@ -1599,27 +1595,6 @@ terminate_threads() {
|
|||
thread->_cv_mutex.lock();
|
||||
}
|
||||
|
||||
// Now tell them to release their windows' graphics contexts.
|
||||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||
RenderThread *thread = (*ti).second;
|
||||
|
||||
while (thread->_thread_state != TS_wait) {
|
||||
thread->_cv_done.wait();
|
||||
}
|
||||
thread->_thread_state = TS_do_release;
|
||||
thread->_cv_start.signal();
|
||||
thread->_cv_mutex.release();
|
||||
}
|
||||
|
||||
// Grab the mutex again to wait for the above to complete.
|
||||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||
RenderThread *thread = (*ti).second;
|
||||
thread->_cv_mutex.lock();
|
||||
while (thread->_thread_state != TS_wait) {
|
||||
thread->_cv_done.wait();
|
||||
}
|
||||
}
|
||||
|
||||
// Now tell them to close their windows and terminate.
|
||||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||
RenderThread *thread = (*ti).second;
|
||||
|
|
@ -1776,30 +1751,6 @@ remove_window(GraphicsOutput *window) {
|
|||
|
||||
Windows::iterator wi;
|
||||
|
||||
wi = _cdraw.find(ptwin);
|
||||
if (wi != _cdraw.end()) {
|
||||
// The window is on our _cdraw list, meaning its GSG operations are
|
||||
// serviced by this thread (cull and draw in the same operation).
|
||||
|
||||
// Move it to the pending release thread so we can release the GSG
|
||||
// when the thread next runs. We can't do this immediately,
|
||||
// because we might not have been called from the subthread.
|
||||
_pending_release.push_back(ptwin);
|
||||
_cdraw.erase(wi);
|
||||
}
|
||||
|
||||
wi = _draw.find(ptwin);
|
||||
if (wi != _draw.end()) {
|
||||
// The window is on our _draw list, meaning its GSG operations are
|
||||
// serviced by this thread (draw performed on this thread).
|
||||
|
||||
// Move it to the pending release thread so we can release the GSG
|
||||
// when the thread next runs. We can't do this immediately,
|
||||
// because we might not have been called from the subthread.
|
||||
_pending_release.push_back(ptwin);
|
||||
_draw.erase(wi);
|
||||
}
|
||||
|
||||
wi = _window.find(ptwin);
|
||||
if (wi != _window.end()) {
|
||||
// The window is on our _window list, meaning its open/close
|
||||
|
|
@ -1924,22 +1875,6 @@ do_flip(GraphicsEngine *engine) {
|
|||
engine->flip_windows(_draw);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::WindowRenderer::do_release
|
||||
// Access: Public
|
||||
// Description: Releases the rendering contexts for all windows on
|
||||
// the _draw list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsEngine::WindowRenderer::
|
||||
do_release(GraphicsEngine *) {
|
||||
MutexHolder holder(_wl_lock);
|
||||
Windows::iterator wi;
|
||||
for (wi = _draw.begin(); wi != _draw.end(); ++wi) {
|
||||
GraphicsOutput *win = (*wi);
|
||||
win->release_gsg();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::WindowRenderer::do_close
|
||||
// Access: Public
|
||||
|
|
@ -1982,16 +1917,6 @@ void GraphicsEngine::WindowRenderer::
|
|||
do_pending(GraphicsEngine *engine) {
|
||||
MutexHolder holder(_wl_lock);
|
||||
|
||||
if (!_pending_release.empty()) {
|
||||
// Release any GSG's that were waiting.
|
||||
Windows::iterator wi;
|
||||
for (wi = _pending_release.begin(); wi != _pending_release.end(); ++wi) {
|
||||
GraphicsOutput *win = (*wi);
|
||||
win->release_gsg();
|
||||
}
|
||||
_pending_release.clear();
|
||||
}
|
||||
|
||||
if (!_pending_close.empty()) {
|
||||
// Close any windows that were pending closure, but only if their
|
||||
// associated GSG has already been released.
|
||||
|
|
@ -2128,7 +2053,6 @@ thread_main() {
|
|||
|
||||
case TS_do_release:
|
||||
do_pending(_engine);
|
||||
do_release(_engine);
|
||||
break;
|
||||
|
||||
case TS_do_windows:
|
||||
|
|
|
|||
|
|
@ -294,7 +294,6 @@ private:
|
|||
Windows _window; // window stage, i.e. process windowing events
|
||||
|
||||
// These are not kept sorted.
|
||||
Windows _pending_release; // moved from _draw, pending release_gsg.
|
||||
Windows _pending_close; // moved from _window, pending close.
|
||||
|
||||
GSGs _gsgs; // draw stage
|
||||
|
|
|
|||
|
|
@ -106,12 +106,27 @@ get_texture(int i) const {
|
|||
return _textures[i]._texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::get_texture_plane
|
||||
// Access: Published
|
||||
// Description: Returns the RenderTexturePlane associated with the
|
||||
// nth render-texture. Returns 0 if there is no such
|
||||
// texture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GraphicsOutput::RenderTexturePlane GraphicsOutput::
|
||||
get_texture_plane(int i) const {
|
||||
if ((i < 0) || (i >= ((int)_textures.size()))) {
|
||||
return (RenderTexturePlane)0;
|
||||
}
|
||||
return _textures[i]._plane;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::get_rtm_mode
|
||||
// Access: Published
|
||||
// Description: Returns the RenderTextureMode associated with the
|
||||
// nth texture. Returns RTM_none if there is no such
|
||||
// texture.
|
||||
// nth render-texture. Returns RTM_none if there is
|
||||
// no such texture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GraphicsOutput::RenderTextureMode GraphicsOutput::
|
||||
get_rtm_mode(int i) const {
|
||||
|
|
|
|||
|
|
@ -218,23 +218,49 @@ clear_render_textures() {
|
|||
//
|
||||
// If tex is not NULL, it is the texture that will be
|
||||
// set up for rendering into; otherwise, a new Texture
|
||||
// object will be created (in which case you may call
|
||||
// get_texture() to retrieve the new texture pointer
|
||||
// later).
|
||||
// object will be created, in which case you may call
|
||||
// get_texture() to retrieve the new texture pointer.
|
||||
//
|
||||
// You can specify a bitplane to attach the texture to.
|
||||
// the legal choices are:
|
||||
//
|
||||
// * RTP_depth
|
||||
// * RTP_stencil
|
||||
// * RTP_color
|
||||
// * RTP_aux_rgba_0
|
||||
// * RTP_aux_rgba_1
|
||||
// * RTP_aux_rgba_2
|
||||
// * RTP_aux_rgba_3
|
||||
//
|
||||
// If you do not specify a bitplane to attach the
|
||||
// texture to, this routine will use a default based
|
||||
// on the texture's format:
|
||||
//
|
||||
// * F_depth_component attaches to RTP_depth
|
||||
// * F_stencil_index attaches to RTP_stencil
|
||||
// * all other formats attach to RTP_color.
|
||||
//
|
||||
// The texture's format will be changed to match
|
||||
// the format of the bitplane to which it is attached.
|
||||
// For example, if you pass in an F_rgba texture and
|
||||
// order that it be attached to RTP_depth, it will turn
|
||||
// into an F_depth_component texture.
|
||||
//
|
||||
// Also see make_texture_buffer(), which is a
|
||||
// higher-level interface for preparing
|
||||
// render-to-a-texture mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsOutput::
|
||||
add_render_texture(Texture *tex, RenderTextureMode mode) {
|
||||
add_render_texture(Texture *tex, RenderTextureMode mode,
|
||||
RenderTexturePlane plane) {
|
||||
if (mode == RTM_none) {
|
||||
return;
|
||||
}
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
throw_event("render-texture-targets-changed");
|
||||
|
||||
|
||||
// Create texture if necessary.
|
||||
if (tex == (Texture *)NULL) {
|
||||
tex = new Texture(get_name());
|
||||
tex->set_wrap_u(Texture::WM_clamp);
|
||||
|
|
@ -242,13 +268,45 @@ add_render_texture(Texture *tex, RenderTextureMode mode) {
|
|||
} else {
|
||||
tex->clear_ram_image();
|
||||
}
|
||||
tex->set_match_framebuffer_format(true);
|
||||
|
||||
// Choose a default bitplane.
|
||||
if (plane == RTP_COUNT) {
|
||||
if (tex->get_format()==Texture::F_depth_component) {
|
||||
plane = RTP_depth;
|
||||
} else if (tex->get_format()==Texture::F_stencil_index) {
|
||||
plane = RTP_stencil;
|
||||
} else {
|
||||
plane = RTP_color;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the texture's format to match the bitplane.
|
||||
// (And validate the bitplane, while we're at it).
|
||||
|
||||
if (plane == RTP_depth) {
|
||||
tex->set_format(Texture::F_depth_component);
|
||||
tex->set_match_framebuffer_format(true);
|
||||
} else if (plane == RTP_stencil) {
|
||||
tex->set_format(Texture::F_stencil_index);
|
||||
tex->set_match_framebuffer_format(true);
|
||||
} else if ((plane == RTP_color)||
|
||||
(plane == RTP_aux_rgba_0)||
|
||||
(plane == RTP_aux_rgba_1)||
|
||||
(plane == RTP_aux_rgba_2)||
|
||||
(plane == RTP_aux_rgba_3)) {
|
||||
tex->set_format(Texture::F_rgba);
|
||||
tex->set_match_framebuffer_format(true);
|
||||
} else {
|
||||
display_cat.error() <<
|
||||
"add_render_texture: invalid bitplane specified.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Go ahead and tell the texture our anticipated size, even if it
|
||||
// might be inaccurate (particularly if this is a GraphicsWindow,
|
||||
// which has system-imposed restrictions on size).
|
||||
tex->set_x_size(get_x_size());
|
||||
tex->set_y_size(get_y_size());
|
||||
tex->set_x_size(Texture::up_to_power_2(get_x_size()));
|
||||
tex->set_y_size(Texture::up_to_power_2(get_y_size()));
|
||||
|
||||
if ((mode == RTM_bind_or_copy)&&(support_render_texture==0)) {
|
||||
mode = RTM_copy_texture;
|
||||
|
|
@ -259,36 +317,15 @@ add_render_texture(Texture *tex, RenderTextureMode mode) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
RenderTexture result;
|
||||
result._texture = tex;
|
||||
result._plane = plane;
|
||||
result._rtm_mode = mode;
|
||||
_textures.push_back(result);
|
||||
|
||||
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
||||
set_inverted(_gsg->get_copy_texture_inverted());
|
||||
|
||||
// Sanity check that we don't have two textures of the same type.
|
||||
int count_stencil_textures = 0;
|
||||
int count_depth_textures = 0;
|
||||
int count_color_textures = 0;
|
||||
for (int i=0; i<count_textures(); i++) {
|
||||
Texture::Format fmt = get_texture(i)->get_format();
|
||||
if (fmt == Texture::F_depth_component) {
|
||||
count_depth_textures += 1;
|
||||
} else if (fmt == Texture::F_stencil_index) {
|
||||
count_stencil_textures += 1;
|
||||
} else {
|
||||
count_color_textures += 1;
|
||||
}
|
||||
}
|
||||
if ((count_color_textures > 1)||
|
||||
(count_depth_textures > 1)||
|
||||
(count_stencil_textures > 1)) {
|
||||
display_cat.error() <<
|
||||
"Currently, each GraphicsOutput can only render to one color texture, "
|
||||
"one depth texture, and one stencil texture at a time. RTM aborted.\n";
|
||||
clear_render_textures();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -778,21 +815,6 @@ make_cube_map(const string &name, int size, NodePath &camera_rig,
|
|||
tex->set_wrap_v(Texture::WM_clamp);
|
||||
GraphicsOutput *buffer;
|
||||
|
||||
// I'll remove this permanently in a few days.
|
||||
// if (show_buffers) {
|
||||
// // If show_buffers is true, we'd like to create a window with the
|
||||
// // six buffers spread out and all visible at once, for the user's
|
||||
// // convenience.
|
||||
// buffer = make_texture_buffer(name, size * 3, size * 2, tex, to_ram);
|
||||
// tex->set_x_size(size);
|
||||
// tex->set_y_size(size);
|
||||
//
|
||||
// } else {
|
||||
// // In the normal case, the six buffers are stacked on top of each
|
||||
// // other like pancakes.
|
||||
// buffer = make_texture_buffer(name, size, size, tex, to_ram);
|
||||
// }
|
||||
|
||||
buffer = make_texture_buffer(name, size, size, tex, to_ram);
|
||||
|
||||
// We don't need to clear the overall buffer; instead, we'll clear
|
||||
|
|
@ -811,13 +833,6 @@ make_cube_map(const string &name, int size, NodePath &camera_rig,
|
|||
camera_np.look_at(cube_faces[i]._look_at, cube_faces[i]._up);
|
||||
|
||||
DisplayRegion *dr;
|
||||
// I'll remove this permanently in a few days. - Josh
|
||||
// if (show_buffers) {
|
||||
// const ShowBuffersCubeMapRegions &r = cube_map_regions[i];
|
||||
// dr = buffer->make_display_region(r.l, r.r, r.b, r.t);
|
||||
// } else {
|
||||
// dr = buffer->make_display_region();
|
||||
// }
|
||||
dr = buffer->make_display_region();
|
||||
|
||||
dr->set_cube_map_index(i);
|
||||
|
|
@ -1093,21 +1108,6 @@ void GraphicsOutput::
|
|||
select_cube_map(int) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::release_gsg
|
||||
// Access: Public
|
||||
// Description: Releases the current GSG pointer, if it is currently
|
||||
// held, and resets the GSG to NULL. The window will be
|
||||
// permanently unable to render; this is normally called
|
||||
// only just before destroying the window. This should
|
||||
// only be called from within the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsOutput::
|
||||
release_gsg() {
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::begin_flip
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -82,6 +82,28 @@ PUBLISHED:
|
|||
RTM_triggered_copy_ram,
|
||||
};
|
||||
|
||||
// It seems awkward to have this type, and also
|
||||
// RenderBuffer::Type. However, the fact that RenderBuffer::Type
|
||||
// is a bitmask makes it awfully awkward to work with.
|
||||
enum RenderTexturePlane {
|
||||
RTP_color,
|
||||
RTP_depth,
|
||||
RTP_stencil,
|
||||
RTP_aux_rgba_0,
|
||||
RTP_aux_rgba_1,
|
||||
RTP_aux_rgba_2,
|
||||
RTP_aux_rgba_3,
|
||||
RTP_aux_hrgba_0,
|
||||
RTP_aux_hrgba_1,
|
||||
RTP_aux_hrgba_2,
|
||||
RTP_aux_hrgba_3,
|
||||
RTP_aux_float_0,
|
||||
RTP_aux_float_1,
|
||||
RTP_aux_float_2,
|
||||
RTP_aux_float_3,
|
||||
RTP_COUNT
|
||||
};
|
||||
|
||||
// There are many reasons to call begin_frame/end_frame.
|
||||
enum FrameMode {
|
||||
FM_render, // We are rendering a frame.
|
||||
|
|
@ -98,9 +120,11 @@ PUBLISHED:
|
|||
INLINE int count_textures() const;
|
||||
INLINE bool has_texture() const;
|
||||
INLINE Texture *get_texture(int i=0) const;
|
||||
INLINE RenderTexturePlane get_texture_plane(int i=0) const;
|
||||
INLINE RenderTextureMode get_rtm_mode(int i=0) const;
|
||||
void clear_render_textures();
|
||||
void add_render_texture(Texture *tex, RenderTextureMode mode);
|
||||
void add_render_texture(Texture *tex, RenderTextureMode mode,
|
||||
RenderTexturePlane bitplane=RTP_COUNT);
|
||||
void setup_render_texture(Texture *tex, bool allow_bind, bool to_ram);
|
||||
|
||||
INLINE int get_x_size() const;
|
||||
|
|
@ -200,8 +224,6 @@ public:
|
|||
void change_scenes(DisplayRegion *new_dr);
|
||||
virtual void select_cube_map(int cube_map_index);
|
||||
|
||||
virtual void release_gsg();
|
||||
|
||||
// These methods will be called within the app (main) thread.
|
||||
virtual void begin_flip();
|
||||
virtual void end_flip();
|
||||
|
|
@ -226,6 +248,7 @@ protected:
|
|||
class RenderTexture {
|
||||
public:
|
||||
PT(Texture) _texture;
|
||||
RenderTexturePlane _plane;
|
||||
RenderTextureMode _rtm_mode;
|
||||
};
|
||||
PT(GraphicsStateGuardian) _gsg;
|
||||
|
|
|
|||
|
|
@ -185,6 +185,8 @@ public:
|
|||
virtual void end_scene();
|
||||
virtual void end_frame();
|
||||
|
||||
void set_current_properties(FrameBufferProperties *properties);
|
||||
|
||||
virtual bool depth_offset_decals();
|
||||
virtual CPT(RenderState) begin_decal_base_first();
|
||||
virtual CPT(RenderState) begin_decal_nested();
|
||||
|
|
@ -244,8 +246,6 @@ protected:
|
|||
virtual void bind_clip_plane(const NodePath &plane, int plane_id);
|
||||
virtual void end_bind_clip_planes();
|
||||
|
||||
void set_current_properties(FrameBufferProperties *properties);
|
||||
|
||||
virtual void free_pointers();
|
||||
virtual void close_gsg();
|
||||
void panic_deactivate();
|
||||
|
|
|
|||
|
|
@ -38,16 +38,19 @@ public:
|
|||
T_aux_rgba_1 = 0x00000002,
|
||||
T_aux_rgba_2 = 0x00000004,
|
||||
T_aux_rgba_3 = 0x00000008,
|
||||
T_aux_rgba_ALL = 0x0000000F,
|
||||
|
||||
T_aux_hrgba_0 = 0x00000010,
|
||||
T_aux_hrgba_1 = 0x00000020,
|
||||
T_aux_hrgba_2 = 0x00000040,
|
||||
T_aux_hrgba_0 = 0x00000010, // These can't really be implemented until
|
||||
T_aux_hrgba_1 = 0x00000020, // we have support for hrgba textures.
|
||||
T_aux_hrgba_2 = 0x00000040, // I've just added the bits for the future.
|
||||
T_aux_hrgba_3 = 0x00000080,
|
||||
T_aux_hrgba_ALL = 0x000000F0,
|
||||
|
||||
T_aux_float_0 = 0x00000100,
|
||||
T_aux_float_1 = 0x00000200,
|
||||
T_aux_float_2 = 0x00000400,
|
||||
T_aux_float_0 = 0x00000100, // These can't really be implemented until
|
||||
T_aux_float_1 = 0x00000200, // we have support for float textures.
|
||||
T_aux_float_2 = 0x00000400, // I've just added the bits for the future.
|
||||
T_aux_float_3 = 0x00000800,
|
||||
T_aux_float_ALL = 0x00000F00,
|
||||
|
||||
T_aux_undef_0 = 0x00001000,
|
||||
T_aux_undef_1 = 0x00002000,
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ begin_frame(FrameMode mode) {
|
|||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame();
|
||||
}
|
||||
|
||||
|
|
@ -328,20 +329,6 @@ select_cube_map(int cube_map_index) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wdxGraphicsBuffer8::release_gsg
|
||||
// Access: Public, Virtual
|
||||
// Description: Releases the current GSG pointer, if it is currently
|
||||
// held, and resets the GSG to NULL. The window will be
|
||||
// permanently unable to render; this is normally called
|
||||
// only just before destroying the window. This should
|
||||
// only be called from within the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void wdxGraphicsBuffer8::
|
||||
release_gsg() {
|
||||
GraphicsBuffer::release_gsg();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wdxGraphicsBuffer8::process_events
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -398,6 +385,9 @@ close_buffer() {
|
|||
this -> _new_z_stencil_surface -> Release ( );
|
||||
this -> _new_z_stencil_surface = NULL;
|
||||
}
|
||||
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
|
||||
_cube_map_index = -1;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ public:
|
|||
virtual void end_frame(FrameMode mode);
|
||||
|
||||
virtual void select_cube_map(int cube_map_index);
|
||||
virtual void release_gsg();
|
||||
|
||||
virtual void process_events();
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ begin_frame(FrameMode mode) {
|
|||
if (mode == FM_render) {
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
bool return_val = _gsg->begin_frame();
|
||||
_dxgsg->set_render_target();
|
||||
return return_val;
|
||||
|
|
@ -251,6 +252,10 @@ verify_window_sizes(int numsizes, int *dimen) {
|
|||
void wdxGraphicsWindow8::
|
||||
close_window() {
|
||||
wdxdisplay8_cat.debug() << "wdx closed window\n";
|
||||
if (_gsg != (GraphicsStateGuardian*)NULL) {
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
_dxgsg->release_swap_chain(&_wcontext);
|
||||
WinGraphicsWindow::close_window();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ begin_frame(FrameMode mode) {
|
|||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame();
|
||||
}
|
||||
|
||||
|
|
@ -364,20 +365,6 @@ select_cube_map(int cube_map_index) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wdxGraphicsBuffer9::release_gsg
|
||||
// Access: Public, Virtual
|
||||
// Description: Releases the current GSG pointer, if it is currently
|
||||
// held, and resets the GSG to NULL. The window will be
|
||||
// permanently unable to render; this is normally called
|
||||
// only just before destroying the window. This should
|
||||
// only be called from within the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void wdxGraphicsBuffer9::
|
||||
release_gsg() {
|
||||
GraphicsBuffer::release_gsg();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wdxGraphicsBuffer9::process_events
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -434,6 +421,9 @@ close_buffer() {
|
|||
this -> _new_z_stencil_surface -> Release ( );
|
||||
this -> _new_z_stencil_surface = NULL;
|
||||
}
|
||||
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
|
||||
_cube_map_index = -1;
|
||||
|
|
|
|||
|
|
@ -48,8 +48,6 @@ public:
|
|||
virtual void end_frame(FrameMode mode);
|
||||
|
||||
virtual void select_cube_map(int cube_map_index);
|
||||
virtual void release_gsg();
|
||||
|
||||
virtual void process_events();
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ begin_frame(FrameMode mode) {
|
|||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
bool return_val = _gsg->begin_frame();
|
||||
_dxgsg->set_render_target();
|
||||
return return_val;
|
||||
|
|
@ -252,6 +253,10 @@ verify_window_sizes(int numsizes, int *dimen) {
|
|||
void wdxGraphicsWindow9::
|
||||
close_window() {
|
||||
wdxdisplay9_cat.debug() << "wdx closed window\n";
|
||||
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
_dxgsg->release_swap_chain(&_wcontext);
|
||||
WinGraphicsWindow::close_window();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,17 +40,10 @@ CLP(GraphicsBuffer)(GraphicsPipe *pipe,
|
|||
_fbo = 0;
|
||||
_rb_size_x = 0;
|
||||
_rb_size_y = 0;
|
||||
for (int i=0; i<SLOT_COUNT; i++) {
|
||||
for (int i=0; i<RTP_COUNT; i++) {
|
||||
_rb[i] = 0;
|
||||
_tex[i] = 0;
|
||||
}
|
||||
_attach_point[SLOT_depth] = GL_DEPTH_ATTACHMENT_EXT;
|
||||
_attach_point[SLOT_stencil] = GL_STENCIL_ATTACHMENT_EXT;
|
||||
_attach_point[SLOT_color] = GL_COLOR_ATTACHMENT0_EXT;
|
||||
|
||||
_slot_format[SLOT_depth] = GL_DEPTH_COMPONENT;
|
||||
_slot_format[SLOT_stencil] = GL_STENCIL_INDEX;
|
||||
_slot_format[SLOT_color] = GL_RGBA;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -77,9 +70,6 @@ begin_frame(FrameMode mode) {
|
|||
return false;
|
||||
}
|
||||
|
||||
CLP(GraphicsStateGuardian) *glgsg;
|
||||
DCAST_INTO_R(glgsg, _gsg, false);
|
||||
|
||||
if (!_host->begin_frame(FM_parasite)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -88,33 +78,52 @@ begin_frame(FrameMode mode) {
|
|||
if (mode == FM_render) {
|
||||
rebuild_bitplanes();
|
||||
clear_cube_map_selection();
|
||||
|
||||
// Verify that the frame buffer is ready for rendering.
|
||||
GLenum status = glgsg->_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
|
||||
GLCAT.error() << "EXT_framebuffer_object reports non-framebuffer-completeness.\n";
|
||||
switch(status) {
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_UNSUPPORTED_EXT\n"; break;
|
||||
default:
|
||||
GLCAT.error() << "OTHER PROBLEM\n"; break;
|
||||
}
|
||||
glgsg->bind_fbo(0);
|
||||
if (!check_fbo()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glGraphicsBuffer::check_fbo
|
||||
// Access: Private
|
||||
// Description: Calls 'glCheckFramebufferStatus'. On error,
|
||||
// prints out an appropriate error message and unbinds
|
||||
// the fbo. Returns true for OK or false for error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(GraphicsBuffer)::
|
||||
check_fbo() {
|
||||
CLP(GraphicsStateGuardian) *glgsg;
|
||||
DCAST_INTO_R(glgsg, _gsg, false);
|
||||
|
||||
GLenum status = glgsg->_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
|
||||
GLCAT.error() << "EXT_framebuffer_object reports non-framebuffer-completeness.\n";
|
||||
switch(status) {
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n"; break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
GLCAT.error() << "FRAMEBUFFER_UNSUPPORTED_EXT\n"; break;
|
||||
default:
|
||||
GLCAT.error() << "OTHER PROBLEM\n"; break;
|
||||
}
|
||||
|
||||
glgsg->bind_fbo(0);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -151,26 +160,45 @@ rebuild_bitplanes() {
|
|||
_host->get_y_size());
|
||||
}
|
||||
}
|
||||
int desired_x = _x_size;
|
||||
int desired_y = _y_size;
|
||||
int bitplane_x = _x_size;
|
||||
int bitplane_y = _y_size;
|
||||
if (!glgsg->get_supports_tex_non_pow2()) {
|
||||
desired_x = Texture::up_to_power_2(desired_x);
|
||||
desired_y = Texture::up_to_power_2(desired_y);
|
||||
bitplane_x = Texture::up_to_power_2(bitplane_x);
|
||||
bitplane_y = Texture::up_to_power_2(bitplane_y);
|
||||
}
|
||||
bool rb_resize = false;
|
||||
if ((bitplane_x != _rb_size_x)||
|
||||
(bitplane_y != _rb_size_y)) {
|
||||
_rb_size_x = bitplane_x;
|
||||
_rb_size_y = bitplane_y;
|
||||
rb_resize = true;
|
||||
}
|
||||
|
||||
// Scan the textures list and determine what should be attached.
|
||||
// These variables indicate what should be bound to each bitplane.
|
||||
|
||||
Texture *attach[SLOT_COUNT];
|
||||
for (int i=0; i<SLOT_COUNT; i++) {
|
||||
attach[i] = 0;
|
||||
Texture *attach[RTP_COUNT];
|
||||
attach[RTP_color] = 0;
|
||||
attach[RTP_depth] = 0;
|
||||
attach[RTP_stencil] = 0;
|
||||
for (int i=0; i<_fb_properties.get_aux_rgba(); i++) {
|
||||
attach[RTP_aux_rgba_0+i] = 0;
|
||||
}
|
||||
for (int i=0; i<_fb_properties.get_aux_hrgba(); i++) {
|
||||
attach[RTP_aux_hrgba_0+i] = 0;
|
||||
}
|
||||
for (int i=0; i<_fb_properties.get_aux_float(); i++) {
|
||||
attach[RTP_aux_float_0+i] = 0;
|
||||
}
|
||||
|
||||
// Sort the textures list into appropriate slots.
|
||||
|
||||
for (int i=0; i<count_textures(); i++) {
|
||||
if (get_rtm_mode(i) != RTM_bind_or_copy) {
|
||||
continue;
|
||||
}
|
||||
Texture *tex = get_texture(i);
|
||||
Texture::Format fmt = tex->get_format();
|
||||
|
||||
RenderTexturePlane plane = get_texture_plane(i);
|
||||
|
||||
// If it's a not a 2D texture or a cube map, punt it.
|
||||
if ((tex->get_texture_type() != Texture::TT_2d_texture)&&
|
||||
(tex->get_texture_type() != Texture::TT_cube_map)) {
|
||||
|
|
@ -178,106 +206,123 @@ rebuild_bitplanes() {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Identify right attachment point.
|
||||
|
||||
int slot = SLOT_COUNT;
|
||||
if (fmt == Texture::F_depth_component) {
|
||||
slot = SLOT_depth;
|
||||
} else if (fmt == Texture::F_stencil_index) {
|
||||
slot = SLOT_stencil;
|
||||
} else if ((fmt == Texture::F_rgba)||(fmt == Texture::F_rgb)) {
|
||||
slot = SLOT_color;
|
||||
} else {
|
||||
_textures[i]._rtm_mode = RTM_copy_texture;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there's already a texture bound to this slot,
|
||||
// then punt this texture.
|
||||
if (attach[slot]) {
|
||||
// If I can't find an appropriate slot, or if there's
|
||||
// already a texture bound to this slot, then punt
|
||||
// this texture.
|
||||
|
||||
if (attach[plane]) {
|
||||
_textures[i]._rtm_mode = RTM_copy_texture;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Assign the texture to this slot.
|
||||
attach[slot] = tex;
|
||||
attach[plane] = tex;
|
||||
}
|
||||
|
||||
|
||||
// For all slots, update the slot.
|
||||
|
||||
for (int slot=0; slot<SLOT_COUNT; slot++) {
|
||||
if (slot == SLOT_stencil) continue;
|
||||
Texture *tex = attach[slot];
|
||||
if (tex) {
|
||||
// If the texture is already bound to the slot, and it's
|
||||
// the right size, then no update of this slot is needed.
|
||||
if ((_tex[slot] == tex)&&
|
||||
(tex->get_x_size() == desired_x)&&
|
||||
(tex->get_y_size() == desired_y)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Bind the texture to the slot.
|
||||
tex->set_x_size(desired_x);
|
||||
tex->set_y_size(desired_y);
|
||||
TextureContext *tc = tex->prepare_now(glgsg->get_prepared_objects(), glgsg);
|
||||
nassertv(tc != (TextureContext *)NULL);
|
||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
||||
|
||||
if (tex->get_texture_type() == Texture::TT_2d_texture) {
|
||||
glgsg->upload_blank_image(tex, gtc);
|
||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, _attach_point[slot],
|
||||
GL_TEXTURE_2D, gtc->_index, 0);
|
||||
} else {
|
||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, _attach_point[slot],
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, gtc->_index, 0);
|
||||
}
|
||||
_tex[slot] = tex;
|
||||
|
||||
// If there was a renderbuffer bound to this slot, delete it.
|
||||
if (_rb[slot] != 0) {
|
||||
glgsg->_glDeleteRenderbuffers(1, &(_rb[slot]));
|
||||
_rb[slot] = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// If a renderbuffer is already attached to the slot, and it's
|
||||
// the right size, then no update of this slot is needed.
|
||||
if ((_rb[slot] != 0)&&
|
||||
(_rb_size_x == desired_x)&&
|
||||
(_rb_size_y == desired_y)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there's no renderbuffer for this slot, create one.
|
||||
if (_rb[slot] == 0) {
|
||||
glgsg->_glGenRenderbuffers(1, &(_rb[slot]));
|
||||
}
|
||||
|
||||
// Resize the renderbuffer appropriately.
|
||||
glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, _rb[slot]);
|
||||
glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, _slot_format[slot],
|
||||
desired_x, desired_y);
|
||||
glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
|
||||
|
||||
// Bind the renderbuffer to the slot.
|
||||
glgsg->_glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, _attach_point[slot],
|
||||
GL_RENDERBUFFER_EXT, _rb[slot]);
|
||||
|
||||
// Toss any texture that was connected to the slot.
|
||||
_tex[slot] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// These record the size of all nonzero renderbuffers.
|
||||
_rb_size_x = desired_x;
|
||||
_rb_size_y = desired_y;
|
||||
bind_slot(rb_resize, attach, RTP_depth,
|
||||
GL_DEPTH_ATTACHMENT_EXT, GL_DEPTH_COMPONENT, Texture::F_depth_component);
|
||||
//bind_slot(rb_resize, attach, RTP_stencil,
|
||||
// GL_STENCIL_ATTACHMENT_EXT, GL_STENCIL_INDEX, Texture::F_stencil_index);
|
||||
bind_slot(rb_resize, attach, RTP_color,
|
||||
GL_COLOR_ATTACHMENT0_EXT, GL_RGBA, Texture::F_rgba);
|
||||
int next = GL_COLOR_ATTACHMENT1_EXT;
|
||||
for (int i=0; i<_fb_properties.get_aux_rgba(); i++) {
|
||||
bind_slot(rb_resize, attach, (RenderTexturePlane)(RTP_aux_rgba_0+i),
|
||||
next, GL_RGBA, Texture::F_rgba);
|
||||
next += 1;
|
||||
}
|
||||
for (int i=0; i<_fb_properties.get_aux_hrgba(); i++) {
|
||||
bind_slot(rb_resize, attach, (RenderTexturePlane)(RTP_aux_hrgba_0+i),
|
||||
next, GL_RGBA, Texture::F_rgba);
|
||||
next += 1;
|
||||
}
|
||||
for (int i=0; i<_fb_properties.get_aux_float(); i++) {
|
||||
bind_slot(rb_resize, attach, (RenderTexturePlane)(RTP_aux_float_0+i),
|
||||
next, GL_RGBA, Texture::F_rgba);
|
||||
next += 1;
|
||||
}
|
||||
|
||||
glgsg->report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glGraphicsBuffer::bind_slot
|
||||
// Access: Private
|
||||
// Description: Attaches either a texture or a renderbuffer to the
|
||||
// specified bitplane.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsBuffer)::
|
||||
bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot,
|
||||
GLenum attachpoint, GLenum texformat, Texture::Format fmt) {
|
||||
|
||||
CLP(GraphicsStateGuardian) *glgsg;
|
||||
DCAST_INTO_V(glgsg, _gsg);
|
||||
|
||||
Texture *tex = attach[slot];
|
||||
if (tex) {
|
||||
// If the texture is already bound to the slot, and it's
|
||||
// the right size, then no update of this slot is needed.
|
||||
if ((_tex[slot] == tex)&&
|
||||
(tex->get_x_size() == _rb_size_x)&&
|
||||
(tex->get_y_size() == _rb_size_y)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bind the texture to the slot.
|
||||
tex->set_x_size(_rb_size_x);
|
||||
tex->set_y_size(_rb_size_y);
|
||||
tex->set_format(fmt);
|
||||
TextureContext *tc = tex->prepare_now(glgsg->get_prepared_objects(), glgsg);
|
||||
nassertv(tc != (TextureContext *)NULL);
|
||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
||||
glgsg->apply_texture(tc);
|
||||
|
||||
if (tex->get_texture_type() == Texture::TT_2d_texture) {
|
||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachpoint,
|
||||
GL_TEXTURE_2D, gtc->_index, 0);
|
||||
} else {
|
||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachpoint,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, gtc->_index, 0);
|
||||
}
|
||||
_tex[slot] = tex;
|
||||
|
||||
// If there was a renderbuffer bound to this slot, delete it.
|
||||
if (_rb[slot] != 0) {
|
||||
glgsg->_glDeleteRenderbuffers(1, &(_rb[slot]));
|
||||
_rb[slot] = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// If a renderbuffer is already attached to the slot, and it's
|
||||
// the right size, then no update of this slot is needed.
|
||||
if ((_rb[slot] != 0)&&(!rb_resize)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there's no renderbuffer for this slot, create one.
|
||||
if (_rb[slot] == 0) {
|
||||
glgsg->_glGenRenderbuffers(1, &(_rb[slot]));
|
||||
}
|
||||
|
||||
// Resize the renderbuffer appropriately.
|
||||
glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, _rb[slot]);
|
||||
glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, texformat,
|
||||
_rb_size_x, _rb_size_y);
|
||||
glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
|
||||
|
||||
// Bind the renderbuffer to the slot.
|
||||
glgsg->_glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, attachpoint,
|
||||
GL_RENDERBUFFER_EXT, _rb[slot]);
|
||||
|
||||
// Toss any texture that was connected to the slot.
|
||||
_tex[slot] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glGraphicsBuffer::generate_mipmaps
|
||||
// Access: Private
|
||||
|
|
@ -292,7 +337,7 @@ generate_mipmaps() {
|
|||
CLP(GraphicsStateGuardian) *glgsg;
|
||||
DCAST_INTO_V(glgsg, _gsg);
|
||||
|
||||
for (int slot=0; slot<SLOT_COUNT; slot++) {
|
||||
for (int slot=0; slot<RTP_COUNT; slot++) {
|
||||
Texture *tex = _tex[slot];
|
||||
if ((tex != 0) && (tex->uses_mipmaps())) {
|
||||
glgsg->_state._texture = 0;
|
||||
|
|
@ -395,7 +440,7 @@ close_buffer() {
|
|||
DCAST_INTO_V(glgsg, _gsg);
|
||||
|
||||
// Delete the renderbuffers.
|
||||
for (int i=0; i<SLOT_COUNT; i++) {
|
||||
for (int i=0; i<RTP_COUNT; i++) {
|
||||
if (_rb[i] != 0) {
|
||||
glgsg->_glDeleteRenderbuffers(1, &(_rb[i]));
|
||||
_rb[i] = 0;
|
||||
|
|
@ -408,5 +453,9 @@ close_buffer() {
|
|||
// Delete the FBO itself.
|
||||
nassertv(_fbo != 0);
|
||||
glgsg->_glDeleteFramebuffers(1, &_fbo);
|
||||
|
||||
// Release the Gsg
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,21 +25,15 @@
|
|||
//
|
||||
// The glGraphicsBuffer is based on the OpenGL
|
||||
// EXT_framebuffer_object and ARB_draw_buffers extensions.
|
||||
// This design has three significant advantages over the
|
||||
// wglGraphicsBuffer and glxGraphicsBuffer.
|
||||
// This design has significant advantages over the
|
||||
// older wglGraphicsBuffer and glxGraphicsBuffer.
|
||||
//
|
||||
// As you might expect, this type of buffer can export
|
||||
// its color buffer as a texture. But it can also export
|
||||
// its depth buffer, its stencil buffer, and any number
|
||||
// of auxiliary buffers. This is the biggest advantage:
|
||||
// it can render to many textures at the same time.
|
||||
//
|
||||
// There is also a speed advantage. When using a
|
||||
// glGraphicsBuffer, it is not necessary to call the
|
||||
// extremely expensive wglMakeCurrent on buffer switches.
|
||||
//
|
||||
// The glGraphicsBuffer can also track the size of a host
|
||||
// window, and automatically resize itself to match.
|
||||
// * Can export depth and stencil.
|
||||
// * Supports auxiliary bitplanes.
|
||||
// * Supports non-power-of-two padding.
|
||||
// * Supports tracking of host window size.
|
||||
// * Faster than pbuffers.
|
||||
// * Can render onto a texture without clearing it first.
|
||||
//
|
||||
// If either of the necessary OpenGL extensions is not
|
||||
// available, then the glGraphicsBuffer will not be
|
||||
|
|
@ -69,24 +63,18 @@ protected:
|
|||
|
||||
private:
|
||||
|
||||
void bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane plane,
|
||||
GLenum attachpoint, GLenum texformat, Texture::Format fmt);
|
||||
bool check_fbo();
|
||||
void generate_mipmaps();
|
||||
void rebuild_bitplanes();
|
||||
|
||||
enum {
|
||||
SLOT_color,
|
||||
SLOT_depth,
|
||||
SLOT_stencil,
|
||||
SLOT_COUNT
|
||||
};
|
||||
|
||||
GLuint _fbo;
|
||||
int _rb_size_x;
|
||||
int _rb_size_y;
|
||||
GLuint _rb[SLOT_COUNT];
|
||||
PT(Texture) _tex[SLOT_COUNT];
|
||||
GLenum _attach_point[SLOT_COUNT];
|
||||
GLenum _slot_format[SLOT_COUNT];
|
||||
|
||||
PT(Texture) _tex[RTP_COUNT];
|
||||
GLuint _rb[RTP_COUNT];
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
|
|||
|
|
@ -3024,24 +3024,15 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
|
|||
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(tc != (TextureContext *)NULL);
|
||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
||||
apply_texture(tc);
|
||||
|
||||
if (z >= 0) {
|
||||
// Copy to a cube map face. This doesn't seem to work too well
|
||||
// with CopyTexSubImage2D, so we always use CopyTexImage2D.
|
||||
GLP(BindTexture)(GL_TEXTURE_CUBE_MAP_ARB, gtc->_index);
|
||||
GLP(CopyTexImage2D)(GL_TEXTURE_CUBE_MAP_POSITIVE_X + z, 0,
|
||||
get_internal_image_format(tex),
|
||||
xo, yo, w, h, 0);
|
||||
|
||||
} else {
|
||||
// If the texture has never been uploaded before, create it. We
|
||||
// cannot use glCopyTexImage2D to create a texture that may be
|
||||
// larger than the screen, so use glTexImage2D with arbitrary
|
||||
// data.
|
||||
GLP(BindTexture)(GL_TEXTURE_2D, gtc->_index);
|
||||
upload_blank_image(tex, gtc);
|
||||
|
||||
// Copy the pixel data from the frame buffer.
|
||||
GLP(CopyTexSubImage2D)(GL_TEXTURE_2D, 0, 0, 0, xo, yo, w, h);
|
||||
}
|
||||
|
||||
|
|
@ -6375,11 +6366,14 @@ bool CLP(GraphicsStateGuardian)::
|
|||
upload_texture(CLP(TextureContext) *gtc) {
|
||||
Texture *tex = gtc->get_texture();
|
||||
CPTA_uchar image = tex->get_ram_image();
|
||||
if (image.is_null()) {
|
||||
return false;
|
||||
}
|
||||
Texture::CompressionMode image_compression = tex->get_ram_image_compression();
|
||||
|
||||
Texture::CompressionMode image_compression;
|
||||
if (image.is_null()) {
|
||||
image_compression = Texture::CM_off;
|
||||
} else {
|
||||
image_compression = tex->get_ram_image_compression();
|
||||
}
|
||||
|
||||
int width = tex->get_x_size();
|
||||
int height = tex->get_y_size();
|
||||
int depth = tex->get_z_size();
|
||||
|
|
@ -6409,71 +6403,75 @@ upload_texture(CLP(TextureContext) *gtc) {
|
|||
return false;
|
||||
}
|
||||
|
||||
int texel_size = tex->get_num_components() * tex->get_component_width();
|
||||
if (!image.is_null()) {
|
||||
|
||||
// If it doesn't fit, we have to reduce it on-the-fly. This is kind
|
||||
// of expensive and it doesn't look great; it would have been better
|
||||
// if the user had specified max-texture-dimension to reduce the
|
||||
// texture at load time instead. Of course, the user doesn't always
|
||||
// know ahead of time what the hardware limits are.
|
||||
if (max_dimension > 0 && image_compression == Texture::CM_off) {
|
||||
if (width > max_dimension) {
|
||||
int byte_chunk = texel_size;
|
||||
int stride = 1;
|
||||
int new_width = width;
|
||||
while (new_width > max_dimension) {
|
||||
stride <<= 1;
|
||||
new_width >>= 1;
|
||||
// If it doesn't fit, we have to reduce it on-the-fly. This is kind
|
||||
// of expensive and it doesn't look great; it would have been better
|
||||
// if the user had specified max-texture-dimension to reduce the
|
||||
// texture at load time instead. Of course, the user doesn't always
|
||||
// know ahead of time what the hardware limits are.
|
||||
if (max_dimension > 0 && image_compression == Texture::CM_off) {
|
||||
if (width > max_dimension) {
|
||||
int texel_size = tex->get_num_components() * tex->get_component_width();
|
||||
int byte_chunk = texel_size;
|
||||
int stride = 1;
|
||||
int new_width = width;
|
||||
while (new_width > max_dimension) {
|
||||
stride <<= 1;
|
||||
new_width >>= 1;
|
||||
}
|
||||
GLCAT.info()
|
||||
<< "Reducing width of " << tex->get_name()
|
||||
<< " from " << width << " to " << new_width << "\n";
|
||||
image = reduce_image(image, byte_chunk, stride);
|
||||
width = new_width;
|
||||
}
|
||||
GLCAT.info()
|
||||
<< "Reducing width of " << tex->get_name()
|
||||
<< " from " << width << " to " << new_width << "\n";
|
||||
image = reduce_image(image, byte_chunk, stride);
|
||||
width = new_width;
|
||||
}
|
||||
if (height > max_dimension) {
|
||||
int byte_chunk = width * texel_size;
|
||||
int stride = 1;
|
||||
int new_height = height;
|
||||
while (new_height > max_dimension) {
|
||||
stride <<= 1;
|
||||
new_height >>= 1;
|
||||
if (height > max_dimension) {
|
||||
int texel_size = tex->get_num_components() * tex->get_component_width();
|
||||
int byte_chunk = width * texel_size;
|
||||
int stride = 1;
|
||||
int new_height = height;
|
||||
while (new_height > max_dimension) {
|
||||
stride <<= 1;
|
||||
new_height >>= 1;
|
||||
}
|
||||
GLCAT.info()
|
||||
<< "Reducing height of " << tex->get_name()
|
||||
<< " from " << height << " to " << new_height << "\n";
|
||||
image = reduce_image(image, byte_chunk, stride);
|
||||
height = new_height;
|
||||
}
|
||||
GLCAT.info()
|
||||
<< "Reducing height of " << tex->get_name()
|
||||
<< " from " << height << " to " << new_height << "\n";
|
||||
image = reduce_image(image, byte_chunk, stride);
|
||||
height = new_height;
|
||||
}
|
||||
if (depth > max_dimension) {
|
||||
int byte_chunk = height * width * texel_size;
|
||||
int stride = 1;
|
||||
int new_depth = depth;
|
||||
while (new_depth > max_dimension) {
|
||||
stride <<= 1;
|
||||
new_depth >>= 1;
|
||||
if (depth > max_dimension) {
|
||||
int texel_size = tex->get_num_components() * tex->get_component_width();
|
||||
int byte_chunk = height * width * texel_size;
|
||||
int stride = 1;
|
||||
int new_depth = depth;
|
||||
while (new_depth > max_dimension) {
|
||||
stride <<= 1;
|
||||
new_depth >>= 1;
|
||||
}
|
||||
GLCAT.info()
|
||||
<< "Reducing depth of " << tex->get_name()
|
||||
<< " from " << depth << " to " << new_depth << "\n";
|
||||
image = reduce_image(image, byte_chunk, stride);
|
||||
depth = new_depth;
|
||||
}
|
||||
GLCAT.info()
|
||||
<< "Reducing depth of " << tex->get_name()
|
||||
<< " from " << depth << " to " << new_depth << "\n";
|
||||
image = reduce_image(image, byte_chunk, stride);
|
||||
depth = new_depth;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_supports_bgr) {
|
||||
// If the GL doesn't claim to support BGR, we may have to reverse
|
||||
// the component ordering of the image.
|
||||
image = fix_component_ordering(image, external_format, tex);
|
||||
}
|
||||
|
||||
if (!_supports_bgr) {
|
||||
// If the GL doesn't claim to support BGR, we may have to reverse
|
||||
// the component ordering of the image.
|
||||
image = fix_component_ordering(image, external_format, tex);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (image_compression == Texture::CM_off) {
|
||||
int wanted_size =
|
||||
compute_gl_image_size(width, height, depth, external_format, component_type);
|
||||
nassertr(wanted_size == (int)image.size(), false);
|
||||
}
|
||||
if (image_compression == Texture::CM_off) {
|
||||
int wanted_size =
|
||||
compute_gl_image_size(width, height, depth, external_format, component_type);
|
||||
nassertr(wanted_size == (int)image.size(), false);
|
||||
}
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
GLP(PixelStorei)(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
|
|
@ -6541,7 +6539,9 @@ upload_texture(CLP(TextureContext) *gtc) {
|
|||
gtc->_depth = depth;
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
gtc->update_data_size_bytes(get_texture_memory_size(tex));
|
||||
if (!image.is_null()) {
|
||||
gtc->update_data_size_bytes(get_texture_memory_size(tex));
|
||||
}
|
||||
#endif
|
||||
|
||||
report_my_gl_errors();
|
||||
|
|
@ -6552,59 +6552,6 @@ upload_texture(CLP(TextureContext) *gtc) {
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::upload_blank_image
|
||||
// Access: Private
|
||||
// Description: Uploads a blank, non-mipmapped image to the specified
|
||||
// texture object. This is usually used to prepare the
|
||||
// texture for render-to-texture operations.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(GraphicsStateGuardian)::
|
||||
upload_blank_image(Texture *tex, CLP(TextureContext) *gtc)
|
||||
|
||||
{
|
||||
GLint internal_format = get_internal_image_format(tex);
|
||||
|
||||
if ((gtc->_already_applied == false)||
|
||||
(gtc->_internal_format != internal_format)||
|
||||
(gtc->_width != tex->get_x_size())||
|
||||
(gtc->_height != tex->get_y_size())||
|
||||
(gtc->_depth != 1)) {
|
||||
|
||||
GLP(BindTexture)(GL_TEXTURE_2D, gtc->_index);
|
||||
|
||||
char *image = new char[tex->get_x_size() * tex->get_y_size()];
|
||||
memset(image, 128, tex->get_x_size() * tex->get_y_size());
|
||||
|
||||
switch (tex->get_format()) {
|
||||
case Texture::F_depth_component:
|
||||
GLP(TexImage2D)(GL_TEXTURE_2D, 0, internal_format,
|
||||
tex->get_x_size(), tex->get_y_size(), 0,
|
||||
GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, image);
|
||||
break;
|
||||
case Texture::F_stencil_index:
|
||||
GLP(TexImage2D)(GL_TEXTURE_2D, 0, internal_format,
|
||||
tex->get_x_size(), tex->get_y_size(), 0,
|
||||
GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, image);
|
||||
break;
|
||||
default:
|
||||
GLP(TexImage2D)(GL_TEXTURE_2D, 0, internal_format,
|
||||
tex->get_x_size(), tex->get_y_size(), 0,
|
||||
GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
|
||||
break;
|
||||
}
|
||||
|
||||
delete image;
|
||||
|
||||
gtc->_already_applied = true;
|
||||
gtc->_internal_format = internal_format;
|
||||
gtc->_width = tex->get_x_size();
|
||||
gtc->_height = tex->get_y_size();
|
||||
gtc->_depth = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::upload_texture_image
|
||||
|
|
@ -6622,7 +6569,7 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||
Texture::CompressionMode image_compression) {
|
||||
// Make sure the error stack is cleared out before we begin.
|
||||
report_my_gl_errors();
|
||||
|
||||
|
||||
if (target == GL_NONE) {
|
||||
// Unsupported target (e.g. 3-d texturing on GL 1.1).
|
||||
return false;
|
||||
|
|
@ -6633,6 +6580,7 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||
|
||||
PStatTimer timer(_load_texture_pcollector);
|
||||
Texture *tex = gtc->get_texture();
|
||||
CPTA_uchar image = tex->get_ram_image();
|
||||
|
||||
if (GLCAT.is_debug()) {
|
||||
if (image_compression != Texture::CM_off) {
|
||||
|
|
@ -6644,33 +6592,11 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||
}
|
||||
}
|
||||
|
||||
int num_ram_mipmap_levels = 1;
|
||||
int num_ram_mipmap_levels = 0;
|
||||
bool load_ram_mipmaps = false;
|
||||
|
||||
if (uses_mipmaps) {
|
||||
num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
|
||||
|
||||
if (num_ram_mipmap_levels == 1) {
|
||||
// No RAM mipmap levels available. Should we generate some?
|
||||
if (!_supports_generate_mipmap ||
|
||||
(!auto_generate_mipmaps && image_compression == Texture::CM_off)) {
|
||||
// Yes, the GL won't generate them, so we need to.
|
||||
tex->generate_ram_mipmap_images();
|
||||
num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
|
||||
}
|
||||
}
|
||||
|
||||
if (num_ram_mipmap_levels != 1) {
|
||||
// We will load the mipmap levels from RAM. Don't ask the GL to
|
||||
// generate them.
|
||||
if (_supports_generate_mipmap) {
|
||||
GLP(TexParameteri)(target, GL_GENERATE_MIPMAP, false);
|
||||
}
|
||||
load_ram_mipmaps = true;
|
||||
|
||||
} else {
|
||||
// We don't have mipmap levels in RAM. Ask the GL to generate
|
||||
// them if it can.
|
||||
if (image.is_null()) {
|
||||
if (uses_mipmaps) {
|
||||
if (_supports_generate_mipmap) {
|
||||
GLP(TexParameteri)(target, GL_GENERATE_MIPMAP, true);
|
||||
} else {
|
||||
|
|
@ -6679,10 +6605,46 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||
uses_mipmaps = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
num_ram_mipmap_levels = 1;
|
||||
if (uses_mipmaps) {
|
||||
num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
|
||||
|
||||
if (num_ram_mipmap_levels == 1) {
|
||||
// No RAM mipmap levels available. Should we generate some?
|
||||
if (!_supports_generate_mipmap ||
|
||||
(!auto_generate_mipmaps && image_compression == Texture::CM_off)) {
|
||||
// Yes, the GL won't generate them, so we need to.
|
||||
tex->generate_ram_mipmap_images();
|
||||
num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
|
||||
}
|
||||
}
|
||||
|
||||
if (num_ram_mipmap_levels != 1) {
|
||||
// We will load the mipmap levels from RAM. Don't ask the GL to
|
||||
// generate them.
|
||||
if (_supports_generate_mipmap) {
|
||||
GLP(TexParameteri)(target, GL_GENERATE_MIPMAP, false);
|
||||
}
|
||||
load_ram_mipmaps = true;
|
||||
|
||||
} else {
|
||||
// We don't have mipmap levels in RAM. Ask the GL to generate
|
||||
// them if it can.
|
||||
if (_supports_generate_mipmap) {
|
||||
GLP(TexParameteri)(target, GL_GENERATE_MIPMAP, true);
|
||||
} else {
|
||||
// If it can't, do without mipmaps.
|
||||
GLP(TexParameteri)(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
uses_mipmaps = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int highest_level = 0;
|
||||
|
||||
|
||||
|
||||
if (!gtc->_already_applied ||
|
||||
gtc->_internal_format != internal_format ||
|
||||
gtc->_width != width ||
|
||||
|
|
@ -6690,6 +6652,24 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||
gtc->_depth != depth) {
|
||||
// We need to reload a new image.
|
||||
|
||||
if (num_ram_mipmap_levels == 0) {
|
||||
int *blank_image = new int[width * height];
|
||||
int color = 0xFF808080;
|
||||
switch (z) {
|
||||
case 0: color = 0xFF0000FF; break;
|
||||
case 1: color = 0xFF00FF00; break;
|
||||
case 2: color = 0xFFFF0000; break;
|
||||
case 3: color = 0xFF00FFFF; break;
|
||||
case 4: color = 0xFFFFFF00; break;
|
||||
case 5: color = 0xFFFF00FF; break;
|
||||
}
|
||||
for (int i=0; i<width * height; i++) blank_image[i]=color;
|
||||
GLP(TexImage2D)(target, 0, internal_format,
|
||||
width, height, 0,
|
||||
external_format, GL_UNSIGNED_BYTE, blank_image);
|
||||
delete blank_image;
|
||||
}
|
||||
|
||||
for (int n = 0; n < num_ram_mipmap_levels; ++n) {
|
||||
const unsigned char *image = tex->get_ram_mipmap_image(n);
|
||||
if (image == (const unsigned char *)NULL) {
|
||||
|
|
|
|||
|
|
@ -274,7 +274,6 @@ protected:
|
|||
void specify_texture(Texture *tex);
|
||||
void apply_texture(TextureContext *tc);
|
||||
bool upload_texture(CLP(TextureContext) *gtc);
|
||||
bool upload_blank_image(Texture *tex, CLP(TextureContext) *gtc);
|
||||
bool upload_texture_image(CLP(TextureContext) *gtc, bool uses_mipmaps,
|
||||
GLenum target, GLint internal_format,
|
||||
int width, int height, int depth,
|
||||
|
|
@ -372,8 +371,6 @@ public:
|
|||
bool _supports_draw_range_elements;
|
||||
PFNGLDRAWRANGEELEMENTSPROC _glDrawRangeElements;
|
||||
|
||||
bool _supports_depth_texture;
|
||||
|
||||
PFNGLTEXIMAGE3DPROC _glTexImage3D;
|
||||
PFNGLTEXSUBIMAGE3DPROC _glTexSubImage3D;
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ begin_frame(FrameMode mode) {
|
|||
// begin_render_texture();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
_gsg()->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame();
|
||||
}
|
||||
|
||||
|
|
@ -128,21 +130,6 @@ end_frame(FrameMode mode) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glxGraphicsBuffer::release_gsg
|
||||
// Access: Public
|
||||
// Description: Releases the current GSG pointer, if it is currently
|
||||
// held, and resets the GSG to NULL. The window will be
|
||||
// permanently unable to render; this is normally called
|
||||
// only just before destroying the window. This should
|
||||
// only be called from within the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void glxGraphicsBuffer::
|
||||
release_gsg() {
|
||||
glXMakeCurrent(_display, None, NULL);
|
||||
GraphicsBuffer::release_gsg();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glxGraphicsBuffer::close_buffer
|
||||
// Access: Protected, Virtual
|
||||
|
|
@ -151,6 +138,12 @@ release_gsg() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void glxGraphicsBuffer::
|
||||
close_buffer() {
|
||||
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||
glXMakeCurrent(_display, None, NULL);
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
|
||||
if (_pbuffer != None) {
|
||||
glXDestroyPbuffer(_display, _pbuffer);
|
||||
_pbuffer = None;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ public:
|
|||
|
||||
virtual bool begin_frame(FrameMode mode);
|
||||
virtual void end_frame(FrameMode mode);
|
||||
virtual void release_gsg();
|
||||
|
||||
protected:
|
||||
virtual void close_buffer();
|
||||
|
|
|
|||
|
|
@ -105,20 +105,6 @@ move_pointer(int device, int x, int y) {
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glxGraphicsWindow::release_gsg
|
||||
// Access: Public
|
||||
// Description: Releases the current GSG pointer, if it is currently
|
||||
// held, and resets the GSG to NULL. The window will be
|
||||
// permanently unable to render; this is normally called
|
||||
// only just before destroying the window. This should
|
||||
// only be called from within the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void glxGraphicsWindow::
|
||||
release_gsg() {
|
||||
glXMakeCurrent(_display, None, NULL);
|
||||
GraphicsWindow::release_gsg();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glxGraphicsWindow::begin_frame
|
||||
|
|
@ -157,6 +143,8 @@ begin_frame(FrameMode mode) {
|
|||
// begin_render_texture();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
_gsg()->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame();
|
||||
}
|
||||
|
||||
|
|
@ -375,8 +363,7 @@ process_events() {
|
|||
// In this case, the default case, the app does not intend
|
||||
// to service the request, so we do by closing the window.
|
||||
|
||||
// TODO: don't call release_gsg() in the window thread.
|
||||
release_gsg();
|
||||
// TODO: don't release the gsg in the window thread.
|
||||
close_window();
|
||||
properties.set_open(false);
|
||||
system_changed_properties(properties);
|
||||
|
|
@ -493,6 +480,12 @@ set_properties_now(WindowProperties &properties) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void glxGraphicsWindow::
|
||||
close_window() {
|
||||
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||
glXMakeCurrent(_display, None, NULL);
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
|
||||
if (_ic != (XIC)NULL) {
|
||||
XDestroyIC(_ic);
|
||||
_ic = (XIC)NULL;
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ public:
|
|||
virtual ~glxGraphicsWindow();
|
||||
|
||||
virtual bool move_pointer(int device, int x, int y);
|
||||
virtual void release_gsg();
|
||||
|
||||
virtual bool begin_frame(FrameMode mode);
|
||||
virtual void end_frame(FrameMode mode);
|
||||
virtual void begin_flip();
|
||||
|
|
|
|||
|
|
@ -931,6 +931,7 @@ set_ram_image(PTA_uchar image, Texture::CompressionMode compression,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
clear_ram_image() {
|
||||
++_modified;
|
||||
_ram_image_compression = CM_off;
|
||||
_ram_images.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,103 +60,6 @@ set_has_3d_uvs(bool flag) {
|
|||
_has_3d_uvs = flag;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_uv_range
|
||||
// Access: Public
|
||||
// Description: Sets the range of UV's that will be applied to the
|
||||
// vertices. If set_has_uvs() is true (as it is by
|
||||
// default), the vertices will be generated with the
|
||||
// indicated range of UV's, which will be useful if a
|
||||
// texture is applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CardMaker::
|
||||
set_uv_range(const TexCoord3f &ll, const TexCoord3f &lr, const TexCoord3f &ur, const TexCoord3f &ul) {
|
||||
_ll_tex = ll;
|
||||
_lr_tex = lr;
|
||||
_ur_tex = ur;
|
||||
_ul_tex = ul;
|
||||
_has_uvs = true;
|
||||
_has_3d_uvs = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_uv_range
|
||||
// Access: Public
|
||||
// Description: Sets the range of UV's that will be applied to the
|
||||
// vertices. If set_has_uvs() is true (as it is by
|
||||
// default), the vertices will be generated with the
|
||||
// indicated range of UV's, which will be useful if a
|
||||
// texture is applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CardMaker::
|
||||
set_uv_range(const TexCoordf &ll, const TexCoordf &lr, const TexCoordf &ur, const TexCoordf &ul) {
|
||||
_ll_tex.set(ll[0], ll[1], 0.0f);
|
||||
_lr_tex.set(lr[0], lr[1], 0.0f);
|
||||
_ur_tex.set(ur[0], ur[1], 0.0f);
|
||||
_ul_tex.set(ul[0], ul[1], 0.0f);
|
||||
_has_uvs = true;
|
||||
_has_3d_uvs = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_uv_range
|
||||
// Access: Public
|
||||
// Description: Sets the range of UV's that will be applied to the
|
||||
// vertices. If set_has_uvs() is true (as it is by
|
||||
// default), the vertices will be generated with the
|
||||
// indicated range of UV's, which will be useful if a
|
||||
// texture is applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CardMaker::
|
||||
set_uv_range(const TexCoordf &ll, const TexCoordf &ur) {
|
||||
_ll_tex.set(ll[0], ll[1], 0.0f);
|
||||
_lr_tex.set(ur[0], ll[1], 0.0f);
|
||||
_ur_tex.set(ur[0], ur[1], 0.0f);
|
||||
_ul_tex.set(ll[0], ur[1], 0.0f);
|
||||
_has_uvs = true;
|
||||
_has_3d_uvs = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_uv_range
|
||||
// Access: Public
|
||||
// Description: Sets the range of UV's that will be applied to the
|
||||
// vertices. If set_has_uvs() is true (as it is by
|
||||
// default), the vertices will be generated with the
|
||||
// indicated range of UV's, which will be useful if a
|
||||
// texture is applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CardMaker::
|
||||
set_uv_range(const LVector4f &x, const LVector4f &y, const LVector4f &z) {
|
||||
_ll_tex.set(x[0], y[0], z[0]);
|
||||
_lr_tex.set(x[1], y[1], z[1]);
|
||||
_ur_tex.set(x[2], y[2], z[2]);
|
||||
_ul_tex.set(x[3], y[3], z[3]);
|
||||
_has_uvs = true;
|
||||
_has_3d_uvs = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_uv_range_cube
|
||||
// Access: Public
|
||||
// Description: Sets the range of UV's that will be applied to the
|
||||
// vertices appropriately for a cube-map face.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CardMaker::
|
||||
set_uv_range_cube(int face) {
|
||||
LVector4f varya(-1, 1, 1, -1);
|
||||
LVector4f varyb(-1, -1, 1, 1);
|
||||
LVector4f fixed( 1, 1, 1, 1);
|
||||
switch(face) {
|
||||
case 0: set_uv_range( fixed, -varyb, varya); break; // positive_x
|
||||
case 1: set_uv_range(-fixed, -varyb, -varya); break; // negative_x
|
||||
case 2: set_uv_range(-varya, fixed, varyb); break; // positive_y
|
||||
case 3: set_uv_range(-varya, -fixed, -varyb); break; // negative_y
|
||||
case 4: set_uv_range(-varya, -varyb, fixed); break; // positive_z
|
||||
case 5: set_uv_range( varya, -varyb, -fixed); break; // negative_z
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_frame
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -159,6 +159,103 @@ generate() {
|
|||
return gnode.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_uv_range
|
||||
// Access: Public
|
||||
// Description: Sets the range of UV's that will be applied to the
|
||||
// vertices. If set_has_uvs() is true (as it is by
|
||||
// default), the vertices will be generated with the
|
||||
// indicated range of UV's, which will be useful if a
|
||||
// texture is applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CardMaker::
|
||||
set_uv_range(const TexCoord3f &ll, const TexCoord3f &lr, const TexCoord3f &ur, const TexCoord3f &ul) {
|
||||
_ll_tex = ll;
|
||||
_lr_tex = lr;
|
||||
_ur_tex = ur;
|
||||
_ul_tex = ul;
|
||||
_has_uvs = true;
|
||||
_has_3d_uvs = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_uv_range
|
||||
// Access: Public
|
||||
// Description: Sets the range of UV's that will be applied to the
|
||||
// vertices. If set_has_uvs() is true (as it is by
|
||||
// default), the vertices will be generated with the
|
||||
// indicated range of UV's, which will be useful if a
|
||||
// texture is applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CardMaker::
|
||||
set_uv_range(const TexCoordf &ll, const TexCoordf &lr, const TexCoordf &ur, const TexCoordf &ul) {
|
||||
_ll_tex.set(ll[0], ll[1], 0.0f);
|
||||
_lr_tex.set(lr[0], lr[1], 0.0f);
|
||||
_ur_tex.set(ur[0], ur[1], 0.0f);
|
||||
_ul_tex.set(ul[0], ul[1], 0.0f);
|
||||
_has_uvs = true;
|
||||
_has_3d_uvs = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_uv_range
|
||||
// Access: Public
|
||||
// Description: Sets the range of UV's that will be applied to the
|
||||
// vertices. If set_has_uvs() is true (as it is by
|
||||
// default), the vertices will be generated with the
|
||||
// indicated range of UV's, which will be useful if a
|
||||
// texture is applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CardMaker::
|
||||
set_uv_range(const TexCoordf &ll, const TexCoordf &ur) {
|
||||
_ll_tex.set(ll[0], ll[1], 0.0f);
|
||||
_lr_tex.set(ur[0], ll[1], 0.0f);
|
||||
_ur_tex.set(ur[0], ur[1], 0.0f);
|
||||
_ul_tex.set(ll[0], ur[1], 0.0f);
|
||||
_has_uvs = true;
|
||||
_has_3d_uvs = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_uv_range
|
||||
// Access: Public
|
||||
// Description: Sets the range of UV's that will be applied to the
|
||||
// vertices. If set_has_uvs() is true (as it is by
|
||||
// default), the vertices will be generated with the
|
||||
// indicated range of UV's, which will be useful if a
|
||||
// texture is applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CardMaker::
|
||||
set_uv_range(const LVector4f &x, const LVector4f &y, const LVector4f &z) {
|
||||
_ll_tex.set(x[0], y[0], z[0]);
|
||||
_lr_tex.set(x[1], y[1], z[1]);
|
||||
_ur_tex.set(x[2], y[2], z[2]);
|
||||
_ul_tex.set(x[3], y[3], z[3]);
|
||||
_has_uvs = true;
|
||||
_has_3d_uvs = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::set_uv_range_cube
|
||||
// Access: Public
|
||||
// Description: Sets the range of UV's that will be applied to the
|
||||
// vertices appropriately for a cube-map face.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CardMaker::
|
||||
set_uv_range_cube(int face) {
|
||||
LVector4f varya(-1, 1, 1, -1);
|
||||
LVector4f varyb(-1, -1, 1, 1);
|
||||
LVector4f fixed( 1, 1, 1, 1);
|
||||
switch(face) {
|
||||
case 0: set_uv_range( fixed, -varyb, -varya); break; // positive_x
|
||||
case 1: set_uv_range(-fixed, -varyb, varya); break; // negative_x
|
||||
case 2: set_uv_range( varya, fixed, varyb); break; // positive_y
|
||||
case 3: set_uv_range( varya, -fixed, -varyb); break; // negative_y
|
||||
case 4: set_uv_range( varya, -varyb, fixed); break; // positive_z
|
||||
case 5: set_uv_range(-varya, -varyb, -fixed); break; // negative_z
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CardMaker::rescale_source_geometry
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -38,13 +38,14 @@ PUBLISHED:
|
|||
INLINE ~CardMaker();
|
||||
|
||||
void reset();
|
||||
INLINE void set_uv_range(const TexCoordf &ll, const TexCoordf &ur);
|
||||
INLINE void set_uv_range(const TexCoordf &ll, const TexCoordf &lr, const TexCoordf &ur, const TexCoordf &ul);
|
||||
INLINE void set_uv_range(const TexCoord3f &ll, const TexCoord3f &lr, const TexCoord3f &ur, const TexCoord3f &ul);
|
||||
INLINE void set_uv_range(const LVector4f &x, const LVector4f &y, const LVector4f &z);
|
||||
void set_uv_range(const TexCoordf &ll, const TexCoordf &ur);
|
||||
void set_uv_range(const TexCoordf &ll, const TexCoordf &lr, const TexCoordf &ur, const TexCoordf &ul);
|
||||
void set_uv_range(const TexCoord3f &ll, const TexCoord3f &lr, const TexCoord3f &ur, const TexCoord3f &ul);
|
||||
void set_uv_range(const LVector4f &x, const LVector4f &y, const LVector4f &z);
|
||||
void set_uv_range_cube(int face);
|
||||
|
||||
INLINE void set_has_uvs(bool flag);
|
||||
INLINE void set_has_3d_uvs(bool flag);
|
||||
INLINE void set_uv_range_cube(int face);
|
||||
|
||||
INLINE void set_frame(float left, float right, float bottom, float top);
|
||||
INLINE void set_frame(const LVecBase4f &frame);
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ begin_frame(FrameMode mode) {
|
|||
// begin_render_texture();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ begin_frame(FrameMode mode) {
|
|||
// begin_render_texture();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame();
|
||||
}
|
||||
|
||||
|
|
@ -113,20 +114,6 @@ end_frame(FrameMode mode) {
|
|||
clear_cube_map_selection();
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: osxGraphicsBuffer::release_gsg
|
||||
// Access: Public
|
||||
// Description: Releases the current GSG pointer, if it is currently
|
||||
// held, and resets the GSG to NULL. The window will be
|
||||
// permanently unable to render; this is normally called
|
||||
// only just before destroying the window. This should
|
||||
// only be called from within the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void osxGraphicsBuffer::
|
||||
release_gsg() {
|
||||
//osxMakeCurrent(_display, None, NULL);
|
||||
GraphicsBuffer::release_gsg();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: osxGraphicsBuffer::close_buffer
|
||||
|
|
@ -136,7 +123,11 @@ release_gsg() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void osxGraphicsBuffer::
|
||||
close_buffer() {
|
||||
|
||||
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||
//osxMakeCurrent(_display, None, NULL);
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
_is_valid = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,8 +45,6 @@ public:
|
|||
|
||||
virtual bool begin_frame(FrameMode mode);
|
||||
virtual void end_frame(FrameMode mode);
|
||||
virtual void release_gsg();
|
||||
|
||||
|
||||
protected:
|
||||
virtual void close_buffer();
|
||||
|
|
|
|||
|
|
@ -568,8 +568,8 @@ bool osxGraphicsWindow::begin_frame(FrameMode mode)
|
|||
|
||||
|
||||
|
||||
_gsg->reset_if_new();
|
||||
|
||||
_gsg->reset_if_new();
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame();
|
||||
}
|
||||
|
||||
|
|
@ -590,22 +590,6 @@ void osxGraphicsWindow::end_frame(FrameMode mode)
|
|||
trigger_flip();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: osxGraphicsWindow::release_gsg
|
||||
// Access: Public, Virtual
|
||||
// Description: Releases the current GSG pointer, if it is currently
|
||||
// held, and resets the GSG to NULL. The window will be
|
||||
// permanently unable to render; this is normally called
|
||||
// only just before destroying the window. This should
|
||||
// only be called from within the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void osxGraphicsWindow::release_gsg()
|
||||
{
|
||||
ReleaseSystemResources();
|
||||
|
||||
GraphicsWindow::release_gsg();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: osxGraphicsWindow::begin_flip
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -632,11 +616,12 @@ void osxGraphicsWindow::begin_flip()
|
|||
// Description: Closes the window right now. Called from the window
|
||||
// thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void osxGraphicsWindow::close_window() {
|
||||
|
||||
ReleaseSystemResources();
|
||||
GraphicsWindow::close_window();
|
||||
|
||||
void osxGraphicsWindow::close_window()
|
||||
{
|
||||
ReleaseSystemResources();
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
GraphicsWindow::close_window();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ public:
|
|||
virtual bool move_pointer(int device, int x, int y);
|
||||
|
||||
// virtual void make_current();
|
||||
virtual void release_gsg();
|
||||
virtual bool begin_frame(FrameMode mode);
|
||||
virtual void end_frame(FrameMode mode);
|
||||
virtual void begin_flip();
|
||||
|
|
|
|||
|
|
@ -91,13 +91,15 @@ begin_frame(FrameMode mode) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wglMakeCurrent(_pbuffer_dc, wglgsg->get_context(_pbuffer_dc));
|
||||
|
||||
if (mode == FM_render) {
|
||||
begin_render_texture();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame();
|
||||
}
|
||||
|
||||
|
|
@ -228,20 +230,6 @@ select_cube_map(int cube_map_index) {
|
|||
wglgsg->_wglSetPbufferAttribARB(_pbuffer, iattrib_list);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wglGraphicsBuffer::release_gsg
|
||||
// Access: Public, Virtual
|
||||
// Description: Releases the current GSG pointer, if it is currently
|
||||
// held, and resets the GSG to NULL. The window will be
|
||||
// permanently unable to render; this is normally called
|
||||
// only just before destroying the window. This should
|
||||
// only be called from within the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void wglGraphicsBuffer::
|
||||
release_gsg() {
|
||||
GraphicsBuffer::release_gsg();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wglGraphicsBuffer::process_events
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -284,7 +272,11 @@ close_buffer() {
|
|||
if (_pbuffer) {
|
||||
wglgsg->_wglDestroyPbufferARB(_pbuffer);
|
||||
}
|
||||
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
|
||||
_pbuffer_dc = 0;
|
||||
_pbuffer = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ public:
|
|||
virtual void end_frame(FrameMode mode);
|
||||
|
||||
virtual void select_cube_map(int cube_map_index);
|
||||
virtual void release_gsg();
|
||||
|
||||
virtual void process_events();
|
||||
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ begin_frame(FrameMode mode) {
|
|||
if (_gsg == (GraphicsStateGuardian *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
wglGraphicsStateGuardian *wglgsg;
|
||||
DCAST_INTO_R(wglgsg, _gsg, false);
|
||||
|
||||
|
|
@ -181,6 +181,7 @@ begin_frame(FrameMode mode) {
|
|||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame();
|
||||
}
|
||||
|
||||
|
|
@ -213,21 +214,6 @@ end_frame(FrameMode mode) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wglGraphicsWindow::release_gsg
|
||||
// Access: Public, Virtual
|
||||
// Description: Releases the current GSG pointer, if it is currently
|
||||
// held, and resets the GSG to NULL. The window will be
|
||||
// permanently unable to render; this is normally called
|
||||
// only just before destroying the window. This should
|
||||
// only be called from within the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void wglGraphicsWindow::
|
||||
release_gsg() {
|
||||
wglMakeCurrent(_hdc, NULL);
|
||||
GraphicsWindow::release_gsg();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wglGraphicsWindow::begin_flip
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -268,6 +254,11 @@ begin_flip() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void wglGraphicsWindow::
|
||||
close_window() {
|
||||
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||
wglMakeCurrent(_hdc, NULL);
|
||||
_gsg.clear();
|
||||
_active = false;
|
||||
}
|
||||
ReleaseDC(_hWnd, _hdc);
|
||||
_hdc = (HDC)0;
|
||||
WinGraphicsWindow::close_window();
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ public:
|
|||
virtual bool begin_frame(FrameMode mode);
|
||||
virtual void end_frame(FrameMode mode);
|
||||
|
||||
virtual void release_gsg();
|
||||
virtual void begin_flip();
|
||||
|
||||
protected:
|
||||
|
|
|
|||
Loading…
Reference in New Issue