improving aspect ratio and window resize/scaling. done for game objects.

This commit is contained in:
Andreas Ortmann 2016-10-02 11:00:03 +02:00
parent 1562dbe8a7
commit 4353609580
14 changed files with 209 additions and 109 deletions

View file

@ -9,11 +9,12 @@ varying vec3 lightDirection;
uniform mat4 model; uniform mat4 model;
uniform vec3 lightPosition; uniform vec3 lightPosition;
uniform float aspectRatio;
void main() void main()
{ {
// TODO: this becomes invalid when projection matrices are used // TODO: this becomes invalid when projection matrices are used
vec3 p = (model*vec4(in_vertex, 1.0)).xyz; vec3 p = (model*vec4(in_vertex/vec3(aspectRatio, 1.0, 1.0), 1.0)).xyz;
lightDirection = normalize(lightPosition - p); lightDirection = normalize(lightPosition - p);
vertex = p.xyz; vertex = p.xyz;

View file

@ -4,7 +4,6 @@ varying vec3 velocity;
varying float decay; varying float decay;
varying float explCenterDist; varying float explCenterDist;
uniform vec3 explCenter;
vec3 hsv2rgb(vec3 c) vec3 hsv2rgb(vec3 c)
{ {

View file

@ -14,6 +14,8 @@ varying vec3 velocity;
varying vec2 vertex; varying vec2 vertex;
varying float explCenterDist; varying float explCenterDist;
uniform float aspectRatio;
// TODO: rotate to face the user! // TODO: rotate to face the user!
void main() void main()
{ {
@ -38,5 +40,5 @@ void main()
vertex = base.xy; vertex = base.xy;
velocity = in_velocity; velocity = in_velocity;
explCenterDist = length(explCenter-offset); explCenterDist = length(explCenter - offset);
} }

View file

@ -80,3 +80,7 @@ bool Game::cycle(float dt)
return true; return true;
} }
void Game::resize(int width, int height)
{
m_state->setPlayingFieldSize(width, height);
}

View file

@ -13,6 +13,9 @@ class Game {
// for rendering // for rendering
game::State *state() const { return m_state; } game::State *state() const { return m_state; }
// resize the playing field
void resize(int width, int height);
private: private:
game::State *m_state; game::State *m_state;

View file

@ -45,7 +45,21 @@ class GameWindow : public endofthejedi::GLWindow {
m_renderer.render(m_game->state()); m_renderer.render(m_game->state());
} }
void resize() override { glViewport(0, 0, getwidth(), getheight()); } void resize() override
{
std::cout<<"resize()" << std::endl;
glViewport(0, 0, getwidth(), getheight());
// resize the game
m_game->resize(getwidth(), getheight());
// TODO: mark it and let the reinit() happen in the next so it happnens just once. while doing the resize
m_game->state()->init();
// resize the renderer
m_renderer.setWindowSize(getwidth(), getheight());
}
public: public:
GameWindow(unsigned int width, unsigned int height, Game *ptr) GameWindow(unsigned int width, unsigned int height, Game *ptr)

View file

@ -99,6 +99,7 @@ namespace endofthejedi {
m_width = attribs.width; m_width = attribs.width;
m_height = attribs.height; m_height = attribs.height;
resize(); resize();
} else if (event.type == ClientMessage) { } else if (event.type == ClientMessage) {
if (event.xclient.data.l[0] == m_atomWmDeleteWindow) { if (event.xclient.data.l[0] == m_atomWmDeleteWindow) {
stop(); stop();

View file

@ -5,6 +5,8 @@
#include <epoxy/gl.h> #include <epoxy/gl.h>
#include <epoxy/glx.h> #include <epoxy/glx.h>
#include <glm/gtc/matrix_transform.hpp>
#include "game.hpp" #include "game.hpp"
namespace endofthejedi { namespace endofthejedi {
@ -21,6 +23,9 @@ namespace endofthejedi {
public: public:
virtual void setup() { } virtual void setup() { }
virtual void render(const game::State *state) = 0; virtual void render(const game::State *state) = 0;
virtual void setWindowSize(int px, int py) { (void) px; (void) py; }
virtual void setCameraMatrix(const glm::mat4 &cam) { (void) cam; }
}; };
} }

View file

@ -33,14 +33,16 @@ namespace endofthejedi {
m_data_velocity.resize(m_numParticles); m_data_velocity.resize(m_numParticles);
m_data_kind.resize(m_numParticles); m_data_kind.resize(m_numParticles);
m_data_max_age.resize(m_numParticles); m_data_max_age.resize(m_numParticles);
}
std::string vss_particles = "../data/shader/particle.vert"; ParticleBatch::~ParticleBatch()
std::string fss_particles = "../data/shader/particle.frag"; {
// TODO: find out if stuff must be deallocated
m_shader.init(); glDeleteBuffers(5, m_data_vbos);
m_shader.loadFile(vss_particles, GL_VERTEX_SHADER); }
m_shader.loadFile(fss_particles, GL_FRAGMENT_SHADER);
void ParticleBatch::setup(Shader *shader)
{
const char *names[] = { const char *names[] = {
"in_vertex", "in_vertex",
"in_position", "in_position",
@ -51,18 +53,12 @@ namespace endofthejedi {
for (int i=0; i<5; i++) { for (int i=0; i<5; i++) {
const char *name = names[i]; const char *name = names[i];
GLint loc = glGetAttribLocation(m_shader.program(), name); GLint loc = glGetAttribLocation(shader->program(), name);
m_attr_locations[i] = loc; m_attr_locations[i] = loc;
//std::cout<<"attr location " << i << " " << loc << " " << name << std::endl; //std::cout<<"attr location " << i << " " << loc << " " << name << std::endl;
} }
} }
ParticleBatch::~ParticleBatch()
{
// TODO: find out if stuff must be deallocated
glDeleteBuffers(5, m_data_vbos);
}
void ParticleBatch::setCenter(const glm::vec3 &center) void ParticleBatch::setCenter(const glm::vec3 &center)
{ {
m_center = center; m_center = center;
@ -130,16 +126,14 @@ namespace endofthejedi {
} }
} }
void ParticleBatch::render() void ParticleBatch::render(Shader *shader)
{ {
//std::cout<<"[ParticleBatch] render " << std::endl; //std::cout<<"[ParticleBatch] render " << std::endl;
m_shader.bind(); glUniform1f(shader->location("age"), m_age);
glUniform1f(shader->location("maxVelocity"), m_maxVelocity);
glUniform1f(m_shader.location("age"), m_age); glUniform1f(shader->location("halfAge"), m_halfAge);
glUniform1f(m_shader.location("maxVelocity"), m_maxVelocity); glUniform1f(shader->location("size"), m_particleRadius);
glUniform1f(m_shader.location("halfAge"), m_halfAge); glUniform3f(shader->location("explCenter"), m_center.x, m_center.y, m_center.z);
glUniform1f(m_shader.location("size"), m_particleRadius);
glUniform3f(m_shader.location("explCenter"), m_center.x, m_center.y, m_center.z);
bind(); bind();

View file

@ -22,15 +22,14 @@ namespace endofthejedi {
void setCenter(const glm::vec3 &center); void setCenter(const glm::vec3 &center);
void setMaxVelocity(float maxVelocity); void setMaxVelocity(float maxVelocity);
void setup(Shader *shader);
void bind(); void bind();
void upload(); void upload();
void render(); void render(Shader *shader);
void tick(float dt); void tick(float dt);
bool done() const; bool done() const;
Shader *shader() { return &m_shader; }
size_t id() const { return m_id; } size_t id() const { return m_id; }
private: private:
@ -55,7 +54,5 @@ namespace endofthejedi {
std::vector<float> m_data_max_age; std::vector<float> m_data_max_age;
GLuint m_attr_locations[5]; GLuint m_attr_locations[5];
Shader m_shader;
}; };
} }

View file

@ -2,11 +2,6 @@
#include <iostream> #include <iostream>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/euler_angles.hpp>
#include <glm/gtc/random.hpp>
namespace endofthejedi { namespace endofthejedi {
void RendererPolygon3d::setup() void RendererPolygon3d::setup()
{ {
@ -14,19 +9,21 @@ namespace endofthejedi {
std::cout<<"setup polygon 3d" << std::endl; std::cout<<"setup polygon 3d" << std::endl;
m_shader.init();
#if 0
std::string vss_simple = "../data/shader/simple.vert";
std::string fss_simple = "../data/shader/simple.frag";
m_shader.loadFile(vss_simple, GL_VERTEX_SHADER);
m_shader.loadFile(fss_simple, GL_FRAGMENT_SHADER);
#else
std::string vss_game_objects = "../data/shader/gameobjects.vert"; std::string vss_game_objects = "../data/shader/gameobjects.vert";
std::string fss_game_objects = "../data/shader/gameobjects.frag"; std::string fss_game_objects = "../data/shader/gameobjects.frag";
m_shader.loadFile(vss_game_objects, GL_VERTEX_SHADER);
m_shader.loadFile(fss_game_objects, GL_FRAGMENT_SHADER); m_shader_game_objects.init();
#endif m_shader_game_objects.loadFile(vss_game_objects, GL_VERTEX_SHADER);
m_shader_game_objects.loadFile(fss_game_objects, GL_FRAGMENT_SHADER);
std::string vss_particles = "../data/shader/particle.vert";
std::string fss_particles = "../data/shader/particle.frag";
m_shader_particles.init();
m_shader_particles.loadFile(vss_particles, GL_VERTEX_SHADER);
m_shader_particles.loadFile(fss_particles, GL_FRAGMENT_SHADER);
//addModel("../data/mesh/small_atomic_bomb.stl", &m_missileModel); //addModel("../data/mesh/small_atomic_bomb.stl", &m_missileModel);
addModel("../data/mesh/rocket.stl", &m_missileModel); addModel("../data/mesh/rocket.stl", &m_missileModel);
@ -56,17 +53,22 @@ namespace endofthejedi {
//float s = 0.1; //float s = 0.1;
//glClearColor(s, s, s, 1.0); //glClearColor(s, s, s, 1.0);
m_shader.bind(); m_shader_game_objects.bind();
// TODO: add ONE sun planet // TODO: add ONE sun planet
// TODO: add lights for explosions // TODO: add lights for explosions
configureLightningInShader(); configureLightningInShader();
//std::cout<<"setting aspect ratio: " << m_aspectRatio << std::endl;
glUniform1f(m_shader_game_objects.location("aspectRatio"), m_aspectRatio);
renderPlanets(); renderPlanets();
renderShips(); renderShips();
renderMissiles(); renderMissiles();
renderParticles(); renderParticles();
renderTraces(); renderTraces();
//glColor3f(1.0, 0.0, 0.0); //glColor3f(1.0, 0.0, 0.0);
@ -82,9 +84,13 @@ namespace endofthejedi {
void RendererPolygon3d::renderParticles() void RendererPolygon3d::renderParticles()
{ {
m_shader_particles.bind();
glUniform1f(m_shader_particles.location("aspectRatio"), m_aspectRatio);
for (ParticleBatch *batch : m_particles) { for (ParticleBatch *batch : m_particles) {
batch->bind(); batch->bind();
batch->render(); batch->render(&m_shader_particles);
} }
} }
@ -100,6 +106,7 @@ namespace endofthejedi {
float maxVelocity = 0.4f; float maxVelocity = 0.4f;
ParticleBatch *batch = new ParticleBatch(id, n, particleRadius, duration); ParticleBatch *batch = new ParticleBatch(id, n, particleRadius, duration);
batch->setup(&m_shader_particles);
batch->setCenter(glm::vec3(pos, 0.0)); batch->setCenter(glm::vec3(pos, 0.0));
batch->setMaxVelocity(maxVelocity); batch->setMaxVelocity(maxVelocity);
@ -168,12 +175,12 @@ namespace endofthejedi {
// too (same for missiles) // too (same for missiles)
for (const game::Planet *planet : m_state->planets) { for (const game::Planet *planet : m_state->planets) {
glm::mat4 model = computeModelMatrix(planet); glm::mat4 model = computeModelMatrix(planet);
glUniformMatrix4fv(m_shader.location("model"), 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(m_shader_game_objects.location("model"), 1, GL_FALSE, glm::value_ptr(model));
glm::vec3 c = planet->getColor(); glm::vec3 c = planet->getColor();
glUniform3f(m_shader.location("materialColor"), c.x, c.y, c.z); glUniform3f(m_shader_game_objects.location("materialColor"), c.x, c.y, c.z);
glUniform1i(m_shader.location("materialSeed"), planet->seed); glUniform1i(m_shader_game_objects.location("materialSeed"), planet->seed);
glUniform1i(m_shader.location("materialKind"), (int) planet->material); glUniform1i(m_shader_game_objects.location("materialKind"), (int) planet->material);
m_planetModel->render(); m_planetModel->render();
} }
@ -186,10 +193,10 @@ namespace endofthejedi {
for (const game::Player *player : m_state->players) { for (const game::Player *player : m_state->players) {
for (const game::Missile *missile : player->missiles) { for (const game::Missile *missile : player->missiles) {
glm::vec3 c = glm::vec3(1.0, 1.0, 0.3); glm::vec3 c = glm::vec3(1.0, 1.0, 0.3);
glUniform3f(m_shader.location("materialColor"), c.x, c.y, c.z); glUniform3f(m_shader_game_objects.location("materialColor"), c.x, c.y, c.z);
glm::mat4 model = computeModelMatrix(missile); glm::mat4 model = computeModelMatrix(missile);
glUniformMatrix4fv(m_shader.location("model"), 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(m_shader_game_objects.location("model"), 1, GL_FALSE, glm::value_ptr(model));
m_missileModel->render(); m_missileModel->render();
} }
@ -202,10 +209,10 @@ namespace endofthejedi {
for (const game::Ship *ship : m_state->ships) { for (const game::Ship *ship : m_state->ships) {
glm::mat4 model = computeModelMatrix(ship); glm::mat4 model = computeModelMatrix(ship);
glUniformMatrix4fv(m_shader.location("model"), 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(m_shader_game_objects.location("model"), 1, GL_FALSE, glm::value_ptr(model));
glm::vec3 c = glm::vec3(0.1, 1.0, 0.2); glm::vec3 c = glm::vec3(0.1, 1.0, 0.2);
glUniform3f(m_shader.location("materialColor"), c.x, c.y, c.z); glUniform3f(m_shader_game_objects.location("materialColor"), c.x, c.y, c.z);
m_shipModel->render(); m_shipModel->render();
} }
@ -221,7 +228,7 @@ namespace endofthejedi {
exit(-1); exit(-1);
} }
(*dest)->setup(&m_shader); (*dest)->setup(&m_shader_game_objects);
(*dest)->uploadToOpenGl(); (*dest)->uploadToOpenGl();
m_models.push_back(*dest); m_models.push_back(*dest);
@ -319,7 +326,17 @@ namespace endofthejedi {
} }
} }
glUniform3f(m_shader.location("lightPosition"), p.x, p.y, p.z); glUniform3f(m_shader_game_objects.location("lightPosition"), p.x, p.y, p.z);
glUniform3f(m_shader.location("lightColor"), c.x, c.y, c.z); glUniform3f(m_shader_game_objects.location("lightColor"), c.x, c.y, c.z);
}
void RendererPolygon3d::setWindowSize(int px, int py)
{
m_aspectRatio = (float) px / (float) py;
}
void RendererPolygon3d::setCameraMatrix(const glm::mat4 &cam)
{
(void) cam;
} }
} }

View file

@ -2,6 +2,13 @@
#include <list> #include <list>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/euler_angles.hpp>
#include <glm/gtc/random.hpp>
#include <glm/vec3.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "glclasses.hpp" #include "glclasses.hpp"
#include "game.hpp" #include "game.hpp"
@ -17,9 +24,6 @@
#include "particle_batch.hpp" #include "particle_batch.hpp"
#include "polygon_model.hpp" #include "polygon_model.hpp"
#include <glm/vec3.hpp>
#include <glm/gtc/matrix_transform.hpp>
namespace endofthejedi { namespace endofthejedi {
class RendererPolygon3d : public Renderer { class RendererPolygon3d : public Renderer {
@ -27,6 +31,9 @@ namespace endofthejedi {
void setup(); void setup();
void render(const game::State *state) override; void render(const game::State *state) override;
void setWindowSize(int px, int py);
void setCameraMatrix(const glm::mat4 &cam);
private: private:
void renderPlanets(); void renderPlanets();
void renderMissiles(); void renderMissiles();
@ -61,7 +68,8 @@ namespace endofthejedi {
PolygonModel *m_shipModel; PolygonModel *m_shipModel;
// for rendering everything // for rendering everything
Shader m_shader; Shader m_shader_game_objects;
Shader m_shader_particles;
// for accessing // for accessing
const game::State *m_state; const game::State *m_state;
@ -70,5 +78,7 @@ namespace endofthejedi {
// time value for last rendering cycle (-1 after setup/startup) // time value for last rendering cycle (-1 after setup/startup)
float m_lastTime; float m_lastTime;
float m_aspectRatio;
}; };
} }

View file

@ -10,7 +10,6 @@
#include "object.hpp" #include "object.hpp"
#include "missile.hpp" #include "missile.hpp"
#include "player.hpp" #include "player.hpp"
#include "planet.hpp"
#include "ship.hpp" #include "ship.hpp"
#include "commands.hpp" #include "commands.hpp"
#include "trace.hpp" #include "trace.hpp"
@ -21,6 +20,14 @@
namespace game { namespace game {
void State::init(int numPlanets, bool devMode) void State::init(int numPlanets, bool devMode)
{ {
for (Planet *planet : planets) {
delete(planet);
}
planets.clear();
//for (Player *player : players) {
//}
m_nextId = 0; m_nextId = 0;
m_time = 0.0; m_time = 0.0;
m_shipRadius = 0.02; m_shipRadius = 0.02;
@ -30,57 +37,34 @@ namespace game {
m_maxNumTraces = 10; m_maxNumTraces = 10;
m_developerMode = devMode; m_developerMode = devMode;
Planet::Material mat = Planet::Material::Rock; setPlayingFieldCenter(0, 0);
for (int i=0; i<numPlanets; i++) { // TODO: need aspect ratio or data!
switch(i) { //setPlayingFieldSize(1000, 300);
case 0:
mat = Planet::Material::Sun;
break;
case 1: setupPlanets(numPlanets);
case 2:
mat = Planet::Material::Water;
break;
case 3:
case 4:
mat = Planet::Material::Sand;
break;
case 5:
mat = Planet::Material::Metal;
break;
default:
mat = Planet::Material::Rock;
} }
glm::vec2 pos; bool State::findPlanetSpawnPosition(bool planetIsSun, float radius, glm::vec2 *pos)
float radius = 0.03 + 0.07*util::randf_0_1(); {
if (i == 0) { (void) planetIsSun;
// sun is bigger but not too big
radius += 0.05;
if (radius > 0.9) {
radius = 0.9;
}
}
bool tooNearToCenter = true; bool tooNearToCenter = true;
bool collidesWithOtherPlanet = true; bool collidesWithOtherPlanet = true;
const glm::vec2 spawnArea = 0.9f * (m_playingFieldSize/std::max(m_playingFieldSize.x, m_playingFieldSize.y));
// distribute but not in the center and not next to other planets // distribute but not in the center and not next to other planets
int tries = 0; int tries = 0;
do { do {
pos = util::randv2_m1_1(); *pos = spawnArea * util::randv2_m1_1();
collidesWithOtherPlanet = false; collidesWithOtherPlanet = false;
tooNearToCenter = glm::length(pos) < 0.1; tooNearToCenter = glm::length(*pos) < 0.1;
if (!tooNearToCenter) { if (!tooNearToCenter) {
for (const Planet *other : planets) { for (const Planet *other : planets) {
float d = glm::distance(other->position, pos); float d = glm::distance(other->position, *pos);
float extraDist = (other->material == Planet::Material::Sun) float extraDist = (other->material == Planet::Material::Sun)
? 4.0 ? 4.0
@ -92,12 +76,59 @@ namespace game {
} }
} }
} }
if (tries++ > 1000) {
return false;
}
} while((collidesWithOtherPlanet || tooNearToCenter) && tries++ < 1000); } while(collidesWithOtherPlanet || tooNearToCenter);
return true;
}
void State::setupPlanets(int numPlanets)
{
for (int i=0; i<numPlanets; i++) {
Planet::Material mat = materialForStandardPlanetDistribution(i);
float radius = 0.03 + 0.07*util::randf_0_1();
if (i == 0) {
// sun is bigger but not too big
radius += 0.05;
if (radius > 0.9) {
radius = 0.9;
}
}
glm::vec2 pos;
if (findPlanetSpawnPosition(mat == Planet::Material::Sun, radius, &pos)) {
planets.push_back(new Planet(pos, i, radius, mat)); planets.push_back(new Planet(pos, i, radius, mat));
} }
} }
}
Planet::Material State::materialForStandardPlanetDistribution(int index)
{
// a few sun/water/sand/metall planents and the rest rocks
switch(index) {
case 0:
return Planet::Material::Sun;
case 1:
case 2:
return Planet::Material::Water;
case 3:
case 4:
return Planet::Material::Sand;
case 5:
return Planet::Material::Metal;
default:
return Planet::Material::Rock;
}
}
bool State::spawnShipForPlayer(Player *player) bool State::spawnShipForPlayer(Player *player)
{ {
@ -430,4 +461,14 @@ namespace game {
deleteTrace(trace); deleteTrace(trace);
} }
} }
void State::setPlayingFieldCenter(int center_x, int center_y)
{
m_playingFieldCenter = glm::vec2((float) center_x, (float) center_y);
}
void State::setPlayingFieldSize(int width, int height)
{
m_playingFieldSize = glm::vec2(width, height);
}
} }

View file

@ -10,6 +10,7 @@
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
#include "missile.hpp" #include "missile.hpp"
#include "planet.hpp"
// TODO: // TODO:
// give points for equipment / better weapons / more energy when: // give points for equipment / better weapons / more energy when:
@ -27,7 +28,7 @@ namespace game {
// forward declarations // forward declarations
class Command; class Command;
class Player; class Player;
class Planet;
class Ship; class Ship;
class Trace; class Trace;
class Explosion; class Explosion;
@ -91,6 +92,11 @@ namespace game {
m_developerMode = on; m_developerMode = on;
} }
// called when the rendering window changes
// TODO: give dpi as information too
void setPlayingFieldSize(int width, int height);
void setPlayingFieldCenter(int width, int height);
/*************************************************************************/ /*************************************************************************/
/* Rendering */ /* Rendering */
/*************************************************************************/ /*************************************************************************/
@ -111,12 +117,15 @@ namespace game {
void playerKillsPlayer(Player *killer, Player *victim); void playerKillsPlayer(Player *killer, Player *victim);
void addExplosionFromHit(const Missile::Event *evt); void addExplosionFromHit(const Missile::Event *evt);
bool findPlanetSpawnPosition(bool planetIsSun, float radius, glm::vec2 *pos);
void advanceTraceAges(float dt); void advanceTraceAges(float dt);
void advanceExplosions(float dt); void advanceExplosions(float dt);
void advancePlayerShipSpawns(float dt); void advancePlayerShipSpawns(float dt);
void advancePlayerCommands(float dt); void advancePlayerCommands(float dt);
void advancePlayerMissiles(float dt); void advancePlayerMissiles(float dt);
void setupPlanets(int numPlanets);
Planet::Material materialForStandardPlanetDistribution(int index);
// try to spawn a ship for this player. // try to spawn a ship for this player.
// return true on success, false on failure to find a spot. // return true on success, false on failure to find a spot.
@ -134,5 +143,8 @@ namespace game {
int m_maxNumTraces; int m_maxNumTraces;
float m_time; float m_time;
bool m_developerMode; bool m_developerMode;
glm::vec2 m_playingFieldCenter;
glm::vec2 m_playingFieldSize;
}; };
}; };