diff options
| author | Jon Bergli Heier <snakebite@jvnv.net> | 2011-04-09 20:22:13 +0200 | 
|---|---|---|
| committer | Jon Bergli Heier <snakebite@jvnv.net> | 2011-04-09 20:22:13 +0200 | 
| commit | 3817acdb49d775edb23fafbed70095be8f648ed6 (patch) | |
| tree | 088d94ebd9f767e84263e1400db336930a7324cd | |
| parent | e19c3838a4d89fb0640ed563ffdf58cd125cde7f (diff) | |
Terrain multitexturing.
| -rw-r--r-- | main.cpp | 88 | ||||
| -rw-r--r-- | quadtree.cpp | 7 | ||||
| -rw-r--r-- | scene.cpp | 7 | ||||
| -rw-r--r-- | shader.cpp | 4 | ||||
| -rw-r--r-- | shader.h | 2 | ||||
| -rw-r--r-- | shaders/terrain_fragment.glsl | 22 | ||||
| -rw-r--r-- | shaders/terrain_vertex.glsl (renamed from terrain_vertex.glsl) | 7 | ||||
| -rw-r--r-- | terrain_fragment.glsl | 11 | 
8 files changed, 90 insertions, 58 deletions
| @@ -20,6 +20,33 @@  FTFont *font; +GLuint load_texture(const std::string filename) { +	GLuint texture; +	SDL_Surface *surface = IMG_Load(filename.c_str()); +	SDL_Surface *image = SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w, surface->h, 32, +			0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); +	SDL_Rect area; +	area.x = area.y = 0; +	area.w = surface->w; +	area.h = surface->h; +	SDL_BlitSurface(surface, &area, image, &area); +	glPixelStorei(GL_UNPACK_ALIGNMENT, 4); +	glGenTextures(1, &texture); +	glBindTexture(GL_TEXTURE_2D, texture); +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +	if(image->format->Amask) { +		gluBuild2DMipmaps(GL_TEXTURE_2D, 4, image->w, image->h, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); +	} else { +		gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->w, image->h, GL_RGB, GL_UNSIGNED_BYTE, image->pixels); +	} +	SDL_FreeSurface(surface); +	SDL_FreeSurface(image); + +	return texture; +} + +  int main(int argc, char **argv) {  	video::width = 1280;  	video::height = 720; @@ -28,40 +55,27 @@ int main(int argc, char **argv) {  	Scene scene;  	GLShaderProgram program; -	GLVertexShader terrain_vertex("terrain_vertex.glsl"); -	GLFragmentShader terrain_fragment("terrain_fragment.glsl"); +	GLVertexShader terrain_vertex("shaders/terrain_vertex.glsl"); +	GLFragmentShader terrain_fragment("shaders/terrain_fragment.glsl");  	program.attach(terrain_vertex);  	program.attach(terrain_fragment);  	program.link(); +	{ +		program.use(); +		GLint tex1loc = glGetUniformLocation(program.get_program(), "tex[1]"); +		glUniform1i(tex1loc, 1); +		GLint tex2loc = glGetUniformLocation(program.get_program(), "tex[2]"); +		glUniform1i(tex2loc, 2); +		glUseProgram(0); +	} +  	font = new FTTextureFont("font.ttf");  	font->FaceSize(10); -	GLuint grass_texture; -	{ -		SDL_Surface *surface = IMG_Load("Grass0073_3_S.jpg"); -		SDL_Surface *image = SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w, surface->h, 32, -				0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); -		SDL_Rect area; -		area.x = area.y = 0; -		area.w = surface->w; -		area.h = surface->h; -		SDL_BlitSurface(surface, &area, image, &area); -		//glPixelStorei(GL_UNPACK_ALIGNMENT, 4); -		glGenTextures(1, &grass_texture); -		glBindTexture(GL_TEXTURE_2D, grass_texture); -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -		if(image->format->Amask) { -			//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); -			gluBuild2DMipmaps(GL_TEXTURE_2D, 4, image->w, image->h, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); -		} else { -			//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->w, image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, image->pixels); -			gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->w, image->h, GL_RGB, GL_UNSIGNED_BYTE, image->pixels); -		} -		SDL_FreeSurface(surface); -		SDL_FreeSurface(image); -	} +	GLuint grass_texture = load_texture("textures/Grass0073_3_S.jpg"); +	GLuint rock_texture = load_texture("textures/RockJagged0010_2_S.jpg"); +	GLuint soil_texture = load_texture("textures/SoilSand0168_9_S.jpg");  	//SDL_WM_GrabInput(SDL_GRAB_ON); @@ -207,9 +221,17 @@ int main(int argc, char **argv) {  		unsigned int chunks_rendered = 0;  		if(terrain) {  			program.use(); -			glBindTexture(GL_TEXTURE_2D, grass_texture);  			glEnable(GL_TEXTURE_2D); -			//for(int i = 0; i < scene.qt->chunk_count; i++) { + +			glActiveTexture(GL_TEXTURE0); +			glBindTexture(GL_TEXTURE_2D, grass_texture); + +			glActiveTexture(GL_TEXTURE1); +			glBindTexture(GL_TEXTURE_2D, rock_texture); + +			glActiveTexture(GL_TEXTURE2); +			glBindTexture(GL_TEXTURE_2D, soil_texture); +  			std::queue<Quadtree::QuadChunk*> q;  			q.push(scene.qt->root);  			while(!q.empty()) { @@ -222,25 +244,21 @@ int main(int argc, char **argv) {  				} else if(!chunk->vbo_object)  					continue;  				chunks_rendered++; -				//std::cout << (boost::format("vertices: %d  nodes: %d") % scene.qt->chunks[i]->vertices % scene.qt->chunks[i]->node_count).str() << std::endl; -			//glBindBuffer(GL_ARRAY_BUFFER, scene.qt->vbo_object); -			//glBindBuffer(GL_ARRAY_BUFFER, scene.qt->chunks[i]->vbo_object);  			glBindBuffer(GL_ARRAY_BUFFER, chunk->vbo_object);  			glVertexPointer(3, GL_FLOAT, 0, NULL); -			//glNormalPointer(GL_FLOAT, 0, (GLvoid*)(scene.qt->vertices*3*sizeof(float)));  			glNormalPointer(GL_FLOAT, 0, (GLvoid*)(chunk->vertices*3*sizeof(float))); -			//glTexCoordPointer(2, GL_FLOAT, 0, (GLvoid*)(scene.qt->vertices*3*sizeof(float)*2));  			glTexCoordPointer(2, GL_FLOAT, 0, (GLvoid*)(chunk->vertices*3*sizeof(float)*2));  			glEnableClientState(GL_VERTEX_ARRAY);  			glEnableClientState(GL_NORMAL_ARRAY);  			glEnableClientState(GL_TEXTURE_COORD_ARRAY); -			//glDrawArrays(GL_TRIANGLES, 0, scene.qt->vertices);  			glDrawArrays(GL_TRIANGLES, 0, chunk->vertices);  			glDisableClientState(GL_VERTEX_ARRAY);  			glDisableClientState(GL_NORMAL_ARRAY);  			glDisableClientState(GL_TEXTURE_COORD_ARRAY);  			}  			glDisable(GL_TEXTURE_2D); +			// set active to texture0 to avoid breaking the texture font +			glActiveTexture(GL_TEXTURE0);  			glUseProgram(0);  		}  		if(grid) { diff --git a/quadtree.cpp b/quadtree.cpp index 1f2dd4a..8bc366c 100644 --- a/quadtree.cpp +++ b/quadtree.cpp @@ -1,9 +1,6 @@  #include "quadtree.h"  #include "vector.h" -#include <boost/format.hpp> -#include <boost/timer.hpp> -  #include "gl.h"  #include <cmath> @@ -333,7 +330,6 @@ Quadtree::Quadtree(int width, int height, float *heightmap) {  	root = new QuadChunk(this, 0, 0, width-1, height-1); -	boost::timer t;  	normals = new Vector3[width*height];  	for(int x = 0; x < width; x++) {  		for(int y = 0; y < height; y++) { @@ -362,12 +358,9 @@ Quadtree::Quadtree(int width, int height, float *heightmap) {  					N += V.cross(U);  				}  			} -			if(N.y < 0) -				std::cout << N.str() << std::endl;  			normals[x*height + y] = N / N.length();  		}  	} -	std::cout << "normal time: " << t.elapsed() << std::endl;  }  Quadtree::~Quadtree() { @@ -8,7 +8,7 @@  #define inrange(a, b, c) ((a) >= (b) && (a) <= (c))  Scene::Scene() { -	SDL_Surface *hm = IMG_Load("heightmap10.png"); +	SDL_Surface *hm = IMG_Load("heightmap.png");  	float *heightmap = new float[hm->w * hm->h];  	for(int x = 0; x < hm->w; x++) {  		for(int y = 0; y < hm->h; y++) { @@ -28,6 +28,7 @@ Scene::~Scene() {  }  void Scene::lookat() { +	const float cam_height = 1.7;  	/* calculate cartesian coordinates for the center vector where yaw is Φ and pitch is θ  	 * x = cos Φ sin θ  	 * y = cos θ @@ -35,10 +36,10 @@ void Scene::lookat() {  	 */  	Vector3 center(sinf(pitch) * cosf(yaw), cosf(pitch), sinf(pitch) * sinf(yaw));  	center += pos; -	center.y += 1; +	center.y += cam_height;  	//Vector3 up(cosf(yaw) * cosf(pitch), sinf(pitch), sinf(yaw) * cosf(pitch));  	Vector3 up(-cosf(pitch) * cosf(yaw), sinf(pitch), -cosf(pitch) * sinf(yaw)); -	gluLookAt(pos.x, pos.y+1, pos.z, +	gluLookAt(pos.x, pos.y+cam_height, pos.z,  			center.x, center.y, center.z,  			up.x, up.y, up.z);  } @@ -92,3 +92,7 @@ void GLShaderProgram::use() {  	gl_check_error("Failed to use program");  } + +GLuint GLShaderProgram::get_program() { +	return program; +} @@ -40,6 +40,8 @@ class GLShaderProgram {  		void detach(GLBaseShader&);  		void link();  		void use(); + +		GLuint get_program();  };  #endif diff --git a/shaders/terrain_fragment.glsl b/shaders/terrain_fragment.glsl new file mode 100644 index 0000000..78417af --- /dev/null +++ b/shaders/terrain_fragment.glsl @@ -0,0 +1,22 @@ +#version 120 + +varying vec3 normal, light_pos; +varying float y; + +uniform sampler2D tex[3]; + +void main() { +	vec3 n = normalize(normal); +	float diffuse = max(dot(n, light_pos), 0.0); + +	float f1 = clamp((y-15.0) / 3.0, 0.0, 1.0); +	float f2 = clamp((y-2) / 3.0, 0.0, 1.0); + +	vec4 t0 = texture2D(tex[0], gl_TexCoord[0].st); +	vec4 t1 = texture2D(tex[1], gl_TexCoord[0].st); +	vec4 t2 = texture2D(tex[2], gl_TexCoord[0].st); + +	gl_FragColor = mix(mix(t2, t0, f2), t1, f1) * diffuse; +} + +/* vim: set syn=glsl: */ diff --git a/terrain_vertex.glsl b/shaders/terrain_vertex.glsl index 8bb21d0..e53c432 100644 --- a/terrain_vertex.glsl +++ b/shaders/terrain_vertex.glsl @@ -1,9 +1,12 @@ -varying vec3 normal, light_pos, V, N; -varying vec4 diffuse, ambient; +#version 120 + +varying vec3 normal, light_pos; +varying float y;  void main() {  	normal = gl_Normal;  	light_pos = vec3(0, 1, 0); +	y = gl_Vertex.y;  	gl_TexCoord[0] = gl_MultiTexCoord0;  	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; diff --git a/terrain_fragment.glsl b/terrain_fragment.glsl deleted file mode 100644 index 774bfd3..0000000 --- a/terrain_fragment.glsl +++ /dev/null @@ -1,11 +0,0 @@ -varying vec3 normal, light_pos; - -uniform sampler2D tex; - -void main() { -	vec3 n = normalize(normal); -	float diffuse = max(dot(n, light_pos), 0.0); -	gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * diffuse; -} - -/* vim: set syn=glsl: */ | 
