mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
add support for render-to-texture
This commit is contained in:
parent
2e58c8d9d8
commit
7f609122ff
@ -43,6 +43,7 @@ wglGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
|
|||||||
// Since the pbuffer never gets flipped, we get screenshots from the
|
// Since the pbuffer never gets flipped, we get screenshots from the
|
||||||
// same buffer we draw into.
|
// same buffer we draw into.
|
||||||
_screenshot_buffer_type = _draw_buffer_type;
|
_screenshot_buffer_type = _draw_buffer_type;
|
||||||
|
_render_texture = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -72,6 +73,12 @@ begin_frame() {
|
|||||||
wglGraphicsStateGuardian *wglgsg;
|
wglGraphicsStateGuardian *wglgsg;
|
||||||
DCAST_INTO_R(wglgsg, _gsg, false);
|
DCAST_INTO_R(wglgsg, _gsg, false);
|
||||||
|
|
||||||
|
if (_render_texture) {
|
||||||
|
// Release the texture so we can render into the pbuffer.
|
||||||
|
// wglgsg->_wglReleaseTexImageARB(_pbuffer, get_draw_buffer_type() == RenderBuffer::T_back ? WGL_BACK_LEFT_ARB : WGL_FRONT_LEFT_ARB);
|
||||||
|
wglgsg->_wglReleaseTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB);
|
||||||
|
}
|
||||||
|
|
||||||
if (_pbuffer_dc) {
|
if (_pbuffer_dc) {
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
wglgsg->_wglQueryPbufferARB(_pbuffer, WGL_PBUFFER_LOST_ARB, &flag);
|
wglgsg->_wglQueryPbufferARB(_pbuffer, WGL_PBUFFER_LOST_ARB, &flag);
|
||||||
@ -100,6 +107,7 @@ end_frame() {
|
|||||||
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
||||||
_gsg->end_frame();
|
_gsg->end_frame();
|
||||||
|
|
||||||
|
|
||||||
if (_copy_texture) {
|
if (_copy_texture) {
|
||||||
wglGraphicsStateGuardian *wglgsg;
|
wglGraphicsStateGuardian *wglgsg;
|
||||||
DCAST_INTO_V(wglgsg, _gsg);
|
DCAST_INTO_V(wglgsg, _gsg);
|
||||||
@ -118,15 +126,29 @@ end_frame() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For now, we copy the framebuffer to the texture every frame.
|
|
||||||
// Eventually we can take advantage of the render_texture
|
|
||||||
// extension, if it is available, to render directly into a
|
|
||||||
// texture in the first place (but I don't have a card that
|
|
||||||
// supports that right now).
|
|
||||||
nassertv(has_texture());
|
nassertv(has_texture());
|
||||||
|
Texture *tex = get_texture();
|
||||||
|
|
||||||
RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type());
|
if (_render_texture) {
|
||||||
_gsg->copy_texture(get_texture(), _default_display_region, buffer);
|
// Bind the pbuffer to our associated texture. This is a newer
|
||||||
|
// extension that might allow us to use the same memory directly
|
||||||
|
// without having to pay for a copy operation. But we can't
|
||||||
|
// render again to the pbuffer while the texture is valid.
|
||||||
|
TextureContext *tc = tex->prepare_now(wglgsg->get_prepared_objects(), wglgsg);
|
||||||
|
nassertv(tc != (TextureContext *)NULL);
|
||||||
|
wglgsg->bind_texture(tc);
|
||||||
|
|
||||||
|
// wglgsg->_wglBindTexImageARB(_pbuffer, get_draw_buffer_type() == RenderBuffer::T_back ? WGL_BACK_LEFT_ARB : WGL_FRONT_LEFT_ARB);
|
||||||
|
wglgsg->_wglBindTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Copy the contents of the frame buffer to our associated
|
||||||
|
// texture. This is an older interface that guarantees a copy
|
||||||
|
// operation will take place, and it might even require
|
||||||
|
// reformatting pixels on the way, so it may be slower.
|
||||||
|
RenderBuffer buffer = wglgsg->get_render_buffer(get_draw_buffer_type());
|
||||||
|
wglgsg->copy_texture(tex, _default_display_region, buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +267,13 @@ open_buffer() {
|
|||||||
if (wgldisplay_cat.is_debug()) {
|
if (wgldisplay_cat.is_debug()) {
|
||||||
wgldisplay_cat.debug()
|
wgldisplay_cat.debug()
|
||||||
<< "Created PBuffer " << _pbuffer << ", DC " << _pbuffer_dc << "\n";
|
<< "Created PBuffer " << _pbuffer << ", DC " << _pbuffer_dc << "\n";
|
||||||
|
if (_render_texture) {
|
||||||
|
wgldisplay_cat.debug()
|
||||||
|
<< "pbuffer renders directly to texture.\n";
|
||||||
|
} else if (_copy_texture) {
|
||||||
|
wgldisplay_cat.debug()
|
||||||
|
<< "pbuffer copies indirectly into texture.\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wglMakeCurrent(_pbuffer_dc, wglgsg->get_context(_pbuffer_dc));
|
wglMakeCurrent(_pbuffer_dc, wglgsg->get_context(_pbuffer_dc));
|
||||||
@ -277,154 +306,60 @@ make_pbuffer(HDC twindow_dc) {
|
|||||||
int pbformat = wglgsg->get_pfnum();
|
int pbformat = wglgsg->get_pfnum();
|
||||||
|
|
||||||
if (wglgsg->_supports_pixel_format) {
|
if (wglgsg->_supports_pixel_format) {
|
||||||
// Select a suitable pixel format that matches the GSG's existing
|
bool got_pbuffer_format = false;
|
||||||
// format, and also is appropriate for a pixel buffer.
|
|
||||||
|
|
||||||
static const int max_attrib_list = 64;
|
if (_copy_texture && wglgsg->_supports_render_texture) {
|
||||||
int iattrib_list[max_attrib_list];
|
// First, try to get a pbuffer format that supports
|
||||||
int ivalue_list[max_attrib_list];
|
// render-to-texture.
|
||||||
int ni = 0;
|
int new_pbformat = choose_pbuffer_format(twindow_dc, true);
|
||||||
|
if (new_pbformat != 0) {
|
||||||
int acceleration_i, pixel_type_i, double_buffer_i, stereo_i,
|
pbformat = new_pbformat;
|
||||||
red_bits_i, green_bits_i, blue_bits_i, alpha_bits_i,
|
got_pbuffer_format = true;
|
||||||
accum_red_bits_i, accum_green_bits_i, accum_blue_bits_i,
|
_render_texture = true;
|
||||||
accum_alpha_bits_i, depth_bits_i,
|
}
|
||||||
stencil_bits_i, sample_buffers_i, multisamples_i;
|
|
||||||
|
|
||||||
iattrib_list[acceleration_i = ni++] = WGL_ACCELERATION_ARB;
|
|
||||||
iattrib_list[pixel_type_i = ni++] = WGL_PIXEL_TYPE_ARB;
|
|
||||||
iattrib_list[double_buffer_i = ni++] = WGL_DOUBLE_BUFFER_ARB;
|
|
||||||
iattrib_list[stereo_i = ni++] = WGL_STEREO_ARB;
|
|
||||||
iattrib_list[red_bits_i = ni++] = WGL_RED_BITS_ARB;
|
|
||||||
iattrib_list[green_bits_i = ni++] = WGL_GREEN_BITS_ARB;
|
|
||||||
iattrib_list[blue_bits_i = ni++] = WGL_BLUE_BITS_ARB;
|
|
||||||
iattrib_list[alpha_bits_i = ni++] = WGL_ALPHA_BITS_ARB;
|
|
||||||
iattrib_list[accum_red_bits_i = ni++] = WGL_ACCUM_RED_BITS_ARB;
|
|
||||||
iattrib_list[accum_green_bits_i = ni++] = WGL_ACCUM_GREEN_BITS_ARB;
|
|
||||||
iattrib_list[accum_blue_bits_i = ni++] = WGL_ACCUM_BLUE_BITS_ARB;
|
|
||||||
iattrib_list[accum_alpha_bits_i = ni++] = WGL_ACCUM_ALPHA_BITS_ARB;
|
|
||||||
iattrib_list[depth_bits_i = ni++] = WGL_DEPTH_BITS_ARB;
|
|
||||||
iattrib_list[stencil_bits_i = ni++] = WGL_STENCIL_BITS_ARB;
|
|
||||||
|
|
||||||
if (wglgsg->_supports_wgl_multisample) {
|
|
||||||
iattrib_list[sample_buffers_i = ni++] = WGL_SAMPLE_BUFFERS_ARB;
|
|
||||||
iattrib_list[multisamples_i = ni++] = WGL_SAMPLES_ARB;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terminate the list.
|
if (!got_pbuffer_format) {
|
||||||
nassertr(ni <= max_attrib_list, false);
|
// Failing that, just get a matching pbuffer format.
|
||||||
|
int new_pbformat = choose_pbuffer_format(twindow_dc, false);
|
||||||
if (!wglgsg->_wglGetPixelFormatAttribivARB(twindow_dc, pbformat, 0,
|
if (new_pbformat != 0) {
|
||||||
ni, iattrib_list, ivalue_list)) {
|
pbformat = new_pbformat;
|
||||||
return false;
|
got_pbuffer_format = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ni = 0;
|
|
||||||
float fattrib_list[max_attrib_list];
|
|
||||||
int nf = 0;
|
|
||||||
|
|
||||||
// Since we are trying to create a pbuffer, the pixel format we
|
|
||||||
// request (and subsequently use) must be "pbuffer capable".
|
|
||||||
iattrib_list[ni++] = WGL_DRAW_TO_PBUFFER_ARB;
|
|
||||||
iattrib_list[ni++] = true;
|
|
||||||
iattrib_list[ni++] = WGL_SUPPORT_OPENGL_ARB;
|
|
||||||
iattrib_list[ni++] = true;
|
|
||||||
|
|
||||||
// Match up the framebuffer bits.
|
|
||||||
iattrib_list[ni++] = WGL_RED_BITS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[red_bits_i];
|
|
||||||
iattrib_list[ni++] = WGL_GREEN_BITS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[green_bits_i];
|
|
||||||
iattrib_list[ni++] = WGL_BLUE_BITS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[blue_bits_i];
|
|
||||||
iattrib_list[ni++] = WGL_ALPHA_BITS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[alpha_bits_i];
|
|
||||||
|
|
||||||
iattrib_list[ni++] = WGL_ACCUM_RED_BITS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[accum_red_bits_i];
|
|
||||||
iattrib_list[ni++] = WGL_ACCUM_GREEN_BITS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[accum_green_bits_i];
|
|
||||||
iattrib_list[ni++] = WGL_ACCUM_BLUE_BITS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[accum_blue_bits_i];
|
|
||||||
iattrib_list[ni++] = WGL_ACCUM_ALPHA_BITS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[accum_alpha_bits_i];
|
|
||||||
|
|
||||||
iattrib_list[ni++] = WGL_DEPTH_BITS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[depth_bits_i];
|
|
||||||
|
|
||||||
iattrib_list[ni++] = WGL_STENCIL_BITS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[stencil_bits_i];
|
|
||||||
|
|
||||||
if (wglgsg->_supports_wgl_multisample) {
|
|
||||||
iattrib_list[ni++] = WGL_SAMPLE_BUFFERS_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[sample_buffers_i];
|
|
||||||
iattrib_list[ni++] = WGL_SAMPLES_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[multisamples_i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match up properties.
|
|
||||||
iattrib_list[ni++] = WGL_DOUBLE_BUFFER_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[double_buffer_i];
|
|
||||||
iattrib_list[ni++] = WGL_STEREO_ARB;
|
|
||||||
iattrib_list[ni++] = ivalue_list[stereo_i];
|
|
||||||
|
|
||||||
// Terminate the lists.
|
|
||||||
nassertr(ni < max_attrib_list && nf < max_attrib_list, NULL);
|
|
||||||
iattrib_list[ni] = 0;
|
|
||||||
fattrib_list[nf] = 0;
|
|
||||||
|
|
||||||
// Now obtain a list of pixel formats that meet these minimum
|
|
||||||
// requirements.
|
|
||||||
static const unsigned int max_pformats = 32;
|
|
||||||
int pformat[max_pformats];
|
|
||||||
memset(pformat, 0, sizeof(pformat));
|
|
||||||
unsigned int nformats = 0;
|
|
||||||
if (!wglgsg->_wglChoosePixelFormatARB(twindow_dc, iattrib_list, fattrib_list,
|
|
||||||
max_pformats, pformat, &nformats)
|
|
||||||
|| nformats == 0) {
|
|
||||||
wgldisplay_cat.info()
|
|
||||||
<< "Couldn't find a suitable pixel format for creating a pbuffer.\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nformats = min(nformats, max_pformats);
|
|
||||||
|
|
||||||
if (wgldisplay_cat.is_debug()) {
|
if (wgldisplay_cat.is_debug()) {
|
||||||
|
FrameBufferProperties properties;
|
||||||
|
wglGraphicsPipe::get_properties_advanced(properties, wglgsg,
|
||||||
|
twindow_dc, pbformat);
|
||||||
wgldisplay_cat.debug()
|
wgldisplay_cat.debug()
|
||||||
<< "Found " << nformats << " pbuffer formats: [";
|
<< "Chose pixfmt #" << pbformat << " for pbuffer = "
|
||||||
for (unsigned int i = 0; i < nformats; i++) {
|
<< properties << "\n";
|
||||||
wgldisplay_cat.debug(false)
|
|
||||||
<< " " << pformat[i];
|
|
||||||
}
|
|
||||||
wgldisplay_cat.debug(false)
|
|
||||||
<< " ]\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// If one of the options is the original pixfmt, keep it.
|
|
||||||
bool found_pbformat = false;
|
|
||||||
for (unsigned int i = 0; i < nformats && !found_pbformat; i++) {
|
|
||||||
if (pformat[i] == pbformat) {
|
|
||||||
found_pbformat = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_pbformat) {
|
|
||||||
// Otherwise, pick any of them.
|
|
||||||
pbformat = pformat[0];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wgldisplay_cat.is_debug()) {
|
static const int max_attrib_list = 64;
|
||||||
wgldisplay_cat.debug()
|
int iattrib_list[max_attrib_list];
|
||||||
<< "Chose pixfmt #" << pbformat << " for pbuffer\n";
|
int ni = 0;
|
||||||
}
|
|
||||||
|
if (_render_texture) {
|
||||||
int attrib_list[] = {
|
if (_gsg->get_properties().get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) {
|
||||||
0,
|
iattrib_list[ni++] = WGL_TEXTURE_FORMAT_ARB;
|
||||||
};
|
iattrib_list[ni++] = WGL_TEXTURE_RGBA_ARB;
|
||||||
|
} else {
|
||||||
|
iattrib_list[ni++] = WGL_TEXTURE_FORMAT_ARB;
|
||||||
|
iattrib_list[ni++] = WGL_TEXTURE_RGB_ARB;
|
||||||
|
}
|
||||||
|
iattrib_list[ni++] = WGL_TEXTURE_TARGET_ARB;
|
||||||
|
iattrib_list[ni++] = WGL_TEXTURE_2D_ARB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminate the list.
|
||||||
|
nassertr(ni <= max_attrib_list, false);
|
||||||
|
iattrib_list[ni] = 0;
|
||||||
|
|
||||||
_pbuffer = wglgsg->_wglCreatePbufferARB(twindow_dc, pbformat,
|
_pbuffer = wglgsg->_wglCreatePbufferARB(twindow_dc, pbformat,
|
||||||
_x_size, _y_size, attrib_list);
|
_x_size, _y_size, iattrib_list);
|
||||||
|
|
||||||
if (_pbuffer == 0) {
|
if (_pbuffer == 0) {
|
||||||
wgldisplay_cat.info()
|
wgldisplay_cat.info()
|
||||||
@ -435,6 +370,180 @@ make_pbuffer(HDC twindow_dc) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: wglGraphicsBuffer::choose_pbuffer_format
|
||||||
|
// Access: Private
|
||||||
|
// Description: Select a suitable pixel format that matches the GSG's
|
||||||
|
// existing format, and also is appropriate for a pixel
|
||||||
|
// buffer. Returns the selected pfnum if successful, or
|
||||||
|
// 0 on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int wglGraphicsBuffer::
|
||||||
|
choose_pbuffer_format(HDC twindow_dc, bool draw_to_texture) {
|
||||||
|
if (wgldisplay_cat.is_debug()) {
|
||||||
|
wgldisplay_cat.debug()
|
||||||
|
<< "choose_pbuffer_format(twindow_dc, draw_to_texture = "
|
||||||
|
<< draw_to_texture << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
wglGraphicsStateGuardian *wglgsg;
|
||||||
|
DCAST_INTO_R(wglgsg, _gsg, false);
|
||||||
|
|
||||||
|
int pbformat = wglgsg->get_pfnum();
|
||||||
|
|
||||||
|
static const int max_attrib_list = 64;
|
||||||
|
int iattrib_list[max_attrib_list];
|
||||||
|
int ivalue_list[max_attrib_list];
|
||||||
|
int ni = 0;
|
||||||
|
|
||||||
|
int acceleration_i, pixel_type_i, double_buffer_i, stereo_i,
|
||||||
|
red_bits_i, green_bits_i, blue_bits_i, alpha_bits_i,
|
||||||
|
accum_red_bits_i, accum_green_bits_i, accum_blue_bits_i,
|
||||||
|
accum_alpha_bits_i, depth_bits_i,
|
||||||
|
stencil_bits_i, sample_buffers_i, multisamples_i;
|
||||||
|
|
||||||
|
iattrib_list[acceleration_i = ni++] = WGL_ACCELERATION_ARB;
|
||||||
|
iattrib_list[pixel_type_i = ni++] = WGL_PIXEL_TYPE_ARB;
|
||||||
|
iattrib_list[double_buffer_i = ni++] = WGL_DOUBLE_BUFFER_ARB;
|
||||||
|
iattrib_list[stereo_i = ni++] = WGL_STEREO_ARB;
|
||||||
|
iattrib_list[red_bits_i = ni++] = WGL_RED_BITS_ARB;
|
||||||
|
iattrib_list[green_bits_i = ni++] = WGL_GREEN_BITS_ARB;
|
||||||
|
iattrib_list[blue_bits_i = ni++] = WGL_BLUE_BITS_ARB;
|
||||||
|
iattrib_list[alpha_bits_i = ni++] = WGL_ALPHA_BITS_ARB;
|
||||||
|
iattrib_list[accum_red_bits_i = ni++] = WGL_ACCUM_RED_BITS_ARB;
|
||||||
|
iattrib_list[accum_green_bits_i = ni++] = WGL_ACCUM_GREEN_BITS_ARB;
|
||||||
|
iattrib_list[accum_blue_bits_i = ni++] = WGL_ACCUM_BLUE_BITS_ARB;
|
||||||
|
iattrib_list[accum_alpha_bits_i = ni++] = WGL_ACCUM_ALPHA_BITS_ARB;
|
||||||
|
iattrib_list[depth_bits_i = ni++] = WGL_DEPTH_BITS_ARB;
|
||||||
|
iattrib_list[stencil_bits_i = ni++] = WGL_STENCIL_BITS_ARB;
|
||||||
|
|
||||||
|
if (wglgsg->_supports_wgl_multisample) {
|
||||||
|
iattrib_list[sample_buffers_i = ni++] = WGL_SAMPLE_BUFFERS_ARB;
|
||||||
|
iattrib_list[multisamples_i = ni++] = WGL_SAMPLES_ARB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminate the list.
|
||||||
|
nassertr(ni <= max_attrib_list, false);
|
||||||
|
|
||||||
|
if (!wglgsg->_wglGetPixelFormatAttribivARB(twindow_dc, pbformat, 0,
|
||||||
|
ni, iattrib_list, ivalue_list)) {
|
||||||
|
if (wgldisplay_cat.is_debug()) {
|
||||||
|
wgldisplay_cat.debug()
|
||||||
|
<< "Could not query old format " << pbformat << ".\n";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ni = 0;
|
||||||
|
float fattrib_list[max_attrib_list];
|
||||||
|
int nf = 0;
|
||||||
|
|
||||||
|
// Since we are trying to create a pbuffer, the pixel format we
|
||||||
|
// request (and subsequently use) must be "pbuffer capable".
|
||||||
|
iattrib_list[ni++] = WGL_DRAW_TO_PBUFFER_ARB;
|
||||||
|
iattrib_list[ni++] = true;
|
||||||
|
iattrib_list[ni++] = WGL_SUPPORT_OPENGL_ARB;
|
||||||
|
iattrib_list[ni++] = true;
|
||||||
|
|
||||||
|
if (draw_to_texture) {
|
||||||
|
// If we want to be able to render-to-texture, request that.
|
||||||
|
if (_gsg->get_properties().get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) {
|
||||||
|
iattrib_list[ni++] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
|
||||||
|
iattrib_list[ni++] = true;
|
||||||
|
} else {
|
||||||
|
iattrib_list[ni++] = WGL_BIND_TO_TEXTURE_RGB_ARB;
|
||||||
|
iattrib_list[ni++] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match up the framebuffer bits.
|
||||||
|
iattrib_list[ni++] = WGL_RED_BITS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[red_bits_i];
|
||||||
|
iattrib_list[ni++] = WGL_GREEN_BITS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[green_bits_i];
|
||||||
|
iattrib_list[ni++] = WGL_BLUE_BITS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[blue_bits_i];
|
||||||
|
iattrib_list[ni++] = WGL_ALPHA_BITS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[alpha_bits_i];
|
||||||
|
|
||||||
|
iattrib_list[ni++] = WGL_ACCUM_RED_BITS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[accum_red_bits_i];
|
||||||
|
iattrib_list[ni++] = WGL_ACCUM_GREEN_BITS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[accum_green_bits_i];
|
||||||
|
iattrib_list[ni++] = WGL_ACCUM_BLUE_BITS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[accum_blue_bits_i];
|
||||||
|
iattrib_list[ni++] = WGL_ACCUM_ALPHA_BITS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[accum_alpha_bits_i];
|
||||||
|
|
||||||
|
iattrib_list[ni++] = WGL_DEPTH_BITS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[depth_bits_i];
|
||||||
|
|
||||||
|
iattrib_list[ni++] = WGL_STENCIL_BITS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[stencil_bits_i];
|
||||||
|
|
||||||
|
if (wglgsg->_supports_wgl_multisample) {
|
||||||
|
iattrib_list[ni++] = WGL_SAMPLE_BUFFERS_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[sample_buffers_i];
|
||||||
|
iattrib_list[ni++] = WGL_SAMPLES_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[multisamples_i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match up properties.
|
||||||
|
iattrib_list[ni++] = WGL_DOUBLE_BUFFER_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[double_buffer_i];
|
||||||
|
iattrib_list[ni++] = WGL_STEREO_ARB;
|
||||||
|
iattrib_list[ni++] = ivalue_list[stereo_i];
|
||||||
|
|
||||||
|
// Terminate the lists.
|
||||||
|
nassertr(ni < max_attrib_list && nf < max_attrib_list, NULL);
|
||||||
|
iattrib_list[ni] = 0;
|
||||||
|
fattrib_list[nf] = 0;
|
||||||
|
|
||||||
|
// Now obtain a list of pixel formats that meet these minimum
|
||||||
|
// requirements.
|
||||||
|
static const unsigned int max_pformats = 32;
|
||||||
|
int pformat[max_pformats];
|
||||||
|
memset(pformat, 0, sizeof(pformat));
|
||||||
|
unsigned int nformats = 0;
|
||||||
|
if (!wglgsg->_wglChoosePixelFormatARB(twindow_dc, iattrib_list, fattrib_list,
|
||||||
|
max_pformats, pformat, &nformats)
|
||||||
|
|| nformats == 0) {
|
||||||
|
if (wgldisplay_cat.is_debug()) {
|
||||||
|
wgldisplay_cat.debug()
|
||||||
|
<< "No formats meet the criteria.\n";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nformats = min(nformats, max_pformats);
|
||||||
|
|
||||||
|
if (wgldisplay_cat.is_debug()) {
|
||||||
|
wgldisplay_cat.debug()
|
||||||
|
<< "Found " << nformats << " pbuffer formats: [";
|
||||||
|
for (unsigned int i = 0; i < nformats; i++) {
|
||||||
|
wgldisplay_cat.debug(false)
|
||||||
|
<< " " << pformat[i];
|
||||||
|
}
|
||||||
|
wgldisplay_cat.debug(false)
|
||||||
|
<< " ]\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// If one of the options is the original pixfmt, keep it.
|
||||||
|
bool found_pbformat = false;
|
||||||
|
for (unsigned int i = 0; i < nformats && !found_pbformat; i++) {
|
||||||
|
if (pformat[i] == pbformat) {
|
||||||
|
found_pbformat = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_pbformat) {
|
||||||
|
// Otherwise, pick any of them.
|
||||||
|
pbformat = pformat[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return pbformat;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: wglGraphicsBuffer::process_1_event
|
// Function: wglGraphicsBuffer::process_1_event
|
||||||
// Access: Private, Static
|
// Access: Private, Static
|
||||||
|
@ -60,11 +60,13 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool make_pbuffer(HDC window_dc);
|
bool make_pbuffer(HDC window_dc);
|
||||||
|
int choose_pbuffer_format(HDC twindow_dc, bool draw_to_texture);
|
||||||
|
|
||||||
static void process_1_event();
|
static void process_1_event();
|
||||||
|
|
||||||
HPBUFFERARB _pbuffer;
|
HPBUFFERARB _pbuffer;
|
||||||
HDC _pbuffer_dc;
|
HDC _pbuffer_dc;
|
||||||
|
bool _render_texture;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
|
@ -329,6 +329,18 @@ int wglGraphicsPipe::
|
|||||||
try_for_pfnum(HDC hdc, bool hardware, bool software, int frame_buffer_mode,
|
try_for_pfnum(HDC hdc, bool hardware, bool software, int frame_buffer_mode,
|
||||||
int want_depth_bits, int want_color_bits,
|
int want_depth_bits, int want_color_bits,
|
||||||
int want_alpha_bits, int want_stencil_bits) {
|
int want_alpha_bits, int want_stencil_bits) {
|
||||||
|
if (wgldisplay_cat.is_debug()) {
|
||||||
|
wgldisplay_cat.debug()
|
||||||
|
<< "try_for_pfnum(hdc, hardware = " << hardware
|
||||||
|
<< ", software = " << software
|
||||||
|
<< ", frame_buffer_mode = 0x" << hex << frame_buffer_mode << dec
|
||||||
|
<< ", want_depth_bits = " << want_depth_bits
|
||||||
|
<< ", want_color_bits = " << want_color_bits
|
||||||
|
<< ", want_alpha_bits = " << want_alpha_bits
|
||||||
|
<< ", want_stencil_bits = " << want_stencil_bits
|
||||||
|
<< ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
ZeroMemory(&pfd,sizeof(PIXELFORMATDESCRIPTOR));
|
ZeroMemory(&pfd,sizeof(PIXELFORMATDESCRIPTOR));
|
||||||
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||||
@ -348,16 +360,6 @@ try_for_pfnum(HDC hdc, bool hardware, bool software, int frame_buffer_mode,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
wgldisplay_cat.debug()
|
|
||||||
<< "try_for_pfnum(hdc, hardware = " << hardware
|
|
||||||
<< ", software = " << software
|
|
||||||
<< ", frame_buffer_mode = 0x" << hex << frame_buffer_mode << dec
|
|
||||||
<< ", want_depth_bits = " << want_depth_bits
|
|
||||||
<< ", want_color_bits = " << want_color_bits
|
|
||||||
<< ", want_alpha_bits = " << want_alpha_bits
|
|
||||||
<< ", want_stencil_bits = " << want_stencil_bits
|
|
||||||
<< ")\n";
|
|
||||||
|
|
||||||
// We have to call DescribePixelFormat() once just to get the
|
// We have to call DescribePixelFormat() once just to get the
|
||||||
// highest pfnum available. Then we can iterate through all of the
|
// highest pfnum available. Then we can iterate through all of the
|
||||||
// pfnums.
|
// pfnums.
|
||||||
@ -647,6 +649,18 @@ try_for_pfnum_advanced(int orig_pfnum, const wglGraphicsStateGuardian *wglgsg,
|
|||||||
int want_depth_bits, int want_color_bits,
|
int want_depth_bits, int want_color_bits,
|
||||||
int want_alpha_bits, int want_stencil_bits,
|
int want_alpha_bits, int want_stencil_bits,
|
||||||
int want_multisamples) {
|
int want_multisamples) {
|
||||||
|
if (wgldisplay_cat.is_debug()) {
|
||||||
|
wgldisplay_cat.debug()
|
||||||
|
<< "try_for_pfnum_advanced(orig_pfnum = " << orig_pfnum
|
||||||
|
<< ", wglgsg, window_dc, frame_buffer_mode = 0x" << hex << frame_buffer_mode << dec
|
||||||
|
<< ", want_depth_bits = " << want_depth_bits
|
||||||
|
<< ", want_color_bits = " << want_color_bits
|
||||||
|
<< ", want_alpha_bits = " << want_alpha_bits
|
||||||
|
<< ", want_stencil_bits = " << want_stencil_bits
|
||||||
|
<< ", want_multisamples = " << want_multisamples
|
||||||
|
<< ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
static const int max_attrib_list = 32;
|
static const int max_attrib_list = 32;
|
||||||
int iattrib_list[max_attrib_list];
|
int iattrib_list[max_attrib_list];
|
||||||
float fattrib_list[max_attrib_list];
|
float fattrib_list[max_attrib_list];
|
||||||
@ -727,8 +741,8 @@ try_for_pfnum_advanced(int orig_pfnum, const wglGraphicsStateGuardian *wglgsg,
|
|||||||
max_pformats, pformat, &nformats) ||
|
max_pformats, pformat, &nformats) ||
|
||||||
nformats == 0) {
|
nformats == 0) {
|
||||||
if (wgldisplay_cat.is_debug()) {
|
if (wgldisplay_cat.is_debug()) {
|
||||||
wgldisplay_cat.info()
|
wgldisplay_cat.debug()
|
||||||
<< "Couldn't find a suitable advanced pixel format.\n";
|
<< "No formats meet the criteria.\n";
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static TypeHandle _type_handle;
|
static TypeHandle _type_handle;
|
||||||
|
|
||||||
|
friend class wglGraphicsBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "wglGraphicsPipe.I"
|
#include "wglGraphicsPipe.I"
|
||||||
|
@ -46,6 +46,7 @@ wglGraphicsStateGuardian(const FrameBufferProperties &properties,
|
|||||||
_supports_pbuffer = false;
|
_supports_pbuffer = false;
|
||||||
_supports_pixel_format = false;
|
_supports_pixel_format = false;
|
||||||
_supports_wgl_multisample = false;
|
_supports_wgl_multisample = false;
|
||||||
|
_supports_render_texture = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -75,6 +76,7 @@ reset() {
|
|||||||
_supports_pbuffer = has_extension("WGL_ARB_pbuffer");
|
_supports_pbuffer = has_extension("WGL_ARB_pbuffer");
|
||||||
_supports_pixel_format = has_extension("WGL_ARB_pixel_format");
|
_supports_pixel_format = has_extension("WGL_ARB_pixel_format");
|
||||||
_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");
|
||||||
|
|
||||||
_wglCreatePbufferARB =
|
_wglCreatePbufferARB =
|
||||||
(PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB");
|
(PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB");
|
||||||
@ -115,6 +117,23 @@ reset() {
|
|||||||
_supports_pixel_format = false;
|
_supports_pixel_format = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_wglBindTexImageARB =
|
||||||
|
(PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress("wglBindTexImageARB");
|
||||||
|
_wglReleaseTexImageARB =
|
||||||
|
(PFNWGLRELEASETEXIMAGEARBPROC)wglGetProcAddress("wglReleaseTexImageARB");
|
||||||
|
_wglSetPbufferAttribARB =
|
||||||
|
(PFNWGLSETPBUFFERATTRIBARBPROC)wglGetProcAddress("wglSetPbufferAttribARB");
|
||||||
|
|
||||||
|
if (_supports_render_texture) {
|
||||||
|
if (_wglBindTexImageARB == NULL ||
|
||||||
|
_wglReleaseTexImageARB == NULL ||
|
||||||
|
_wglSetPbufferAttribARB == NULL) {
|
||||||
|
wgldisplay_cat.error()
|
||||||
|
<< "Driver claims to support WGL_ARB_render_texture, but does not define all functions.\n";
|
||||||
|
_supports_render_texture = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -82,7 +82,6 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
bool _supports_pbuffer;
|
bool _supports_pbuffer;
|
||||||
|
|
||||||
PFNWGLCREATEPBUFFERARBPROC _wglCreatePbufferARB;
|
PFNWGLCREATEPBUFFERARBPROC _wglCreatePbufferARB;
|
||||||
PFNWGLGETPBUFFERDCARBPROC _wglGetPbufferDCARB;
|
PFNWGLGETPBUFFERDCARBPROC _wglGetPbufferDCARB;
|
||||||
PFNWGLRELEASEPBUFFERDCARBPROC _wglReleasePbufferDCARB;
|
PFNWGLRELEASEPBUFFERDCARBPROC _wglReleasePbufferDCARB;
|
||||||
@ -90,13 +89,17 @@ public:
|
|||||||
PFNWGLQUERYPBUFFERARBPROC _wglQueryPbufferARB;
|
PFNWGLQUERYPBUFFERARBPROC _wglQueryPbufferARB;
|
||||||
|
|
||||||
bool _supports_pixel_format;
|
bool _supports_pixel_format;
|
||||||
|
|
||||||
PFNWGLGETPIXELFORMATATTRIBIVARBPROC _wglGetPixelFormatAttribivARB;
|
PFNWGLGETPIXELFORMATATTRIBIVARBPROC _wglGetPixelFormatAttribivARB;
|
||||||
PFNWGLGETPIXELFORMATATTRIBFVARBPROC _wglGetPixelFormatAttribfvARB;
|
PFNWGLGETPIXELFORMATATTRIBFVARBPROC _wglGetPixelFormatAttribfvARB;
|
||||||
PFNWGLCHOOSEPIXELFORMATARBPROC _wglChoosePixelFormatARB;
|
PFNWGLCHOOSEPIXELFORMATARBPROC _wglChoosePixelFormatARB;
|
||||||
|
|
||||||
bool _supports_wgl_multisample;
|
bool _supports_wgl_multisample;
|
||||||
|
|
||||||
|
bool _supports_render_texture;
|
||||||
|
PFNWGLBINDTEXIMAGEARBPROC _wglBindTexImageARB;
|
||||||
|
PFNWGLRELEASETEXIMAGEARBPROC _wglReleaseTexImageARB;
|
||||||
|
PFNWGLSETPBUFFERATTRIBARBPROC _wglSetPbufferAttribARB;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
return _type_handle;
|
return _type_handle;
|
||||||
@ -113,6 +116,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static TypeHandle _type_handle;
|
static TypeHandle _type_handle;
|
||||||
|
|
||||||
|
friend class wglGraphicsBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "wglGraphicsStateGuardian.I"
|
#include "wglGraphicsStateGuardian.I"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user