adjusts names

This commit is contained in:
tosh 2013-05-19 13:01:57 +02:00
parent 188ff45a45
commit de665c2d48
14 changed files with 391 additions and 391 deletions

View file

@ -49,27 +49,27 @@ namespace {
Log::Log(FILE* tPipeTo, unsigned bufferedLines, Log::Log(FILE* tPipeTo, unsigned bufferedLines,
unsigned defaultLogWidth, unsigned defaultCharWidth, unsigned defaultCharHeight) : unsigned defaultLogWidth, unsigned defaultCharWidth, unsigned defaultCharHeight) :
_ptrStream(tPipeTo), _stream(tPipeTo),
_arrChars(0l), _chars(0l),
_arrLines(0l), _lines(0l),
_valLogWidth(defaultLogWidth) { _logWidth(defaultLogWidth) {
pthread_mutex_init(& _mtx, 0l); pthread_mutex_init(& _mutex, 0l);
// allocate twice as much (so we have spare space for a copy not to block // allocate twice as much (so we have spare space for a copy not to block
// logging from other threads during 'render') // logging from other threads during 'render')
_arrChars = new char[CHARACTER_BUFFER_SIZE * 2]; _chars = new char[CHARACTER_BUFFER_SIZE * 2];
_ptrCharsEnd = _arrChars + CHARACTER_BUFFER_SIZE; _charsEnd = _chars + CHARACTER_BUFFER_SIZE;
_arrLines = new char*[LINE_BUFFER_SIZE * 2]; _lines = new char*[LINE_BUFFER_SIZE * 2];
_ptrLinesEnd = _arrLines + LINE_BUFFER_SIZE; _linesEnd = _lines + LINE_BUFFER_SIZE;
// initialize the log to all empty lines // initialize the log to all empty lines
_arrChars[0] = '\0'; _chars[0] = '\0';
_itrWritePos = _arrChars; _writePos = _chars;
_itrWriteLineStart = _arrChars; _writeLineStartPos = _chars;
_itrLastLine = _arrLines; _lastLinePos = _lines;
_valWrittenInLine = 0; _writtenInLine = 0;
memset(_arrLines, 0, LINE_BUFFER_SIZE * sizeof(char*)); memset(_lines, 0, LINE_BUFFER_SIZE * sizeof(char*));
setCharacterSize(defaultCharWidth, defaultCharHeight); setCharacterSize(defaultCharWidth, defaultCharHeight);
} }
@ -77,8 +77,8 @@ Log::Log(FILE* tPipeTo, unsigned bufferedLines,
Log::~Log() { Log::~Log() {
delete[] _arrChars; delete[] _chars;
delete[] _arrLines; delete[] _lines;
} }
inline void Log::addMessage(char const* ptr) { inline void Log::addMessage(char const* ptr) {
@ -86,8 +86,8 @@ inline void Log::addMessage(char const* ptr) {
// precondition: mutex is locked so noone gets in our way // precondition: mutex is locked so noone gets in our way
// T-pipe, if requested // T-pipe, if requested
if (_ptrStream != 0l) { if (_stream != 0l) {
fprintf(_ptrStream, "%s", ptr); fprintf(_stream, "%s", ptr);
} }
while (*ptr != '\0') { while (*ptr != '\0') {
@ -104,51 +104,51 @@ inline void Log::addMessage(char const* ptr) {
// found LF -> write NUL (c == '\0' tells us to wrap, below) // found LF -> write NUL (c == '\0' tells us to wrap, below)
c = '\0'; c = '\0';
} }
*_itrWritePos++ = c; *_writePos++ = c;
if (_itrWritePos == _ptrCharsEnd) { if (_writePos == _charsEnd) {
// reached the end of the circular character buffer? -> start over // reached the end of the circular character buffer? -> start over
_itrWritePos = _arrChars; _writePos = _chars;
} }
if (++_valWrittenInLine >= _valLineLength || c == '\0') { if (++_writtenInLine >= _lineLength || c == '\0') {
// new line? store its start to the line buffer and mark next line as empty // new line? store its start to the line buffer and mark next line as empty
++_itrLastLine; ++_lastLinePos;
if (_itrLastLine == _ptrLinesEnd) { if (_lastLinePos == _linesEnd) {
_itrLastLine = _arrLines; _lastLinePos = _lines;
_itrLastLine[1] = 0l; _lastLinePos[1] = 0l;
} else if (_itrLastLine + 1 != _ptrLinesEnd) { } else if (_lastLinePos + 1 != _linesEnd) {
_itrLastLine[1] = 0l; _lastLinePos[1] = 0l;
} else { } else {
_arrLines[0] = 0l; _lines[0] = 0l;
} }
*_itrLastLine = _itrWriteLineStart; *_lastLinePos = _writeLineStartPos;
// debug mode: make sure all line pointers we write here are valid // debug mode: make sure all line pointers we write here are valid
assert(! (_itrLastLine < _arrLines || _itrLastLine >= _ptrLinesEnd)); assert(! (_lastLinePos < _lines || _lastLinePos >= _linesEnd));
assert(! (*_itrLastLine < _arrChars || *_itrLastLine >= _ptrCharsEnd)); assert(! (*_lastLinePos < _chars || *_lastLinePos >= _charsEnd));
// terminate line, unless done already // terminate line, unless done already
if (c != '\0') { if (c != '\0') {
*_itrWritePos++ = '\0'; *_writePos++ = '\0';
if (_itrWritePos == _ptrCharsEnd) { if (_writePos == _charsEnd) {
_itrWritePos = _arrChars; _writePos = _chars;
} }
} }
// remember start position in character buffer for next line and reset character count // remember start position in character buffer for next line and reset character count
_itrWriteLineStart = _itrWritePos; _writeLineStartPos = _writePos;
_valWrittenInLine = 0; _writtenInLine = 0;
} }
} }
} }
int Log::vprint(char const* fmt, va_list args) { int Log::vprint(char const* fmt, va_list args) {
pthread_mutex_lock(& _mtx); pthread_mutex_lock(& _mutex);
// print to buffer // print to buffer
char buf[MAX_MESSAGE_LENGTH]; char buf[MAX_MESSAGE_LENGTH];
@ -161,11 +161,11 @@ int Log::vprint(char const* fmt, va_list args) {
} else { } else {
// error? -> mutter on stream or stderr // error? -> mutter on stream or stderr
fprintf(_ptrStream != 0l ? _ptrStream : stderr, fprintf(_stream != 0l ? _stream : stderr,
"Log: Failed to log message with format string = \"%s\".\n", fmt); "Log: Failed to log message with format string = \"%s\".\n", fmt);
} }
pthread_mutex_unlock(& _mtx); pthread_mutex_unlock(& _mutex);
return n; return n;
} }
@ -179,22 +179,22 @@ void Log::operator()(char const* fmt, ...) {
void Log::setLogWidth(unsigned pixels) { void Log::setLogWidth(unsigned pixels) {
pthread_mutex_lock(& _mtx); pthread_mutex_lock(& _mutex);
_valLogWidth = pixels; _logWidth = pixels;
_valLineLength = _valLogWidth / _valCharWidth; _lineLength = _logWidth / _charWidth;
pthread_mutex_unlock(& _mtx); pthread_mutex_unlock(& _mutex);
} }
void Log::setCharacterSize(unsigned width, unsigned height) { void Log::setCharacterSize(unsigned width, unsigned height) {
pthread_mutex_lock(& _mtx); pthread_mutex_lock(& _mutex);
_valCharWidth = width; _charWidth = width;
_valCharHeight = height; _charHeight = height;
_valCharYoffset = height * CHAR_FRACT_BASELINE; _charYoffset = height * CHAR_FRACT_BASELINE;
_valCharScale = float(width) / CHAR_WIDTH; _charScale = float(width) / CHAR_WIDTH;
_valCharAspect = (height * CHAR_WIDTH) / (width * CHAR_HEIGHT); _charAspect = (height * CHAR_WIDTH) / (width * CHAR_HEIGHT);
_valLineLength = _valLogWidth / _valCharWidth; _lineLength = _logWidth / _charWidth;
pthread_mutex_unlock(& _mtx); pthread_mutex_unlock(& _mutex);
} }
static TextRenderer* textRenderer() { static TextRenderer* textRenderer() {
@ -206,17 +206,17 @@ void Log::render(unsigned screenWidth, unsigned screenHeight) {
// rendering might take some time, so create a local copy of the portion we need // rendering might take some time, so create a local copy of the portion we need
// instead of having to hold the mutex all the time // instead of having to hold the mutex all the time
pthread_mutex_lock(& _mtx); pthread_mutex_lock(& _mutex);
// determine number of visible lines // determine number of visible lines
unsigned showLines = divRoundUp(screenHeight, _valCharHeight); unsigned showLines = divRoundUp(screenHeight, _charHeight);
char** lastLine = _itrLastLine; char** lastLine = _lastLinePos;
char** firstLine = _itrLastLine; char** firstLine = _lastLinePos;
if (! *lastLine) { if (! *lastLine) {
// empty log // empty log
pthread_mutex_unlock(& _mtx); pthread_mutex_unlock(& _mutex);
return; return;
} }
@ -225,8 +225,8 @@ void Log::render(unsigned screenWidth, unsigned screenHeight) {
char** prevFirstLine = firstLine; char** prevFirstLine = firstLine;
--firstLine; --firstLine;
if (firstLine < _arrLines) { if (firstLine < _lines) {
firstLine = _ptrLinesEnd - 1; firstLine = _linesEnd - 1;
} }
if (! *firstLine) { if (! *firstLine) {
firstLine = prevFirstLine; firstLine = prevFirstLine;
@ -235,37 +235,37 @@ void Log::render(unsigned screenWidth, unsigned screenHeight) {
} }
// debug mode: make sure all line pointers we find here are valid // debug mode: make sure all line pointers we find here are valid
assert(! (firstLine < _arrLines || firstLine >= _ptrLinesEnd)); assert(! (firstLine < _lines || firstLine >= _linesEnd));
assert(! (*firstLine < _arrChars || *firstLine >= _ptrCharsEnd)); assert(! (*firstLine < _chars || *firstLine >= _charsEnd));
} }
// copy the line buffer portion into a contiguous region at _ptrLinesEnd // copy the line buffer portion into a contiguous region at _linesEnd
if (firstLine <= lastLine) { if (firstLine <= lastLine) {
memcpy(_ptrLinesEnd, firstLine, showLines * sizeof(char*)); memcpy(_linesEnd, firstLine, showLines * sizeof(char*));
} else { } else {
unsigned atEnd = _ptrLinesEnd - firstLine; unsigned atEnd = _linesEnd - firstLine;
memcpy(_ptrLinesEnd, firstLine, atEnd * sizeof(char*)); memcpy(_linesEnd, firstLine, atEnd * sizeof(char*));
memcpy(_ptrLinesEnd + atEnd, _arrLines, (showLines - atEnd) * sizeof(char*)); memcpy(_linesEnd + atEnd, _lines, (showLines - atEnd) * sizeof(char*));
} }
// copy relevant char buffer portion and determine information to remap the pointers // copy relevant char buffer portion and determine information to remap the pointers
char* firstChar = *firstLine; char* firstChar = *firstLine;
char* lastChar = *lastLine + strlen(*lastLine) + 1; char* lastChar = *lastLine + strlen(*lastLine) + 1;
ptrdiff_t charOffset = _ptrCharsEnd - firstChar, charOffsetBeforeFirst = 0; ptrdiff_t charOffset = _charsEnd - firstChar, charOffsetBeforeFirst = 0;
if (firstChar <= lastChar) { if (firstChar <= lastChar) {
memcpy(_ptrCharsEnd, firstChar, lastChar - firstChar + 1); memcpy(_charsEnd, firstChar, lastChar - firstChar + 1);
} else { } else {
unsigned atEnd = _ptrCharsEnd - firstChar; unsigned atEnd = _charsEnd - firstChar;
memcpy(_ptrCharsEnd, firstChar, atEnd); memcpy(_charsEnd, firstChar, atEnd);
memcpy(_ptrCharsEnd + atEnd, _arrChars, lastChar + 1 - _arrChars); memcpy(_charsEnd + atEnd, _chars, lastChar + 1 - _chars);
charOffsetBeforeFirst = _ptrCharsEnd + atEnd - _arrChars; charOffsetBeforeFirst = _charsEnd + atEnd - _chars;
} }
// get values for rendering // get values for rendering
@ -273,31 +273,31 @@ void Log::render(unsigned screenWidth, unsigned screenHeight) {
int yStart = screenHeight - textRenderer()->metrics().descent(); int yStart = screenHeight - textRenderer()->metrics().descent();
// render text // render text
char** line = _ptrLinesEnd + showLines; char** line = _linesEnd + showLines;
int x = screenWidth - _valLogWidth; int x = screenWidth - _logWidth;
pthread_mutex_unlock(& _mtx); pthread_mutex_unlock(& _mutex);
// ok, we got all we need // ok, we got all we need
for (int y = yStart; y > 0; y -= yStep) { for (int y = yStart; y > 0; y -= yStep) {
// debug mode: check line pointer is valid // debug mode: check line pointer is valid
assert(! (line < _ptrLinesEnd || line >= _ptrLinesEnd + (_ptrLinesEnd - _arrLines))); assert(! (line < _linesEnd || line >= _linesEnd + (_linesEnd - _lines)));
// get character pointer // get character pointer
if (--line < _ptrLinesEnd) { if (--line < _linesEnd) {
break; break;
} }
char* chars = *line; char* chars = *line;
// debug mode: check char pointer we find is valid // debug mode: check char pointer we find is valid
assert(! (chars < _arrChars || chars >= _ptrCharsEnd)); assert(! (chars < _chars || chars >= _charsEnd));
// remap character pointer it to copied buffer // remap character pointer it to copied buffer
chars += chars >= firstChar ? charOffset : charOffsetBeforeFirst; chars += chars >= firstChar ? charOffset : charOffsetBeforeFirst;
// debug mode: check char pointer is still valid (in new range) // debug mode: check char pointer is still valid (in new range)
assert(! (chars < _ptrCharsEnd || chars >= _ptrCharsEnd + (_ptrCharsEnd - _arrChars))); assert(! (chars < _charsEnd || chars >= _charsEnd + (_charsEnd - _chars)));
// render the string // render the string
glColor3f(TEXT_RED, TEXT_GREEN, TEXT_BLUE); glColor3f(TEXT_RED, TEXT_GREEN, TEXT_BLUE);

View file

@ -48,26 +48,26 @@ extern Log logger;
// Logging subsystem. // Logging subsystem.
// //
class Log { class Log {
FILE* _ptrStream; FILE* _stream;
char* _arrChars; char* _chars;
char* _ptrCharsEnd; char* _charsEnd;
char** _arrLines; char** _lines;
char** _ptrLinesEnd; char** _linesEnd;
char* _itrWritePos; // character position to write to char* _writePos; // character position to write to
char* _itrWriteLineStart; // character position where line being written starts char* _writeLineStartPos; // character position where line being written starts
char** _itrLastLine; // last line in the log char** _lastLinePos; // last line in the log
unsigned _valWrittenInLine; // character counter for line wrapping unsigned _writtenInLine; // character counter for line wrapping
unsigned _valLineLength; // number of characters before line wrap unsigned _lineLength; // number of characters before line wrap
unsigned _valLogWidth; // width of the log in pixels unsigned _logWidth; // width of the log in pixels
unsigned _valCharWidth; // width of a character in pixels unsigned _charWidth; // width of a character in pixels
unsigned _valCharHeight; // height of a character in pixels unsigned _charHeight; // height of a character in pixels
unsigned _valCharYoffset; // baseline offset in pixels unsigned _charYoffset; // baseline offset in pixels
float _valCharScale; // scale factor float _charScale; // scale factor
float _valCharAspect; // aspect (h/w) float _charAspect; // aspect (h/w)
pthread_mutex_t _mtx; pthread_mutex_t _mutex;
public: public:

View file

@ -26,9 +26,9 @@
// lOut << "Hello there!" << std::endl; // lOut << "Hello there!" << std::endl;
// //
class LogStream { class LogStream {
std::ostringstream _objOutStream; std::ostringstream _outStream;
Log& _refLog; Log& _logRef;
bool _flgThreadSafe; bool _isThreadSafe;
public: public:
inline LogStream(Log& log, bool threadSafe = false); inline LogStream(Log& log, bool threadSafe = false);
@ -46,26 +46,26 @@ private:
}; };
inline LogStream::LogStream(Log& log, bool threadSafe) : inline LogStream::LogStream(Log& log, bool threadSafe) :
_objOutStream(std::ios_base::out), _refLog(log), _flgThreadSafe(threadSafe) { } _outStream(std::ios_base::out), _logRef(log), _isThreadSafe(threadSafe) { }
inline void LogStream::ostreamBegin() { inline void LogStream::ostreamBegin() {
if (_flgThreadSafe) { if (_isThreadSafe) {
// the user wants to share this LogStream among threads, // the user wants to share this LogStream among threads,
// so lock the global log here, already // so lock the global log here, already
pthread_mutex_lock(& _refLog._mtx); pthread_mutex_lock(& _logRef._mutex);
} }
_objOutStream.str(""); _outStream.str("");
} }
inline void LogStream::ostreamEnd() { inline void LogStream::ostreamEnd() {
if (! _flgThreadSafe) { if (! _isThreadSafe) {
// haven't locked, so far (we have memory for each thread) // haven't locked, so far (we have memory for each thread)
pthread_mutex_lock(& _refLog._mtx); pthread_mutex_lock(& _logRef._mutex);
} }
_refLog.addMessage(_objOutStream.str().c_str()); _logRef.addMessage(_outStream.str().c_str());
pthread_mutex_unlock(& _refLog._mtx); pthread_mutex_unlock(& _logRef._mutex);
} }
@ -73,22 +73,22 @@ inline void LogStream::ostreamEnd() {
// The Log::StreamRef class makes operator<< work. It... // The Log::StreamRef class makes operator<< work. It...
// //
class LogStream::StreamRef { class LogStream::StreamRef {
mutable LogStream* _ptrLogStream; mutable LogStream* _logStream;
typedef std::ostream& (*manipulator)(std::ostream&); typedef std::ostream& (*manipulator)(std::ostream&);
friend class LogStream; friend class LogStream;
template< typename T > friend inline LogStream::StreamRef const operator<<(LogStream&, T const&); template< typename T > friend inline LogStream::StreamRef const operator<<(LogStream&, T const&);
StreamRef(LogStream* log) : _ptrLogStream(log) { } StreamRef(LogStream* log) : _logStream(log) { }
public: public:
// ...forwards << operator calls to stringstream... // ...forwards << operator calls to stringstream...
template< typename T > StreamRef const operator<<(T const& x) const { _ptrLogStream->_objOutStream << x; return *this; } template< typename T > StreamRef const operator<<(T const& x) const { _logStream->_outStream << x; return *this; }
// ...has to dance around to make manipulators (such as std::hex, std::endl) work... // ...has to dance around to make manipulators (such as std::hex, std::endl) work...
StreamRef const operator<<(manipulator x) const { _ptrLogStream->_objOutStream << x; return *this; } StreamRef const operator<<(manipulator x) const { _logStream->_outStream << x; return *this; }
// ...informs the logger that a stream has ended when it has the responsibility... // ...informs the logger that a stream has ended when it has the responsibility...
~StreamRef() { if (_ptrLogStream != 0l) { _ptrLogStream->ostreamEnd(); } } ~StreamRef() { if (_logStream != 0l) { _logStream->ostreamEnd(); } }
// ...which is passed on upon copy. // ...which is passed on upon copy.
StreamRef(StreamRef const& other) : _ptrLogStream(other._ptrLogStream) { other._ptrLogStream = 0l; } StreamRef(StreamRef const& other) : _logStream(other._logStream) { other._logStream = 0l; }
private: private:
// don't // don't
@ -98,7 +98,7 @@ private:
template< typename T > inline LogStream::StreamRef const operator<<(LogStream& s, T const& x) { template< typename T > inline LogStream::StreamRef const operator<<(LogStream& s, T const& x) {
s.ostreamBegin(); s.ostreamBegin();
s._objOutStream << x; s._outStream << x;
return LogStream::StreamRef(& s); // calls streamEnd at the end of the stream expression return LogStream::StreamRef(& s); // calls streamEnd at the end of the stream expression
} }

View file

@ -33,26 +33,26 @@ namespace { // everything in here only exists while compiling this .cpp file
Oscilloscope::Oscilloscope(int w, int h, bool isEnabled) : Oscilloscope::Oscilloscope(int w, int h, bool isEnabled) :
_valWidth(w), _valHeight(h), _width(w), _height(h),
_arrSamples(0l), _arrVertices(0l), _samples(0l), _vertices(0l),
_valLowpassFactor(0.4f), _valDownsampleFactor(3), _lowpassFactor(0.4f), _downsampleFactor(3),
enabled(isEnabled), inputPaused(false) { enabled(isEnabled), inputPaused(false) {
// allocate enough space for the sample data and to turn it into // allocate enough space for the sample data and to turn it into
// vertices and since they're all 'short', do so in one shot // vertices and since they're all 'short', do so in one shot
_arrSamples = new short[N_INT16_TO_ALLOC]; _samples = new short[N_INT16_TO_ALLOC];
memset(_arrSamples, 0, N_INT16_TO_ALLOC * sizeof(short)); memset(_samples, 0, N_INT16_TO_ALLOC * sizeof(short));
_arrVertices = _arrSamples + MAX_SAMPLES; _vertices = _samples + MAX_SAMPLES;
// initialize write positions to start of each channel's region // initialize write positions to start of each channel's region
for (unsigned ch = 0; ch < MAX_CHANNELS; ++ch) { for (unsigned ch = 0; ch < MAX_CHANNELS; ++ch) {
_arrWritePos[ch] = MAX_SAMPLES_PER_CHANNEL * ch; _writePos[ch] = MAX_SAMPLES_PER_CHANNEL * ch;
} }
} }
Oscilloscope::~Oscilloscope() { Oscilloscope::~Oscilloscope() {
delete[] _arrSamples; delete[] _samples;
} }
void Oscilloscope::addSamples(unsigned ch, short const* data, unsigned n) { void Oscilloscope::addSamples(unsigned ch, short const* data, unsigned n) {
@ -66,7 +66,7 @@ void Oscilloscope::addSamples(unsigned ch, short const* data, unsigned n) {
unsigned endOffs = baseOffs + MAX_SAMPLES_PER_CHANNEL; unsigned endOffs = baseOffs + MAX_SAMPLES_PER_CHANNEL;
// fetch write position for this channel // fetch write position for this channel
unsigned writePos = _arrWritePos[ch]; unsigned writePos = _writePos[ch];
// determine write position after adding the samples // determine write position after adding the samples
unsigned newWritePos = writePos + n; unsigned newWritePos = writePos + n;
@ -79,13 +79,13 @@ void Oscilloscope::addSamples(unsigned ch, short const* data, unsigned n) {
} }
// copy data // copy data
memcpy(_arrSamples + writePos, data, n * sizeof(short)); memcpy(_samples + writePos, data, n * sizeof(short));
if (n2 > 0) { if (n2 > 0) {
memcpy(_arrSamples + baseOffs, data + n, n2 * sizeof(short)); memcpy(_samples + baseOffs, data + n, n2 * sizeof(short));
} }
// set new write position for this channel // set new write position for this channel
_arrWritePos[ch] = newWritePos; _writePos[ch] = newWritePos;
} }
void Oscilloscope::render(int x, int y) { void Oscilloscope::render(int x, int y) {
@ -95,19 +95,19 @@ void Oscilloscope::render(int x, int y) {
} }
// determine lowpass / downsample factors // determine lowpass / downsample factors
int lowpass = -int(std::numeric_limits<short>::min()) * _valLowpassFactor; int lowpass = -int(std::numeric_limits<short>::min()) * _lowpassFactor;
unsigned downsample = _valDownsampleFactor; unsigned downsample = _downsampleFactor;
// keep half of the buffer for writing and ensure an even vertex count // keep half of the buffer for writing and ensure an even vertex count
unsigned usedWidth = min(_valWidth, MAX_SAMPLES_PER_CHANNEL / (downsample * 2)) & ~1u; unsigned usedWidth = min(_width, MAX_SAMPLES_PER_CHANNEL / (downsample * 2)) & ~1u;
unsigned usedSamples = usedWidth * downsample; unsigned usedSamples = usedWidth * downsample;
// expand samples to vertex data // expand samples to vertex data
for (unsigned ch = 0; ch < MAX_CHANNELS; ++ch) { for (unsigned ch = 0; ch < MAX_CHANNELS; ++ch) {
// for each channel: determine memory regions // for each channel: determine memory regions
short const* basePtr = _arrSamples + MAX_SAMPLES_PER_CHANNEL * ch; short const* basePtr = _samples + MAX_SAMPLES_PER_CHANNEL * ch;
short const* endPtr = basePtr + MAX_SAMPLES_PER_CHANNEL; short const* endPtr = basePtr + MAX_SAMPLES_PER_CHANNEL;
short const* inPtr = _arrSamples + _arrWritePos[ch]; short const* inPtr = _samples + _writePos[ch];
short* outPtr = _arrVertices + MAX_COORDS_PER_CHANNEL * ch; short* outPtr = _vertices + MAX_COORDS_PER_CHANNEL * ch;
int sample = 0, x = usedWidth; int sample = 0, x = usedWidth;
for (int i = int(usedSamples); --i >= 0 ;) { for (int i = int(usedSamples); --i >= 0 ;) {
if (inPtr == basePtr) { if (inPtr == basePtr) {
@ -124,13 +124,13 @@ void Oscilloscope::render(int x, int y) {
} }
} }
// set up rendering state (vertex data lives at _arrVertices) // set up rendering state (vertex data lives at _vertices)
glLineWidth(1.0); glLineWidth(1.0);
glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH);
glPushMatrix(); glPushMatrix();
glTranslatef((float)x + 0.0f, (float)y + _valHeight / 2.0f, 0.0f); glTranslatef((float)x + 0.0f, (float)y + _height / 2.0f, 0.0f);
glScaled(1.0f, _valHeight / 32767.0f, 1.0f); glScaled(1.0f, _height / 32767.0f, 1.0f);
glVertexPointer(2, GL_SHORT, 0, _arrVertices); glVertexPointer(2, GL_SHORT, 0, _vertices);
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
// render channel 0 // render channel 0

View file

@ -26,8 +26,8 @@ public:
volatile bool enabled; volatile bool enabled;
volatile bool inputPaused; volatile bool inputPaused;
void setLowpass(float w) { assert(w > 0.0f && w <= 1.0f); _valLowpassFactor = w; } void setLowpass(float w) { assert(w > 0.0f && w <= 1.0f); _lowpassFactor = w; }
void setDownsampling(unsigned f) { assert(f > 0); _valDownsampleFactor = f; } void setDownsampling(unsigned f) { assert(f > 0); _downsampleFactor = f; }
private: private:
// don't copy/assign // don't copy/assign
@ -36,14 +36,14 @@ private:
// state variables // state variables
unsigned _valWidth; unsigned _width;
unsigned _valHeight; unsigned _height;
short* _arrSamples; short* _samples;
short* _arrVertices; short* _vertices;
unsigned _arrWritePos[MAX_CHANNELS]; unsigned _writePos[MAX_CHANNELS];
float _valLowpassFactor; float _lowpassFactor;
unsigned _valDownsampleFactor; unsigned _downsampleFactor;
}; };
#endif /* defined(__interface__oscilloscope__) */ #endif /* defined(__interface__oscilloscope__) */

View file

@ -14,24 +14,24 @@
#undef __interface__Starfield_impl__ #undef __interface__Starfield_impl__
Stars::Stars() : Stars::Stars() :
_ptrController(0l) { _controller(0l) {
_ptrController = new starfield::Controller; _controller = new starfield::Controller;
} }
Stars::~Stars() { Stars::~Stars() {
delete _ptrController; delete _controller;
} }
bool Stars::readInput(const char* url, const char* cacheFile, unsigned limit) { bool Stars::readInput(const char* url, const char* cacheFile, unsigned limit) {
return _ptrController->readInput(url, cacheFile, limit); return _controller->readInput(url, cacheFile, limit);
} }
bool Stars::setResolution(unsigned k) { bool Stars::setResolution(unsigned k) {
return _ptrController->setResolution(k); return _controller->setResolution(k);
} }
float Stars::changeLOD(float fraction, float overalloc, float realloc) { float Stars::changeLOD(float fraction, float overalloc, float realloc) {
return float(_ptrController->changeLOD(fraction, overalloc, realloc)); return float(_controller->changeLOD(fraction, overalloc, realloc));
} }
void Stars::render(float fovY, float aspect, float nearZ, float alpha) { void Stars::render(float fovY, float aspect, float nearZ, float alpha) {
@ -46,7 +46,7 @@ void Stars::render(float fovY, float aspect, float nearZ, float alpha) {
// pull the modelview matrix off the GL stack // pull the modelview matrix off the GL stack
glm::mat4 view; glGetFloatv(GL_MODELVIEW_MATRIX, glm::value_ptr(view)); glm::mat4 view; glGetFloatv(GL_MODELVIEW_MATRIX, glm::value_ptr(view));
_ptrController->render(fovDiagonal, aspect, glm::affineInverse(view), alpha); _controller->render(fovDiagonal, aspect, glm::affineInverse(view), alpha);
} }

View file

@ -18,7 +18,7 @@ namespace starfield { class Controller; }
// //
class Stars { class Stars {
starfield::Controller* _ptrController; starfield::Controller* _controller;
public: public:

View file

@ -56,35 +56,35 @@ namespace starfield {
class Controller { class Controller {
InputVertices _seqInput; InputVertices _inputSequence;
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
mutex _mtxInput; mutex _inputMutex;
atomic<unsigned> _valTileResolution; atomic<unsigned> _tileResolution;
mutex _mtxLodState; mutex _lodStateMutex;
#else #else
unsigned _valTileResolution; unsigned _tileResolution;
#endif #endif
double _valLodFraction; double _lodFraction;
double _valLodLowWaterMark; double _lodLowWaterMark;
double _valLodHighWaterMark; double _lodHighWaterMark;
double _valLodOveralloc; double _lodOveralloc;
size_t _valLodNalloc; size_t _lodNalloc;
size_t _valLodNRender; size_t _lodNRender;
BrightnessLevels _seqLodBrightness; BrightnessLevels _lodBrightnessSequence;
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
atomic<BrightnessLevel> _valLodBrightness; atomic<BrightnessLevel> _lodBrightness;
BrightnessLevel _valLodAllocBrightness; BrightnessLevel _lodAllocBrightness;
atomic<Renderer*> _ptrRenderer; atomic<Renderer*> _renderer;
typedef lock_guard<mutex> lock; typedef lock_guard<mutex> lock;
#else #else
BrightnessLevel _valLodBrightness; BrightnessLevel _lodBrightness;
BrightnessLevel _valLodAllocBrightness; BrightnessLevel _lodAllocBrightness;
Renderer* _ptrRenderer; Renderer* _renderer;
#define lock #define lock
#define _(x) #define _(x)
@ -97,16 +97,16 @@ namespace starfield {
public: public:
Controller() : Controller() :
_valTileResolution(20), _tileResolution(20),
_valLodFraction(1.0), _lodFraction(1.0),
_valLodLowWaterMark(0.8), _lodLowWaterMark(0.8),
_valLodHighWaterMark(1.0), _lodHighWaterMark(1.0),
_valLodOveralloc(1.2), _lodOveralloc(1.2),
_valLodNalloc(0), _lodNalloc(0),
_valLodNRender(0), _lodNRender(0),
_valLodBrightness(0), _lodBrightness(0),
_valLodAllocBrightness(0), _lodAllocBrightness(0),
_ptrRenderer(0l) { _renderer(0l) {
} }
bool readInput(const char* url, const char* cacheFile, unsigned limit) bool readInput(const char* url, const char* cacheFile, unsigned limit)
@ -121,13 +121,13 @@ namespace starfield {
// input is read, now run the entire data pipeline on the new input // input is read, now run the entire data pipeline on the new input
{ lock _(_mtxInput); { lock _(_inputMutex);
_seqInput.swap(vertices); _inputSequence.swap(vertices);
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
unsigned k = _valTileResolution.load(memory_order_relaxed); unsigned k = _tileResolution.load(memory_order_relaxed);
#else #else
unsigned k = _valTileResolution; unsigned k = _tileResolution;
#endif #endif
size_t n, nRender; size_t n, nRender;
BrightnessLevel bMin, b; BrightnessLevel bMin, b;
@ -136,27 +136,27 @@ namespace starfield {
// we'll have to build a new LOD state for a new total N, // we'll have to build a new LOD state for a new total N,
// ideally keeping allocation size and number of vertices // ideally keeping allocation size and number of vertices
{ lock _(_mtxLodState); { lock _(_lodStateMutex);
size_t newLast = _seqInput.size() - 1; size_t newLast = _inputSequence.size() - 1;
// reciprocal change N_old/N_new tells us how to scale // reciprocal change N_old/N_new tells us how to scale
// the fractions // the fractions
rcpChange = min(1.0, double(vertices.size()) / _seqInput.size()); rcpChange = min(1.0, double(vertices.size()) / _inputSequence.size());
// initialization? use defaults / previously set values // initialization? use defaults / previously set values
if (rcpChange == 0.0) { if (rcpChange == 0.0) {
rcpChange = 1.0; rcpChange = 1.0;
nRender = toBufSize(_valLodFraction * newLast); nRender = toBufSize(_lodFraction * newLast);
n = min(newLast, toBufSize(_valLodOveralloc * nRender)); n = min(newLast, toBufSize(_lodOveralloc * nRender));
} else { } else {
// cannot allocate or render more than we have // cannot allocate or render more than we have
n = min(newLast, _valLodNalloc); n = min(newLast, _lodNalloc);
nRender = min(newLast, _valLodNRender); nRender = min(newLast, _lodNRender);
} }
// determine new minimum brightness levels // determine new minimum brightness levels
@ -178,26 +178,26 @@ namespace starfield {
} catch (...) { } catch (...) {
// rollback transaction and rethrow // rollback transaction and rethrow
vertices.swap(_seqInput); vertices.swap(_inputSequence);
throw; throw;
} }
// finally publish the new LOD state // finally publish the new LOD state
{ lock _(_mtxLodState); { lock _(_lodStateMutex);
_seqLodBrightness.swap(brightness); _lodBrightnessSequence.swap(brightness);
_valLodFraction *= rcpChange; _lodFraction *= rcpChange;
_valLodLowWaterMark *= rcpChange; _lodLowWaterMark *= rcpChange;
_valLodHighWaterMark *= rcpChange; _lodHighWaterMark *= rcpChange;
_valLodOveralloc *= rcpChange; _lodOveralloc *= rcpChange;
_valLodNalloc = n; _lodNalloc = n;
_valLodNRender = nRender; _lodNRender = nRender;
_valLodAllocBrightness = bMin; _lodAllocBrightness = bMin;
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
_valLodBrightness.store(b, memory_order_relaxed); _lodBrightness.store(b, memory_order_relaxed);
#else #else
_valLodBrightness = b; _lodBrightness = b;
#endif #endif
} }
} }
@ -214,24 +214,24 @@ namespace starfield {
// printLog("Stars.cpp: setResolution(%d)\n", k); // printLog("Stars.cpp: setResolution(%d)\n", k);
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
if (k != _valTileResolution.load(memory_order_relaxed)) if (k != _tileResolution.load(memory_order_relaxed))
#else #else
if (k != _valTileResolution) if (k != _tileResolution)
#endif #endif
{ lock _(_mtxInput); { lock _(_inputMutex);
unsigned n; unsigned n;
BrightnessLevel b, bMin; BrightnessLevel b, bMin;
{ lock _(_mtxLodState); { lock _(_lodStateMutex);
n = _valLodNalloc; n = _lodNalloc;
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
b = _valLodBrightness.load(memory_order_relaxed); b = _lodBrightness.load(memory_order_relaxed);
#else #else
b = _valLodBrightness; b = _lodBrightness;
#endif #endif
bMin = _valLodAllocBrightness; bMin = _lodAllocBrightness;
} }
this->retile(n, k, b, bMin); this->retile(n, k, b, bMin);
@ -249,14 +249,14 @@ namespace starfield {
Tiling tiling(k); Tiling tiling(k);
VertexOrder scanner(tiling); VertexOrder scanner(tiling);
radix2InplaceSort(_seqInput.begin(), _seqInput.end(), scanner); radix2InplaceSort(_inputSequence.begin(), _inputSequence.end(), scanner);
// printLog( // printLog(
// "Stars.cpp: recreateRenderer(%d, %d, %d, %d)\n", n, k, b, bMin); // "Stars.cpp: recreateRenderer(%d, %d, %d, %d)\n", n, k, b, bMin);
recreateRenderer(n, k, b, bMin); recreateRenderer(n, k, b, bMin);
_valTileResolution = k; _tileResolution = k;
} }
public: public:
@ -273,13 +273,13 @@ namespace starfield {
BrightnessLevel bMin, b; BrightnessLevel bMin, b;
double fraction, lwm, hwm; double fraction, lwm, hwm;
{ lock _(_mtxLodState); { lock _(_lodStateMutex);
// acuire a consistent copy of the current LOD state // acuire a consistent copy of the current LOD state
fraction = _valLodFraction; fraction = _lodFraction;
lwm = _valLodLowWaterMark; lwm = _lodLowWaterMark;
hwm = _valLodHighWaterMark; hwm = _lodHighWaterMark;
size_t last = _seqLodBrightness.size() - 1; size_t last = _lodBrightnessSequence.size() - 1;
// apply factor // apply factor
fraction = max(0.0, min(1.0, fraction * factor)); fraction = max(0.0, min(1.0, fraction * factor));
@ -288,23 +288,23 @@ namespace starfield {
// threshold // threshold
double oaFract = std::min(fraction * (1.0 + overalloc), 1.0); double oaFract = std::min(fraction * (1.0 + overalloc), 1.0);
n = toBufSize(oaFract * last); n = toBufSize(oaFract * last);
bMin = _seqLodBrightness[n]; bMin = _lodBrightnessSequence[n];
n = std::upper_bound( n = std::upper_bound(
_seqLodBrightness.begin() + n - 1, _lodBrightnessSequence.begin() + n - 1,
_seqLodBrightness.end(), _lodBrightnessSequence.end(),
bMin, GreaterBrightness() ) - _seqLodBrightness.begin(); bMin, GreaterBrightness() ) - _lodBrightnessSequence.begin();
// also determine number of vertices to render and brightness // also determine number of vertices to render and brightness
nRender = toBufSize(fraction * last); nRender = toBufSize(fraction * last);
// Note: nRender does not have to be accurate // Note: nRender does not have to be accurate
b = _seqLodBrightness[nRender]; b = _lodBrightnessSequence[nRender];
// this setting controls the renderer, also keep b as the // this setting controls the renderer, also keep b as the
// brightness becomes volatile as soon as the mutex is // brightness becomes volatile as soon as the mutex is
// released, so keep b // released, so keep b
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
_valLodBrightness.store(b, memory_order_relaxed); _lodBrightness.store(b, memory_order_relaxed);
#else #else
_valLodBrightness = b; _lodBrightness = b;
#endif #endif
// printLog("Stars.cpp: " // printLog("Stars.cpp: "
@ -313,34 +313,34 @@ namespace starfield {
// will not have to reallocate? set new fraction right away // will not have to reallocate? set new fraction right away
// (it is consistent with the rest of the state in this case) // (it is consistent with the rest of the state in this case)
if (fraction >= _valLodLowWaterMark if (fraction >= _lodLowWaterMark
&& fraction <= _valLodHighWaterMark) { && fraction <= _lodHighWaterMark) {
_valLodFraction = fraction; _lodFraction = fraction;
return fraction; return fraction;
} }
} }
// reallocate // reallocate
{ lock _(_mtxInput); { lock _(_inputMutex);
recreateRenderer(n, _valTileResolution, b, bMin); recreateRenderer(n, _tileResolution, b, bMin);
// printLog("Stars.cpp: LOD reallocation\n"); // printLog("Stars.cpp: LOD reallocation\n");
// publish new lod state // publish new lod state
{ lock _(_mtxLodState); { lock _(_lodStateMutex);
_valLodNalloc = n; _lodNalloc = n;
_valLodNRender = nRender; _lodNRender = nRender;
_valLodFraction = fraction; _lodFraction = fraction;
_valLodLowWaterMark = fraction * (1.0 - realloc); _lodLowWaterMark = fraction * (1.0 - realloc);
_valLodHighWaterMark = fraction * (1.0 + realloc); _lodHighWaterMark = fraction * (1.0 + realloc);
_valLodOveralloc = fraction * (1.0 + overalloc); _lodOveralloc = fraction * (1.0 + overalloc);
_valLodAllocBrightness = bMin; _lodAllocBrightness = bMin;
} }
} }
return fraction; return fraction;
@ -352,10 +352,10 @@ namespace starfield {
BrightnessLevel b, BrightnessLevel bMin) { BrightnessLevel b, BrightnessLevel bMin) {
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
delete _ptrRenderer.exchange(new Renderer(_seqInput, n, k, b, bMin) ); delete _renderer.exchange(new Renderer(_inputSequence, n, k, b, bMin) );
#else #else
delete _ptrRenderer; delete _renderer;
_ptrRenderer = new Renderer(_seqInput, n, k, b, bMin); _renderer = new Renderer(_inputSequence, n, k, b, bMin);
#endif #endif
} }
@ -365,17 +365,17 @@ namespace starfield {
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
// check out renderer // check out renderer
Renderer* renderer = _ptrRenderer.exchange(0l); Renderer* renderer = _renderer.exchange(0l);
#else #else
Renderer* renderer = _ptrRenderer; Renderer* renderer = _renderer;
#endif #endif
// have it render // have it render
if (renderer != 0l) { if (renderer != 0l) {
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
BrightnessLevel b = _valLodBrightness.load(memory_order_relaxed); BrightnessLevel b = _lodBrightness.load(memory_order_relaxed);
#else #else
BrightnessLevel b = _valLodBrightness; BrightnessLevel b = _lodBrightness;
#endif #endif
renderer->render(perspective, angle, orientation, b, alpha); renderer->render(perspective, angle, orientation, b, alpha);
} }
@ -383,7 +383,7 @@ namespace starfield {
#if STARFIELD_MULTITHREADING #if STARFIELD_MULTITHREADING
// check in - or dispose if there is a new one // check in - or dispose if there is a new one
Renderer* newOne = 0l; Renderer* newOne = 0l;
if (! _ptrRenderer.compare_exchange_strong(newOne, renderer)) { if (! _renderer.compare_exchange_strong(newOne, renderer)) {
assert(!! newOne); assert(!! newOne);
delete renderer; delete renderer;

View file

@ -24,35 +24,35 @@ namespace starfield {
class Loader : UrlReader { class Loader : UrlReader {
InputVertices* _ptrVertices; InputVertices* _vertices;
unsigned _valLimit; unsigned _limit;
unsigned _valLineNo; unsigned _lineNo;
char const* _strUrl; char const* _urlStr;
unsigned _valRecordsRead; unsigned _recordsRead;
BrightnessLevel _valMinBrightness; BrightnessLevel _minBrightness;
public: public:
bool loadVertices( bool loadVertices(
InputVertices& destination, char const* url, char const* cacheFile, unsigned limit) InputVertices& destination, char const* url, char const* cacheFile, unsigned limit)
{ {
_ptrVertices = & destination; _vertices = & destination;
_valLimit = limit; _limit = limit;
#if STARFIELD_SAVE_MEMORY #if STARFIELD_SAVE_MEMORY
if (_valLimit == 0 || _valLimit > 60000u) if (_limit == 0 || _limit > 60000u)
_valLimit = 60000u; _limit = 60000u;
#endif #endif
_strUrl = url; // in case we fail early _urlStr = url; // in case we fail early
if (! UrlReader::readUrl(url, *this, cacheFile)) if (! UrlReader::readUrl(url, *this, cacheFile))
{ {
printLog("%s:%d: %s\n", printLog("%s:%d: %s\n",
_strUrl, _valLineNo, getError()); _urlStr, _lineNo, getError());
return false; return false;
} }
printLog("Loaded %u stars.\n", _valRecordsRead); printLog("Loaded %u stars.\n", _recordsRead);
return true; return true;
} }
@ -66,13 +66,13 @@ namespace starfield {
int64_t size, int64_t size,
int64_t stardate) { int64_t stardate) {
_valLineNo = 0u; _lineNo = 0u;
_strUrl = url; // new value in http redirect _urlStr = url; // new value in http redirect
_valRecordsRead = 0u; _recordsRead = 0u;
_ptrVertices->clear(); _vertices->clear();
_ptrVertices->reserve(_valLimit); _vertices->reserve(_limit);
// printLog("Stars.cpp: loader begin %s\n", url); // printLog("Stars.cpp: loader begin %s\n", url);
} }
@ -88,7 +88,7 @@ namespace starfield {
for (; next != end && isspace(*next); ++next); for (; next != end && isspace(*next); ++next);
consumed = next - input; consumed = next - input;
line = next; line = next;
++_valLineNo; ++_lineNo;
for (; next != end && *next != '\n' && *next != '\r'; ++next); for (; next != end && *next != '\n' && *next != '\r'; ++next);
if (next == end) if (next == end)
return consumed; return consumed;
@ -109,12 +109,12 @@ namespace starfield {
storeVertex(azi, alt, c); storeVertex(azi, alt, c);
} }
++_valRecordsRead; ++_recordsRead;
} else { } else {
printLog("Stars.cpp:%d: Bad input from %s\n", printLog("Stars.cpp:%d: Bad input from %s\n",
_valLineNo, _strUrl); _lineNo, _urlStr);
} }
} }
@ -126,7 +126,7 @@ namespace starfield {
private: private:
bool atLimit() { return _valLimit > 0u && _valRecordsRead >= _valLimit; } bool atLimit() { return _limit > 0u && _recordsRead >= _limit; }
bool spaceFor(BrightnessLevel b) { bool spaceFor(BrightnessLevel b) {
@ -136,42 +136,42 @@ namespace starfield {
// just reached the limit? -> establish a minimum heap and // just reached the limit? -> establish a minimum heap and
// remember the brightness at its top // remember the brightness at its top
if (_valRecordsRead == _valLimit) { if (_recordsRead == _limit) {
// printLog("Stars.cpp: vertex limit reached -> heap mode\n"); // printLog("Stars.cpp: vertex limit reached -> heap mode\n");
make_heap( make_heap(
_ptrVertices->begin(), _ptrVertices->end(), _vertices->begin(), _vertices->end(),
GreaterBrightness() ); GreaterBrightness() );
_valMinBrightness = getBrightness( _minBrightness = getBrightness(
_ptrVertices->begin()->getColor() ); _vertices->begin()->getColor() );
} }
// not interested? say so // not interested? say so
if (_valMinBrightness >= b) if (_minBrightness >= b)
return false; return false;
// otherwise free up space for the new vertex // otherwise free up space for the new vertex
pop_heap( pop_heap(
_ptrVertices->begin(), _ptrVertices->end(), _vertices->begin(), _vertices->end(),
GreaterBrightness() ); GreaterBrightness() );
_ptrVertices->pop_back(); _vertices->pop_back();
return true; return true;
} }
void storeVertex(float azi, float alt, unsigned color) { void storeVertex(float azi, float alt, unsigned color) {
_ptrVertices->push_back(InputVertex(azi, alt, color)); _vertices->push_back(InputVertex(azi, alt, color));
if (atLimit()) { if (atLimit()) {
push_heap( push_heap(
_ptrVertices->begin(), _ptrVertices->end(), _vertices->begin(), _vertices->end(),
GreaterBrightness() ); GreaterBrightness() );
_valMinBrightness = getBrightness( _minBrightness = getBrightness(
_ptrVertices->begin()->getColor() ); _vertices->begin()->getColor() );
} }
} }
}; };

View file

@ -19,7 +19,7 @@ namespace starfield {
class GpuVertex { class GpuVertex {
unsigned _valColor; unsigned _color;
float _valX; float _valX;
float _valY; float _valY;
float _valZ; float _valZ;
@ -29,7 +29,7 @@ namespace starfield {
GpuVertex(InputVertex const& in) { GpuVertex(InputVertex const& in) {
_valColor = in.getColor(); _color = in.getColor();
float azi = in.getAzimuth(); float azi = in.getAzimuth();
float alt = in.getAltitude(); float alt = in.getAltitude();
@ -44,7 +44,7 @@ namespace starfield {
_valZ = gz * exz; _valZ = gz * exz;
} }
unsigned getColor() const { return _valColor; } unsigned getColor() const { return _color; }
}; };
} // anonymous namespace } // anonymous namespace

View file

@ -19,14 +19,14 @@ namespace starfield {
class InputVertex { class InputVertex {
unsigned _valColor; unsigned _color;
float _valAzimuth; float _azimuth;
float _valAltitude; float _altitude;
public: public:
InputVertex(float azimuth, float altitude, unsigned color) { InputVertex(float azimuth, float altitude, unsigned color) {
_valColor = ((color >> 16) & 0xffu) | (color & 0xff00u) | _color = ((color >> 16) & 0xffu) | (color & 0xff00u) |
((color << 16) & 0xff0000u) | 0xff000000u; ((color << 16) & 0xff0000u) | 0xff000000u;
azimuth = angleConvert<Degrees,Radians>(azimuth); azimuth = angleConvert<Degrees,Radians>(azimuth);
@ -34,13 +34,13 @@ namespace starfield {
angleHorizontalPolar<Radians>(azimuth, altitude); angleHorizontalPolar<Radians>(azimuth, altitude);
_valAzimuth = azimuth; _azimuth = azimuth;
_valAltitude = altitude; _altitude = altitude;
} }
float getAzimuth() const { return _valAzimuth; } float getAzimuth() const { return _azimuth; }
float getAltitude() const { return _valAltitude; } float getAltitude() const { return _altitude; }
unsigned getColor() const { return _valColor; } unsigned getColor() const { return _color; }
}; };
typedef std::vector<InputVertex> InputVertices; typedef std::vector<InputVertex> InputVertices;

View file

@ -65,20 +65,20 @@ namespace starfield {
class Renderer { class Renderer {
GpuVertex* _arrData; GpuVertex* _dataArray;
Tile* _arrTile; Tile* _tileArray;
GLint* _arrBatchOffs; GLint* _batchOffs;
GLsizei* _arrBatchCount; GLsizei* _batchCountArray;
GLuint _hndVertexArray; GLuint _vertexArrayHandle;
ProgramObject _objProgram; ProgramObject _program;
int _alphaLocationHandle; int _alphaLocationHandle;
Tiling _objTiling; Tiling _tiling;
unsigned* _itrOutIndex; unsigned* _outIndexPos;
vec3 _vecWRow; vec3 _wRowVec;
float _valHalfPerspectiveAngle; float _halfPerspectiveAngle;
BrightnessLevel _valMinBright; BrightnessLevel _minBright;
public: public:
@ -88,9 +88,9 @@ namespace starfield {
BrightnessLevel b, BrightnessLevel b,
BrightnessLevel bMin) : BrightnessLevel bMin) :
_arrData(0l), _dataArray(0l),
_arrTile(0l), _tileArray(0l),
_objTiling(k) { _tiling(k) {
this->glAlloc(); this->glAlloc();
@ -101,10 +101,10 @@ namespace starfield {
// REVISIT: batch arrays are probably oversized, but - hey - they // REVISIT: batch arrays are probably oversized, but - hey - they
// are not very large (unless for insane tiling) and we're better // are not very large (unless for insane tiling) and we're better
// off safe than sorry // off safe than sorry
_arrData = new GpuVertex[n]; _dataArray = new GpuVertex[n];
_arrTile = new Tile[nTiles + 1]; _tileArray = new Tile[nTiles + 1];
_arrBatchOffs = new GLint[nTiles * 2]; _batchOffs = new GLint[nTiles * 2];
_arrBatchCount = new GLsizei[nTiles * 2]; _batchCountArray = new GLsizei[nTiles * 2];
prepareVertexData(src, n, tiling, b, bMin); prepareVertexData(src, n, tiling, b, bMin);
@ -113,10 +113,10 @@ namespace starfield {
~Renderer() { ~Renderer() {
delete[] _arrData; delete[] _dataArray;
delete[] _arrTile; delete[] _tileArray;
delete[] _arrBatchCount; delete[] _batchCountArray;
delete[] _arrBatchOffs; delete[] _batchOffs;
this->glFree(); this->glFree();
} }
@ -172,23 +172,23 @@ namespace starfield {
matrix = glm::frustum(-hw,hw, -hh,hh, nearClip,10.0f) * glm::affineInverse(matrix); matrix = glm::frustum(-hw,hw, -hh,hh, nearClip,10.0f) * glm::affineInverse(matrix);
this->_itrOutIndex = (unsigned*) _arrBatchOffs; this->_outIndexPos = (unsigned*) _batchOffs;
this->_vecWRow = vec3(row(matrix, 3)); this->_wRowVec = vec3(row(matrix, 3));
this->_valHalfPerspectiveAngle = halfPersp; this->_halfPerspectiveAngle = halfPersp;
this->_valMinBright = minBright; this->_minBright = minBright;
TileSelection::Cursor cursor; TileSelection::Cursor cursor;
cursor.current = _arrTile + _objTiling.getTileIndex(azimuth, altitude); cursor.current = _tileArray + _tiling.getTileIndex(azimuth, altitude);
cursor.firstInRow = _arrTile + _objTiling.getTileIndex(0.0f, altitude); cursor.firstInRow = _tileArray + _tiling.getTileIndex(0.0f, altitude);
floodFill(cursor, TileSelection(*this, _arrTile, _arrTile + _objTiling.getTileCount(), floodFill(cursor, TileSelection(*this, _tileArray, _tileArray + _tiling.getTileCount(),
(TileSelection::Cursor*) _arrBatchCount)); (TileSelection::Cursor*) _batchCountArray));
#if STARFIELD_DEBUG_CULLING #if STARFIELD_DEBUG_CULLING
# define matrix matrix_debug # define matrix matrix_debug
#endif #endif
this->glBatch(glm::value_ptr(matrix), prepareBatch( this->glBatch(glm::value_ptr(matrix), prepareBatch(
(unsigned*) _arrBatchOffs, _itrOutIndex), alpha); (unsigned*) _batchOffs, _outIndexPos), alpha);
#if STARFIELD_DEBUG_CULLING #if STARFIELD_DEBUG_CULLING
# undef matrix # undef matrix
@ -206,9 +206,9 @@ namespace starfield {
size_t nTiles = tiling.getTileCount(); size_t nTiles = tiling.getTileCount();
size_t vertexIndex = 0u, currTileIndex = 0u, count_active = 0u; size_t vertexIndex = 0u, currTileIndex = 0u, count_active = 0u;
_arrTile[0].offset = 0u; _tileArray[0].offset = 0u;
_arrTile[0].lod = b; _tileArray[0].lod = b;
_arrTile[0].flags = 0u; _tileArray[0].flags = 0u;
for (InputVertices::const_iterator i = for (InputVertices::const_iterator i =
src.begin(), e = src.end(); i != e; ++i) { src.begin(), e = src.end(); i != e; ++i) {
@ -225,8 +225,8 @@ namespace starfield {
// moved on to another tile? -> flush // moved on to another tile? -> flush
if (tileIndex != currTileIndex) { if (tileIndex != currTileIndex) {
Tile* t = _arrTile + currTileIndex; Tile* t = _tileArray + currTileIndex;
Tile* tLast = _arrTile + tileIndex; Tile* tLast = _tileArray + tileIndex;
// set count of active vertices (upcoming lod) // set count of active vertices (upcoming lod)
t->count = count_active; t->count = count_active;
@ -251,14 +251,14 @@ namespace starfield {
// printLog("Stars.cpp: Vertex %d on tile #%d\n", vertexIndex, tileIndex); // printLog("Stars.cpp: Vertex %d on tile #%d\n", vertexIndex, tileIndex);
// write converted vertex // write converted vertex
_arrData[vertexIndex++] = *i; _dataArray[vertexIndex++] = *i;
} }
} }
assert(vertexIndex == n); assert(vertexIndex == n);
// flush last tile (see above) // flush last tile (see above)
Tile* t = _arrTile + currTileIndex; Tile* t = _tileArray + currTileIndex;
t->count = count_active; t->count = count_active;
for (Tile* e = _arrTile + nTiles + 1; ++t != e;) { for (Tile* e = _tileArray + nTiles + 1; ++t != e;) {
t->offset = vertexIndex, t->count = 0u, t->offset = vertexIndex, t->count = 0u,
t->lod = b, t->flags = 0; t->lod = b, t->flags = 0;
} }
@ -275,22 +275,22 @@ namespace starfield {
public: public:
struct Cursor { Tile* current, * firstInRow; }; struct Cursor { Tile* current, * firstInRow; };
private: private:
Renderer& _refRenderer; Renderer& _rendererRef;
Cursor* const _arrStack; Cursor* const _stackArray;
Cursor* _itrStack; Cursor* _stackPos;
Tile const* const _arrTile; Tile const* const _tileArray;
Tile const* const _ptrTilesEnd; Tile const* const _tilesEnd;
public: public:
TileSelection(Renderer& renderer, Tile const* tiles, TileSelection(Renderer& renderer, Tile const* tiles,
Tile const* tiles_end, Cursor* stack) : Tile const* tiles_end, Cursor* stack) :
_refRenderer(renderer), _rendererRef(renderer),
_arrStack(stack), _stackArray(stack),
_itrStack(stack), _stackPos(stack),
_arrTile(tiles), _tileArray(tiles),
_ptrTilesEnd(tiles_end) { _tilesEnd(tiles_end) {
} }
protected: protected:
@ -300,7 +300,7 @@ namespace starfield {
bool select(Cursor const& c) { bool select(Cursor const& c) {
Tile* t = c.current; Tile* t = c.current;
if (t < _arrTile || t >= _ptrTilesEnd || if (t < _tileArray || t >= _tilesEnd ||
!! (t->flags & Tile::checked)) { !! (t->flags & Tile::checked)) {
// out of bounds or been here already // out of bounds or been here already
@ -309,7 +309,7 @@ namespace starfield {
// will check now and never again // will check now and never again
t->flags |= Tile::checked; t->flags |= Tile::checked;
if (_refRenderer.visitTile(t)) { if (_rendererRef.visitTile(t)) {
// good one -> remember (for batching) and propagate // good one -> remember (for batching) and propagate
t->flags |= Tile::render; t->flags |= Tile::render;
@ -332,39 +332,39 @@ namespace starfield {
void right(Cursor& c) const { void right(Cursor& c) const {
c.current += 1; c.current += 1;
if (c.current == c.firstInRow + _refRenderer._objTiling.getAzimuthalTiles()) { if (c.current == c.firstInRow + _rendererRef._tiling.getAzimuthalTiles()) {
c.current = c.firstInRow; c.current = c.firstInRow;
} }
} }
void left(Cursor& c) const { void left(Cursor& c) const {
if (c.current == c.firstInRow) { if (c.current == c.firstInRow) {
c.current = c.firstInRow + _refRenderer._objTiling.getAzimuthalTiles(); c.current = c.firstInRow + _rendererRef._tiling.getAzimuthalTiles();
} }
c.current -= 1; c.current -= 1;
} }
void up(Cursor& c) const { void up(Cursor& c) const {
unsigned d = _refRenderer._objTiling.getAzimuthalTiles(); unsigned d = _rendererRef._tiling.getAzimuthalTiles();
c.current += d; c.current += d;
c.firstInRow += d; c.firstInRow += d;
} }
void down(Cursor& c) const { void down(Cursor& c) const {
unsigned d = _refRenderer._objTiling.getAzimuthalTiles(); unsigned d = _rendererRef._tiling.getAzimuthalTiles();
c.current -= d; c.current -= d;
c.firstInRow -= d; c.firstInRow -= d;
} }
void defer(Cursor const& t) { void defer(Cursor const& t) {
*_itrStack++ = t; *_stackPos++ = t;
} }
bool deferred(Cursor& cursor) { bool deferred(Cursor& cursor) {
if (_itrStack != _arrStack) { if (_stackPos != _stackArray) {
cursor = *--_itrStack; cursor = *--_stackPos;
return true; return true;
} }
return false; return false;
@ -373,35 +373,35 @@ namespace starfield {
bool visitTile(Tile* t) { bool visitTile(Tile* t) {
unsigned index = t - _arrTile; unsigned index = t - _tileArray;
*_itrOutIndex++ = index; *_outIndexPos++ = index;
if (! tileVisible(t, index)) { if (! tileVisible(t, index)) {
return false; return false;
} }
if (t->lod != _valMinBright) { if (t->lod != _minBright) {
updateVertexCount(t, _valMinBright); updateVertexCount(t, _minBright);
} }
return true; return true;
} }
bool tileVisible(Tile* t, unsigned i) { bool tileVisible(Tile* t, unsigned i) {
float slice = _objTiling.getSliceAngle(); float slice = _tiling.getSliceAngle();
float halfSlice = 0.5f * slice; float halfSlice = 0.5f * slice;
unsigned stride = _objTiling.getAzimuthalTiles(); unsigned stride = _tiling.getAzimuthalTiles();
float azimuth = (i % stride) * slice; float azimuth = (i % stride) * slice;
float altitude = (i / stride) * slice - Radians::halfPi(); float altitude = (i / stride) * slice - Radians::halfPi();
float gx = sin(azimuth); float gx = sin(azimuth);
float gz = -cos(azimuth); float gz = -cos(azimuth);
float exz = cos(altitude); float exz = cos(altitude);
vec3 tileCenter = vec3(gx * exz, sin(altitude), gz * exz); vec3 tileCenter = vec3(gx * exz, sin(altitude), gz * exz);
float w = dot(_vecWRow, tileCenter); float w = dot(_wRowVec, tileCenter);
float daz = halfSlice * cos(std::max(0.0f, abs(altitude) - halfSlice)); float daz = halfSlice * cos(std::max(0.0f, abs(altitude) - halfSlice));
float dal = halfSlice; float dal = halfSlice;
float adjustedNear = cos(_valHalfPerspectiveAngle + sqrt(daz * daz + dal * dal)); float adjustedNear = cos(_halfPerspectiveAngle + sqrt(daz * daz + dal * dal));
// printLog("Stars.cpp: checking tile #%d, w = %f, near = %f\n", i, w, nearClip); // printLog("Stars.cpp: checking tile #%d, w = %f, near = %f\n", i, w, nearClip);
@ -415,8 +415,8 @@ namespace starfield {
// perform a binary search in the so found partition for the // perform a binary search in the so found partition for the
// new vertex count of this tile // new vertex count of this tile
GpuVertex const* start = _arrData + t[0].offset; GpuVertex const* start = _dataArray + t[0].offset;
GpuVertex const* end = _arrData + t[1].offset; GpuVertex const* end = _dataArray + t[1].offset;
assert(end >= start); assert(end >= start);
@ -431,9 +431,9 @@ namespace starfield {
end = std::upper_bound( end = std::upper_bound(
start, end, minBright, GreaterBrightness()); start, end, minBright, GreaterBrightness());
assert(end >= _arrData + t[0].offset); assert(end >= _dataArray + t[0].offset);
t->count = end - _arrData - t[0].offset; t->count = end - _dataArray - t[0].offset;
t->lod = minBright; t->lod = minBright;
} }
@ -441,13 +441,13 @@ namespace starfield {
unsigned const* indicesEnd) { unsigned const* indicesEnd) {
unsigned nRanges = 0u; unsigned nRanges = 0u;
GLint* offs = _arrBatchOffs; GLint* offs = _batchOffs;
GLsizei* count = _arrBatchCount; GLsizei* count = _batchCountArray;
for (unsigned* i = (unsigned*) _arrBatchOffs; for (unsigned* i = (unsigned*) _batchOffs;
i != indicesEnd; ++i) { i != indicesEnd; ++i) {
Tile* t = _arrTile + *i; Tile* t = _tileArray + *i;
if ((t->flags & Tile::render) > 0u && t->count > 0u) { if ((t->flags & Tile::render) > 0u && t->count > 0u) {
*offs++ = t->offset; *offs++ = t->offset;
@ -476,28 +476,28 @@ namespace starfield {
" gl_PointSize = s;\n" " gl_PointSize = s;\n"
"}\n"; "}\n";
_objProgram.addShaderFromSourceCode(QGLShader::Vertex, VERTEX_SHADER); _program.addShaderFromSourceCode(QGLShader::Vertex, VERTEX_SHADER);
GLchar const* const FRAGMENT_SHADER = GLchar const* const FRAGMENT_SHADER =
"#version 120\n" "#version 120\n"
"void main(void) {\n" "void main(void) {\n"
" gl_FragColor = gl_Color;\n" " gl_FragColor = gl_Color;\n"
"}\n"; "}\n";
_objProgram.addShaderFromSourceCode(QGLShader::Fragment, FRAGMENT_SHADER); _program.addShaderFromSourceCode(QGLShader::Fragment, FRAGMENT_SHADER);
_objProgram.link(); _program.link();
_alphaLocationHandle = _objProgram.uniformLocation("alpha"); _alphaLocationHandle = _program.uniformLocation("alpha");
glGenBuffersARB(1, & _hndVertexArray); glGenBuffersARB(1, & _vertexArrayHandle);
} }
void glFree() { void glFree() {
glDeleteBuffersARB(1, & _hndVertexArray); glDeleteBuffersARB(1, & _vertexArrayHandle);
} }
void glUpload(GLsizei n) { void glUpload(GLsizei n) {
glBindBufferARB(GL_ARRAY_BUFFER, _hndVertexArray); glBindBufferARB(GL_ARRAY_BUFFER, _vertexArrayHandle);
glBufferData(GL_ARRAY_BUFFER, glBufferData(GL_ARRAY_BUFFER,
n * sizeof(GpuVertex), _arrData, GL_STATIC_DRAW); n * sizeof(GpuVertex), _dataArray, GL_STATIC_DRAW);
//glInterleavedArrays(GL_C4UB_V3F, sizeof(GpuVertex), 0l); //glInterleavedArrays(GL_C4UB_V3F, sizeof(GpuVertex), 0l);
glBindBufferARB(GL_ARRAY_BUFFER, 0); glBindBufferARB(GL_ARRAY_BUFFER, 0);
@ -509,7 +509,7 @@ namespace starfield {
// for (int i = 0; i < n_ranges; ++i) // for (int i = 0; i < n_ranges; ++i)
// printLog("Stars.cpp: Batch #%d - %d stars @ %d\n", i, // printLog("Stars.cpp: Batch #%d - %d stars @ %d\n", i,
// _arrBatchOffs[i], _arrBatchCount[i]); // _batchOffs[i], _batchCountArray[i]);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
@ -531,18 +531,18 @@ namespace starfield {
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
// select shader and vertex array // select shader and vertex array
_objProgram.bind(); _program.bind();
_objProgram.setUniformValue(_alphaLocationHandle, alpha); _program.setUniformValue(_alphaLocationHandle, alpha);
glBindBufferARB(GL_ARRAY_BUFFER, _hndVertexArray); glBindBufferARB(GL_ARRAY_BUFFER, _vertexArrayHandle);
glInterleavedArrays(GL_C4UB_V3F, sizeof(GpuVertex), 0l); glInterleavedArrays(GL_C4UB_V3F, sizeof(GpuVertex), 0l);
// render // render
glMultiDrawArrays(GL_POINTS, glMultiDrawArrays(GL_POINTS,
_arrBatchOffs, _arrBatchCount, n_ranges); _batchOffs, _batchCountArray, n_ranges);
// restore state // restore state
glBindBufferARB(GL_ARRAY_BUFFER, 0); glBindBufferARB(GL_ARRAY_BUFFER, 0);
_objProgram.release(); _program.release();
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDisable(GL_POINT_SMOOTH); glDisable(GL_POINT_SMOOTH);
glPopMatrix(); glPopMatrix();

View file

@ -20,20 +20,20 @@ namespace starfield {
class Tiling { class Tiling {
unsigned _valK; unsigned _valK;
float _valRcpSlice; float _rcpSlice;
unsigned _valNBits; unsigned _nBits;
public: public:
Tiling(unsigned k) : Tiling(unsigned k) :
_valK(k), _valK(k),
_valRcpSlice(k / Radians::twicePi()) { _rcpSlice(k / Radians::twicePi()) {
_valNBits = ceil(log(getTileCount()) * 1.4426950408889634); // log2 _nBits = ceil(log(getTileCount()) * 1.4426950408889634); // log2
} }
unsigned getAzimuthalTiles() const { return _valK; } unsigned getAzimuthalTiles() const { return _valK; }
unsigned getAltitudinalTiles() const { return _valK / 2 + 1; } unsigned getAltitudinalTiles() const { return _valK / 2 + 1; }
unsigned getTileIndexBits() const { return _valNBits; } unsigned getTileIndexBits() const { return _nBits; }
unsigned getTileCount() const { unsigned getTileCount() const {
return getAzimuthalTiles() * getAltitudinalTiles(); return getAzimuthalTiles() * getAltitudinalTiles();
@ -45,14 +45,14 @@ namespace starfield {
} }
float getSliceAngle() const { float getSliceAngle() const {
return 1.0f / _valRcpSlice; return 1.0f / _rcpSlice;
} }
private: private:
unsigned discreteAngle(float unsigned_angle) const { unsigned discreteAngle(float unsigned_angle) const {
return unsigned(floor(unsigned_angle * _valRcpSlice + 0.5f)); return unsigned(floor(unsigned_angle * _rcpSlice + 0.5f));
} }
unsigned discreteAzimuth(float a) const { unsigned discreteAzimuth(float a) const {

View file

@ -25,7 +25,7 @@ namespace starfield {
*/ */
class VertexOrder : public Radix2IntegerScanner<unsigned> class VertexOrder : public Radix2IntegerScanner<unsigned>
{ {
Tiling _objTiling; Tiling _tiling;
typedef Radix2IntegerScanner<unsigned> base; typedef Radix2IntegerScanner<unsigned> base;
public: public:
@ -33,14 +33,14 @@ namespace starfield {
explicit VertexOrder(Tiling const& tiling) : explicit VertexOrder(Tiling const& tiling) :
base(tiling.getTileIndexBits() + BrightnessBits), base(tiling.getTileIndexBits() + BrightnessBits),
_objTiling(tiling) { _tiling(tiling) {
} }
bool bit(InputVertex const& v, state_type const& s) const { bool bit(InputVertex const& v, state_type const& s) const {
// inspect (tile_index, brightness) tuples // inspect (tile_index, brightness) tuples
unsigned key = getBrightness(v.getColor()) ^ BrightnessMask; unsigned key = getBrightness(v.getColor()) ^ BrightnessMask;
key |= _objTiling.getTileIndex( key |= _tiling.getTileIndex(
v.getAzimuth(), v.getAltitude()) << BrightnessBits; v.getAzimuth(), v.getAltitude()) << BrightnessBits;
return base::bit(key, s); return base::bit(key, s);
} }