What Is The Fastest Way to Display an Image in Qt on X11 Without Opengl

What is the fastest way to display an image in QT on X11 without OpenGL?

did you try to use XPutImage? (or XShmPutImage if you going to transfer image more then once from client and have MIT-SHM extension available) Also look at video4linux webcam sample viewer.c, but they convert 565 to 16 or 24 bit depth before sending. For your setup it should be possible to send image without conversion

How do I render Video in Qt / X11 on an embedded device

After downloading and reading through the VLC source code I settled on using the Xvideo extension for X11. The VLC source code contains an xvideo output "engine" using xcb to communicated with the xserver. I used this as an example to code my own solution.

On our platform the scaling and display features of the xvideo extension are hardware accelerated.

I intend to provide a tutorial and example code as soon as time allows.

Displaying raw image data from DirectShow in Qt with OpenGL

To display the image in a QLabel (not upside down):

ui->imageLabel->setPixmap(QPixmap::fromImage(img.mirrored(false, true)));

The problem here is that you are having the image in the GL/Windows format that Qt does not expect. Qt expects the X11 format, being a 180° rotated GL image.

But you could as well go ahead and use a QGLWidget where you draw a square and map the image as texture on it.

How it would work for OpenGL in a QGLWidget:

GLuint texture;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_buffer);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glColor3f(1.0, 1.0, 1.0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0, 0);
glVertex2f(-1, -1);
glTexCoord2f(1, 0);
glVertex2f(1, -1);
glTexCoord2f(0, 1);
glVertex2f(-1, 1);
glTexCoord2f(1, 1);
glVertex2f(1, 1);
glEnd();
glPopMatrix();

Draw pixels in a linux window without OpenGL in C

How can I draw pixels inside of a linux window manually?

Linux per-se doesn't know about windows (or any graphics beyond screen framebuffers for that matter).

Are you addressing X11, Wayland (or Mir or DirectFB – those later two are hardly used these days).

OpenGL or similar libraries

OpenGL is not a library. It's an API that allows you to talk more or less directly to the GPU (there's a lot of bookkeeping behind the scenes). If you want an even more hands-on API then use Vulkan. Those are the most direct ways to use a GPU, short of writing your own drivers.

Is it possible to write something pixel-by-pixel in the window?

Yes it is, but it's terribly inefficient, since doing it pixel-by-pixel will involve a complete trip from your program through several abstraction layer until it reaches the destination.

It's much more efficient to just send complete pictures, or ask for getting raw access to the framebuffer to write to it directly. Of course to be really efficient you want to make use of the GPU's capabilities. And that will require talking to it through an API as OpenGL or Vulkan.

With X11 what you can do it create an X MIT-SHM pixmap and map it into your process' address space and directly manipulate it's contents. To show it on screen you then use XPutImage to copy it into the window.

With Wayland you can get a mapping of the window's framebuffer itself, so that you don't have to do that additional copy step.

Update / Minimal example of how to use MIT-SHM with Xcb

This example shows how to obtain with X11 MIT-SHM a process address spaced framebuffer for direct pixel manipulation. Based on the Xcb tutorial https://xcb.freedesktop.org/tutorial/basicwindowsanddrawing/ to which I added my own code.

/* 
* compile with
*
* gcc -o minimal_xcb_shm_image \
* minimal_xcb_shm_image.c \
* -lxcb -lxcb-image -lxcb-shm
*/
#include <stdlib.h>
#include <stdio.h>

#include <sys/ipc.h>
#include <sys/shm.h>

#include <xcb/xcb.h>
#include <xcb/shm.h>
#include <xcb/xcb_image.h>

#if __ORDER_LITTLE_ENDIAN == __BYTE_ORDER__
# define NATIVE_XCB_IMAGE_ORDER XCB_IMAGE_ORDER_LSB_FIRST
#else
# define NATIVE_XCB_IMAGE_ORDER XCB_IMAGE_ORDER_MSB_FIRST
#endif

enum {
IMAGE_WIDTH = 512,
IMAGE_HEIGHT = 512,
IMAGE_DEPTH = 24,
};

static xcb_format_t const *query_xcb_format_for_depth(
xcb_connection_t *const connection,
unsigned depth )
{
xcb_setup_t const *const setup = xcb_get_setup(connection);
xcb_format_iterator_t it;
for( it = xcb_setup_pixmap_formats_iterator(setup)
; it.rem
; xcb_format_next(&it)
){
xcb_format_t const *const format = it.data;
if( format->depth == depth ){
return format;
}
}
return NULL;
}

