Esempio n. 1
0
Heightmap Heightmap::operator-=( Heightmap &other )
{
	for(int j=0;j<Size;j++)
		for(int i=0;i<Size;i++)
			put(i,j,at(i,j)-other.at(i,j));
	return *this;
}
Esempio n. 2
0
Heightmap Heightmap::operator-( Heightmap &other )
{
	Heightmap temp(Size);
	for(int j=0;j<Size;j++)
		for(int i=0;i<Size;i++)
			temp.put(i,j,at(i,j)-other.at(i,j));
	return temp;
}
Esempio n. 3
0
	void Blendmap::Generate (Heightmap *rootHm, int lodLevel, float hmScale, float hmOffset)
	{
		Heightmap *heightmap = rootHm->GetLevel(-lodLevel);

		// Allocate the blendmap image
		AlphaImage *bm = new AlphaImage;
		bm->Alloc (heightmap->w-1, heightmap->h-1); // texture dimensions have to be power-of-two

		Blendmap::GeneratorInfo *gi = generatorInfo;

		// Calculate blend factors using the function parameters and heightmap input:
		for (int y=0;y<bm->h;y++)
		{
			for (int x=0;x<bm->w;x++)
			{
				float h = (heightmap->at (x,y) - hmOffset) / hmScale;
				float factor=1.0f;

				if(h < gi->minHeight - gi->minHeightFuzzy) {
					bm->at (x,y) = 0.0f;
					continue;
				} else if (gi->minHeightFuzzy > 0.0f && h < gi->minHeight + gi->minHeightFuzzy)
					factor = (h - (gi->minHeight - gi->minHeightFuzzy)) / (2.0f * gi->minHeightFuzzy);

				if(h > gi->maxHeight + gi->maxHeightFuzzy) {
					bm->at (x,y) = 0.0f;
					continue;
				} else if (gi->maxHeightFuzzy > 0.0f && h > gi->maxHeight - gi->maxHeightFuzzy)
					factor *= ((gi->maxHeight + gi->maxHeightFuzzy) - h) / (2.0f * gi->maxHeightFuzzy);

                float norm_y = 0.0f;
				if (heightmap->normalData) {
					uchar *cnorm = heightmap->GetNormal (x,y);
					norm_y = cnorm[1] / 255.0f * 2.0f - 1.0f;
					if (norm_y > 1.0f) norm_y = 1.0f;
				} else {
					Vector3 tangent, binormal;
					CalculateTangents(heightmap, x,y,tangent,binormal);
					Vector3 normal = tangent.cross(binormal);
					normal.ANormalize();
					norm_y = normal.y;
				}

				// flatness=dotproduct of surface normal with up vector
				float slope = 1.0f - fabs(norm_y);

				if (slope < gi->minSlope - gi->minSlopeFuzzy) {
					bm->at (x,y) = 0.0f;
					continue;
				} else if (gi->minSlopeFuzzy > 0.0f && slope < gi->minSlope + gi->minSlopeFuzzy)
					factor *= (h - (gi->minSlope - gi->minSlopeFuzzy)) / ( 2.0f * gi->minSlopeFuzzy);

				if (slope > gi->maxSlope + gi->maxSlopeFuzzy) {
					bm->at (x,y) = 0.0f;
					continue;
				} else if (gi->maxSlopeFuzzy > 0.0f && slope > gi->maxSlope - gi->maxSlopeFuzzy)
					factor *= ((gi->maxSlope + gi->maxSlopeFuzzy) - h) / (2.0f * gi->maxSlopeFuzzy);

				factor *= gi->coverage;
				factor *= (rand () < gi->noise * RAND_MAX) ? 0.0f : 1.0f;

				bm->at (x,y) = factor;
			}
		}

		BlendmapFilter(bm);
		image = bm;
	}
