Pixel Zoom

From X-Plane SDK
Revision as of 21:36, 20 April 2011 by Bsupnik (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search



/*
	This sample plugin is still a work in progress...I wrote it as a test plugin to view
	pixel shader output in 'crisp' zoomed mode for FSAA work.
	
	I will document it more later - for now please note that this is not necessarily the
	fastest way to rip and pull X-plane output.

*/

#include "XPLMDefs.h"
#include "XPLMDisplay.h"
#include "XPLMGraphics.h"
#include "XPLMMenus.h"

#include <string.h>

#if APL
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif

static GLuint		tex_id = 0;
static int			bounds[4] = { 256, 192, 768, 576 };
static int			zooming = 0;
static XPLMMenuID	menu = 0;

static int rip_and_redraw_phase(
                                   XPLMDrawingPhase     inPhase,    
                                   int                  inIsBefore,    
                                   void *               inRefcon)
{
	if(tex_id == 0)
	{
		XPLMGenerateTextureNumbers((int *) &tex_id, 1);
		XPLMBindTexture2d(tex_id,0);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds[2] - bounds[0], bounds[3] - bounds[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	} else
		XPLMBindTexture2d(tex_id,0);

	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds[0], bounds[1], bounds[2] - bounds[0], bounds[3] - bounds[1]);
	XPLMSetGraphicsState(0, 1, 0,  0, 0,    0, 0);

	int x, y;
	
	XPLMGetScreenSize(&x, &y);

	glPushAttrib(GL_VIEWPORT_BIT);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glOrtho(0, x, 0, y, -1, 1);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	glViewport(0, 0, x, y);
	
	glColor3f(1,1,1);
	glBegin(GL_QUADS);
	glTexCoord2f(0,0);			glVertex2f(0,0);
	glTexCoord2f(0,1);			glVertex2f(0,y);
	glTexCoord2f(1,1);			glVertex2f(x,y);
	glTexCoord2f(1,0);			glVertex2f(x,0);
	glEnd();
	
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();	
	glPopAttrib();
	
	return 1;
}


static void toggle_zoom(void *               inMenuRef,    
                        void *               inItemRef)
{
	zooming = !zooming;
	XPLMCheckMenuItem(menu, 0, zooming ? xplm_Menu_Checked : xplm_Menu_Unchecked);
	if(zooming)
	{
		XPLMRegisterDrawCallback(rip_and_redraw_phase, xplm_Phase_Window, 1, NULL);
	}
	else
	{
		XPLMUnregisterDrawCallback(rip_and_redraw_phase, xplm_Phase_Window, 1, NULL);
	}
}



PLUGIN_API int XPluginStart(char * out_name, char * out_sig, char * out_desc)
{
	strcpy(out_name,"PixelZoom");
	strcpy(out_sig,"xpsdk.sample_code.pixel_zoom");
	strcpy(out_sig,"A plugin that lets you zoom into one part of the screen.");
	int i = XPLMAppendMenuItem(XPLMFindPluginsMenu(), "Pixel Zoom", NULL, 0);
	menu = XPLMCreateMenu("Pixel Zoom", XPLMFindPluginsMenu(), i, toggle_zoom, NULL);
	XPLMAppendMenuItem(menu, "Toggle Zoom", NULL, 0);
	return 1;
}


PLUGIN_API void XPluginStop()
{
}

PLUGIN_API int XPluginEnable(void)
{
	return 1;
}

PLUGIN_API void XPluginDisable(void)
{
}

PLUGIN_API void XPluginReceiveMessage(
					XPLMPluginID	inFromWho,
					long			inMessage,
					void *			inParam)
{
}