typedef struct shm_xcb_image_t {
xcb_connection_t *connection;
xcb_image_t *image;
xcb_shm_seg_t shm_seg;
int shm_id;
} shm_xcb_image_t;

static shm_xcb_image_t *shm_xcb_image_create(
xcb_connection_t *const connection,
unsigned const width,
unsigned const height,
unsigned const depth )
{
xcb_generic_error_t *error = NULL;

shm_xcb_image_t *shmimg = calloc(1, sizeof(*shmimg));
if( !shmimg ){ goto fail; }
shmimg->connection = connection;

xcb_format_t const *const format = query_xcb_format_for_depth(connection, depth);
if( !format ){ goto fail; }
shmimg->image = xcb_image_create(
width, height,
XCB_IMAGE_FORMAT_Z_PIXMAP,
format->scanline_pad,
format->depth, format->bits_per_pixel, 0,
NATIVE_XCB_IMAGE_ORDER,
XCB_IMAGE_ORDER_MSB_FIRST,
NULL, ~0, 0);
if( !shmimg->image ){ goto fail; }

size_t const image_segment_size = shmimg->image->stride * shmimg->image->height;

shmimg->shm_id = shmget(IPC_PRIVATE, image_segment_size, IPC_CREAT | 0600);
if( 0 > shmimg->shm_id ){ goto fail; }

shmimg->image->data = shmat(shmimg->shm_id, 0, 0);
if( (void*)-1 == (void*)(shmimg->image->data) ){ goto fail; }

shmimg->shm_seg = xcb_generate_id(connection),
error = xcb_request_check(connection,
xcb_shm_attach_checked(
connection,
shmimg->shm_seg, shmimg->shm_id, 0) );
fail:
if( shmimg ){
if( shmimg->image ){
if( shmimg->image->data && error ){
shmdt(shmimg->image->data);
shmimg->image->data = NULL;
}
if( !shmimg->image->data ){
shmctl(shmimg->shm_id, IPC_RMID, 0);
shmimg->shm_id = -1;
}
}
if( 0 > shmimg->shm_id ){
xcb_image_destroy(shmimg->image);
shmimg->image = NULL;
}
if( !shmimg->image ){
free(shmimg);
shmimg = NULL;
}
}
free(error);

return shmimg;
}

static void shm_xcb_image_destroy(shm_xcb_image_t *shmimg)
{
xcb_shm_detach(shmimg->connection, shmimg->shm_seg);
shmdt(shmimg->image->data);
shmctl(shmimg->shm_id, IPC_RMID, 0);
xcb_image_destroy(shmimg->image);
free(shmimg);
}

static void generate_image(
shm_xcb_image_t *shmimg,
unsigned t )
{
for( unsigned j = 0; j < shmimg->image->height; ++j ){
uint8_t *const line = shmimg->image->data + j * shmimg->image->stride;
for( unsigned i = 0; i < shmimg->image->width; ++i ){
unsigned const bytes_per_pixel = shmimg->image->bpp/8;
uint8_t *pixel = line + i * bytes_per_pixel;

unsigned const a = (i + t);
unsigned const b = (j + (i >> 8) & 0xFF);
unsigned const c = (j >> 8) & 0xFF;

switch( bytes_per_pixel ){
case 4: pixel[3] = 0xFF; /* fallthrough */
case 3: pixel[2] = a & 0xFF; /* fallthrough */
case 2: pixel[1] = b & 0xFF; /* fallthrough */
case 1: pixel[0] = c & 0xFF; /* fallthrough */
default: break;
}
}
}
}

