From ea9a81e44f024a2eae6e11a4d242e82145e45f08 Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 16 Nov 2014 23:17:44 +0000 Subject: [PATCH] Implement DisplayRendererPreview in renderdoccmd for linux --- renderdoccmd/Makefile | 2 +- renderdoccmd/renderdoccmd.cpp | 43 +++++++++++++++- renderdoccmd/renderdoccmd_linux.cpp | 76 +++++++++++++++++++++++++++-- renderdoccmd/renderdoccmd_win32.cpp | 63 +++--------------------- 4 files changed, 123 insertions(+), 61 deletions(-) diff --git a/renderdoccmd/Makefile b/renderdoccmd/Makefile index 5472383d3..fdf974e7a 100644 --- a/renderdoccmd/Makefile +++ b/renderdoccmd/Makefile @@ -7,7 +7,7 @@ MACROS=-DLINUX \ -DGIT_COMMIT_HASH="\"$(COMMIT)\"" CFLAGS=-c -Wall -Werror -fPIC $(MACROS) -I../renderdoc/api/ CPPFLAGS=-std=c++11 -g -Wno-unused -Wno-unknown-pragmas -Wno-reorder -LDFLAGS=-L../renderdoc/ -lrenderdoc -lGL +LDFLAGS=-L../renderdoc/ -lrenderdoc -lGL -lX11 OBJDIR=.obj OBJECTS=renderdoccmd.o renderdoccmd_linux.o diff --git a/renderdoccmd/renderdoccmd.cpp b/renderdoccmd/renderdoccmd.cpp index 64e3a1448..3e078c625 100644 --- a/renderdoccmd/renderdoccmd.cpp +++ b/renderdoccmd/renderdoccmd.cpp @@ -67,10 +67,49 @@ bool argequal(const wchar_t *a, const wchar_t *b) return *a == 0 && *b == 0; } -// defined in *_specific.cpp -void DisplayRendererPreview(ReplayRenderer *renderer); +// defined in platform .cpps +void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg); wstring GetUsername(); +void DisplayRendererPreview(ReplayRenderer *renderer) +{ + if(renderer == NULL) return; + + rdctype::array texs; + ReplayRenderer_GetTextures(renderer, &texs); + + TextureDisplay d; + + for(int32_t i=0; i < texs.count; i++) + { + if(texs[i].creationFlags & eTextureCreate_SwapBuffer) + { + d.texid = texs[i].ID; + d.mip = 0; + d.sampleIdx = ~0U; + d.overlay = eTexOverlay_None; + d.CustomShader = ResourceId(); + d.HDRMul = -1.0f; + d.linearDisplayAsGamma = true; + d.FlipY = false; + d.rangemin = 0.0f; + d.rangemax = 1.0f; + d.scale = 1.0f; + d.offx = 0.0f; + d.offy = 0.0f; + d.sliceFace = 0; + d.rawoutput = false; + d.lightBackgroundColour = d.darkBackgroundColour = + FloatVector(0.0f, 0.0f, 0.0f, 0.0f); + d.Red = d.Green = d.Blue = true; + d.Alpha = false; + break; + } + } + + DisplayRendererPreview(renderer, d); +} + int renderdoccmd(int argc, wchar_t **argv) { CaptureOptions opts; diff --git a/renderdoccmd/renderdoccmd_linux.cpp b/renderdoccmd/renderdoccmd_linux.cpp index 300a9d6d2..8e412d0b4 100644 --- a/renderdoccmd/renderdoccmd_linux.cpp +++ b/renderdoccmd/renderdoccmd_linux.cpp @@ -28,6 +28,11 @@ #include #include +#include +#include +#include +#include + #include #include @@ -42,11 +47,76 @@ wstring GetUsername() return wstring(buf, buf+strlen(buf)); } -void DisplayRendererPreview(ReplayRenderer *renderer) +void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg) { - if(renderer == NULL) return; + Display *dpy = XOpenDisplay(NULL); - // TODO! + if(dpy == NULL) return; + + static int visAttribs[] = { + GLX_X_RENDERABLE, True, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, + GLX_DOUBLEBUFFER, True, + 0 + }; + int numCfgs = 0; + GLXFBConfig *fbcfg = glXChooseFBConfig(dpy, DefaultScreen(dpy), visAttribs, &numCfgs); + + if(fbcfg == NULL) + { + XCloseDisplay(dpy); + return; + } + + XVisualInfo *vInfo = glXGetVisualFromFBConfig(dpy, fbcfg[0]); + + XSetWindowAttributes swa = {0}; + swa.event_mask = StructureNotifyMask; + swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vInfo->screen), vInfo->visual, AllocNone); + + Window win = XCreateWindow(dpy, RootWindow(dpy, vInfo->screen), 200, 200, 1280, 720, + 0, vInfo->depth, InputOutput, vInfo->visual, + CWBorderPixel | CWColormap | CWEventMask, &swa); + + XStoreName(dpy, win, "renderdoccmd"); + XMapWindow(dpy, win); + + GLXWindow glwnd = glXCreateWindow(dpy, fbcfg[0], win, NULL); + + void *displayAndDrawable[] = { (void *)dpy, (void *)glwnd }; + + ReplayOutput *out = ReplayRenderer_CreateOutput(renderer, displayAndDrawable); + + OutputConfig c = { eOutputType_TexDisplay }; + + ReplayOutput_SetOutputConfig(out, c); + ReplayOutput_SetTextureDisplay(out, displayCfg); + + bool done = false; + while(!done) + { + while(XPending(dpy) > 0) + { + XEvent event = {0}; + XNextEvent(dpy, &event); + switch(event.type) + { + case ButtonPress: done = true; + default: break; + } + } + + ReplayRenderer_SetFrameEvent(renderer, 0, 10000000+rand()%1000); + ReplayOutput_Display(out); + + usleep(40000); + } } // symbol defined in libGL but not librenderdoc. diff --git a/renderdoccmd/renderdoccmd_win32.cpp b/renderdoccmd/renderdoccmd_win32.cpp index 746c6690e..fe49371cd 100644 --- a/renderdoccmd/renderdoccmd_win32.cpp +++ b/renderdoccmd/renderdoccmd_win32.cpp @@ -207,66 +207,22 @@ wstring GetUsername() return username; } -void DisplayRendererPreview(ReplayRenderer *renderer) +void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg) { - if(renderer == NULL) return; + HWND wnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdoccmd", L"renderdoccmd", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720, NULL, NULL, hInstance, NULL); - HWND wnd = 0; - - wnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdoccmd", L"renderdoccmd", WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720, - NULL, NULL, hInstance, NULL); - - if(wnd == NULL) - { - return; - } + if(wnd == NULL) return; ShowWindow(wnd, SW_SHOW); UpdateWindow(wnd); - rdctype::array texs; - ReplayRenderer_GetTextures(renderer, &texs); - ReplayOutput *out = ReplayRenderer_CreateOutput(renderer, wnd); - ReplayRenderer_SetFrameEvent(renderer, 0, 10000000); - - OutputConfig c; - c.m_Type = eOutputType_TexDisplay; + OutputConfig c = { eOutputType_TexDisplay }; ReplayOutput_SetOutputConfig(out, c); - - for(int32_t i=0; i < texs.count; i++) - { - if(texs[i].creationFlags & eTextureCreate_SwapBuffer) - { - TextureDisplay d; - d.texid = texs[i].ID; - d.mip = 0; - d.sampleIdx = ~0U; - d.overlay = eTexOverlay_None; - d.CustomShader = ResourceId(); - d.HDRMul = -1.0f; - d.linearDisplayAsGamma = true; - d.FlipY = false; - d.rangemin = 0.0f; - d.rangemax = 1.0f; - d.scale = 1.0f; - d.offx = 0.0f; - d.offy = 0.0f; - d.sliceFace = 0; - d.rawoutput = false; - d.lightBackgroundColour = d.darkBackgroundColour = - FloatVector(0.0f, 0.0f, 0.0f, 0.0f); - d.Red = d.Green = d.Blue = true; - d.Alpha = false; - - ReplayOutput_SetTextureDisplay(out, d); - - break; - } - } + ReplayOutput_SetTextureDisplay(out, displayCfg); MSG msg; ZeroMemory(&msg, sizeof(msg)); @@ -281,13 +237,10 @@ void DisplayRendererPreview(ReplayRenderer *renderer) } // If the message is WM_QUIT, exit the while loop - if(msg.message == WM_QUIT) - break; + if(msg.message == WM_QUIT) break; + // set to random event beyond the end of the frame to ensure output is marked as dirty ReplayRenderer_SetFrameEvent(renderer, 0, 10000000+rand()%1000); - - ReplayOutput_SetOutputConfig(out, c); - ReplayOutput_Display(out); Sleep(40);