|
@@ -16,7 +16,11 @@
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
*/
|
|
|
|
|
|
+#ifdef LA_USE_GLES
|
|
|
+#define NANOVG_GLES3_IMPLEMENTATION
|
|
|
+#else
|
|
|
#define NANOVG_GL3_IMPLEMENTATION
|
|
|
+#endif
|
|
|
#include "la_5.h"
|
|
|
|
|
|
#include <stdio.h>
|
|
@@ -170,7 +174,7 @@ void la_XErrorHandler(Display *display, XErrorEvent *event){
|
|
|
printf("X Error:\n%s\n",buf);
|
|
|
}
|
|
|
|
|
|
-SYSWINDOW la_CreateWindowX11(int x, int y, int w, int h, char *title, int SyncToVBlank, GLXContext* r_glc){
|
|
|
+SYSWINDOW la_CreateWindowX11(int x, int y, int w, int h, char *title, int SyncToVBlank, GLXContext* r_glc, void* egl_surf){
|
|
|
XSetWindowAttributes swa;
|
|
|
XWindowAttributes wa;
|
|
|
swa.event_mask =
|
|
@@ -187,17 +191,24 @@ SYSWINDOW la_CreateWindowX11(int x, int y, int w, int h, char *title, int SyncTo
|
|
|
my_hints.x = x; my_hints.y = y;
|
|
|
XSetNormalHints(MAIN.dpy, win, &my_hints);
|
|
|
}
|
|
|
+ XStoreName(MAIN.dpy, win, title);
|
|
|
|
|
|
+#ifdef LA_USE_GLES
|
|
|
+ static const EGLint ctx_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
|
|
|
+ (*r_glc)=eglCreateContext(MAIN.egl_dpy, MAIN.BestFBC, MAIN.glc, ctx_attribs );
|
|
|
+ if (!(*r_glc)){ printf("\n\tcannot create gl context\n\n"); exit(0); }
|
|
|
+ EGLSurface* surf=egl_surf;
|
|
|
+ (*surf)=eglCreateWindowSurface(MAIN.egl_dpy, MAIN.BestFBC, win, NULL);
|
|
|
+ if (!(*surf)) { printf("Error: eglCreateWindowSurface failed %d\n",eglGetError()); exit(1); }
|
|
|
+ tnsContextMakeCurrent((*r_glc),win,(*surf));
|
|
|
+#else
|
|
|
int attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, MAIN.GLMajor, GLX_CONTEXT_MINOR_VERSION_ARB, MAIN.GLMinor, 0};
|
|
|
if (((*r_glc) = glXCreateContextAttribsF(MAIN.dpy, MAIN.BestFBC, MAIN.glc, GL_TRUE, attribs)) == NULL){
|
|
|
printf("\n\tcannot create gl context\n\n"); exit(0);
|
|
|
}
|
|
|
-
|
|
|
- XStoreName(MAIN.dpy, win, title);
|
|
|
- //XMapWindow(MAIN.dpy, win);
|
|
|
- tnsContextMakeCurrent((*r_glc),win);
|
|
|
-
|
|
|
+ tnsContextMakeCurrent((*r_glc),win,0);
|
|
|
int sync=SyncToVBlank?1:0; glXSwapIntervalEXTF(MAIN.dpy, win, sync);
|
|
|
+#endif
|
|
|
|
|
|
MAIN.im = XOpenIM(MAIN.dpy, NULL, NULL, NULL);
|
|
|
MAIN.ic = XCreateIC(MAIN.im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, NULL);
|
|
@@ -226,8 +237,9 @@ SYSWINDOW la_CreateWindowX11(int x, int y, int w, int h, char *title, int SyncTo
|
|
|
return win;
|
|
|
};
|
|
|
void la_DestroySystemWindowX11(laWindow* w) {
|
|
|
- tnsContextMakeCurrent(0,0);
|
|
|
+ tnsContextMakeCurrent(0,0,0);
|
|
|
tnsDeleteContext(w->glc);
|
|
|
+ eglDestroySurface(MAIN.egl_dpy, w->egl_surf);
|
|
|
XDestroyWindow(MAIN.dpy, w->win);
|
|
|
};
|
|
|
#endif //linux
|
|
@@ -358,7 +370,7 @@ void la_SetupGLEnviornment(laWindow* window, HWND hwnd, int Sync) {
|
|
|
|
|
|
if (!hglrc) SEND_PANIC_ERROR("Can't Create Opengl Context!\n", );
|
|
|
|
|
|
- tnsContextMakeCurrent(hglrc, hdc);
|
|
|
+ tnsContextMakeCurrent(hglrc, hdc,0);
|
|
|
|
|
|
//int sync = Sync ? 1 : 0; wglSwapIntervalEXT(sync);
|
|
|
wglSwapIntervalEXT(-1);
|
|
@@ -375,7 +387,7 @@ SYSWINDOW la_CreateWindowWin32(int x, int y, int w, int h, char* title, int Sync
|
|
|
return hwnd;
|
|
|
};
|
|
|
void la_DestroySystemWindowWin32(laWindow* w) {
|
|
|
- tnsContextMakeCurrent(0,0);
|
|
|
+ tnsContextMakeCurrent(0,0,0);
|
|
|
tnsDeleteContext(w->glc);
|
|
|
ReleaseDC(w->win, w->hdc);
|
|
|
DestroyWindow(w->win);
|
|
@@ -457,12 +469,7 @@ void la_NotifyGLDebugChanges(){
|
|
|
void la_SetupWindowGLStates(laWindow* w){
|
|
|
tnsBindVertexArray(w->vao); tnsUnbindTexture(); tnsUseImmShader(); tnsEnableShaderv(T->immShader);
|
|
|
if(w->GLDebugNeedsUpdate){
|
|
|
-#ifdef __linux__
|
|
|
- tnsContextMakeCurrent(w->glc,w->win);
|
|
|
-#endif
|
|
|
-#ifdef _WIN32
|
|
|
- tnsContextMakeCurrent(w->glc,w->hdc);
|
|
|
-#endif
|
|
|
+ tnsContextMakeWindowCurrent(w);
|
|
|
la_SetCurrentGLContextDebug(); w->GLDebugNeedsUpdate=0;
|
|
|
}
|
|
|
}
|
|
@@ -470,7 +477,11 @@ void la_SetupWindowGLStates(laWindow* w){
|
|
|
int la_CreateSystemWindow(laWindow *window, int SyncToVBlank){
|
|
|
SYSGLCONTEXT glc;
|
|
|
#ifdef __linux__
|
|
|
- SYSWINDOW hwnd = la_CreateWindowX11(window->X, window->Y, window->W, window->H, window->Title->Ptr, SyncToVBlank, &glc);
|
|
|
+ void* egl_surf=0;
|
|
|
+#ifdef LA_USE_GLES
|
|
|
+ egl_surf=&window->egl_surf;
|
|
|
+#endif
|
|
|
+ SYSWINDOW hwnd = la_CreateWindowX11(window->X, window->Y, window->W, window->H, window->Title->Ptr, SyncToVBlank, &glc, egl_surf);
|
|
|
#endif
|
|
|
#ifdef _WIN32
|
|
|
SYSWINDOW hwnd = la_CreateWindowWin32(window->X, window->Y, window->W, window->H, window->Title->Ptr, SyncToVBlank, &glc);
|
|
@@ -495,7 +506,11 @@ int la_CreateSystemWindow(laWindow *window, int SyncToVBlank){
|
|
|
glGenVertexArrays(1,&window->vao); tnsBindVertexArray(window->vao);
|
|
|
la_SetupWindowGLStates(window);
|
|
|
|
|
|
+#ifdef LA_USE_GLES
|
|
|
+ window->nvg=nvgCreateGLES3(NVG_STENCIL_STROKES|NVG_DEBUG|NVG_ANTIALIAS);
|
|
|
+#else
|
|
|
window->nvg=nvgCreateGL3(NVG_STENCIL_STROKES|NVG_DEBUG|NVG_ANTIALIAS);
|
|
|
+#endif
|
|
|
|
|
|
window->OutputShowStripes=1; window->Redraw=1;
|
|
|
window->GLDebugNeedsUpdate=1;
|
|
@@ -505,7 +520,11 @@ int la_CreateSystemWindow(laWindow *window, int SyncToVBlank){
|
|
|
};
|
|
|
|
|
|
int la_DestroySystemWindow(laWindow* wnd){
|
|
|
+#ifdef LA_USE_GLES
|
|
|
+ nvgDeleteGLES3(wnd->nvg);
|
|
|
+#else
|
|
|
nvgDeleteGL3(wnd->nvg);
|
|
|
+#endif
|
|
|
#ifdef __linux__
|
|
|
la_DestroySystemWindowX11(wnd);
|
|
|
#endif
|
|
@@ -787,7 +806,7 @@ void laSetFontFolderPath(char* absolute){
|
|
|
}
|
|
|
|
|
|
void laSetDefaultInitArguments(laInitArguments* ia){
|
|
|
- ia->GLMajor=3; ia->GLMinor=3; ia->BufferSamples=0;
|
|
|
+ ia->GLMajor=3; ia->GLMinor=3; ia->BufferSamples=0; ia->GLDebug=1;
|
|
|
ia->UseColorManagement=0;
|
|
|
ia->HasWorldObjects=0;
|
|
|
ia->HasAction=0;
|
|
@@ -860,6 +879,60 @@ int laGetReadyWith(laInitArguments* ia){
|
|
|
MAIN.GLMajor=MAIN.InitArgs.GLMajor; MAIN.GLMinor=MAIN.InitArgs.GLMinor; MAIN.BufferSamples=MAIN.InitArgs.BufferSamples;
|
|
|
logPrint("Chosen OpenGL version %d.%d\n",MAIN.GLMajor,MAIN.GLMinor);
|
|
|
|
|
|
+#ifdef LA_USE_GLES
|
|
|
+
|
|
|
+ MAIN.egl_dpy=eglGetDisplay(MAIN.dpy);
|
|
|
+ if(!MAIN.egl_dpy){ printf("Error: eglGetDisplay() failed\n"); exit(1); }
|
|
|
+ EGLint egl_major, egl_minor;
|
|
|
+ if (!eglInitialize(MAIN.egl_dpy, &egl_major, &egl_minor)) {
|
|
|
+ printf("Error: eglInitialize() failed\n"); return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ int scrnum;
|
|
|
+ XSetWindowAttributes attr;
|
|
|
+ XVisualInfo *visInfo, visTemplate;
|
|
|
+ int num_visuals;
|
|
|
+ EGLContext ctx;
|
|
|
+ EGLint num_configs;
|
|
|
+ EGLint vid;
|
|
|
+ static const EGLint attribs[] = {
|
|
|
+ EGL_RED_SIZE, 8,
|
|
|
+ EGL_GREEN_SIZE, 8,
|
|
|
+ EGL_BLUE_SIZE, 8,
|
|
|
+ EGL_DEPTH_SIZE, 1,
|
|
|
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
|
|
+ EGL_NONE
|
|
|
+ };
|
|
|
+ if (!eglChooseConfig(MAIN.egl_dpy, attribs, &MAIN.BestFBC, 1, &num_configs)) {
|
|
|
+ printf("Error: couldn't get an EGL visual config\n"); exit(1);
|
|
|
+ }
|
|
|
+ if (!eglGetConfigAttrib(MAIN.egl_dpy, MAIN.BestFBC, EGL_NATIVE_VISUAL_ID, &vid)) {
|
|
|
+ printf("Error: eglGetConfigAttrib() failed\n"); exit(1);
|
|
|
+ }
|
|
|
+ visTemplate.visualid = vid;
|
|
|
+ visInfo = XGetVisualInfo(MAIN.dpy, VisualIDMask, &visTemplate, &num_visuals);
|
|
|
+ if (!visInfo) {
|
|
|
+ printf("Error: couldn't get X visual\n"); exit(1);
|
|
|
+ }
|
|
|
+ MAIN.xvi=visInfo;
|
|
|
+
|
|
|
+ root = DefaultRootWindow(MAIN.dpy);
|
|
|
+ if ((MAIN.cmap = XCreateColormap(MAIN.dpy, root, MAIN.xvi->visual, AllocNone)) == 0){
|
|
|
+ printf("\n\tcannot create colormap\n\n"); exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ eglBindAPI(EGL_OPENGL_ES_API);
|
|
|
+ static const EGLint ctx_attribs[] = {
|
|
|
+ EGL_CONTEXT_CLIENT_VERSION, 2,
|
|
|
+ EGL_NONE
|
|
|
+ };
|
|
|
+ MAIN.glc = eglCreateContext(MAIN.egl_dpy, MAIN.BestFBC, EGL_NO_CONTEXT, ctx_attribs);
|
|
|
+ if (!MAIN.glc) {
|
|
|
+ printf("Error: eglCreateContext failed\n"); exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
+#else
|
|
|
+
|
|
|
int visual_attribs[] = {
|
|
|
GLX_X_RENDERABLE , True,
|
|
|
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
|
|
@@ -901,7 +974,7 @@ int laGetReadyWith(laInitArguments* ia){
|
|
|
|
|
|
swa.colormap = MAIN.cmap;
|
|
|
root = DefaultRootWindow(MAIN.dpy);
|
|
|
- win = XCreateWindow(MAIN.dpy, root, 0, 0, 100, 100, 0, MAIN.xvi->depth, InputOutput, MAIN.xvi->visual, CWColormap | CWEventMask, &swa);
|
|
|
+ win = XCreateWindow(MAIN.dpy, root, 0, 0, 100, 100, 0, MAIN.xvi->depth, InputOutput, MAIN.xvi->visual, CWBackPixel | CWBorderPixel|CWColormap | CWEventMask, &swa);
|
|
|
MAIN.win=win;
|
|
|
int attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, MAIN.GLMajor, GLX_CONTEXT_MINOR_VERSION_ARB, MAIN.GLMinor, 0};
|
|
|
glXCreateContextAttribsF = (glXCreateContextAttribsARBProc) glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
|
|
@@ -910,7 +983,7 @@ int laGetReadyWith(laInitArguments* ia){
|
|
|
}
|
|
|
glXSwapIntervalEXTF = (glXSwapIntervalEXTProc) glXGetProcAddressARB( (const GLubyte *) "glXSwapIntervalEXT" );
|
|
|
|
|
|
- tnsContextMakeCurrent(MAIN.glc,win);
|
|
|
+ tnsContextMakeCurrent(MAIN.glc,win,0);
|
|
|
|
|
|
int major,minor; glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor);
|
|
|
logPrint(" OpenGL Version: %d.%d\n",major,minor);
|
|
@@ -921,6 +994,8 @@ int laGetReadyWith(laInitArguments* ia){
|
|
|
printf("%d\n",err); printf("%s\n",glewGetErrorString(err));
|
|
|
};
|
|
|
|
|
|
+#endif /* gles or glx */
|
|
|
+
|
|
|
glGenVertexArrays(1,&MAIN.TempVAO); tnsBindVertexArray(MAIN.TempVAO);
|
|
|
|
|
|
la_SetCurrentGLContextDebug();
|
|
@@ -980,7 +1055,7 @@ int laGetReadyWith(laInitArguments* ia){
|
|
|
|
|
|
SetPixelFormat(hdc, 1, &cpfd);
|
|
|
hglrc = wglCreateContext(hdc);
|
|
|
- tnsContextMakeCurrent(hglrc, hdc);
|
|
|
+ tnsContextMakeCurrent(hglrc, hdc,0);
|
|
|
|
|
|
//MAIN.hdc = hdc;
|
|
|
// MAIN.tWND = hwnd;
|
|
@@ -1173,11 +1248,14 @@ void laShutoff(int SavePrefereces){
|
|
|
tnsBindVertexArray(0); glDeleteVertexArrays(1,&MAIN.TempVAO);
|
|
|
|
|
|
#ifdef __linux__
|
|
|
- tnsContextMakeCurrent(0,0);
|
|
|
+ tnsContextMakeCurrent(0,0,0);
|
|
|
tnsDeleteContext(MAIN.glc);
|
|
|
+ #ifdef LA_USE_GLES
|
|
|
+ eglTerminate(MAIN.egl_dpy);
|
|
|
+ #endif
|
|
|
#endif
|
|
|
#ifdef _WIN32
|
|
|
- tnsContextMakeCurrent(0,0);
|
|
|
+ tnsContextMakeCurrent(0,0,0);
|
|
|
tnsDeleteContext(MAIN.glc);
|
|
|
UnloadWintab();
|
|
|
#endif
|
|
@@ -2531,7 +2609,7 @@ void la_WindowDefDraw(laWindow *w, laBoxedTheme *bt){
|
|
|
int laStartWindow(laWindow *w){
|
|
|
#ifdef __linux__
|
|
|
XMapWindow(MAIN.dpy,w->win);
|
|
|
- tnsContextMakeCurrent(w->glc,w->win);
|
|
|
+ tnsContextMakeWindowCurrent(w);
|
|
|
#endif
|
|
|
#ifdef _WIN32
|
|
|
ShowWindow(w->win, SW_SHOWNORMAL);
|
|
@@ -7452,12 +7530,7 @@ void laMainLoop(){
|
|
|
laRecordTime(&FrameStartTime);
|
|
|
|
|
|
if(MAIN.GLDebugNeedsUpdate){
|
|
|
-#ifdef __linux__
|
|
|
- tnsContextMakeCurrent(MAIN.glc,MAIN.win);
|
|
|
-#endif
|
|
|
-#ifdef _WIN32
|
|
|
- tnsContextMakeCurrent(MAIN.glc,MAIN.hdc);
|
|
|
-#endif
|
|
|
+ tnsContextMakeWindowCurrent(w);
|
|
|
la_SetCurrentGLContextDebug(); MAIN.GLDebugNeedsUpdate=0;
|
|
|
}
|
|
|
|
|
@@ -7484,7 +7557,11 @@ void laMainLoop(){
|
|
|
for(w=MAIN.Windows.pFirst;w;w=w->Item.pNext){
|
|
|
if(!w->RedrawTouched) continue; w->RedrawTouched=0;
|
|
|
#ifdef __linux__
|
|
|
+ #ifdef LA_USE_GLES
|
|
|
+ eglSwapBuffers(MAIN.egl_dpy, w->egl_surf);
|
|
|
+ #else
|
|
|
glXSwapBuffers(MAIN.dpy, w->win); //XSync(MAIN.dpy,0);
|
|
|
+ #endif
|
|
|
#endif
|
|
|
#ifdef _WIN32
|
|
|
SwapBuffers(w->hdc);
|