Skip to content

Instantly share code, notes, and snippets.

@JDeeth
Last active April 11, 2018 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JDeeth/b315f03161a58fa4ea833b45c57e927f to your computer and use it in GitHub Desktop.
Save JDeeth/b315f03161a58fa4ea833b45c57e927f to your computer and use it in GitHub Desktop.
X-Plane OpenGL Hello World (copied from https://developer.x-plane.com/code-sample/texturedraw/)
#include "openglsnippet.h"
#include <cstring>
#if APL == 1
#include <OpenGL/OpenGL.h>
#include <OpenGL/glu.h>
#elif IBM == 1
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// order must be glew, gl, glu
#include "GL/glew.h"
#include <gl/gl.h>
#include <gl/glu.h>
#elif LIN == 1
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#include <XPLMDisplay.h>
#include <XPLMGraphics.h>
namespace OpenGLSnippet {
// Our texture dimensions. Textures MUST be powers of 2 in OpenGL - if you
// don't need that much space, just round up to the nearest power of 2.
const int WIDTH = 128;
const int HEIGHT = 128;
// This is our texture ID. Texture IDs in OpenGL are just ints...but this is a
// global for the life of our plugin.
static int g_tex_num = 0;
// We use this memory to prep the buffer. Note that this memory DOES NOT have
// to be global - the memory is FULLY read by OpenGL before glTexSubImage2D or
// glTexImage2D return, so you could use local or temporary storage, or change
// the image AS SOON as the call returns! 4 bytes for R,G,B,A 32-bit pixels.
static unsigned char buffer[WIDTH * HEIGHT * 4];
static int my_draw_tex(XPLMDrawingPhase, int, void*) {
// A really dumb bitmap generator - just fill R and G with x and Y based color
// watch, and the B and alpha channels based on mouse position.
int mx, my, sx, sy;
XPLMGetMouseLocation(&mx, &my);
XPLMGetScreenSize(&sx, &sy);
unsigned char* c = buffer;
for (int y = 0; y < HEIGHT; ++y)
for (int x = 0; x < WIDTH; ++x) {
*c++ = x * 255 / WIDTH;
*c++ = y * 255 / HEIGHT;
*c++ = mx * 255 / sx;
*c++ = my * 255 / sy;
}
XPLMBindTexture2d(g_tex_num, 0);
// Note: if the tex size is not changing, glTexSubImage2D is faster than
// glTexImage2D.
glTexSubImage2D(GL_TEXTURE_2D,
0, // mipmap level
0, // x-offset
0, // y-offset
WIDTH,
HEIGHT,
GL_RGBA, // color of data we are seding
GL_UNSIGNED_BYTE, // encoding of data we are sending
buffer);
// The drawing part.
XPLMSetGraphicsState(
0, // No fog, equivalent to glDisable(GL_FOG);
1, // One texture, equivalent to glEnable(GL_TEXTURE_2D);
0, // No lighting, equivalent to glDisable(GL_LIGHT0);
0, // No alpha testing, e.g glDisable(GL_ALPHA_TEST);
1, // Use alpha blending, e.g. glEnable(GL_BLEND);
0, // No depth read, e.g. glDisable(GL_DEPTH_TEST);
0); // No depth write, e.g. glDepthMask(GL_FALSE);
glColor3f(1, 1, 1); // Set color to white.
int x1 = 20;
int y1 = 20;
int x2 = x1 + WIDTH * 8;
int y2 = y1 + HEIGHT * 8;
// We draw one textured quad. Note: the first numbers 0,1 are texture
// coordinates, which are ratios. lower left is 0,0, upper right is 1,1. So
// if we wanted to use the lower half of the texture, we would use 0,0 to
// 0,0.5 to 1,0.5, to 1,0. Note that for X-Plane front facing polygons are
// clockwise unless you change it; if you change it, change it back!
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(x1, y1);
glTexCoord2f(0, 1);
glVertex2f(x1, y2);
glTexCoord2f(1, 1);
glVertex2f(x2, y2);
glTexCoord2f(1, 0);
glVertex2f(x2, y1);
glEnd();
return 1;
}
void start() {
// Initialization: allocate a textiure number.
XPLMGenerateTextureNumbers(&g_tex_num, 1);
XPLMBindTexture2d(g_tex_num, 0);
// Init to black for now.
memset(buffer, 0, WIDTH * HEIGHT * 4);
// The first time we must use glTexImage2D.
glTexImage2D(GL_TEXTURE_2D,
0, // mipmap level
GL_RGBA, // internal format for the GL to use. (We could ask
// for a floating point tex or 16-bit tex if we were crazy!)
WIDTH,
HEIGHT,
0, // border size
GL_RGBA, // format of color we are giving to GL
GL_UNSIGNED_BYTE, // encoding of our data
buffer);
// Note: we must set the filtering params to SOMETHING or OpenGL won't draw
// anything!
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
XPLMRegisterDrawCallback(my_draw_tex, xplm_Phase_Gauges, 0, nullptr);
}
void stop() {
XPLMUnregisterDrawCallback(my_draw_tex, xplm_Phase_Gauges, 0, nullptr);
XPLMBindTexture2d(g_tex_num, 0);
GLuint t = g_tex_num;
glDeleteTextures(1, &t);
}
} // namespace
#pragma once
// Code copied from https://developer.x-plane.com/code-sample/texturedraw/
// and minimally reorganised and reformatted
namespace OpenGLSnippet {
// call from XPluginStart
void start();
// call from XPluginStop
void stop();
} // namespace
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment