Beispiel #1
0
void pie_RemainingPasses(void)
{
    GL_DEBUG("Remaining passes - shadows");
    // Draw shadows
    if (shadows)
    {
        pie_DrawShadows();
    }
    // Draw models
    // TODO, sort list to reduce state changes
    GL_DEBUG("Remaining passes - opaque models");
    for (SHAPE const &shape : shapes)
    {
        pie_SetShaderStretchDepth(shape.stretch);
        pie_Draw3DShape2(shape.shape, shape.frame, shape.colour, shape.teamcolour, shape.flag, shape.flag_data, shape.matrix);
    }
    // Draw translucent models last
    // TODO, sort list by Z order to do translucency correctly
    GL_DEBUG("Remaining passes - translucent models");
    for (SHAPE const &shape : tshapes)
    {
        pie_SetShaderStretchDepth(shape.stretch);
        pie_Draw3DShape2(shape.shape, shape.frame, shape.colour, shape.teamcolour, shape.flag, shape.flag_data, shape.matrix);
    }
    pie_SetShaderStretchDepth(0);
    pie_DeactivateShader();
    tshapes.clear();
    shapes.clear();
    GL_DEBUG("Remaining passes - done");
}
Beispiel #2
0
static void pie_Draw3DButton(iIMDShape *shape)
{
	const PIELIGHT colour = WZCOL_WHITE;
	const PIELIGHT teamcolour = pal_GetTeamColour(NetPlay.players[selectedPlayer].colour);
	pie_SetFogStatus(false);
	pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON);
	pie_ActivateShader(SHADER_BUTTON, shape, teamcolour, colour);
	pie_SetRendMode(REND_OPAQUE);
	glColor4ubv(colour.vector);     // Only need to set once for entire model
	pie_SetTexturePage(shape->texpage);
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_VERTEX]); glVertexPointer(3, GL_FLOAT, 0, NULL);
	glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_NORMAL]); glNormalPointer(GL_FLOAT, 0, NULL);
	glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_TEXCOORD]); glTexCoordPointer(2, GL_FLOAT, 0, NULL);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->buffers[VBO_INDEX]);
	glDrawElements(GL_TRIANGLES, shape->npolys * 3, GL_UNSIGNED_SHORT, NULL);
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	polyCount += shape->npolys;
	pie_DeactivateShader();
	pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON);
}
Beispiel #3
0
static void drawDecals(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_DECALS, ModelViewProjection, paramsXLight, paramsYLight, 0, 1, textureMatrix,
		renderState.fogEnabled, renderState.fogBegin, renderState.fogEnd, fogColor);
	// select the terrain texture page
	pie_SetTexturePage(terrainPage);

	// use the alpha to blend
	pie_SetRendMode(REND_ALPHA);

	// and the texture coordinates buffer
	decalVBO->bind();
	glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, sizeof(DecalVertex), BUFFER_OFFSET(0));
	glEnableVertexAttribArray(program.locVertex);

	glVertexAttribPointer(program.locTexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(DecalVertex), BUFFER_OFFSET(12));
	glEnableVertexAttribArray(program.locTexCoord);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	int size = 0;
	int offset = 0;
	for (int x = 0; x < xSectors; x++)
	{
		for (int y = 0; y < ySectors + 1; y++)
		{
			if (y < ySectors && offset + size == sectors[x * ySectors + y].decalOffset && sectors[x * ySectors + y].draw)
			{
				// append
				size += sectors[x * ySectors + y].decalSize;
				continue;
			}
			// can't append, so draw what we have and start anew
			if (size > 0)
			{
				glDrawArrays(GL_TRIANGLES, offset, size);
			}
			size = 0;
			if (y < ySectors && sectors[x * ySectors + y].draw)
			{
				offset = sectors[x * ySectors + y].decalOffset;
				size = sectors[x * ySectors + y].decalSize;
			}
		}
	}

	glDepthMask(GL_TRUE);
	glDisableVertexAttribArray(program.locTexCoord);
	glDisableVertexAttribArray(program.locVertex);
	pie_DeactivateShader();
}
Beispiel #4
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();
}
Beispiel #5
0
static void pie_Draw3DButton(iIMDShape *shape, PIELIGHT teamcolour)
{
	const PIELIGHT colour = WZCOL_WHITE;
	pie_SetFogStatus(false);
	pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON);
	SHADER_PROGRAM &program = pie_ActivateShader(SHADER_BUTTON, shape, teamcolour, colour);
	pie_SetRendMode(REND_OPAQUE);
	pie_SetTexturePage(shape->texpage);
	enableArray(shape->buffers[VBO_VERTEX], program.locVertex, 3, GL_FLOAT, false, 0, 0);
	enableArray(shape->buffers[VBO_NORMAL], program.locNormal, 3, GL_FLOAT, false, 0, 0);
	enableArray(shape->buffers[VBO_TEXCOORD], program.locTexCoord, 2, GL_FLOAT, false, 0, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->buffers[VBO_INDEX]);
	glDrawElements(GL_TRIANGLES, shape->npolys * 3, GL_UNSIGNED_SHORT, NULL);
	disableArrays();
	polyCount += shape->npolys;
	pie_DeactivateShader();
	pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON);
}
Beispiel #6
0
void pie_RemainingPasses(void)
{
	GL_DEBUG("Remaining passes - shadows");
	glEnable(GL_LIGHT0);
	// Draw shadows
	if (shadows)
	{
		pie_DrawShadows();
	}
	// Draw models
	// TODO, sort list to reduce state changes
	GL_DEBUG("Remaining passes - opaque models");
	glPushMatrix();
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	for (unsigned i = 0; i < shapes.size(); ++i)
	{
		pie_Draw3DShape2(shapes[i].shape, shapes[i].frame, shapes[i].colour, shapes[i].teamcolour, shapes[i].flag, shapes[i].flag_data, shapes[i].matrix);
	}
	// Draw translucent models last
	// TODO, sort list by Z order to do translucency correctly
	GL_DEBUG("Remaining passes - translucent models");
	for (unsigned i = 0; i < tshapes.size(); ++i)
	{
		pie_Draw3DShape2(tshapes[i].shape, tshapes[i].frame, tshapes[i].colour, tshapes[i].teamcolour, tshapes[i].flag, tshapes[i].flag_data, tshapes[i].matrix);
	}
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisable(GL_LIGHT0);
	pie_DeactivateShader();
	glPopMatrix();
	tshapes.resize(0);
	shapes.resize(0);
	GL_DEBUG("Remaining passes - done");
}
Beispiel #7
0
static void pie_Draw3DShape2(const iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, int pieFlag, int pieFlagData, glm::mat4 &matrix)
{
	bool light = true;

	glLoadMatrixf(&matrix[0][0]);

	/* Set fog status */
	if (!(pieFlag & pie_FORCE_FOG) && (pieFlag & pie_ADDITIVE || pieFlag & pie_TRANSLUCENT || pieFlag & pie_PREMULTIPLIED))
	{
		pie_SetFogStatus(false);
	}
	else
	{
		pie_SetFogStatus(true);
	}

	/* Set tranlucency */
	if (pieFlag & pie_ADDITIVE)
	{
		pie_SetRendMode(REND_ADDITIVE);
		colour.byte.a = (UBYTE)pieFlagData;
		light = false;
	}
	else if (pieFlag & pie_TRANSLUCENT)
	{
		pie_SetRendMode(REND_ALPHA);
		colour.byte.a = (UBYTE)pieFlagData;
		light = false;
	}
	else if (pieFlag & pie_PREMULTIPLIED)
	{
		pie_SetRendMode(REND_PREMULTIPLIED);
		light = false;
	}
	else
	{
		pie_SetRendMode(REND_OPAQUE);
	}

	if ((pieFlag & pie_PREMULTIPLIED) == 0)
	{
		glEnable(GL_ALPHA_TEST);
		glAlphaFunc(GL_GREATER, 0.001f);
	}

	if (pieFlag & pie_ECM)
	{
		pie_SetRendMode(REND_ALPHA);
		light = true;
		pie_SetShaderEcmEffect(true);
	}

	if (light)
	{
		if (shape->shaderProgram)
		{
			pie_ActivateShader(shape->shaderProgram, shape, teamcolour, colour);
		}
		else
		{
			pie_ActivateShader(SHADER_COMPONENT, shape, teamcolour, colour);
		}
	}
	else
	{
		pie_DeactivateShader();
	}

	glColor4ubv(colour.vector);     // Only need to set once for entire model
	pie_SetTexturePage(shape->texpage);

	frame %= MAX(1, shape->numFrames);

	glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_VERTEX]); glVertexPointer(3, GL_FLOAT, 0, NULL);
	glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_NORMAL]); glNormalPointer(GL_FLOAT, 0, NULL);
	glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_TEXCOORD]); glTexCoordPointer(2, GL_FLOAT, 0, NULL);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->buffers[VBO_INDEX]);
	glDrawElements(GL_TRIANGLES, shape->npolys * 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(frame * shape->npolys * 3 * sizeof(uint16_t)));

	polyCount += shape->npolys;

	pie_SetShaderEcmEffect(false);
	glDisable(GL_ALPHA_TEST);
}
Beispiel #8
0
static void pie_Draw3DShape2(iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, int pieFlag, int pieFlagData)
{
	iIMDPoly *pPolys;
	bool light = true;
	bool shaders = pie_GetShaderUsage();

	pie_SetAlphaTest((pieFlag & pie_PREMULTIPLIED) == 0);

	/* Set fog status */
	if (!(pieFlag & pie_FORCE_FOG) && 
		(pieFlag & pie_ADDITIVE || pieFlag & pie_TRANSLUCENT || pieFlag & pie_BUTTON || pieFlag & pie_PREMULTIPLIED))
	{
		pie_SetFogStatus(false);
	}
	else
	{
		pie_SetFogStatus(true);
	}

	/* Set tranlucency */
	if (pieFlag & pie_ADDITIVE)
	{
		pie_SetRendMode(REND_ADDITIVE);
		colour.byte.a = (UBYTE)pieFlagData;
		light = false;
	}
	else if (pieFlag & pie_TRANSLUCENT)
	{
		pie_SetRendMode(REND_ALPHA);
		colour.byte.a = (UBYTE)pieFlagData;
		light = false;
	}
	else if (pieFlag & pie_PREMULTIPLIED)
	{
		pie_SetRendMode(REND_PREMULTIPLIED);
		light = false;
	}
	else
	{
		if (pieFlag & pie_BUTTON)
		{
			pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON);
			light = false;
			if (shaders)
			{
				pie_ActivateShader(SHADER_BUTTON, shape, teamcolour, colour);
			}
			else
			{
				pie_ActivateFallback(SHADER_BUTTON, shape, teamcolour, colour);
			}
		}
		pie_SetRendMode(REND_OPAQUE);
	}
	if (pieFlag & pie_ECM)
	{
		pie_SetRendMode(REND_ALPHA);
		light = true;
		pie_SetShaderEcmEffect(true);
	}

	if (light)
	{
		glMaterialfv(GL_FRONT, GL_AMBIENT, shape->material[LIGHT_AMBIENT]);
		glMaterialfv(GL_FRONT, GL_DIFFUSE, shape->material[LIGHT_DIFFUSE]);
		glMaterialfv(GL_FRONT, GL_SPECULAR, shape->material[LIGHT_SPECULAR]);
		glMaterialf(GL_FRONT, GL_SHININESS, shape->shininess);
		glMaterialfv(GL_FRONT, GL_EMISSION, shape->material[LIGHT_EMISSIVE]);
		if (shaders)
		{
			pie_ActivateShader(SHADER_COMPONENT, shape, teamcolour, colour);
		}
		else
		{
			pie_ActivateFallback(SHADER_COMPONENT, shape, teamcolour, colour);
		}
	}

	if (pieFlag & pie_HEIGHT_SCALED)	// construct
	{
		glScalef(1.0f, (float)pieFlagData / (float)pie_RAISE_SCALE, 1.0f);
	}
	if (pieFlag & pie_RAISE)		// collapse
	{
		glTranslatef(1.0f, (-shape->max.y * (pie_RAISE_SCALE - pieFlagData)) * (1.0f / pie_RAISE_SCALE), 1.0f);
	}

	glColor4ubv(colour.vector);     // Only need to set once for entire model
	pie_SetTexturePage(shape->texpage);

	frame %= MAX(1, shape->numFrames);

	glBegin(GL_TRIANGLES);
	for (pPolys = shape->polys; pPolys < shape->polys + shape->npolys; pPolys++)
	{
		Vector3f	vertexCoords[3];
		unsigned int	n, frameidx = frame;
		int	*index;

		if (!(pPolys->flags & iV_IMD_TEXANIM))
		{
			frameidx = 0;
		}

		for (n = 0, index = pPolys->pindex;
				n < pPolys->npnts;
				n++, index++)
		{
			vertexCoords[n].x = shape->points[*index].x;
			vertexCoords[n].y = shape->points[*index].y;
			vertexCoords[n].z = shape->points[*index].z;
		}

		polyCount++;

		glNormal3fv((GLfloat*)&pPolys->normal);
		for (n = 0; n < pPolys->npnts; n++)
		{
			GLfloat* texCoord = (GLfloat*)&pPolys->texCoord[frameidx * pPolys->npnts + n];
			glTexCoord2fv(texCoord);
			if (!shaders)
			{
				glMultiTexCoord2fv(GL_TEXTURE1, texCoord);
			}
			glVertex3fv((GLfloat*)&vertexCoords[n]);
		}
	}
	glEnd();

	if (light || (pieFlag & pie_BUTTON))
	{
		if (shaders)
		{
			pie_DeactivateShader();
		}
		else
		{
			pie_DeactivateFallback();
		}
	}
	pie_SetShaderEcmEffect(false);

	if (pieFlag & pie_BUTTON)
	{
		pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON);
	}
}
Beispiel #9
0
static void pie_Draw3DShape2(iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, WZ_DECL_UNUSED PIELIGHT specular, int pieFlag, int pieFlagData)
{
	iIMDPoly *pPolys;
	bool light = lighting;

	pie_SetAlphaTest(true);

	/* Set fog status */
	if (!(pieFlag & pie_FORCE_FOG) && 
		(pieFlag & pie_ADDITIVE || pieFlag & pie_TRANSLUCENT || pieFlag & pie_BUTTON))
	{
		pie_SetFogStatus(false);
	}
	else
	{
		pie_SetFogStatus(true);
	}

	/* Set tranlucency */
	if (pieFlag & pie_ADDITIVE)
	{
		pie_SetRendMode(REND_ADDITIVE);
		colour.byte.a = (UBYTE)pieFlagData;
		light = false;
	}
	else if (pieFlag & pie_TRANSLUCENT)
	{
		pie_SetRendMode(REND_ALPHA);
		colour.byte.a = (UBYTE)pieFlagData;
		light = false;
	}
	else
	{
		if (pieFlag & pie_BUTTON)
		{
			pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON);
		}
		pie_SetRendMode(REND_OPAQUE);
	}

	if (light)
	{
		const float ambient[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
		const float diffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
		const float specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
		const float shininess = 10;

		glEnable(GL_LIGHTING);
		glEnable(GL_NORMALIZE);

		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
	}

	if (pieFlag & pie_HEIGHT_SCALED)	// construct
	{
		glScalef(1.0f, (float)pieFlagData / (float)pie_RAISE_SCALE, 1.0f);
	}
	if (pieFlag & pie_RAISE)		// collapse
	{
		glTranslatef(1.0f, (-shape->max.y * (pie_RAISE_SCALE - pieFlagData)) / pie_RAISE_SCALE, 1.0f);
	}

	glColor4ubv(colour.vector);	// Only need to set once for entire model
	pie_SetTexturePage(shape->texpage);

	// Activate TCMask if needed
	if (shape->flags & iV_IMD_TCMASK &&	rendStates.rendMode == REND_OPAQUE)
	{
#ifdef _DEBUG
	glErrors();
#endif
		if (pie_GetShadersStatus())
		{
			pie_ActivateShader_TCMask(teamcolour, shape->tcmaskpage);
		}
		else
		{
			//Set the environment colour with tcmask
			GLfloat tc_env_colour[4];  
			pal_PIELIGHTtoRGBA4f(&tc_env_colour[0], teamcolour);

			// TU0
			glActiveTexture(GL_TEXTURE0);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,	GL_COMBINE);
			glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, tc_env_colour);

			// TU0 RGB
			glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,		GL_ADD_SIGNED);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB,		GL_TEXTURE);
			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,		GL_SRC_COLOR);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB,		GL_CONSTANT);
			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,		GL_SRC_COLOR);

			// TU0 Alpha
			glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,		GL_REPLACE);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,		GL_TEXTURE);
			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,	GL_SRC_ALPHA);

			// TU1
			glActiveTexture(GL_TEXTURE1);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, _TEX_PAGE[shape->tcmaskpage].id);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,	GL_COMBINE);

			// TU1 RGB
			glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,		GL_INTERPOLATE);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB,		GL_PREVIOUS);
			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,		GL_SRC_COLOR);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB,		GL_TEXTURE0);
			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,		GL_SRC_COLOR);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB,		GL_TEXTURE);
			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,		GL_SRC_ALPHA);

			// TU1 Alpha
			glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,		GL_REPLACE);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,		GL_PREVIOUS);
			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,	GL_SRC_ALPHA);


			// This is why we are doing in opaque mode.
			glEnable(GL_BLEND);
			glBlendFunc(GL_CONSTANT_COLOR, GL_ZERO);
			glBlendColor(colour.byte.r / 255.0, colour.byte.g / 255.0,
						colour.byte.b / 255.0, colour.byte.a / 255.0);
		}
