Ejemplo n.º 1
0
static void drawDepthOnly(const glm::mat4 &ModelViewProjection, const glm::vec4 &paramsXLight, const glm::vec4 &paramsYLight)
{
	const auto &program = pie_ActivateShader(SHADER_TERRAIN_DEPTH, ModelViewProjection, paramsXLight, paramsYLight, 1, glm::mat4(1.f), glm::mat4(1.f));
	pie_SetTexturePage(TEXPAGE_NONE);
	pie_SetRendMode(REND_OPAQUE);

	// we only draw in the depth buffer of using fog of war, as the clear color is black then
	if (!pie_GetFogStatus())
	{
		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	}

	// draw slightly higher distance than it actually is so it will not
	// by accident obscure the actual terrain
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(0.1f, 1.0f);

	// bind the vertex buffer
	geometryIndexVBO->bind();
	geometryVBO->bind();

	glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, sizeof(RenderVertex), BUFFER_OFFSET(0));
	glEnableVertexAttribArray(program.locVertex);

	for (int x = 0; x < xSectors; x++)
	{
		for (int y = 0; y < ySectors; y++)
		{
			if (sectors[x * ySectors + y].draw)
			{
				addDrawRangeElements(GL_TRIANGLES,
					sectors[x * ySectors + y].geometryOffset,
					sectors[x * ySectors + y].geometryOffset + sectors[x * ySectors + y].geometrySize,
					sectors[x * ySectors + y].geometryIndexSize,
					GL_UNSIGNED_INT,
					sectors[x * ySectors + y].geometryIndexOffset);
			}
		}
	}
	finishDrawRangeElements();
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	if (!pie_GetFogStatus())
	{
		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	}

	// disable the depth offset
	glDisable(GL_POLYGON_OFFSET_FILL);
	glDisableVertexAttribArray(program.locVertex);
	pie_DeactivateShader();
}
Ejemplo n.º 2
0
/**
 * Either draw the elements or batch them to be sent to OpenGL later
 * This improves performance by reducing the amount of OpenGL calls.
 */
static void addDrawRangeElements(GLenum mode,
                                 GLuint start, 
                                 GLuint end, 
                                 GLsizei count, 
                                 GLenum type, 
                                 GLuint offset)
{
	ASSERT(mode == GL_TRIANGLES, "not supported");
	ASSERT(type == GL_UNSIGNED_INT, "not supported");
	
	if (end - start + 1 > GLmaxElementsVertices)
	{
		debug(LOG_WARNING, "A single call provided too much vertices, will operate at reduced performance or crash. Decrease the sector size to fix this.");
	}
	if (count > GLmaxElementsIndices)
	{
		debug(LOG_WARNING, "A single call provided too much indices, will operate at reduced performance or crash. Decrease the sector size to fix this.");
	}
	
	if (!drawRangeElementsStarted)
	{
		dreStart  = start;
		dreEnd    = end;
		dreCount  = count;
		dreOffset = offset;
		drawRangeElementsStarted = true;
		return;
	}
	
	// check if we can append theoretically and 
	// check if this will not go over the bounds advised by the opengl implementation
	if (dreOffset + dreCount != offset ||
		dreCount + count > GLmaxElementsIndices ||
		end - dreStart + 1 > GLmaxElementsVertices)
	{
		finishDrawRangeElements();
		// start anew
		addDrawRangeElements(mode, start, end, count, type, offset);
	}
	else
	{
		// OK to append
		dreCount += count;
		dreEnd = end;
	}
	// make sure we did everything right
	ASSERT(dreEnd - dreStart + 1 <= GLmaxElementsVertices, "too many vertices (%i)", (int)(dreEnd - dreStart + 1));
	ASSERT(dreCount <= GLmaxElementsIndices, "too many indices (%i)", (int)(dreCount));
}
Ejemplo n.º 3
0
/**
 * Draw the water.
 */
