mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
*** empty log message ***
This commit is contained in:
parent
5c29aace8d
commit
efc2a9ce26
@ -60,30 +60,36 @@ get_name() const {
|
|||||||
return _name;
|
return _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsOutput::count_textures
|
||||||
|
// Access: Published
|
||||||
|
// Description: If the GraphicsOutput is set to render into a
|
||||||
|
// texture, returns the number of textures that are
|
||||||
|
// being rendered into. Normally, the textures would
|
||||||
|
// be associated with different buffers - a color
|
||||||
|
// texture, a depth texture, and a stencil texture.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int GraphicsOutput::
|
||||||
|
count_textures() const {
|
||||||
|
return _textures.size();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsOutput::has_texture
|
// Function: GraphicsOutput::has_texture
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns true if the GraphicsOutput is set to render
|
// Description: Returns true if the GraphicsOutput is rendering
|
||||||
// into a texture, or false otherwise.
|
// into any textures at all.
|
||||||
//
|
|
||||||
// Normally, this will only be true for a GraphicsBuffer
|
|
||||||
// object, and only when want_texture is passed in as
|
|
||||||
// true to the GraphicsBuffer constructor. If
|
|
||||||
// show-buffers is true, this may also be set for a
|
|
||||||
// GraphicsWindow, which is in this case serving in the
|
|
||||||
// place of a GraphicsBuffer.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE bool GraphicsOutput::
|
INLINE bool GraphicsOutput::
|
||||||
has_texture() const {
|
has_texture() const {
|
||||||
return !(_texture.is_null());
|
return (_textures.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsOutput::get_texture
|
// Function: GraphicsOutput::get_texture
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns the texture into which the GraphicsOutput
|
// Description: Returns the nth texture into which the GraphicsOutput
|
||||||
// renders, if has_texture() is true, or NULL if
|
// renders. Returns NULL if there is no such texture.
|
||||||
// has_texture() is false.
|
|
||||||
//
|
//
|
||||||
// If the texture is non-NULL, it may be applied to
|
// If the texture is non-NULL, it may be applied to
|
||||||
// geometry to be rendered for any other windows or
|
// geometry to be rendered for any other windows or
|
||||||
@ -93,8 +99,26 @@ has_texture() const {
|
|||||||
// the texture will be invalid.
|
// the texture will be invalid.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE Texture *GraphicsOutput::
|
INLINE Texture *GraphicsOutput::
|
||||||
get_texture() const {
|
get_texture(int i) const {
|
||||||
return _texture;
|
if ((i < 0) || (i >= ((int)_textures.size()))) {
|
||||||
|
return (Texture *)NULL;
|
||||||
|
}
|
||||||
|
return _textures[i]._texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// 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.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE GraphicsOutput::RenderTextureMode GraphicsOutput::
|
||||||
|
get_rtm_mode(int i) const {
|
||||||
|
if ((i < 0) || (i >= ((int)_textures.size()))) {
|
||||||
|
return RTM_none;
|
||||||
|
}
|
||||||
|
return _textures[i]._rtm_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -225,7 +249,12 @@ INLINE bool GraphicsOutput::
|
|||||||
get_delete_flag() const {
|
get_delete_flag() const {
|
||||||
// We only delete the window or buffer automatically when it is
|
// We only delete the window or buffer automatically when it is
|
||||||
// no longer associated with a texture.
|
// no longer associated with a texture.
|
||||||
return _delete_flag && !_hold_texture.is_valid_pointer();
|
for (int i=0; i<(int)_hold_textures.size(); i++) {
|
||||||
|
if (_hold_textures[i].is_valid_pointer()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _delete_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -80,7 +80,6 @@ GraphicsOutput(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
|
|||||||
_y_size = 0;
|
_y_size = 0;
|
||||||
_has_size = false;
|
_has_size = false;
|
||||||
_is_valid = false;
|
_is_valid = false;
|
||||||
_rtm_mode = RTM_none;
|
|
||||||
_flip_ready = false;
|
_flip_ready = false;
|
||||||
_needs_context = true;
|
_needs_context = true;
|
||||||
_cube_map_index = -1;
|
_cube_map_index = -1;
|
||||||
@ -187,12 +186,24 @@ GraphicsOutput::
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsOutput::setup_render_texture
|
// Function: GraphicsOutput::clear_render_textures
|
||||||
|
// Access: Published
|
||||||
|
// Description: If the GraphicsOutput is currently rendering to
|
||||||
|
// a texture, then all textures are dissociated from
|
||||||
|
// the GraphicsOuput.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void GraphicsOutput::
|
||||||
|
clear_render_textures() {
|
||||||
|
MutexHolder holder(_lock);
|
||||||
|
_textures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsOutput::add_render_texture
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Creates a new Texture object, suitable for rendering
|
// Description: Creates a new Texture object, suitable for rendering
|
||||||
// the contents of this buffer into, and stores it in
|
// the contents of this buffer into, and appends it to
|
||||||
// _texture. This also disassociates the previous
|
// the list of render textures.
|
||||||
// texture (if any).
|
|
||||||
//
|
//
|
||||||
// If tex is not NULL, it is the texture that will be
|
// If tex is not NULL, it is the texture that will be
|
||||||
// set up for rendering into; otherwise, a new Texture
|
// set up for rendering into; otherwise, a new Texture
|
||||||
@ -200,66 +211,84 @@ GraphicsOutput::
|
|||||||
// get_texture() to retrieve the new texture pointer
|
// get_texture() to retrieve the new texture pointer
|
||||||
// later).
|
// later).
|
||||||
//
|
//
|
||||||
// If allow_bind is true, and this GraphicsOutput is an
|
|
||||||
// offscreen graphics buffer that has not yet been
|
|
||||||
// rendered into, it will attempt to set up the buffer
|
|
||||||
// for rendering directly into the texture, avoiding the
|
|
||||||
// cost of the copy-to-texture-memory each frame. This
|
|
||||||
// is not supported by all graphics hardware, but if it
|
|
||||||
// is not supported, this option is quietly ignored.
|
|
||||||
//
|
|
||||||
// If to_ram is true, the texture image will be
|
|
||||||
// downloaded from the framebuffer memory into system
|
|
||||||
// RAM each frame, which is more expensive but allows
|
|
||||||
// the texture to subsequently be applied to any GSG.
|
|
||||||
// Otherwise, the texture image remains in texture
|
|
||||||
// memory only.
|
|
||||||
//
|
|
||||||
// Also see make_texture_buffer(), which is a
|
// Also see make_texture_buffer(), which is a
|
||||||
// higher-level interface for preparing
|
// higher-level interface for preparing
|
||||||
// render-to-a-texture mode.
|
// render-to-a-texture mode.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void GraphicsOutput::
|
void GraphicsOutput::
|
||||||
setup_render_texture(Texture *tex, RenderTextureMode mode) {
|
add_render_texture(Texture *tex, RenderTextureMode mode) {
|
||||||
if (mode == RTM_none) {
|
if (mode == RTM_none) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MutexHolder holder(_lock);
|
MutexHolder holder(_lock);
|
||||||
_rtm_mode = mode;
|
|
||||||
|
|
||||||
if (tex == (Texture *)NULL) {
|
if (tex == (Texture *)NULL) {
|
||||||
_texture = new Texture(get_name());
|
tex = new Texture(get_name());
|
||||||
_texture->set_wrap_u(Texture::WM_clamp);
|
tex->set_wrap_u(Texture::WM_clamp);
|
||||||
_texture->set_wrap_v(Texture::WM_clamp);
|
tex->set_wrap_v(Texture::WM_clamp);
|
||||||
} else {
|
} else {
|
||||||
_texture = tex;
|
tex->clear_ram_image();
|
||||||
_texture->clear_ram_image();
|
|
||||||
}
|
}
|
||||||
_texture->set_match_framebuffer_format(true);
|
tex->set_match_framebuffer_format(true);
|
||||||
|
|
||||||
// Go ahead and tell the texture our anticipated size, even if it
|
// Go ahead and tell the texture our anticipated size, even if it
|
||||||
// might be inaccurate (particularly if this is a GraphicsWindow,
|
// might be inaccurate (particularly if this is a GraphicsWindow,
|
||||||
// which has system-imposed restrictions on size).
|
// which has system-imposed restrictions on size).
|
||||||
_texture->set_x_size(get_x_size());
|
tex->set_x_size(get_x_size());
|
||||||
_texture->set_y_size(get_y_size());
|
tex->set_y_size(get_y_size());
|
||||||
|
|
||||||
|
RenderTexture result;
|
||||||
|
result._texture = tex;
|
||||||
|
result._rtm_mode = mode;
|
||||||
|
_textures.push_back(result);
|
||||||
|
|
||||||
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
||||||
set_inverted(_gsg->get_copy_texture_inverted());
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsOutput::setup_render_texture
|
// Function: GraphicsOutput::setup_render_texture
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description:
|
// Description: This is a deprecated interface that made sense back
|
||||||
|
// when GraphicsOutputs could only render into one
|
||||||
|
// texture at a time. From now on, use
|
||||||
|
// clear_render_textures and add_render_texture
|
||||||
|
// instead.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void GraphicsOutput::
|
void GraphicsOutput::
|
||||||
setup_render_texture(Texture *tex, bool allow_bind, bool to_ram) {
|
setup_render_texture(Texture *tex, bool allow_bind, bool to_ram) {
|
||||||
|
display_cat.warning() <<
|
||||||
|
"Using deprecated setup_render_texture interface.\n";
|
||||||
|
clear_render_textures();
|
||||||
if (to_ram) {
|
if (to_ram) {
|
||||||
setup_render_texture(tex, RTM_copy_ram);
|
add_render_texture(tex, RTM_copy_ram);
|
||||||
} else if (allow_bind) {
|
} else if (allow_bind) {
|
||||||
setup_render_texture(tex, RTM_bind_or_copy);
|
add_render_texture(tex, RTM_bind_or_copy);
|
||||||
} else {
|
} else {
|
||||||
setup_render_texture(tex, RTM_copy_texture);
|
add_render_texture(tex, RTM_copy_texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,7 +606,20 @@ get_texture_card() {
|
|||||||
PT(GeomNode) gnode = new GeomNode("texture card");
|
PT(GeomNode) gnode = new GeomNode("texture card");
|
||||||
gnode->add_geom(_texture_card);
|
gnode->add_geom(_texture_card);
|
||||||
NodePath path(gnode);
|
NodePath path(gnode);
|
||||||
path.set_texture(get_texture(), 0);
|
|
||||||
|
// The texture card, by default, is textured with the first
|
||||||
|
// render-to-texture output texture. Depth and stencil
|
||||||
|
// textures are ignored. The user can freely alter the
|
||||||
|
// card's texture attrib.
|
||||||
|
for (int i=0; i<count_textures(); i++) {
|
||||||
|
Texture *texture = get_texture(i);
|
||||||
|
if ((texture->get_format() != Texture::F_depth_component) &&
|
||||||
|
(texture->get_format() != Texture::F_stencil_index)) {
|
||||||
|
path.set_texture(texture, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,7 +677,7 @@ make_texture_buffer(const string &name, int x_size, int y_size,
|
|||||||
// host window size. If the user requests this, we have to use a
|
// host window size. If the user requests this, we have to use a
|
||||||
// parasite buffer.
|
// parasite buffer.
|
||||||
buffer = engine->make_parasite(host, name, sort, x_size, y_size);
|
buffer = engine->make_parasite(host, name, sort, x_size, y_size);
|
||||||
buffer->setup_render_texture(tex, false, to_ram);
|
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -644,7 +686,7 @@ make_texture_buffer(const string &name, int x_size, int y_size,
|
|||||||
// since it all amounts to the same thing anyway--this will
|
// since it all amounts to the same thing anyway--this will
|
||||||
// actually create a new GraphicsWindow.
|
// actually create a new GraphicsWindow.
|
||||||
buffer = engine->make_buffer(gsg, name, sort, x_size, y_size);
|
buffer = engine->make_buffer(gsg, name, sort, x_size, y_size);
|
||||||
buffer->setup_render_texture(tex, false, to_ram);
|
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,7 +703,7 @@ make_texture_buffer(const string &name, int x_size, int y_size,
|
|||||||
(x_size <= host->get_x_size() && y_size <= host->get_y_size())) {
|
(x_size <= host->get_x_size() && y_size <= host->get_y_size())) {
|
||||||
buffer = engine->make_parasite(host, name, sort, x_size, y_size);
|
buffer = engine->make_parasite(host, name, sort, x_size, y_size);
|
||||||
if (buffer != (GraphicsOutput *)NULL) {
|
if (buffer != (GraphicsOutput *)NULL) {
|
||||||
buffer->setup_render_texture(tex, false, to_ram);
|
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -680,7 +722,11 @@ make_texture_buffer(const string &name, int x_size, int y_size,
|
|||||||
buffer = engine->make_buffer(sb_gsg, name, sort, x_size, y_size);
|
buffer = engine->make_buffer(sb_gsg, name, sort, x_size, y_size);
|
||||||
if (buffer != (GraphicsOutput *)NULL) {
|
if (buffer != (GraphicsOutput *)NULL) {
|
||||||
// Check the buffer for goodness.
|
// Check the buffer for goodness.
|
||||||
buffer->setup_render_texture(tex, allow_bind, to_ram);
|
if (allow_bind) {
|
||||||
|
buffer->add_render_texture(tex, RTM_bind_or_copy);
|
||||||
|
} else {
|
||||||
|
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
|
||||||
|
}
|
||||||
engine->open_windows();
|
engine->open_windows();
|
||||||
if (buffer->is_valid()) {
|
if (buffer->is_valid()) {
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -700,7 +746,11 @@ make_texture_buffer(const string &name, int x_size, int y_size,
|
|||||||
// source window is double-buffered.
|
// source window is double-buffered.
|
||||||
buffer = engine->make_buffer(gsg, name, sort, x_size, y_size);
|
buffer = engine->make_buffer(gsg, name, sort, x_size, y_size);
|
||||||
if (buffer != (GraphicsOutput *)NULL) {
|
if (buffer != (GraphicsOutput *)NULL) {
|
||||||
buffer->setup_render_texture(tex, allow_bind, to_ram);
|
if (allow_bind) {
|
||||||
|
buffer->add_render_texture(tex, RTM_bind_or_copy);
|
||||||
|
} else {
|
||||||
|
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
|
||||||
|
}
|
||||||
engine->open_windows();
|
engine->open_windows();
|
||||||
if (buffer->is_valid()) {
|
if (buffer->is_valid()) {
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -714,7 +764,7 @@ make_texture_buffer(const string &name, int x_size, int y_size,
|
|||||||
// Looks like we have to settle for a parasite buffer.
|
// Looks like we have to settle for a parasite buffer.
|
||||||
if (x_size <= host->get_x_size() && y_size <= host->get_y_size()) {
|
if (x_size <= host->get_x_size() && y_size <= host->get_y_size()) {
|
||||||
buffer = engine->make_parasite(host, name, sort, x_size, y_size);
|
buffer = engine->make_parasite(host, name, sort, x_size, y_size);
|
||||||
buffer->setup_render_texture(tex, false, to_ram);
|
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -926,10 +976,7 @@ begin_frame() {
|
|||||||
// Okay, we already have a GSG, so activate it.
|
// Okay, we already have a GSG, so activate it.
|
||||||
make_current();
|
make_current();
|
||||||
|
|
||||||
if (_rtm_mode == RTM_bind_or_copy) {
|
begin_render_texture();
|
||||||
// Release the texture so we can render into the frame buffer.
|
|
||||||
_gsg->framebuffer_release_texture(this, get_texture());
|
|
||||||
}
|
|
||||||
|
|
||||||
_cube_map_index = -1;
|
_cube_map_index = -1;
|
||||||
_cube_map_dr = NULL;
|
_cube_map_dr = NULL;
|
||||||
@ -982,33 +1029,24 @@ end_frame() {
|
|||||||
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
||||||
_gsg->end_frame();
|
_gsg->end_frame();
|
||||||
|
|
||||||
// If _rtm_mode isn't RTM_none, it means we should copy or lock the
|
// Handle all render-to-texture operations that use bind-to-texture
|
||||||
// framebuffer to the GraphicsOutput's associated texture after the
|
end_render_texture();
|
||||||
// frame has rendered.
|
|
||||||
if (_rtm_mode != RTM_none) {
|
// Handle all render-to-texture operations that use copy-to-texture
|
||||||
|
for (int i=0; i<count_textures(); i++) {
|
||||||
|
RenderTextureMode rtm_mode = get_rtm_mode(i);
|
||||||
|
if ((rtm_mode == RTM_none)||(rtm_mode == RTM_bind_or_copy)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture *texture = get_texture(i);
|
||||||
PStatTimer timer(_copy_texture_pcollector);
|
PStatTimer timer(_copy_texture_pcollector);
|
||||||
nassertv(has_texture());
|
nassertv(has_texture());
|
||||||
|
|
||||||
// If _rtm_mode is one of the bind-modes, it means we should attempt
|
if ((rtm_mode == RTM_copy_texture)||
|
||||||
// to lock the framebuffer directly to the texture memory, avoiding
|
(rtm_mode == RTM_copy_ram)||
|
||||||
// the copy.
|
((rtm_mode == RTM_triggered_copy_texture)&&(_trigger_copy))||
|
||||||
if (_rtm_mode == RTM_bind_or_copy) {
|
((rtm_mode == RTM_triggered_copy_ram)&&(_trigger_copy))) {
|
||||||
if (display_cat.is_debug()) {
|
|
||||||
display_cat.debug()
|
|
||||||
<< "Locking texture for " << get_name() << " at frame end.\n";
|
|
||||||
}
|
|
||||||
if (!_gsg->framebuffer_bind_to_texture(this, get_texture())) {
|
|
||||||
display_cat.warning()
|
|
||||||
<< "Lock-to-texture failed, resorting to copy.\n";
|
|
||||||
_rtm_mode = RTM_copy_texture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_rtm_mode == RTM_copy_texture)||
|
|
||||||
(_rtm_mode == RTM_copy_ram)||
|
|
||||||
((_rtm_mode == RTM_triggered_copy_texture)&&(_trigger_copy))||
|
|
||||||
((_rtm_mode == RTM_triggered_copy_ram)&&(_trigger_copy))) {
|
|
||||||
_trigger_copy = false;
|
|
||||||
if (display_cat.is_debug()) {
|
if (display_cat.is_debug()) {
|
||||||
display_cat.debug()
|
display_cat.debug()
|
||||||
<< "Copying texture for " << get_name() << " at frame end.\n";
|
<< "Copying texture for " << get_name() << " at frame end.\n";
|
||||||
@ -1017,24 +1055,25 @@ end_frame() {
|
|||||||
}
|
}
|
||||||
RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type());
|
RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type());
|
||||||
if (_cube_map_dr != (DisplayRegion *)NULL) {
|
if (_cube_map_dr != (DisplayRegion *)NULL) {
|
||||||
if ((_rtm_mode == RTM_copy_ram)||(_rtm_mode == RTM_triggered_copy_ram)) {
|
if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
|
||||||
_gsg->framebuffer_copy_to_ram(get_texture(), _cube_map_index,
|
_gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
|
||||||
_cube_map_dr, buffer);
|
_cube_map_dr, buffer);
|
||||||
} else {
|
} else {
|
||||||
_gsg->framebuffer_copy_to_texture(get_texture(), _cube_map_index,
|
_gsg->framebuffer_copy_to_texture(texture, _cube_map_index,
|
||||||
_cube_map_dr, buffer);
|
_cube_map_dr, buffer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((_rtm_mode == RTM_copy_ram)||(_rtm_mode == RTM_triggered_copy_ram)) {
|
if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
|
||||||
_gsg->framebuffer_copy_to_ram(get_texture(), _cube_map_index,
|
_gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
|
||||||
_default_display_region, buffer);
|
_default_display_region, buffer);
|
||||||
} else {
|
} else {
|
||||||
_gsg->framebuffer_copy_to_texture(get_texture(), _cube_map_index,
|
_gsg->framebuffer_copy_to_texture(texture, _cube_map_index,
|
||||||
_default_display_region, buffer);
|
_default_display_region, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_trigger_copy = false;
|
||||||
|
|
||||||
// If we're not single-buffered, we're now ready to flip.
|
// If we're not single-buffered, we're now ready to flip.
|
||||||
if (!_gsg->get_properties().is_single_buffered()) {
|
if (!_gsg->get_properties().is_single_buffered()) {
|
||||||
@ -1059,23 +1098,53 @@ end_frame() {
|
|||||||
|
|
||||||
// If we were rendering directly to texture, we can't delete the
|
// If we were rendering directly to texture, we can't delete the
|
||||||
// buffer until the texture is gone too.
|
// buffer until the texture is gone too.
|
||||||
if (_rtm_mode == RTM_bind_or_copy) {
|
for (int i=0; i<count_textures(); i++) {
|
||||||
_hold_texture = _texture;
|
if (get_rtm_mode(i) == RTM_bind_or_copy) {
|
||||||
|
_hold_textures.push_back(get_texture(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to be sure to clear the _texture pointer, though, or
|
// We have to be sure to clear the _textures pointers, though, or
|
||||||
// we'll end up holding a reference to it forever.
|
// we'll end up holding a reference to the textures forever.
|
||||||
_texture = NULL;
|
clear_render_textures();
|
||||||
|
|
||||||
// And we need to stop trying to copy to the texture.
|
|
||||||
_rtm_mode = RTM_none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_cube_map_index = -1;
|
_cube_map_index = -1;
|
||||||
_cube_map_dr = NULL;
|
_cube_map_dr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsOutput::begin_render_texture
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: If the GraphicsOutput supports direct render-to-texture,
|
||||||
|
// and if any setup needs to be done during begin_frame,
|
||||||
|
// then the setup code should go here. Any textures that
|
||||||
|
// can not be rendered to directly should be reflagged
|
||||||
|
// as RTM_copy_texture.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void GraphicsOutput::
|
||||||
|
begin_render_texture() {
|
||||||
|
for (int i=0; i<count_textures(); i++) {
|
||||||
|
if (get_rtm_mode(i) == RTM_bind_or_copy) {
|
||||||
|
_textures[i]._rtm_mode = RTM_copy_texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsOutput::end_render_texture
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: If the GraphicsOutput supports direct render-to-texture,
|
||||||
|
// and if any setup needs to be done during end_frame,
|
||||||
|
// then the setup code should go here. Any textures that
|
||||||
|
// could not be rendered to directly should be reflagged
|
||||||
|
// as RTM_copy_texture.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void GraphicsOutput::
|
||||||
|
end_render_texture() {
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsOutput::change_scenes
|
// Function: GraphicsOutput::change_scenes
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -1095,31 +1164,35 @@ change_scenes(DisplayRegion *new_dr) {
|
|||||||
_cube_map_index = new_cube_map_index;
|
_cube_map_index = new_cube_map_index;
|
||||||
_cube_map_dr = new_dr;
|
_cube_map_dr = new_dr;
|
||||||
|
|
||||||
if (_rtm_mode != RTM_none) {
|
for (int i=0; i<count_textures(); i++) {
|
||||||
if (_rtm_mode == RTM_bind_or_copy) {
|
Texture *texture = get_texture(i);
|
||||||
// In render-to-texture mode, switch the rendering backend to
|
RenderTextureMode rtm_mode = get_rtm_mode(i);
|
||||||
// the new cube map face, so that the subsequent frame will be
|
if (rtm_mode != RTM_none) {
|
||||||
// rendered to the new face.
|
if (rtm_mode == RTM_bind_or_copy) {
|
||||||
|
// In render-to-texture mode, switch the rendering backend to
|
||||||
|
// the new cube map face, so that the subsequent frame will be
|
||||||
|
// rendered to the new face.
|
||||||
|
|
||||||
select_cube_map(new_cube_map_index);
|
select_cube_map(new_cube_map_index);
|
||||||
|
|
||||||
} else if (old_cube_map_index != -1) {
|
} else if (old_cube_map_index != -1) {
|
||||||
// In copy-to-texture mode, copy the just-rendered framebuffer
|
// In copy-to-texture mode, copy the just-rendered framebuffer
|
||||||
// to the old cube map face.
|
// to the old cube map face.
|
||||||
nassertv(old_cube_map_dr != (DisplayRegion *)NULL);
|
nassertv(old_cube_map_dr != (DisplayRegion *)NULL);
|
||||||
if (display_cat.is_debug()) {
|
if (display_cat.is_debug()) {
|
||||||
display_cat.debug()
|
display_cat.debug()
|
||||||
<< "Copying texture for " << get_name() << " at scene change.\n";
|
<< "Copying texture for " << get_name() << " at scene change.\n";
|
||||||
display_cat.debug()
|
display_cat.debug()
|
||||||
<< "cube_map_index = " << old_cube_map_index << "\n";
|
<< "cube_map_index = " << old_cube_map_index << "\n";
|
||||||
}
|
}
|
||||||
RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type());
|
RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type());
|
||||||
if (_rtm_mode == RTM_copy_ram) {
|
if (rtm_mode == RTM_copy_ram) {
|
||||||
_gsg->framebuffer_copy_to_ram(get_texture(), old_cube_map_index,
|
_gsg->framebuffer_copy_to_ram(texture, old_cube_map_index,
|
||||||
old_cube_map_dr, buffer);
|
old_cube_map_dr, buffer);
|
||||||
} else {
|
} else {
|
||||||
_gsg->framebuffer_copy_to_texture(get_texture(), old_cube_map_index,
|
_gsg->framebuffer_copy_to_texture(texture, old_cube_map_index,
|
||||||
old_cube_map_dr, buffer);
|
old_cube_map_dr, buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,9 +84,12 @@ PUBLISHED:
|
|||||||
INLINE GraphicsPipe *get_pipe() const;
|
INLINE GraphicsPipe *get_pipe() const;
|
||||||
INLINE const string &get_name() const;
|
INLINE const string &get_name() const;
|
||||||
|
|
||||||
|
INLINE int count_textures() const;
|
||||||
INLINE bool has_texture() const;
|
INLINE bool has_texture() const;
|
||||||
INLINE Texture *get_texture() const;
|
INLINE Texture *get_texture(int i=0) const;
|
||||||
void setup_render_texture(Texture *tex, RenderTextureMode mode);
|
INLINE RenderTextureMode get_rtm_mode(int i=0) const;
|
||||||
|
void clear_render_textures();
|
||||||
|
void add_render_texture(Texture *tex, RenderTextureMode mode);
|
||||||
void setup_render_texture(Texture *tex, bool allow_bind, bool to_ram);
|
void setup_render_texture(Texture *tex, bool allow_bind, bool to_ram);
|
||||||
|
|
||||||
INLINE int get_x_size() const;
|
INLINE int get_x_size() const;
|
||||||
@ -157,10 +160,13 @@ public:
|
|||||||
// It is an error to call any of the following methods from any
|
// It is an error to call any of the following methods from any
|
||||||
// thread other than the draw thread. These methods are normally
|
// thread other than the draw thread. These methods are normally
|
||||||
// called by the GraphicsEngine.
|
// called by the GraphicsEngine.
|
||||||
virtual bool begin_frame();
|
|
||||||
void clear();
|
void clear();
|
||||||
|
virtual bool begin_frame();
|
||||||
virtual void end_frame();
|
virtual void end_frame();
|
||||||
|
|
||||||
|
virtual void begin_render_texture();
|
||||||
|
virtual void end_render_texture();
|
||||||
|
|
||||||
void change_scenes(DisplayRegion *new_dr);
|
void change_scenes(DisplayRegion *new_dr);
|
||||||
virtual void select_cube_map(int cube_map_index);
|
virtual void select_cube_map(int cube_map_index);
|
||||||
|
|
||||||
@ -182,11 +188,15 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
class RenderTexture {
|
||||||
|
public:
|
||||||
|
PT(Texture) _texture;
|
||||||
|
RenderTextureMode _rtm_mode;
|
||||||
|
};
|
||||||
PT(GraphicsStateGuardian) _gsg;
|
PT(GraphicsStateGuardian) _gsg;
|
||||||
PT(GraphicsPipe) _pipe;
|
PT(GraphicsPipe) _pipe;
|
||||||
string _name;
|
string _name;
|
||||||
PT(Texture) _texture;
|
pvector<RenderTexture> _textures;
|
||||||
RenderTextureMode _rtm_mode;
|
|
||||||
bool _flip_ready;
|
bool _flip_ready;
|
||||||
bool _needs_context;
|
bool _needs_context;
|
||||||
int _cube_map_index;
|
int _cube_map_index;
|
||||||
@ -211,11 +221,11 @@ protected:
|
|||||||
bool _inverted;
|
bool _inverted;
|
||||||
bool _delete_flag;
|
bool _delete_flag;
|
||||||
|
|
||||||
// This weak pointer is used to keep track of whether the buffer's
|
// These weak pointers are used to keep track of whether the
|
||||||
// bound Texture has been deleted or not. Until it has, we don't
|
// buffer's bound Texture has been deleted or not. Until they have,
|
||||||
// auto-close the buffer (since that would deallocate the memory
|
// we don't auto-close the buffer (since that would deallocate the
|
||||||
// associated with the texture).
|
// memory associated with the texture).
|
||||||
WPT(Texture) _hold_texture;
|
pvector<WPT(Texture)> _hold_textures;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Mutex _lock;
|
Mutex _lock;
|
||||||
|
@ -971,39 +971,6 @@ end_draw_primitives() {
|
|||||||
_vertex_data = NULL;
|
_vertex_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: GraphicsStateGuardian::framebuffer_bind_to_texture
|
|
||||||
// Access: Public, Virtual
|
|
||||||
// Description: Works in lieu of copy_texture() to bind the primary
|
|
||||||
// render buffer of the framebuffer to the indicated
|
|
||||||
// texture (which must have been created via
|
|
||||||
// GraphicsOutput::setup_render_texture()).
|
|
||||||
//
|
|
||||||
// If supported by the graphics backend, this will make
|
|
||||||
// the framebuffer memory directly accessible within the
|
|
||||||
// texture, but the frame cannot be rendered again until
|
|
||||||
// framebuffer_release_texture() is called.
|
|
||||||
//
|
|
||||||
// The return value is true if successful, false on
|
|
||||||
// failure.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool GraphicsStateGuardian::
|
|
||||||
framebuffer_bind_to_texture(GraphicsOutput *, Texture *) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: GraphicsStateGuardian::framebuffer_release_texture
|
|
||||||
// Access: Public, Virtual
|
|
||||||
// Description: Undoes a previous call to
|
|
||||||
// framebuffer_bind_to_texture(). The framebuffer may
|
|
||||||
// again be rendered into, and the contents of the
|
|
||||||
// texture is undefined.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void GraphicsStateGuardian::
|
|
||||||
framebuffer_release_texture(GraphicsOutput *, Texture *) {
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsStateGuardian::do_issue_color_scale
|
// Function: GraphicsStateGuardian::do_issue_color_scale
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -191,9 +191,6 @@ public:
|
|||||||
virtual void draw_points(const GeomPoints *primitive);
|
virtual void draw_points(const GeomPoints *primitive);
|
||||||
virtual void end_draw_primitives();
|
virtual void end_draw_primitives();
|
||||||
|
|
||||||
virtual bool framebuffer_bind_to_texture(GraphicsOutput *win, Texture *tex);
|
|
||||||
virtual void framebuffer_release_texture(GraphicsOutput *win, Texture *tex);
|
|
||||||
|
|
||||||
INLINE bool reset_if_new();
|
INLINE bool reset_if_new();
|
||||||
INLINE void mark_new();
|
INLINE void mark_new();
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
@ -203,9 +203,6 @@ public:
|
|||||||
virtual bool framebuffer_copy_to_ram
|
virtual bool framebuffer_copy_to_ram
|
||||||
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0;
|
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0;
|
||||||
|
|
||||||
virtual bool framebuffer_bind_to_texture(GraphicsOutput *win, Texture *tex)=0;
|
|
||||||
virtual void framebuffer_release_texture(GraphicsOutput *win, Texture *tex)=0;
|
|
||||||
|
|
||||||
virtual CoordinateSystem get_internal_coordinate_system() const=0;
|
virtual CoordinateSystem get_internal_coordinate_system() const=0;
|
||||||
|
|
||||||
virtual void bind_light(PointLight *light_obj, const NodePath &light,
|
virtual void bind_light(PointLight *light_obj, const NodePath &light,
|
||||||
|
@ -89,6 +89,75 @@ begin_frame() {
|
|||||||
return GraphicsBuffer::begin_frame();
|
return GraphicsBuffer::begin_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: wglGraphicsStateGuardian::begin_render_texture
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: If the GraphicsOutput supports direct render-to-texture,
|
||||||
|
// and if any setup needs to be done during begin_frame,
|
||||||
|
// then the setup code should go here. Any textures that
|
||||||
|
// can not be rendered to directly should be reflagged
|
||||||
|
// as RTM_copy_texture.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void wglGraphicsBuffer::
|
||||||
|
begin_render_texture() {
|
||||||
|
wglGraphicsStateGuardian *wglgsg;
|
||||||
|
DCAST_INTO_V(wglgsg, _gsg);
|
||||||
|
|
||||||
|
if (_gsg->get_properties().is_single_buffered()) {
|
||||||
|
wglgsg->_wglReleaseTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB);
|
||||||
|
} else {
|
||||||
|
wglgsg->_wglReleaseTexImageARB(_pbuffer, WGL_BACK_LEFT_ARB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsOutput::end_render_texture
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: If the GraphicsOutput supports direct render-to-texture,
|
||||||
|
// and if any setup needs to be done during end_frame,
|
||||||
|
// then the setup code should go here. Any textures that
|
||||||
|
// could not be rendered to directly should be reflagged
|
||||||
|
// as RTM_copy_texture.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void wglGraphicsBuffer::
|
||||||
|
end_render_texture() {
|
||||||
|
wglGraphicsStateGuardian *wglgsg;
|
||||||
|
DCAST_INTO_V(wglgsg, _gsg);
|
||||||
|
|
||||||
|
// Find the color texture, if there is one. That one can be bound to
|
||||||
|
// the framebuffer. All others must be marked RTM_copy_to_texture.
|
||||||
|
int tex_index = -1;
|
||||||
|
for (int i=0; i<count_textures(); i++) {
|
||||||
|
if (get_rtm_mode(i) == RTM_bind_or_copy) {
|
||||||
|
if ((get_texture(i)->get_format() != Texture::F_depth_component)&&
|
||||||
|
(get_texture(i)->get_format() != Texture::F_stencil_index)&&
|
||||||
|
(tex_index < 0)) {
|
||||||
|
tex_index = i;
|
||||||
|
} else {
|
||||||
|
_textures[i]._rtm_mode = RTM_copy_texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex_index >= 0) {
|
||||||
|
Texture *tex = get_texture(tex_index);
|
||||||
|
TextureContext *tc = tex->prepare_now(_gsg->get_prepared_objects(), _gsg);
|
||||||
|
nassertv(tc != (TextureContext *)NULL);
|
||||||
|
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
||||||
|
GLenum target = wglgsg->get_texture_target(tex->get_texture_type());
|
||||||
|
if (target == GL_NONE) {
|
||||||
|
_textures[tex_index]._rtm_mode = RTM_copy_texture;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GLP(BindTexture)(target, gtc->_index);
|
||||||
|
if (_gsg->get_properties().is_single_buffered()) {
|
||||||
|
wglgsg->_wglBindTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB);
|
||||||
|
} else {
|
||||||
|
wglgsg->_wglBindTexImageARB(_pbuffer, WGL_BACK_LEFT_ARB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: wglGraphicsBuffer::select_cube_map
|
// Function: wglGraphicsBuffer::select_cube_map
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -231,29 +300,6 @@ open_buffer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_pbuffer_dc = wglgsg->_wglGetPbufferDCARB(_pbuffer);
|
_pbuffer_dc = wglgsg->_wglGetPbufferDCARB(_pbuffer);
|
||||||
if (wgldisplay_cat.is_debug()) {
|
|
||||||
wgldisplay_cat.debug()
|
|
||||||
<< "Created PBuffer " << _pbuffer << ", DC " << _pbuffer_dc << "\n";
|
|
||||||
switch (_rtm_mode) {
|
|
||||||
case RTM_bind_or_copy:
|
|
||||||
wgldisplay_cat.debug()
|
|
||||||
<< "pbuffer renders directly to texture.\n";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTM_copy_texture:
|
|
||||||
wgldisplay_cat.debug()
|
|
||||||
<< "pbuffer copies indirectly into texture.\n";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTM_copy_ram:
|
|
||||||
wgldisplay_cat.debug()
|
|
||||||
<< "pbuffer copies indirectly into system RAM.\n";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wglMakeCurrent(_pbuffer_dc, wglgsg->get_context(_pbuffer_dc));
|
wglMakeCurrent(_pbuffer_dc, wglgsg->get_context(_pbuffer_dc));
|
||||||
wglgsg->report_my_gl_errors();
|
wglgsg->report_my_gl_errors();
|
||||||
@ -286,9 +332,15 @@ make_pbuffer(HDC twindow_dc) {
|
|||||||
|
|
||||||
if (wglgsg->_supports_pixel_format) {
|
if (wglgsg->_supports_pixel_format) {
|
||||||
bool got_pbuffer_format = false;
|
bool got_pbuffer_format = false;
|
||||||
|
bool any_binds = false;
|
||||||
|
|
||||||
if ((_rtm_mode == RTM_bind_or_copy) &&
|
for (int i=0; i<count_textures(); i++) {
|
||||||
wglgsg->_supports_render_texture) {
|
if (get_rtm_mode(i) == RTM_bind_or_copy) {
|
||||||
|
any_binds = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (any_binds && wglgsg->_supports_render_texture) {
|
||||||
// First, try to get a pbuffer format that supports
|
// First, try to get a pbuffer format that supports
|
||||||
// render-to-texture.
|
// render-to-texture.
|
||||||
int new_pbformat = choose_pbuffer_format(twindow_dc, true);
|
int new_pbformat = choose_pbuffer_format(twindow_dc, true);
|
||||||
@ -299,8 +351,13 @@ make_pbuffer(HDC twindow_dc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!got_pbuffer_format) {
|
if (!got_pbuffer_format) {
|
||||||
// Failing that, just get a matching pbuffer format.
|
// Failing that, just get a matching pbuffer format,
|
||||||
_rtm_mode = RTM_copy_texture;
|
// and disable RTM_bind_or_copy.
|
||||||
|
for (int i=0; i<count_textures(); i++) {
|
||||||
|
if (get_rtm_mode(i) == RTM_bind_or_copy) {
|
||||||
|
_textures[i]._rtm_mode = RTM_copy_texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
int new_pbformat = choose_pbuffer_format(twindow_dc, false);
|
int new_pbformat = choose_pbuffer_format(twindow_dc, false);
|
||||||
if (new_pbformat != 0) {
|
if (new_pbformat != 0) {
|
||||||
pbformat = new_pbformat;
|
pbformat = new_pbformat;
|
||||||
@ -322,8 +379,18 @@ make_pbuffer(HDC twindow_dc) {
|
|||||||
int iattrib_list[max_attrib_list];
|
int iattrib_list[max_attrib_list];
|
||||||
int ni = 0;
|
int ni = 0;
|
||||||
|
|
||||||
if (_rtm_mode == RTM_bind_or_copy) {
|
// Find the texture to bind to the color buffer.
|
||||||
nassertr(_texture != (Texture *)NULL, false);
|
Texture *bindtexture = NULL;
|
||||||
|
for (int i=0; i<count_textures(); i++) {
|
||||||
|
if ((get_rtm_mode(i) == RTM_bind_or_copy)&&
|
||||||
|
(get_texture(i)->get_format() != Texture::F_depth_component)&&
|
||||||
|
(get_texture(i)->get_format() != Texture::F_stencil_index)) {
|
||||||
|
bindtexture = get_texture(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bindtexture != 0) {
|
||||||
|
|
||||||
if (_gsg->get_properties().get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) {
|
if (_gsg->get_properties().get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) {
|
||||||
iattrib_list[ni++] = WGL_TEXTURE_FORMAT_ARB;
|
iattrib_list[ni++] = WGL_TEXTURE_FORMAT_ARB;
|
||||||
@ -333,12 +400,12 @@ make_pbuffer(HDC twindow_dc) {
|
|||||||
iattrib_list[ni++] = WGL_TEXTURE_RGB_ARB;
|
iattrib_list[ni++] = WGL_TEXTURE_RGB_ARB;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_texture->uses_mipmaps()) {
|
if (bindtexture->uses_mipmaps()) {
|
||||||
iattrib_list[ni++] = WGL_MIPMAP_TEXTURE_ARB;
|
iattrib_list[ni++] = WGL_MIPMAP_TEXTURE_ARB;
|
||||||
iattrib_list[ni++] = 1;
|
iattrib_list[ni++] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (_texture->get_texture_type()) {
|
switch (bindtexture->get_texture_type()) {
|
||||||
case Texture::TT_cube_map:
|
case Texture::TT_cube_map:
|
||||||
iattrib_list[ni++] = WGL_TEXTURE_TARGET_ARB;
|
iattrib_list[ni++] = WGL_TEXTURE_TARGET_ARB;
|
||||||
iattrib_list[ni++] = WGL_TEXTURE_CUBE_MAP_ARB;
|
iattrib_list[ni++] = WGL_TEXTURE_CUBE_MAP_ARB;
|
||||||
|
@ -52,6 +52,9 @@ public:
|
|||||||
virtual void make_current();
|
virtual void make_current();
|
||||||
virtual void release_gsg();
|
virtual void release_gsg();
|
||||||
|
|
||||||
|
virtual void begin_render_texture();
|
||||||
|
virtual void end_render_texture();
|
||||||
|
|
||||||
virtual void process_events();
|
virtual void process_events();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -63,66 +63,6 @@ wglGraphicsStateGuardian::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: wglGraphicsStateGuardian::framebuffer_bind_to_texture
|
|
||||||
// Access: Public, Virtual
|
|
||||||
// Description: Works in lieu of copy_texture() to bind the primary
|
|
||||||
// render buffer of the framebuffer to the indicated
|
|
||||||
// texture (which must have been created via
|
|
||||||
// GraphicsOutput::setup_render_texture()).
|
|
||||||
//
|
|
||||||
// If supported by the graphics backend, this will make
|
|
||||||
// the framebuffer memory directly accessible within the
|
|
||||||
// texture, but the frame cannot be rendered again until
|
|
||||||
// framebuffer_release_texture() is called.
|
|
||||||
//
|
|
||||||
// The return value is true if successful, false on
|
|
||||||
// failure.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool wglGraphicsStateGuardian::
|
|
||||||
framebuffer_bind_to_texture(GraphicsOutput *win, Texture *tex) {
|
|
||||||
wglGraphicsBuffer *buffer;
|
|
||||||
DCAST_INTO_R(buffer, win, false);
|
|
||||||
|
|
||||||
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
|
|
||||||
nassertr(tc != (TextureContext *)NULL, false);
|
|
||||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
|
||||||
GLenum target = get_texture_target(tex->get_texture_type());
|
|
||||||
if (target == GL_NONE) {
|
|
||||||
// Invalid texture, can't bind it.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
GLP(BindTexture)(target, gtc->_index);
|
|
||||||
|
|
||||||
if (get_properties().is_single_buffered()) {
|
|
||||||
_wglBindTexImageARB(buffer->_pbuffer, WGL_FRONT_LEFT_ARB);
|
|
||||||
} else {
|
|
||||||
_wglBindTexImageARB(buffer->_pbuffer, WGL_BACK_LEFT_ARB);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: wglGraphicsStateGuardian::framebuffer_release_texture
|
|
||||||
// Access: Public, Virtual
|
|
||||||
// Description: Undoes a previous call to
|
|
||||||
// framebuffer_bind_to_texture(). The framebuffer may
|
|
||||||
// again be rendered into, and the contents of the
|
|
||||||
// texture is undefined.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void wglGraphicsStateGuardian::
|
|
||||||
framebuffer_release_texture(GraphicsOutput *win, Texture *) {
|
|
||||||
wglGraphicsBuffer *buffer;
|
|
||||||
DCAST_INTO_V(buffer, win);
|
|
||||||
|
|
||||||
if (get_properties().is_single_buffered()) {
|
|
||||||
_wglReleaseTexImageARB(buffer->_pbuffer, WGL_FRONT_LEFT_ARB);
|
|
||||||
} else {
|
|
||||||
_wglReleaseTexImageARB(buffer->_pbuffer, WGL_BACK_LEFT_ARB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: wglGraphicsStateGuardian::reset
|
// Function: wglGraphicsStateGuardian::reset
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -43,9 +43,6 @@ public:
|
|||||||
INLINE bool made_context() const;
|
INLINE bool made_context() const;
|
||||||
INLINE HGLRC get_context(HDC hdc);
|
INLINE HGLRC get_context(HDC hdc);
|
||||||
|
|
||||||
virtual bool framebuffer_bind_to_texture(GraphicsOutput *win, Texture *tex);
|
|
||||||
virtual void framebuffer_release_texture(GraphicsOutput *win, Texture *tex);
|
|
||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|
||||||
INLINE HDC get_twindow_dc();
|
INLINE HDC get_twindow_dc();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user