fix screenshots on dx9; robustify Panda screenshot interface
This commit is contained in:
parent
1a5404e454
commit
429fbba758
|
|
@ -81,6 +81,9 @@ const bool yield_timeslice = config_display.GetBool("yield-timeslice", false);
|
|||
// This variable may be repeated several times.
|
||||
|
||||
|
||||
const string screenshot_filename = config_display.GetString("screenshot-filename", "%~p-%a-%b-%d-%H-%M-%S-%Y-%~f.%~e");
|
||||
const string screenshot_extension = config_display.GetString("screenshot-extension", "jpg");
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: init_libdisplay
|
||||
// Description: Initializes the library. This must be called at
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ extern const string threading_model;
|
|||
extern const bool auto_flip;
|
||||
extern const bool yield_timeslice;
|
||||
|
||||
extern const string screenshot_filename;
|
||||
extern const string screenshot_extension;
|
||||
|
||||
extern EXPCL_PANDA const bool multiple_windows;
|
||||
|
||||
extern EXPCL_PANDA void init_libdisplay();
|
||||
|
|
|
|||
|
|
@ -385,6 +385,122 @@ get_display_region(int n) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::take_screenshot
|
||||
// Access: Published
|
||||
// Description: Saves a screenshot of the window to a default
|
||||
// filename, and returns the filename, or empty string
|
||||
// if the screenshot failed. The default filename is
|
||||
// generated from the supplied prefix and from the
|
||||
// Configrc variable screenshot-filename, which contains
|
||||
// the following strings:
|
||||
//
|
||||
// %~p - the supplied prefix
|
||||
// %~f - the frame count
|
||||
// %~e - the value of screenshot-extension
|
||||
// All other % strings in strftime().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Filename GraphicsWindow::
|
||||
take_screenshot(const string &prefix) {
|
||||
time_t now = time(NULL);
|
||||
struct tm *ttm = localtime(&now);
|
||||
int frame_count = ClockObject::get_global_clock()->get_frame_count();
|
||||
|
||||
static const int buffer_size = 1024;
|
||||
char buffer[buffer_size];
|
||||
|
||||
ostringstream filename_strm;
|
||||
|
||||
size_t i = 0;
|
||||
while (i < screenshot_filename.length()) {
|
||||
char ch1 = screenshot_filename[i++];
|
||||
if (ch1 == '%' && i < screenshot_filename.length()) {
|
||||
char ch2 = screenshot_filename[i++];
|
||||
if (ch2 == '~' && i < screenshot_filename.length()) {
|
||||
char ch3 = screenshot_filename[i++];
|
||||
switch (ch3) {
|
||||
case 'p':
|
||||
filename_strm << prefix;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
filename_strm << frame_count;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
filename_strm << screenshot_extension;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Use strftime() to decode the percent code.
|
||||
char format[3] = {'%', ch2, '\0'};
|
||||
if (strftime(buffer, buffer_size, format, ttm)) {
|
||||
for (char *b = buffer; *b != '\0'; b++) {
|
||||
switch (*b) {
|
||||
case ' ':
|
||||
case ':':
|
||||
case '/':
|
||||
filename_strm << '-';
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
break;
|
||||
|
||||
default:
|
||||
filename_strm << *b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
filename_strm << ch1;
|
||||
}
|
||||
}
|
||||
|
||||
Filename filename = filename_strm.str();
|
||||
if (take_screenshot(filename)) {
|
||||
return filename;
|
||||
}
|
||||
return Filename();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::take_screenshot
|
||||
// Access: Published
|
||||
// Description: Saves a screenshot of the window to the indicated
|
||||
// filename. Returns true on success, false on failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsWindow::
|
||||
take_screenshot(const Filename &filename) {
|
||||
if (_gsg == (GraphicsStateGuardian *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WindowProperties props = get_properties();
|
||||
if (!props.has_size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int x_size = props.get_x_size();
|
||||
int y_size = props.get_y_size();
|
||||
|
||||
PixelBuffer p(x_size, y_size, 3, 1, PixelBuffer::T_unsigned_byte,
|
||||
PixelBuffer::F_rgb);
|
||||
|
||||
DisplayRegion dr(x_size, y_size);
|
||||
RenderBuffer rb = _gsg->get_render_buffer(RenderBuffer::T_front);
|
||||
if (!p.copy(_gsg, &dr, rb)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!p.write(filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_num_input_devices
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "iterator_types.h"
|
||||
#include "notify.h"
|
||||
#include "pmutex.h"
|
||||
#include "filename.h"
|
||||
|
||||
#include "pvector.h"
|
||||
#include "pdeque.h"
|
||||
|
|
@ -97,6 +98,9 @@ PUBLISHED:
|
|||
int get_num_display_regions() const;
|
||||
DisplayRegion *get_display_region(int n) const;
|
||||
|
||||
Filename take_screenshot(const string &prefix = "screenshot");
|
||||
bool take_screenshot(const Filename &filename);
|
||||
|
||||
// Mouse and keyboard routines
|
||||
int get_num_input_devices() const;
|
||||
string get_input_device_name(int device) const;
|
||||
|
|
|
|||
|
|
@ -3641,21 +3641,18 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
|
|||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian7::
|
||||
bool DXGraphicsStateGuardian7::
|
||||
copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
||||
|
||||
extern HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf);
|
||||
|
||||
nassertv(pb != NULL && dr != NULL);
|
||||
nassertr(pb != NULL && dr != NULL, false);
|
||||
|
||||
int xo, yo, w, h;
|
||||
dr->get_region_pixels(xo, yo, w, h);
|
||||
|
||||
// only handled simple case
|
||||
nassertv(xo==0);
|
||||
nassertv(yo==0);
|
||||
nassertv(w==pb->get_xsize());
|
||||
nassertv(h==pb->get_ysize());
|
||||
nassertr(xo == 0 && yo==0 && w == pb->get_xsize() && h == pb->get_ysize(), false);
|
||||
|
||||
/*
|
||||
set_pack_alignment(1);
|
||||
|
|
@ -3669,7 +3666,8 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
|
||||
(void) ConvertDDSurftoPixBuf(pb,((_cur_read_pixel_buffer & RenderBuffer::T_back) ? _pScrn->pddsBack : _pScrn->pddsPrimary));
|
||||
|
||||
nassertv(!pb->_image.empty());
|
||||
nassertr(!pb->_image.empty(), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3677,11 +3675,11 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian7::
|
||||
bool DXGraphicsStateGuardian7::
|
||||
copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb) {
|
||||
set_read_buffer(rb);
|
||||
copy_pixel_buffer(pb, dr);
|
||||
return copy_pixel_buffer(pb, dr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -106,8 +106,8 @@ public:
|
|||
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
|
||||
const DisplayRegion *dr);
|
||||
|
||||
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr);
|
||||
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
virtual bool copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr);
|
||||
virtual bool copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
virtual void apply_material(const Material *material);
|
||||
|
|
|
|||
|
|
@ -3318,20 +3318,17 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
|
|||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
bool DXGraphicsStateGuardian8::
|
||||
copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
||||
|
||||
RECT SrcCopyRect;
|
||||
nassertv(pb != NULL && dr != NULL);
|
||||
nassertr(pb != NULL && dr != NULL, false);
|
||||
|
||||
int xo, yo, w, h;
|
||||
dr->get_region_pixels(xo, yo, w, h);
|
||||
|
||||
// only handled simple case
|
||||
nassertv(xo==0);
|
||||
nassertv(yo==0);
|
||||
nassertv(w==pb->get_xsize());
|
||||
nassertv(h==pb->get_ysize());
|
||||
nassertr(xo == 0 && yo==0 && w == pb->get_xsize() && h == pb->get_ysize(), false);
|
||||
|
||||
IDirect3DSurface8 *pD3DSurf;
|
||||
HRESULT hr;
|
||||
|
|
@ -3345,7 +3342,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
|
||||
if(FAILED(hr)) {
|
||||
dxgsg8_cat.error() << "GetBackBuffer failed" << D3DERRORSTRING(hr);
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
D3DSURFACE_DESC SurfDesc;
|
||||
|
|
@ -3389,31 +3386,32 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
hr=_pD3DDevice->CreateImageSurface(TmpSurfXsize,TmpSurfYsize,D3DFMT_A8R8G8B8,&pD3DSurf);
|
||||
if(FAILED(hr)) {
|
||||
dxgsg8_cat.error() << "CreateImageSurface failed in copy_pixel_buffer()" << D3DERRORSTRING(hr);
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr=_pD3DDevice->GetFrontBuffer(pD3DSurf);
|
||||
|
||||
if(hr==D3DERR_DEVICELOST) {
|
||||
// dont necessary want to exit in this case
|
||||
pD3DSurf->Release();
|
||||
dxgsg8_cat.error() << "copy_pixel_buffer failed: device lost\n";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
dxgsg8_cat.error() << "copy_pixel_buffer: unhandled current_read_pixel_buffer type\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if((RECT_XSIZE(SrcCopyRect)>w) || (RECT_YSIZE(SrcCopyRect)>h)) {
|
||||
dxgsg8_cat.error() << "copy_pixel_buffer: pixel buffer size does not match selected screen RenderBuffer size!\n";
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
(void) ConvertD3DSurftoPixBuf(SrcCopyRect,pD3DSurf,pb);
|
||||
|
||||
RELEASE(pD3DSurf,dxgsg8,"pD3DSurf",RELEASE_ONCE);
|
||||
|
||||
nassertv(!pb->_image.empty());
|
||||
nassertr(!pb->_image.empty(), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3421,11 +3419,11 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
bool DXGraphicsStateGuardian8::
|
||||
copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb) {
|
||||
set_read_buffer(rb);
|
||||
copy_pixel_buffer(pb, dr);
|
||||
return copy_pixel_buffer(pb, dr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ public:
|
|||
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
|
||||
const DisplayRegion *dr);
|
||||
|
||||
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr);
|
||||
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
virtual bool copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr);
|
||||
virtual bool copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
virtual void apply_material(const Material *material);
|
||||
|
|
|
|||
|
|
@ -3337,20 +3337,17 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
|
|||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
bool DXGraphicsStateGuardian9::
|
||||
copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
||||
|
||||
RECT SrcCopyRect;
|
||||
nassertv(pb != NULL && dr != NULL);
|
||||
nassertr(pb != NULL && dr != NULL, false);
|
||||
|
||||
int xo, yo, w, h;
|
||||
dr->get_region_pixels(xo, yo, w, h);
|
||||
|
||||
// only handled simple case
|
||||
nassertv(xo==0);
|
||||
nassertv(yo==0);
|
||||
nassertv(w==pb->get_xsize());
|
||||
nassertv(h==pb->get_ysize());
|
||||
nassertr(xo == 0 && yo==0 && w == pb->get_xsize() && h == pb->get_ysize(), false);
|
||||
|
||||
IDirect3DSurface9 *pD3DSurf;
|
||||
HRESULT hr;
|
||||
|
|
@ -3364,7 +3361,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
|
||||
if(FAILED(hr)) {
|
||||
dxgsg9_cat.error() << "GetBackBuffer failed" << D3DERRORSTRING(hr);
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
D3DSURFACE_DESC SurfDesc;
|
||||
|
|
@ -3405,34 +3402,35 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
SrcCopyRect.bottom=TmpSurfYsize;
|
||||
}
|
||||
|
||||
hr=_pD3DDevice->CreateOffscreenPlainSurface(TmpSurfXsize,TmpSurfYsize,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED, &pD3DSurf, NULL);
|
||||
hr=_pD3DDevice->CreateOffscreenPlainSurface(TmpSurfXsize,TmpSurfYsize,D3DFMT_A8R8G8B8,D3DPOOL_SCRATCH, &pD3DSurf, NULL);
|
||||
if(FAILED(hr)) {
|
||||
dxgsg9_cat.error() << "CreateImageSurface failed in copy_pixel_buffer()" << D3DERRORSTRING(hr);
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr=_pD3DDevice->GetFrontBufferData(0, pD3DSurf);
|
||||
|
||||
if(hr==D3DERR_DEVICELOST) {
|
||||
// dont necessary want to exit in this case
|
||||
pD3DSurf->Release();
|
||||
dxgsg9_cat.error() << "copy_pixel_buffer failed: device lost\n";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
dxgsg9_cat.error() << "copy_pixel_buffer: unhandled current_read_pixel_buffer type\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if((RECT_XSIZE(SrcCopyRect)>w) || (RECT_YSIZE(SrcCopyRect)>h)) {
|
||||
dxgsg9_cat.error() << "copy_pixel_buffer: pixel buffer size does not match selected screen RenderBuffer size!\n";
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
(void) ConvertD3DSurftoPixBuf(SrcCopyRect,pD3DSurf,pb);
|
||||
|
||||
RELEASE(pD3DSurf,dxgsg9,"pD3DSurf",RELEASE_ONCE);
|
||||
|
||||
nassertv(!pb->_image.empty());
|
||||
nassertr(!pb->_image.empty(), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3440,11 +3438,11 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
bool DXGraphicsStateGuardian9::
|
||||
copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb) {
|
||||
set_read_buffer(rb);
|
||||
copy_pixel_buffer(pb, dr);
|
||||
return copy_pixel_buffer(pb, dr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ public:
|
|||
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
|
||||
const DisplayRegion *dr);
|
||||
|
||||
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr);
|
||||
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
virtual bool copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr);
|
||||
virtual bool copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
virtual void apply_material(const Material *material);
|
||||
|
|
|
|||
|
|
@ -45,3 +45,4 @@ const float win_background_b = config_framework.GetFloat("win-background-b", 0.4
|
|||
const string record_session = config_framework.GetString("record-session", "");
|
||||
const string playback_session = config_framework.GetString("playback-session", "");
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -618,6 +618,14 @@ do_frame() {
|
|||
DataGraphTraverser dg_trav;
|
||||
dg_trav.traverse(_data_root.node());
|
||||
_event_handler.process_events();
|
||||
|
||||
if (!_screenshot_text.is_empty()) {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
if (now >= _screenshot_clear_time) {
|
||||
_screenshot_text.remove_node();
|
||||
}
|
||||
}
|
||||
|
||||
if (_recorder != (RecorderController *)NULL) {
|
||||
_recorder->record_frame();
|
||||
}
|
||||
|
|
@ -701,6 +709,7 @@ do_enable_default_keys() {
|
|||
define_key("arrow_left", "move highlight to sibling", event_arrow_left, this);
|
||||
define_key("arrow_right", "move highlight to sibling", event_arrow_right, this);
|
||||
define_key("shift-s", "activate PStats", event_S, this);
|
||||
define_key("f9", "Take screenshot", event_f9, this);
|
||||
define_key(",", "change background color", event_comma, this);
|
||||
define_key("?", "", event_question, this);
|
||||
define_key("shift-/", "", event_question, this);
|
||||
|
|
@ -708,6 +717,29 @@ do_enable_default_keys() {
|
|||
_event_handler.add_hook("window-event", event_window_event, this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaFramework::clear_text
|
||||
// Access: Protected
|
||||
// Description: Removes any onscreen text (like help text or
|
||||
// screenshot filename). Returns true if there was any
|
||||
// text in the first place, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PandaFramework::
|
||||
clear_text() {
|
||||
bool any_text = false;
|
||||
if (!_screenshot_text.is_empty()) {
|
||||
_screenshot_text.remove_node();
|
||||
any_text = true;
|
||||
}
|
||||
|
||||
if (!_help_text.is_empty()) {
|
||||
_help_text.remove_node();
|
||||
any_text = true;
|
||||
}
|
||||
|
||||
return any_text;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaFramework::event_esc
|
||||
// Access: Protected, Static
|
||||
|
|
@ -1031,7 +1063,7 @@ event_arrow_right(CPT_Event, void *data) {
|
|||
// Description: Default handler for shift-S key: activate stats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaFramework::
|
||||
event_S(CPT_Event, void *data) {
|
||||
event_S(CPT_Event, void *) {
|
||||
#ifdef DO_PSTATS
|
||||
nout << "Connecting to stats host" << endl;
|
||||
PStatClient::connect();
|
||||
|
|
@ -1040,6 +1072,48 @@ event_S(CPT_Event, void *data) {
|
|||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaFramework::event_f9
|
||||
// Access: Protected, Static
|
||||
// Description: Default handler for f9 key: take screenshot.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaFramework::
|
||||
event_f9(CPT_Event event, void *data) {
|
||||
PandaFramework *self = (PandaFramework *)data;
|
||||
|
||||
if (event->get_num_parameters() == 1) {
|
||||
EventParameter param = event->get_parameter(0);
|
||||
WindowFramework *wf;
|
||||
DCAST_INTO_V(wf, param.get_ptr());
|
||||
|
||||
if (self->clear_text()) {
|
||||
// Render one more frame to remove the text.
|
||||
self->_engine.render_frame();
|
||||
}
|
||||
|
||||
Filename filename = wf->get_graphics_window()->take_screenshot();
|
||||
string text;
|
||||
if (filename.empty()) {
|
||||
text = "Screenshot failed";
|
||||
} else {
|
||||
text = filename;
|
||||
}
|
||||
|
||||
TextNode *text_node = new TextNode("screenshot");
|
||||
self->_screenshot_text = NodePath(text_node);
|
||||
text_node->set_align(TextNode::A_center);
|
||||
text_node->set_shadow_color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
text_node->set_shadow(0.04f, 0.04f);
|
||||
text_node->set_text(text);
|
||||
self->_screenshot_text.set_scale(0.06);
|
||||
self->_screenshot_text.set_pos(0.0, 0.0, -0.7);
|
||||
self->_screenshot_text.reparent_to(wf->get_aspect_2d());
|
||||
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
self->_screenshot_clear_time = now + 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaFramework::event_comma
|
||||
// Access: Protected, Static
|
||||
|
|
@ -1073,15 +1147,17 @@ event_comma(CPT_Event event, void *) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaFramework::
|
||||
event_question(CPT_Event event, void *data) {
|
||||
cerr << "got question\n";
|
||||
PandaFramework *self = (PandaFramework *)data;
|
||||
if (event->get_num_parameters() == 1) {
|
||||
EventParameter param = event->get_parameter(0);
|
||||
WindowFramework *wf;
|
||||
DCAST_INTO_V(wf, param.get_ptr());
|
||||
|
||||
self->_screenshot_text.remove_node();
|
||||
|
||||
if (!self->_help_text.is_empty()) {
|
||||
self->_help_text.remove_node();
|
||||
// This key is a toggle; remove the help text and do nothing else.
|
||||
|
||||
} else {
|
||||
// Build up a string to display.
|
||||
|
|
@ -1096,12 +1172,12 @@ event_question(CPT_Event event, void *data) {
|
|||
|
||||
string help_text = help.str();
|
||||
|
||||
TextNode *text_node = new TextNode("text");
|
||||
TextNode *text_node = new TextNode("help");
|
||||
self->_help_text = NodePath(text_node);
|
||||
text_node->set_text(help_text);
|
||||
text_node->set_align(TextNode::A_left);
|
||||
text_node->set_shadow_color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
text_node->set_shadow(0.04f, 0.04f);
|
||||
text_node->set_text(help_text);
|
||||
|
||||
LVecBase4f frame = text_node->get_frame_actual();
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ protected:
|
|||
virtual PT(WindowFramework) make_window_framework();
|
||||
virtual void make_default_pipe();
|
||||
virtual void do_enable_default_keys();
|
||||
bool clear_text();
|
||||
|
||||
static void event_esc(CPT_Event, void *data);
|
||||
static void event_f(CPT_Event, void *data);
|
||||
|
|
@ -133,6 +134,7 @@ protected:
|
|||
static void event_arrow_left(CPT_Event, void *data);
|
||||
static void event_arrow_right(CPT_Event, void *data);
|
||||
static void event_S(CPT_Event, void *data);
|
||||
static void event_f9(CPT_Event, void *data);
|
||||
static void event_comma(CPT_Event, void *data);
|
||||
static void event_question(CPT_Event event, void *data);
|
||||
static void event_window_event(CPT_Event, void *data);
|
||||
|
|
@ -181,6 +183,8 @@ private:
|
|||
KeyDefinitions _key_definitions;
|
||||
|
||||
NodePath _help_text;
|
||||
NodePath _screenshot_text;
|
||||
double _screenshot_clear_time;
|
||||
|
||||
PT(RecorderController) _recorder;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ public:
|
|||
INLINE bool get_one_sided_reverse() const;
|
||||
INLINE bool get_lighting() const;
|
||||
INLINE BackgroundType get_background_type() const;
|
||||
|
||||
|
||||
protected:
|
||||
PT(Camera) make_camera();
|
||||
void setup_lights();
|
||||
|
|
|
|||
|
|
@ -1954,9 +1954,9 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
|
|||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GLGraphicsStateGuardian::
|
||||
bool GLGraphicsStateGuardian::
|
||||
copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
||||
nassertv(pb != NULL && dr != NULL);
|
||||
nassertr(pb != NULL && dr != NULL, false);
|
||||
set_pack_alignment(1);
|
||||
|
||||
// Bug fix for RE, RE2, and VTX - need to disable texturing in order
|
||||
|
|
@ -2014,7 +2014,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
|
||||
// pixelbuffer "origin" represents upper left screen point at which
|
||||
// pixelbuffer should be drawn using draw_pixel_buffer
|
||||
nassertv(!pb->_image.empty());
|
||||
nassertr(!pb->_image.empty(), false);
|
||||
glReadPixels(pb->get_xorg() + xo, pb->get_yorg() + yo,
|
||||
pb->get_xsize(), pb->get_ysize(),
|
||||
external_format,
|
||||
|
|
@ -2035,6 +2035,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
}
|
||||
|
||||
report_gl_errors();
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2042,11 +2043,11 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
|||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GLGraphicsStateGuardian::
|
||||
bool GLGraphicsStateGuardian::
|
||||
copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb) {
|
||||
set_read_buffer(rb);
|
||||
copy_pixel_buffer(pb, dr);
|
||||
return copy_pixel_buffer(pb, dr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -104,8 +104,8 @@ public:
|
|||
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
|
||||
const DisplayRegion *dr);
|
||||
|
||||
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr);
|
||||
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
virtual bool copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr);
|
||||
virtual bool copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
virtual void apply_material(const Material *material);
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ PUBLISHED:
|
|||
public:
|
||||
virtual void config( void ) { WritableConfigurable::config(); }
|
||||
|
||||
virtual void copy(GraphicsStateGuardianBase *, const DisplayRegion *)=0;
|
||||
virtual void copy(GraphicsStateGuardianBase *, const DisplayRegion *,
|
||||
virtual bool copy(GraphicsStateGuardianBase *, const DisplayRegion *)=0;
|
||||
virtual bool copy(GraphicsStateGuardianBase *, const DisplayRegion *,
|
||||
const RenderBuffer &rb)=0;
|
||||
|
||||
PUBLISHED:
|
||||
|
|
|
|||
|
|
@ -422,12 +422,12 @@ copy(const PixelBuffer *pb) {
|
|||
_image.v() = pb->_image.v();
|
||||
}
|
||||
|
||||
void PixelBuffer::copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr) {
|
||||
gsg->copy_pixel_buffer(this, dr);
|
||||
bool PixelBuffer::copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr) {
|
||||
return gsg->copy_pixel_buffer(this, dr);
|
||||
}
|
||||
|
||||
void PixelBuffer::copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
|
||||
bool PixelBuffer::copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb) {
|
||||
gsg->copy_pixel_buffer(this, dr, rb);
|
||||
return gsg->copy_pixel_buffer(this, dr, rb);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,10 +105,10 @@ public:
|
|||
bool store( PNMImage& pnmimage ) const;
|
||||
|
||||
void copy(const PixelBuffer *pb);
|
||||
|
||||
virtual void copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr);
|
||||
virtual void copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
virtual bool copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr);
|
||||
virtual bool copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
INLINE void set_xsize(int size);
|
||||
INLINE void set_ysize(int size);
|
||||
|
|
|
|||
|
|
@ -606,13 +606,15 @@ get_ram_image() {
|
|||
}
|
||||
}
|
||||
|
||||
void Texture::copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr) {
|
||||
bool Texture::copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr) {
|
||||
gsg->copy_texture(prepare(gsg), dr);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Texture::copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
|
||||
bool Texture::copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb) {
|
||||
gsg->copy_texture(prepare(gsg), dr, rb);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -116,8 +116,8 @@ public:
|
|||
|
||||
INLINE void apply(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
virtual void copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr);
|
||||
virtual void copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
|
||||
virtual bool copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr);
|
||||
virtual bool copy(GraphicsStateGuardianBase *gsg, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
// These bits are used as parameters to Texture::mark_dirty() and
|
||||
|
|
|
|||
|
|
@ -164,8 +164,8 @@ public:
|
|||
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
|
||||
const DisplayRegion *dr)=0;
|
||||
|
||||
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr)=0;
|
||||
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
virtual bool copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr)=0;
|
||||
virtual bool copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb)=0;
|
||||
|
||||
virtual void apply_material(const Material *material)=0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue