From 0e9e54bc7acbaa12f789e83f7517d8ee5a6de390 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Thu, 13 Sep 2012 22:55:25 -0400 Subject: [PATCH] move OpenGL/SFML code to Client-gl.cc --- src/client/Client-gl.cc | 232 ++++++++++++++++++++++++++++++++++++++++ src/client/Client.cc | 223 +------------------------------------- src/client/Client.h | 10 +- src/client/main.cc | 26 ++--- 4 files changed, 256 insertions(+), 235 deletions(-) create mode 100644 src/client/Client-gl.cc diff --git a/src/client/Client-gl.cc b/src/client/Client-gl.cc new file mode 100644 index 0000000..4f4cdb8 --- /dev/null +++ b/src/client/Client-gl.cc @@ -0,0 +1,232 @@ + +#include +#include +#include GL_INCLUDE_FILE +#include +#include +#include +#include "Client.h" +#include "ccfs.h" +#include "HexTile.h" + +using namespace std; + +#define OPENGL_CONTEXT_MAJOR 3 +#define OPENGL_CONTEXT_MINOR 0 + +static bool load_file(const char *fname, WFObj::Buffer & buff) +{ + unsigned int length; + uint8_t *contents = (uint8_t *) CFS.get_file(fname, &length); + if (contents != NULL) + { + buff.data = contents; + buff.length = length; + return true; + } + return false; +} + +bool Client::create_window(bool fullscreen, int width, int height) +{ + sf::VideoMode mode = fullscreen + ? sf::VideoMode::getDesktopMode() + : sf::VideoMode(width, height, 32); + long style = fullscreen + ? sf::Style::Fullscreen + : sf::Style::Resize | sf::Style::Close; + sf::ContextSettings cs = sf::ContextSettings(0, 0, 0, + OPENGL_CONTEXT_MAJOR, OPENGL_CONTEXT_MINOR); + m_window = new sf::Window(mode, "Treacherous Terrain", style, cs); + m_window->setMouseCursorVisible(false); + if (!initgl()) + return false; + resize_window(m_window->getSize().x, m_window->getSize().y); + return true; +} + +bool Client::initgl() +{ + if (gl3wInit()) + { + cerr << "Failed to initialize GL3W" << endl; + return false; + } + if (!gl3wIsSupported(3, 0)) + { + cerr << "OpenGL 3.0 is not supported!" << endl; + return false; + } + glEnable(GL_DEPTH_TEST); + GLProgram::AttributeBinding obj_attrib_bindings[] = { + {0, "pos"}, + {1, "normal"}, + {0, NULL} + }; + const char *v_source = (const char *) CFS.get_file("shaders/obj_v.glsl", NULL); + const char *f_source = (const char *) CFS.get_file("shaders/obj_f.glsl", NULL); + if (v_source == NULL || f_source == NULL) + { + cerr << "Error loading shader sources" << endl; + return false; + } + else if (!m_obj_program.create(v_source, f_source, obj_attrib_bindings)) + { + cerr << "Error creating obj program" << endl; + return false; + } + if (!m_tank_obj.load("models/tank.obj", load_file)) + { + cerr << "Error loading tank model" << endl; + return false; + } + if (!m_tile_obj.load("models/hex-tile.obj", load_file)) + { + cerr << "Error loading hex-tile model" << endl; + return false; + } + return true; +} + +void Client::resize_window(int width, int height) +{ + m_width = width; + m_height = height; + sf::Mouse::setPosition(sf::Vector2i(m_width / 2, m_height / 2), *m_window); + glViewport(0, 0, width, height); + float aspect = (float)width / (float)height; + m_projection.load_identity(); + m_projection.perspective(60.0f, aspect, 1.0f, 5000.0f); +} + +void Client::redraw() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + double dir_x = cos(m_player->direction); + double dir_y = sin(m_player->direction); + m_modelview.load_identity(); + m_modelview.look_at( + m_player->x - dir_x * 25, m_player->y - dir_y * 25, 30, + m_player->x, m_player->y, 20, + 0, 0, 1); + + draw_players(); + draw_map(); + + m_window->display(); +} + +void Client::draw_players() +{ + GLint uniform_locations[7]; + const char *uniforms[] = { "ambient", "diffuse", "specular", "shininess", "scale", "projection", "modelview" }; + m_obj_program.get_uniform_locations(uniforms, 7, uniform_locations); + m_modelview.push(); + m_modelview.translate(m_player->x, m_player->y, 4); + m_modelview.rotate(m_player->direction * 180.0 / M_PI, 0, 0, 1); + m_obj_program.use(); + m_tank_obj.bindBuffers(); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + int stride = m_tank_obj.getStride(); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, + stride, (GLvoid *) m_tank_obj.getVertexOffset()); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, + stride, (GLvoid *) m_tank_obj.getNormalOffset()); + glUniform1f(uniform_locations[4], 2.0f); + m_projection.to_uniform(uniform_locations[5]); + m_modelview.to_uniform(uniform_locations[6]); + for (map::iterator it = + m_tank_obj.getMaterials().begin(); + it != m_tank_obj.getMaterials().end(); + it++) + { + WFObj::Material & m = it->second; + if (m.flags & WFObj::Material::SHININESS_BIT) + { + glUniform1f(uniform_locations[3], m.shininess); + } + if (m.flags & WFObj::Material::AMBIENT_BIT) + { + glUniform4fv(uniform_locations[0], 1, &m.ambient[0]); + } + if (m.flags & WFObj::Material::DIFFUSE_BIT) + { + glUniform4fv(uniform_locations[1], 1, &m.diffuse[0]); + } + if (m.flags & WFObj::Material::SPECULAR_BIT) + { + glUniform4fv(uniform_locations[2], 1, &m.specular[0]); + } + glDrawElements(GL_TRIANGLES, m.num_vertices, + GL_UNSIGNED_SHORT, + (GLvoid *) (sizeof(GLushort) * m.first_vertex)); + } + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glUseProgram(0); + m_modelview.pop(); +} + +void Client::draw_map() +{ + const int width = m_map.get_width(); + const int height = m_map.get_height(); + const float tile_size = 50; + GLint uniform_locations[7]; + const char *uniforms[] = { "ambient", "diffuse", "specular", "shininess", "scale", "projection", "modelview" }; + m_obj_program.get_uniform_locations(uniforms, 7, uniform_locations); + m_obj_program.use(); + glUniform1f(uniform_locations[4], tile_size); + m_projection.to_uniform(uniform_locations[5]); + m_tile_obj.bindBuffers(); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + int stride = m_tile_obj.getStride(); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, + stride, (GLvoid *) m_tile_obj.getVertexOffset()); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, + stride, (GLvoid *) m_tile_obj.getNormalOffset()); + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + if (m_map.tile_present(x, y)) + { + m_modelview.push(); + float cx = m_map.get_tile(x, y)->get_x(); + float cy = m_map.get_tile(x, y)->get_y(); + m_modelview.translate(cx, cy, 0); + m_modelview.to_uniform(uniform_locations[6]); + for (map::iterator it = + m_tile_obj.getMaterials().begin(); + it != m_tile_obj.getMaterials().end(); + it++) + { + WFObj::Material & m = it->second; + if (m.flags & WFObj::Material::SHININESS_BIT) + { + glUniform1f(uniform_locations[3], m.shininess); + } + if (m.flags & WFObj::Material::AMBIENT_BIT) + { + glUniform4fv(uniform_locations[0], 1, &m.ambient[0]); + } + if (m.flags & WFObj::Material::DIFFUSE_BIT) + { + glUniform4fv(uniform_locations[1], 1, &m.diffuse[0]); + } + if (m.flags & WFObj::Material::SPECULAR_BIT) + { + glUniform4fv(uniform_locations[2], 1, &m.specular[0]); + } + glDrawElements(GL_TRIANGLES, m.num_vertices, + GL_UNSIGNED_SHORT, + (GLvoid *) (sizeof(GLushort) * m.first_vertex)); + } + m_modelview.pop(); + } + } + } +} diff --git a/src/client/Client.cc b/src/client/Client.cc index c8e818c..7cfdad4 100755 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -1,89 +1,20 @@ -#include #include -#include GL_INCLUDE_FILE -#include -#include -#include #include "Client.h" -#include -#include -#include "ccfs.h" -#include "HexTile.h" -using namespace std; - -static bool load_file(const char *fname, WFObj::Buffer & buff) +Client::Client() { - unsigned int length; - uint8_t *contents = (uint8_t *) CFS.get_file(fname, &length); - if (contents != NULL) - { - buff.data = contents; - buff.length = length; - return true; - } - return false; } -Client::Client(bool fullscreen, bool compatibility_context, - unsigned int antialias_level) +void Client::run(bool fullscreen, int width, int height) { - sf::VideoMode mode = fullscreen - ? sf::VideoMode::getDesktopMode() - : sf::VideoMode(800, 600, 32); - long style = fullscreen - ? sf::Style::Fullscreen - : sf::Style::Resize | sf::Style::Close; - const unsigned int opengl_major = compatibility_context ? 2 : 4; - const unsigned int opengl_minor = 0u; - sf::ContextSettings cs = sf::ContextSettings(0, 0, antialias_level, - opengl_major, opengl_minor); - m_window = new sf::Window(mode, "Treacherous Terrain", style, cs); - if (gl3wInit()) - { - cerr << "Failed to initialize GL3W" << endl; - } - if (!gl3wIsSupported(3, 0)) - { - cerr << "OpenGL 3.0 is not supported!" << endl; - } - initgl(); - resize_window(m_window->getSize().x, m_window->getSize().y); + if (!create_window(fullscreen, width, height)) + return; m_player = new Player(); m_player->x = 0; m_player->y = 0; m_player->direction = M_PI_2; - GLProgram::AttributeBinding obj_attrib_bindings[] = { - {0, "pos"}, - {1, "normal"}, - {0, NULL} - }; - const char *v_source = (const char *) CFS.get_file("shaders/obj_v.glsl", NULL); - const char *f_source = (const char *) CFS.get_file("shaders/obj_f.glsl", NULL); - if (v_source == NULL || f_source == NULL) - { - cerr << "Error loading shader sources" << endl; - } - else if (!m_obj_program.create(v_source, f_source, - obj_attrib_bindings)) - { - cerr << "Error creating obj program" << endl; - } - if (!m_tank_obj.load("models/tank.obj", load_file)) - { - cerr << "Error loading tank model" << endl; - } - if (!m_tile_obj.load("models/hex-tile.obj", load_file)) - { - cerr << "Error loading hex-tile model" << endl; - } -} - -void Client::run() -{ m_clock.restart(); - m_window->setMouseCursorVisible(false); sf::Mouse::setPosition(sf::Vector2i(m_width / 2, m_height / 2), *m_window); double last_time = 0.0; while (m_window->isOpen()) @@ -117,41 +48,11 @@ void Client::run() } update(elapsed_time); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - double dir_x = cos(m_player->direction); - double dir_y = sin(m_player->direction); - m_modelview.load_identity(); - m_modelview.look_at( - m_player->x - dir_x * 25, m_player->y - dir_y * 25, 30, - m_player->x, m_player->y, 20, - 0, 0, 1); - - draw_players(); - draw_map(); - - m_window->display(); + redraw(); last_time = current_time; } } -void Client::initgl() -{ - glEnable(GL_DEPTH_TEST); - glPolygonOffset(1, 1); -} - -void Client::resize_window(int width, int height) -{ - m_width = width; - m_height = height; - sf::Mouse::setPosition(sf::Vector2i(m_width / 2, m_height / 2), *m_window); - glViewport(0, 0, width, height); - float aspect = (float)width / (float)height; - m_projection.load_identity(); - m_projection.perspective(60.0f, aspect, 1.0f, 5000.0f); -} - void Client::update(double elapsed_time) { const double move_speed = 75.0; @@ -183,117 +84,3 @@ void Client::update(double elapsed_time) sf::Mouse::setPosition(sf::Vector2i(m_width / 2, m_height / 2), *m_window); m_player->direction -= M_PI * 0.5 * xrel / 1000; } - -void Client::draw_players() -{ - GLint uniform_locations[7]; - const char *uniforms[] = { "ambient", "diffuse", "specular", "shininess", "scale", "projection", "modelview" }; - m_obj_program.get_uniform_locations(uniforms, 7, uniform_locations); - m_modelview.push(); - m_modelview.translate(m_player->x, m_player->y, 4); - m_modelview.rotate(m_player->direction * 180.0 / M_PI, 0, 0, 1); - m_obj_program.use(); - m_tank_obj.bindBuffers(); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - int stride = m_tank_obj.getStride(); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, - stride, (GLvoid *) m_tank_obj.getVertexOffset()); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, - stride, (GLvoid *) m_tank_obj.getNormalOffset()); - glUniform1f(uniform_locations[4], 2.0f); - m_projection.to_uniform(uniform_locations[5]); - m_modelview.to_uniform(uniform_locations[6]); - for (map::iterator it = - m_tank_obj.getMaterials().begin(); - it != m_tank_obj.getMaterials().end(); - it++) - { - WFObj::Material & m = it->second; - if (m.flags & WFObj::Material::SHININESS_BIT) - { - glUniform1f(uniform_locations[3], m.shininess); - } - if (m.flags & WFObj::Material::AMBIENT_BIT) - { - glUniform4fv(uniform_locations[0], 1, &m.ambient[0]); - } - if (m.flags & WFObj::Material::DIFFUSE_BIT) - { - glUniform4fv(uniform_locations[1], 1, &m.diffuse[0]); - } - if (m.flags & WFObj::Material::SPECULAR_BIT) - { - glUniform4fv(uniform_locations[2], 1, &m.specular[0]); - } - glDrawElements(GL_TRIANGLES, m.num_vertices, - GL_UNSIGNED_SHORT, - (GLvoid *) (sizeof(GLushort) * m.first_vertex)); - } - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - glUseProgram(0); - m_modelview.pop(); -} - -void Client::draw_map() -{ - const int width = m_map.get_width(); - const int height = m_map.get_height(); - const float tile_size = 50; - GLint uniform_locations[7]; - const char *uniforms[] = { "ambient", "diffuse", "specular", "shininess", "scale", "projection", "modelview" }; - m_obj_program.get_uniform_locations(uniforms, 7, uniform_locations); - m_obj_program.use(); - glUniform1f(uniform_locations[4], tile_size); - m_projection.to_uniform(uniform_locations[5]); - m_tile_obj.bindBuffers(); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - int stride = m_tile_obj.getStride(); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, - stride, (GLvoid *) m_tile_obj.getVertexOffset()); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, - stride, (GLvoid *) m_tile_obj.getNormalOffset()); - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - if (m_map.tile_present(x, y)) - { - m_modelview.push(); - float cx = m_map.get_tile(x, y)->get_x(); - float cy = m_map.get_tile(x, y)->get_y(); - m_modelview.translate(cx, cy, 0); - m_modelview.to_uniform(uniform_locations[6]); - for (map::iterator it = - m_tile_obj.getMaterials().begin(); - it != m_tile_obj.getMaterials().end(); - it++) - { - WFObj::Material & m = it->second; - if (m.flags & WFObj::Material::SHININESS_BIT) - { - glUniform1f(uniform_locations[3], m.shininess); - } - if (m.flags & WFObj::Material::AMBIENT_BIT) - { - glUniform4fv(uniform_locations[0], 1, &m.ambient[0]); - } - if (m.flags & WFObj::Material::DIFFUSE_BIT) - { - glUniform4fv(uniform_locations[1], 1, &m.diffuse[0]); - } - if (m.flags & WFObj::Material::SPECULAR_BIT) - { - glUniform4fv(uniform_locations[2], 1, &m.specular[0]); - } - glDrawElements(GL_TRIANGLES, m.num_vertices, - GL_UNSIGNED_SHORT, - (GLvoid *) (sizeof(GLushort) * m.first_vertex)); - } - m_modelview.pop(); - } - } - } -} diff --git a/src/client/Client.h b/src/client/Client.h index dccde45..6c321bb 100755 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -14,15 +14,17 @@ class Client { public: - Client(bool fullscreen, bool compatibility_context, - unsigned int antialias_level); - void run(); + Client(); + void run(bool fullscreen, int width, int height); protected: - void initgl(); + bool create_window(bool fullscreen, int width, int height); + bool initgl(); void resize_window(int width, int height); void update(double elapsed_time); + void redraw(); void draw_players(); void draw_map(); + refptr m_window; sf::Clock m_clock; Map m_map; diff --git a/src/client/main.cc b/src/client/main.cc index aa4ff30..4cab148 100755 --- a/src/client/main.cc +++ b/src/client/main.cc @@ -6,37 +6,37 @@ int main(int argc, char *argv[]) { bool fullscreen = false; - unsigned int antialias_level = 0u; - bool compatibility_context = false; + int width = 800; + int height = 600; struct option longopts[] = { - {"antialias-level", required_argument, NULL, 'a'}, - {"compatibility", no_argument, NULL, 'c'}, {"fullscreen", no_argument, NULL, 'f'}, + {"height", required_argument, NULL, 'h'}, + {"width", required_argument, NULL, 'w'}, {NULL, 0, NULL, 0} }; for (;;) { - int c = getopt_long(argc, argv, "a:cf", longopts, NULL); + int c = getopt_long(argc, argv, "fh:w:", longopts, NULL); if (c == -1) break; switch (c) { - case 'a': - antialias_level = atoi(optarg); - break; - case 'c': - compatibility_context = true; - break; case 'f': fullscreen = true; break; + case 'h': + height = atoi(optarg); + break; + case 'w': + width = atoi(optarg); + break; } } - Client client(fullscreen, compatibility_context, antialias_level); + Client client; - client.run(); + client.run(fullscreen, width, height); return 0; }