int main(int argc, char *argv[])
{
/* Open the connection to the X server */
xcb_connection_t *connection = xcb_connect(NULL, NULL);

/* Check that X MIT-SHM is available (should be). */
const xcb_query_extension_reply_t *shm_extension = xcb_get_extension_data(connection, &xcb_shm_id);
if( !shm_extension || !shm_extension->present ){
fprintf(stderr, "Query for X MIT-SHM extension failed.\n");
return 1;
}

shm_xcb_image_t *shmimg = shm_xcb_image_create(connection, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DEPTH);
if( !shmimg ){
fprintf(stderr, "Creating shared memory image failed");
}

/* Get the first screen */
xcb_screen_t *const screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;

/* Create a window */
uint32_t const window_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t const window_values[] = { screen->white_pixel, XCB_EVENT_MASK_EXPOSURE};
xcb_drawable_t const window = xcb_generate_id(connection);
xcb_create_window(connection,
XCB_COPY_FROM_PARENT, /* depth */
window, /* window Id */
screen->root, /* parent window */
0, 0, /* x, y */
IMAGE_WIDTH, IMAGE_HEIGHT, /* width, height */
0, /* border_width */
XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
screen->root_visual, /* visual */
window_mask, window_values /* masks */
);

/* Create black (foreground) graphic context */
xcb_gcontext_t const gc = xcb_generate_id( connection );
uint32_t const gc_mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
uint32_t const gc_values[] = {screen->black_pixel, 0};
xcb_create_gc(connection, gc, window, gc_mask, gc_values);

/* Map the window on the screen and flush*/
xcb_map_window(connection, window);
xcb_flush(connection);

/* Event loop */
unsigned counter = 0;
for( xcb_generic_event_t *event
; (event = xcb_wait_for_event(connection))
; free(event)
){
switch( event->response_type & ~0x80 ){
case XCB_EXPOSE:
generate_image(shmimg, counter++);
xcb_shm_put_image(connection, window, gc,
shmimg->image->width, shmimg->image->height, 0, 0,
shmimg->image->width, shmimg->image->height, 0, 0,
shmimg->image->depth, shmimg->image->format, 0,
shmimg->shm_seg, 0);

/* flush the request */
xcb_flush(connection);
break;
default:
/* Unknown event type, ignore it */
break;
}

}

shm_xcb_image_destroy(shmimg);

return 0;
}

Does OpenGL use Xlib to draw windows and render things, or is it the other way around?

WARNING: Wall of text coming in!

@sourcejedi already gave an answer but there are some inaccuracies in it – that are not hurtful, but may be confusing.

