init versie
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
#include "qscenerenderer.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
|
||||
GLuint vertexbuffer;
|
||||
GLuint VertexArrayID;
|
||||
QSceneRenderer::QSceneRenderer(QWidget* parent): QOpenGLWidget(parent)
|
||||
{
|
||||
setFocusPolicy(Qt::FocusPolicy::StrongFocus);
|
||||
installEventFilter(this);
|
||||
QImage img = QImage("/home/bart/project/tiletest/images/heightmap.jpg").convertToFormat(QImage::Format_RGB32);
|
||||
m_zoom = 4;
|
||||
m_point = new Matrix2D<TerrainPoint>(img.width(),img.height());
|
||||
m_numPoints05= img.width()/MAP_WIDTH/1.5/2;
|
||||
for (int y = 0; y<img.height(); y++) {
|
||||
QRgb *line = (QRgb *) img.scanLine(img.height() - 1 - y);
|
||||
TerrainPoint *row = m_point->row(y);
|
||||
for (int x = 0; x<img.width(); x++) {
|
||||
row[x].height = qRed(line[x]);
|
||||
}
|
||||
}
|
||||
|
||||
cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0);
|
||||
cameraTransformation.rotate(zRot, 0, 0, 1);
|
||||
cameraPosition = cameraTransformation * QVector3D(5, 5, 5);
|
||||
/*
|
||||
for (int y=0; y<getNumPointsHeight(); y++)
|
||||
for (int x=0; x<getNumPointsWidth(); x++){
|
||||
|
||||
m_point->operator ()(x,y).height = abs((x*10%200)-100);
|
||||
}*/
|
||||
|
||||
tiles=new Matrix2D<Tile>(MAP_WIDTH,MAP_HEIGHT);
|
||||
}
|
||||
|
||||
Tile * QSceneRenderer::getTile(int x, int y)
|
||||
{
|
||||
return &tiles->operator ()(x,y);
|
||||
}
|
||||
|
||||
void QSceneRenderer::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
lastPos = event->pos();
|
||||
}
|
||||
|
||||
void QSceneRenderer::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
/*int dx = event->x() - lastPos.x();
|
||||
int dy = event->y() - lastPos.y();
|
||||
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
zRot += 8 * dx;
|
||||
} else if (event->buttons() & Qt::RightButton) {
|
||||
zRot -= 8 * dx;
|
||||
}
|
||||
lastPos = event->pos();
|
||||
update();*/
|
||||
|
||||
}
|
||||
|
||||
void QSceneRenderer::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
if (e->key()== Qt::Key_A) {
|
||||
cameraPosition.setX(cameraPosition.x()+ 0.1f*cos(PI*(zRot+90)/180.0f));
|
||||
cameraPosition.setY(cameraPosition.y()+ 0.1f*sin(PI*(zRot+90)/180.0f));
|
||||
}
|
||||
else if (e->key()== Qt::Key_D) {
|
||||
cameraPosition.setX(cameraPosition.x()+ 0.1f*cos(PI*(zRot-90)/180.0f));
|
||||
cameraPosition.setY(cameraPosition.y()+ 0.1f*sin(PI*(zRot-90)/180.0f));
|
||||
}
|
||||
|
||||
if (e->key()== Qt::Key_W) {
|
||||
cameraPosition.setX(cameraPosition.x()+ 0.1f*cos(PI*(zRot+0)/180.0f));
|
||||
cameraPosition.setY(cameraPosition.y()+ 0.1f*sin(PI*(zRot+0)/180.0f));
|
||||
}
|
||||
else if (e->key()== Qt::Key_S) {
|
||||
cameraPosition.setX(cameraPosition.x()+ 0.1f*cos(PI*(zRot+180)/180.0f));
|
||||
cameraPosition.setY(cameraPosition.y()+ 0.1f*sin(PI*(zRot+180)/180.0f));
|
||||
}
|
||||
else if (e->key()== Qt::Key_E) {
|
||||
zRot --;
|
||||
if (zRot<0.0)
|
||||
zRot+=360.0;
|
||||
}
|
||||
else if (e->key()== Qt::Key_Q) {
|
||||
zRot ++;
|
||||
if (zRot>=360.0)
|
||||
zRot-=360.0;
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void QSceneRenderer::wheelEvent(QWheelEvent *e)
|
||||
{
|
||||
m_zoom -= e->delta()/100.0;
|
||||
if (m_zoom<2) m_zoom =2;
|
||||
if (m_zoom>10)m_zoom =10;
|
||||
update();
|
||||
}
|
||||
|
||||
void QSceneRenderer::initializeGL()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
}
|
||||
|
||||
void QSceneRenderer::resizeGL(int width, int height)
|
||||
{
|
||||
Projection= QMatrix4x4();
|
||||
Projection.perspective(45, (float) width / (float)height,0.1f,100.0f);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void QSceneRenderer::paintGL()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
QMatrix4x4 cameraTransformation;
|
||||
QMatrix4x4 vMatrix;
|
||||
|
||||
cameraTransformation.rotate(zRot, 0, 0, 1);
|
||||
cameraUpDirection = cameraTransformation * QVector3D(0, 0, 1);
|
||||
cameraPosition.setZ(m_zoom);
|
||||
|
||||
QVector3D lookat = QVector3D(cameraPosition.x()+ m_zoom*m_zoom/5.0f*cos(PI*zRot/180.0f)
|
||||
, cameraPosition.y()+ m_zoom*m_zoom/5.0f*sin(PI*zRot/180.0f)
|
||||
,0);
|
||||
vMatrix.lookAt(cameraPosition, lookat, cameraUpDirection);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Bounding box of the visible area in world coordinates
|
||||
float minWorldX = std::min(cameraPosition.x(), lookat.x());
|
||||
float maxWorldX = std::max(cameraPosition.x(), lookat.x());
|
||||
float minWorldY = std::min(cameraPosition.y(), lookat.y());
|
||||
float maxWorldY = std::max(cameraPosition.y(), lookat.y());
|
||||
|
||||
float margin = m_zoom * 2.5f + 8.0f;
|
||||
minWorldX -= margin;
|
||||
maxWorldX += margin;
|
||||
minWorldY -= margin;
|
||||
maxWorldY += margin;
|
||||
|
||||
float tileStepX = LOD_0_SIZE * 0.75f;
|
||||
float tileStepY = LOD_0_SIZE_Y * 2.0f;
|
||||
|
||||
int minTileX = std::max(0, (int)floor(minWorldX / tileStepX));
|
||||
int maxTileX = std::min(MAP_WIDTH - 1, (int)ceil(maxWorldX / tileStepX));
|
||||
int minTileY = std::max(0, (int)floor(minWorldY / tileStepY));
|
||||
int maxTileY = std::min(MAP_HEIGHT - 1, (int)ceil(maxWorldY / tileStepY));
|
||||
|
||||
// Expand margin by 1 for neighbor normal calculations
|
||||
int initMinX = std::max(0, minTileX - 1);
|
||||
int initMaxX = std::min(MAP_WIDTH - 1, maxTileX + 1);
|
||||
int initMinY = std::max(0, minTileY - 1);
|
||||
int initMaxY = std::min(MAP_HEIGHT - 1, maxTileY + 1);
|
||||
|
||||
// 1. Lazy initialize visible tiles and direct neighbors
|
||||
for (int y = initMinY; y <= initMaxY; ++y) {
|
||||
for (int x = initMinX; x <= initMaxX; ++x) {
|
||||
tiles->operator()(x, y).ensureInitialized(this, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Ensure normals are built for visible tiles
|
||||
for (int y = minTileY; y <= maxTileY; ++y) {
|
||||
for (int x = minTileX; x <= maxTileX; ++x) {
|
||||
tiles->operator()(x, y).ensureNormalsBuilt();
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Render only visible tiles
|
||||
for (int y = minTileY; y <= maxTileY; ++y) {
|
||||
for (int x = minTileX; x <= maxTileX; ++x) {
|
||||
tiles->operator()(x, y).paint(Projection, cameraPosition, cameraUpDirection, vMatrix, zRot);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user