summaryrefslogtreecommitdiff
path: root/render.c
blob: 0d93a347e5d352876ffcdc54d5ac62b36b518756 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

#include <dlfcn.h>
#include "xenon.h"
#include "render.h"
#include "draw.h"
#include <GL/glx.h>


typedef struct xenon_libX11
{
	void* handle;
	int (*XFlush)(Display*);
	Display* (*XOpenDisplay)(const char*);
	Colormap (*XCreateColormap)(Display*, Window, Visual*, int);
	Window (*XCreateWindow)(Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*);
	int (*XMapRaised)(Display*, Window);
}
xenon_libX11;

static xenon_libX11 libX11;

typedef struct xenon_libGL
{
	void* handle;
	XVisualInfo* (*glXChooseVisual) (Display*, int, int*);
	GLXContext (*glXCreateContext) (Display*, XVisualInfo*, GLXContext, Bool);
	Bool (*glXMakeCurrent) (Display*, GLXDrawable, GLXContext );
	void (*glDrawPixels) (GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
	void (*glRasterPos2i) (GLint, GLint);
	void (*glViewport) (GLint, GLint, GLsizei, GLsizei);
	void (*glMatrixMode) (GLenum);
	void (*glLoadIdentity) (void);
	void (*glOrtho) (GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble);
}
xenon_libGL;

static xenon_libGL libGL;
int inhibit_rendering = 1;

static void render_init_libs()
{
	libX11.handle = dlopen("/usr/lib64/libX11.so.6", RTLD_LAZY);
	if (!libX11.handle)
		libX11.handle = dlopen("/usr/lib/libX11.so.6", RTLD_LAZY);
	if (!libX11.handle)
		printf("can't open libX11\n");
	libX11.XFlush = dlsym(libX11.handle, "XFlush");
	libX11.XOpenDisplay = dlsym(libX11.handle, "XOpenDisplay");
	libX11.XCreateColormap = dlsym(libX11.handle, "XCreateColormap");
	libX11.XCreateWindow = dlsym(libX11.handle, "XCreateWindow");
	libX11.XMapRaised = dlsym(libX11.handle, "XMapRaised");

	libGL.handle = dlopen("/usr/lib64/libGL.so", RTLD_LAZY);
	if (!libGL.handle)
		libGL.handle = dlopen("/usr/lib/libGL.so", RTLD_LAZY);
	if (!libGL.handle)
		printf("can't open libGL\n");
	libGL.glXChooseVisual = dlsym(libGL.handle, "glXChooseVisual");
	libGL.glXCreateContext = dlsym(libGL.handle, "glXCreateContext");
	libGL.glXMakeCurrent = dlsym(libGL.handle, "glXMakeCurrent");
	libGL.glDrawPixels = dlsym(libGL.handle, "glDrawPixels");
	libGL.glRasterPos2i = dlsym(libGL.handle, "glRasterPos2i");
	libGL.glViewport = dlsym(libGL.handle, "glViewport");
	libGL.glMatrixMode = dlsym(libGL.handle, "glMatrixMode");
	libGL.glLoadIdentity = dlsym(libGL.handle, "glLoadIdentity");
	libGL.glOrtho = dlsym(libGL.handle, "glOrtho");
}

void render_init(int w, int h)
{
	render_init_libs();

	Display* dpy = libX11.XOpenDisplay(0);

	int screen = DefaultScreen(dpy);
	GLint glxattr[] = {GLX_RGBA, None};
	XVisualInfo* vi = libGL.glXChooseVisual(dpy, screen, glxattr);

	GLXContext ctx = libGL.glXCreateContext(dpy, vi, 0, GL_TRUE);

	XSetWindowAttributes attr;
	attr.colormap = libX11.XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
	attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
	Window win = libX11.XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, w, h, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &attr);

	libX11.XMapRaised(dpy, win);

	libGL.glXMakeCurrent(dpy, win, ctx);

	libGL.glViewport(0, 0, w, h);
	libGL.glMatrixMode( GL_PROJECTION );
	libGL.glLoadIdentity();
	libGL.glOrtho(0.0, (GLfloat)w, 0.0, (GLfloat)h, 0.0, 2.0);
	libGL.glMatrixMode( GL_MODELVIEW );
	libGL.glLoadIdentity();

	screen_rect.x = 0;
	screen_rect.y = 0;
	screen_rect.w = w;
	screen_rect.h = h;

	pixels = (unsigned char*) calloc (1, w * h * 4);

	render_update(screen_rect);
}

void render_update(xenon_rect r)
{
	inhibit_rendering = 1;
	for(int j = r.y ; j < r.y + r.h ; j++)
	{
		libGL.glRasterPos2i(r.x, r.h - j - 1);
		libGL.glDrawPixels(r.w, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels + (r.x + j * screen_rect.w) * 4 );
	}
	inhibit_rendering = 0;
}