Skip to content

Commit

Permalink
Finally added FreeGLUT /GLX version for Linux - build passing Maybe r…
Browse files Browse the repository at this point in the history
…emove axXXX (Xlib)

Buttons not implemented;
Still not 'a program to rule them all';
  • Loading branch information
AdamOnAir committed Nov 23, 2024
1 parent cb18239 commit 81ebe56
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 117 deletions.
14 changes: 6 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ add_library(Airlib SHARED
)

if(UNIX AND NOT APPLE)
target_link_libraries(Airlib PRIVATE X11)
target_link_libraries(Airlib PRIVATE pulse-simple)
find_package(GLUT REQUIRED)
find_package(OpenGL REQUIRED)
target_link_libraries(Airlib PRIVATE X11 OpenGL::GL GLUT::GLUT pulse-simple)
elseif(WIN32)
target_link_libraries(Airlib winmm)
target_link_libraries(Airlib winmm)
target_link_libraries(Airlib opengl32)
target_link_libraries(Airlib
gdi32
Expand All @@ -37,12 +38,9 @@ add_executable(Airlib_test main.c)

# Link the Airlib library to the Airlib_test executable
target_link_libraries(Airlib_test PRIVATE Airlib)

if (UNIX AND NOT APPLE)
target_link_libraries(Airlib_test PRIVATE X11)
target_link_libraries(Airlib_test
OpenGL::GL
GLUT::GLUT
)
target_link_libraries(Airlib_test PRIVATE OpenGL::GL GLUT::GLUT X11)
endif()

#[[
Expand Down
32 changes: 7 additions & 25 deletions include/video.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
/* X11 */
#ifdef __linux__

#include <X11/Xlib.h>

#define KEY_ESCAPE 9
#define KEY_SPACEBAR 65
#define KEY_UP 111
Expand All @@ -12,23 +14,22 @@
#define KEY_LEFT 113

static Display *d;
static Window w;
static XEvent e;
static int s;
static int *s;
static GC gc;

void axCreateWindow(int width, int height);
void axDrawRect(unsigned long color, int x, int y, int width, int height);
void axClearWindow();
int axGetNextEvent(XEvent *event);
void axCloseWindow();
int axGetNextEvent(XEvent *event)
int axGetNextEvent(XEvent *event);

#endif

/* FreeGLUT (cross-platform) */

typedef struct Window {
typedef struct CustomWindow {
void (*create)(int width, int height, const char* title);
void (*pollEvents)(void);
void (*swapBuffers)(void);
Expand All @@ -37,28 +38,9 @@ typedef struct Window {
void (*drawButton)(float x, float y, float width, float height, const char* label);
void (*destroy)(void);
int (*isButtonClicked)(float x, float y, float width, float height);
} Window;
} CustomWindow;

Window* createWindowInstance(void);
CustomWindow* createWindowInstance(void);

#endif

/*
Copyright (C) 2024 Ellouze Adam <[email protected]>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
41 changes: 14 additions & 27 deletions main.c
Original file line number Diff line number Diff line change
@@ -1,41 +1,28 @@
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdio.h>
#include "include/video.h"

static const char* display_text = "yOU ARE A KING !";

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

Window* window = createWindowInstance();
window->create(800, 600, "Best game ever");

glClearColor(0.0f, 1.0f, 1.0f, 0.0f);
glutInit(&argc, argv); // Initialize FreeGLUT

while (!window->shouldClose()) {
window->pollEvents();
glClear(GL_COLOR_BUFFER_BIT);
CustomWindow *win = createWindowInstance();
win->create(800, 600, "Linux GLX Window");

// Draw button background
glColor3f(0.0,0.0,0.0);
window->drawButton(-0.5f, -0.5f, 1.0f, 0.3f, "BUD");
while (!win->shouldClose()) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Text
glColor3f(0.0f, 0.0f, 1.0f);
window->drawText(-0.2f, -0.4f, "Click Me");
win->drawText(-0.5f, 0.0f, "Hello, Linux with GLX!");
win->drawButton(-0.5f, -0.5f, 0.3f, 0.2f, "Click Me");

// Draw header text in white
glColor3f(0.0f, 0.0f, 1.0f);
window->drawText(-0.8f, 0.8f, display_text);

if (window->isButtonClicked(-0.5f, -0.5f, 1.0f, 0.3f)) {
display_text = "Hello GLUT!";
if (win->isButtonClicked(-0.5f, -0.5f, 0.3f, 0.2f)) {
printf("Button was clicked!\n");
}

window->swapBuffers();
win->swapBuffers();
win->pollEvents();
}

window->destroy();
win->destroy();
return 0;
}

4 changes: 4 additions & 0 deletions src/system/Windows/WIN_video.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#ifdef _WIN32

#include "../../../include/video.h"
#include <windows.h>
#include <GL/gl.h>
Expand Down Expand Up @@ -112,3 +114,5 @@ __declspec(dllexport) Window* createWindowInstance(void) {
};
return &window;
}

#endif
151 changes: 94 additions & 57 deletions src/system/gnu_linux/linux_video.c
Original file line number Diff line number Diff line change
@@ -1,85 +1,122 @@
#include "../../../include/video.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* X11 */
#include <GL/glut.h>
#include <GL/glx.h>

#ifdef __linux__
/* FreeGLUT (native) */

#include <X11/Xlib.h>
static Display *display;
static Window xWindow;
static GLXContext glContext;
static int shouldCloseFlag = 0;

static Display *d;
static Window w;
static XEvent e;
static int s;
static GC gc;
static void create(int width, int height, const char* title) {
display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "Cannot open X display\n");
exit(1);
}

void axCreateWindow(int width, int height) {
d = XOpenDisplay(NULL);
if (d == NULL) {
printf("Cannot open display\n");
static int visual_attribs[] = {
GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None
};
int screen = DefaultScreen(display);
XVisualInfo *vi = glXChooseVisual(display, screen, visual_attribs);
if (vi == NULL) {
fprintf(stderr, "No appropriate visual found\n");
exit(1);
}

s = DefaultScreen(d);
w = XCreateSimpleWindow(d, RootWindow(d,s), 0, 0, width, height, 1,
BlackPixel(d,s), WhitePixel(d,s));
Colormap cmap = XCreateColormap(display, RootWindow(display, screen), vi->visual, AllocNone);
XSetWindowAttributes swa;
swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;

// Enable key press and expose events
XSelectInput(d, w, KeyPressMask | ExposureMask);
xWindow = XCreateWindow(display, RootWindow(display, screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
CWColormap | CWEventMask, &swa);
XMapWindow(display, xWindow);
XStoreName(display, xWindow, title);

// Create graphics context
gc = DefaultGC(d, s);
glContext = glXCreateContext(display, vi, NULL, GL_TRUE);
glXMakeCurrent(display, xWindow, glContext);

XMapWindow(d, w);
XFlush(d);
glEnable(GL_DEPTH_TEST);
}

void axDrawRect(unsigned long color, int x, int y, int width, int height) {
XSetForeground(d, gc, color);
XFillRectangle(d, w, gc, x, y, width, height);
XFlush(d);
static void pollEvents(void) {
XEvent xev;
while (XPending(display) > 0) {
XNextEvent(display, &xev);
if (xev.type == ClientMessage || xev.type == KeyPress) {
shouldCloseFlag = 1;
} else if (xev.type == ButtonPress) {
// Add button click logic here
}
}
}

void axClearWindow() {
XClearWindow(d, w);
XFlush(d);
static void swapBuffers(void) {
glXSwapBuffers(display, xWindow);
}

int axGetNextEvent(XEvent *event) {
if (XPending(d)) {
XNextEvent(d, event);
return 1;
}
return 0;
static int shouldClose(void) {
return shouldCloseFlag;
}

void axCloseWindow() {
XCloseDisplay(d);
static void drawText(float x, float y, const char* text) {
glRasterPos2f(x, y);
while (*text) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *text);
text++;
}
}

#endif

/* FreeGLUT (cross-platform) */
static void drawButton(float x, float y, float width, float height, const char* label) {
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x + width, y);
glVertex2f(x + width, y + height);
glVertex2f(x, y + height);
glEnd();
drawText(x + width / 10.0f, y + height / 2.0f, label);
}

static int isButtonClicked(float x, float y, float width, float height) {
XEvent xev;
if (XPending(display) > 0) {
XNextEvent(display, &xev);
if (xev.type == ButtonPress) {
int mouseX = xev.xbutton.x;
int mouseY = xev.xbutton.y;
if (mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height) {
return 1;
}
}
}
return 0;
}

static void destroy(void) {
glXMakeCurrent(display, None, NULL);
glXDestroyContext(display, glContext);
XDestroyWindow(display, xWindow);
XCloseDisplay(display);
}

/*
Copyright (C) 2024 Ellouze Adam <[email protected]>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
CustomWindow* createWindowInstance(void) {
static CustomWindow win = {
.create = create,
.pollEvents = pollEvents,
.swapBuffers = swapBuffers,
.shouldClose = shouldClose,
.drawText = drawText,
.drawButton = drawButton,
.destroy = destroy,
.isButtonClicked = isButtonClicked
};
return &win;
}

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

0 comments on commit 81ebe56

Please sign in to comment.