From 623fc8c73de35bef0785f09bae8a3f607f8ed087 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Fri, 27 Apr 2012 20:43:08 +0200 Subject: qt_terr - a simple quadtree based terrain renderer with LOD --- samples/OpenGL/qt_terr/terragen.cpp | 138 ++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 samples/OpenGL/qt_terr/terragen.cpp (limited to 'samples/OpenGL/qt_terr/terragen.cpp') diff --git a/samples/OpenGL/qt_terr/terragen.cpp b/samples/OpenGL/qt_terr/terragen.cpp new file mode 100644 index 0000000..3b922a4 --- /dev/null +++ b/samples/OpenGL/qt_terr/terragen.cpp @@ -0,0 +1,138 @@ +#include +#include +#include +#include + +#include "terragen.h" + +// Some custom types and helper macros that +// allow for a portable file to number variable +// read procedure + +typedef uint8_t DUET[2]; +typedef uint8_t QUARTET[4]; +typedef uint8_t OCTET[8]; + +#define DUET_TO_NUMBER(duet) ((duet[0]|duet[1]<<8)) +#define QUARTET_TO_NUMBER(quartet) ((quartet[0])|(quartet[1]<<8)|(quartet[2]<<16)|(quartet[3]<<24)) + +int read_terrain(char *filename, double **pbuffer, int *width, int *height, double *scale) +// [in] filename: path to the file to be read in +// [out] pbuffer: address of new allocated data buffer +// [out] width: width of the terrain +// [out] heigt: height of the terrain +// [out] return value: 0 if read in successfully 1 otherwise +{ + FILE *file=fopen(filename, "rb"); + if(!file) + return -1; + + OCTET octet; + QUARTET quartet; + QUARTET quartet_marker; + DUET duet; + + fread(octet, 8, 1, file); + if(memcmp(octet, "TERRAGEN", 8)) + return -1; + + fread(octet, 8, 1, file); + if(memcmp(octet, "TERRAIN ", 8)) + return -1; + + fread(quartet, 4, 1, file); + if(memcmp(quartet, "SIZE", 4)) + return -1; + fread(duet, 2, 1, file); + fseek(file, 2, SEEK_CUR); + int size=DUET_TO_NUMBER(duet); + + int xpts=0, ypts=0; + do + { + fread(quartet_marker, 4, 1, file); + + if(memcmp(quartet_marker, "XPTS", 4)==0) + { + fread(duet, 2, 1, file); + fseek(file, 2, SEEK_CUR); + xpts=DUET_TO_NUMBER(duet); + continue; + } + + if(memcmp(quartet_marker, "YPTS", 4)==0) + { + fread(duet, 2, 1, file); + fseek(file, 2, SEEK_CUR); + ypts=DUET_TO_NUMBER(duet); + continue; + } + + // I'm going to ignore the other segments so long + // so we can leave the quartet marker test to the + // while condition + //if(strcmp(quartet_marker, "SIZE")) // Ignore SIZE + // fseek(file, 4, SEEK_CUR); + + if(memcmp(quartet_marker, "SCAL", 4)==0&&scale) // Ignore SCAL + { + float fscale[3]; + fread(&(fscale[0]), 4, 1, file); + fread(&(fscale[1]), 4, 1, file); + fread(&(fscale[2]), 4, 1, file); + scale[0]=fscale[0]; + scale[1]=fscale[1]; + scale[2]=fscale[2]; + } + + //if(strcmp(quartet_marker, "CRAD")) // Ignore CRAD + // fseek(file, 4, SEEK_CUR); + + //if(strcmp(quartet_marker, "CRVM")) // Ignore CRVM + // fseek(file, 4, SEEK_CUR); + + }while(memcmp(quartet_marker, "ALTW", 4)); + + int16_t height_scale, base_height; + fread(duet, 2, 1, file); + height_scale = DUET_TO_NUMBER(duet); + fread(duet, 2, 1, file); + base_height = DUET_TO_NUMBER(duet); + + if(xpts==0&&ypts==0) + { + xpts=size+1; + ypts=size+1; + } + + *width=xpts; + *height=ypts; + + // The caller of this function is responsible + // to free the memory consumed by buffer + DUET *buffer=new DUET[xpts*ypts]; + fread(buffer, 2, xpts*ypts, file); + + *pbuffer=new double[xpts*ypts]; + for(int y=0; y(base_height+elev*height_scale/65536); + } + } + delete[] buffer; + + // a last test, the next we read should be "EOF ", since currently the Terragen + // file format says, that "ALTW" must be the last segment of a file + // however it's no problem for _us_ if we've no "EOF " here, because it doesn't matter + fread(quartet, 4, 1, file); + if(memcmp(quartet, "EOF ", 4)) + printf("read terrain file with \"EOF \" at the end\n"); + + fclose(file); + return 0; +} -- cgit v1.2.3