Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

Can OpenGL be mixed with other game libraries

Programming languages, Coding, Executables, Package Creation, and Scripting.
Post Reply
Message
Author
larienna
Posts: 107
Joined: 2014-09-27 20:54

Can OpenGL be mixed with other game libraries

#1 Post by larienna »

The objective is to draw a 1st person 3D maze on the background and draw additonnal information in a user interface on the top of that 3D maze. Performance is not an issue as the game does not have real time animation.

Theoretically, I could upload all the textures and maze layout to OpenGL then render the scene. At this point, the scene should be in the video buffer. After wards, if I use other game libraries like SDL, Allegro, Raylib, blitting routines should be allows to draw on the top of what is already in the video buffer. As long as I don't clear the screen, I should be able to overlap Game library Rendering over OpenGL rendering.

Now I might be missing something, this is why I am asking. Could this work?

If the game library does not use the GPU to draw it's information, there should not be any conflicts as it only sends pixels directly to the video buffer. On the other hand, if the game library also use the GPU, there could be some conflicts. Again, just theoretical assumptions.

If mixing OpenGL and other GL is possible, then I could make my maze drawing with OpenGL to be compatible with any GL. Else I will need to use a GL that allows 3D polygons, like Raylib, and strictly use the GL.

gusnan
Posts: 47
Joined: 2009-01-15 06:26
Has thanked: 3 times
Been thanked: 1 time

Re: Can OpenGL be mixed with other game libraries

#2 Post by gusnan »

This is definitely possible to make work - I'm using Allegro for such stuff myself, and there it's as easy as first drawing the OpenGL, then restoring your transforms and projection_transforms and render_state, and then you can simply draw using allegros primitives or whatever.