void drawWater(const glm::mat4 &viewMatrix)
{
	int x, y;
	const glm::vec4 paramsX(0, 0, -1.0f / world_coord(4), 0);
	const glm::vec4 paramsY(1.0f / world_coord(4), 0, 0, 0);
	const glm::vec4 paramsX2(0, 0, -1.0f / world_coord(5), 0);
	const glm::vec4 paramsY2(1.0f / world_coord(5), 0, 0, 0);
	const auto &renderState = getCurrentRenderState();

	const auto &program = pie_ActivateShader(SHADER_WATER, viewMatrix, paramsX, paramsY, paramsX2, paramsY2, 0, 1,
		glm::translate(glm::vec3(waterOffset, 0.f, 0.f)), glm::mat4(1.f), renderState.fogEnabled, renderState.fogBegin, renderState.fogEnd);

	glDepthMask(GL_FALSE);

	// first texture unit
	pie_SetTexturePage(iV_GetTexture("page-80-water-1.png"));
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	// multiplicative blending
	pie_SetRendMode(REND_MULTIPLICATIVE);

	// second texture unit
	glActiveTexture(GL_TEXTURE1);
	pie_Texture(iV_GetTexture("page-81-water-2.png")).bind();
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	// bind the vertex buffer
	waterIndexVBO->bind();
	waterVBO->bind();
	glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, sizeof(RenderVertex), BUFFER_OFFSET(0));
	glEnableVertexAttribArray(program.locVertex);

	for (x = 0; x < xSectors; x++)
	{
		for (y = 0; y < ySectors; y++)
		{
			if (sectors[x * ySectors + y].draw)
			{
				addDrawRangeElements(GL_TRIANGLES,
				                     sectors[x * ySectors + y].geometryOffset,
				                     sectors[x * ySectors + y].geometryOffset + sectors[x * ySectors + y].geometrySize,
				                     sectors[x * ySectors + y].waterIndexSize,
				                     GL_UNSIGNED_INT,
				                     sectors[x * ySectors + y].waterIndexOffset);
			}
		}
	}
	finishDrawRangeElements();
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	glDisableVertexAttribArray(program.locVertex);

	// move the water
	if (!gamePaused())
	{
		waterOffset += graphicsTimeAdjustedIncrement(0.1f);
	}

	// disable second texture
	glActiveTexture(GL_TEXTURE0);

	// clean up
	glDepthMask(GL_TRUE);
	pie_DeactivateShader();

	//glBindBuffer(GL_ARRAY_BUFFER, 0);  // HACK Must unbind GL_ARRAY_BUFFER (don't know if it has to be unbound everywhere), otherwise text rendering may mysteriously crash.
}
Ejemplo n.º 4
0
static void drawTerrainLayers(const glm::mat4 &ModelViewProjection, const glm::vec4 &paramsXLight, const glm::vec4 &paramsYLight, const glm::mat4 &textureMatrix)
{
	const auto &renderState = getCurrentRenderState();
	const glm::vec4 fogColor(
		renderState.fogColour.vector[0] / 255.f,
		renderState.fogColour.vector[1] / 255.f,
		renderState.fogColour.vector[2] / 255.f,
		renderState.fogColour.vector[3] / 255.f
	);
	const auto &program = pie_ActivateShader(SHADER_TERRAIN, ModelViewProjection, glm::vec4(0.f), glm::vec4(0.f), paramsXLight, paramsYLight, 0, 1,
		glm::mat4(1.f), textureMatrix, renderState.fogEnabled, renderState.fogBegin, renderState.fogEnd, fogColor);

	// additive blending
	pie_SetRendMode(REND_ADDITIVE);

	// only draw colors
	glDepthMask(GL_FALSE);

	textureIndexVBO->bind();

	// load the vertex (geometry) buffer
	geometryVBO->bind();
	glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, sizeof(RenderVertex), BUFFER_OFFSET(0));
	glEnableVertexAttribArray(program.locVertex);

	textureVBO->bind();

	ASSERT_OR_RETURN(, psGroundTypes, "Ground type was not set, no textures will be seen.");

	// draw each layer separately
	for (int layer = 0; layer < numGroundTypes; layer++)
	{
		const glm::vec4 paramsX(0, 0, -1.0f / world_coord(psGroundTypes[layer].textureSize), 0 );
		const glm::vec4 paramsY(1.0f / world_coord(psGroundTypes[layer].textureSize), 0, 0, 0 );
		pie_ActivateShader(SHADER_TERRAIN, ModelViewProjection, paramsX, paramsY, paramsXLight, paramsYLight, 0, 1, glm::mat4(1.f), textureMatrix,
			renderState.fogEnabled, renderState.fogBegin, renderState.fogEnd, fogColor);

		// load the texture
		int texPage = iV_GetTexture(psGroundTypes[layer].textureName);
		pie_SetTexturePage(texPage);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

		// load the color buffer
		glVertexAttribPointer(program.locColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(PIELIGHT), BUFFER_OFFSET(sizeof(PIELIGHT)*xSectors * ySectors * (sectorSize + 1) * (sectorSize + 1) * 2 * layer));
		glEnableVertexAttribArray(program.locColor);

		for (int x = 0; x < xSectors; x++)
		{
			for (int y = 0; y < ySectors; y++)
			{
				if (sectors[x * ySectors + y].draw)
				{
					addDrawRangeElements(GL_TRIANGLES,
						sectors[x * ySectors + y].geometryOffset,
						sectors[x * ySectors + y].geometryOffset + sectors[x * ySectors + y].geometrySize,
						sectors[x * ySectors + y].textureIndexSize[layer],
						GL_UNSIGNED_INT,
						sectors[x * ySectors + y].textureIndexOffset[layer]);
				}
			}
		}
		finishDrawRangeElements();
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	// we don't need this one anymore
	glDisableVertexAttribArray(program.locVertex);
	glDisableVertexAttribArray(program.locColor);
	pie_DeactivateShader();
}