diff options
Diffstat (limited to 'scene.cpp')
-rw-r--r-- | scene.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
@@ -5,6 +5,7 @@ #include <SDL_image.h> #include <boost/format.hpp> #include <boost/bind.hpp> +#include <assimp/aiPostProcess.h> #include "gl.h" @@ -27,10 +28,13 @@ Scene::Scene() { tool = NULL; /* setup shader programs */ + GLFragmentShader fog_fragment("shaders/fog_fragment.glsl"); + GLVertexShader terrain_vertex("shaders/terrain_vertex.glsl"); GLFragmentShader terrain_fragment("shaders/terrain_fragment.glsl"); terrain_program.attach(terrain_vertex); terrain_program.attach(terrain_fragment); + terrain_program.attach(fog_fragment); terrain_program.link(); GLFragmentShader water_fragment("shaders/water_fragment.glsl"); @@ -38,12 +42,24 @@ Scene::Scene() { water_program.attach(water_fragment); water_program.link(); + GLVertexShader tree_vertex("shaders/tree_vertex.glsl"); + GLFragmentShader tree_fragment("shaders/tree_fragment.glsl"); + tree_program.attach(tree_vertex); + tree_program.attach(tree_fragment); + tree_program.attach(fog_fragment); + tree_program.link(); + terrain_program.use(); GLint tex = glGetUniformLocation(terrain_program.get_program(), "tex"); GLint texv[] = {0, 1, 2}; glUniform1iv(tex, 3, texv); GLint markloc = glGetUniformLocation(terrain_program.get_program(), "marktex"); glUniform1i(markloc, 3); + + tree_program.use(); + tex = glGetUniformLocation(tree_program.get_program(), "tex"); + glUniform1iv(tex, 1, texv); + glUseProgram(0); /* load textures */ @@ -54,6 +70,17 @@ Scene::Scene() { marker_texture = load_texture("textures/cross.png"); placeholder_texture = load_texture("textures/placeholder.png"); + tree_scene = ai_importer.ReadFile("models/trees.blend", aiProcess_Triangulate); + + for(unsigned int i = 0; i < tree_scene->mNumTextures; i++) { + aiTexture *texture = tree_scene->mTextures[i]; + GLuint tx = load_texture(texture); + std::string name = (boost::format("*%d") % i).str(); + scene_textures.insert(std::pair<std::string, GLuint>(name, tx)); + } + + tree = new models::Tree(tree_scene, scene_textures); + /* init terrain */ terrain = new Terrain(); @@ -78,6 +105,7 @@ Scene::~Scene() { delete lua; if(tool) delete tool; + delete tree; if(terrain) delete terrain; delete font; @@ -380,6 +408,8 @@ void Scene::render() { glEnable(GL_CULL_FACE); glCullFace(GL_BACK); + Terrain::Chunk::ObjectList trees; + // render terrain if(render_terrain) { const float fog_color[4] = {1, 1, 1, 0}; @@ -417,6 +447,9 @@ void Scene::render() { // draw chunk VBOs for(std::list<Terrain::Chunk*>::iterator it = terrain->chunks.begin(); it != terrain->chunks.end(); it++) { Terrain::Chunk *chunk = *it; + + trees.insert(trees.end(), chunk->objects.begin(), chunk->objects.end()); + glPushMatrix(); glTranslatef(-pos.x + chunk->x, -pos.y, -pos.z + chunk->y); glUniform2f(chunk_pos, chunk->x, chunk->y); @@ -548,7 +581,39 @@ void Scene::render() { (*it)->render(font, steps, placeholder_texture); } + // don't pop matrix; use translated player position + + // rotate to point upwards along the y-aksis + glRotatef(-90, 1, 0, 0); + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + tree_program.use(); + + GLint player_pos = glGetUniformLocation(tree_program.get_program(), "player_pos"); + glUniform3f(player_pos, pos.x, pos.y, pos.z); + + GLint tree_pos = glGetUniformLocation(tree_program.get_program(), "tree_pos"); + + //tree->render(); + for(Terrain::Chunk::ObjectList::iterator it = trees.begin(); it != trees.end(); it++) { + glPushMatrix(); + Vector3 pos(it->second); + glUniform3f(tree_pos, pos.x, pos.y, pos.z); + // rotated around x-axis; swap y and z, do magic to fix positions + glTranslatef(pos.x, -pos.z, pos.y+.5); + it->first->render(); + glPopMatrix(); + } + glPopMatrix(); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + glUseProgram(0); + + // active texture # must be reset before rendering UI stuff + glActiveTexture(GL_TEXTURE0); // HUD video::ortho(); @@ -608,6 +673,30 @@ GLuint Scene::load_texture(const char *filename) { return texture; } +GLuint Scene::load_texture(aiTexture *texture) { + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if(texture->mHeight == 0) { + SDL_RWops *rw = SDL_RWFromConstMem(texture->pcData, texture->mWidth); + SDL_Surface *image = IMG_Load_RW(rw, 1); + 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(image); + } else { + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texture->mWidth, texture->mHeight, GL_BGRA, GL_UNSIGNED_BYTE, texture->pcData); + } + + return tex; +} + static bool playerlist_sort(Vector3 pos, Player::p a, Player::p b) { return (a->get_pos() - pos).length() > (b->get_pos() - pos).length(); } |