First and foremost OpenGL and Xlib are orthogonal with each other. Neither depends on the other one and you can use them independently. There is a dependency on Xlib by GLX (which is, why you can't fully ditch Xlib in favor of Xcb if you want to GLX), but the surface area of that dependency is small enough, so that you can use Xcb for the most part and use the Xlib-on-Xcb wrapper for the few parts where you have to use GLX. Now I've dropped a few acronyms here, so let's categorize them first:

Xlib & Xcb are both libraries that implement the client side of the X11 protocol. Technically you could talk to a X11 server without them, by implementing the protocol "yourself" (in fact there is an ongoing effort to autogenerate Haskell code from the same specification files that are also used to generate Xcb code). X11 is transferred over sockets, so if you can somehow transfer that socket and some internal state between bindings you can even mix and match bindings, if you're careful where you tread.

OpenGL itself is a pure low level (low level in the sense of which primitives it offers: points, lines and triangles) drawing tool, and there is no concept of "windows" in it. With the introduction of framebuffer objects, in principle you can create a headless OpenGL context and operate entirely within the bounds of self-managed image surfaces. But often (but certainly not always) you want your drawing(s) to be visible immediately on a display. That's where a window system interface (WSI) comes into play. OpenGL and thereby the whole support structure around it is quite old though, so not a lot of thought has been put into the whole WSI business, which led to a rather, well… actually there's no cleanly defined interface for this at all, so far, it all happens circumstancial. The usual way is "here I've got some preexisting image surface curtsey of the display system, I can haz OpenGL on that please?" Which brings us to the rather ad-hoc window system APIs for OpenGL. GLX for X11 and WGL for Win32; Apple is a whole chapter of its own…

GLX is two things: First it's a X11 extension, i.e. it uses X11 transport to create a channel for a new set of commands in the X11 server. These commands are the OpenGL functions as specified for versions 1.1 through 2.1 (GLX has not yet been specified for 3.x onward). In that regard GLX places a OpenGL implementation on the X11 server side and GLX opcodes are used for remote procedure call toward the OpenGL context running server side. Second a GLX client side implementation that's housed in the libGL.so OpenGL API access library.

In addition to that GLX implements a few "convenience" functions, like creating OpenGL display-listed rasterop "fonts" from X11 server side fonts; works only for the old-and-busted bitmap fonts that have been around with X11 core since ever. Doesn't antialias and don't look particularly good on low pixel density displays (if you have a high pixel density output device you can get away without antialiasing and high resolution bitmap fonts actually look excellent, case in point: laser printers). WGL followed GLX's lead and did the same for Windows bitmap fonts. That's the only "kind-of" font rendering support that's built directly into the OpenGL ecosystem. But it's pretty much useless for anything outside the 7-bit printable ASCII set. And it totally lacks a layout engine that would properly format the text (left, right, center aligned, justified or whatever). And it completely relies on display lists and OpenGL raster ops which have caveats like "the whole thing won't even go to work if the starting position of the first character happens to lie outside the viewport". So don't bother even trying to use it.

With GLX you can take an existing X11 window and send the X11 server commands that set up this window for use with OpenGL. Also with GLX you can send the X11 server commands that ask it to create a OpenGL context. A OpenGL context is not tied to a particular X11 drawable. You can attach and detach it freely, as long as the drawable you're intending to attach it is compatible with that context (i.e. has been configured for the particular framebuffer format, that context expects for its main framebuffer). Then when you make OpenGL calls, GLX wraps them up into opcodes and sends them over the socket connection to the X11 server where they're executed.

Of course all that de-/serialization incurs some non insignificant execution cost, hence very quickly a special mode called "direct context" was introduced, where the GLX/X11-server combo are used only to setup the OpenGL context and making it current on X11 drawables and for the rest the program is working directly against the OpenGL implementation, thereby avoiding all that serialization and even getting direct access to address space where bulk data objects (textures, buffer objects, etc.) reside. This is why in a X11 based environment you can find instances of a OpenGL implementation for the same direct connection context to actually be present in two processes: The X11 server and the client using it.

As I already mentioned above Xlib, Xcb & co are just client side implementations of the X11 protocol. The server side of X11 provides a basic set of graphics functions. X11 core has some limited bitmap font drawing capabilities, along with functions for drawing points, lines, arcs, (rounded) rectangles, circles and polygons. Drawing and filling happens with a solid pen or hatching pattern; there's no interpolation or gradients going on. Depending on the kind of image you want to draw this is rather limiting. Between the years 2000 to 2010 everybody wanted to draw colourful UIs with lots of gradients and fancy borders and whatnot (personally I never liked those), but in past years semi-/flat UI designs have become a trend and those you could actually draw rather well with X11 core (sans the antialiased text). Eventually people wanted to be able to draw gradients X11 side, so the XRender extension was introduced, which gives you what is essentially the 2D equivalent of OpenGL's GL_TRIANGLES primitive, without shaders, textures and illumination; you get color interpolation, gradients and antialiasing though. As a sidetrack the Xft library (important, that's a library, not a X11 server thing), was created that piggybacks on XRender to load a bunch of client side rasterized font glyphs to the server so that you could with that onto a drawable "antialiased" text. That's about the drawing capabilities of a X11 server. How these drawing capabilities are actually implemented in the X11 server is unspecified and completely depend on the implementation and more importantly on the device dependent X code (DDX) aka the X graphics driver! It could be done purely in software (often the case, currently through a server side component based on the pixman render library), but as well GPU accelerated or even based on the server side part of the used OpenGL implementation (glamor).

Which one should I use if I want more "low-level" control over the rendering and display?

That depends entirely on your target application.

If you're aiming for doing something that's not doing a lot of graphics-graphics (text editor, chat program or so) and you're okay with being tied to X11 then probably X11 through Xlib or Xcb. Most importantly X11 gives you something that pretends to be half-way reasonable text drawing functions that at least work in predictable ways.

OpenGL is the proper choice if you're aiming for doing graphics-graphics work (image manipulation, CAD, desktop publishing, also web browsers), but it means that you're "on your own" for anything that goes beyond points, lines and triangles.

These days it's practically a given that a GPU is present. 10 years ago, not so much, so the UI toolkits and graphics backends that were developed back then (and we're still using those) will do most of their work purely in software, on the CPU and transfer the final image to the display device. This was reasonable then. And if the ultimate goal is reproducible, high quality graphics it still is, because GPUs cut a lot of corners for performance and don't behave identically (OpenGL demands that rendering results of the same chain of operations within the same context are 1:1 matches, but change only one bit and they all bets are off).

The three rendering libraries you can find these days on a modern Linux(!) system (not X11 based in general!) and can be used "stand-alone" are Cairo, Anti-Grain-Geometry (AGG) and pixman. Cairo is used mostly by GDK/GTK+ based programs, pixman in the X11 server (but you can use it in your program, too). AGG is none toolkit's primary graphics kit in particular, but used by a number of programs and libraries (most notably plotting, like matplotlib). One must also not forget the "raster" graphics engine in Qt, but that can be used only within Qt within QPainter (so stand-alone if your program uses Qt, but can't be used without Qt).

