1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 
4 #include "HeightMapTexture.h"
5 
6 #include "ReadMap.h"
7 #include "System/EventHandler.h"
8 #include "System/Rectangle.h"
9 #include "System/Config/ConfigHandler.h"
10 
11 
12 CONFIG(bool, HeightMapTexture).defaultValue(true);
13 
14 HeightMapTexture* heightMapTexture = NULL;
HeightMapTexture()15 HeightMapTexture::HeightMapTexture()
16 	: CEventClient("[HeightMapTexture]", 2718965, false)
17 {
18 	texID = 0;
19 	xSize = 0;
20 	ySize = 0;
21 
22 	eventHandler.AddClient(this);
23 	Init();
24 }
25 
26 
~HeightMapTexture()27 HeightMapTexture::~HeightMapTexture()
28 {
29 	Kill();
30 	eventHandler.RemoveClient(this);
31 }
32 
33 
Init()34 void HeightMapTexture::Init()
35 {
36 	if (readMap == NULL) {
37 		return;
38 	}
39 
40 	if (!configHandler->GetBool("HeightMapTexture")) {
41 		return;
42 	}
43 
44 	if (!GLEW_ARB_texture_float ||
45 	    !GLEW_ARB_texture_non_power_of_two) {
46 		return;
47 	}
48 
49 	xSize = gs->mapxp1;
50 	ySize = gs->mapyp1;
51 
52 	glGenTextures(1, &texID);
53 	glBindTexture(GL_TEXTURE_2D, texID);
54 
55 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
56 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
57 
58 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
59 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
60 
61 	const float* heightMap = readMap->GetCornerHeightMapUnsynced();
62 
63 	glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE32F_ARB,
64 		xSize, ySize, 0,
65 		GL_LUMINANCE, GL_FLOAT, heightMap);
66 
67 	glBindTexture(GL_TEXTURE_2D, 0);
68 }
69 
70 
Kill()71 void HeightMapTexture::Kill()
72 {
73 	glDeleteTextures(1, &texID);
74 	texID = 0;
75 	xSize = 0;
76 	ySize = 0;
77 }
78 
79 
UnsyncedHeightMapUpdate(const SRectangle & rect)80 void HeightMapTexture::UnsyncedHeightMapUpdate(const SRectangle& rect)
81 {
82 	if (texID == 0) {
83 		return;
84 	}
85 	const float* heightMap = readMap->GetCornerHeightMapUnsynced();
86 
87 	const int sizeX = rect.x2 - rect.x1 + 1;
88 	const int sizeZ = rect.z2 - rect.z1 + 1;
89 
90 	pbo.Bind();
91 	pbo.New(sizeX * sizeZ * sizeof(float));
92 
93 	{
94 		float* buf = (float*) pbo.MapBuffer();
95 		for (int z = 0; z < sizeZ; z++) {
96 			const void* src = heightMap + rect.x1 + (z + rect.z1) * xSize;
97 			      void* dst = buf + z * sizeX;
98 
99 			memcpy(dst, src, sizeX * sizeof(float));
100 		}
101 		pbo.UnmapBuffer();
102 	}
103 
104 	glBindTexture(GL_TEXTURE_2D, texID);
105 	glTexSubImage2D(GL_TEXTURE_2D, 0,
106 		rect.x1, rect.z1, sizeX, sizeZ,
107 		GL_LUMINANCE, GL_FLOAT, pbo.GetPtr());
108 
109 	pbo.Invalidate();
110 	pbo.Unbind();
111 }
112