mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
fixes to depth buffer for cube maps
This commit is contained in:
parent
d743dc8a55
commit
fffc982206
@ -245,6 +245,7 @@ void GraphicsOutput::
|
|||||||
clear_render_textures() {
|
clear_render_textures() {
|
||||||
CDWriter cdata(_cycler, true);
|
CDWriter cdata(_cycler, true);
|
||||||
cdata->_textures.clear();
|
cdata->_textures.clear();
|
||||||
|
++(cdata->_textures_seq);
|
||||||
throw_event("render-texture-targets-changed");
|
throw_event("render-texture-targets-changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,6 +389,7 @@ add_render_texture(Texture *tex, RenderTextureMode mode,
|
|||||||
result._plane = plane;
|
result._plane = plane;
|
||||||
result._rtm_mode = mode;
|
result._rtm_mode = mode;
|
||||||
cdata->_textures.push_back(result);
|
cdata->_textures.push_back(result);
|
||||||
|
++(cdata->_textures_seq);
|
||||||
|
|
||||||
throw_event("render-texture-targets-changed");
|
throw_event("render-texture-targets-changed");
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "cycleDataReader.h"
|
#include "cycleDataReader.h"
|
||||||
#include "cycleDataWriter.h"
|
#include "cycleDataWriter.h"
|
||||||
#include "pipelineCycler.h"
|
#include "pipelineCycler.h"
|
||||||
|
#include "updateSeq.h"
|
||||||
|
|
||||||
class PNMImage;
|
class PNMImage;
|
||||||
class GraphicsEngine;
|
class GraphicsEngine;
|
||||||
@ -345,6 +346,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
RenderTextures _textures;
|
RenderTextures _textures;
|
||||||
|
UpdateSeq _textures_seq;
|
||||||
bool _active;
|
bool _active;
|
||||||
int _one_shot_frame;
|
int _one_shot_frame;
|
||||||
ActiveDisplayRegions _active_display_regions;
|
ActiveDisplayRegions _active_display_regions;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TypeHandle CLP(GraphicsBuffer)::_type_handle;
|
TypeHandle CLP(GraphicsBuffer)::_type_handle;
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: glGraphicsBuffer::Constructor
|
// Function: glGraphicsBuffer::Constructor
|
||||||
@ -36,9 +37,11 @@ CLP(GraphicsBuffer)(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||||||
_screenshot_buffer_type = RenderBuffer::T_front;
|
_screenshot_buffer_type = RenderBuffer::T_front;
|
||||||
|
|
||||||
// Initialize these.
|
// Initialize these.
|
||||||
_fbo = 0;
|
_num_faces = 0;
|
||||||
|
memset(_fbo, 0, sizeof(_fbo));
|
||||||
_fbo_multisample = 0;
|
_fbo_multisample = 0;
|
||||||
_initial_clear = true;
|
_initial_clear = true;
|
||||||
|
_needs_rebuild = true;
|
||||||
DCAST_INTO_V(glgsg, _gsg);
|
DCAST_INTO_V(glgsg, _gsg);
|
||||||
|
|
||||||
if (glgsg->get_supports_framebuffer_multisample() && glgsg->get_supports_framebuffer_blit()) {
|
if (glgsg->get_supports_framebuffer_multisample() && glgsg->get_supports_framebuffer_blit()) {
|
||||||
@ -72,18 +75,14 @@ CLP(GraphicsBuffer)(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||||||
|
|
||||||
_rb_size_x = 0;
|
_rb_size_x = 0;
|
||||||
_rb_size_y = 0;
|
_rb_size_y = 0;
|
||||||
_cube_face_active = 0;
|
|
||||||
for (int i=0; i<RTP_COUNT; i++) {
|
for (int i=0; i<RTP_COUNT; i++) {
|
||||||
_rb[i] = 0;
|
_rb[i] = 0;
|
||||||
_tex[i] = 0;
|
_tex[i] = 0;
|
||||||
_rbm[i] = 0;
|
_rbm[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int f = 0; f < 6; f++) {
|
|
||||||
_cubemap_fbo [f] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_shared_depth_buffer = 0;
|
_shared_depth_buffer = 0;
|
||||||
|
_active_cube_map_index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -127,6 +126,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
begin_frame_spam(mode);
|
begin_frame_spam(mode);
|
||||||
|
|
||||||
check_host_valid();
|
check_host_valid();
|
||||||
|
_active_cube_map_index = -1;
|
||||||
|
|
||||||
if (!_is_valid) {
|
if (!_is_valid) {
|
||||||
if (GLCAT.is_debug()) {
|
if (GLCAT.is_debug()) {
|
||||||
@ -147,13 +147,25 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
// Figure out the desired size of the buffer.
|
// Figure out the desired size of the buffer.
|
||||||
if (mode == FM_render) {
|
if (mode == FM_render) {
|
||||||
clear_cube_map_selection();
|
clear_cube_map_selection();
|
||||||
rebuild_bitplanes();
|
|
||||||
if (!check_fbo()) {
|
{
|
||||||
if (GLCAT.is_debug()) {
|
// If the set of render-to-textures has recently changed, we
|
||||||
GLCAT.debug()
|
// need to rebuild bitplanes.
|
||||||
<< get_name() << " check_fbo() returns false\n";
|
CDReader cdata(_cycler);
|
||||||
|
if (cdata->_textures_seq != _last_textures_seq) {
|
||||||
|
_last_textures_seq = cdata->_textures_seq;
|
||||||
|
_needs_rebuild = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_needs_rebuild) {
|
||||||
|
rebuild_bitplanes();
|
||||||
|
|
||||||
|
if (_needs_rebuild) {
|
||||||
|
// If we still need rebuild, something went wrong with
|
||||||
|
// rebuild_bitplanes().
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,234 +237,160 @@ rebuild_bitplanes() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLP(GraphicsStateGuardian) *glgsg;
|
if (!_needs_rebuild) {
|
||||||
DCAST_INTO_V(glgsg, _gsg);
|
|
||||||
|
|
||||||
// Bind the FBO
|
|
||||||
|
|
||||||
Texture *tex = get_texture(0);
|
|
||||||
if (tex == 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RenderTextureMode rtm_mode = get_rtm_mode(0);
|
|
||||||
|
|
||||||
if (tex->get_texture_type() != Texture::TT_cube_map ||
|
CLP(GraphicsStateGuardian) *glgsg;
|
||||||
rtm_mode != RTM_bind_or_copy) {
|
DCAST_INTO_V(glgsg, _gsg);
|
||||||
// We're not rendering directly to a cube map, so set up the
|
|
||||||
// framebuffers normally.
|
// Calculate bitplane size. This can be larger than the buffer.
|
||||||
if (_fbo == 0) {
|
if (_creation_flags & GraphicsPipe::BF_size_track_host) {
|
||||||
glgsg->_glGenFramebuffers(1, &_fbo);
|
if ((_host->get_x_size() != _x_size)||
|
||||||
if (_fbo == 0) {
|
(_host->get_y_size() != _y_size)) {
|
||||||
|
set_size_and_recalc(_host->get_x_size(),
|
||||||
|
_host->get_y_size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int bitplane_x = _x_size;
|
||||||
|
int bitplane_y = _y_size;
|
||||||
|
if (Texture::get_textures_power_2() != ATS_none) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These variables indicate what should be bound to each bitplane.
|
||||||
|
Texture *attach[RTP_COUNT];
|
||||||
|
memset(attach, 0, sizeof(Texture *) * RTP_COUNT);
|
||||||
|
|
||||||
|
// Sort the textures list into appropriate slots.
|
||||||
|
bool any_cube_maps = false;
|
||||||
|
{
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
for (size_t i = 0; i != cdata->_textures.size(); ++i) {
|
||||||
|
const RenderTexture &rt = cdata->_textures[i];
|
||||||
|
RenderTextureMode rtm_mode = rt._rtm_mode;
|
||||||
|
if (rtm_mode != RTM_bind_or_copy) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Texture *tex = rt._texture;
|
||||||
|
RenderTexturePlane plane = rt._plane;
|
||||||
|
|
||||||
|
// 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)) {
|
||||||
|
((CData *)cdata.p())->_textures[i]._rtm_mode = RTM_copy_texture;
|
||||||
|
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
|
||||||
|
// already a texture bound to this slot, then punt
|
||||||
|
// this texture.
|
||||||
|
if (attach[plane]) {
|
||||||
|
((CData *)cdata.p())->_textures[i]._rtm_mode = RTM_copy_texture;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Assign the texture to this slot.
|
||||||
|
attach[plane] = tex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Having both a depth texture and a depth_stencil texture is
|
||||||
|
// invalid: depth_stencil implies depth, and we can't bind them
|
||||||
|
// both. Detect that case, normalize it, and complain.
|
||||||
|
if (( attach[RTP_depth] != NULL ) && ( attach[RTP_depth_stencil] != NULL )) {
|
||||||
|
attach[RTP_depth] = NULL;
|
||||||
|
GLCAT.warning() << "Attempt to bind both Depth and DepthStencil bitplanes.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
_num_faces = 1;
|
||||||
|
if (any_cube_maps) {
|
||||||
|
_num_faces = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now create the FBO's.
|
||||||
|
for (int face = 0; face < _num_faces; ++face) {
|
||||||
|
// Bind the FBO
|
||||||
|
if (_fbo[face] == 0) {
|
||||||
|
glgsg->_glGenFramebuffers(1, &_fbo[face]);
|
||||||
|
if (_fbo[face] == 0) {
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glgsg->bind_fbo(_fbo);
|
glgsg->bind_fbo(_fbo[face]);
|
||||||
|
|
||||||
// Calculate bitplane size. This can be larger than the buffer.
|
|
||||||
|
|
||||||
if (_creation_flags & GraphicsPipe::BF_size_track_host) {
|
|
||||||
if ((_host->get_x_size() != _x_size)||
|
|
||||||
(_host->get_y_size() != _y_size)) {
|
|
||||||
set_size_and_recalc(_host->get_x_size(),
|
|
||||||
_host->get_y_size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int bitplane_x = _x_size;
|
|
||||||
int bitplane_y = _y_size;
|
|
||||||
if (Texture::get_textures_power_2() != ATS_none) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// These variables indicate what should be bound to each bitplane.
|
|
||||||
|
|
||||||
Texture *attach[RTP_COUNT];
|
|
||||||
attach[RTP_color] = 0;
|
|
||||||
attach[RTP_depth] = 0;
|
|
||||||
attach[RTP_depth_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.
|
|
||||||
|
|
||||||
{
|
|
||||||
CDReader cdata(_cycler);
|
|
||||||
for (size_t i = 0; i != cdata->_textures.size(); ++i) {
|
|
||||||
const RenderTexture &rt = cdata->_textures[i];
|
|
||||||
RenderTextureMode rtm_mode = rt._rtm_mode;
|
|
||||||
if (rtm_mode != RTM_bind_or_copy) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Texture *tex = rt._texture;
|
|
||||||
RenderTexturePlane plane = rt._plane;
|
|
||||||
|
|
||||||
// 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)) {
|
|
||||||
((CData *)cdata.p())->_textures[i]._rtm_mode = RTM_copy_texture;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// 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]) {
|
|
||||||
((CData *)cdata.p())->_textures[i]._rtm_mode = RTM_copy_texture;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Assign the texture to this slot.
|
|
||||||
attach[plane] = tex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Having both a depth texture and a depth_stencil texture is invalid: depth_stencil implies
|
|
||||||
// depth, and we can't bind them both. Detect that case, normalize it, and complain.
|
|
||||||
if (( attach[RTP_depth] != NULL ) && ( attach[RTP_depth_stencil] != NULL )) {
|
|
||||||
attach[RTP_depth] = NULL;
|
|
||||||
GLCAT.warning() << "Attempt to bind both Depth and DepthStencil bitplanes.\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// For all slots, update the slot.
|
// For all slots, update the slot.
|
||||||
|
|
||||||
bind_slot(rb_resize, attach, RTP_depth_stencil, GL_DEPTH_ATTACHMENT_EXT);
|
bind_slot(face, rb_resize, attach, RTP_depth_stencil, GL_DEPTH_ATTACHMENT_EXT);
|
||||||
bind_slot(rb_resize, attach, RTP_depth, GL_DEPTH_ATTACHMENT_EXT);
|
bind_slot(face, rb_resize, attach, RTP_depth, GL_DEPTH_ATTACHMENT_EXT);
|
||||||
bind_slot(rb_resize, attach, RTP_color, GL_COLOR_ATTACHMENT0_EXT);
|
bind_slot(face, rb_resize, attach, RTP_color, GL_COLOR_ATTACHMENT0_EXT);
|
||||||
#ifndef OPENGLES
|
#ifndef OPENGLES
|
||||||
int next = GL_COLOR_ATTACHMENT1_EXT;
|
int next = GL_COLOR_ATTACHMENT1_EXT;
|
||||||
for (int i=0; i<_fb_properties.get_aux_rgba(); i++) {
|
for (int i=0; i<_fb_properties.get_aux_rgba(); i++) {
|
||||||
bind_slot(rb_resize, attach, (RenderTexturePlane)(RTP_aux_rgba_0+i), next);
|
bind_slot(face, rb_resize, attach, (RenderTexturePlane)(RTP_aux_rgba_0+i), next);
|
||||||
next += 1;
|
next += 1;
|
||||||
}
|
}
|
||||||
for (int i=0; i<_fb_properties.get_aux_hrgba(); i++) {
|
for (int i=0; i<_fb_properties.get_aux_hrgba(); i++) {
|
||||||
bind_slot(rb_resize, attach, (RenderTexturePlane)(RTP_aux_hrgba_0+i), next);
|
bind_slot(face, rb_resize, attach, (RenderTexturePlane)(RTP_aux_hrgba_0+i), next);
|
||||||
next += 1;
|
next += 1;
|
||||||
}
|
}
|
||||||
for (int i=0; i<_fb_properties.get_aux_float(); i++) {
|
for (int i=0; i<_fb_properties.get_aux_float(); i++) {
|
||||||
bind_slot(rb_resize, attach, (RenderTexturePlane)(RTP_aux_float_0+i), next);
|
bind_slot(face, rb_resize, attach, (RenderTexturePlane)(RTP_aux_float_0+i), next);
|
||||||
next += 1;
|
next += 1;
|
||||||
}
|
}
|
||||||
// Setup any required multisample buffers.
|
|
||||||
if (_requested_multisamples) {
|
// Clear if the fbo was just created, regardless of the clear settings per frame.
|
||||||
if (_fbo_multisample == 0) {
|
if (_initial_clear) {
|
||||||
glgsg->_glGenFramebuffers(1, &_fbo_multisample);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
}
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
glgsg->bind_fbo(_fbo_multisample);
|
}
|
||||||
bind_slot_multisample(rb_resize, attach, RTP_depth, GL_DEPTH_ATTACHMENT_EXT);
|
}
|
||||||
bind_slot_multisample(rb_resize, attach, RTP_color, GL_COLOR_ATTACHMENT0_EXT);
|
|
||||||
int next = GL_COLOR_ATTACHMENT1_EXT;
|
// Setup any required multisample buffers.
|
||||||
for (int i=0; i<_fb_properties.get_aux_rgba(); i++) {
|
if (_requested_multisamples) {
|
||||||
bind_slot_multisample(rb_resize, attach, (RenderTexturePlane)(RTP_aux_rgba_0+i), next);
|
if (_fbo_multisample == 0) {
|
||||||
next += 1;
|
glgsg->_glGenFramebuffers(1, &_fbo_multisample);
|
||||||
}
|
}
|
||||||
for (int i=0; i<_fb_properties.get_aux_hrgba(); i++) {
|
glgsg->bind_fbo(_fbo_multisample);
|
||||||
bind_slot_multisample(rb_resize, attach, (RenderTexturePlane)(RTP_aux_hrgba_0+i), next);
|
bind_slot_multisample(rb_resize, attach, RTP_depth, GL_DEPTH_ATTACHMENT_EXT);
|
||||||
next += 1;
|
bind_slot_multisample(rb_resize, attach, RTP_color, GL_COLOR_ATTACHMENT0_EXT);
|
||||||
}
|
int next = GL_COLOR_ATTACHMENT1_EXT;
|
||||||
for (int i=0; i<_fb_properties.get_aux_float(); i++) {
|
for (int i=0; i<_fb_properties.get_aux_rgba(); i++) {
|
||||||
bind_slot_multisample(rb_resize, attach, (RenderTexturePlane)(RTP_aux_float_0+i), next);
|
bind_slot_multisample(rb_resize, attach, (RenderTexturePlane)(RTP_aux_rgba_0+i), next);
|
||||||
next += 1;
|
next += 1;
|
||||||
}
|
}
|
||||||
glEnable(GL_MULTISAMPLE);
|
for (int i=0; i<_fb_properties.get_aux_hrgba(); i++) {
|
||||||
} else {
|
bind_slot_multisample(rb_resize, attach, (RenderTexturePlane)(RTP_aux_hrgba_0+i), next);
|
||||||
glDisable(GL_MULTISAMPLE);
|
next += 1;
|
||||||
|
}
|
||||||
|
for (int i=0; i<_fb_properties.get_aux_float(); i++) {
|
||||||
|
bind_slot_multisample(rb_resize, attach, (RenderTexturePlane)(RTP_aux_float_0+i), next);
|
||||||
|
next += 1;
|
||||||
|
}
|
||||||
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
|
if (_initial_clear) {
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
#endif // OPENGLES
|
|
||||||
} else {
|
} else {
|
||||||
// make an FBO for each cubemap face
|
glDisable(GL_MULTISAMPLE);
|
||||||
int update;
|
|
||||||
|
|
||||||
update = false;
|
|
||||||
for (int f = 0; f < 6; f++) {
|
|
||||||
if (_cubemap_fbo [f] == 0) {
|
|
||||||
glgsg->_glGenFramebuffers(1, &_cubemap_fbo [f]);
|
|
||||||
update = true;
|
|
||||||
if (_cubemap_fbo [f] == 0) {
|
|
||||||
report_my_gl_errors();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update) {
|
|
||||||
int color_attachment = GL_COLOR_ATTACHMENT0_EXT;
|
|
||||||
|
|
||||||
for (int i=0; i<count_textures(); i++) {
|
|
||||||
// Do we really need the following lines?
|
|
||||||
// Uncommenting them seems to break stuff.
|
|
||||||
//if (get_rtm_mode(i) != RTM_bind_or_copy) {
|
|
||||||
// continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
Texture *tex = get_texture(i);
|
|
||||||
TextureContext *tc = tex->prepare_now(0, glgsg->get_prepared_objects(), glgsg);
|
|
||||||
nassertv(tc != (TextureContext *)NULL);
|
|
||||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
|
||||||
glgsg->update_texture(tc, true);
|
|
||||||
|
|
||||||
RenderTexturePlane plane = get_texture_plane(i);
|
|
||||||
|
|
||||||
switch (plane) {
|
|
||||||
case RTP_depth:
|
|
||||||
case RTP_depth_stencil:
|
|
||||||
for (int f = 0; f < 6; f++) {
|
|
||||||
glgsg->bind_fbo(_cubemap_fbo [f]);
|
|
||||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + f,
|
|
||||||
gtc->_index, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTP_color:
|
|
||||||
case RTP_aux_rgba_0:
|
|
||||||
case RTP_aux_rgba_1:
|
|
||||||
case RTP_aux_rgba_2:
|
|
||||||
case RTP_aux_rgba_3:
|
|
||||||
case RTP_aux_hrgba_0:
|
|
||||||
case RTP_aux_hrgba_1:
|
|
||||||
case RTP_aux_hrgba_2:
|
|
||||||
case RTP_aux_hrgba_3:
|
|
||||||
case RTP_aux_float_0:
|
|
||||||
case RTP_aux_float_1:
|
|
||||||
case RTP_aux_float_2:
|
|
||||||
case RTP_aux_float_3:
|
|
||||||
for (int f = 0; f < 6; f++) {
|
|
||||||
glgsg->bind_fbo(_cubemap_fbo [f]);
|
|
||||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, color_attachment,
|
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + f,
|
|
||||||
gtc->_index, 0);
|
|
||||||
}
|
|
||||||
color_attachment++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glgsg->bind_fbo(_cubemap_fbo [0]);
|
|
||||||
}
|
}
|
||||||
|
#endif // OPENGLES
|
||||||
|
|
||||||
// Clear if the fbo was just created, regardless of the clear settings per frame.
|
_initial_clear = false;
|
||||||
if (_initial_clear) {
|
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
||||||
_initial_clear = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef OPENGLES
|
#ifndef OPENGLES
|
||||||
if ((_fb_properties.get_rgb_color() > 0) ||
|
if ((_fb_properties.get_rgb_color() > 0) ||
|
||||||
@ -465,8 +403,17 @@ rebuild_bitplanes() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_cube_face_active = 0;
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
|
|
||||||
|
if (!check_fbo()) {
|
||||||
|
if (GLCAT.is_debug()) {
|
||||||
|
GLCAT.debug()
|
||||||
|
<< get_name() << " check_fbo() returns false\n";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_needs_rebuild = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -476,7 +423,7 @@ rebuild_bitplanes() {
|
|||||||
// specified bitplane.
|
// specified bitplane.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CLP(GraphicsBuffer)::
|
void CLP(GraphicsBuffer)::
|
||||||
bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum attachpoint) {
|
bind_slot(int face, bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum attachpoint) {
|
||||||
CLP(GraphicsStateGuardian) *glgsg;
|
CLP(GraphicsStateGuardian) *glgsg;
|
||||||
DCAST_INTO_V(glgsg, _gsg);
|
DCAST_INTO_V(glgsg, _gsg);
|
||||||
|
|
||||||
@ -502,48 +449,43 @@ bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum atta
|
|||||||
|
|
||||||
Texture *tex = attach[slot];
|
Texture *tex = attach[slot];
|
||||||
if (tex) {
|
if (tex) {
|
||||||
// If the texture is already bound to the slot, and it's
|
bool is_cube_map = (tex->get_texture_type() == Texture::TT_cube_map);
|
||||||
// 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)) {
|
|
||||||
tex->set_pad_size(_rb_size_x - _x_size, _rb_size_y - _y_size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind the texture to the slot.
|
// Bind the texture to the slot.
|
||||||
tex->set_x_size(_rb_size_x);
|
tex->set_x_size(_rb_size_x);
|
||||||
tex->set_y_size(_rb_size_y);
|
tex->set_y_size(_rb_size_y);
|
||||||
tex->set_pad_size(_rb_size_x - _x_size, _rb_size_y - _y_size);
|
tex->set_pad_size(_rb_size_x - _x_size, _rb_size_y - _y_size);
|
||||||
|
|
||||||
|
TextureContext *tc = tex->prepare_now(0, glgsg->get_prepared_objects(), glgsg);
|
||||||
|
nassertv(tc != (TextureContext *)NULL);
|
||||||
|
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
||||||
|
glgsg->update_texture(tc, true);
|
||||||
|
|
||||||
_use_depth_stencil = false;
|
_use_depth_stencil = false;
|
||||||
if (attachpoint == GL_DEPTH_ATTACHMENT_EXT) {
|
if (attachpoint == GL_DEPTH_ATTACHMENT_EXT) {
|
||||||
if ( _gsg->get_supports_depth_stencil() && tex->get_format() == Texture::F_depth_stencil ) {
|
if ( _gsg->get_supports_depth_stencil() && tex->get_format() == Texture::F_depth_stencil ) {
|
||||||
tex->set_component_type(Texture::T_unsigned_int_24_8);
|
tex->set_component_type(Texture::T_unsigned_int_24_8);
|
||||||
_use_depth_stencil = true;
|
_use_depth_stencil = true;
|
||||||
}
|
}
|
||||||
TextureContext *tc = tex->prepare_now(0, glgsg->get_prepared_objects(), glgsg);
|
|
||||||
nassertv(tc != (TextureContext *)NULL);
|
|
||||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
|
||||||
glgsg->update_texture(tc, true);
|
|
||||||
#ifndef OPENGLES
|
#ifndef OPENGLES
|
||||||
GLclampf priority = 1.0f;
|
GLclampf priority = 1.0f;
|
||||||
glPrioritizeTextures(1, >c->_index, &priority);
|
glPrioritizeTextures(1, >c->_index, &priority);
|
||||||
#endif
|
#endif
|
||||||
if (_cube_map_index < 0) {
|
if (!is_cube_map) {
|
||||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
||||||
GL_TEXTURE_2D, gtc->_index, 0);
|
GL_TEXTURE_2D, gtc->_index, 0);
|
||||||
} else {
|
} else {
|
||||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
|
||||||
gtc->_index, 0);
|
gtc->_index, 0);
|
||||||
}
|
}
|
||||||
if (_use_depth_stencil) {
|
if (_use_depth_stencil) {
|
||||||
if (_cube_map_index < 0) {
|
if (!is_cube_map) {
|
||||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
|
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
|
||||||
GL_TEXTURE_2D, gtc->_index, 0);
|
GL_TEXTURE_2D, gtc->_index, 0);
|
||||||
} else {
|
} else {
|
||||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
|
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
|
||||||
gtc->_index, 0);
|
gtc->_index, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -560,20 +502,17 @@ bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum atta
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TextureContext *tc = tex->prepare_now(0, glgsg->get_prepared_objects(), glgsg);
|
|
||||||
nassertv(tc != (TextureContext *)NULL);
|
|
||||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
|
||||||
#ifndef OPENGLES
|
#ifndef OPENGLES
|
||||||
GLclampf priority = 1.0f;
|
GLclampf priority = 1.0f;
|
||||||
glPrioritizeTextures(1, >c->_index, &priority);
|
glPrioritizeTextures(1, >c->_index, &priority);
|
||||||
#endif
|
#endif
|
||||||
glgsg->update_texture(tc, true);
|
glgsg->update_texture(tc, true);
|
||||||
if (_cube_map_index < 0) {
|
if (!is_cube_map) {
|
||||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachpoint,
|
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachpoint,
|
||||||
GL_TEXTURE_2D, gtc->_index, 0);
|
GL_TEXTURE_2D, gtc->_index, 0);
|
||||||
} else {
|
} else {
|
||||||
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachpoint,
|
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachpoint,
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
|
||||||
gtc->_index, 0);
|
gtc->_index, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -591,12 +530,6 @@ bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum atta
|
|||||||
// Disconnect from any texture that was previously bound to this slot.
|
// Disconnect from any texture that was previously bound to this slot.
|
||||||
_tex[slot] = 0;
|
_tex[slot] = 0;
|
||||||
|
|
||||||
// If a renderbuffer is already attached to the slot, and it's
|
|
||||||
// the right size, then no update of this slot is needed.
|
|
||||||
if (_shared_depth_buffer == 0 && (_rb[slot] != 0)&&(!rb_resize)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef OPENGLES_2
|
#ifndef OPENGLES_2
|
||||||
// Check for the tricky case of a depth_stencil buffer:
|
// Check for the tricky case of a depth_stencil buffer:
|
||||||
// If we think we need one, but we have a texture bound in the depth slot,
|
// If we think we need one, but we have a texture bound in the depth slot,
|
||||||
@ -649,9 +582,9 @@ bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum atta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll bail out before here if we set a depth_stencil buffer, or figure out that we're
|
// We'll bail out before here if we set a depth_stencil buffer,
|
||||||
// GOING to set a depth_stencil buffer.
|
// or figure out that we're GOING to set a depth_stencil buffer.
|
||||||
//
|
|
||||||
// If we get here, we're using the simple fallback case.
|
// If we get here, we're using the simple fallback case.
|
||||||
#endif
|
#endif
|
||||||
#ifdef OPENGLES
|
#ifdef OPENGLES
|
||||||
@ -680,6 +613,8 @@ bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum atta
|
|||||||
GL_RENDERBUFFER_EXT, _rb[slot]);
|
GL_RENDERBUFFER_EXT, _rb[slot]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
report_my_gl_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -833,10 +768,16 @@ generate_mipmaps() {
|
|||||||
// after rendering is completed for a given frame. It
|
// after rendering is completed for a given frame. It
|
||||||
// should do whatever finalization is required.
|
// should do whatever finalization is required.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CLP(GraphicsBuffer)::end_frame(FrameMode mode, Thread *current_thread) {
|
void CLP(GraphicsBuffer)::
|
||||||
|
end_frame(FrameMode mode, Thread *current_thread) {
|
||||||
end_frame_spam(mode);
|
end_frame_spam(mode);
|
||||||
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
||||||
|
|
||||||
|
// Resolve Multisample rendering if using it.
|
||||||
|
if (_requested_multisamples && _fbo_multisample) {
|
||||||
|
resolve_multisamples();
|
||||||
|
}
|
||||||
|
|
||||||
if (mode == FM_render) {
|
if (mode == FM_render) {
|
||||||
copy_to_textures();
|
copy_to_textures();
|
||||||
}
|
}
|
||||||
@ -844,79 +785,8 @@ void CLP(GraphicsBuffer)::end_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
// Unbind the FBO
|
// Unbind the FBO
|
||||||
CLP(GraphicsStateGuardian) *glgsg;
|
CLP(GraphicsStateGuardian) *glgsg;
|
||||||
DCAST_INTO_V(glgsg, _gsg);
|
DCAST_INTO_V(glgsg, _gsg);
|
||||||
|
|
||||||
// Resolve Multisample rendering if using it.
|
|
||||||
if (_requested_multisamples && _fbo_multisample) {
|
|
||||||
glgsg->report_my_gl_errors();
|
|
||||||
glgsg->_glBindFramebuffer( GL_DRAW_FRAMEBUFFER_EXT, _fbo );
|
|
||||||
glgsg->_glBindFramebuffer( GL_READ_FRAMEBUFFER_EXT, _fbo_multisample );
|
|
||||||
|
|
||||||
// If the depth buffer is shared, resolve it only on the last to render FBO.
|
|
||||||
int do_depth_blit = 0;
|
|
||||||
if (_shared_depth_buffer) {
|
|
||||||
CLP(GraphicsBuffer) *graphics_buffer = NULL;
|
|
||||||
CLP(GraphicsBuffer) *highest_sort_graphics_buffer = NULL;
|
|
||||||
list <CLP(GraphicsBuffer) *>::iterator graphics_buffer_iterator;
|
|
||||||
|
|
||||||
int max_sort_order = 0;
|
|
||||||
for (graphics_buffer_iterator = _shared_depth_buffer_list.begin();
|
|
||||||
graphics_buffer_iterator != _shared_depth_buffer_list.end();
|
|
||||||
graphics_buffer_iterator++) {
|
|
||||||
graphics_buffer = (*graphics_buffer_iterator);
|
|
||||||
if (graphics_buffer) {
|
|
||||||
// this call removes the entry from the list
|
|
||||||
if ( graphics_buffer->get_sort() >= max_sort_order ) {
|
|
||||||
max_sort_order = graphics_buffer->get_sort();
|
|
||||||
highest_sort_graphics_buffer = graphics_buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (max_sort_order == this->get_sort()) {
|
|
||||||
do_depth_blit = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
do_depth_blit = 1;
|
|
||||||
}
|
|
||||||
if (do_depth_blit) {
|
|
||||||
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
|
|
||||||
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
|
|
||||||
GL_NEAREST);
|
|
||||||
} else {
|
|
||||||
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
|
|
||||||
GL_COLOR_BUFFER_BIT,
|
|
||||||
GL_NEAREST);
|
|
||||||
}
|
|
||||||
#ifndef OPENGLES
|
|
||||||
// Now handle the other color buffers.
|
|
||||||
int next = GL_COLOR_ATTACHMENT1_EXT;
|
|
||||||
for (int i=0; i<_fb_properties.get_aux_rgba(); i++) {
|
|
||||||
glReadBuffer( next );
|
|
||||||
glDrawBuffer( next );
|
|
||||||
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
|
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
next += 1;
|
|
||||||
}
|
|
||||||
for (int i=0; i<_fb_properties.get_aux_hrgba(); i++) {
|
|
||||||
glReadBuffer( next );
|
|
||||||
glDrawBuffer( next );
|
|
||||||
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
|
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
next += 1;
|
|
||||||
}
|
|
||||||
for (int i=0; i<_fb_properties.get_aux_float(); i++) {
|
|
||||||
glReadBuffer( next );
|
|
||||||
glDrawBuffer( next );
|
|
||||||
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
|
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
next += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
|
||||||
#endif
|
|
||||||
glgsg->report_my_gl_errors();
|
|
||||||
}
|
|
||||||
glgsg->bind_fbo(0);
|
glgsg->bind_fbo(0);
|
||||||
|
_active_cube_map_index = -1;
|
||||||
|
|
||||||
if (mode == FM_render) {
|
if (mode == FM_render) {
|
||||||
generate_mipmaps();
|
generate_mipmaps();
|
||||||
@ -942,15 +812,20 @@ void CLP(GraphicsBuffer)::end_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CLP(GraphicsBuffer)::
|
void CLP(GraphicsBuffer)::
|
||||||
select_cube_map(int cube_map_index) {
|
select_cube_map(int cube_map_index) {
|
||||||
if (cube_map_index == _cube_face_active) {
|
nassertv(cube_map_index >=0 && cube_map_index < _num_faces);
|
||||||
return;
|
|
||||||
|
if (_active_cube_map_index != -1) {
|
||||||
|
// Resolve the multisample rendering for the previous face.
|
||||||
|
if (_requested_multisamples && _fbo_multisample) {
|
||||||
|
resolve_multisamples();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_cube_face_active = cube_map_index;
|
|
||||||
|
|
||||||
CLP(GraphicsStateGuardian) *glgsg;
|
CLP(GraphicsStateGuardian) *glgsg;
|
||||||
DCAST_INTO_V(glgsg, _gsg);
|
DCAST_INTO_V(glgsg, _gsg);
|
||||||
|
|
||||||
glgsg->bind_fbo(_cubemap_fbo [cube_map_index]);
|
glgsg->bind_fbo(_fbo[cube_map_index]);
|
||||||
|
_active_cube_map_index = cube_map_index;
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
}
|
}
|
||||||
@ -1009,6 +884,7 @@ open_buffer() {
|
|||||||
_fb_properties.set_force_software(_host->get_fb_properties().get_force_software());
|
_fb_properties.set_force_software(_host->get_fb_properties().get_force_software());
|
||||||
|
|
||||||
_is_valid = true;
|
_is_valid = true;
|
||||||
|
_needs_rebuild = true;
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1055,19 +931,12 @@ close_buffer() {
|
|||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
|
|
||||||
// Delete the FBO itself.
|
// Delete the FBO itself.
|
||||||
if (_fbo != 0) {
|
for (int face = 0; face < _num_faces; ++face) {
|
||||||
glgsg->_glDeleteFramebuffers(1, &_fbo);
|
glgsg->_glDeleteFramebuffers(1, &_fbo[face]);
|
||||||
_fbo = 0;
|
|
||||||
}
|
}
|
||||||
report_my_gl_errors();
|
_num_faces = 0;
|
||||||
|
|
||||||
for (int f = 0; f < 6; f++) {
|
report_my_gl_errors();
|
||||||
if (_cubemap_fbo [f]) {
|
|
||||||
glgsg->_glDeleteFramebuffers(1, &_cubemap_fbo [f]);
|
|
||||||
_cubemap_fbo [f] = 0;
|
|
||||||
report_my_gl_errors();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release the Gsg
|
// Release the Gsg
|
||||||
_gsg.clear();
|
_gsg.clear();
|
||||||
@ -1124,6 +993,7 @@ share_depth_buffer(GraphicsOutput *graphics_output) {
|
|||||||
_shared_depth_buffer = input_graphics_output;
|
_shared_depth_buffer = input_graphics_output;
|
||||||
state = true;
|
state = true;
|
||||||
}
|
}
|
||||||
|
_needs_rebuild = true;
|
||||||
}
|
}
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
return state;
|
return state;
|
||||||
@ -1141,6 +1011,7 @@ unshare_depth_buffer() {
|
|||||||
// sharing its depth buffer
|
// sharing its depth buffer
|
||||||
_shared_depth_buffer -> unregister_shared_depth_buffer(this);
|
_shared_depth_buffer -> unregister_shared_depth_buffer(this);
|
||||||
_shared_depth_buffer = 0;
|
_shared_depth_buffer = 0;
|
||||||
|
_needs_rebuild = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1209,3 +1080,101 @@ check_host_valid() {
|
|||||||
_host.clear();
|
_host.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glGraphicsBuffer::resolve_multisamples
|
||||||
|
// Access: Private
|
||||||
|
// Description: After the frame has been rendered into the
|
||||||
|
// multisample buffer, filters it down into the final
|
||||||
|
// render buffer.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(GraphicsBuffer)::
|
||||||
|
resolve_multisamples() {
|
||||||
|
CLP(GraphicsStateGuardian) *glgsg;
|
||||||
|
DCAST_INTO_V(glgsg, _gsg);
|
||||||
|
|
||||||
|
glgsg->report_my_gl_errors();
|
||||||
|
GLuint fbo = _fbo[0];
|
||||||
|
if (_active_cube_map_index != -1) {
|
||||||
|
fbo = _fbo[_active_cube_map_index];
|
||||||
|
}
|
||||||
|
glgsg->_glBindFramebuffer( GL_DRAW_FRAMEBUFFER_EXT, fbo );
|
||||||
|
glgsg->_glBindFramebuffer( GL_READ_FRAMEBUFFER_EXT, _fbo_multisample );
|
||||||
|
|
||||||
|
// If the depth buffer is shared, resolve it only on the last to render FBO.
|
||||||
|
int do_depth_blit = 0;
|
||||||
|
if (_shared_depth_buffer) {
|
||||||
|
CLP(GraphicsBuffer) *graphics_buffer = NULL;
|
||||||
|
CLP(GraphicsBuffer) *highest_sort_graphics_buffer = NULL;
|
||||||
|
list <CLP(GraphicsBuffer) *>::iterator graphics_buffer_iterator;
|
||||||
|
|
||||||
|
int max_sort_order = 0;
|
||||||
|
for (graphics_buffer_iterator = _shared_depth_buffer_list.begin();
|
||||||
|
graphics_buffer_iterator != _shared_depth_buffer_list.end();
|
||||||
|
graphics_buffer_iterator++) {
|
||||||
|
graphics_buffer = (*graphics_buffer_iterator);
|
||||||
|
if (graphics_buffer) {
|
||||||
|
// this call removes the entry from the list
|
||||||
|
if ( graphics_buffer->get_sort() >= max_sort_order ) {
|
||||||
|
max_sort_order = graphics_buffer->get_sort();
|
||||||
|
highest_sort_graphics_buffer = graphics_buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (max_sort_order == this->get_sort()) {
|
||||||
|
do_depth_blit = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
do_depth_blit = 1;
|
||||||
|
}
|
||||||
|
if (do_depth_blit) {
|
||||||
|
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
|
||||||
|
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
|
||||||
|
GL_NEAREST);
|
||||||
|
} else {
|
||||||
|
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
|
||||||
|
GL_COLOR_BUFFER_BIT,
|
||||||
|
GL_NEAREST);
|
||||||
|
}
|
||||||
|
#ifndef OPENGLES
|
||||||
|
// Now handle the other color buffers.
|
||||||
|
int next = GL_COLOR_ATTACHMENT1_EXT;
|
||||||
|
for (int i=0; i<_fb_properties.get_aux_rgba(); i++) {
|
||||||
|
glReadBuffer( next );
|
||||||
|
glDrawBuffer( next );
|
||||||
|
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
next += 1;
|
||||||
|
}
|
||||||
|
for (int i=0; i<_fb_properties.get_aux_hrgba(); i++) {
|
||||||
|
glReadBuffer( next );
|
||||||
|
glDrawBuffer( next );
|
||||||
|
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
next += 1;
|
||||||
|
}
|
||||||
|
for (int i=0; i<_fb_properties.get_aux_float(); i++) {
|
||||||
|
glReadBuffer( next );
|
||||||
|
glDrawBuffer( next );
|
||||||
|
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
next += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
|
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
|
#endif
|
||||||
|
report_my_gl_errors();
|
||||||
|
|
||||||
|
#ifndef OPENGLES
|
||||||
|
if ((_fb_properties.get_rgb_color() > 0) ||
|
||||||
|
(_fb_properties.get_aux_hrgba() > 0)) {
|
||||||
|
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
|
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
|
} else {
|
||||||
|
glDrawBuffer(GL_NONE);
|
||||||
|
glReadBuffer(GL_NONE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
report_my_gl_errors();
|
||||||
|
}
|
||||||
|
@ -90,29 +90,44 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void bind_slot(bool rb_resize, Texture **attach,
|
void bind_slot(int face, bool rb_resize, Texture **attach,
|
||||||
RenderTexturePlane plane, GLenum attachpoint);
|
RenderTexturePlane plane, GLenum attachpoint);
|
||||||
void bind_slot_multisample(bool rb_resize, Texture **attach,
|
void bind_slot_multisample(bool rb_resize, Texture **attach,
|
||||||
RenderTexturePlane plane, GLenum attachpoint);
|
RenderTexturePlane plane, GLenum attachpoint);
|
||||||
bool check_fbo();
|
bool check_fbo();
|
||||||
void generate_mipmaps();
|
void generate_mipmaps();
|
||||||
void rebuild_bitplanes();
|
void rebuild_bitplanes();
|
||||||
|
void resolve_multisamples();
|
||||||
GLuint _fbo; // allows for textures to be attached for render to texture.
|
|
||||||
GLuint _fbo_multisample; // all render buffers, resolves to _fbo at end of frame.
|
// We create one FBO for each cube map face we'll be rendering to.
|
||||||
|
// If we aren't rendering to any cube maps, we use only _fbo[0].
|
||||||
|
GLuint _fbo[6];
|
||||||
|
int _num_faces;
|
||||||
|
|
||||||
|
// For multisample we render first to a multisample buffer, then
|
||||||
|
// filter it to _fbo[face] at the end of the frame.
|
||||||
|
GLuint _fbo_multisample;
|
||||||
int _requested_multisamples;
|
int _requested_multisamples;
|
||||||
int _requested_coverage_samples;
|
int _requested_coverage_samples;
|
||||||
bool _use_depth_stencil;
|
bool _use_depth_stencil;
|
||||||
bool _initial_clear;
|
|
||||||
|
|
||||||
int _rb_size_x;
|
int _rb_size_x;
|
||||||
int _rb_size_y;
|
int _rb_size_y;
|
||||||
int _cube_face_active;
|
|
||||||
|
// The texture or render buffer bound to each plane.
|
||||||
PT(Texture) _tex[RTP_COUNT];
|
PT(Texture) _tex[RTP_COUNT];
|
||||||
GLuint _rb[RTP_COUNT];
|
GLuint _rb[RTP_COUNT];
|
||||||
GLuint _rbm[RTP_COUNT]; // A mirror of _rb, for the multisample FBO.
|
|
||||||
|
|
||||||
GLuint _cubemap_fbo [6];
|
// The render buffer for _fbo_multisample.
|
||||||
|
GLuint _rbm[RTP_COUNT];
|
||||||
|
|
||||||
|
// The cube map face we are currently drawing to or have just
|
||||||
|
// finished drawing to, or -1 if we are not drawing to a cube map.
|
||||||
|
int _active_cube_map_index;
|
||||||
|
|
||||||
|
bool _initial_clear;
|
||||||
|
bool _needs_rebuild;
|
||||||
|
UpdateSeq _last_textures_seq;
|
||||||
|
|
||||||
CLP(GraphicsBuffer) *_shared_depth_buffer;
|
CLP(GraphicsBuffer) *_shared_depth_buffer;
|
||||||
list <CLP(GraphicsBuffer) *> _shared_depth_buffer_list;
|
list <CLP(GraphicsBuffer) *> _shared_depth_buffer_list;
|
||||||
|
@ -9888,13 +9888,11 @@ get_supports_cg_profile(const string &name) const {
|
|||||||
void CLP(GraphicsStateGuardian)::
|
void CLP(GraphicsStateGuardian)::
|
||||||
bind_fbo(GLuint fbo) {
|
bind_fbo(GLuint fbo) {
|
||||||
nassertv(_glBindFramebuffer != 0);
|
nassertv(_glBindFramebuffer != 0);
|
||||||
#ifdef OPENGLES_2
|
#if defined(OPENGLES_2)
|
||||||
_glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
_glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
#endif
|
#elif defined(OPENGLES_1)
|
||||||
#ifdef OPENGLES_1
|
|
||||||
_glBindFramebuffer(GL_FRAMEBUFFER_OES, fbo);
|
_glBindFramebuffer(GL_FRAMEBUFFER_OES, fbo);
|
||||||
#endif
|
#else
|
||||||
#ifndef OPENGLES
|
|
||||||
_glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
|
_glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
|
||||||
#endif
|
#endif
|
||||||
_current_fbo = fbo;
|
_current_fbo = fbo;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user