Esempio n. 1
0
bool TEXTURE::Load(const std::string & path, const TEXTUREINFO & info, std::ostream & error)
{
	if (id)
	{
		error << "Tried to double load texture " << path << std::endl;
		return false;
	}

	if (path.empty() && !info.data)
	{
		error << "Tried to load a texture with an empty name" << std::endl;
		return false;
	}

	id = 0;
	cube = info.cube;
	if (info.cube && info.verticalcross)
	{
		return LoadCubeVerticalCross(path, info, error);
	}
	else if (info.cube)
	{
		return LoadCube(path, info, error);
	}

	SDL_Surface * orig_surface = 0;
	if (info.data)
	{
		Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
		rmask = 0xff000000;
		gmask = 0x00ff0000;
		bmask = 0x0000ff00;
		amask = 0x000000ff;
#else
		rmask = 0x000000ff;
		gmask = 0x0000ff00;
		bmask = 0x00ff0000;
		amask = 0xff000000;
#endif
		orig_surface = SDL_CreateRGBSurfaceFrom(
							info.data, info.width, info.height,
							info.bytespp * 8, info.width * info.bytespp,
							rmask, gmask, bmask, amask);
	}
	if (!orig_surface)
	{
		orig_surface = IMG_Load(path.c_str());
		if (!orig_surface)
		{
			error << "Error loading texture file: " << path << std::endl;
			return false;
		}
	}

	SDL_Surface * texture_surface = orig_surface;
	if (orig_surface)
	{
	    origw = texture_surface->w;
        origh = texture_surface->h;

		//scale to power of two if necessary
		bool norescale = (IsPowerOfTwo(orig_surface->w) && IsPowerOfTwo(orig_surface->h)) ||
					(info.npot && (GLEW_VERSION_2_0 || GLEW_ARB_texture_non_power_of_two));
		if (!norescale)
	    {
			int maxsize = 2048;
	        int newx = GetPowerOfTwo(orig_surface->w, maxsize);
	        int newy = GetPowerOfTwo(orig_surface->h, maxsize);
	        float scalew = ((float)newx+0.5) / orig_surface->w;
	        float scaleh = ((float)newy+0.5) / orig_surface->h;

	        SDL_Surface * pot_surface = zoomSurface(orig_surface, scalew, scaleh, SMOOTHING_ON);

	        assert(IsPowerOfTwo(pot_surface->w));
	        assert(IsPowerOfTwo(pot_surface->h));

	        SDL_FreeSurface(orig_surface);
	        orig_surface = pot_surface;
	        texture_surface = orig_surface;
	    }

		//scale texture down if necessary
		scale = Scale(info.maxsize, orig_surface->w, orig_surface->h);
		if (scale < 1.0)
		{
			texture_surface = zoomSurface(orig_surface, scale, scale, SMOOTHING_ON);
		}

		//store dimensions
		w = texture_surface->w;
		h = texture_surface->h;

		GenTexture(texture_surface, info, id, alpha, error);
	}

	//free the texture surface separately if it's a scaled copy of the original
	if (texture_surface != orig_surface && texture_surface)
	{
		SDL_FreeSurface(texture_surface);
	}

	//free the original surface if it's not a custom surface (used for the track map)
	if (!info.data && orig_surface)
	{
		SDL_FreeSurface(orig_surface);
	}

	return true;
}
Esempio n. 2
0
bool Texture::LoadCube(const std::string & path, const TextureInfo & info, std::ostream & error)
{
	if (info.verticalcross)
	{
		return LoadCubeVerticalCross(path, info, error);
	}

	std::string cubefiles[6];
	cubefiles[0] = path+"-xp.png";
	cubefiles[1] = path+"-xn.png";
	cubefiles[2] = path+"-yn.png";
	cubefiles[3] = path+"-yp.png";
	cubefiles[4] = path+"-zn.png";
	cubefiles[5] = path+"-zp.png";

	unsigned id = 0;
	glGenTextures(1, &id);
	CheckForOpenGLErrors("Cubemap texture ID generation", error);
	glBindTexture(GL_TEXTURE_CUBE_MAP, id);
	m_id = id;

	for (int i = 0; i < 6; ++i)
	{
		SDL_Surface * surface = IMG_Load(cubefiles[i].c_str());
		if (!surface)
		{
			error << "Error loading texture file: " + path + " (" + cubefiles[i] + ")" << std::endl;
			error << IMG_GetError() << std::endl;
			return false;
		}

		// store dimensions
		if (i != 0 && ((m_w != (unsigned)surface->w) || (m_h != (unsigned)surface->h)))
		{
			error << "Cube map sides aren't equal sizes" << std::endl;
			return false;
		}
		m_w = surface->w;
		m_h = surface->h;

		// detect channels
		int format = GL_RGB;
		switch (surface->format->BytesPerPixel)
		{
			case 1:
				format = GL_LUMINANCE;
				break;
			case 2:
				format = GL_LUMINANCE_ALPHA;
				break;
			case 3:
				format = GL_RGB;
				break;
			case 4:
				format = GL_RGBA;
				break;
			default:
				error << "Texture has unknown format: " + path + " (" + cubefiles[i] + ")" << std::endl;
				return false;
				break;
		}

		// Create MipMapped Texture
		GLenum targetparam;
		if (i == 0)
			targetparam = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
		else if (i == 1)
			targetparam = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
		else if (i == 2)
			targetparam = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
		else if (i == 3)
			targetparam = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
		else if (i == 4)
			targetparam = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
		else if (i == 5)
			targetparam = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
		else
		{
			error << "Iterated too far: " + path + " (" + cubefiles[i] + ")" << std::endl;
			assert(0);
		}

		glTexImage2D(targetparam, 0, format, surface->w, surface->h, 0, format, GL_UNSIGNED_BYTE, surface->pixels );

		SDL_FreeSurface(surface);
	}

	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	glDisable(GL_TEXTURE_CUBE_MAP);

	CheckForOpenGLErrors("Cubemap creation", error);

	return true;
}
Esempio n. 3
0
bool TEXTURE::LoadCube(const std::string & path, const TEXTUREINFO & info, std::ostream & error)
{
	if (info.verticalcross)
	{
		return LoadCubeVerticalCross(path, info, error);
	}

	std::string cubefiles[6];
	cubefiles[0] = path+"-xp.png";
	cubefiles[1] = path+"-xn.png";
	cubefiles[2] = path+"-yn.png";
	cubefiles[3] = path+"-yp.png";
	cubefiles[4] = path+"-zn.png";
	cubefiles[5] = path+"-zp.png";

	GLuint new_handle = 0;
	glGenTextures(1, &new_handle);
	OPENGL_UTILITY::CheckForOpenGLErrors("Cubemap texture ID generation", error);
	id = new_handle;

	glBindTexture(GL_TEXTURE_CUBE_MAP, new_handle);

	for (unsigned int i = 0; i < 6; ++i)
	{
		SDL_Surface * texture_surface = IMG_Load(cubefiles[i].c_str());
		if (texture_surface)
		{
			//store dimensions
			if (i != 0 && (w != (unsigned int) texture_surface->w || h != (unsigned int) texture_surface->h))
			{
				error << "Cube map sides aren't equal sizes" << std::endl;
				return false;
			}
			w = texture_surface->w;
			h = texture_surface->h;

			//detect channels
			int format = GL_RGB;
			switch (texture_surface->format->BytesPerPixel)
			{
				case 1:
					format = GL_LUMINANCE;
					break;
				case 2:
					format = GL_LUMINANCE_ALPHA;
					break;
				case 3:
					format = GL_RGB;
					break;
				case 4:
					format = GL_RGBA;
					break;
				default:
					error << "Texture has unknown format: " + path + " (" + cubefiles[i] + ")" << std::endl;
					return false;
					break;
			}

			if (format != GL_RGB)
			{
				error << "Cube map texture format isn't GL_RGB (this causes problems for some reason): " + path + " (" + cubefiles[i] + ")" << std::endl;
				return false;
			}

			// Create MipMapped Texture

			GLenum targetparam;
			if (i == 0)
				targetparam = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
			else if (i == 1)
				targetparam = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
			else if (i == 2)
				targetparam = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
			else if (i == 3)
				targetparam = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
			else if (i == 4)
				targetparam = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
			else if (i == 5)
				targetparam = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
			else
			{
				error << "Iterated too far: " + path + " (" + cubefiles[i] + ")" << std::endl;
				assert(0);
			}

			glTexImage2D( targetparam, 0, format,texture_surface->w, texture_surface->h, 0, format, GL_UNSIGNED_BYTE, texture_surface->pixels );
		}
		else
		{
			error << "Error loading texture file: " + path + " (" + cubefiles[i] + ")" << std::endl;
			return false;
		}

		if (texture_surface)
		{
			// Free up any memory we may have used
			SDL_FreeSurface( texture_surface );
			texture_surface = NULL;
		}
	}

	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	glDisable(GL_TEXTURE_CUBE_MAP);

	OPENGL_UTILITY::CheckForOpenGLErrors("Cubemap creation", error);

	return true;
}