Patches contributed by Norman Vine to do ultra-hires tiled screen dumps.
This commit is contained in:
parent
52848158ff
commit
af2a0da64c
5 changed files with 313 additions and 19 deletions
|
@ -964,7 +964,19 @@ static void set_hud_color(float r, float g, float b) {
|
||||||
// all C++.
|
// all C++.
|
||||||
//
|
//
|
||||||
void fgUpdateHUD( void ) {
|
void fgUpdateHUD( void ) {
|
||||||
fgUpdateHUD( 0.0f, 0.0f, 640.0f, 480.0f );
|
|
||||||
|
static const float normal_aspect = float(640) / float(480);
|
||||||
|
// note: win_ratio is Y/X
|
||||||
|
float current_aspect = 1.0f/globals->get_current_view()->get_win_ratio();
|
||||||
|
if( current_aspect > normal_aspect ) {
|
||||||
|
float aspect_adjust = current_aspect / normal_aspect;
|
||||||
|
float adjust = 320.0f*aspect_adjust - 320.0f;
|
||||||
|
fgUpdateHUD( -adjust, 0.0f, 640.0f+adjust, 480.0f );
|
||||||
|
} else {
|
||||||
|
float aspect_adjust = normal_aspect / current_aspect;
|
||||||
|
float adjust = 240.0f*aspect_adjust - 240.0f;
|
||||||
|
fgUpdateHUD( 0.0f, -adjust, 640.0f, 480.0f+adjust );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
|
void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
|
||||||
|
@ -1009,6 +1021,7 @@ void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
|
||||||
// glEnable(GL_BLEND);
|
// glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);
|
glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);
|
||||||
|
// glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
|
||||||
glLineWidth(1.5);
|
glLineWidth(1.5);
|
||||||
} else {
|
} else {
|
||||||
glLineWidth(1.0);
|
glLineWidth(1.0);
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
/**
|
/**
|
||||||
* Calculate the aspect adjustment for the panel.
|
* Calculate the aspect adjustment for the panel.
|
||||||
*/
|
*/
|
||||||
float
|
static float
|
||||||
get_aspect_adjust (int xsize, int ysize)
|
get_aspect_adjust (int xsize, int ysize)
|
||||||
{
|
{
|
||||||
float ideal_aspect = float(WIN_W) / float(WIN_H);
|
float ideal_aspect = float(WIN_W) / float(WIN_H);
|
||||||
|
@ -240,32 +240,36 @@ FGPanel::unbind ()
|
||||||
void
|
void
|
||||||
FGPanel::update ()
|
FGPanel::update ()
|
||||||
{
|
{
|
||||||
float aspect_adjust = get_aspect_adjust(_xsize_node->getIntValue(),
|
|
||||||
_ysize_node->getIntValue());
|
|
||||||
|
|
||||||
// Do nothing if the panel isn't visible.
|
// Do nothing if the panel isn't visible.
|
||||||
if (!fgPanelVisible())
|
if (!fgPanelVisible())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If the mouse is down, do something
|
// If the mouse is down, do something
|
||||||
if (_mouseDown) {
|
if (_mouseDown) {
|
||||||
_mouseDelay--;
|
_mouseDelay--;
|
||||||
if (_mouseDelay < 0) {
|
if (_mouseDelay < 0) {
|
||||||
_mouseInstrument->doMouseAction(_mouseButton, _mouseX, _mouseY);
|
_mouseInstrument->doMouseAction(_mouseButton, _mouseX, _mouseY);
|
||||||
_mouseDelay = 2;
|
_mouseDelay = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Now, draw the panel
|
// Now, draw the panel
|
||||||
|
float aspect_adjust = get_aspect_adjust(_xsize_node->getIntValue(),
|
||||||
|
_ysize_node->getIntValue());
|
||||||
|
if (aspect_adjust <1.0)
|
||||||
|
update(WIN_X, int(WIN_W * aspect_adjust), WIN_Y, WIN_H);
|
||||||
|
else
|
||||||
|
update(WIN_X, WIN_W, WIN_Y, int(WIN_H / aspect_adjust));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FGPanel::update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh)
|
||||||
|
{
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
if (aspect_adjust <1.0)
|
gluOrtho2D(winx, winx + winw, winy, winy + winh);
|
||||||
gluOrtho2D(WIN_X, WIN_X + int(WIN_W * aspect_adjust),
|
|
||||||
WIN_Y, WIN_Y + WIN_H);
|
|
||||||
else
|
|
||||||
gluOrtho2D(WIN_X, WIN_X + WIN_W,
|
|
||||||
WIN_Y, WIN_Y + int(WIN_H / aspect_adjust));
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
|
@ -133,6 +133,7 @@ public:
|
||||||
virtual void bind ();
|
virtual void bind ();
|
||||||
virtual void unbind ();
|
virtual void unbind ();
|
||||||
virtual void update ();
|
virtual void update ();
|
||||||
|
virtual void update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh);
|
||||||
|
|
||||||
// transfer pointer ownership!!!
|
// transfer pointer ownership!!!
|
||||||
virtual void addInstrument (FGPanelInstrument * instrument);
|
virtual void addInstrument (FGPanelInstrument * instrument);
|
||||||
|
|
203
src/GUI/gui.cxx
203
src/GUI/gui.cxx
|
@ -450,6 +450,202 @@ void helpCb (puObject *)
|
||||||
//mkDialog (text.c_str());
|
//mkDialog (text.c_str());
|
||||||
mkDialog ("Help started in netscape window.");
|
mkDialog ("Help started in netscape window.");
|
||||||
}
|
}
|
||||||
|
#define TR_HIRES_SNAP
|
||||||
|
#if defined( TR_HIRES_SNAP)
|
||||||
|
#include <simgear/screen/tr.h>
|
||||||
|
extern void trRenderFrame( void );
|
||||||
|
extern void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
|
||||||
|
GLfloat x_end, GLfloat y_end );
|
||||||
|
|
||||||
|
void fgHiResDump()
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
string message;
|
||||||
|
bool show_pu_cursor = false;
|
||||||
|
bool show_menu = false;
|
||||||
|
char *filename = new char [24];
|
||||||
|
static int count = 1;
|
||||||
|
|
||||||
|
int freeze = globals->get_freeze();
|
||||||
|
if(!freeze)
|
||||||
|
globals->set_freeze( true );
|
||||||
|
|
||||||
|
if(gui_menu_on) {
|
||||||
|
show_menu = true;
|
||||||
|
guiToggleMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !puCursorIsHidden() ) {
|
||||||
|
show_pu_cursor = true;
|
||||||
|
puHideCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
fgInitVisuals();
|
||||||
|
fgReshape( fgGetInt("/sim/startup/xsize"),
|
||||||
|
fgGetInt("/sim/startup/ysize") );
|
||||||
|
|
||||||
|
// we need two render frames here to clear the menu and cursor
|
||||||
|
// ... not sure why but doing an extra fgRenderFrame() shouldn't
|
||||||
|
// hurt anything
|
||||||
|
fgRenderFrame();
|
||||||
|
fgRenderFrame();
|
||||||
|
|
||||||
|
// Make sure we have SSG projection primed for current view
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
ssgSetCamera( (sgVec4 *)globals->get_current_view()->get_VIEW() );
|
||||||
|
float fov = globals->get_current_view()->get_fov();
|
||||||
|
ssgSetFOV(fov, fov * globals->get_current_view()->get_win_ratio());
|
||||||
|
// ssgSetNearFar( 10.0f, 120000.0f );
|
||||||
|
ssgSetNearFar( 0.5f, 1200000.0f );
|
||||||
|
|
||||||
|
|
||||||
|
// This ImageSize stuff is a temporary hack
|
||||||
|
// should probably use 128x128 tile size and
|
||||||
|
// support any image size
|
||||||
|
|
||||||
|
// This should be a requester to get multiplier from user
|
||||||
|
int multiplier = 3;
|
||||||
|
int width = fgGetInt("/sim/startup/xsize");
|
||||||
|
int height = fgGetInt("/sim/startup/ysize");
|
||||||
|
|
||||||
|
/* allocate buffer large enough to store one tile */
|
||||||
|
GLubyte *tile = (GLubyte *)malloc(width * height * 3 * sizeof(GLubyte));
|
||||||
|
if (!tile) {
|
||||||
|
printf("Malloc of tile buffer failed!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int imageWidth = multiplier*width;
|
||||||
|
int imageHeight = multiplier*height;
|
||||||
|
|
||||||
|
/* allocate buffer to hold a row of tiles */
|
||||||
|
GLubyte *buffer
|
||||||
|
= (GLubyte *)malloc(imageWidth * height * 3 * sizeof(GLubyte));
|
||||||
|
if (!buffer) {
|
||||||
|
free(tile);
|
||||||
|
printf("Malloc of tile row buffer failed!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TRcontext *tr = trNew();
|
||||||
|
trTileSize(tr, width, height, 0);
|
||||||
|
trTileBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, tile);
|
||||||
|
trImageSize(tr, imageWidth, imageHeight);
|
||||||
|
trRowOrder(tr, TR_TOP_TO_BOTTOM);
|
||||||
|
sgFrustum *frustum = ssgGetFrustum();
|
||||||
|
trFrustum(tr,
|
||||||
|
frustum->getLeft(), frustum->getRight(),
|
||||||
|
frustum->getBot(), frustum->getTop(),
|
||||||
|
frustum->getNear(), frustum->getFar());
|
||||||
|
|
||||||
|
/* Prepare ppm output file */
|
||||||
|
while (count < 1000) {
|
||||||
|
snprintf(filename, 24, "fgfs-screen-%03d.ppm", count++);
|
||||||
|
if ( (f = fopen(filename, "r")) == NULL )
|
||||||
|
break;
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
f = fopen(filename, "wb");
|
||||||
|
if (!f) {
|
||||||
|
printf("Couldn't open image file: %s\n", filename);
|
||||||
|
free(buffer);
|
||||||
|
free(tile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(f,"P6\n");
|
||||||
|
fprintf(f,"# ppm-file created by %s\n", "trdemo2");
|
||||||
|
fprintf(f,"%i %i\n", imageWidth, imageHeight);
|
||||||
|
fprintf(f,"255\n");
|
||||||
|
|
||||||
|
/* just to be safe... */
|
||||||
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
|
/* Because the HUD and Panel change the ViewPort we will
|
||||||
|
* need to handle some lowlevel stuff ourselves */
|
||||||
|
int ncols = trGet(tr, TR_COLUMNS);
|
||||||
|
int nrows = trGet(tr, TR_ROWS);
|
||||||
|
|
||||||
|
bool do_hud = fgGetBool("/sim/hud/visibility");
|
||||||
|
GLfloat hud_col_step = 640.0 / ncols;
|
||||||
|
GLfloat hud_row_step = 480.0 / nrows;
|
||||||
|
|
||||||
|
bool do_panel = fgPanelVisible();
|
||||||
|
GLfloat panel_col_step = current_panel->getWidth() / ncols;
|
||||||
|
GLfloat panel_row_step = current_panel->getHeight() / nrows;
|
||||||
|
|
||||||
|
/* Draw tiles */
|
||||||
|
int more = 1;
|
||||||
|
while (more) {
|
||||||
|
trBeginTile(tr);
|
||||||
|
int curColumn = trGet(tr, TR_CURRENT_COLUMN);
|
||||||
|
int curRow = trGet(tr, TR_CURRENT_ROW);
|
||||||
|
trRenderFrame();
|
||||||
|
if ( do_hud )
|
||||||
|
fgUpdateHUD( curColumn*hud_col_step, curRow*hud_row_step,
|
||||||
|
(curColumn+1)*hud_col_step, (curRow+1)*hud_row_step );
|
||||||
|
if (do_panel)
|
||||||
|
current_panel->update( curColumn*panel_col_step, panel_col_step,
|
||||||
|
curRow*panel_row_step, panel_row_step );
|
||||||
|
more = trEndTile(tr);
|
||||||
|
|
||||||
|
/* save tile into tile row buffer*/
|
||||||
|
int curTileWidth = trGet(tr, TR_CURRENT_TILE_WIDTH);
|
||||||
|
int bytesPerImageRow = imageWidth * 3*sizeof(GLubyte);
|
||||||
|
int bytesPerTileRow = (width) * 3*sizeof(GLubyte);
|
||||||
|
int xOffset = curColumn * bytesPerTileRow;
|
||||||
|
int bytesPerCurrentTileRow = (curTileWidth) * 3*sizeof(GLubyte);
|
||||||
|
int i;
|
||||||
|
for (i=0;i<height;i++) {
|
||||||
|
memcpy(buffer + i*bytesPerImageRow + xOffset, /* Dest */
|
||||||
|
tile + i*bytesPerTileRow, /* Src */
|
||||||
|
bytesPerCurrentTileRow); /* Byte count*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curColumn == trGet(tr, TR_COLUMNS)-1) {
|
||||||
|
/* write this buffered row of tiles to the file */
|
||||||
|
int curTileHeight = trGet(tr, TR_CURRENT_TILE_HEIGHT);
|
||||||
|
int bytesPerImageRow = imageWidth * 3*sizeof(GLubyte);
|
||||||
|
int i;
|
||||||
|
for (i=0;i<curTileHeight;i++) {
|
||||||
|
/* Remember, OpenGL images are bottom to top. Have to reverse. */
|
||||||
|
GLubyte *rowPtr = buffer + (curTileHeight-1-i) * bytesPerImageRow;
|
||||||
|
fwrite(rowPtr, 1, imageWidth*3, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fgReshape( width, height );
|
||||||
|
|
||||||
|
trDelete(tr);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
message = "Snap shot saved to ";
|
||||||
|
message += filename;
|
||||||
|
mkDialog (message.c_str());
|
||||||
|
|
||||||
|
free(tile);
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
// message = "Snap shot saved to ";
|
||||||
|
// message += filename;
|
||||||
|
// mkDialog (message.c_str());
|
||||||
|
|
||||||
|
delete [] filename;
|
||||||
|
|
||||||
|
if( show_menu )
|
||||||
|
guiToggleMenu();
|
||||||
|
|
||||||
|
if ( show_pu_cursor ) {
|
||||||
|
puShowCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!freeze)
|
||||||
|
globals->set_freeze( false );
|
||||||
|
}
|
||||||
|
#endif // #if defined( TR_HIRES_SNAP)
|
||||||
|
|
||||||
|
|
||||||
#if defined( WIN32 ) && !defined( __CYGWIN__)
|
#if defined( WIN32 ) && !defined( __CYGWIN__)
|
||||||
|
|
||||||
|
@ -525,6 +721,11 @@ void dumpSnapShot ( puObject *obj ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dumpHiResSnapShot ( puObject *obj ) {
|
||||||
|
fgHiResDump();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// do a screen snap shot
|
// do a screen snap shot
|
||||||
void fgDumpSnapShot () {
|
void fgDumpSnapShot () {
|
||||||
bool show_pu_cursor = false;
|
bool show_pu_cursor = false;
|
||||||
|
@ -621,6 +822,7 @@ char *fileSubmenu [] = {
|
||||||
"Print",
|
"Print",
|
||||||
#endif
|
#endif
|
||||||
"Snap Shot",
|
"Snap Shot",
|
||||||
|
"Hires Snap Shot",
|
||||||
"---------",
|
"---------",
|
||||||
"Reset",
|
"Reset",
|
||||||
"Load flight",
|
"Load flight",
|
||||||
|
@ -634,6 +836,7 @@ puCallback fileSubmenuCb [] = {
|
||||||
#endif
|
#endif
|
||||||
/* NULL, notCb, */
|
/* NULL, notCb, */
|
||||||
dumpSnapShot,
|
dumpSnapShot,
|
||||||
|
dumpHiResSnapShot,
|
||||||
NULL,
|
NULL,
|
||||||
reInit,
|
reInit,
|
||||||
loadFlight,
|
loadFlight,
|
||||||
|
|
|
@ -311,6 +311,79 @@ void fgInitVisuals( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// For HiRes screen Dumps using Brian Pauls TR Library
|
||||||
|
void trRenderFrame( void ) {
|
||||||
|
|
||||||
|
if ( fgPanelVisible() ) {
|
||||||
|
GLfloat height = fgGetInt("/sim/startup/ysize");
|
||||||
|
GLfloat view_h =
|
||||||
|
(current_panel->getViewHeight() - current_panel->getYOffset())
|
||||||
|
* (height / 768.0) + 1;
|
||||||
|
glTranslatef( 0.0, view_h, 0.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static double m_log01 = -log( 0.01 );
|
||||||
|
static double sqrt_m_log01 = sqrt( m_log01 );
|
||||||
|
|
||||||
|
static GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
|
||||||
|
static GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
|
||||||
|
|
||||||
|
fgLIGHT *l = &cur_light_params;
|
||||||
|
|
||||||
|
glClearColor(l->adj_fog_color[0], l->adj_fog_color[1],
|
||||||
|
l->adj_fog_color[2], l->adj_fog_color[3]);
|
||||||
|
|
||||||
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
|
||||||
|
// set the opengl state to known default values
|
||||||
|
default_state->force();
|
||||||
|
|
||||||
|
// update fog params
|
||||||
|
double actual_visibility = thesky->get_visibility();
|
||||||
|
// GLfloat fog_exp_density = m_log01 / actual_visibility;
|
||||||
|
GLfloat fog_exp2_density = sqrt_m_log01 / actual_visibility;
|
||||||
|
GLfloat fog_exp2_punch_through = sqrt_m_log01 / ( actual_visibility * 1.5 );
|
||||||
|
|
||||||
|
glEnable( GL_FOG );
|
||||||
|
glFogf ( GL_FOG_DENSITY, fog_exp2_density);
|
||||||
|
glFogi ( GL_FOG_MODE, GL_EXP2 );
|
||||||
|
glFogfv ( GL_FOG_COLOR, l->adj_fog_color );
|
||||||
|
|
||||||
|
// GL_LIGHT_MODEL_AMBIENT has a default non-zero value so if
|
||||||
|
// we only update GL_AMBIENT for our lights we will never get
|
||||||
|
// a completely dark scene. So, we set GL_LIGHT_MODEL_AMBIENT
|
||||||
|
// explicitely to black.
|
||||||
|
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
|
||||||
|
|
||||||
|
ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient );
|
||||||
|
|
||||||
|
// texture parameters
|
||||||
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
|
||||||
|
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ;
|
||||||
|
|
||||||
|
// we need a white diffuse light for the phase of the moon
|
||||||
|
ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, white );
|
||||||
|
thesky->preDraw();
|
||||||
|
|
||||||
|
// draw the ssg scene
|
||||||
|
// return to the desired diffuse color
|
||||||
|
ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse );
|
||||||
|
glEnable( GL_DEPTH_TEST );
|
||||||
|
ssgCullAndDraw( scene );
|
||||||
|
|
||||||
|
// draw the lights
|
||||||
|
glFogf (GL_FOG_DENSITY, fog_exp2_punch_through);
|
||||||
|
ssgCullAndDraw( lighting );
|
||||||
|
|
||||||
|
thesky->postDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER );
|
||||||
|
|
||||||
|
// need to do this here as hud_and_panel state is static to
|
||||||
|
// main.cxx and HUD and Panel routines have to be called with
|
||||||
|
// knowledge of the the TR struct < see gui.cxx::HighResDump()
|
||||||
|
hud_and_panel->apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update all Visuals (redraws anything graphics related)
|
// Update all Visuals (redraws anything graphics related)
|
||||||
void fgRenderFrame( void ) {
|
void fgRenderFrame( void ) {
|
||||||
// Update the default (kludged) properties.
|
// Update the default (kludged) properties.
|
||||||
|
|
Loading…
Add table
Reference in a new issue