When it comes to AGG vs. Cairo the biggest selling point for Cairo is, that it got a pure C binding. Unfortunately Cairo is not a very fast renderer (it made huge progress in the past 10 years). But it's eating the dust of AGG, which is much faster and (ironically) also produces better quality; unfortunately AGG is a C++ library, so to effectively use it you're bound to use C++, which is a downside. Also the principle developer of AGG sadly passed away a few years ago, which stalled development for some time, but it's been picked up by the community again.

Is there a way to get a transparent OpenGL ES background with X11?

Yes it is possible. I modified a example program written by fungus to create a RGBA OpenGL window. If a compositor is enabled the results look like in the video I posted here: http://www.youtube.com/watch?v=iHZfH1Qhonk

/*------------------------------------------------------------------------
The simplest possible Linux OpenGL program? Maybe...
Modification for creating a RGBA window (transparency with compositors)
by Wolfgang 'datenwolf' Draxinger

(c) 2002 by FTB. See me in comp.graphics.api.opengl

(c) 2011 Wolfgang Draxinger. See me in comp.graphics.api.opengl and on StackOverflow

License agreement: This source code is provided "as is". You
can use this source code however you want for your own personal
use. If you give this source code to anybody else then you must
leave this message in it.

--
<\___/>
/ O O \
\_____/ FTB.

--
datenwolf

------------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <GL/glx.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xrender.h>

typedef struct
{
Visual *visual;
VisualID visualid;
int screen;
unsigned int depth;
int klass;
unsigned long red_mask;
unsigned long green_mask;
unsigned long blue_mask;
int colormap_size;
int bits_per_rgb;
} XVisualInfo_CPP;

/*------------------------------------------------------------------------
Something went horribly wrong
------------------------------------------------------------------------*/\
static void fatalError(const char *why)
{
fprintf(stderr, "%s", why);
exit(0x666);
}

/*------------------------------------------------------------------------
Global vars
------------------------------------------------------------------------*/
static int Xscreen;
static Atom del_atom;
static Colormap cmap;
static Display *Xdisplay;
static XVisualInfo_CPP *visual;
static XRenderPictFormat *pictFormat;
static GLXFBConfig *fbconfigs, fbconfig;
static int numfbconfigs;
static GLXContext RenderContext;
static Window Xroot, WindowHandle, GLXWindowHandle;
static int width, height; /* Size of the window */

int const tex_width=512;
int const tex_height=512;
static GLuint texture;

static int VisData[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_DOUBLEBUFFER, True,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_DEPTH_SIZE, 1,
None
};
/*------------------------------------------------------------------------
Create a window
------------------------------------------------------------------------*/
static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
{
return (e->type == MapNotify) && (e->xmap.window == *(Window*)arg);
}

