You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

189 lines
4.2 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #if defined USE_EGL
  14. # include <X11/Xlib.h>
  15. # include <X11/Xatom.h>
  16. # include <X11/Xutil.h>
  17. # include <EGL/egl.h>
  18. #endif
  19. #include "core.h"
  20. #include "lolgl.h"
  21. #include "eglapp.h"
  22. namespace lol
  23. {
  24. /*
  25. * EGL App implementation class
  26. */
  27. class EglAppData
  28. {
  29. friend class EglApp;
  30. private:
  31. #if defined USE_EGL
  32. Display *dpy;
  33. Window win;
  34. EGLDisplay egl_dpy;
  35. EGLContext egl_ctx;
  36. EGLSurface egl_surf;
  37. #endif
  38. };
  39. /*
  40. * Public EglApp class
  41. */
  42. EglApp::EglApp(char const *title, ivec2 res, float fps) :
  43. data(new EglAppData())
  44. {
  45. #if defined USE_EGL
  46. data->dpy = XOpenDisplay(NULL);
  47. if (data->dpy == NULL)
  48. {
  49. Log::Error("cannot connect to X server\n");
  50. exit(EXIT_FAILURE);
  51. }
  52. Window root = DefaultRootWindow(data->dpy);
  53. XSetWindowAttributes swa;
  54. swa.event_mask = ExposureMask | PointerMotionMask | KeyPressMask;
  55. data->win = XCreateWindow(data->dpy, root, 0, 0, res.x, res.y, 0,
  56. CopyFromParent, InputOutput,
  57. CopyFromParent, CWEventMask, &swa);
  58. XSetWindowAttributes xattr;
  59. xattr.override_redirect = False;
  60. XChangeWindowAttributes(data->dpy, data->win, CWOverrideRedirect, &xattr);
  61. XWMHints hints;
  62. hints.flags = InputHint;
  63. hints.input = True;
  64. XSetWMHints(data->dpy, data->win, &hints);
  65. XMapWindow(data->dpy, data->win);
  66. XStoreName(data->dpy, data->win, title);
  67. data->egl_dpy = eglGetDisplay((EGLNativeDisplayType)data->dpy);
  68. if (data->egl_dpy == EGL_NO_DISPLAY)
  69. {
  70. Log::Error("cannot get EGL display\n");
  71. exit(EXIT_FAILURE);
  72. }
  73. if (!eglInitialize(data->egl_dpy, NULL, NULL))
  74. {
  75. Log::Error("cannot initialize EGL\n");
  76. exit(EXIT_FAILURE);
  77. }
  78. EGLint attr[] =
  79. {
  80. EGL_BUFFER_SIZE, 16,
  81. EGL_RENDERABLE_TYPE,
  82. #if defined HAVE_GLES_2X
  83. EGL_OPENGL_ES2_BIT,
  84. #endif
  85. EGL_NONE
  86. };
  87. EGLConfig ecfg;
  88. EGLint num_config;
  89. if (!eglChooseConfig(data->egl_dpy, attr, &ecfg, 1, &num_config))
  90. {
  91. Log::Error("cannot choose EGL config (%i)\n", eglGetError());
  92. exit(EXIT_FAILURE);
  93. }
  94. if (num_config != 1)
  95. {
  96. Log::Error("cannot choose between %i EGL configs\n", num_config);
  97. exit(EXIT_FAILURE);
  98. }
  99. data->egl_surf = eglCreateWindowSurface(data->egl_dpy, ecfg,
  100. data->win, NULL);
  101. if (data->egl_surf == EGL_NO_SURFACE)
  102. {
  103. Log::Error("cannot create EGL surface (%i)\n", eglGetError());
  104. exit(EXIT_FAILURE);
  105. }
  106. EGLint ctxattr[] =
  107. {
  108. #if defined HAVE_GLES_2X
  109. EGL_CONTEXT_CLIENT_VERSION, 2,
  110. #endif
  111. EGL_NONE
  112. };
  113. data->egl_ctx = eglCreateContext(data->egl_dpy, ecfg,
  114. EGL_NO_CONTEXT, ctxattr);
  115. if (data->egl_ctx == EGL_NO_CONTEXT)
  116. {
  117. Log::Error("cannot create EGL context (%i)\n", eglGetError());
  118. exit(EXIT_FAILURE);
  119. }
  120. eglMakeCurrent(data->egl_dpy, data->egl_surf,
  121. data->egl_surf, data->egl_ctx);
  122. XWindowAttributes gwa;
  123. XGetWindowAttributes(data->dpy, data->win, &gwa);
  124. /* Initialise everything */
  125. Ticker::Setup(fps);
  126. Video::Setup(ivec2(gwa.width, gwa.height));
  127. Audio::Setup(2);
  128. #endif
  129. }
  130. void EglApp::Run()
  131. {
  132. while (!Ticker::Finished())
  133. {
  134. /* Tick the game */
  135. Ticker::TickGame();
  136. /* Tick the renderer, show the frame and clamp to desired framerate. */
  137. Ticker::TickDraw();
  138. #if defined USE_EGL
  139. eglSwapBuffers(data->egl_dpy, data->egl_surf);
  140. #endif
  141. Ticker::ClampFps();
  142. }
  143. }
  144. EglApp::~EglApp()
  145. {
  146. #if defined USE_EGL
  147. eglDestroyContext(data->egl_dpy, data->egl_ctx);
  148. eglDestroySurface(data->egl_dpy, data->egl_surf);
  149. eglTerminate(data->egl_dpy);
  150. XDestroyWindow(data->dpy, data->win);
  151. XCloseDisplay(data->dpy);
  152. #endif
  153. delete data;
  154. }
  155. } /* namespace lol */