Пример #1
0
	GLuint GenSphereBumpmap()
	{
		GLuint id;
		glGenTextures(1, &id);
		glBindTexture(GL_TEXTURE_2D, id);

		uchar img[3 * 64 * 64], *p = img;

		for (int y = 0; y < 64; y++) {
			for (int x = 0; x < 64; x++)
			{
				int sx = x - 32;
				int sy = y - 32;
				Vector3 n;

				if (sx*sx + sy*sy < 32*32) {
					const int sz = (int)sqrt(static_cast<float>(32 * 32 - sx*sx - sy*sy));
					n = Vector3(sx, sy, sz);
					n.ANormalize();
				}

				// compress it into a color
				*(p++) = (uchar)(255 * (n.x * 0.5f + 0.5f));
				*(p++) = (uchar)(255 * (n.y * 0.5f + 0.5f));
				*(p++) = (uchar)(255 * (n.z * 0.5f + 0.5f));
			}
		}

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, img);

		SaveImage("sphere_bm.jpg", 3, GL_UNSIGNED_BYTE, 64, 64, img);
		return id;
	}
Пример #2
0
	void RenderDataManager::InitializeNode(TQuad* q)
	{
		assert(!q->renderData);

		QuadRenderData* rd = q->renderData = Allocate();

		// Allocate vertex data space
		const size_t vertexSize = q->GetVertexSize();
		if (static_cast<int>(vertexSize) != rd->vertexSize) {
			const size_t size = NUM_VERTICES * vertexSize;

			if (rd->vertexBuffer.GetSize() != size) {
				rd->vertexBuffer.Init(size);
			}
			rd->vertexSize = vertexSize;
		}

		// build the vertex buffer
		Vector3* v = (Vector3*)rd->vertexBuffer.LockData();

		uint vda = q->textureSetup->vertexDataReq; 		// vertex data requirements
		const Heightmap* hm = roothm->GetLevel(q->depth); // get the right heightmap level

		for (int y = q->hmPos.y; y <= (q->hmPos.y + QUAD_W); y++)
			for (int x = q->hmPos.x; x <= (q->hmPos.x + QUAD_W); x++)
			{
				*(v++) = Vector3(x * hm->squareSize, hm->atSynced(x, y), y * hm->squareSize);

				Vector3 tangent, binormal;
				CalculateTangents(hm, x,y, tangent, binormal);
				Vector3 normal = binormal.cross(tangent);
				normal.ANormalize();

				if (vda & VRT_Normal)
					*(v++) = normal;

				if (vda & VRT_TangentSpaceMatrix)
				{
					tangent.ANormalize();
					binormal.ANormalize();

					// orthonormal matrix, so inverse=transpose
					// Take the inverse of the tangent space -> world space transformation
					Vector3* tgs2ws = v;
					tgs2ws[0] = Vector3(tangent.x, binormal.x, normal.x);
					tgs2ws[1] = Vector3(tangent.y, binormal.y, normal.y);
					tgs2ws[2] = Vector3(tangent.z, binormal.z, normal.z);
					v += 3;
				}
			}
		rd->vertexBuffer.UnlockData();
		rd->SetQuad(q);
	}
Пример #3
0
	void Heightmap::GenerateNormals()
	{
		normalData = new uchar[3 * w * h];

		uchar* cnorm = normalData;
		for (int y = 0; y < h;y++)
			for (int x = 0; x < w; x++) {
				Vector3 tangent, binormal;
				CalculateTangents(this, x, y, tangent, binormal);

				Vector3 normal = binormal.cross(tangent);
				normal.ANormalize();

				*(cnorm++) = (uchar)((normal.x * 0.5f + 0.5f) * 255);
				*(cnorm++) = (uchar)((normal.y * 0.5f + 0.5f) * 255);
				*(cnorm++) = (uchar)((normal.z * 0.5f + 0.5f) * 255);
			}
	}
Пример #4
0
	void Blendmap::Generate(Heightmap* rootHm, int lodLevel, float hmScale, float hmOffset)
	{
		const 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++)
			{
				const float h = (heightmap->atSynced(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) {
					const 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;
	}
Пример #5
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";

	const Heightmap* hm = NULL;
	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;
	const 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->atSynced(x, y)+ (int)hm->atSynced(x + 1, y) + (int)hm->atSynced(x, y + 1) + (int)hm->atSynced(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);

				const 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;
	LOG("Lightmap generation: %2.3f seconds", spring_tomsecs(numTicks) * 0.001f);
}