2016-09-28 09:50:35 +00:00
|
|
|
#include "renderer_polygon_3d.hpp"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
2016-09-28 13:33:35 +00:00
|
|
|
#include <glm/gtc/type_ptr.hpp>
|
2016-09-28 13:10:57 +00:00
|
|
|
#include <glm/gtc/matrix_transform.hpp>
|
2016-09-28 13:33:35 +00:00
|
|
|
#include <glm/gtx/euler_angles.hpp>
|
2016-09-28 12:19:05 +00:00
|
|
|
|
2016-09-28 09:50:35 +00:00
|
|
|
namespace endofthejedi {
|
|
|
|
void RendererPolygon3d::setup()
|
|
|
|
{
|
2016-09-29 06:28:56 +00:00
|
|
|
m_lastTime = -1.0;
|
|
|
|
|
2016-09-28 12:19:05 +00:00
|
|
|
std::cout<<"setup polygon 3d" << std::endl;
|
2016-09-28 11:00:40 +00:00
|
|
|
|
2016-09-28 12:19:05 +00:00
|
|
|
//m_missileModel = new PolygonModel("../data/mesh/quad_screen_coords.stl");
|
2016-09-28 11:16:11 +00:00
|
|
|
|
2016-09-28 12:19:05 +00:00
|
|
|
addModel("../data/mesh/small_atomic_bomb.stl", &m_missileModel);
|
2016-09-29 06:47:32 +00:00
|
|
|
addModel("../data/mesh/planet_64.stl", &m_planetModel);
|
|
|
|
addModel("../data/mesh/ship_ufo.stl", &m_shipModel);
|
2016-09-28 11:36:22 +00:00
|
|
|
|
2016-09-28 12:19:05 +00:00
|
|
|
std::string vss_simple =
|
2016-09-29 00:50:51 +00:00
|
|
|
#include "simple.vert"
|
2016-09-28 11:36:22 +00:00
|
|
|
;
|
|
|
|
|
2016-09-28 12:19:05 +00:00
|
|
|
std::string fss_simple =
|
2016-09-29 00:50:51 +00:00
|
|
|
#include "simple.frag"
|
2016-09-28 11:36:22 +00:00
|
|
|
;
|
|
|
|
|
2016-09-28 12:19:05 +00:00
|
|
|
std::string vss_game_objects =
|
2016-09-29 00:50:51 +00:00
|
|
|
#include "gameobjects.vert"
|
2016-09-28 12:19:05 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
std::string fss_game_objects =
|
2016-09-29 00:50:51 +00:00
|
|
|
#include "gameobjects.frag"
|
2016-09-28 12:19:05 +00:00
|
|
|
;
|
|
|
|
|
2016-09-28 11:36:22 +00:00
|
|
|
m_shader.init();
|
2016-09-28 12:19:05 +00:00
|
|
|
|
|
|
|
#if 0
|
2016-09-29 00:50:51 +00:00
|
|
|
(void) vss_simple;
|
|
|
|
(void) fss_simple;
|
2016-09-28 12:19:05 +00:00
|
|
|
m_shader.load(vss_simple.c_str(), GL_VERTEX_SHADER);
|
|
|
|
m_shader.load(fss_simple.c_str(), GL_FRAGMENT_SHADER);
|
|
|
|
#else
|
2016-09-29 00:50:51 +00:00
|
|
|
(void) vss_game_objects;
|
|
|
|
(void) fss_game_objects;
|
2016-09-28 12:19:05 +00:00
|
|
|
m_shader.load(vss_game_objects.c_str(), GL_VERTEX_SHADER);
|
|
|
|
m_shader.load(fss_game_objects.c_str(), GL_FRAGMENT_SHADER);
|
|
|
|
#endif
|
2016-09-28 09:50:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void RendererPolygon3d::render(const game::State *state)
|
|
|
|
{
|
2016-09-29 06:28:56 +00:00
|
|
|
if (m_lastTime == -1.0) {
|
|
|
|
m_lastTime = state->timestamp();
|
|
|
|
}
|
|
|
|
|
|
|
|
float dt = state->timestamp() - m_lastTime;
|
|
|
|
if (dt < 0.0) {
|
|
|
|
dt = 0.0;
|
|
|
|
}
|
|
|
|
|
2016-09-28 14:12:25 +00:00
|
|
|
m_state = state;
|
2016-09-29 06:28:56 +00:00
|
|
|
advanceGraphicObjects(dt);
|
|
|
|
|
2016-09-29 09:38:26 +00:00
|
|
|
// TODO: add stars (texture)
|
|
|
|
// TODO: add dust particles
|
|
|
|
// TODO: add little rocks flying around
|
|
|
|
|
|
|
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
|
|
|
2016-09-28 11:36:22 +00:00
|
|
|
m_shader.bind();
|
|
|
|
|
2016-09-29 09:38:26 +00:00
|
|
|
glm::vec3 c = glm::vec3(1.0, 1.0, 0.5);
|
|
|
|
glUniform3f(m_shader.location("lightColor"), c.x, c.y, c.z);
|
|
|
|
|
2016-09-29 09:43:00 +00:00
|
|
|
//glm::vec3 p = glm::vec3(1.0, 0.0, 0.0);
|
|
|
|
glm::vec3 p = glm::vec3(0.5f, 0.5f, -4.0f);
|
2016-09-29 09:38:26 +00:00
|
|
|
glUniform3f(m_shader.location("lightPosition"), p.x, p.y, p.z);
|
|
|
|
|
2016-09-28 22:52:58 +00:00
|
|
|
renderPlanets();
|
|
|
|
renderShips();
|
|
|
|
renderMissiles();
|
2016-09-28 12:41:15 +00:00
|
|
|
|
2016-09-29 07:05:35 +00:00
|
|
|
//glDisable(GL_DEPTH_TEST);
|
2016-09-29 09:38:26 +00:00
|
|
|
//renderParticles();
|
2016-09-29 07:05:35 +00:00
|
|
|
//glEnable(GL_DEPTH_TEST);
|
2016-09-28 19:26:11 +00:00
|
|
|
|
2016-09-29 07:36:57 +00:00
|
|
|
renderTraces();
|
|
|
|
|
2016-09-28 11:38:31 +00:00
|
|
|
//glColor3f(1.0, 0.0, 0.0);
|
|
|
|
//glBegin(GL_QUADS);
|
|
|
|
//glVertex2f(-1.0f, -1.0f);
|
|
|
|
//glVertex2f(1.0f, -1.0f);
|
|
|
|
//glVertex2f(1.0f, 1.0f);
|
|
|
|
//glVertex2f(-1.0f, 1.0f);
|
|
|
|
//glEnd();
|
2016-09-29 06:28:56 +00:00
|
|
|
|
|
|
|
m_lastTime = state->timestamp();
|
2016-09-28 12:19:05 +00:00
|
|
|
}
|
|
|
|
|
2016-09-28 19:26:11 +00:00
|
|
|
void RendererPolygon3d::renderParticles()
|
|
|
|
{
|
2016-09-29 06:28:56 +00:00
|
|
|
for (ParticleBatch *batch : m_particles) {
|
|
|
|
batch->bind();
|
|
|
|
batch->render();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RendererPolygon3d::addExplosionEffect(const glm::vec2 &pos, size_t n, float duration)
|
|
|
|
{
|
|
|
|
ParticleBatch *batch = new ParticleBatch(n, 0.005, duration);
|
|
|
|
|
|
|
|
for (size_t i=0; i<n; i++) {
|
|
|
|
// distribute in a circle
|
2016-09-29 07:05:35 +00:00
|
|
|
float t = 4.0 * M_PI * i / (float) n;
|
2016-09-29 06:28:56 +00:00
|
|
|
t += 0.2*util::randf_m1_1();
|
|
|
|
|
|
|
|
// with random velocities
|
|
|
|
glm::vec2 v = 0.2f*glm::vec2(sin(t), cos(t));
|
2016-09-29 07:05:35 +00:00
|
|
|
v *= 0.2+0.8*util::randf_0_1();
|
2016-09-29 06:28:56 +00:00
|
|
|
|
|
|
|
batch->setParticle(i, pos, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
batch->upload();
|
|
|
|
|
|
|
|
m_particles.push_back(batch);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RendererPolygon3d::advanceGraphicObjects(float dt)
|
|
|
|
{
|
2016-09-29 07:05:35 +00:00
|
|
|
for (const game::Explosion *expl : m_state->explosions) {
|
|
|
|
if (expl->age == 0.0) {
|
|
|
|
addExplosionEffect(expl->position, 200, 3.0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<ParticleBatch*> rm;
|
|
|
|
|
2016-09-29 06:28:56 +00:00
|
|
|
for (ParticleBatch *batch : m_particles) {
|
|
|
|
batch->tick(dt);
|
|
|
|
if (batch->done()) {
|
2016-09-29 07:05:35 +00:00
|
|
|
rm.push_back(batch);
|
2016-09-29 06:28:56 +00:00
|
|
|
}
|
|
|
|
}
|
2016-09-29 07:05:35 +00:00
|
|
|
|
|
|
|
for (ParticleBatch *batch : rm) {
|
|
|
|
m_particles.remove(batch);
|
|
|
|
delete(batch);
|
|
|
|
}
|
2016-09-28 19:26:11 +00:00
|
|
|
}
|
|
|
|
|
2016-09-28 14:12:25 +00:00
|
|
|
void RendererPolygon3d::renderPlanets()
|
2016-09-28 12:19:05 +00:00
|
|
|
{
|
2016-09-29 06:28:56 +00:00
|
|
|
m_planetModel->bind(m_shader);
|
2016-09-28 12:19:05 +00:00
|
|
|
|
2016-09-28 14:12:25 +00:00
|
|
|
for (const game::Planet *planet : m_state->planets) {
|
|
|
|
glm::mat4 model = computeModelMatrix(planet);
|
2016-09-28 13:22:16 +00:00
|
|
|
glUniformMatrix4fv(m_shader.location("model"), 1, GL_FALSE, glm::value_ptr(model));
|
|
|
|
|
2016-09-29 00:50:51 +00:00
|
|
|
glm::vec3 c = planet->getColor();
|
2016-09-29 09:38:26 +00:00
|
|
|
glUniform3f(m_shader.location("materialColor"), c.x, c.y, c.z);
|
2016-09-29 00:50:51 +00:00
|
|
|
glUniform3f(m_shader.location("color"), c.x, c.y, c.z);
|
2016-09-28 12:19:05 +00:00
|
|
|
|
2016-09-29 02:24:14 +00:00
|
|
|
m_planetModel->render(m_shader);
|
2016-09-28 12:19:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-28 14:12:25 +00:00
|
|
|
void RendererPolygon3d::renderMissiles()
|
2016-09-28 12:19:05 +00:00
|
|
|
{
|
2016-09-29 06:28:56 +00:00
|
|
|
m_missileModel->bind(m_shader);
|
2016-09-28 12:41:15 +00:00
|
|
|
|
2016-09-28 14:12:25 +00:00
|
|
|
for (const game::Player *player : m_state->players) {
|
2016-09-28 12:41:15 +00:00
|
|
|
for (const game::Missile *missile : player->missiles) {
|
|
|
|
glm::vec3 c = glm::vec3(1.0, 1.0, 0.3);
|
2016-09-29 09:38:26 +00:00
|
|
|
glUniform3f(m_shader.location("materialColor"), c.x, c.y, c.z);
|
2016-09-28 13:10:57 +00:00
|
|
|
|
2016-09-28 14:12:25 +00:00
|
|
|
glm::mat4 model = computeModelMatrix(missile);
|
2016-09-28 13:22:16 +00:00
|
|
|
glUniformMatrix4fv(m_shader.location("model"), 1, GL_FALSE, glm::value_ptr(model));
|
2016-09-28 12:41:15 +00:00
|
|
|
|
2016-09-29 02:24:14 +00:00
|
|
|
m_missileModel->render(m_shader);
|
2016-09-28 12:41:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-28 14:12:25 +00:00
|
|
|
void RendererPolygon3d::renderShips()
|
2016-09-28 12:41:15 +00:00
|
|
|
{
|
2016-09-29 06:28:56 +00:00
|
|
|
m_shipModel->bind(m_shader);
|
2016-09-28 12:41:15 +00:00
|
|
|
|
2016-09-28 14:12:25 +00:00
|
|
|
for (const game::Ship *ship : m_state->ships) {
|
|
|
|
glm::mat4 model = computeModelMatrix(ship);
|
2016-09-28 13:22:16 +00:00
|
|
|
glUniformMatrix4fv(m_shader.location("model"), 1, GL_FALSE, glm::value_ptr(model));
|
|
|
|
|
2016-09-28 14:12:25 +00:00
|
|
|
glm::vec3 c = glm::vec3(0.1, 1.0, 0.2);
|
2016-09-29 09:38:26 +00:00
|
|
|
glUniform3f(m_shader.location("materialColor"), c.x, c.y, c.z);
|
2016-09-28 12:41:15 +00:00
|
|
|
|
2016-09-29 02:24:14 +00:00
|
|
|
m_shipModel->render(m_shader);
|
2016-09-28 12:41:15 +00:00
|
|
|
}
|
2016-09-28 12:19:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void RendererPolygon3d::addModel(const std::string &filename, PolygonModel **dest)
|
|
|
|
{
|
2016-09-28 13:10:57 +00:00
|
|
|
//std::cout<<"adding a model: " << filename << std::endl;
|
2016-09-28 12:19:05 +00:00
|
|
|
|
|
|
|
*dest = new PolygonModel(filename);
|
|
|
|
if (!(*dest)->import()) {
|
|
|
|
std::cout<<"error: failed to load needed model!!!" << std::endl << std::endl;
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
(*dest)->uploadToOpenGl();
|
2016-09-28 11:16:11 +00:00
|
|
|
|
2016-09-28 12:19:05 +00:00
|
|
|
m_models.push_back(*dest);
|
2016-09-28 09:50:35 +00:00
|
|
|
}
|
2016-09-28 14:12:25 +00:00
|
|
|
|
|
|
|
glm::mat4 RendererPolygon3d::computeModelMatrix(const game::Planet *planet)
|
|
|
|
{
|
|
|
|
return computeModelMatrix(planet->position, planet->radius);
|
|
|
|
}
|
|
|
|
|
|
|
|
glm::mat4 RendererPolygon3d::computeModelMatrix(const game::Missile *missile)
|
|
|
|
{
|
|
|
|
glm::vec2 vn = glm::normalize(missile->velocity);
|
|
|
|
float a = std::atan2(vn.y, vn.x);
|
|
|
|
|
|
|
|
// TODO: which visual size has the rocket? in game its just a point with
|
|
|
|
// no size because all others have size.
|
2016-09-29 07:05:35 +00:00
|
|
|
return computeModelMatrix(missile->position, 0.03f, a);
|
2016-09-28 14:12:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glm::mat4 RendererPolygon3d::computeModelMatrix(const game::Ship *ship)
|
|
|
|
{
|
|
|
|
// TODO: rotate them before shooting, that looks better
|
2016-09-29 07:05:35 +00:00
|
|
|
glm::mat4 mat = computeModelMatrix(ship->position, m_state->shipRadius());
|
2016-09-29 06:47:32 +00:00
|
|
|
// XXX model is flipped
|
2016-09-29 07:05:35 +00:00
|
|
|
//glm::mat4 mat = computeModelMatrix(ship->position, 0.3);
|
2016-09-29 06:47:32 +00:00
|
|
|
mat = glm::rotate(mat, (float) M_PI, glm::vec3(0.0f, 1.0f, 0.0f));
|
|
|
|
return mat;
|
2016-09-28 14:12:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glm::mat4 RendererPolygon3d::computeModelMatrix(const glm::vec2 &pos, float scale, float angle)
|
|
|
|
{
|
|
|
|
// init as identity matrix
|
|
|
|
glm::mat4 model;
|
|
|
|
|
|
|
|
model = glm::translate(model, glm::vec3(pos, 0.0));
|
|
|
|
|
|
|
|
if (scale != 1.0) {
|
|
|
|
model = glm::scale(model, glm::vec3(scale));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (angle != 0.0) {
|
|
|
|
model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f));
|
|
|
|
}
|
|
|
|
|
|
|
|
return model;
|
|
|
|
}
|
2016-09-29 07:16:34 +00:00
|
|
|
|
|
|
|
void RendererPolygon3d::renderTraces()
|
|
|
|
{
|
|
|
|
// revert to default
|
|
|
|
glUseProgram(0);
|
|
|
|
|
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
|
|
for (const game::Trace *trace : m_state->traces) {
|
2016-09-29 07:32:56 +00:00
|
|
|
float fade_out = 1.0;
|
|
|
|
if (trace->missile == nullptr) {
|
|
|
|
fade_out = 1.0 - (trace->age / trace->maxAge);
|
|
|
|
}
|
|
|
|
|
2016-09-29 09:43:00 +00:00
|
|
|
glColor3f(0.0, 0.0, 1.0*fade_out);
|
2016-09-29 07:16:34 +00:00
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
for (const game::Trace::TracePoint &tp : trace->points) {
|
|
|
|
glVertex2f(tp.position.x, tp.position.y);
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
2016-09-28 09:50:35 +00:00
|
|
|
}
|