static void createTheWindow()
{
XEvent event;
int x,y, attr_mask;
XSizeHints hints;
XWMHints *StartupState;
XTextProperty textprop;
XSetWindowAttributes attr;
static char *title = "FTB's little OpenGL example";

/* Connect to the X server */
Xdisplay = XOpenDisplay(NULL);
if (!Xdisplay) {
fatalError("Couldn't connect to X server\n");
}
Xscreen = DefaultScreen(Xdisplay);
Xroot = RootWindow(Xdisplay, Xscreen);

fbconfigs = glXChooseFBConfig(Xdisplay, Xscreen, VisData, &numfbconfigs);
for(int i = 0; i<numfbconfigs; i++) {
visual = (XVisualInfo_CPP*) glXGetVisualFromFBConfig(Xdisplay, fbconfigs[i]);
if(!visual)
continue;

pictFormat = XRenderFindVisualFormat(Xdisplay, visual->visual);
if(!pictFormat)
continue;

if(pictFormat->direct.alphaMask > 0) {
fbconfig = fbconfigs[i];
break;
}
}

/* Create a colormap - only needed on some X clients, eg. IRIX */
cmap = XCreateColormap(Xdisplay, Xroot, visual->visual, AllocNone);

/* Prepare the attributes for our window */
attr.colormap = cmap;

attr.border_pixel = 0;
attr.event_mask =
StructureNotifyMask |
EnterWindowMask |
LeaveWindowMask |
ExposureMask |
ButtonPressMask |
ButtonReleaseMask |
OwnerGrabButtonMask |
KeyPressMask |
KeyReleaseMask;

attr.background_pixmap = None;

attr_mask =
CWBackPixmap|
CWColormap|
CWBorderPixel|
CWEventMask; /* What's in the attr data */

/* Create the window */
width = DisplayWidth(Xdisplay, DefaultScreen(Xdisplay))/2;
height = DisplayHeight(Xdisplay, DefaultScreen(Xdisplay))/2;
x=width/2, y=height/2;

/* Create the window */
WindowHandle = XCreateWindow( Xdisplay, /* Screen */
Xroot, /* Parent */
x, y, width, height,/* Position */
1,/* Border */
visual->depth,/* Color depth*/
InputOutput,/* klass */
visual->visual,/* Visual */
attr_mask, &attr);/* Attributes*/

if( !WindowHandle ) {
fatalError("Couldn't create the window\n");
}

/* Configure it... (ok, ok, this next bit isn't "minimal") */
textprop.value = (unsigned char*)title;
textprop.encoding = XA_STRING;
textprop.format = 8;
textprop.nitems = strlen(title);

hints.x = x;
hints.y = y;
hints.width = width;
hints.height = height;
hints.flags = USPosition|USSize;

StartupState = XAllocWMHints();
StartupState->initial_state = NormalState;
StartupState->flags = StateHint;

XSetWMProperties(Xdisplay, WindowHandle,&textprop, &textprop,/* Window title/icon title*/
NULL, 0,/* Argv[], argc for program*/
&hints, /* Start position/size*/
StartupState,/* Iconised/not flag */
NULL);

XFree(StartupState);

/* Open it, wait for it to appear */
XMapWindow(Xdisplay, WindowHandle);
XIfEvent(Xdisplay, &event, WaitForMapNotify, (char*)&WindowHandle);

/* Set the kill atom so we get a message when the user tries to close the window */
if ((del_atom = XInternAtom(Xdisplay, "WM_DELETE_WINDOW", 0)) != None) {
XSetWMProtocols(Xdisplay, WindowHandle, &del_atom, 1);
}
}
/*------------------------------------------------------------------------
Create the OpenGL rendering context
------------------------------------------------------------------------*/
static void createTheRenderContext()
{
/* See if we can do OpenGL on this visual */
int dummy;
if (!glXQueryExtension(Xdisplay, &dummy, &dummy)) {
fatalError("OpenGL not supported by X server\n");
}

/* Create the OpenGL rendering context */
RenderContext = glXCreateNewContext(Xdisplay, fbconfig, GLX_RGBA_TYPE, 0, True);
if (!RenderContext) {
fatalError("Failed to create a GL context\n");
}

GLXWindowHandle = glXCreateWindow(Xdisplay, fbconfig, WindowHandle, NULL);

/* Make it current */
if (!glXMakeContextCurrent(Xdisplay, GLXWindowHandle, GLXWindowHandle, RenderContext)) {
fatalError("glXMakeCurrent failed for window\n");
}

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
/*------------------------------------------------------------------------
Window messages
------------------------------------------------------------------------*/
static int updateTheMessageQueue()
{
XEvent event;
XConfigureEvent *xc;

while (XPending(Xdisplay))
{
XNextEvent(Xdisplay, &event);
switch (event.type)
{
case ClientMessage:
if (event.xclient.data.l[0] == del_atom)
{
return 0;
}
break;

case ConfigureNotify:
xc = &(event.xconfigure);
width = xc->width;
height = xc->height;
break;
}
}
return 1;
}

/*------------------------------------------------------------------------
Redraw the window
------------------------------------------------------------------------*/
float const light_dir[]={1,1,1,0};
float const light_color[]={1,0.95,0.9,1};

static void redrawTheWindow()
{
int size;
static float a=0;
static float b=0;
static float c=0;

glViewport(0,0,width,height);

/* Clear the screen */
// glClearColor(0.750,0.750,1.0,0.5);
glClearColor(0.0,0.0,0.0,0.);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (float)width/(float)height, 1, 10);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);

glLightfv(GL_LIGHT0, GL_POSITION, light_dir);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);

glTranslatef(0,0,-5);

glRotatef(a, 1, 0, 0);
glRotatef(b, 0, 1, 0);
glRotatef(c, 0, 0, 1);


Related Topics



Leave a reply



Submit