コード例 #1
0
ファイル: tex.cpp プロジェクト: Zabanya/warzone2100
int pie_AddTexPage(iV_Image *s, const char *filename, bool gameTexture, int page)
{
	ASSERT(s && filename, "Bad input parameter");

	if (page < 0)
	{
		iTexPage tex;
		page = _TEX_PAGE.size();
		glGenTextures(1, &tex.id);
		sstrcpy(tex.name, filename);
		_TEX_PAGE.append(tex);
	}
	else // replace
	{
		sstrcpy(_TEX_PAGE[page].name, filename);

	}
	debug(LOG_TEXTURE, "%s page=%d", filename, page);

	pie_SetTexturePage(page);
	if (GLEW_VERSION_4_3 || GLEW_KHR_debug)
	{
		glObjectLabel(GL_TEXTURE, pie_Texture(page), -1, filename);
	}

	if (gameTexture) // this is a game texture, use texture compression
	{
		gluBuild2DMipmaps(GL_TEXTURE_2D, wz_texture_compression, s->width, s->height, iV_getPixelFormat(s), GL_UNSIGNED_BYTE, s->bmp);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	}
	else	// this is an interface texture, do not use compression
	{
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, s->width, s->height, 0, iV_getPixelFormat(s), GL_UNSIGNED_BYTE, s->bmp);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	}
	// it is uploaded, we do not need it anymore
	free(s->bmp);
	s->bmp = NULL;

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	// Use anisotropic filtering, if available, but only max 4.0 to reduce processor burden
	if (GLEW_EXT_texture_filter_anisotropic)
	{
		GLfloat max;
		glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, MIN(4.0f, max));
	}
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	/* Send back the texpage number so we can store it in the IMD */
	return page;
}
コード例 #2
0
ファイル: piestate.cpp プロジェクト: ik3210/warzone2100
/** Selects a texture page and binds it for the current texture unit
 *  \param num a number indicating the texture page to bind. If this is a
 *         negative value (doesn't matter what value) it will disable texturing.
 */
void pie_SetTexturePage(SDWORD num)
{
	// Only bind textures when they're not bound already
	if (num != rendStates.texPage)
	{
		switch (num)
		{
		case TEXPAGE_NONE:
			glBindTexture(GL_TEXTURE_2D, 0);
			break;
		case TEXPAGE_EXTERN:
			break;
		default:
			glBindTexture(GL_TEXTURE_2D, pie_Texture(num));
		}
		rendStates.texPage = num;
	}
}
コード例 #3
0
ファイル: piestate.cpp プロジェクト: Mailaender/warzone2100
/** Selects a texture page and binds it for the current texture unit
 *  \param num a number indicating the texture page to bind. If this is a
 *         negative value (doesn't matter what value) it will disable texturing.
 */
