open_toontown_panda3d/panda/src/testbed/motion.cxx

114 lines
3.1 KiB
C++

// Filename: motion.cxx
// Created by: frang (23Mar99)
//
////////////////////////////////////////////////////////////////////
#include <eventHandler.h>
#include <texture.h>
#include <graphicsWindow.h>
#include <graphicsStateGuardian.h>
#include <chancfg.h>
#include <notify.h>
#include <string>
#include <list>
extern GraphicsWindow* win;
extern int framework_main(int argc, char *argv[]);
extern void (*extra_display_func)();
extern void (*define_keys)(EventHandler&);
#include <GL/gl.h>
typedef list<Texture*> TexList;
TexList screenshots;
typedef list<PixelBuffer*> PBList;
PBList sshots;
int num_frames = 4;
int frame_num = 0;
void motion_display_func( void ) {
GraphicsStateGuardian* g = win->get_gsg();
const RenderBuffer& r = g->get_render_buffer(RenderBuffer::T_front);
Texture* t;
PixelBuffer* p;
if (frame_num < num_frames) {
t = new Texture;
t->_pbuffer->set_xsize(win->get_width());
t->_pbuffer->set_ysize(win->get_height());
p = new PixelBuffer;
p->set_xsize(win->get_width());
p->set_ysize(win->get_height());
p->_image = PTA_uchar(win->get_width() * win->get_height() * 4);
} else {
TexList::iterator i = screenshots.begin();
PBList::iterator l = sshots.begin();
for (int j=0, k=frame_num%num_frames; j<k; ++i, ++j, ++l);
t = *i;
p = *l;
}
// g->copy_texture_from(t, r);
g->copy_pixel_buffer_from(p, r);
const RenderBuffer& rb = g->get_render_buffer(RenderBuffer::T_back);
if (frame_num < num_frames) {
// screenshots.push_back(t);
sshots.push_back(p);
}
// now we accumulate. Off the top of my head I have 3 plans for this:
// 1) apply the screen shots to one or several whole-screen polygon(s) with
// appropriate alpha
// 2) accumulate this into an accumulation buffer every frame
// 3) blend the new frame into the accumulation buffer, and subtractively
// blend the old one out.
// version 2. Even this could be better if we didn't start by blowing away
// the frame we just rendered.
GLfloat d = 1. / GLfloat(screenshots.size() + 1.);
TexList::iterator i = screenshots.begin();
PBList::iterator j = sshots.begin();
// for (TexList::iterator i=screenshots.begin(); i!=screenshots.end(); ++i) {
for (; j!=sshots.end(); ++j) {
// t = *i;
// g->draw_texture_to(t, rb);
p = *j;
g->draw_pixel_buffer_to(p, rb);
// if (i == screenshots.begin())
if (j == sshots.begin())
glAccum(GL_LOAD, d);
else
glAccum(GL_ACCUM, d);
}
glAccum(GL_RETURN, 1.0);
g->end_frame();
++frame_num;
}
void event_plus(CPT_Event) {
frame_num %= num_frames++;
nout << "now blending " << num_frames << " frames." << endl;
}
void event_minus(CPT_Event) {
frame_num %= --num_frames;
nout << "now blending " << num_frames << " frames." << endl;
// screenshots.erase(--(screenshots.end()));
sshots.erase(--(sshots.end()));
}
void motion_keys(EventHandler& eh) {
eh.add_hook("plus", event_plus);
eh.add_hook("minus", event_minus);
}
int main(int argc, char *argv[]) {
extra_display_func = &motion_display_func;
define_keys = &motion_keys;
return framework_main(argc, argv);
}