first step in the rendering process, we can display a sphere
This commit is contained in:
parent
61c6f97da3
commit
b6c9377268
@ -26,8 +26,8 @@ void Camera::computeProjectionMatrix()
|
||||
|
||||
void Camera::computeViewMatrix()
|
||||
{
|
||||
m_viewMatrix = glm::rotate(glm::mat4(), m_rotation.y, glm::vec3(0, 1, 0));
|
||||
m_viewMatrix = glm::rotate(m_viewMatrix, m_rotation.x, glm::vec3(1, 0, 0));
|
||||
m_viewMatrix = glm::rotate(glm::mat4(), m_rotation.y, glm::vec3(1, 0, 0));
|
||||
m_viewMatrix = glm::rotate(m_viewMatrix, m_rotation.x, glm::vec3(0, 1, 0));
|
||||
m_viewMatrix = glm::translate(m_viewMatrix, -m_position);
|
||||
m_viewHasChanged = false;
|
||||
}
|
||||
@ -85,8 +85,7 @@ void Camera::lookAt(glm::vec3 position)
|
||||
glm::vec3 delta = position - m_position;
|
||||
glm::normalize(delta);
|
||||
m_rotation.y = std::asin(delta.y);
|
||||
m_rotation.x = std::acos(delta.z/std::acos(delta.y));
|
||||
if(delta.z < 0) m_rotation.x += M_PI;
|
||||
m_rotation.x = std::atan2(delta.z, delta.x);
|
||||
}
|
||||
|
||||
void Camera::lookAt(glm::vec2 rotation)
|
||||
|
2
mesh.cpp
2
mesh.cpp
@ -8,7 +8,7 @@ Mesh::~Mesh()
|
||||
destroyGL();
|
||||
}
|
||||
|
||||
void Mesh::addVertex(Vertex& v)
|
||||
void Mesh::addVertex(const Vertex& v)
|
||||
{
|
||||
if(!locked)
|
||||
vertices.push_back(v);
|
||||
|
4
mesh.h
4
mesh.h
@ -16,14 +16,14 @@ public:
|
||||
} Vertex;
|
||||
|
||||
~Mesh();
|
||||
void addVertex(Vertex& v);
|
||||
void addVertex(const Vertex& v);
|
||||
void addFace(int i1, int i2, int i3);
|
||||
void initGL();
|
||||
void destroyGL();
|
||||
void draw();
|
||||
bool isLocked(){return locked;}
|
||||
|
||||
private:
|
||||
protected:
|
||||
enum {VERTEX_BUFFER, INDICES_BUFFER, NB_BUFFERS};
|
||||
|
||||
std::vector<Vertex> vertices;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "scene.h"
|
||||
#include "glassert.h"
|
||||
#include "camera.h"
|
||||
#include "gridmesh.h"
|
||||
#include "sphere.h"
|
||||
#include "phongmaterial.h"
|
||||
#include <iostream>
|
||||
#include <glm/glm.hpp>
|
||||
@ -55,8 +55,11 @@ void MyGLWidget::initializeGL()
|
||||
void MyGLWidget::buildScene()
|
||||
{
|
||||
scene = new Scene();
|
||||
scene->setCamera(new Camera(width(), height()));
|
||||
Mesh* myGrid = new GridMesh(2, 2, false);
|
||||
Camera* cam = new Camera(width(), height());
|
||||
cam->moveTo(glm::vec3(-1, 0, 0));
|
||||
cam->lookAt(glm::vec3(0, 0, 0));
|
||||
scene->setCamera(cam);
|
||||
Mesh* myGrid = new Sphere(2);
|
||||
myGrid->initGL();
|
||||
Shader* shader = new Shader(QString("../phong.vert"), QString("../phong.frag"));
|
||||
Material* mat = new PhongMaterial(shader);
|
||||
@ -79,28 +82,30 @@ void MyGLWidget::paintGL()
|
||||
|
||||
void MyGLWidget::mouseMoveEvent(QMouseEvent *e)
|
||||
{
|
||||
static QPoint* last = NULL;
|
||||
if(last == NULL)
|
||||
last = new QPoint(e->pos().x(), e->pos().y());
|
||||
else
|
||||
controller.mouseMove(e->pos().x() - last->x(), e->pos().y() - last->y());
|
||||
*last = e->pos();
|
||||
controller.mouseMove(e->pos().x() - last.x(), e->pos().y() - last.y());
|
||||
last = e->pos();
|
||||
updateGL();
|
||||
}
|
||||
|
||||
void MyGLWidget::mousePressEvent(QMouseEvent* e)
|
||||
{
|
||||
controller.mouseEvent(e->button(), true);
|
||||
last = e->pos();
|
||||
updateGL();
|
||||
}
|
||||
void MyGLWidget::mouseReleaseEvent(QMouseEvent* e)
|
||||
{
|
||||
controller.mouseEvent(e->button(), false);
|
||||
updateGL();
|
||||
}
|
||||
|
||||
void MyGLWidget::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
controller.mouseEvent(e->key(), true);
|
||||
updateGL();
|
||||
}
|
||||
void MyGLWidget::keyReleaseEvent(QKeyEvent *e)
|
||||
{
|
||||
controller.mouseEvent(e->key(), false);
|
||||
updateGL();
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ class MyGLWidget : public QGLWidget
|
||||
|
||||
Scene* scene;
|
||||
SceneController controller;
|
||||
QPoint last;
|
||||
|
||||
public:
|
||||
explicit MyGLWidget(QWidget *parent = 0);
|
||||
|
@ -10,12 +10,32 @@ void SceneController::setScene(Scene* myScene)
|
||||
|
||||
void SceneController::mouseMove(int dx, int dy)
|
||||
{
|
||||
|
||||
switch(grabbed)
|
||||
{
|
||||
case 1:
|
||||
camera->rotate(glm::vec2(dx*3.14f/180, dy*3.14f/180));
|
||||
break;
|
||||
case 2:
|
||||
camera->translate(glm::vec3(dx*0.01f, dy*0.01f, 0));
|
||||
camera->lookAt(glm::vec3(0, 0, 0));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneController::mouseEvent(int button, bool state)
|
||||
{
|
||||
|
||||
switch (button) {
|
||||
case Qt::LeftButton:
|
||||
grabbed += state ? 1 : -1;
|
||||
break;
|
||||
case Qt::RightButton:
|
||||
grabbed += state ? 2 : -2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneController::keyEvent(int key, bool state)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef SCENECONTROLLER_H
|
||||
#define SCENECONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <cstddef>
|
||||
|
||||
class Scene;
|
||||
class Camera;
|
||||
@ -10,7 +10,10 @@ class SceneController
|
||||
{
|
||||
Camera* camera;
|
||||
Scene* scene;
|
||||
int grabbed;
|
||||
public:
|
||||
SceneController() : camera(NULL), scene(NULL), grabbed(0) {}
|
||||
|
||||
void setScene(Scene* myScene);
|
||||
void mouseMove(int dx, int dy);
|
||||
void mouseEvent(int button, bool state);
|
||||
|
@ -29,7 +29,8 @@ SOURCES += main.cpp\
|
||||
gridmesh.cpp \
|
||||
texture.cpp \
|
||||
phongmaterial.cpp \
|
||||
scenecontroller.cpp
|
||||
scenecontroller.cpp \
|
||||
sphere.cpp
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
myglwidget.h \
|
||||
@ -42,7 +43,8 @@ HEADERS += mainwindow.h \
|
||||
gridmesh.h \
|
||||
texture.h \
|
||||
phongmaterial.h \
|
||||
scenecontroller.h
|
||||
scenecontroller.h \
|
||||
sphere.h
|
||||
|
||||
FORMS += mainwindow.ui
|
||||
|
||||
|
108
sphere.cpp
Normal file
108
sphere.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
#include "sphere.h"
|
||||
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define MAGIC_RATIO 0.37139f
|
||||
|
||||
Sphere::Sphere(int n)
|
||||
{
|
||||
// icosahedron :
|
||||
|
||||
// top cap
|
||||
createVertex(0, 1);
|
||||
for(int i=0; i<5; i++)
|
||||
createVertex(i/5.f, 1-MAGIC_RATIO);
|
||||
|
||||
// bottom cap
|
||||
createVertex(0, 0);
|
||||
for(int i=0; i<5; i++)
|
||||
createVertex((i+0.5f)/5.f, MAGIC_RATIO);
|
||||
|
||||
// Compute faces
|
||||
for(int i=0; i<5; i++){
|
||||
int top = 1;
|
||||
int bottom = 7;
|
||||
int offset = (i+1)%5;
|
||||
// top cap
|
||||
addFace(0, top+i, top+offset);
|
||||
// bottom cap
|
||||
addFace(6, bottom+i, bottom+offset);
|
||||
// middle ribbon
|
||||
addFace(bottom+i, top+offset, top+i);
|
||||
addFace(top+offset, bottom+offset, bottom+i);
|
||||
}
|
||||
|
||||
// geodesic subdivisions :
|
||||
for(int i=0; i<n; i++){
|
||||
edges = new Edge[vertices.size()-1];
|
||||
int nb_triangles = indices.size()/3;
|
||||
for(int j=0; j<nb_triangles; j++)
|
||||
{
|
||||
int vid[3];
|
||||
for(int k=0; k<3; k++)
|
||||
{
|
||||
int idA = indices[j*3 + k];
|
||||
int idB = indices[j*3 + (k+1)%3];
|
||||
int a = idA < idB ? idA : idB;
|
||||
int b = idA > idB ? idA : idB;
|
||||
vid[k] = getEdge(a, b);
|
||||
}
|
||||
for(int k=0; k<3; k++)
|
||||
addFace(indices[j*3 + k], vid[k], vid[(k+2)%3]);
|
||||
addFace(vid[0], vid[1], vid[2]);
|
||||
}
|
||||
delete[](edges);
|
||||
indices.erase(indices.begin(), indices.begin()+nb_triangles*3);
|
||||
}
|
||||
}
|
||||
|
||||
int Sphere::getEdge(int a, int b)
|
||||
{
|
||||
Edge* current = edges+a;
|
||||
int vid = -1;
|
||||
while(vid == -1)
|
||||
{
|
||||
if(current->b == b)
|
||||
vid = current->vertex;
|
||||
else if(current->next == NULL)
|
||||
{
|
||||
// creating subdivision vertex
|
||||
Vertex v;
|
||||
Vertex v0 = vertices[a];
|
||||
Vertex v1 = vertices[b];
|
||||
v.position = glm::normalize((v0.position + v1.position)/2.f);
|
||||
v.normal = v.position;
|
||||
|
||||
// u/v sphériques, cohérents sur toute la sphère sauf des artefacts au niveau des u==0
|
||||
float newU = (v.position.x < 0 ? 1.5f : 1.f) + atan(v.position.z/v.position.x)/(2*M_PI);
|
||||
float newV = acos(v.position.y)/M_PI;
|
||||
v.texCoord = glm::vec2(newU - floor(newU), newV);
|
||||
// alternative, u/v moyennés :
|
||||
//v.texcoord_ = (v0.texcoord_ + v1.texcoord_)/2.f;
|
||||
|
||||
vid = vertices.size();
|
||||
addVertex(v);
|
||||
// inserting the new vertex in the edge collection
|
||||
if(current->b == -1)
|
||||
{
|
||||
current->vertex = vid;
|
||||
current->b = b;
|
||||
}
|
||||
else
|
||||
current->next = new Edge(b, vid);
|
||||
}
|
||||
else
|
||||
current = current->next;
|
||||
}
|
||||
return vid;
|
||||
}
|
||||
|
||||
void Sphere::createVertex(float u, float v)
|
||||
{
|
||||
Vertex vert;
|
||||
vert.position = glm::vec3(cos(u*2*M_PI)*sin(v*M_PI),
|
||||
cos(v*M_PI),
|
||||
sin(u*2*M_PI)*sin(v*M_PI));
|
||||
vert.normal = vert.position;
|
||||
vert.texCoord = glm::vec2(u, v);
|
||||
addVertex(vert);
|
||||
}
|
25
sphere.h
Normal file
25
sphere.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef SPHERE_H
|
||||
#define SPHERE_H
|
||||
|
||||
#include "mesh.h"
|
||||
|
||||
class Sphere : public Mesh
|
||||
{
|
||||
private:
|
||||
class Edge{
|
||||
public:
|
||||
int b;
|
||||
int vertex;
|
||||
Edge* next;
|
||||
Edge(int myB = -1, int myVertex = -1):b(myB),vertex(myVertex),next(NULL){}
|
||||
~Edge(){ if(next != NULL) delete(next); }
|
||||
};
|
||||
|
||||
Edge* edges;
|
||||
int getEdge(int a, int b);
|
||||
void createVertex(float u, float v);
|
||||
public:
|
||||
Sphere(int n = 0);
|
||||
};
|
||||
|
||||
#endif // SPHERE_H
|
Loading…
x
Reference in New Issue
Block a user