Esempio n. 4
0
Lightmap::Lightmap(Heightmap *orghm, int level, int shadowLevelDif, LightingInfo *li)
{
	const spring_time startTicks = spring_gettime();
	tilesize.x = orghm->w-1;
	tilesize.y = orghm->h-1;
	name = "lightmap";

	Heightmap *hm;
	int w;

	for(;;) {
		hm = orghm->GetLevel(-level);
		w=hm->w-1;

		GLint maxw;
		glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxw);

		if (w > maxw) level ++;
		else break;
	}

	shadowLevelDif=0;
	Heightmap *shadowhm = orghm->GetLevel(-(level+shadowLevelDif));
	int shadowScale=1<<shadowLevelDif;
	int shadowW=shadowhm->w-1;
	assert (w/shadowW == shadowScale);
	//float org2c = w/float(orghm->w-1);
	//float c2org = (float)(orghm->w-1)/w;

	float *centerhm = new float[w*w];
	Vector3 *shading = new Vector3[w*w];
	for (int y=0;y<w;y++)
		for (int x=0;x<w;x++) {
			centerhm[y*w+x] =/* hm->scale * */ 0.25f * ( (int)hm->at(x,y)+ (int)hm->at(x+1,y)+ (int)hm->at(x,y+1) + (int)hm->at(x+1,y+1) ); //+ hm->offset;
			shading[y*w+x] = li->ambient;
		}

	uchar *lightMap = new uchar[shadowW*shadowW];
	for (std::vector<StaticLight>::const_iterator l=li->staticLights.begin();l!=li->staticLights.end();++l)
	{
		float lightx;
		float lighty;

		if (l->directional) {
			lightx = l->position.x;
			lighty = l->position.y;
		} else {
			lightx = (int)(l->position.x / shadowhm->squareSize);
			lighty = (int)(l->position.z / shadowhm->squareSize);
		}
		CalculateShadows(lightMap, shadowW, lightx, lighty,
			l->position.y, centerhm, w, shadowScale, l->directional);

		for (int y=0;y<w;y++)
		{
			for (int x=0;x<w;x++)
			{
				if (!lightMap[(y*shadowW+x)/shadowScale])
					continue;

				Vector3 wp;
				if (l->directional)
					wp = l->position;
				else
					wp = l->position - Vector3((x+0.5f)*hm->squareSize,centerhm[y*w+x],(y+0.5f)*hm->squareSize);

				uchar* normal = hm->GetNormal (x,y);
				Vector3 normv((2 * (int)normal[0] - 256)/255.0f, (2 * (int)normal[1] - 256)/255.0f, (2 * (int)normal[2] - 256)/255.0f);

				wp.ANormalize();
				float dot = wp.dot(normv);
				if(dot < 0.0f) dot = 0.0f;
				if(dot > 1.0f) dot = 1.0f;
				dot *= lightMap[(y*shadowW+x)/shadowScale]*(1.0f/255.0f);
				shading[y*w+x] += l->color * dot;
			}
		}

	}
	delete[] lightMap;

	glGenTextures(1,&shadingTex);
	glBindTexture (GL_TEXTURE_2D, shadingTex);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

	uchar *shadingTexData=new uchar[w*w*4];
	for(int y=0;y<w;y++) {
		for (int x=0;x<w;x++) {
			shadingTexData[(y*w+x)*4+0] = (uchar)(min(1.0f, shading[y*w+x].x) * 255);
			shadingTexData[(y*w+x)*4+1] = (uchar)(min(1.0f, shading[y*w+x].y) * 255);
			shadingTexData[(y*w+x)*4+2] = (uchar)(min(1.0f, shading[y*w+x].z) * 255);
			shadingTexData[(y*w+x)*4+3] = CReadMap::EncodeHeight(centerhm[w*y+x]);
		}
	}

	SaveImage ("lightmap.png", 4, IL_UNSIGNED_BYTE, w,w, shadingTexData);

	glBuildMipmaps(GL_TEXTURE_2D, 4, w,w, GL_RGBA, GL_UNSIGNED_BYTE, shadingTexData);
	delete[] shadingTexData;

	id = shadingTex;

	delete[] shading;
	delete[] centerhm;

	const spring_duration numTicks = spring_gettime() - startTicks;
	d_trace ("Lightmap generation: %2.3f seconds\n", spring_tomsecs(numTicks) * 0.001f);
}
Esempio n. 5
0
Lightmap::Lightmap(Heightmap *orghm, int level, LightingInfo *li)
{
	int startTicks = SDL_GetTicks();
	tilesize.x = orghm->w-1;
	tilesize.y = orghm->h-1;
	name = "lightmap";

	Heightmap *hm = orghm->GetLevel(-level);
	int w=hm->w-1;
	float org2c = w/float(orghm->w-1);
	float c2org = (float)(orghm->w-1)/w;

	float *centerhm = new float[w*w];
	Vector3 *shading = new Vector3[w*w];
	for (int y=0;y<w;y++)
		for (int x=0;x<w;x++) {
			centerhm[y*w+x] = hm->scale * 0.25f * ( (int)hm->at(x,y)+ (int)hm->at(x+1,y)+ (int)hm->at(x,y+1) + (int)hm->at(x+1,y+1) ) + hm->offset;
			shading[y*w+x] = li->ambient;
		}

	uchar *lightMap = new uchar[w*w];
	int lightIndex = 0;
	for (std::vector<StaticLight>::const_iterator l=li->staticLights.begin();l!=li->staticLights.end();++l) 
	{
		memset(lightMap, 255, w*w); // 255 is lit, 0 is unlit

		int lightx = (int)(l->position.x / hm->squareSize);
		int lighty = (int)(l->position.z / hm->squareSize);
		
		for (int y=0;y<w;y++)
		{
			for (int x=0;x<w;x++)
			{
				if (!lightMap[y*w+x]) // shadowed pixels can't shadow other pixels
					continue;

				if (x==lightx && y==lighty)
					continue;

				float dx = lightx-x;
				float dy = lighty-y;
				float h = centerhm[y*w+x];

				float dh = l->position.y-h;
				float len = sqrtf(dx*dx+dy*dy);
				const float step = 5.0f;
				float invLength2d = step/len;
				dx *= invLength2d;
				dy *= invLength2d;
				dh *= invLength2d;

				float px = x + dx, py = y + dy;
				h += dh;
				while (px >= 0.0f && px < w && py >= 0.0f && py < w && len >= 0.0f)
				{
					int index = (int)py * w + (int)px;

					if (centerhm[index] > h + 2.0f)
					{
						lightMap[y*w+x]=0;
						break;
					}

					px += dx;
					py += dy;
					h += dh;
					len -= step;
				}
			}
		}

		BlurGrayscaleImage(w,w,lightMap);

		char sm_fn[64];
		SNPRINTF(sm_fn, sizeof(sm_fn), "shadowmap%d.bmp", lightIndex++);
		SaveImage(sm_fn, 1, IL_UNSIGNED_BYTE, w,w, lightMap);

		for (int y=0;y<w;y++)
		{
			for (int x=0;x<w;x++)
			{
				if (!lightMap[y*w+x])
					continue;

				Vector3 wp((x+0.5f)*hm->squareSize,centerhm[y*w+x],(y+0.5f)*hm->squareSize);
				wp = l->position - wp;

				uchar* normal = hm->GetNormal (x,y);
				Vector3 normv((2 * (int)normal[0] - 256)/255.0f, (2 * (int)normal[1] - 256)/255.0f, (2 * (int)normal[2] - 256)/255.0f);

				wp.Normalize();
				float dot = wp.dot(normv);
				if(dot < 0.0f) dot = 0.0f; 
				if(dot > 1.0f) dot = 1.0f;
				dot *= lightMap[y*w+x]*(1.0f/255.0f);
				shading[y*w+x] += l->color * dot;
			}
		}

	}
	delete[] lightMap;

	shadingTex.Bind();
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

	uchar *shadingTexData=new uchar[w*w*3], *td = shadingTexData;
	for(int y=0;y<w;y++) {
		for (int x=0;x<w;x++) {
			shadingTexData[(y*w+x)*3+0] = (uchar)(min(1.0f, shading[y*w+x].x) * 255);
			shadingTexData[(y*w+x)*3+1] = (uchar)(min(1.0f, shading[y*w+x].y) * 255);
			shadingTexData[(y*w+x)*3+2] = (uchar)(min(1.0f, shading[y*w+x].z) * 255);
		}
	}


	SaveImage ("lightmap.png", 3, IL_UNSIGNED_BYTE, w,w, shadingTexData);

	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, w,w, GL_RGB, GL_UNSIGNED_BYTE, shadingTexData);
	delete[] shadingTexData;

	id = shadingTex;

	delete[] shading;
	delete[] centerhm;

	int numTicks = SDL_GetTicks() - startTicks;
	d_trace ("Lightmap generation: %2.3f seconds\n", numTicks * 0.001f);
}