An example (minorly edited version of allegro example ex_opengl - https://github.com/liballeg/allegro5/bl ... x_opengl.c ), I have a al_draw_rectangle close to the bottom of the main loop that is drawn over the openGL fun.

build with

Code: Select all

gcc test.c -o test `pkg-config --cflags --libs gl allegro-5 allegro_primitives-5 allegro_main-5 ` -lm

Code: Select all

#define ALLEGRO_UNSTABLE

#include <stdio.h>
#include <math.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_opengl.h>
#include <allegro5/allegro_primitives.h>

#include <stdio.h>
#include <stdarg.h>

#ifdef ALLEGRO_ANDROID
   #include "allegro5/allegro_android.h"
#endif

void init_platform_specific(void);
void abort_example(char const *format, ...);
void open_log(void);
void open_log_monospace(void);
void close_log(bool wait_for_user);
void log_printf(char const *format, ...);

void init_platform_specific(void)
{
#ifdef ALLEGRO_ANDROID
   al_install_touch_input();
   al_android_set_apk_file_interface();
#endif
}

#ifdef ALLEGRO_POPUP_EXAMPLES

#include "allegro5/allegro_native_dialog.h"

ALLEGRO_TEXTLOG *textlog = NULL;

void abort_example(char const *format, ...)
{
   char str[1024];
   va_list args;
   ALLEGRO_DISPLAY *display;

   va_start(args, format);
   vsnprintf(str, sizeof str, format, args);
   va_end(args);

   if (al_init_native_dialog_addon()) {
      display = al_is_system_installed() ? al_get_current_display() : NULL;
      al_show_native_message_box(display, "Error", "Cannot run example", str, NULL, 0);
   }
   else {
      fprintf(stderr, "%s", str);
   }
   exit(1);
}

void open_log(void)
{
   if (al_init_native_dialog_addon()) {
      textlog = al_open_native_text_log("Log", 0);
   }
}

void open_log_monospace(void)
{
   if (al_init_native_dialog_addon()) {
      textlog = al_open_native_text_log("Log", ALLEGRO_TEXTLOG_MONOSPACE);
   }
}

void close_log(bool wait_for_user)
{
   if (textlog && wait_for_user) {
      ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue();
      al_register_event_source(queue, al_get_native_text_log_event_source(
         textlog));
      al_wait_for_event(queue, NULL);
      al_destroy_event_queue(queue);
   }

   al_close_native_text_log(textlog);
   textlog = NULL;
}

void log_printf(char const *format, ...)
{
   char str[1024];
   va_list args;
   va_start(args, format);
   vsnprintf(str, sizeof str, format, args);
   va_end(args);
   al_append_native_text_log(textlog, "%s", str);
}

#else

void abort_example(char const *format, ...)
{
   va_list args;
   va_start(args, format);
   vfprintf(stderr, format, args);
   va_end(args);
   exit(1);
}

void open_log(void)
{
}

void open_log_monospace(void)
{
}

void close_log(bool wait_for_user)
{
   (void)wait_for_user;
}

void log_printf(char const *format, ...)
{
   va_list args;
   va_start(args, format);
   #ifdef ALLEGRO_ANDROID
   char x[1024];
   vsnprintf(x, sizeof x, format, args);
   ALLEGRO_TRACE_CHANNEL_LEVEL("log", 1)("%s", x);
   #else
   vprintf(format, args);
   #endif
   va_end(args);
}

#endif

/* vim: set sts=3 sw=3 et: */


/* Simple example showing how to use an extension. It draws a yellow triangle
 * on red background onto a texture, then draws a quad with that texture.
 */

GLuint tex, fbo;
bool no_fbo = false;

static void draw_opengl(void)
{
   double secs = al_get_time();
   
   ALLEGRO_TRANSFORM projection = *al_get_current_projection_transform();
   ALLEGRO_TRANSFORM t;

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   /* Let's create a texture. It will only be visible if we cannot draw over
    * it with the framebuffer extension.
    */
   if (!tex) {
      unsigned char *pixels = malloc(256 * 256 * 4);
      int x, y;

      for (y = 0; y < 256; y++) {
         for (x = 0; x < 256; x++) {
            unsigned char r = x, g = y, b = 0, a = 255;
            pixels[y * 256 * 4 + x * 4 + 0] = r;
            pixels[y * 256 * 4 + x * 4 + 1] = g;
            pixels[y * 256 * 4 + x * 4 + 2] = b;
            pixels[y * 256 * 4 + x * 4 + 3] = a;
         }
      }
      glGenTextures(1, &tex);
      glBindTexture(GL_TEXTURE_2D, tex);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA,
         GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      free(pixels);
   }

   /* Let's create a framebuffer object. */
   if (!fbo && !no_fbo) {
      /* Did Allegro discover the OpenGL extension for us? */
      if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object) {
         /* If yes, then it also filled in the function pointer. How nice. */
         glGenFramebuffersEXT(1, &fbo);

         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
         /* Attach the framebuffer object to our texture. */
         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
            GL_TEXTURE_2D, tex, 0);
         if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) !=
            GL_FRAMEBUFFER_COMPLETE_EXT) {
            no_fbo = true;
         }
         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
      }
      else {
         /* We are screwed, the extension is not available. */
         no_fbo = true;
      }
   }

  /* Draw a yellow triangle on red background to the framebuffer object. */
   if (fbo && !no_fbo) {
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

      glPushAttrib(GL_VIEWPORT_BIT | GL_TRANSFORM_BIT);
      glViewport(0, 0, 256, 256);
      glClearColor(1, 0, 0, 1);
      glClear(GL_COLOR_BUFFER_BIT);

      glMatrixMode(GL_PROJECTION);
      glPushMatrix();

      glLoadIdentity();
      glOrtho(0, 256, 256, 0, -1, 1);

      glDisable(GL_TEXTURE_2D);
      glColor3f(1, 1, 0);
      glTranslatef(128, 128 + sin(secs * ALLEGRO_PI * 2 * 2) * 20, 0);
      glBegin(GL_TRIANGLES);
      glVertex2f(0, -100);
      glVertex2f(100, 0);
      glVertex2f(-100, 0);
      glEnd();

      glPopMatrix();
      glPopAttrib();

      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
   }

   /* Draw a quad with our texture. */
   glClearColor(0, 0, 1, 1);
   glClear(GL_COLOR_BUFFER_BIT);

   glLoadIdentity();
   glTranslatef(320, 240, 0);
   glRotatef(secs * 360 / 4, 0, 0, 1);
   glColor3f(1, 1, 1);
   glEnable(GL_TEXTURE_2D);
   glBindTexture(GL_TEXTURE_2D, tex);
   glBegin(GL_QUADS);
   glTexCoord2f(0, 0); glVertex2f(-100, -100);
   glTexCoord2f(1, 0); glVertex2f(+100, -100);
   glTexCoord2f(1, 1); glVertex2f(+100, +100);
   glTexCoord2f(0, 1); glVertex2f(-100, +100);
   glEnd();
   
      /* Restore projection. */
   al_identity_transform(&t);
   al_use_transform(&t);
   al_use_projection_transform(&projection);
   al_set_render_state(ALLEGRO_DEPTH_TEST, 0);
}

int main(int argc, char **argv)
{
   ALLEGRO_DISPLAY *display;
   ALLEGRO_EVENT_QUEUE *queue;
   ALLEGRO_EVENT event;
   int frames = 0;
   double start;

   (void)argc;
   (void)argv;

   if (!al_init()) {
      abort_example("Could not init Allegro.\n");
   }

   open_log();

   al_install_keyboard();
   al_set_new_display_flags(ALLEGRO_OPENGL);
   display = al_create_display(640, 480);
   if (!display) {
      abort_example("Could not create display.\n");
   }

   queue = al_create_event_queue();
   al_register_event_source(queue, al_get_keyboard_event_source());
   al_register_event_source(queue, al_get_display_event_source(display));

   start = al_get_time();
   while (true) {
      /* Check for ESC key or close button event and quit in either case. */
      if (!al_is_event_queue_empty(queue)) {
         while (al_get_next_event(queue, &event)) {
            switch (event.type) {
               case ALLEGRO_EVENT_DISPLAY_CLOSE:
                  goto done;

               case ALLEGRO_EVENT_KEY_DOWN:
                  if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
                     goto done;
                  break;
            }
         }
      }
      draw_opengl();
      
      al_draw_rectangle(20, 20, 300, 200, al_map_rgba_f(0.5, 0, 0, 1), 1);
      
      al_flip_display();
      frames++;
   }

done:

   log_printf("%.1f FPS\n", frames / (al_get_time() - start));
   al_destroy_event_queue(queue);
   al_destroy_display(display);

   close_log(true);

   return 0;
}



Post Reply