Example #1
0
bool C4LandscapeRenderGL::LoadShader(C4GroupSet *pGroups, C4Shader& shader, const char* name, int ssc)
{
	// Setup #defines
	shader.AddDefine("OPENCLONK");
	shader.AddDefine("OC_LANDSCAPE");
	if(ssc & C4SSC_LIGHT) shader.AddDefine("OC_DYNAMIC_LIGHT"); // sample light from light texture

	// Create vertex shader
	shader.LoadVertexSlices(pGroups, "LandscapeVertexShader.glsl");

	// Then load slices for fragment shader
	shader.LoadFragmentSlices(pGroups, "CommonShader.glsl");
	shader.LoadFragmentSlices(pGroups, "LandscapeShader.glsl");

	// Make attribute name map
	const char* AttributeNames[C4LRA_Count + 1];
	AttributeNames[C4LRA_Position] = "oc_Position";
	AttributeNames[C4LRA_LandscapeTexCoord] = "oc_LandscapeTexCoord";
	AttributeNames[C4LRA_LightTexCoord] = "oc_LightTexCoord"; // unused if no dynamic light
	AttributeNames[C4LRA_Count] = NULL;

	// Initialise!
	if (!shader.Init(name, UniformNames, AttributeNames)) {
		shader.ClearSlices();
		return false;
	}

	return true;
}
Example #2
0
	virtual void AddShaderSlices(C4Shader& shader, int ssc)
	{
#ifndef USE_CONSOLE
		// Add mesh-independent slices
		shader.AddDefine("OPENCLONK");
		shader.AddDefine("OC_MESH");

		if (ssc & C4SSC_MOD2) shader.AddDefine("OC_CLRMOD_MOD2");
		if (ssc & C4SSC_LIGHT) shader.AddDefine("OC_DYNAMIC_LIGHT");

		// Note these are never set for meshes at the moment:
		if (ssc & C4SSC_BASE) shader.AddDefine("OC_HAVE_BASE");
		if (ssc & C4SSC_OVERLAY) shader.AddDefine("OC_HAVE_OVERLAY");

		shader.LoadFragmentSlices(&::GraphicsResource.Files, "CommonShader.glsl");
		shader.LoadFragmentSlices(&::GraphicsResource.Files, "ObjectShader.glsl");
#endif
	}