#ifdef _DEBUG
	glErrors();
#endif
	}

	for (pPolys = shape->polys; pPolys < shape->polys + shape->npolys; pPolys++)
	{
		Vector2f	texCoords[pie_MAX_VERTICES_PER_POLYGON];
		Vector3f	vertexCoords[pie_MAX_VERTICES_PER_POLYGON];
		unsigned int n;
		VERTEXID	*index;

		for (n = 0, index = pPolys->pindex;
				n < pPolys->npnts;
				n++, index++)
		{
			vertexCoords[n].x = shape->points[*index].x;
			vertexCoords[n].y = shape->points[*index].y;
			vertexCoords[n].z = shape->points[*index].z;
			texCoords[n].x = pPolys->texCoord[n].x;
			texCoords[n].y = pPolys->texCoord[n].y;
		}

		polyCount++;

		// Run TextureAnimation (exluding the new teamcoloured models)
		if (frame && pPolys->flags & iV_IMD_TEXANIM && !(shape->flags & iV_IMD_TCMASK))
		{
			frame %= shape->numFrames;

			if (frame > 0)
			{
				const int framesPerLine = OLD_TEXTURE_SIZE_FIX / (pPolys->texAnim.x * OLD_TEXTURE_SIZE_FIX);
				const int uFrame = (frame % framesPerLine) * (pPolys->texAnim.x * OLD_TEXTURE_SIZE_FIX);
				const int vFrame = (frame / framesPerLine) * (pPolys->texAnim.y * OLD_TEXTURE_SIZE_FIX);

				for (n = 0; n < pPolys->npnts; n++)
				{
					texCoords[n].x += uFrame / OLD_TEXTURE_SIZE_FIX;
					texCoords[n].y += vFrame / OLD_TEXTURE_SIZE_FIX;
				}
			}
		}

		glBegin(GL_TRIANGLE_FAN);

		if (light)
		{
			glNormal3fv((GLfloat*)&pPolys->normal);
		}

		for (n = 0; n < pPolys->npnts; n++)
		{
			glTexCoord2fv((GLfloat*)&texCoords[n]);
			if (shape->flags & iV_IMD_TCMASK && rendStates.rendMode == REND_OPAQUE &&
				!pie_GetShadersStatus())
			{
				glMultiTexCoord2fv(GL_TEXTURE1, (GLfloat*)&texCoords[n]);
			}
			glVertex3fv((GLfloat*)&vertexCoords[n]);
		}

		glEnd();
	}

	// Deactivate TCMask if it was previously enabled
	if (shape->flags & iV_IMD_TCMASK && rendStates.rendMode == REND_OPAQUE)
	{
		if (pie_GetShadersStatus())
		{
			pie_DeactivateShader();
		}
		else
		{
			glDisable(GL_BLEND);

			glActiveTexture(GL_TEXTURE1);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			glDisable(GL_TEXTURE_2D);

			glActiveTexture(GL_TEXTURE0);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		}
	}

	if (pieFlag & pie_BUTTON)
	{
		pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON);
	}

	if (light)
	{
		glDisable(GL_LIGHTING);
		glDisable(GL_NORMALIZE);
	}
}
Beispiel #10
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.
}
Beispiel #11
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();
}
Beispiel #12
0
/// Draw the shadow for a shape
static void pie_DrawShadow(iIMDShape *shape, int flag, int flag_data, const glm::vec4 &light, const glm::mat4 &modelViewMatrix)
{
    static std::vector<EDGE> edgelist;  // Static, to save allocations.
    static std::vector<EDGE> edgelistFlipped;  // Static, to save allocations.
    static std::vector<EDGE> edgelistFiltered;  // Static, to save allocations.
    EDGE *drawlist = NULL;

    unsigned edge_count;
    Vector3f *pVertices = shape->points;
    if (flag & pie_STATIC_SHADOW && shape->shadowEdgeList)
    {
        drawlist = shape->shadowEdgeList;
        edge_count = shape->nShadowEdges;
    }
    else
    {
        edgelist.clear();
        iIMDPoly *end = shape->polys + shape->npolys;
        for (iIMDPoly *pPolys = shape->polys; pPolys != end; ++pPolys)
        {
            glm::vec3 p[3];
            for (int j = 0; j < 3; ++j)
            {
                int current = pPolys->pindex[j];
                p[j] = glm::vec3(pVertices[current].x, scale_y(pVertices[current].y, flag, flag_data), pVertices[current].z);
            }
            if (glm::dot(glm::cross(p[2] - p[0], p[1] - p[0]), glm::vec3(light)) > 0.0f)
            {
                for (int n = 0; n < 3; ++n)
                {
                    // Add the edges
                    edgelist.push_back({pPolys->pindex[n], pPolys->pindex[(n + 1)%3]});
                }
            }
        }

        // Remove duplicate pairs from the edge list. For example, in the list ((1 2), (2 6), (6 2), (3, 4)), remove (2 6) and (6 2).
        edgelistFlipped = edgelist;
        std::for_each(edgelistFlipped.begin(), edgelistFlipped.end(), flipEdge);
        std::sort(edgelist.begin(), edgelist.end(), edgeLessThan);
        std::sort(edgelistFlipped.begin(), edgelistFlipped.end(), edgeLessThan);
        edgelistFiltered.resize(edgelist.size());
        edgelistFiltered.erase(std::set_difference(edgelist.begin(), edgelist.end(), edgelistFlipped.begin(), edgelistFlipped.end(), edgelistFiltered.begin(), edgeLessThan), edgelistFiltered.end());

        drawlist = &edgelistFiltered[0];
        edge_count = edgelistFiltered.size();
        //debug(LOG_WARNING, "we have %i edges", edge_count);

        if (flag & pie_STATIC_SHADOW)
        {
            // then store it in the imd
            shape->nShadowEdges = edge_count;
            shape->shadowEdgeList = (EDGE *)realloc(shape->shadowEdgeList, sizeof(EDGE) * shape->nShadowEdges);
            std::copy(drawlist, drawlist + edge_count, shape->shadowEdgeList);
        }
    }

    std::vector<Vector3f> vertexes;
    for (unsigned i = 0; i < edge_count; i++)
    {
        int a = drawlist[i].from, b = drawlist[i].to;

        glm::vec3 v1(pVertices[b].x, scale_y(pVertices[b].y, flag, flag_data), pVertices[b].z);
        glm::vec3 v2(pVertices[b].x + light[0], scale_y(pVertices[b].y, flag, flag_data) + light[1], pVertices[b].z + light[2]);
        glm::vec3 v3(pVertices[a].x + light[0], scale_y(pVertices[a].y, flag, flag_data) + light[1], pVertices[a].z + light[2]);
        glm::vec3 v4(pVertices[a].x, scale_y(pVertices[a].y, flag, flag_data), pVertices[a].z);

        vertexes.push_back(v1);
        vertexes.push_back(v2);
        vertexes.push_back(v3);

        vertexes.push_back(v3);
        vertexes.push_back(v4);
        vertexes.push_back(v1);
    }

    // draw the shadow volume
    const auto &program = pie_ActivateShader(SHADER_GENERIC_COLOR, pie_PerspectiveGet() * modelViewMatrix, glm::vec4());
    static glBufferWrapper buffer;
    glBindBuffer(GL_ARRAY_BUFFER, buffer.id);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3f) * vertexes.size(), vertexes.data(), GL_STREAM_DRAW);
    glEnableVertexAttribArray(program.locVertex);
    glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    glDrawArrays(GL_TRIANGLES, 0, edge_count * 2 * 3);
    glDisableVertexAttribArray(program.locVertex);
    pie_DeactivateShader();
}
Beispiel #13
0
static void pie_Draw3DShape2(const iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, int pieFlag, int pieFlagData, glm::mat4 const &matrix)
{
    bool light = true;

    /* Set fog status */
    if (!(pieFlag & pie_FORCE_FOG) && (pieFlag & pie_ADDITIVE || pieFlag & pie_TRANSLUCENT || pieFlag & pie_PREMULTIPLIED))
    {
        pie_SetFogStatus(false);
    }
    else
    {
        pie_SetFogStatus(true);
    }

    /* Set tranlucency */
    if (pieFlag & pie_ADDITIVE)
    {
        pie_SetRendMode(REND_ADDITIVE);
        colour.byte.a = (UBYTE)pieFlagData;
        light = false;
    }
    else if (pieFlag & pie_TRANSLUCENT)
    {
        pie_SetRendMode(REND_ALPHA);
        colour.byte.a = (UBYTE)pieFlagData;
        light = false;
    }
    else if (pieFlag & pie_PREMULTIPLIED)
    {
        pie_SetRendMode(REND_PREMULTIPLIED);
        light = false;
    }
    else
    {
        pie_SetRendMode(REND_OPAQUE);
    }

    if (pieFlag & pie_ECM)
    {
        pie_SetRendMode(REND_ALPHA);
        light = true;
        pie_SetShaderEcmEffect(true);
    }

    glm::vec4 sceneColor(lighting0[LIGHT_EMISSIVE][0], lighting0[LIGHT_EMISSIVE][1], lighting0[LIGHT_EMISSIVE][2], lighting0[LIGHT_EMISSIVE][3]);
    glm::vec4 ambient(lighting0[LIGHT_AMBIENT][0], lighting0[LIGHT_AMBIENT][1], lighting0[LIGHT_AMBIENT][2], lighting0[LIGHT_AMBIENT][3]);
    glm::vec4 diffuse(lighting0[LIGHT_DIFFUSE][0], lighting0[LIGHT_DIFFUSE][1], lighting0[LIGHT_DIFFUSE][2], lighting0[LIGHT_DIFFUSE][3]);
    glm::vec4 specular(lighting0[LIGHT_SPECULAR][0], lighting0[LIGHT_SPECULAR][1], lighting0[LIGHT_SPECULAR][2], lighting0[LIGHT_SPECULAR][3]);

    SHADER_MODE mode = shape->shaderProgram == SHADER_NONE ? light ? SHADER_COMPONENT : SHADER_NOLIGHT : shape->shaderProgram;
    pie_internal::SHADER_PROGRAM &program = pie_ActivateShaderDeprecated(mode, shape, teamcolour, colour, matrix, pie_PerspectiveGet(),
                                            glm::vec4(currentSunPosition, 0.f), sceneColor, ambient, diffuse, specular);

    if (program.locations.size() >= 9)
        glUniform1i(program.locations[8], (pieFlag & pie_PREMULTIPLIED) == 0);

    pie_SetTexturePage(shape->texpage);

    frame %= std::max<int>(1, shape->numFrames);

    enableArray(shape->buffers[VBO_VERTEX], program.locVertex, 3, GL_FLOAT, false, 0, 0);
    enableArray(shape->buffers[VBO_NORMAL], program.locNormal, 3, GL_FLOAT, false, 0, 0);
    enableArray(shape->buffers[VBO_TEXCOORD], program.locTexCoord, 2, GL_FLOAT, false, 0, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->buffers[VBO_INDEX]);
    glDrawElements(GL_TRIANGLES, shape->npolys * 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(frame * shape->npolys * 3 * sizeof(uint16_t)));
    disableArrays();

    polyCount += shape->npolys;

    pie_SetShaderEcmEffect(false);
    pie_DeactivateShader();
}