mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
X zoom window
This commit is contained in:
parent
5bde231490
commit
0f634524be
@ -446,27 +446,8 @@ end_scene() {
|
|||||||
int fb_xsize = int(xsize * pixel_factor);
|
int fb_xsize = int(xsize * pixel_factor);
|
||||||
int fb_ysize = int(ysize * pixel_factor);
|
int fb_ysize = int(ysize * pixel_factor);
|
||||||
|
|
||||||
int tyinc = _current_frame_buffer->linesize / PSZB;
|
ZB_zoomFrameBuffer(_current_frame_buffer, xmin, ymin, xsize, ysize,
|
||||||
int fyinc = _aux_frame_buffer->linesize / PSZB;
|
_aux_frame_buffer, 0, 0, fb_xsize, fb_ysize);
|
||||||
|
|
||||||
int fyt = 0;
|
|
||||||
for (int ty = 0; ty < ysize; ++ty) {
|
|
||||||
int fy = fyt / ysize;
|
|
||||||
fyt += fb_ysize;
|
|
||||||
|
|
||||||
PIXEL *tp = _current_frame_buffer->pbuf + xmin + (ymin + ty) * tyinc;
|
|
||||||
PIXEL *fp = _aux_frame_buffer->pbuf + fy * fyinc;
|
|
||||||
ZPOINT *tz = _current_frame_buffer->zbuf + xmin + (ymin + ty) * _current_frame_buffer->xsize;
|
|
||||||
ZPOINT *fz = _aux_frame_buffer->zbuf + fy * _aux_frame_buffer->xsize;
|
|
||||||
int fxt = 0;
|
|
||||||
for (int tx = 0; tx < xsize; ++tx) {
|
|
||||||
int fx = fxt / xsize;
|
|
||||||
fxt += fb_xsize;
|
|
||||||
|
|
||||||
tp[tx] = fp[fx];
|
|
||||||
tz[tx] = fz[fx];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_c->zb = _current_frame_buffer;
|
_c->zb = _current_frame_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,8 @@ TinyXGraphicsWindow(GraphicsPipe *pipe,
|
|||||||
_net_wm_state_add = tinyx_pipe->_net_wm_state_add;
|
_net_wm_state_add = tinyx_pipe->_net_wm_state_add;
|
||||||
_net_wm_state_remove = tinyx_pipe->_net_wm_state_remove;
|
_net_wm_state_remove = tinyx_pipe->_net_wm_state_remove;
|
||||||
|
|
||||||
_frame_buffer = NULL;
|
_reduced_frame_buffer = NULL;
|
||||||
|
_full_frame_buffer = NULL;
|
||||||
_ximage = NULL;
|
_ximage = NULL;
|
||||||
update_pixel_factor();
|
update_pixel_factor();
|
||||||
|
|
||||||
@ -159,7 +160,11 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
TinyGraphicsStateGuardian *tinygsg;
|
TinyGraphicsStateGuardian *tinygsg;
|
||||||
DCAST_INTO_R(tinygsg, _gsg, false);
|
DCAST_INTO_R(tinygsg, _gsg, false);
|
||||||
|
|
||||||
tinygsg->_current_frame_buffer = _frame_buffer;
|
if (_reduced_frame_buffer != (ZBuffer *)NULL) {
|
||||||
|
tinygsg->_current_frame_buffer = _reduced_frame_buffer;
|
||||||
|
} else {
|
||||||
|
tinygsg->_current_frame_buffer = _full_frame_buffer;
|
||||||
|
}
|
||||||
tinygsg->reset_if_new();
|
tinygsg->reset_if_new();
|
||||||
|
|
||||||
_gsg->set_current_properties(&get_fb_properties());
|
_gsg->set_current_properties(&get_fb_properties());
|
||||||
@ -210,17 +215,25 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void TinyXGraphicsWindow::
|
void TinyXGraphicsWindow::
|
||||||
begin_flip() {
|
begin_flip() {
|
||||||
if (_bytes_per_pixel == 4 && _pitch == _frame_buffer->linesize) {
|
if (_reduced_frame_buffer != (ZBuffer *)NULL) {
|
||||||
|
// Zoom the reduced buffer onto the full buffer.
|
||||||
|
ZB_zoomFrameBuffer(_full_frame_buffer, 0, 0,
|
||||||
|
_full_frame_buffer->xsize, _full_frame_buffer->ysize,
|
||||||
|
_reduced_frame_buffer, 0, 0,
|
||||||
|
_reduced_frame_buffer->xsize, _reduced_frame_buffer->ysize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_bytes_per_pixel == 4 && _pitch == _full_frame_buffer->linesize) {
|
||||||
// If we match the expected bpp, we don't need an intervening copy
|
// If we match the expected bpp, we don't need an intervening copy
|
||||||
// operation. Just point the XImage directly at the framebuffer
|
// operation. Just point the XImage directly at the framebuffer
|
||||||
// data.
|
// data.
|
||||||
_ximage->data = (char *)_frame_buffer->pbuf;
|
_ximage->data = (char *)_full_frame_buffer->pbuf;
|
||||||
} else {
|
} else {
|
||||||
ZB_copyFrameBuffer(_frame_buffer, _ximage->data, _pitch);
|
ZB_copyFrameBuffer(_full_frame_buffer, _ximage->data, _pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
XPutImage(_display, _xwindow, _gc, _ximage, 0, 0, 0, 0,
|
XPutImage(_display, _xwindow, _gc, _ximage, 0, 0, 0, 0,
|
||||||
_frame_buffer->xsize, _frame_buffer->ysize);
|
_full_frame_buffer->xsize, _full_frame_buffer->ysize);
|
||||||
XFlush(_display);
|
XFlush(_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,8 +344,9 @@ process_events() {
|
|||||||
// A normal window may be resized by the user at will.
|
// A normal window may be resized by the user at will.
|
||||||
properties.set_size(event.xconfigure.width, event.xconfigure.height);
|
properties.set_size(event.xconfigure.width, event.xconfigure.height);
|
||||||
system_changed_properties(properties);
|
system_changed_properties(properties);
|
||||||
ZB_resize(_frame_buffer, NULL, _properties.get_x_size(), _properties.get_y_size());
|
ZB_resize(_full_frame_buffer, NULL, _properties.get_x_size(), _properties.get_y_size());
|
||||||
_pitch = (_frame_buffer->xsize * _bytes_per_pixel + 3) & ~3;
|
_pitch = (_full_frame_buffer->xsize * _bytes_per_pixel + 3) & ~3;
|
||||||
|
create_reduced_frame_buffer();
|
||||||
create_ximage();
|
create_ximage();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -774,16 +788,17 @@ open_window() {
|
|||||||
|
|
||||||
_gc = XCreateGC(_display, _xwindow, 0, NULL);
|
_gc = XCreateGC(_display, _xwindow, 0, NULL);
|
||||||
|
|
||||||
create_frame_buffer();
|
create_full_frame_buffer();
|
||||||
if (_frame_buffer == NULL) {
|
if (_full_frame_buffer == NULL) {
|
||||||
tinydisplay_cat.error()
|
tinydisplay_cat.error()
|
||||||
<< "Could not create frame buffer.\n";
|
<< "Could not create frame buffer.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
create_reduced_frame_buffer();
|
||||||
create_ximage();
|
create_ximage();
|
||||||
nassertr(_ximage != NULL, false);
|
nassertr(_ximage != NULL, false);
|
||||||
|
|
||||||
tinygsg->_current_frame_buffer = _frame_buffer;
|
tinygsg->_current_frame_buffer = _full_frame_buffer;
|
||||||
|
|
||||||
tinygsg->reset_if_new();
|
tinygsg->reset_if_new();
|
||||||
if (!tinygsg->is_valid()) {
|
if (!tinygsg->is_valid()) {
|
||||||
@ -805,6 +820,17 @@ open_window() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TinyXGraphicsWindow::pixel_factor_changed
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Called internally when the pixel factor changes.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void TinyXGraphicsWindow::
|
||||||
|
pixel_factor_changed() {
|
||||||
|
GraphicsWindow::pixel_factor_changed();
|
||||||
|
create_reduced_frame_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TinyXGraphicsWindow::set_wm_properties
|
// Function: TinyXGraphicsWindow::set_wm_properties
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -1580,16 +1606,16 @@ check_event(Display *display, XEvent *event, char *arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TinyXGraphicsWindow::create_frame_buffer
|
// Function: TinyXGraphicsWindow::create_full_frame_buffer
|
||||||
// Access: Private
|
// Access: Private
|
||||||
// Description: Creates a suitable frame buffer for the current
|
// Description: Creates a suitable frame buffer for the current
|
||||||
// window size.
|
// window size.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void TinyXGraphicsWindow::
|
void TinyXGraphicsWindow::
|
||||||
create_frame_buffer() {
|
create_full_frame_buffer() {
|
||||||
if (_frame_buffer != NULL) {
|
if (_full_frame_buffer != NULL) {
|
||||||
ZB_close(_frame_buffer);
|
ZB_close(_full_frame_buffer);
|
||||||
_frame_buffer = NULL;
|
_full_frame_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mode;
|
int mode;
|
||||||
@ -1610,8 +1636,34 @@ create_frame_buffer() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_frame_buffer = ZB_open(_properties.get_x_size(), _properties.get_y_size(), mode, 0, 0, 0, 0);
|
_full_frame_buffer = ZB_open(_properties.get_x_size(), _properties.get_y_size(), mode, 0, 0, 0, 0);
|
||||||
_pitch = (_frame_buffer->xsize * _bytes_per_pixel + 3) & ~3;
|
_pitch = (_full_frame_buffer->xsize * _bytes_per_pixel + 3) & ~3;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TinyXGraphicsWindow::create_reduced_frame_buffer
|
||||||
|
// Access: Private
|
||||||
|
// Description: Creates a suitable frame buffer for the current
|
||||||
|
// window size and pixel zoom.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void TinyXGraphicsWindow::
|
||||||
|
create_reduced_frame_buffer() {
|
||||||
|
if (_reduced_frame_buffer != NULL) {
|
||||||
|
ZB_close(_reduced_frame_buffer);
|
||||||
|
_reduced_frame_buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x_size = get_fb_x_size();
|
||||||
|
int y_size = get_fb_y_size();
|
||||||
|
|
||||||
|
if (x_size == _full_frame_buffer->xsize) {
|
||||||
|
// No zooming is necessary.
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// The reduced size is different, so we need a separate buffer to
|
||||||
|
// render into.
|
||||||
|
_reduced_frame_buffer = ZB_open(x_size, y_size, _full_frame_buffer->mode, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1632,14 +1684,14 @@ create_ximage() {
|
|||||||
_ximage = NULL;
|
_ximage = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int image_size = _frame_buffer->ysize * _pitch;
|
int image_size = _full_frame_buffer->ysize * _pitch;
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
if (_bytes_per_pixel != 4) {
|
if (_bytes_per_pixel != 4) {
|
||||||
data = (char *)PANDA_MALLOC_ARRAY(image_size);
|
data = (char *)PANDA_MALLOC_ARRAY(image_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ximage = XCreateImage(_display, _visual, _depth, ZPixmap, 0, data,
|
_ximage = XCreateImage(_display, _visual, _depth, ZPixmap, 0, data,
|
||||||
_frame_buffer->xsize, _frame_buffer->ysize,
|
_full_frame_buffer->xsize, _full_frame_buffer->ysize,
|
||||||
32, 0);
|
32, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual void close_window();
|
virtual void close_window();
|
||||||
virtual bool open_window();
|
virtual bool open_window();
|
||||||
|
virtual void pixel_factor_changed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_wm_properties(const WindowProperties &properties,
|
void set_wm_properties(const WindowProperties &properties,
|
||||||
@ -69,11 +70,13 @@ private:
|
|||||||
void open_raw_mice();
|
void open_raw_mice();
|
||||||
void poll_raw_mice();
|
void poll_raw_mice();
|
||||||
|
|
||||||
void create_frame_buffer();
|
void create_full_frame_buffer();
|
||||||
|
void create_reduced_frame_buffer();
|
||||||
void create_ximage();
|
void create_ximage();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZBuffer *_frame_buffer;
|
ZBuffer *_reduced_frame_buffer;
|
||||||
|
ZBuffer *_full_frame_buffer;
|
||||||
int _pitch;
|
int _pitch;
|
||||||
XImage *_ximage;
|
XImage *_ximage;
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ void ZB_resize(ZBuffer * zb, void *frame_buffer, int xsize, int ysize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ZB_copyBuffer(ZBuffer * zb,
|
static void ZB_copyBuffer(const ZBuffer * zb,
|
||||||
void *buf,
|
void *buf,
|
||||||
int linesize)
|
int linesize)
|
||||||
{
|
{
|
||||||
@ -152,7 +152,7 @@ static void ZB_copyBuffer(ZBuffer * zb,
|
|||||||
(((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3))
|
(((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3))
|
||||||
|
|
||||||
/* XXX: not optimized */
|
/* XXX: not optimized */
|
||||||
static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
|
static void ZB_copyFrameBuffer5R6G5B(const ZBuffer * zb,
|
||||||
void *buf, int linesize)
|
void *buf, int linesize)
|
||||||
{
|
{
|
||||||
PIXEL *q;
|
PIXEL *q;
|
||||||
@ -178,7 +178,7 @@ static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: not optimized */
|
/* XXX: not optimized */
|
||||||
static void ZB_copyFrameBufferRGB24(ZBuffer * zb,
|
static void ZB_copyFrameBufferRGB24(const ZBuffer * zb,
|
||||||
void *buf, int linesize)
|
void *buf, int linesize)
|
||||||
{
|
{
|
||||||
PIXEL *q;
|
PIXEL *q;
|
||||||
@ -204,7 +204,7 @@ static void ZB_copyFrameBufferRGB24(ZBuffer * zb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
|
void ZB_copyFrameBuffer(const ZBuffer * zb, void *buf,
|
||||||
int linesize)
|
int linesize)
|
||||||
{
|
{
|
||||||
switch (zb->mode) {
|
switch (zb->mode) {
|
||||||
@ -228,6 +228,33 @@ void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy from (source_xmin,source_ymin)+(source_xsize,source_ysize) to
|
||||||
|
// (dest_xmin,dest_ymin)+(dest_xsize,dest_ysize).
|
||||||
|
void ZB_zoomFrameBuffer(ZBuffer *dest, int dest_xmin, int dest_ymin, int dest_xsize, int dest_ysize,
|
||||||
|
const ZBuffer *source, int source_xmin, int source_ymin, int source_xsize, int source_ysize) {
|
||||||
|
int tyinc = dest->linesize / PSZB;
|
||||||
|
int fyinc = source->linesize / PSZB;
|
||||||
|
|
||||||
|
int fyt = 0;
|
||||||
|
for (int ty = 0; ty < dest_ysize; ++ty) {
|
||||||
|
int fy = fyt / dest_ysize;
|
||||||
|
fyt += source_ysize;
|
||||||
|
|
||||||
|
PIXEL *tp = dest->pbuf + dest_xmin + (dest_ymin + ty) * tyinc;
|
||||||
|
PIXEL *fp = source->pbuf + source_xmin + (source_ymin + fy) * fyinc;
|
||||||
|
ZPOINT *tz = dest->zbuf + dest_xmin + (dest_ymin + ty) * dest->xsize;
|
||||||
|
ZPOINT *fz = source->zbuf + source_xmin + (source_ymin + fy) * source->xsize;
|
||||||
|
int fxt = 0;
|
||||||
|
for (int tx = 0; tx < dest_xsize; ++tx) {
|
||||||
|
int fx = fxt / dest_xsize;
|
||||||
|
fxt += source_xsize;
|
||||||
|
|
||||||
|
tp[tx] = fp[fx];
|
||||||
|
tz[tx] = fz[fx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* adr must be aligned on an 'int'
|
* adr must be aligned on an 'int'
|
||||||
|
@ -229,7 +229,11 @@ int texcoord_mirror(int coord, int max_coord);
|
|||||||
int texcoord_mirror_once(int coord, int max_coord);
|
int texcoord_mirror_once(int coord, int max_coord);
|
||||||
|
|
||||||
/* linesize is in BYTES */
|
/* linesize is in BYTES */
|
||||||
void ZB_copyFrameBuffer(ZBuffer *zb,void *buf,int linesize);
|
void ZB_copyFrameBuffer(const ZBuffer *zb,void *buf,int linesize);
|
||||||
|
void ZB_zoomFrameBuffer(ZBuffer *dest, int dest_xmin, int dest_ymin,
|
||||||
|
int dest_xsize, int dest_ysize,
|
||||||
|
const ZBuffer *source, int source_xmin, int source_ymin,
|
||||||
|
int source_xsize, int source_ysize);
|
||||||
|
|
||||||
/* zdither.c */
|
/* zdither.c */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user