COffscreenGLContext::COffscreenGLContext() { //FIXME: couldn't test this code myself! (coded from online documentations) AGLContext currentCtx = aglGetCurrentContext(); if (!currentCtx) throw opengl_error("Couldn't create an offscreen GL context: aglGetCurrentContext/aglGetCurrentDrawable failed!"); //! Get PixelFormat int attributeList[] = { AGL_ACCELERATED, AGL_RGBA, //AGL_OFFSCREEN, //AGL_DISPLAY_MASK, 1 //FIXME: detect SDL Window's CGOpenGLDisplayMask AGL_NONE }; pxlfmt = aglChoosePixelFormat(NULL, 0, attributeList); if (!pxlfmt) throw opengl_error("Couldn't create an offscreen GL context: aglChoosePixelFmt failed!"); //! Create Shared Context workerCtx = aglCreateContext(pxlfmt, currentCtx); if (!workerCtx) throw opengl_error("Couldn't create an offscreen GL context: aglCreateContext failed!"); }
COffscreenGLContext::COffscreenGLContext() { //! this creates a 2nd OpenGL context on the >onscreen< window/HDC //! so don't render to the the default framebuffer (always bind FBOs,DLs,...) !!! //! get the main (onscreen) GL context HGLRC mainRC = wglGetCurrentContext(); hdc = wglGetCurrentDC(); if (!hdc || !mainRC) { throw opengl_error("Couldn't create an offscreen GL context: wglGetCurrentDC failed!"); } //! create a 2nd GL context offscreenRC = wglCreateContext(hdc); if (!offscreenRC) { throw opengl_error("Couldn't create an offscreen GL context: wglCreateContext failed!"); } //! share the GL resources (textures,DLists,shaders,...) if(!wglMakeCurrent(NULL, NULL)) throw opengl_error("Could not deactivate rendering context"); int status = wglShareLists(mainRC, offscreenRC); if(!wglMakeCurrent(hdc, mainRC)) throw opengl_error("Could not activate rendering context"); if (!status) { DWORD err = GetLastError(); char msg[256]; SNPRINTF(msg, 255, "Couldn't create an offscreen GL context: wglShareLists failed (error: %i)!", (int)err); throw opengl_error(msg); } }
void COffscreenGLContext::WorkerThreadFree() { //! must run in the same thread as the offscreen GL context! if(!wglMakeCurrent(NULL, NULL)) throw opengl_error("Could not deactivate worker rendering context"); if(!wglDeleteContext(offscreenRC)) throw opengl_error("Could not delete off-screen rendering context"); }
CDecalsDrawerGL4::CDecalsDrawerGL4() : CEventClient("[CDecalsDrawerGL4]", 314159, false) , curWorstDecalIdx(-1) , curWorstDecalRating(1e6) , maxDecals(0) , maxDecalGroups(0) , useSSBO(false) , laggedFrames(0) , overlapStage(0) , depthTex(0) , atlasTex(0) { //if (!GetDrawDecals()) { // return; //} if (!GLEW_ARB_depth_clamp) throw opengl_error(LOG_SECTION_DECALS_GL4 ": missing GL_ARB_depth_clamp"); if (!GLEW_ARB_vertex_array_object) throw opengl_error(LOG_SECTION_DECALS_GL4 ": missing GL_ARB_vertex_array_object"); if (!globalRendering->haveGLSL) throw opengl_error(LOG_SECTION_DECALS_GL4 ": missing GLSL"); if (!dynamic_cast<CSMFReadMap*>(readMap)) throw unsupported_error(LOG_SECTION_DECALS_GL4 ": only SMF supported"); if (static_cast<CSMFReadMap*>(readMap)->GetNormalsTexture() <= 0) throw unsupported_error(LOG_SECTION_DECALS_GL4 ": advanced map shading must be enabled"); DetectMaxDecals(); LoadShaders(); if (!decalShader->IsValid()) { throw opengl_error(LOG_SECTION_DECALS_GL4 ": cannot compile shader"); } glGenTextures(1, &depthTex); CreateBoundingBoxVBOs(); CreateStructureVBOs(); SunChanged(); ViewResize(); GenerateAtlasTexture(); fboOverlap.Bind(); //fboOverlap.CreateRenderBuffer(GL_COLOR_ATTACHMENT0, GL_RGBA8, OVERLAP_TEST_TEXTURE_SIZE, OVERLAP_TEST_TEXTURE_SIZE); fboOverlap.CreateRenderBuffer(GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8, OVERLAP_TEST_TEXTURE_SIZE, OVERLAP_TEST_TEXTURE_SIZE); fboOverlap.CheckStatus(LOG_SECTION_DECALS_GL4); fboOverlap.Unbind(); eventHandler.AddClient(this); CExplosionCreator::AddExplosionListener(this); decalDrawer = this; }
void COffscreenGLContext::WorkerThreadPost() { if (!glXMakeCurrent(display, pbuf, workerCtx)) throw opengl_error("Could not activate worker rendering context"); const PFNGLACTIVETEXTUREPROC workerGlActiveTexture = (PFNGLACTIVETEXTUREPROC)glXGetProcAddress((const GLubyte*)"glActiveTexture"); if (workerGlActiveTexture != mainGlActiveTexture) { WorkerThreadFree(); throw opengl_error("Could not activate worker rendering context (uses different function pointers)"); } }
void COffscreenGLContext::WorkerThreadPost() { //! activate the offscreen GL context in the worker thread if (!wglMakeCurrent(hdc, offscreenRC)) throw opengl_error("Could not activate worker rendering context"); const PFNGLACTIVETEXTUREPROC workerGlActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"); if (workerGlActiveTexture != mainGlActiveTexture) { WorkerThreadFree(); throw opengl_error("Could not activate worker rendering context (uses different function pointers)"); } }
COffscreenGLContext::COffscreenGLContext() { //! this creates a 2nd OpenGL context on the >onscreen< window/HDC //! so don't render to the the default framebuffer (always bind FBOs,DLs,...) !!! if (!mainGlActiveTexture) mainGlActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"); //! get the main (onscreen) GL context HGLRC mainRC = wglGetCurrentContext(); hdc = wglGetCurrentDC(); if (!hdc || !mainRC) { throw opengl_error("Couldn't create an offscreen GL context: wglGetCurrentDC failed!"); } int status = TRUE; offscreenRC = NULL; #ifdef WGL_ARB_create_context if (wglCreateContextAttribsARB) { static const int contextAttribs[] = { WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, 0 }; offscreenRC = wglCreateContextAttribsARB(hdc, mainRC, contextAttribs); if (!offscreenRC) LOG_L(L_WARNING, "Couldn't create an offscreen GL context: wglCreateContextAttribsARB failed!"); } #endif if (!offscreenRC) { //! create a 2nd GL context offscreenRC = wglCreateContext(hdc); if (!offscreenRC) { throw opengl_error("Couldn't create an offscreen GL context: wglCreateContext failed!"); } //! share the GL resources (textures,DLists,shaders,...) if (!wglMakeCurrent(NULL, NULL)) throw opengl_error("Could not deactivate rendering context"); status = wglShareLists(mainRC, offscreenRC); if (!wglMakeCurrent(hdc, mainRC)) throw opengl_error("Could not activate rendering context"); } if (!status) { DWORD err = GetLastError(); char msg[256]; SNPRINTF(msg, 255, "Couldn't create an offscreen GL context: wglShareLists failed (error: %i)!", (int)err); throw opengl_error(msg); } }
void COffscreenGLContext::WorkerThreadFree() { CGLError err = CGLSetCurrentContext(NULL); if (kCGLNoError != err) { LOG_L(L_ERROR, CGLErrorString(err)); throw opengl_error("Could not deactivate worker rendering context"); } }
COffscreenGLContext::COffscreenGLContext() { // Get Current OnScreen Context CGLContextObj currentCglCtx = CGLGetCurrentContext(); if (!currentCglCtx) throw opengl_error("Couldn't create an offscreen GL context: CGLGetCurrentContext failed!"); // Get PixelFormat CGLPixelFormatAttribute attribs[] = { (CGLPixelFormatAttribute)0 }; GLint numPixelFormats = 0; CGLPixelFormatObj cglPxlfmt = NULL; CGLChoosePixelFormat(attribs, &cglPxlfmt, &numPixelFormats); if (!cglPxlfmt) throw opengl_error("Couldn't create an offscreen GL context: CGLChoosePixelFmt failed!"); // Create Shared Context CGLCreateContext(cglPxlfmt, currentCglCtx, &cglWorkerCtx); CGLDestroyPixelFormat(cglPxlfmt); if (!cglWorkerCtx) throw opengl_error("Couldn't create an offscreen GL context: CGLCreateContext failed!"); }
COffscreenGLContext::COffscreenGLContext() { //! Get MainCtx & X11-Display GLXContext mainCtx = glXGetCurrentContext(); //GLXDrawable mainDrawable = glXGetCurrentDrawable(); if(!mainCtx) throw opengl_error("Couldn't create an offscreen GL context: glXGetCurrentContext failed!"); SDL_SysWMinfo info; SDL_VERSION(&info.version); if(!SDL_GetWMInfo(&info)) throw opengl_error("Couldn't create an offscreen GL context: SDL_GetWMInfo failed!"); info.info.x11.lock_func(); display = info.info.x11.display; int scrnum = XDefaultScreen(display); info.info.x11.unlock_func(); if (!display) throw opengl_error("Couldn't create an offscreen GL context: Couldn't determine display!"); //! Create a FBConfig int nelements = 0; const int fbattrib[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, GLX_BUFFER_SIZE, 32, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, None }; GLXFBConfig* fbcfg = glXChooseFBConfig(display, scrnum, (const int*)fbattrib, &nelements); if (!fbcfg || (nelements == 0)) throw opengl_error("Couldn't create an offscreen GL context: glXChooseFBConfig failed!"); //! Create a pbuffer (each render context needs a drawable) const int pbuf_attrib[] = { GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, GLX_PRESERVED_CONTENTS, false, None }; pbuf = glXCreatePbuffer(display, *fbcfg, (const int*)pbuf_attrib); if (!pbuf) throw opengl_error("Couldn't create an offscreen GL context: glXCreatePbuffer failed!"); //! Create render context workerCtx = glXCreateNewContext(display, *fbcfg, GLX_RGBA_TYPE, mainCtx, true); if (!workerCtx) throw opengl_error("Couldn't create an offscreen GL context: glXCreateNewContext failed!"); XFree(fbcfg); }
CInfoTextureCombiner::CInfoTextureCombiner() : CPboInfoTexture("info") , disabled(true) { texSize = (configHandler->GetBool("HighResInfoTexture")) ? int2(mapDims.pwr2mapx, mapDims.pwr2mapy) : int2(mapDims.pwr2mapx >> 1, mapDims.pwr2mapy >> 1); //texSize = (configHandler->GetBool("HighResInfoTexture")) ? int2(512, 512) : int2(256, 256); texChannels = 4; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // precision hint: // GL_RGBA8 hasn't enough precision for subtle blending operations, // cause we update the texture slowly with alpha values of 0.05, so // per update the change is too subtle. With just 8bits per channel // the update is too less to change the texture value at all. The // texture keeps unchanged then and never reaches the wanted final // state, keeping `shadow` images of the old state. // Testing showed that 10bits per channel are already good enough to // counter this, GL_RGBA16 would be another solution, but needs twice // as much texture memory + bandwidth. // Also GL3.x enforces that GL_RGB10_A2 must be renderable. glSpringTexStorage2D(GL_TEXTURE_2D, -1, GL_RGB10_A2, texSize.x, texSize.y); if (FBO::IsSupported()) { fbo.Bind(); fbo.AttachTexture(texture); /*bool status =*/ fbo.CheckStatus("CInfoTextureCombiner"); glClearColor(0.5f, 0.5f, 0.5f, 1.0f); if (fbo.IsValid()) glClear(GL_COLOR_BUFFER_BIT); FBO::Unbind(); // create mipmaps glBindTexture(GL_TEXTURE_2D, texture); glGenerateMipmap(GL_TEXTURE_2D); } shader = shaderHandler->CreateProgramObject("[CInfoTextureCombiner]", "CInfoTextureCombiner", false); if (!fbo.IsValid() /*|| !shader->IsValid()*/) { // don't check shader (it gets created/switched at runtime) throw opengl_error(""); } }
CLosTexture::CLosTexture() : CPboInfoTexture("los") , uploadTex(0) { texSize = losHandler->los.size; texChannels = 1; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, -1, GL_R8, texSize.x, texSize.y); infoTexPBO.Bind(); infoTexPBO.New(texSize.x * texSize.y * texChannels * 2, GL_STREAM_DRAW); infoTexPBO.Unbind(); if (FBO::IsSupported()) { fbo.Bind(); fbo.AttachTexture(texture); /*bool status =*/ fbo.CheckStatus("CLosTexture"); FBO::Unbind(); } if (!fbo.IsValid()) throw opengl_error(""); const std::string vertexCode = R"( #version 410 core layout(location = 0) in vec3 aVertexPos; layout(location = 1) in vec2 aTexCoords; // ignored out vec2 vTexCoords; void main() { vTexCoords = aVertexPos.xy * 0.5 + 0.5; gl_Position = vec4(aVertexPos, 1.0); } )"; const std::string fragmentCode = R"( #version 410 core uniform sampler2D tex0; in vec2 vTexCoords; layout(location = 0) out vec4 fFragColor; void main() { vec2 f = texture(tex0, vTexCoords).rg; float c = (f.r + f.g) * 200000.0; fFragColor = vec4(c); } )"; const char* errorFormats[2] = { "%s-shader compilation error: %s", "%s-shader validation error: %s", }; shader = shaderHandler->CreateProgramObject("[CLosTexture]", "CLosTexture"); shader->AttachShaderObject(shaderHandler->CreateShaderObject(vertexCode, "", GL_VERTEX_SHADER)); shader->AttachShaderObject(shaderHandler->CreateShaderObject(fragmentCode, "", GL_FRAGMENT_SHADER)); shader->Link(); if (!shader->IsValid()) { LOG_L(L_ERROR, errorFormats[0], shader->GetName().c_str(), shader->GetLog().c_str()); throw opengl_error(""); } shader->Enable(); shader->SetUniform("tex0", 0); shader->Disable(); shader->Validate(); if (!shader->IsValid()) { LOG_L(L_ERROR, errorFormats[1], shader->GetName().c_str(), shader->GetLog().c_str()); throw opengl_error(""); } glGenTextures(1, &uploadTex); glBindTexture(GL_TEXTURE_2D, uploadTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, 1, GL_RG8, texSize.x, texSize.y); }
CHeightTexture::CHeightTexture() : CPboInfoTexture("height") , CEventClient("[CHeightTexture]", 271990, false) , needUpdate(true) { eventHandler.AddClient(this); texSize = int2(mapDims.mapxp1, mapDims.mapyp1); texChannels = 4; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, texSize.x, texSize.y); glGenTextures(1, &paletteTex); glBindTexture(GL_TEXTURE_2D, paletteTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 2); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 1, GL_RGBA, GL_UNSIGNED_BYTE, &CHeightLinePalette::paletteColored[0].r); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 1, 256, 1, GL_RGBA, GL_UNSIGNED_BYTE, &CHeightLinePalette::paletteBlackAndWhite[0].r); if (FBO::IsSupported()) { fbo.Bind(); fbo.AttachTexture(texture); /*bool status =*/ fbo.CheckStatus("CHeightTexture"); FBO::Unbind(); } if (!fbo.IsValid()) throw opengl_error(""); const std::string vertexCode = R"( #version 410 core layout(location = 0) in vec3 aVertexPos; layout(location = 1) in vec2 aTexCoords; // ignored out vec2 vTexCoords; void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); gl_Position.xy = aVertexPos.xy * 2.0 - 1.0; vTexCoords = aVertexPos.st; } )"; const std::string fragmentCode = R"( #version 410 core uniform sampler2D texHeight; uniform sampler2D texPalette; uniform float paletteOffset; in vec2 vTexCoords; layout(location = 0) out vec4 fFragColor; void main() { float h = texture(texHeight, vTexCoords).r; vec2 tc = vec2(h * (8. / 256.), paletteOffset); fFragColor = texture(texPalette, tc); } )"; const char* errorFormats[2] = { "%s-shader compilation error: %s", "%s-shader validation error: %s", }; shader = shaderHandler->CreateProgramObject("[CHeightTexture]", "CHeightTexture"); shader->AttachShaderObject(shaderHandler->CreateShaderObject(vertexCode, "", GL_VERTEX_SHADER)); shader->AttachShaderObject(shaderHandler->CreateShaderObject(fragmentCode, "", GL_FRAGMENT_SHADER)); shader->Link(); if (!shader->IsValid()) { LOG_L(L_ERROR, errorFormats[0], shader->GetName().c_str(), shader->GetLog().c_str()); throw opengl_error(""); } shader->Enable(); shader->SetUniform("texHeight", 0); shader->SetUniform("texPalette", 1); shader->SetUniform("paletteOffset", configHandler->GetBool("ColorElev") ? 0.0f : 1.0f); shader->Disable(); shader->Validate(); if (!shader->IsValid()) { LOG_L(L_ERROR, errorFormats[1], shader->GetName().c_str(), shader->GetLog().c_str()); throw opengl_error(""); } }
void COffscreenGLContext::WorkerThreadFree() { if (!glXMakeCurrent(display, None, NULL)) throw opengl_error("Could not deactivate worker rendering context"); }
void COffscreenGLContext::WorkerThreadPost() { //! activate the offscreen GL context in the worker thread if(!wglMakeCurrent(hdc, offscreenRC)) throw opengl_error("Could not activate worker rendering context"); }
/*********************************************************************** * X11DRV_SetPixelFormat */ static BOOL X11DRV_SetPixelFormat( PHYSDEV dev, int fmt, const PIXELFORMATDESCRIPTOR *ppfd ) { opengl_error(); return FALSE; }
/*********************************************************************** * X11DRV_DescribePixelFormat */ static int X11DRV_DescribePixelFormat( PHYSDEV dev, int fmt, UINT size, PIXELFORMATDESCRIPTOR *ppfd ) { opengl_error(); return 0; }
CRadarTexture::CRadarTexture() : CPboInfoTexture("radar") , uploadTexRadar(0) , uploadTexJammer(0) { texSize = losHandler->radar.size; texChannels = 2; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, -1, GL_RG8, texSize.x, texSize.y); infoTexPBO.Bind(); infoTexPBO.New(texSize.x * texSize.y * texChannels * sizeof(unsigned short), GL_STREAM_DRAW); infoTexPBO.Unbind(); if (FBO::IsSupported()) { fbo.Bind(); fbo.AttachTexture(texture); /*bool status =*/ fbo.CheckStatus("CRadarTexture"); FBO::Unbind(); } const std::string vertexCode = R"( varying vec2 texCoord; void main() { texCoord = gl_Vertex.xy * 0.5 + 0.5; gl_Position = vec4(gl_Vertex.xyz, 1.0); } )"; const std::string fragmentCode = R"( uniform sampler2D texLoS; uniform sampler2D texRadar; uniform sampler2D texJammer; varying vec2 texCoord; void main() { float los = texture2D(texLoS, texCoord).r; vec2 fr = texture2D(texRadar, texCoord).rg; vec2 fj = texture2D(texJammer, texCoord).rg; float cr = (fr.r + fr.g) * 200000.0; float cj = (fj.r + fj.g) * 200000.0; gl_FragColor = vec4(cr, los * cj, 0.0f, 0.0f); } )"; shader = shaderHandler->CreateProgramObject("[CRadarTexture]", "CRadarTexture", false); shader->AttachShaderObject(shaderHandler->CreateShaderObject(vertexCode, "", GL_VERTEX_SHADER)); shader->AttachShaderObject(shaderHandler->CreateShaderObject(fragmentCode, "", GL_FRAGMENT_SHADER)); shader->Link(); if (!shader->IsValid()) { const char* fmt = "%s-shader compilation error: %s"; LOG_L(L_ERROR, fmt, shader->GetName().c_str(), shader->GetLog().c_str()); } else { shader->Enable(); shader->SetUniform("texRadar", 1); shader->SetUniform("texJammer", 0); shader->SetUniform("texLoS", 2); shader->Disable(); shader->Validate(); if (!shader->IsValid()) { const char* fmt = "%s-shader validation error: %s"; LOG_L(L_ERROR, fmt, shader->GetName().c_str(), shader->GetLog().c_str()); } } if (fbo.IsValid() && shader->IsValid()) { glGenTextures(1, &uploadTexRadar); glBindTexture(GL_TEXTURE_2D, uploadTexRadar); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, 1, GL_RG8, texSize.x, texSize.y); glGenTextures(1, &uploadTexJammer); glBindTexture(GL_TEXTURE_2D, uploadTexJammer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, 1, GL_RG8, texSize.x, texSize.y); } if (!fbo.IsValid() || !shader->IsValid()) { throw opengl_error(""); } }
CDecalsDrawerGL4::CDecalsDrawerGL4() { throw opengl_error(LOG_SECTION_DECALS_GL4 ": Compiled without OpenGL4 support!"); }
COffscreenGLContext::COffscreenGLContext() { if (!mainGlActiveTexture) mainGlActiveTexture = (PFNGLACTIVETEXTUREPROC)glXGetProcAddress((const GLubyte*)"glActiveTexture"); //! Get MainCtx & X11-Display GLXContext mainCtx = glXGetCurrentContext(); display = glXGetCurrentDisplay(); //GLXDrawable mainDrawable = glXGetCurrentDrawable(); if(!mainCtx) throw opengl_error("Couldn't create an offscreen GL context: glXGetCurrentContext failed!"); if (!display) throw opengl_error("Couldn't create an offscreen GL context: Couldn't determine display!"); int scrnum = XDefaultScreen(display); //! Create a FBConfig int nelements = 0; const int fbattribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, GLX_BUFFER_SIZE, 32, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, None }; GLXFBConfig* fbcfg = glXChooseFBConfig(display, scrnum, (const int*)fbattribs, &nelements); if (!fbcfg || (nelements == 0)) throw opengl_error("Couldn't create an offscreen GL context: glXChooseFBConfig failed!"); //! Create a pbuffer (each render context needs a drawable) const int pbuf_attribs[] = { GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, GLX_PRESERVED_CONTENTS, false, None }; pbuf = glXCreatePbuffer(display, fbcfg[0], (const int*)pbuf_attribs); if (!pbuf) throw opengl_error("Couldn't create an offscreen GL context: glXCreatePbuffer failed!"); /* //Create a GL 3.0 context const int ctx_attribs[] = { //GLX_CONTEXT_MAJOR_VERSION_ARB, 2, //GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, //GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None }; workerCtx = glXCreateContextAttribsARB(display, fbcfg[0], mainCtx, true, ctx_attribs); */ //! Create render context workerCtx = glXCreateNewContext(display, fbcfg[0], GLX_RGBA_TYPE, mainCtx, true); if (!workerCtx) throw opengl_error("Couldn't create an offscreen GL context: glXCreateNewContext failed!"); XFree(fbcfg); }