move GSG::get_supports_render_texture() into GraphicsOutput to support render-to-texture on non-Windows platform. Also, further fixes to FBO render-to-texture.

This commit is contained in:
David Rose 2012-02-11 21:09:35 +00:00
parent 37b5aa6fd2
commit bb8867fb77
21 changed files with 130 additions and 44 deletions

View File

@ -365,15 +365,10 @@ add_render_texture(Texture *tex, RenderTextureMode mode,
tex->set_size_padded(get_x_size(), get_y_size()); tex->set_size_padded(get_x_size(), get_y_size());
if (mode == RTM_bind_or_copy) { if (mode == RTM_bind_or_copy) {
if (!support_render_texture || !get_supports_render_texture()) {
// Binding is not supported or it is disabled, so just fall back // Binding is not supported or it is disabled, so just fall back
// to copy instead. // to copy instead.
if (!support_render_texture) {
mode = RTM_copy_texture; mode = RTM_copy_texture;
} else {
nassertv(_gsg != NULL);
if (!_gsg->get_supports_render_texture()) {
mode = RTM_copy_texture;
}
} }
} }
@ -1128,6 +1123,19 @@ void GraphicsOutput::
unshare_depth_buffer() { unshare_depth_buffer() {
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::get_supports_render_texture
// Access: Published, Virtual
// Description: Returns true if this particular GraphicsOutput can
// render directly into a texture, or false if it must
// always copy-to-texture at the end of each frame to
// achieve this effect.
////////////////////////////////////////////////////////////////////
bool GraphicsOutput::
get_supports_render_texture() const {
return false;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::flip_ready // Function: GraphicsOutput::flip_ready
// Access: Public, Virtual // Access: Public, Virtual

View File

@ -213,6 +213,8 @@ PUBLISHED:
virtual bool share_depth_buffer(GraphicsOutput *graphics_output); virtual bool share_depth_buffer(GraphicsOutput *graphics_output);
virtual void unshare_depth_buffer(); virtual void unshare_depth_buffer();
virtual bool get_supports_render_texture() const;
public: public:
// These are not intended to be called directly by the user. // These are not intended to be called directly by the user.
virtual bool flip_ready() const; virtual bool flip_ready() const;

View File

@ -584,19 +584,6 @@ get_supports_generate_mipmap() const {
return _supports_generate_mipmap; return _supports_generate_mipmap;
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_supports_render_texture
// Access: Published
// Description: Returns true if this particular GSG can render
// directly into a texture, or false if it must always
// copy-to-texture at the end of each frame to achieve
// this effect.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
get_supports_render_texture() const {
return _supports_render_texture;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_supports_depth_texture // Function: GraphicsStateGuardian::get_supports_depth_texture
// Access: Published // Access: Published

View File

@ -210,7 +210,6 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
// Similarly with these capabilities flags. // Similarly with these capabilities flags.
_supports_multisample = false; _supports_multisample = false;
_supports_generate_mipmap = false; _supports_generate_mipmap = false;
_supports_render_texture = false;
_supports_depth_texture = false; _supports_depth_texture = false;
_supports_depth_stencil = false; _supports_depth_stencil = false;
_supports_shadow_filter = false; _supports_shadow_filter = false;

View File

@ -139,7 +139,6 @@ PUBLISHED:
INLINE bool get_copy_texture_inverted() const; INLINE bool get_copy_texture_inverted() const;
virtual bool get_supports_multisample() const; virtual bool get_supports_multisample() const;
INLINE bool get_supports_generate_mipmap() const; INLINE bool get_supports_generate_mipmap() const;
INLINE bool get_supports_render_texture() const;
INLINE bool get_supports_depth_texture() const; INLINE bool get_supports_depth_texture() const;
INLINE bool get_supports_depth_stencil() const; INLINE bool get_supports_depth_stencil() const;
INLINE bool get_supports_shadow_filter() const; INLINE bool get_supports_shadow_filter() const;
@ -478,7 +477,6 @@ protected:
bool _copy_texture_inverted; bool _copy_texture_inverted;
bool _supports_multisample; bool _supports_multisample;
bool _supports_generate_mipmap; bool _supports_generate_mipmap;
bool _supports_render_texture;
bool _supports_depth_texture; bool _supports_depth_texture;
bool _supports_depth_stencil; bool _supports_depth_stencil;
bool _supports_shadow_filter; bool _supports_shadow_filter;

View File

@ -144,3 +144,16 @@ get_safe_buffer_start() {
return _safe_buffer_start; return _safe_buffer_start;
} }
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::get_supports_render_texture
// Access: Published
// Description: Returns true if this particular GSG can render
// from a wdxGraphicsBuffer8 directly into a texture, or
// false if it must always copy-to-texture at the end of
// each frame to achieve this effect.
////////////////////////////////////////////////////////////////////
INLINE bool DXGraphicsStateGuardian8::
get_supports_render_texture() const {
return _supports_render_texture;
}

View File

@ -96,6 +96,7 @@ DXGraphicsStateGuardian8(GraphicsEngine *engine, GraphicsPipe *pipe) :
_vertex_blending_enabled = false; _vertex_blending_enabled = false;
_overlay_windows_supported = false; _overlay_windows_supported = false;
_tex_stats_retrieval_impossible = false; _tex_stats_retrieval_impossible = false;
_supports_render_texture = false;
_active_vbuffer = NULL; _active_vbuffer = NULL;
_active_ibuffer = NULL; _active_ibuffer = NULL;

View File

@ -122,6 +122,7 @@ public:
virtual void set_state_and_transform(const RenderState *state, virtual void set_state_and_transform(const RenderState *state,
const TransformState *transform); const TransformState *transform);
LPDIRECT3DDEVICE8 get_d3d_device(); LPDIRECT3DDEVICE8 get_d3d_device();
INLINE bool get_supports_render_texture() const;
static bool get_gamma_table(void); static bool get_gamma_table(void);
static bool static_set_gamma(bool restore, PN_stdfloat gamma); static bool static_set_gamma(bool restore, PN_stdfloat gamma);
@ -225,6 +226,7 @@ protected:
HRESULT _last_testcooplevel_result; HRESULT _last_testcooplevel_result;
bool _vertex_blending_enabled; bool _vertex_blending_enabled;
bool _supports_render_texture;
RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation
bool _auto_rescale_normal; bool _auto_rescale_normal;

View File

@ -213,3 +213,16 @@ set_sampler_state (DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value)
return hr; return hr;
} }
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian9::get_supports_render_texture
// Access: Published
// Description: Returns true if this particular GSG can render
// from a wdxGraphicsBuffer9 directly into a texture, or
// false if it must always copy-to-texture at the end of
// each frame to achieve this effect.
////////////////////////////////////////////////////////////////////
INLINE bool DXGraphicsStateGuardian9::
get_supports_render_texture() const {
return _supports_render_texture;
}

View File

@ -115,6 +115,7 @@ DXGraphicsStateGuardian9(GraphicsEngine *engine, GraphicsPipe *pipe) :
_vertex_blending_enabled = false; _vertex_blending_enabled = false;
_overlay_windows_supported = false; _overlay_windows_supported = false;
_tex_stats_retrieval_impossible = false; _tex_stats_retrieval_impossible = false;
_supports_render_texture = false;
_active_ibuffer = NULL; _active_ibuffer = NULL;

View File

@ -157,6 +157,8 @@ public:
INLINE HRESULT set_texture_stage_state (DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value); INLINE HRESULT set_texture_stage_state (DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value);
INLINE HRESULT set_sampler_state (DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value); INLINE HRESULT set_sampler_state (DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value);
INLINE bool get_supports_render_texture() const;
static bool get_gamma_table(void); static bool get_gamma_table(void);
static bool static_set_gamma(bool restore, PN_stdfloat gamma); static bool static_set_gamma(bool restore, PN_stdfloat gamma);
bool set_gamma(PN_stdfloat gamma); bool set_gamma(PN_stdfloat gamma);
@ -269,6 +271,7 @@ protected:
HRESULT _last_testcooplevel_result; HRESULT _last_testcooplevel_result;
bool _vertex_blending_enabled; bool _vertex_blending_enabled;
bool _supports_render_texture;
RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation
bool _auto_rescale_normal; bool _auto_rescale_normal;

View File

@ -232,11 +232,15 @@ make_output(const string &name,
bool support_rtt; bool support_rtt;
support_rtt = false; support_rtt = false;
/*
Currently, no support for eglGraphicsBuffer render-to-texture.
if (eglgsg) { if (eglgsg) {
support_rtt = support_rtt =
eglgsg -> get_supports_render_texture() && eglgsg -> get_supports_render_texture() &&
support_render_texture; support_render_texture;
} }
*/
// First thing to try: an eglGraphicsWindow // First thing to try: an eglGraphicsWindow
if (retry == 0) { if (retry == 0) {

View File

@ -158,7 +158,6 @@ begin_frame(FrameMode mode, Thread *current_thread) {
} }
} }
if (_needs_rebuild) {
rebuild_bitplanes(); rebuild_bitplanes();
if (_needs_rebuild) { if (_needs_rebuild) {
@ -167,7 +166,6 @@ begin_frame(FrameMode mode, Thread *current_thread) {
return false; return false;
} }
} }
}
_gsg->set_current_properties(&get_fb_properties()); _gsg->set_current_properties(&get_fb_properties());
report_my_gl_errors(); report_my_gl_errors();
@ -237,13 +235,14 @@ rebuild_bitplanes() {
return; return;
} }
if (!_needs_rebuild) {
return;
}
CLP(GraphicsStateGuardian) *glgsg; CLP(GraphicsStateGuardian) *glgsg;
DCAST_INTO_V(glgsg, _gsg); DCAST_INTO_V(glgsg, _gsg);
if (!_needs_rebuild) {
glgsg->bind_fbo(_fbo[0]);
return;
}
// Calculate bitplane size. This can be larger than the buffer. // Calculate bitplane size. This can be larger than the buffer.
if (_creation_flags & GraphicsPipe::BF_size_track_host) { if (_creation_flags & GraphicsPipe::BF_size_track_host) {
if ((_host->get_x_size() != _x_size)|| if ((_host->get_x_size() != _x_size)||
@ -290,10 +289,6 @@ rebuild_bitplanes() {
continue; continue;
} }
if (tex->get_texture_type() == Texture::TT_cube_map) {
any_cube_maps = true;
}
// If I can't find an appropriate slot, or if there's // If I can't find an appropriate slot, or if there's
// already a texture bound to this slot, then punt // already a texture bound to this slot, then punt
// this texture. // this texture.
@ -301,8 +296,12 @@ rebuild_bitplanes() {
((CData *)cdata.p())->_textures[i]._rtm_mode = RTM_copy_texture; ((CData *)cdata.p())->_textures[i]._rtm_mode = RTM_copy_texture;
continue; continue;
} }
// Assign the texture to this slot. // Assign the texture to this slot.
attach[plane] = tex; attach[plane] = tex;
if (tex->get_texture_type() == Texture::TT_cube_map) {
any_cube_maps = true;
}
} }
} }
@ -1018,6 +1017,20 @@ unshare_depth_buffer() {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: glGraphicsBuffer::get_supports_render_texture
// Access: Published, Virtual
// Description: Returns true if this particular GraphicsOutput can
// render directly into a texture, or false if it must
// always copy-to-texture at the end of each frame to
// achieve this effect.
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsBuffer)::
get_supports_render_texture() const {
// FBO-based buffers, by their nature, can always bind-to-texture.
return true;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: glGraphicsBuffer::register_shared_depth_buffer // Function: glGraphicsBuffer::register_shared_depth_buffer
// Access: Public // Access: Public

View File

@ -77,6 +77,8 @@ public:
virtual bool share_depth_buffer(GraphicsOutput *graphics_output); virtual bool share_depth_buffer(GraphicsOutput *graphics_output);
virtual void unshare_depth_buffer(); virtual void unshare_depth_buffer();
virtual bool get_supports_render_texture() const;
void register_shared_depth_buffer(GraphicsOutput *graphics_output); void register_shared_depth_buffer(GraphicsOutput *graphics_output);
void unregister_shared_depth_buffer(GraphicsOutput *graphics_output); void unregister_shared_depth_buffer(GraphicsOutput *graphics_output);

View File

@ -95,11 +95,15 @@ make_output(const string &name,
bool support_rtt; bool support_rtt;
support_rtt = false; support_rtt = false;
/*
Currently, no support for glxGraphicsBuffer render-to-texture.
if (glxgsg) { if (glxgsg) {
support_rtt = support_rtt =
glxgsg -> get_supports_render_texture() && glxgsg -> get_supports_render_texture() &&
support_render_texture; support_render_texture;
} }
*/
// First thing to try: a glxGraphicsWindow // First thing to try: a glxGraphicsWindow
if (retry == 0) { if (retry == 0) {

View File

@ -253,6 +253,25 @@ process_events() {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsBuffer::get_supports_render_texture
// Access: Published, Virtual
// Description: Returns true if this particular GraphicsOutput can
// render directly into a texture, or false if it must
// always copy-to-texture at the end of each frame to
// achieve this effect.
////////////////////////////////////////////////////////////////////
bool wglGraphicsBuffer::
get_supports_render_texture() const {
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
wglGraphicsStateGuardian *wglgsg;
DCAST_INTO_R(wglgsg, _gsg, false);
return wglgsg->get_supports_wgl_render_texture();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: wglGraphicsBuffer::close_buffer // Function: wglGraphicsBuffer::close_buffer
// Access: Protected, Virtual // Access: Protected, Virtual

View File

@ -53,6 +53,8 @@ public:
virtual void process_events(); virtual void process_events();
virtual bool get_supports_render_texture() const;
protected: protected:
virtual void close_buffer(); virtual void close_buffer();
virtual bool open_buffer(); virtual bool open_buffer();

View File

@ -126,7 +126,7 @@ make_output(const string &name,
support_rtt = false; support_rtt = false;
if (wglgsg) { if (wglgsg) {
support_rtt = support_rtt =
wglgsg -> get_supports_render_texture() && wglgsg -> get_supports_wgl_render_texture() &&
support_render_texture; support_render_texture;
} }

View File

@ -100,3 +100,15 @@ get_twindow_dc() {
return _twindow_dc; return _twindow_dc;
} }
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsStateGuardian::get_supports_wgl_render_texture
// Access: Published
// Description: Returns true if this particular GSG can render
// from a wglGraphicsBuffer directly into a texture, or
// false if it must always copy-to-texture at the end of
// each frame to achieve this effect.
////////////////////////////////////////////////////////////////////
INLINE bool wglGraphicsStateGuardian::
get_supports_wgl_render_texture() const {
return _supports_wgl_render_texture;
}

View File

@ -45,6 +45,7 @@ wglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
_supports_pbuffer = false; _supports_pbuffer = false;
_supports_pixel_format = false; _supports_pixel_format = false;
_supports_wgl_multisample = false; _supports_wgl_multisample = false;
_supports_wgl_render_texture = false;
get_gamma_table(); get_gamma_table();
atexit(atexit_function); atexit(atexit_function);
@ -518,9 +519,9 @@ reset() {
_supports_wgl_multisample = has_extension("WGL_ARB_multisample"); _supports_wgl_multisample = has_extension("WGL_ARB_multisample");
_supports_render_texture = has_extension("WGL_ARB_render_texture"); _supports_wgl_render_texture = has_extension("WGL_ARB_render_texture");
if (_supports_render_texture) { if (_supports_wgl_render_texture) {
_wglBindTexImageARB = _wglBindTexImageARB =
(PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress("wglBindTexImageARB"); (PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress("wglBindTexImageARB");
_wglReleaseTexImageARB = _wglReleaseTexImageARB =
@ -532,7 +533,7 @@ reset() {
_wglSetPbufferAttribARB == NULL) { _wglSetPbufferAttribARB == NULL) {
wgldisplay_cat.error() wgldisplay_cat.error()
<< "Driver claims to support WGL_ARB_render_texture, but does not define all functions.\n"; << "Driver claims to support WGL_ARB_render_texture, but does not define all functions.\n";
_supports_render_texture = false; _supports_wgl_render_texture = false;
} }
} }
} }

View File

@ -47,6 +47,7 @@ public:
virtual void reset(); virtual void reset();
INLINE HDC get_twindow_dc(); INLINE HDC get_twindow_dc();
INLINE bool get_supports_wgl_render_texture() const;
static bool get_gamma_table(void); static bool get_gamma_table(void);
static bool static_set_gamma(bool restore, PN_stdfloat gamma); static bool static_set_gamma(bool restore, PN_stdfloat gamma);
@ -54,6 +55,7 @@ public:
void restore_gamma(); void restore_gamma();
static void atexit_function(void); static void atexit_function(void);
protected: protected:
virtual void get_extra_extensions(); virtual void get_extra_extensions();
virtual void *do_get_extension_func(const char *prefix, const char *name); virtual void *do_get_extension_func(const char *prefix, const char *name);
@ -84,7 +86,6 @@ private:
FrameBufferProperties _pre_pfnum_properties; FrameBufferProperties _pre_pfnum_properties;
int _pre_pfnum; int _pre_pfnum;
bool _made_context; bool _made_context;
HGLRC _context; HGLRC _context;
@ -112,6 +113,7 @@ public:
bool _supports_wgl_multisample; bool _supports_wgl_multisample;
bool _supports_wgl_render_texture;
PFNWGLBINDTEXIMAGEARBPROC _wglBindTexImageARB; PFNWGLBINDTEXIMAGEARBPROC _wglBindTexImageARB;
PFNWGLRELEASETEXIMAGEARBPROC _wglReleaseTexImageARB; PFNWGLRELEASETEXIMAGEARBPROC _wglReleaseTexImageARB;
PFNWGLSETPBUFFERATTRIBARBPROC _wglSetPbufferAttribARB; PFNWGLSETPBUFFERATTRIBARBPROC _wglSetPbufferAttribARB;