--- /dev/null
+#include <stdio.h>
+#include "meshgen.h"
+#include "mesh.h"
+
+// ------ geosphere ------
+#define PHI 1.618034
+
+/* icosahedron points */
+static Vec3 icosa_pt[] = {
+ Vec3(PHI, 1, 0),
+ Vec3(-PHI, 1, 0),
+ Vec3(PHI, -1, 0),
+ Vec3(-PHI, -1, 0),
+ Vec3(1, 0, PHI),
+ Vec3(1, 0, -PHI),
+ Vec3(-1, 0, PHI),
+ Vec3(-1, 0, -PHI),
+ Vec3(0, PHI, 1),
+ Vec3(0, -PHI, 1),
+ Vec3(0, PHI, -1),
+ Vec3(0, -PHI, -1)
+};
+/* indices that map to 20hedron pts to create the polygons */
+enum { P11, P12, P13, P14, P21, P22, P23, P24, P31, P32, P33, P34 };
+static int icosa_idx[] = {
+ P11, P31, P21,
+ P11, P22, P33,
+ P13, P21, P32,
+ P13, P34, P22,
+ P12, P23, P31,
+ P12, P33, P24,
+ P14, P32, P23,
+ P14, P24, P34,
+
+ P11, P33, P31,
+ P12, P31, P33,
+ P13, P32, P34,
+ P14, P34, P32,
+
+ P21, P13, P11,
+ P22, P11, P13,
+ P23, P12, P14,
+ P24, P14, P12,
+
+ P31, P23, P21,
+ P32, P21, P23,
+ P33, P22, P24,
+ P34, P24, P22
+};
+
+static void geosphere(std::vector<Vec3> *verts, const Vec3 &v1, const Vec3 &v2, const Vec3 &v3, int iter)
+{
+ if(!iter) {
+ verts->push_back(v1);
+ verts->push_back(v2);
+ verts->push_back(v3);
+ return;
+ }
+
+ /* we find mid points of the 3 vertices + normalize */
+
+ Vec3 v12 = normalize(v1 + v2);
+ Vec3 v23 = normalize(v2 + v3);
+ Vec3 v31 = normalize(v3 + v1);
+
+ /* create 4 triangles (recursive subdivision of the initial icosahedron */
+
+ geosphere(verts, v1, v12, v31, iter - 1);
+ geosphere(verts, v2, v23, v12, iter - 1);
+ geosphere(verts, v3, v31, v23, iter - 1);
+ geosphere(verts, v12, v23, v31, iter - 1);
+}
+
+void gen_geosphere(Mesh *mesh, float rad, int subdiv, bool hemi)
+{
+ /* the triangles of the icosahedron (fixed) */
+ int num_tri = (sizeof icosa_idx / sizeof *icosa_idx) / 3;
+
+ std::vector<Vec3> verts;
+ for(int i=0; i<num_tri; i++) {
+ Vec3 v[3];
+
+ /* we select the 3 vertices from the i-th triangle of the 20hedron */
+ for(int j=0; j<3; j++) {
+ int vidx = icosa_idx[i * 3 + j];
+ v[j] = normalize(icosa_pt[vidx]);
+ }
+
+ /* if hemi, we discard the triangles of the lower part of the 20hedron */
+ if(hemi && (v[0].y < 0.0 || v[1].y < 0.0 || v[2].y < 0.0)) {
+ continue;
+ }
+
+ geosphere(&verts, v[0], v[1], v[2], subdiv);
+ }
+
+ /* now the verts contains all the sphere vertices */
+
+ int num_verts = (int)verts.size();
+
+ mesh->vertices.resize(num_verts);
+ mesh->normals.resize(num_verts);
+ mesh->tex_coords.resize(num_verts);
+
+ for(int i=0; i<num_verts; i++) {
+ mesh->vertices[i] = verts[i] * rad;
+ mesh->normals[i] = verts[i];
+
+ float theta = atan2(verts[i].z, verts[i].x);
+ float phi = acos(verts[i].y);
+
+ float u = 0.5 * theta / M_PI + 0.5;
+ float v = phi / M_PI;
+ mesh->tex_coords[i] = Vec2(u, v);
+ }
+
+ /* TODO: optimize indices by detecting the common vertices */
+ mesh->indices.resize(num_verts);
+ for(int i=0; i<num_verts; i++) {
+ mesh->indices[i] = i;
+ }
+ mesh->update_vertex_data();
+}
\ No newline at end of file
#include <GL/glew.h>
+#include <gmath/gmath.h>
#include "global.h"
+#include "gfxapi.h"
#include "camera.h"
#include "mesh.h"
+#include "meshgen.h"
#include "object.h"
#include "renderer.h"
#include "scene.h"
#include "shader_manager.h"
#include "texture.h"
+/* skybox */
+
+static Mesh *skymesh; /* it will be used by many renderers => no destroy */
+static ShaderProgram *skyprog;
+static int viewproj_loc;
+
Renderer::Renderer()
{
scene = 0;
return false;
}
- if(!(sprog->link())) {
- return false;
- }
-
/* getting material uniform locations: diffuse, specular, specular exponent (strength) */
if((diff_loc = sprog->get_uniform_location("diffuse")) == -1) {
void Renderer::set_sky_tex(Texture *stex)
{
+ if(!skymesh) {
+ skymesh = gfx_create_mesh();
+ gen_geosphere(skymesh, 1, 0);
+ }
+ if(!skyprog) {
+ if(!(skyprog = sdr_man->create_shader_program("sky.v.glsl", "sky.f.glsl")))
+ return;
+ if((viewproj_loc = skyprog->get_uniform_location("viewproj") == -1))
+ return;
+ }
skytex = stex;
}
void Renderer::set_diffuse_sky_tex(Texture *dstex)
{
dskytex = dstex;
+}
+
+void Renderer::draw_skybox()
+{
+ if(!skymesh || !skytex)
+ return;
+
+ skytex->bind();
+ skyprog->use();
+
+ Mat4 mviewproj;
+ mviewproj = camera->get_view_matrix().upper3x3() * mprojection;
+ skyprog->set_uniform_matrix(viewproj_loc, mviewproj);
+
+ skymesh->draw();
}
\ No newline at end of file