summaryrefslogtreecommitdiff
path: root/scene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene.cpp')
-rw-r--r--scene.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/scene.cpp b/scene.cpp
index 1fda39e..4e884a6 100644
--- a/scene.cpp
+++ b/scene.cpp
@@ -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();
}