From d823930b20c37f92073791e18f9e6a744dc34d51 Mon Sep 17 00:00:00 2001 From: Egor Date: Sat, 10 Feb 2018 11:56:36 -0800 Subject: Fixed linux build --- Common/NativeApp/src/Linux/LinuxMain.cpp | 218 +++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 Common/NativeApp/src/Linux/LinuxMain.cpp (limited to 'Common/NativeApp/src/Linux') diff --git a/Common/NativeApp/src/Linux/LinuxMain.cpp b/Common/NativeApp/src/Linux/LinuxMain.cpp new file mode 100644 index 0000000..648696c --- /dev/null +++ b/Common/NativeApp/src/Linux/LinuxMain.cpp @@ -0,0 +1,218 @@ +/* Copyright 2015-2018 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include +#include + +#include "PlatformDefinitions.h" +#include "NativeAppBase.h" +#include "StringTools.h" +#include "Timer.h" +#include "Errors.h" + + +#ifndef GLX_CONTEXT_MAJOR_VERSION_ARB +# define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#endif + +#ifndef GLX_CONTEXT_MINOR_VERSION_ARB +# define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#endif + +#ifndef GLX_CONTEXT_FLAGS_ARB +# define GLX_CONTEXT_FLAGS_ARB 0x2094 +#endif + +#ifndef GLX_CONTEXT_DEBUG_BIT_ARB +# define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 +#endif + +typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, int, const int*); + + + using namespace Diligent; + +int main (int argc, char ** argv) +{ + std::unique_ptr TheApp(CreateApplication()); + Display *display = XOpenDisplay(0); + + static int visual_attribs[] = + { + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_DOUBLEBUFFER, true, + + // The largest available total RGBA color buffer size (sum of GLX_RED_SIZE, + // GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE) of at least the minimum + // size specified for each color component is preferred. + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, + + // The largest available depth buffer of at least GLX_DEPTH_SIZE size is preferred + GLX_DEPTH_SIZE, 24, + + //GLX_SAMPLE_BUFFERS, 1, + GLX_SAMPLES, 1, + None + }; + + int fbcount = 0; + GLXFBConfig *fbc = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount); + if (!fbc) + { + LOG_ERROR_MESSAGE("Failed to retrieve a framebuffer config"); + return -1; + } + + XVisualInfo *vi = glXGetVisualFromFBConfig(display, fbc[0]); + + XSetWindowAttributes swa; + swa.colormap = XCreateColormap(display, RootWindow(display, vi->screen), vi->visual, AllocNone); + swa.border_pixel = 0; + swa.event_mask = + StructureNotifyMask | + ExposureMask | + KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask; + + Window win = XCreateWindow(display, RootWindow(display, vi->screen), 0, 0, 1024, 768, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa); + if (!win) + { + LOG_ERROR_MESSAGE("Failed to create window."); + return -1; + } + + XMapWindow(display, win); + + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = nullptr; + { + // Create an oldstyle context first, to get the correct function pointer for glXCreateContextAttribsARB + GLXContext ctx_old = glXCreateContext(display, vi, 0, GL_TRUE); + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); + glXMakeCurrent(display, None, NULL); + glXDestroyContext(display, ctx_old); + } + + if (glXCreateContextAttribsARB == nullptr) + { + LOG_ERROR("glXCreateContextAttribsARB entry point not found. Aborting."); + return -1; + } + + int Flags = GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; +#ifdef _DEBUG + Flags |= GLX_CONTEXT_DEBUG_BIT_ARB; +#endif + + int major_version = 4; + int minor_version = 3; + static int context_attribs[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, major_version, + GLX_CONTEXT_MINOR_VERSION_ARB, minor_version, + GLX_CONTEXT_FLAGS_ARB, Flags, + None + }; + + constexpr int True = 1; + GLXContext ctx = glXCreateContextAttribsARB(display, fbc[0], NULL, True, context_attribs); + if (!ctx) + { + LOG_ERROR("Failed to create GL context."); + return -1; + } + XFree(fbc); + + + glXMakeCurrent(display, win, ctx); + TheApp->OnGLContextCreated(display, win); + std::string Title = TheApp->GetAppTitle(); + + Timer timer; + auto PrevTime = timer.GetElapsedTime(); + double filteredFrameTime = 0.0; + + while (true) + { + bool EscPressed = false; + XEvent xev; + // Handle all events in the queue + while(XCheckMaskEvent(display, 0xFFFFFFFF, &xev)) + { + TheApp->HandleXEvent(&xev); + switch(xev.type) + { + case KeyPress: + { + KeySym keysym; + char buffer[80]; + int num_char = XLookupString((XKeyEvent *)&xev, buffer, _countof(buffer), &keysym, 0); + EscPressed = (keysym==XK_Escape); + } + + case ConfigureNotify: + { + XConfigureEvent &xce = reinterpret_cast(xev); + if(xce.width != 0 && xce.height != 0) + TheApp->WindowResize(xce.width, xce.height); + break; + } + } + } + + if(EscPressed) + break; + + // Render the scene + auto CurrTime = timer.GetElapsedTime(); + auto ElapsedTime = CurrTime - PrevTime; + PrevTime = CurrTime; + + TheApp->Update(CurrTime, ElapsedTime); + + TheApp->Render(); + + TheApp->Present(); + + double filterScale = 0.2; + filteredFrameTime = filteredFrameTime * (1.0 - filterScale) + filterScale * ElapsedTime; + std::stringstream fpsCounterSS; + fpsCounterSS << " - " << std::fixed << std::setprecision(1) << filteredFrameTime * 1000; + fpsCounterSS << " ms (" << 1.0 / filteredFrameTime << " fps)"; + XStoreName(display, win, (Title + fpsCounterSS.str()).c_str()); + } + + TheApp.reset(); + + ctx = glXGetCurrentContext(); + glXMakeCurrent(display, None, NULL); + glXDestroyContext(display, ctx); + XDestroyWindow(display, win); + XCloseDisplay(display); +} -- cgit v1.2.3