bool C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
{
#ifndef USE_CONSOLE
	// Update FoW at interesting location
	pFoW->Update(Region, pPlayer);

	// On screen? No need to set up frame buffer - simply shortcut
	if (pOnScreen)
	{
		pFoW->Render(this, pOnScreen, pPlayer, pGL->GetProjectionMatrix());
		return true;
	}

	// Set up shader. If this one doesn't work, we're really in trouble.
	C4Shader *pShader = pFoW->GetFramebufShader();
	assert(pShader);
	if (!pShader) return false;

	// Create & bind the frame buffer
	pDraw->StorePrimaryClipper();
	if(!BindFramebuf())
	{
		pDraw->RestorePrimaryClipper();
		return false;
	}
	assert(pSurface && hFrameBufDraw);
	if (!pSurface || !hFrameBufDraw)
		return false;

	// Set up a clean context
	glViewport(0, 0, pSurface->Wdt, pSurface->Hgt);
	const StdProjectionMatrix projectionMatrix = StdProjectionMatrix::Orthographic(0.0f, pSurface->Wdt, pSurface->Hgt, 0.0f);

	// Clear texture contents
	assert(pSurface->Hgt % 2 == 0);
	glScissor(0, pSurface->Hgt / 2, pSurface->Wdt, pSurface->Hgt / 2);
	glClearColor(0.0f, 0.5f / 1.5f, 0.5f / 1.5f, 0.0f);
	glEnable(GL_SCISSOR_TEST);
	glClear(GL_COLOR_BUFFER_BIT);

	// clear lower half of texture
	glScissor(0, 0, pSurface->Wdt, pSurface->Hgt / 2);
	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);
	glDisable(GL_SCISSOR_TEST);

	// Render FoW to frame buffer object
	glBlendFunc(GL_ONE, GL_ONE);
	pFoW->Render(this, NULL, pPlayer, projectionMatrix);

	// Copy over the old state
	if (OldRegion.Wdt > 0)
	{

		// How much the borders have moved
		int dx0 = Region.x - OldRegion.x,
			dy0 = Region.y - OldRegion.y,
			dx1 = Region.x + Region.Wdt - OldRegion.x - OldRegion.Wdt,
			dy1 = Region.y + Region.Hgt - OldRegion.y - OldRegion.Hgt;

		// Source and target rect coordinates (landscape coordinate system)
		int sx0 = std::max(0, dx0),                  sy0 = std::max(0, dy0),
			sx1 = OldRegion.Wdt - std::max(0, -dx1), sy1 = OldRegion.Hgt - std::max(0, -dy1),
			tx0 = std::max(0, -dx0),                 ty0 = std::max(0, -dy0),
			tx1 = Region.Wdt - std::max(0, dx1),     ty1 = Region.Hgt - std::max(0, dy1);

		// Quad coordinates
		float vtxData[16];
		float* squad = &vtxData[0];
		float* tquad = &vtxData[8];

		squad[0] = float(sx0);
		squad[1] = float(sy0);
		squad[2] = float(sx0);
		squad[3] = float(sy1);
		squad[4] = float(sx1);
		squad[5] = float(sy0);
		squad[6] = float(sx1);
		squad[7] = float(sy1);

		tquad[0] = float(tx0);
		tquad[1] = float(ty0);
		tquad[2] = float(tx0);
		tquad[3] = float(ty1);
		tquad[4] = float(tx1);
		tquad[5] = float(ty0);
		tquad[6] = float(tx1);
		tquad[7] = float(ty1);

		// Transform into texture coordinates
		for (int i = 0; i < 4; i++)
		{
			squad[i*2] = squad[i*2] / pBackSurface->Wdt;
			squad[i*2+1] = 1.0 - squad[i*2+1] / pBackSurface->Hgt;
		}

		// Load coordinates into vertex buffer
		if (hVBO == 0)
		{
			glGenBuffers(1, &hVBO);
			glBindBuffer(GL_ARRAY_BUFFER, hVBO);
			glBufferData(GL_ARRAY_BUFFER, sizeof(vtxData), vtxData, GL_STREAM_DRAW);

			assert(vaoid == 0);
			vaoid = pGL->GenVAOID();
		}
		else
		{
			glBindBuffer(GL_ARRAY_BUFFER, hVBO);
			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vtxData), vtxData);
		}

		// Copy using shader
		C4ShaderCall Call(pShader);
		Call.Start();
		if (Call.AllocTexUnit(C4FoWFSU_Texture))
			glBindTexture(GL_TEXTURE_2D, pBackSurface->texture->texName);
		Call.SetUniformMatrix4x4(C4FoWFSU_ProjectionMatrix, projectionMatrix);
		glBlendFunc(GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR);
		float normalBlend = 1.0f / 4.0f, // Normals change quickly
		      brightBlend = 1.0f / 16.0f; // Intensity more slowly
		glBlendColor(0.0f,normalBlend,normalBlend,brightBlend);

		GLuint vao;
		const bool has_vao = pGL->GetVAO(vaoid, vao);
		glBindVertexArray(vao);
		if (!has_vao)
		{
			glEnableVertexAttribArray(pShader->GetAttribute(C4FoWFSA_Position));
			glEnableVertexAttribArray(pShader->GetAttribute(C4FoWFSA_TexCoord));
			glVertexAttribPointer(pShader->GetAttribute(C4FoWFSA_Position), 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<const uint8_t*>(8 * sizeof(float)));
			glVertexAttribPointer(pShader->GetAttribute(C4FoWFSA_TexCoord), 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<const uint8_t*>(0));
		}

		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

		glBindVertexArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);

		Call.Finish();
	}

	// Done!
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	pDraw->RestorePrimaryClipper();

	OldRegion = Region;
