current revision
This commit is contained in:
82
ui/map/3D/gl/GL.h
Normal file
82
ui/map/3D/gl/GL.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef HELPER_GL_H
|
||||
#define HELPER_GL_H
|
||||
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLTexture>
|
||||
|
||||
struct Vert {
|
||||
QVector3D vert;
|
||||
Vert(QVector3D vert) : vert(vert) {;}
|
||||
int getVertOffset() const {return 0;}
|
||||
bool operator == (const Vert& o) const {return (vert == o.vert);}
|
||||
};
|
||||
|
||||
struct VertColor {
|
||||
QVector3D vert;
|
||||
QVector3D color;
|
||||
VertColor(QVector3D vert, QVector3D color) : vert(vert), color(color) {;}
|
||||
int getVertOffset() const {return 0;}
|
||||
int getColorOffset() const {return sizeof(QVector3D);}
|
||||
int getTanOffset() const {throw "error";}
|
||||
int getNormOffset() const {throw "error";}
|
||||
int getTexOffset() const {throw "error";}
|
||||
bool operator == (const VertColor& o) const {return (vert == o.vert) && (color == o.color);}
|
||||
static bool hasTangent() {return false;}
|
||||
static bool hasColor() {return true;}
|
||||
static bool hasNormal() {return false;}
|
||||
static bool hasTexCoord() {return false;}
|
||||
};
|
||||
|
||||
struct VertNorm {
|
||||
QVector3D vert;
|
||||
QVector3D norm;
|
||||
VertNorm(QVector3D vert, QVector3D norm) : vert(vert), norm(norm) {;}
|
||||
int getVertOffset() const {return 0;}
|
||||
int getNormOffset() const {return sizeof(QVector3D);}
|
||||
int getTanOffset() const {throw "error";}
|
||||
int getColorOffset() const {throw "error";}
|
||||
bool operator == (const VertNorm& o) const {return (vert == o.vert) && (norm == o.norm);}
|
||||
static bool hasTangent() {return false;}
|
||||
static bool hasNormal() {return true;}
|
||||
static bool hasTexCoord() {return false;}
|
||||
static bool hasColor() {return false;}
|
||||
};
|
||||
|
||||
struct VertNormTex {
|
||||
QVector3D vert;
|
||||
QVector3D norm;
|
||||
QVector2D tex;
|
||||
VertNormTex(QVector3D vert, QVector3D norm, QVector3D tex) : vert(vert), norm(norm), tex(tex) {;}
|
||||
int getVertOffset() const {return 0;}
|
||||
int getNormOffset() const {return sizeof(QVector3D);}
|
||||
int getTexOffset() const {return sizeof(QVector3D)*2;}
|
||||
int getTanOffset() const {throw "error";}
|
||||
int getColorOffset() const {throw "error";}
|
||||
bool operator == (const VertNormTex& o) const {return (vert == o.vert) && (norm == o.norm) && (tex == o.tex);}
|
||||
static bool hasTangent() {return false;}
|
||||
static bool hasNormal() {return true;}
|
||||
static bool hasTexCoord() {return true;}
|
||||
static bool hasColor() {return false;}
|
||||
};
|
||||
|
||||
struct VertNormTexTan {
|
||||
QVector3D vert;
|
||||
QVector3D norm;
|
||||
QVector2D tex;
|
||||
QVector3D tan;
|
||||
VertNormTexTan(QVector3D vert, QVector3D norm, QVector3D tex, QVector3D tan) : vert(vert), norm(norm), tex(tex), tan(tan) {;}
|
||||
int getVertOffset() const {return 0;}
|
||||
int getNormOffset() const {return sizeof(QVector3D);}
|
||||
int getTexOffset() const {return sizeof(QVector3D)*2;}
|
||||
int getTanOffset() const {return sizeof(QVector3D)*2 + sizeof(QVector2D);}
|
||||
int getColorOffset() const {throw "error";}
|
||||
bool operator == (const VertNormTexTan& o) const {return (vert == o.vert) && (norm == o.norm) && (tex == o.tex) && (tan == o.tan);}
|
||||
static bool hasTangent() {return true;}
|
||||
static bool hasNormal() {return true;}
|
||||
static bool hasTexCoord() {return true;}
|
||||
static bool hasColor() {return false;}
|
||||
};
|
||||
|
||||
#endif // HELPER_GL_H
|
||||
67
ui/map/3D/gl/GLHelper.h
Normal file
67
ui/map/3D/gl/GLHelper.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef MAP_HELPER_H
|
||||
#define MAP_HELPER_H
|
||||
|
||||
#include <Indoor/geo/Point3.h>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
class GLHelper {
|
||||
|
||||
public:
|
||||
|
||||
static QVector3D getNormal(const QVector3D& v1, const QVector3D& v2, const QVector3D& v3) {
|
||||
|
||||
// get two of the triangle's edges
|
||||
const QVector4D v21 = v2-v1;
|
||||
const QVector4D v31 = v3-v1;
|
||||
|
||||
const QVector3D n = QVector3D::crossProduct(v21.toVector3D(), v31.toVector3D()).normalized();
|
||||
|
||||
return isCCW(v1, v2, v3) ? (n) : (-n);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* is the triangle given by p1,p2,p3 CCW?
|
||||
* NOTE: uses OUR coordinate system (x,y,z) where z is the floor-height
|
||||
*/
|
||||
static bool isCCW(const Point3 p1, const Point3 p2, const Point3 p3) {
|
||||
const QVector3D v1(p1.x, p1.z, p1.y);
|
||||
const QVector3D v2(p2.x, p2.z, p2.y);
|
||||
const QVector3D v3(p3.x, p3.z, p3.y);
|
||||
return isCCW(v1, v2, v3);
|
||||
}
|
||||
|
||||
/**
|
||||
* is the triangle given by p1,p2,p3 CCW?
|
||||
* NOTE: uses OpenGL coordinate system (x,z,y) (our z is the floor-height)
|
||||
*/
|
||||
static bool isCCW(const QVector3D& p1, const QVector3D& p2, const QVector3D& p3) {
|
||||
|
||||
// camera position
|
||||
QMatrix4x4 proj; proj.lookAt(QVector3D(-1,20,-1), QVector3D(0,0,0), QVector3D(0,1,0));
|
||||
|
||||
// to camera space
|
||||
QVector4D v1(p1.x(), p1.y(), p1.z(), 1);
|
||||
QVector4D v2(p2.x(), p2.y(), p2.z(), 1);
|
||||
QVector4D v3(p3.x(), p3.y(), p3.z(), 1);
|
||||
v1 = proj * v1;
|
||||
v2 = proj * v2;
|
||||
v3 = proj * v3;
|
||||
|
||||
// get two of the triangle's edges
|
||||
const QVector4D v21 = v2-v1;
|
||||
const QVector4D v31 = v3-v1;
|
||||
|
||||
// check the angle between both
|
||||
const float angle = QVector2D::dotProduct(v21.toVector2D(), v31.toVector2D());
|
||||
return angle > 0;
|
||||
|
||||
// const QVector3D n = QVector3D::crossProduct(v21.toVector3D(), v31.toVector3D());
|
||||
// return n.z() > 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // MAP_HELPER_H
|
||||
126
ui/map/3D/gl/GLLines.h
Normal file
126
ui/map/3D/gl/GLLines.h
Normal file
@@ -0,0 +1,126 @@
|
||||
#ifndef GLLINES_H
|
||||
#define GLLINES_H
|
||||
|
||||
#include <QOpenGLFunctions>
|
||||
#include "GL.h"
|
||||
#include "GLHelper.h"
|
||||
|
||||
#include <Indoor/geo/Point3.h>
|
||||
|
||||
class GLLines : protected QOpenGLFunctions {
|
||||
|
||||
private:
|
||||
|
||||
QOpenGLBuffer arrayBuf;
|
||||
QOpenGLBuffer indexBuf;
|
||||
|
||||
std::vector<Vert> vertices;
|
||||
std::vector<GLushort> indices;
|
||||
|
||||
int mode = GL_LINES;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
GLLines() : arrayBuf(QOpenGLBuffer::VertexBuffer), indexBuf(QOpenGLBuffer::IndexBuffer) {
|
||||
;
|
||||
}
|
||||
|
||||
/** dtor */
|
||||
~GLLines() {
|
||||
arrayBuf.destroy();
|
||||
indexBuf.destroy();
|
||||
}
|
||||
|
||||
/** add a new face to this element */
|
||||
void addLine(const QVector3D& p1, const QVector3D& p2) {
|
||||
|
||||
// add vertices (remove duplicates!)
|
||||
const int i1 = addOnce(p1);
|
||||
const int i2 = addOnce(p2);
|
||||
|
||||
// add indices
|
||||
indices.push_back(i1);
|
||||
indices.push_back(i2);
|
||||
|
||||
}
|
||||
|
||||
void addVertex(const QVector3D& p1) {
|
||||
const int i1 = addOnce(p1);
|
||||
indices.push_back(i1);
|
||||
}
|
||||
|
||||
|
||||
/** build the underlying buffers */
|
||||
void build() {
|
||||
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
// Transfer vertex data to VBO 0
|
||||
arrayBuf.create();
|
||||
arrayBuf.bind();
|
||||
arrayBuf.allocate(vertices.data(), vertices.size() * sizeof(vertices[0]));
|
||||
|
||||
// Transfer index data to VBO 1
|
||||
indexBuf.create();
|
||||
indexBuf.bind();
|
||||
indexBuf.allocate(indices.data(), indices.size() * sizeof(indices[0]));
|
||||
|
||||
}
|
||||
|
||||
void rebuild() {
|
||||
if (indexBuf.isCreated()) {indexBuf.destroy();}
|
||||
if (arrayBuf.isCreated()) {arrayBuf.destroy();}
|
||||
build();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
indices.clear();
|
||||
vertices.clear();
|
||||
}
|
||||
|
||||
void setMode(const int mode) {
|
||||
this->mode = mode;
|
||||
}
|
||||
|
||||
/** render the element */
|
||||
void render(QOpenGLShaderProgram *program) {
|
||||
|
||||
// Tell OpenGL which VBOs to use
|
||||
arrayBuf.bind();
|
||||
indexBuf.bind();
|
||||
|
||||
// vertices
|
||||
int vertLoc = program->attributeLocation("a_position");
|
||||
program->enableAttributeArray(vertLoc);
|
||||
program->setAttributeBuffer(vertLoc, GL_FLOAT, vertices[0].getVertOffset(), 3, sizeof(vertices[0]));
|
||||
|
||||
// Draw cube geometry using indices from VBO 1
|
||||
glDrawElements(mode, indices.size(), GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** to conserve memory, avoid duplicate VNTs! */
|
||||
int addOnce(const Vert& vnt) {
|
||||
|
||||
const auto it = std::find(vertices.begin(), vertices.end(), vnt);
|
||||
|
||||
if (it == vertices.end()) {
|
||||
const int idx = vertices.size();
|
||||
vertices.push_back(vnt);
|
||||
return idx;
|
||||
} else {
|
||||
const int idx = it - vertices.begin();
|
||||
return idx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // GLLINES_H
|
||||
134
ui/map/3D/gl/GLPoints.h
Normal file
134
ui/map/3D/gl/GLPoints.h
Normal file
@@ -0,0 +1,134 @@
|
||||
#ifndef GLPOINTS_H
|
||||
#define GLPOINTS_H
|
||||
|
||||
|
||||
#include <QOpenGLFunctions>
|
||||
#include "GL.h"
|
||||
#include "GLHelper.h"
|
||||
|
||||
#include <Indoor/geo/Point3.h>
|
||||
|
||||
class GLPoints : protected QOpenGLFunctions {
|
||||
|
||||
private:
|
||||
|
||||
QOpenGLBuffer arrayBuf;
|
||||
QOpenGLBuffer indexBuf;
|
||||
|
||||
std::vector<VertColor> vertices;
|
||||
std::vector<GLuint> indices;
|
||||
|
||||
// use rectangles instead of GL_POINTS
|
||||
int mode = GL_TRIANGLES;
|
||||
bool initOnce = true;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
GLPoints() : arrayBuf(QOpenGLBuffer::VertexBuffer), indexBuf(QOpenGLBuffer::IndexBuffer) {
|
||||
alloc();
|
||||
}
|
||||
|
||||
/** dtor */
|
||||
~GLPoints() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
/** add a new face to this element */
|
||||
void addPoint(const QVector3D& pt, const QColor& color) {
|
||||
|
||||
const QVector3D c(color.redF(), color.greenF(), color.blueF());
|
||||
|
||||
float s = 10 / 100.0f;
|
||||
|
||||
const VertColor vc1(pt + QVector3D(-s, 0, -s), c);
|
||||
const VertColor vc2(pt + QVector3D(+s, 0, -s), c);
|
||||
const VertColor vc3(pt + QVector3D(+s, 0, +s), c);
|
||||
const VertColor vc4(pt + QVector3D(-s, 0, +s), c);
|
||||
|
||||
const int start = vertices.size();
|
||||
|
||||
vertices.push_back(vc1);
|
||||
vertices.push_back(vc2);
|
||||
vertices.push_back(vc3);
|
||||
vertices.push_back(vc4);
|
||||
|
||||
indices.push_back(start + 3);
|
||||
indices.push_back(start + 2);
|
||||
indices.push_back(start + 1);
|
||||
|
||||
indices.push_back(start + 3);
|
||||
indices.push_back(start + 1);
|
||||
indices.push_back(start + 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void alloc() {
|
||||
if (!indexBuf.isCreated()) {indexBuf.create();}
|
||||
if (!arrayBuf.isCreated()) {arrayBuf.create();}
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
if (indexBuf.isCreated()) {indexBuf.destroy();}
|
||||
if (arrayBuf.isCreated()) {arrayBuf.destroy();}
|
||||
}
|
||||
|
||||
/** build the underlying buffers */
|
||||
void build() {
|
||||
|
||||
// Transfer vertex data to VBO 0
|
||||
arrayBuf.bind();
|
||||
arrayBuf.allocate(vertices.data(), vertices.size() * sizeof(vertices[0]));
|
||||
|
||||
// Transfer index data to VBO 1
|
||||
indexBuf.bind();
|
||||
indexBuf.allocate(indices.data(), indices.size() * sizeof(indices[0]));
|
||||
|
||||
}
|
||||
|
||||
void initGL() {
|
||||
initializeOpenGLFunctions();
|
||||
}
|
||||
|
||||
void rebuild() {
|
||||
build();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
indices.clear();
|
||||
vertices.clear();
|
||||
}
|
||||
|
||||
void setMode(const int mode) {
|
||||
this->mode = mode;
|
||||
}
|
||||
|
||||
/** render the element */
|
||||
void render(QOpenGLShaderProgram *program) {
|
||||
|
||||
if (indices.empty()) {return;}
|
||||
|
||||
// Tell OpenGL which VBOs to use
|
||||
arrayBuf.bind();
|
||||
indexBuf.bind();
|
||||
|
||||
// vertices
|
||||
int vertLoc = program->attributeLocation("a_position");
|
||||
program->enableAttributeArray(vertLoc);
|
||||
program->setAttributeBuffer(vertLoc, GL_FLOAT, vertices[0].getVertOffset(), 3, sizeof(vertices[0]));
|
||||
|
||||
// colors
|
||||
int colorLoc = program->attributeLocation("a_color");
|
||||
program->enableAttributeArray(colorLoc);
|
||||
program->setAttributeBuffer(colorLoc, GL_FLOAT, vertices[0].getColorOffset(), 3, sizeof(vertices[0]));
|
||||
|
||||
// Draw cube geometry using indices from VBO 1
|
||||
glDrawElements(mode, indices.size(), GL_UNSIGNED_INT, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // GLPOINTS_H
|
||||
223
ui/map/3D/gl/GLTriangles.h
Normal file
223
ui/map/3D/gl/GLTriangles.h
Normal file
@@ -0,0 +1,223 @@
|
||||
#ifndef GLTRIANGLES_H
|
||||
#define GLTRIANGLES_H
|
||||
|
||||
#include <QOpenGLFunctions>
|
||||
#include "GL.h"
|
||||
#include "GLHelper.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <Indoor/geo/Point3.h>
|
||||
|
||||
template <typename T> class GLTriangles : protected QOpenGLFunctions {
|
||||
|
||||
private:
|
||||
|
||||
QOpenGLBuffer arrayBuf;
|
||||
QOpenGLBuffer indexBuf;
|
||||
QOpenGLTexture* textures[4];
|
||||
|
||||
std::vector<T> vertices;
|
||||
std::vector<GLuint> indices;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
GLTriangles() : arrayBuf(QOpenGLBuffer::VertexBuffer), indexBuf(QOpenGLBuffer::IndexBuffer), textures() {
|
||||
;
|
||||
}
|
||||
|
||||
/** dtor */
|
||||
~GLTriangles() {
|
||||
|
||||
arrayBuf.destroy();
|
||||
indexBuf.destroy();
|
||||
|
||||
for (int i = 0; i < 4; ++i) {delete textures[i];}
|
||||
|
||||
}
|
||||
|
||||
/** set the to-be-used texture */
|
||||
void setTexture(const int slot, const QString& textureFile) {
|
||||
|
||||
const QImage img(textureFile);
|
||||
if (img.width() <= 0) {throw "error";}
|
||||
|
||||
QOpenGLTexture* texture = new QOpenGLTexture(img);
|
||||
texture->setMinificationFilter(QOpenGLTexture::Linear);
|
||||
texture->setMagnificationFilter(QOpenGLTexture::Linear);
|
||||
texture->setWrapMode(QOpenGLTexture::Repeat);
|
||||
texture->generateMipMaps();
|
||||
textures[slot] = texture;
|
||||
|
||||
}
|
||||
|
||||
void setDiffuse(const QString& textureFile) {
|
||||
setTexture(0, textureFile);
|
||||
}
|
||||
|
||||
void setNormalMap(const QString& textureFile) {
|
||||
setTexture(1, textureFile);
|
||||
}
|
||||
|
||||
/** add a new face to this element */
|
||||
void addFace(const T& vnt1, const T& vnt2, const T& vnt3) {
|
||||
addFace(vnt1, vnt2, vnt3, 0);
|
||||
}
|
||||
|
||||
/** add a new face to this element */
|
||||
void addFaceCCW(const T& vnt1, const T& vnt2, const T& vnt3) {
|
||||
addFace(vnt1, vnt2, vnt3, 1);
|
||||
}
|
||||
|
||||
/** add a new face to this element */
|
||||
void addFaceCW(const T& vnt1, const T& vnt2, const T& vnt3) {
|
||||
addFace(vnt1, vnt2, vnt3, 2);
|
||||
}
|
||||
|
||||
/** add a new quad to this element */
|
||||
void addQuadCCW(const T& vnt1, const T& vnt2, const T& vnt3, const T& vnt4) {
|
||||
addFace(vnt1, vnt2, vnt3, 1);
|
||||
addFace(vnt3, vnt4, vnt1, 1);
|
||||
}
|
||||
|
||||
/** add a new quad to this element */
|
||||
void addQuadCW(const T& vnt1, const T& vnt2, const T& vnt3, const T& vnt4) {
|
||||
addFace(vnt1, vnt2, vnt3, 2);
|
||||
addFace(vnt3, vnt4, vnt1, 2);
|
||||
}
|
||||
|
||||
/** add a new quad to this element */
|
||||
void addQuad(const T& vnt1, const T& vnt2, const T& vnt3, const T& vnt4) {
|
||||
addFace(vnt1, vnt2, vnt3, 0);
|
||||
addFace(vnt3, vnt4, vnt1, 0);
|
||||
}
|
||||
|
||||
/** build the underlying buffers */
|
||||
void build() {
|
||||
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
// Transfer vertex data to VBO 0
|
||||
arrayBuf.create();
|
||||
arrayBuf.bind();
|
||||
arrayBuf.allocate(vertices.data(), vertices.size() * sizeof(vertices[0]));
|
||||
|
||||
// Transfer index data to VBO 1
|
||||
indexBuf.create();
|
||||
indexBuf.bind();
|
||||
indexBuf.allocate(indices.data(), indices.size() * sizeof(indices[0]));
|
||||
|
||||
}
|
||||
|
||||
void rebuild() {
|
||||
if (indexBuf.isCreated()) {indexBuf.destroy();}
|
||||
if (arrayBuf.isCreated()) {arrayBuf.destroy();}
|
||||
build();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
indices.clear();
|
||||
vertices.clear();
|
||||
}
|
||||
|
||||
/** render the element */
|
||||
void render(QOpenGLShaderProgram* program) {
|
||||
|
||||
// nothing to-do?
|
||||
if (indices.empty()) {return;}
|
||||
|
||||
// Tell OpenGL which VBOs to use
|
||||
arrayBuf.bind();
|
||||
indexBuf.bind();
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (textures[i]) { textures[i]->bind(i); }
|
||||
}
|
||||
|
||||
// vertices
|
||||
int vertLoc = program->attributeLocation("a_position");
|
||||
program->enableAttributeArray(vertLoc);
|
||||
program->setAttributeBuffer(vertLoc, GL_FLOAT, vertices[0].getVertOffset(), 3, sizeof(vertices[0]));
|
||||
|
||||
// Tell OpenGL programmable pipeline how to locate vertex texture coordinate data
|
||||
if (T::hasNormal()) {
|
||||
int normLoc = program->attributeLocation("a_normal");
|
||||
program->enableAttributeArray(normLoc);
|
||||
program->setAttributeBuffer(normLoc, GL_FLOAT, vertices[0].getNormOffset(), 3, sizeof(vertices[0]));
|
||||
}
|
||||
|
||||
if (T::hasTexCoord()) {
|
||||
int texcoordLocation = program->attributeLocation("a_texcoord");
|
||||
program->enableAttributeArray(texcoordLocation);
|
||||
program->setAttributeBuffer(texcoordLocation, GL_FLOAT, vertices[0].getTexOffset(), 2, sizeof(vertices[0]));
|
||||
}
|
||||
|
||||
// bind tangent data?
|
||||
if (T::hasTangent()) {
|
||||
int tanLocation = program->attributeLocation("a_tangent");
|
||||
program->enableAttributeArray(tanLocation);
|
||||
program->setAttributeBuffer(tanLocation, GL_FLOAT, vertices[0].getTanOffset(), 3, sizeof(vertices[0]));
|
||||
}
|
||||
|
||||
// bind color data?
|
||||
if (T::hasColor()) {
|
||||
int colorLoc = program->attributeLocation("a_color");
|
||||
program->enableAttributeArray(colorLoc);
|
||||
program->setAttributeBuffer(colorLoc, GL_FLOAT, vertices[0].getColorOffset(), 3, sizeof(vertices[0]));
|
||||
}
|
||||
|
||||
// texture
|
||||
program->setUniformValue("texture", 0);
|
||||
|
||||
// Draw cube geometry using indices from VBO 1
|
||||
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void addFace(const T& vnt1, const T& vnt2, const T& vnt3, const int mode) {
|
||||
|
||||
// add vertices (remove duplicates!)
|
||||
const int i1 = addOnce(vnt1);
|
||||
const int i2 = addOnce(vnt2);
|
||||
const int i3 = addOnce(vnt3);
|
||||
|
||||
// get current orientation
|
||||
const bool ccw = GLHelper::isCCW(vnt1.vert, vnt2.vert, vnt3.vert);
|
||||
|
||||
// create indices
|
||||
if (mode == 0 || (mode == 1 && ccw) || (mode == 2 && !ccw) ) {
|
||||
indices.push_back(i1);
|
||||
indices.push_back(i2);
|
||||
indices.push_back(i3);
|
||||
} else {
|
||||
indices.push_back(i3);
|
||||
indices.push_back(i2);
|
||||
indices.push_back(i1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** to conserve memory, avoid duplicate VNTs! */
|
||||
int addOnce(const T& vnt) {
|
||||
|
||||
const auto it = std::find(vertices.begin(), vertices.end(), vnt);
|
||||
|
||||
if (it == vertices.end()) {
|
||||
const int idx = vertices.size();
|
||||
vertices.push_back(vnt);
|
||||
return idx;
|
||||
} else {
|
||||
const int idx = it - vertices.begin();
|
||||
return idx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // GLTRIANGLES_H
|
||||
31
ui/map/3D/gl/Shader.h
Normal file
31
ui/map/3D/gl/Shader.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef SHADER_H
|
||||
#define SHADER_H
|
||||
|
||||
#include <QOpenGLShaderProgram>
|
||||
|
||||
/**
|
||||
* just some helper methods
|
||||
*/
|
||||
class Shader {
|
||||
|
||||
private:
|
||||
|
||||
QOpenGLShaderProgram program;
|
||||
|
||||
public:
|
||||
|
||||
/** get the underlying program */
|
||||
QOpenGLShaderProgram* getProgram() {return &program;}
|
||||
|
||||
/** helper method to build the shader */
|
||||
void loadShaderFromFile(const QString& vertex, const QString& fragment) {
|
||||
if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, vertex)) {throw "1";}
|
||||
if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, fragment)) {throw "2";}
|
||||
if (!program.link()) {throw "3";}
|
||||
if (!program.bind()) {throw "4";}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // SHADER_H
|
||||
Reference in New Issue
Block a user