init versie

This commit is contained in:
bart
2026-11-08 11:22:15 +01:00
commit dfd497d728
45 changed files with 3041 additions and 0 deletions
+388
View File
@@ -0,0 +1,388 @@
#include "tile.h"
#include "matrix2d.h"
#include <math.h>
#include "qscenerenderer.h"
#include <QVector3D>
QImage * Tile::m_image = NULL;
QOpenGLTexture * Tile::m_texture = NULL;
QImage * Tile::m_image_border = NULL;
QOpenGLTexture * Tile::m_texture_border = NULL;
QOpenGLTexture * Tile::m_texture_rock = NULL;
QImage * Tile::m_image_rock = NULL;
Vertex * Tile::m_vertices= NULL;
int Tile::m_numVertex;
QOpenGLBuffer Tile::m_vertex=QOpenGLBuffer();
QOpenGLVertexArrayObject Tile::m_object;
QOpenGLShaderProgram *Tile::m_program= NULL;
Tile::Tile()
: m_scene(NULL), m_tilevertices(NULL), m_x(0), m_y(0),
m_startpoint_x(0.0f), m_startpoint_y(0.0f),
m_initialized(false), m_normalsBuilt(false)
{
}
void Tile::ensureInitialized(QSceneRenderer* s, int x, int y)
{
if (!m_initialized) {
init(s, x, y);
}
}
void Tile::ensureNormalsBuilt()
{
if (!m_normalsBuilt && m_initialized) {
buildNormals();
m_normalsBuilt = true;
}
}
void Tile::init(QSceneRenderer* s, int x, int y)
{
m_x = x;
m_y = y;
m_scene = s;
//m_x*LOD_0_SIZE *1.5+ (m_y%2==1 ?( LOD_0_SIZE*1.5f)/2.0f:0),m_y*LOD_0_SIZE/2.0f,1.0f)
// m_startpoint_x =( m_scene->getNumPoints05()*3*x)+ (y%2==1? (m_scene->getNumPoints05()*1.5):0);
//m_startpoint_y = m_scene->getNumPoints05()*y;
m_startpoint_x =( m_scene->getNumPoints05()*1.5f*x) ;
m_startpoint_y = m_scene->getNumPoints05()*y*2.0f + (x%2==1? (m_scene->getNumPoints05()):0) ;
bool first = false;
if (m_vertices==NULL){
buildVertices();first=true;
}
buildHeights();
if (Tile::m_image == NULL)
Tile::m_image = new QImage("/home/bart/project/tiletest/images/grass.jpg");
if (Tile::m_image_border == NULL)
Tile::m_image_border = new QImage("/home/bart/project/tiletest/images/border.png");
if (Tile::m_image_rock == NULL)
Tile::m_image_rock = new QImage("/home/bart/project/tiletest/images/rock.jpg");
if (Tile::m_texture_rock == NULL) {
m_texture_rock = new QOpenGLTexture(*m_image_rock);
m_texture_rock->setWrapMode(QOpenGLTexture::Repeat);
m_texture_rock->setMinificationFilter(QOpenGLTexture::NearestMipMapNearest);
m_texture_rock->setMagnificationFilter(QOpenGLTexture::Nearest);
//m_texture->setFormat(QOpenGLTexture::RGB32F);33
m_texture_rock->allocateStorage();
}
if (Tile::m_texture_border == NULL) {
m_texture_border = new QOpenGLTexture(*m_image_border);
m_texture_border->setWrapMode(QOpenGLTexture::Repeat);
m_texture_border->setMinificationFilter(QOpenGLTexture::NearestMipMapNearest);
m_texture_border->setMagnificationFilter(QOpenGLTexture::Nearest);
//m_texture->setFormat(QOpenGLTexture::RGB32F);33
m_texture_border->allocateStorage();
}
if (Tile::m_texture == NULL) {
m_texture = new QOpenGLTexture(*m_image);
m_texture->setWrapMode(QOpenGLTexture::Repeat);
m_texture->setMinificationFilter(QOpenGLTexture::NearestMipMapNearest);
m_texture->setMagnificationFilter(QOpenGLTexture::Nearest);
//m_texture->setFormat(QOpenGLTexture::RGB32F);
m_texture->allocateStorage();
}
if (first){
m_program = new QOpenGLShaderProgram();
m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, "/home/bart/project/tiletest/shaders/simple.vert");
m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, "/home/bart/project/tiletest/shaders/simple.frag");
m_program->link();
}
m_program->bind();
// Generate 1 buffer, put the resulting identifier in vertexbuffer
// Create Buffer (Do not release until VAO is created)
if (first) {
m_vertex.create();
m_vertex.bind();
m_vertex.setUsagePattern(QOpenGLBuffer::StaticDraw);
m_vertex.allocate(m_vertices, sizeof(Vertex) * (m_numVertex+1));
// Create Vertex Array Object
m_object.create();
m_object.bind();
m_program->enableAttributeArray(0);
m_program->enableAttributeArray(1);
m_program->setAttributeBuffer(0, GL_FLOAT, Vertex::positionOffset(), Vertex::PositionTupleSize, Vertex::stride());
m_program->setAttributeBuffer(1, GL_FLOAT, Vertex::colorOffset(), Vertex::ColorTupleSize, Vertex::stride());
// Release (unbind) all
m_object.release();
m_vertex.release();
m_program->release();
}
m_initialized = true;
}
void Tile::paint(QMatrix4x4 p, QVector3D& cameraPosition,QVector3D& cameraUpDirection,QMatrix4x4& vMatrix, float zRot)
{
if (!m_initialized) return;
QMatrix4x4 mModelToCamera;
QMatrix4x4 rMatrix;
QMatrix4x4 mMatrix;
float fSunAngle = 45.0;
QVector3D vSunPos(-sin(fSunAngle*PI/180.0f), -cos(fSunAngle*PI/180.0f), 0.0);
glActiveTexture(GL_TEXTURE0);
//mMatrix.translate(m_x*LOD_0_SIZE *1.5+ (m_y%2==1 ?( LOD_0_SIZE*1.5f)/2.0f:0),m_y*LOD_0_SIZE/2.0f,1.0f);
mMatrix.translate(m_x*(LOD_0_SIZE*0.75) ,(m_y*(LOD_0_SIZE_Y*2)+(m_x%2==0?0:LOD_0_SIZE_Y)) ,1.0f);
m_texture->bind(0);
m_texture_border->bind(1);
m_texture_rock->bind(2);
// Render using our shader
m_program->bind();
m_heightsbuffer.create();
m_heightsbuffer.bind();
m_heightsbuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
m_heightsbuffer.allocate(m_tilevertices, sizeof(TileVertexInfo) * (m_numVertex+1));
{ vSunPos.normalize();
float fSign = -1.0f; // This just returns -1.0f or 1.0f (try to examine this)
m_program->setUniformValue("sunLight.vColor", QVector3D(1.0f, 1.0f, 1.0f));
m_program->setUniformValue("sunLight.fAmbientIntensity",0.8f);
m_program->setUniformValue("sunLight.vDirection", vSunPos);
QVector3D vPos = QVector3D(fSign*15.0f, 0.0f, 50.0f-float(0)*25.0f);
vPos.setZ(vPos.z()+1.0f);
mModelToCamera =vMatrix * mMatrix.inverted().transposed();//QMatrix4x4();// vPos.translate(1.0f);
//mModelToCamera.scale(0.8);
m_program->setUniformValue("grass", 0);
m_program->setUniformValue("border", 1);
m_program->setUniformValue("rock", 2);
m_object.bind();
m_heightsbuffer.bind();
m_program->enableAttributeArray(2);
m_program->setAttributeBuffer(2, GL_FLOAT,TileVertexInfo::heightOffset(),TileVertexInfo::HeightTupleSize, TileVertexInfo::stride());
m_program->enableAttributeArray(3);
m_program->setAttributeBuffer(3, GL_FLOAT,TileVertexInfo::normalOffset(),TileVertexInfo::NormalTupleSize, TileVertexInfo::stride());
m_heightsbuffer.release();
rMatrix.translate(0.5f,LOD_0_SIZE_Y,0);
m_program->setUniformValue("cameraPosition", cameraPosition);
//mModelToCamera =vMatrix * mMatrix.inverted().transposed();//QMatrix4x4();// vPos.translate(1.0f);
m_program->setUniformValue("normalMatrix", mModelToCamera);
m_program->setUniformValue("modelMatrix", rMatrix);
m_program->setUniformValue("modelViewMatrix", vMatrix * mMatrix);
m_program->setUniformValue("MVP", p * vMatrix * mMatrix);
glDrawArrays(GL_TRIANGLES, 0, NUM_TRIANGLES*NUM_TRIANGLE_VERTICES);
m_object.release();
}m_heightsbuffer.destroy();
m_program->release();
}
void Tile::buildVertices()
{
m_numVertex= NUM_TRIANGLES*NUM_TRIANGLE_VERTICES;
m_vertices = new Vertex[m_numVertex];
int cnt =0;
for (int i = 0; i< NUM_TRIANGLES_0; i++) {
addTriangleVertices(cnt
, QVector2D( 0.0f, 0.0f)
, QVector2D( 0.5f*cos(PI*60.0f*i/180.0f)*-1.0f , 0.5f*sin(PI*60.0f*i/180.0f))//, QVector2D(-LOD_0_SIZE/2.0f , 0.0f ) )
, QVector2D( 0.5f*cos(PI*60.0f*(i+1)/180.0f)*-1.0f , 0.5f*sin(PI*60.0f*(i+1)/180.0f))//, QVector2D(-LOD_0_SIZE/4.0f , LOD_0_SIZE/2.0f) )
//, QVector2D(0.0f , 0.0f ) )
, 1 , 0, 0 );
}
}
void Tile::addTriangleVertices(int &cnt, QVector2D t1, QVector2D t2, QVector2D t3,int level, int hex, int l1)
{
if (level>0) {
level--;
addTriangleVertices(cnt
, QVector2D( t1.x(), t1.y())//, QVector2D(0,0) )
, QVector2D( (t1.x()+t2.x())/2.0f, (t1.y()+t2.y())/2.0f )//, QVector2D(0,0) )
, QVector2D( (t1.x()+t3.x())/2.0f , (t1.y()+t3.y())/2.0f )//, QVector2D(0,0) )
, level, hex, 0
);
addTriangleVertices(cnt
, QVector2D( (t1.x()+t2.x())/2.0f, (t1.y()+t2.y())/2.0f)//, QVector2D(0,0) )
, QVector2D( (t2.x()+t3.x())/2.0f, (t2.y()+t3.y())/2.0f)//, QVector2D(0,0) )
, QVector2D( (t1.x()+t3.x())/2.0f , (t1.y()+t3.y())/2.0f )//, QVector2D(0,0) )
, level, hex, 1
);
addTriangleVertices(cnt
, QVector2D( (t1.x()+t2.x())/2.0f, (t1.y()+t2.y())/2.0f )//, QVector2D(0,0) )
, QVector2D( t2.x(), t2.y() )//, t1.texturepos()*0.7f )
, QVector2D( (t2.x()+t3.x())/2.0f, (t2.y()+t3.y())/2.0f)//,QVector2D(0,0) )
, level, hex, 2
);
addTriangleVertices(cnt
, QVector2D( (t1.x()+t3.x())/2.0f , (t1.y()+t3.y())/2.0f )//,QVector2D(0,0) )
, QVector2D( (t2.x()+t3.x())/2.0f, (t2.y()+t3.y())/2.0f )//, QVector2D(0,0) )
, QVector2D( t3.x(), t3.y() )//, t1.texturepos())
, level, hex, 3
);
}
else {
drawSubTriangleVertices(cnt
, QVector2D( t1.x(), t1.y())//, QVector2D(0,0) )
, QVector2D( (t1.x()+t2.x())/2.0f, (t1.y()+t2.y())/2.0f )//, QVector2D(0,0) )
, QVector2D( (t1.x()+t3.x())/2.0f , (t1.y()+t3.y())/2.0f )//, QVector2D(0,0) )
, hex, l1,0
);
drawSubTriangleVertices(cnt
, QVector2D( (t1.x()+t2.x())/2.0f, (t1.y()+t2.y())/2.0f)//, QVector2D(0,0) )
, QVector2D( (t2.x()+t3.x())/2.0f, (t2.y()+t3.y())/2.0f)//, QVector2D(0,0) )
, QVector2D( (t1.x()+t3.x())/2.0f , (t1.y()+t3.y())/2.0f )//, QVector2D(0,0) )
, hex, l1,1
);
drawSubTriangleVertices(cnt
, QVector2D( (t1.x()+t2.x())/2.0f, (t1.y()+t2.y())/2.0f )//, QVector2D(0,0) )
, QVector2D( t2.x(), t2.y() )//, t1.texturepos()*0.7f )
, QVector2D( (t2.x()+t3.x())/2.0f, (t2.y()+t3.y())/2.0f)//,QVector2D(0,0) )
, hex, l1,2
);
drawSubTriangleVertices(cnt
, QVector2D( (t1.x()+t3.x())/2.0f , (t1.y()+t3.y())/2.0f )//,QVector2D(0,0) )
, QVector2D( (t2.x()+t3.x())/2.0f, (t2.y()+t3.y())/2.0f )//, QVector2D(0,0) )
, QVector2D( t3.x(), t3.y() )//, t1.texturepos())
, hex, l1,3
);
}
}
void Tile::drawSubTriangleVertices(int &cnt, QVector2D t1, QVector2D t2, QVector2D t3, int hex, int l1, int l2)
{
m_vertices[cnt++] = Vertex( t1
, QVector2D(t1.x()+LOD_0_SIZE/2.0f,t1.y()+LOD_0_SIZE/2.0f)
);
m_vertices[cnt++] = Vertex( t2
, QVector2D(t2.x()+LOD_0_SIZE/2.0f,t2.y()+LOD_0_SIZE/2.0f)
);
m_vertices[cnt++] = Vertex( t3
, QVector2D(t3.x()+LOD_0_SIZE/2.0f,t3.y()+LOD_0_SIZE/2.0f)
);
}
void Tile::buildHeights() {
m_tilevertices = new TileVertexInfo[m_numVertex];
Matrix2D<TerrainPoint> * points = Tile::m_scene->getMapPoints();
for (int i = 0; i< m_numVertex; i++) {
/*float x=m_vertices[i].position().x();
int xpos = m_vertices[i].position().x()*(m_scene->getNumPoints05()*2);
int mappos=(int) round( m_startpoint_x+ ( m_vertices[i].position().x())*(m_scene->getNumPoints05()*2));
int res = (int) round( m_startpoint_x+ ( m_vertices[i].position().x())*(m_scene->getNumPoints05()*2));*/
float r = points->operator ()( (int) round( m_startpoint_x+ ( m_vertices[i].position().x())*(m_scene->getNumPoints05()*2.0f))
,(int) round( m_startpoint_y+ ( m_vertices[i].position().y())*(m_scene->getNumPoints05()*2.0f))).height /255.0f;
//m_heights[i] = 1r;
m_tilevertices[i].setHeight(r);
//m_tilevertices[i].setNormal(QVector3D(rand()%20/10.0f-1.0,rand()%20/10.0f-1.0,rand()%20/10.0f-1.0));
}
m_faces.reserve(m_numVertex/3);
int i =0;
for (int h = 0; h< 6; h++) {
m_face[h].createSub();
for (int l0 = 0; l0< 4; l0++) {
m_face[h].getSub(l0).createSub();
for (int l1 = 0; l1< 4; l1++) {
m_face[h].getSub(l0).getSub(l1).setSettings(
&m_vertices[i],&m_tilevertices[i],
&m_vertices[i+1],&m_tilevertices[i+1],
&m_vertices[i+2],&m_tilevertices[i+2]
);
m_faces.push_back(m_face[h].getSub(l0).getSub(l1));
i +=3;
}
}
}
}
void Tile::findFaces(std::vector<Face *> &vec, QVector2D s)
{
if (!m_initialized) return;
for (int h = 0; h< 6; h++) {
m_face[h].findFaces(vec, s);
}
}
void Tile::buildNormals()
{
if (!m_initialized) return;
std::vector<Face *> vec;
for (int i=0; i<m_numVertex;i++) {
vec.clear();
findFaces(vec, m_vertices[i].position());
m_scene->getTile(m_x-1,m_y)->findFaces(vec,m_vertices[i].position());
m_scene->getTile(m_x+1,m_y)->findFaces(vec,m_vertices[i].position());
QVector3D r;
float cnt =0;
for (std::vector<Face *>::iterator it = vec.begin() ; it != vec.end(); ++it) {
QVector3D v = (*it)->normal();
cnt++;
r.setX(r.x() + v.x());
r.setY(r.y() + v.y());
r.setZ(r.z() + v.z());
}
r.setX(r.x() /cnt);
r.setY(r.y() /cnt);
r.setZ(r.z() /cnt);
m_tilevertices[i].setNormal(r);
}
}