114 lines
3.1 KiB
C++
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);
|
|
}
|