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!");
}
示例#2
0
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");
}
示例#4
0
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");
	}
}
示例#9
0
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!");
}
示例#10
0
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);
}
示例#11
0
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("");
	}
}
示例#12
0
文件: Los.cpp 项目: sprunk/spring
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);
}
示例#13
0
文件: Height.cpp 项目: sprunk/spring
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");
}
示例#16
0
/***********************************************************************
 *		X11DRV_SetPixelFormat
 */
static BOOL X11DRV_SetPixelFormat( PHYSDEV dev, int fmt, const PIXELFORMATDESCRIPTOR *ppfd )
{
    opengl_error();
    return FALSE;
}
示例#17
0
/***********************************************************************
 *		X11DRV_DescribePixelFormat
 */
static int X11DRV_DescribePixelFormat( PHYSDEV dev, int fmt, UINT size, PIXELFORMATDESCRIPTOR *ppfd )
{
    opengl_error();
    return 0;
}
示例#18
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("");
	}
}
示例#19
0
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);
}