#endif
	return true;
}
bool CStdGL::PrepareSpriteShader(C4Shader& shader, const char* name, int ssc, C4GroupSet* pGroups, const char* const* additionalDefines, const char* const* additionalSlices)
{
	const char* uniformNames[C4SSU_Count + 1];
	uniformNames[C4SSU_ProjectionMatrix] = "projectionMatrix";
	uniformNames[C4SSU_ModelViewMatrix] = "modelviewMatrix";
	uniformNames[C4SSU_NormalMatrix] = "normalMatrix";
	uniformNames[C4SSU_ClrMod] = "clrMod";
	uniformNames[C4SSU_Gamma] = "gamma";
	uniformNames[C4SSU_BaseTex] = "baseTex";
	uniformNames[C4SSU_OverlayTex] = "overlayTex";
	uniformNames[C4SSU_OverlayClr] = "overlayClr";
	uniformNames[C4SSU_LightTex] = "lightTex";
	uniformNames[C4SSU_LightTransform] = "lightTransform";
	uniformNames[C4SSU_NormalTex] = "normalTex";
	uniformNames[C4SSU_AmbientTex] = "ambientTex";
	uniformNames[C4SSU_AmbientTransform] = "ambientTransform";
	uniformNames[C4SSU_AmbientBrightness] = "ambientBrightness";
	uniformNames[C4SSU_MaterialAmbient] = "materialAmbient"; // unused
	uniformNames[C4SSU_MaterialDiffuse] = "materialDiffuse"; // unused
	uniformNames[C4SSU_MaterialSpecular] = "materialSpecular"; // unused
	uniformNames[C4SSU_MaterialEmission] = "materialEmission"; // unused
	uniformNames[C4SSU_MaterialShininess] = "materialShininess"; // unused
	uniformNames[C4SSU_Bones] = "bones"; // unused
	uniformNames[C4SSU_CullMode] = "cullMode"; // unused
	uniformNames[C4SSU_FrameCounter] = "frameCounter";
	uniformNames[C4SSU_Count] = NULL;

	const char* attributeNames[C4SSA_Count + 1];
	attributeNames[C4SSA_Position] = "oc_Position";
	attributeNames[C4SSA_Normal] = "oc_Normal"; // unused
	attributeNames[C4SSA_TexCoord] = "oc_TexCoord"; // only used if C4SSC_Base is set
	attributeNames[C4SSA_Color] = "oc_Color";
	attributeNames[C4SSA_BoneIndices0] = "oc_BoneIndices0"; // unused
	attributeNames[C4SSA_BoneIndices1] = "oc_BoneIndices1"; // unused
	attributeNames[C4SSA_BoneWeights0] = "oc_BoneWeights0"; // unused
	attributeNames[C4SSA_BoneWeights1] = "oc_BoneWeights1"; // unused
	attributeNames[C4SSA_Count] = NULL;

	// Clear previous content
	shader.Clear();
	shader.ClearSlices();

	// Start with #defines
	shader.AddDefine("OPENCLONK");
	shader.AddDefine("OC_SPRITE");
	if (ssc & C4SSC_MOD2) shader.AddDefine("OC_CLRMOD_MOD2");
	if (ssc & C4SSC_NORMAL) shader.AddDefine("OC_WITH_NORMALMAP");
	if (ssc & C4SSC_LIGHT) shader.AddDefine("OC_DYNAMIC_LIGHT");
	if (ssc & C4SSC_BASE) shader.AddDefine("OC_HAVE_BASE");
	if (ssc & C4SSC_OVERLAY) shader.AddDefine("OC_HAVE_OVERLAY");

	if (additionalDefines)
		for (const char* const* define = additionalDefines; *define != NULL; ++define)
			shader.AddDefine(*define);

	// Then load slices for fragment and vertex shader
	shader.LoadVertexSlices(pGroups, "SpriteVertexShader.glsl");
	shader.LoadFragmentSlices(pGroups, "CommonShader.glsl");
	shader.LoadFragmentSlices(pGroups, "ObjectShader.glsl");

	if (additionalSlices)
		for (const char* const* slice = additionalSlices; *slice != NULL; ++slice)
			shader.LoadFragmentSlices(pGroups, *slice);

	if (!shader.Init(name, uniformNames, attributeNames))
	{
		shader.ClearSlices();
		return false;
	}

	return true;
}