void pie_SetTexturePage(SDWORD num)
{
	// Only bind textures when they're not bound already
	if (num != rendStates.texPage)
	{
		switch (num)
		{
		case TEXPAGE_NONE:
			glDisable(GL_TEXTURE_2D);
			break;
		case TEXPAGE_EXTERN:
			// GLC will set the texture, we just need to enable texturing
			glEnable(GL_TEXTURE_2D);
			break;
		default:
			if (rendStates.texPage == TEXPAGE_NONE)
			{
				glEnable(GL_TEXTURE_2D);
			}
			glBindTexture(GL_TEXTURE_2D, pie_Texture(num));
		}
		rendStates.texPage = num;
	}
}
コード例 #4
0
ファイル: piestate.cpp プロジェクト: ik3210/warzone2100
pie_internal::SHADER_PROGRAM &pie_ActivateShaderDeprecated(SHADER_MODE shaderMode, const iIMDShape *shape, PIELIGHT teamcolour, PIELIGHT colour, const glm::mat4 &ModelView, const glm::mat4 &Proj,
	const glm::vec4 &sunPos, const glm::vec4 &sceneColor, const glm::vec4 &ambient, const glm::vec4 &diffuse, const glm::vec4 &specular)
{
	int maskpage = shape->tcmaskpage;
	int normalpage = shape->normalpage;
	int specularpage = shape->specularpage;
	pie_internal::SHADER_PROGRAM &program = pie_internal::shaderProgram[shaderMode];

	if (shaderMode != pie_internal::currentShaderMode)
	{
		glUseProgram(program.program);

		// These do not change during our drawing pass
		glUniform1i(program.locations[4], rendStates.fog);
		glUniform1f(program.locations[9], timeState);

		pie_internal::currentShaderMode = shaderMode;
	}
	glUniform4fv(program.locations[0], 1, &pal_PIELIGHTtoVec4(colour)[0]);
	pie_SetTexturePage(shape->texpage);

	glUniform4fv(program.locations[1], 1, &pal_PIELIGHTtoVec4(teamcolour)[0]);
	glUniform1i(program.locations[3], maskpage != iV_TEX_INVALID);

	glUniform1i(program.locations[8], 0);

	glUniformMatrix4fv(program.locations[10], 1, GL_FALSE, glm::value_ptr(ModelView));
	glUniformMatrix4fv(program.locations[11], 1, GL_FALSE, glm::value_ptr(Proj * ModelView));
	glUniformMatrix4fv(program.locations[12], 1, GL_FALSE, glm::value_ptr(glm::transpose(glm::inverse(ModelView))));
	glUniform4fv(program.locations[13], 1, &sunPos[0]);
	glUniform4fv(program.locations[14], 1, &sceneColor[0]);
	glUniform4fv(program.locations[15], 1, &ambient[0]);
	glUniform4fv(program.locations[16], 1, &diffuse[0]);
	glUniform4fv(program.locations[17], 1, &specular[0]);

	glUniform1f(program.locations[18], fogBegin);
	glUniform1f(program.locations[19], fogEnd);

	float color[4] = {
		rendStates.fogColour.vector[0] / 255.f,
		rendStates.fogColour.vector[1] / 255.f,
		rendStates.fogColour.vector[2] / 255.f,
		rendStates.fogColour.vector[3] / 255.f
	};
	glUniform4fv(program.locations[20], 1, color);

	if (program.locations[2] >= 0)
	{
		glUniform1f(program.locations[2], shaderStretch);
	}
	if (program.locations[5] >= 0)
	{
		glUniform1i(program.locations[5], normalpage != iV_TEX_INVALID);
	}
	if (program.locations[6] >= 0)
	{
		glUniform1i(program.locations[6], specularpage != iV_TEX_INVALID);
	}
	if (program.locations[7] >= 0)
	{
		glUniform1i(program.locations[7], ecmState);
	}

	if (maskpage != iV_TEX_INVALID)
	{
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, pie_Texture(maskpage));
	}
	if (normalpage != iV_TEX_INVALID)
	{
		glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_2D, pie_Texture(normalpage));
	}
	if (specularpage != iV_TEX_INVALID)
	{
		glActiveTexture(GL_TEXTURE3);
		glBindTexture(GL_TEXTURE_2D, pie_Texture(specularpage));
	}
	glActiveTexture(GL_TEXTURE0);

	return program;
}
コード例 #5
0
ファイル: terrain.cpp プロジェクト: Warzone2100/warzone2100
/**
 * 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.
}
コード例 #6
0
ファイル: texture.cpp プロジェクト: pcdummy/warzone2100
bool texLoad(const char *fileName)
{
	char fullPath[PATH_MAX], partialPath[PATH_MAX], *buffer;
	unsigned int i, j, k, size;
	int texPage;
	GLint glval;

	firstPage = pie_NumberOfPages();

	ASSERT_OR_RETURN(false, MIPMAP_MAX == TILE_WIDTH && MIPMAP_MAX == TILE_HEIGHT, "Bad tile sizes");

	// store the filename so we can later determine which tileset we are using
	if (tilesetDir)
	{
		free(tilesetDir);
	}
	tilesetDir = strdup(fileName);

	// reset defaults
	mipmap_max = MIPMAP_MAX;
	mipmap_levels = MIPMAP_LEVELS;

	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glval);

	while (glval < mipmap_max * TILES_IN_PAGE_COLUMN)
	{
		mipmap_max /= 2;
		mipmap_levels--;
		debug(LOG_ERROR, "Max supported texture size %dx%d is too low - reducing texture detail to %dx%d.",
		      (int)glval, (int)glval, mipmap_max, mipmap_max);
		ASSERT(mipmap_levels > 0, "Supported texture size %d is too low to load any mipmap levels!",
		       (int)glval);
		if (mipmap_levels == 0)
		{
			exit(1);
		}
	}
	while (maxTextureSize < mipmap_max)
	{
		mipmap_max /= 2;
		mipmap_levels--;
		debug(LOG_TEXTURE, "Downgrading texture quality to %d due to user setting %d", mipmap_max, maxTextureSize);
	}

	/* Get and set radar colours */

	sprintf(fullPath, "%s.radar", fileName);
	if (!loadFile(fullPath, &buffer, &size))
	{
		debug(LOG_FATAL, "texLoad: Could not find radar colours at %s", fullPath);
		abort(); // cannot recover; we could possibly generate a random palette?
	}
	i = 0; // tile
	j = 0; // place in buffer
	do
	{
		unsigned int r, g, b;
		int cnt = 0;

		k = sscanf(buffer + j, "%2x%2x%2x%n", &r, &g, &b, &cnt);
		j += cnt;
		if (k >= 3)
		{
			radarColour(i, r, g, b);
		}
		i++; // next tile
	}
	while (k >= 3 && j + 6 < size);
	free(buffer);

	/* Now load the actual tiles */

	i = mipmap_max; // i is used to keep track of the tile dimensions
	for (j = 0; j < mipmap_levels; j++)
	{
		int xOffset = 0, yOffset = 0; // offsets into the texture atlas
		int xSize = 1;
		int ySize = 1;
		const int xLimit = TILES_IN_PAGE_COLUMN * i;
		const int yLimit = TILES_IN_PAGE_ROW * i;

		// pad width and height into ^2 values
		while (xLimit > (xSize *= 2)) {}
		while (yLimit > (ySize *= 2)) {}

		// Generate the empty texture buffer in VRAM
		texPage = newPage(fileName, j, xSize, ySize, 0);

		sprintf(partialPath, "%s-%d", fileName, i);

		// Load until we cannot find anymore of them
		for (k = 0; k < MAX_TILES; k++)
		{
			iV_Image tile;

			snprintf(fullPath, sizeof(fullPath), "%s/tile-%02d.png", partialPath, k);
			if (PHYSFS_exists(fullPath)) // avoid dire warning
			{
				bool retval = iV_loadImage_PNG(fullPath, &tile);
				ASSERT_OR_RETURN(false, retval, "Could not load %s!", fullPath);
			}
			else
			{
				// no more textures in this set
				ASSERT_OR_RETURN(false, k > 0, "Could not find %s", fullPath);
				break;
			}
			// Insert into texture page
			pie_Texture(texPage).upload(j, xOffset, yOffset, tile.width, tile.height, gfx_api::pixel_format::rgba, tile.bmp);
			free(tile.bmp);
			if (i == mipmap_max) // dealing with main texture page; so register coordinates
			{
				tileTexInfo[k].uOffset = (float)xOffset / (float)xSize;
				tileTexInfo[k].vOffset = (float)yOffset / (float)ySize;
				tileTexInfo[k].texPage = texPage;
				debug(LOG_TEXTURE, "  texLoad: Registering k=%d i=%d u=%f v=%f xoff=%d yoff=%d xsize=%d ysize=%d tex=%d (%s)",
				      k, i, tileTexInfo[k].uOffset, tileTexInfo[k].vOffset, xOffset, yOffset, xSize, ySize, texPage, fullPath);
			}
			xOffset += i; // i is width of tile
			if (xOffset + i > xLimit)
			{
				yOffset += i; // i is also height of tile
				xOffset = 0;
			}
			if (yOffset + i > yLimit)
			{
				/* Change to next texture page */
				xOffset = 0;
				yOffset = 0;
				debug(LOG_TEXTURE, "texLoad: Extra page added at %d for %s, was page %d, opengl id %u",
				      k, partialPath, texPage, (unsigned)pie_Texture(texPage).id());
				texPage = newPage(fileName, j, xSize, ySize, k);
			}
		}
		debug(LOG_TEXTURE, "texLoad: Found %d textures for %s mipmap level %d, added to page %d, opengl id %u",
		      k, partialPath, i, texPage, (unsigned)pie_Texture(texPage).id());
		i /= 2;	// halve the dimensions for the next series; OpenGL mipmaps start with largest at level zero
	}
	return true;
}
コード例 #7
0
ファイル: piestate.cpp プロジェクト: Mailaender/warzone2100
void pie_ActivateShader(int shaderMode, const iIMDShape *shape, PIELIGHT teamcolour, PIELIGHT colour)
{
	int maskpage = shape->tcmaskpage;
	int normalpage = shape->normalpage;
	int specularpage = shape->specularpage;
	GLfloat colour4f[4];
	SHADER_PROGRAM program = shaderProgram[shaderMode];

	if (shaderMode != currentShaderMode)
	{
		glUseProgram(program.program);

		// These do not change during our drawing pass
		glUniform1i(program.locFog, rendStates.fog);
		glUniform1f(program.locTime, timeState);

		currentShaderMode = shaderMode;
	}

	glColor4ubv(colour.vector);
	pie_SetTexturePage(shape->texpage);

	pal_PIELIGHTtoRGBA4f(&colour4f[0], teamcolour);
	glUniform4fv(program.locTeam, 1, &colour4f[0]);
	glUniform1i(program.locTCMask, maskpage != iV_TEX_INVALID);
	if (program.locStretch >= 0)
	{
		glUniform1f(program.locStretch, shaderStretch);
	}
	if (program.locNormalMap >= 0)
	{
		glUniform1i(program.locNormalMap, normalpage != iV_TEX_INVALID);
	}
	if (program.locSpecularMap >= 0)
	{
		glUniform1i(program.locSpecularMap, specularpage != iV_TEX_INVALID);
	}
	if (program.locEcm >= 0)
	{
		glUniform1i(program.locEcm, ecmState);
	}

	if (maskpage != iV_TEX_INVALID)
	{
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, pie_Texture(maskpage));
	}
	if (normalpage != iV_TEX_INVALID)
	{
		glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_2D, pie_Texture(normalpage));
	}
	if (specularpage != iV_TEX_INVALID)
	{
		glActiveTexture(GL_TEXTURE3);
		glBindTexture(GL_TEXTURE_2D, pie_Texture(specularpage));
	}
	glActiveTexture(GL_TEXTURE0);

#ifdef _DEBUG
	glErrors();
#endif
}