From 1e58f6fd40f1395b585d17cf52ee0d9f6f73cd33 Mon Sep 17 00:00:00 2001 From: tosh Date: Thu, 18 Apr 2013 20:02:24 +0200 Subject: [PATCH 1/3] fixes upside down aspect ratio --- interface/src/starfield/renderer/Renderer.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/starfield/renderer/Renderer.h b/interface/src/starfield/renderer/Renderer.h index a09226ed85..5148c5fa01 100644 --- a/interface/src/starfield/renderer/Renderer.h +++ b/interface/src/starfield/renderer/Renderer.h @@ -133,14 +133,14 @@ namespace starfield { // determine dimensions based on a sought screen diagonal // // ww + hh = dd - // a = h / w => h = wa - // ww + ww aa = dd - // ww = dd / (1 + aa) + // a = w / h => w = ha + // hh + hh aa = dd + // hh = dd / (1 + aa) float diag = 2.0f * std::sin(halfPersp); float nearClip = std::cos(halfPersp); - float hw = 0.5f * sqrt(diag * diag / (1.0f + aspect * aspect)); - float hh = hw * aspect; + float hh = 0.5f * sqrt(diag * diag / (1.0f + aspect * aspect)); + float hw = hh * aspect; // cancel all translation mat4 matrix = orientation; From 715534154e02ab5f7567f2bbef0b70a87ec5c577 Mon Sep 17 00:00:00 2001 From: tosh Date: Fri, 19 Apr 2013 02:46:34 +0200 Subject: [PATCH 2/3] numerous starfield fixes --- interface/src/Stars.cpp | 12 ++- interface/src/Stars.h | 80 +++++++-------- interface/src/main.cpp | 7 +- interface/src/starfield/renderer/Renderer.h | 105 ++++++++++++-------- interface/src/starfield/renderer/Tiling.h | 3 +- libraries/shared/src/FloodFill.h | 101 ++++++++----------- 6 files changed, 164 insertions(+), 144 deletions(-) diff --git a/interface/src/Stars.cpp b/interface/src/Stars.cpp index 97d68bc61d..a049269305 100644 --- a/interface/src/Stars.cpp +++ b/interface/src/Stars.cpp @@ -34,7 +34,17 @@ float Stars::changeLOD(float fraction, float overalloc, float realloc) { return float(_ptrController->changeLOD(fraction, overalloc, realloc)); } -void Stars::render(float fovDiagonal, float aspect, glm::mat4 const& view) { +void Stars::render(float fovY, float aspect, float nearZ) { + + // determine length of screen diagonal from quadrant height and aspect ratio + float quadrantHeight = nearZ * tan(angleConvert(fovY) * 0.5f); + float halfDiagonal = sqrt(quadrantHeight * quadrantHeight * (1.0f + aspect * aspect)); + + // determine fov angle in respect to the diagonal + float fovDiagonal = atan(halfDiagonal / nearZ) * 2.0f; + + // pull the modelview matrix off the GL stack + glm::mat4 view; glGetFloatv(GL_MODELVIEW_MATRIX, glm::value_ptr(view)); _ptrController->render(fovDiagonal, aspect, glm::affineInverse(view)); } diff --git a/interface/src/Stars.h b/interface/src/Stars.h index 92c7b0f806..caca215444 100644 --- a/interface/src/Stars.h +++ b/interface/src/Stars.h @@ -13,9 +13,9 @@ namespace starfield { class Controller; } -/** - * Starfield rendering component. - */ +// +// Starfield rendering component. +// class Stars { starfield::Controller* _ptrController; @@ -25,49 +25,49 @@ class Stars { Stars(); ~Stars(); - /** - * Reads input file from URL. Returns true upon success. - * - * The limit parameter allows to reduce the number of stars - * that are loaded, keeping the brightest ones. - */ + // + // Reads input file from URL. Returns true upon success. + // + // The limit parameter allows to reduce the number of stars + // that are loaded, keeping the brightest ones. + // bool readInput(const char* url, const char* cacheFile = 0l, unsigned limit = 200000); - /** - * Renders the starfield from a local viewer's perspective. - * The parameter specifies the field of view. - */ - void render(float fovDiagonal, float aspect, glm::mat4 const& view); + // + // Renders the starfield from a local viewer's perspective. + // The parameters specifiy the field of view. + // + void render(float fovY, float aspect, float nearZ); - /** - * Sets the resolution for FOV culling. - * - * The parameter determines the number of tiles in azimuthal - * and altitudinal directions. - * - * GPU resources are updated upon change in which case 'true' - * is returned. - */ + // + // Sets the resolution for FOV culling. + // + // The parameter determines the number of tiles in azimuthal + // and altitudinal directions. + // + // GPU resources are updated upon change in which case 'true' + // is returned. + // bool setResolution(unsigned k); - /** - * Allows to alter the number of stars to be rendered given a - * factor. The least brightest ones are omitted first. - * - * The further parameters determine when GPU resources should - * be reallocated. Its value is fractional in respect to the - * last number of stars 'n' that caused 'n * (1+overalloc)' to - * be allocated. When the next call to setLOD causes the total - * number of stars that could be rendered to drop below 'n * - * (1-realloc)' or rises above 'n * (1+realloc)' GPU resources - * are updated. Note that all parameters must be fractions, - * that is within the range [0;1] and that 'overalloc' must be - * greater than or equal to 'realloc'. - * - * The current level of detail is returned as a float in [0;1]. - */ + // + // Allows to alter the number of stars to be rendered given a + // factor. The least brightest ones are omitted first. + // + // The further parameters determine when GPU resources should + // be reallocated. Its value is fractional in respect to the + // last number of stars 'n' that caused 'n * (1+overalloc)' to + // be allocated. When the next call to setLOD causes the total + // number of stars that could be rendered to drop below 'n * + // (1-realloc)' or rises above 'n * (1+realloc)' GPU resources + // are updated. Note that all parameters must be fractions, + // that is within the range [0;1] and that 'overalloc' must be + // greater than or equal to 'realloc'. + // + // The current level of detail is returned as a float in [0;1]. + // float changeLOD(float factor, - float overalloc = 0.25, float realloc = 0.15); + float overalloc = 0.25, float realloc = 0.15); private: // don't copy/assign diff --git a/interface/src/main.cpp b/interface/src/main.cpp index c44aeea168..a413a0cedf 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -762,9 +762,10 @@ void display(void) if (::starsOn) { // should be the first rendering pass - w/o depth buffer / lighting - glm::mat4 view; - glGetFloatv(GL_MODELVIEW_MATRIX, glm::value_ptr(view)); - stars.render(angleConvert(whichCamera.getFieldOfView()), aspectRatio, view); + + // finally render the starfield + stars.render(whichCamera.getFieldOfView(), aspectRatio, whichCamera.getNearClip()); + } glEnable(GL_LIGHTING); diff --git a/interface/src/starfield/renderer/Renderer.h b/interface/src/starfield/renderer/Renderer.h index 5148c5fa01..c0ffff2ce2 100644 --- a/interface/src/starfield/renderer/Renderer.h +++ b/interface/src/starfield/renderer/Renderer.h @@ -130,16 +130,17 @@ namespace starfield { float halfPersp = perspective * 0.5f; - // determine dimensions based on a sought screen diagonal + // define diagonal and near distance + float halfDiag = std::sin(halfPersp); + float nearClip = std::cos(halfPersp); + + // determine half dimensions based on the screen diagonal // // ww + hh = dd // a = w / h => w = ha // hh + hh aa = dd // hh = dd / (1 + aa) - float diag = 2.0f * std::sin(halfPersp); - float nearClip = std::cos(halfPersp); - - float hh = 0.5f * sqrt(diag * diag / (1.0f + aspect * aspect)); + float hh = sqrt(halfDiag * halfDiag / (1.0f + aspect * aspect)); float hw = hh * aspect; // cancel all translation @@ -154,32 +155,34 @@ namespace starfield { float azimuth = atan2(ahead.x,-ahead.z) + Radians::pi(); float altitude = atan2(-ahead.y, hypotf(ahead.x, ahead.z)); angleHorizontalPolar(azimuth, altitude); + float const eps = 0.002f; + altitude = glm::clamp(altitude, + -Radians::halfPi() + eps, Radians::halfPi() - eps); #if STARFIELD_HEMISPHERE_ONLY altitude = std::max(0.0f, altitude); #endif - unsigned tileIndex = - _objTiling.getTileIndex(azimuth, altitude); - // fprintf(stderr, "Stars.cpp: starting on tile #%d\n", tileIndex); #if STARFIELD_DEBUG_CULLING - mat4 matrix_debug = glm::translate( - glm::frustum(-hw, hw, -hh, hh, nearClip, 10.0f), - vec3(0.0f, 0.0f, -4.0f)) * glm::affineInverse(matrix); + mat4 matrix_debug = glm::translate(glm::frustum(-hw, hw, -hh, hh, nearClip, 10.0f), + vec3(0.0f, 0.0f, -4.0f)) * + glm::affineInverse(matrix); #endif - 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->_vecWxform = vec3(row(matrix, 3)); this->_valHalfPersp = halfPersp; this->_valMinBright = minBright; - floodFill(_arrTile + tileIndex, TileSelection(*this, - _arrTile, _arrTile + _objTiling.getTileCount(), - (Tile**) _arrBatchCount)); + TileSelection::Cursor cursor; + cursor.current = _arrTile + _objTiling.getTileIndex(azimuth, altitude); + cursor.firstInRow = _arrTile + _objTiling.getTileIndex(0.0f, altitude); + + floodFill(cursor, TileSelection(*this, _arrTile, _arrTile + _objTiling.getTileCount(), + (TileSelection::Cursor*) _arrBatchCount)); #if STARFIELD_DEBUG_CULLING # define matrix matrix_debug @@ -269,31 +272,35 @@ namespace starfield { class TileSelection { + public: + struct Cursor { Tile* current, * firstInRow; }; + private: Renderer& _refRenderer; - Tile** const _arrStack; - Tile** _itrStack; + Cursor* const _arrStack; + Cursor* _itrStack; Tile const* const _arrTile; - Tile const* const _itrTilesEnd; + Tile const* const _ptrTilesEnd; public: TileSelection(Renderer& renderer, Tile const* tiles, - Tile const* tiles_end, Tile** stack) : + Tile const* tiles_end, Cursor* stack) : _refRenderer(renderer), _arrStack(stack), _itrStack(stack), _arrTile(tiles), - _itrTilesEnd(tiles_end) { + _ptrTilesEnd(tiles_end) { } protected: // flood fill strategy - bool select(Tile* t) { + bool select(Cursor const& c) { + Tile* t = c.current; - if (t < _arrTile || t >= _itrTilesEnd || + if (t < _arrTile || t >= _ptrTilesEnd || !! (t->flags & Tile::checked)) { // out of bounds or been here already @@ -311,7 +318,8 @@ namespace starfield { return false; } - bool process(Tile* t) { + bool process(Cursor const& c) { + Tile* t = c.current; if (! (t->flags & Tile::visited)) { @@ -321,14 +329,39 @@ namespace starfield { return false; } - void right(Tile*& cursor) const { cursor += 1; } - void left(Tile*& cursor) const { cursor -= 1; } - void up(Tile*& cursor) const { cursor += yStride(); } - void down(Tile*& cursor) const { cursor -= yStride(); } + void right(Cursor& c) const { - void defer(Tile* t) { *_itrStack++ = t; } + c.current += 1; + if (c.current == c.firstInRow + _refRenderer._objTiling.getAzimuthalTiles()) { + c.current = c.firstInRow; + } + } + void left(Cursor& c) const { + + if (c.current == c.firstInRow) { + c.current = c.firstInRow + _refRenderer._objTiling.getAzimuthalTiles(); + } + c.current -= 1; + } + void up(Cursor& c) const { - bool deferred(Tile*& cursor) { + unsigned d = _refRenderer._objTiling.getAzimuthalTiles(); + c.current += d; + c.firstInRow += d; + } + void down(Cursor& c) const { + + unsigned d = _refRenderer._objTiling.getAzimuthalTiles(); + c.current -= d; + c.firstInRow -= d; + } + + void defer(Cursor const& t) { + + *_itrStack++ = t; + } + + bool deferred(Cursor& cursor) { if (_itrStack != _arrStack) { cursor = *--_itrStack; @@ -336,12 +369,6 @@ namespace starfield { } return false; } - - private: - unsigned yStride() const { - - return _refRenderer._objTiling.getAzimuthalTiles(); - } }; bool visitTile(Tile* t) { @@ -362,6 +389,7 @@ namespace starfield { bool tileVisible(Tile* t, unsigned i) { float slice = _objTiling.getSliceAngle(); + float halfSlice = 0.5f * slice; unsigned stride = _objTiling.getAzimuthalTiles(); float azimuth = (i % stride) * slice; float altitude = (i / stride) * slice - Radians::halfPi(); @@ -371,14 +399,13 @@ namespace starfield { vec3 tileCenter = vec3(gx * exz, sin(altitude), gz * exz); float w = dot(_vecWxform, tileCenter); - float halfSlice = 0.5f * slice; - float daz = halfSlice * cos(abs(altitude) - halfSlice); + float daz = halfSlice * cos(std::max(0.0f, abs(altitude) - halfSlice)); float dal = halfSlice; float adjustedNear = cos(_valHalfPersp + sqrt(daz * daz + dal * dal)); // fprintf(stderr, "Stars.cpp: checking tile #%d, w = %f, near = %f\n", i, w, nearClip); - return w > adjustedNear; + return w >= adjustedNear; } void updateVertexCount(Tile* t, BrightnessLevel minBright) { diff --git a/interface/src/starfield/renderer/Tiling.h b/interface/src/starfield/renderer/Tiling.h index 1df4dd1956..56df23f30c 100644 --- a/interface/src/starfield/renderer/Tiling.h +++ b/interface/src/starfield/renderer/Tiling.h @@ -1,5 +1,5 @@ // -// starfield/renderer/ +// starfield/renderer/Tiling.h // interface // // Created by Tobias Schwinger on 3/22/13. @@ -51,6 +51,7 @@ namespace starfield { private: unsigned discreteAngle(float unsigned_angle) const { + return unsigned(floor(unsigned_angle * _valRcpSlice + 0.5f)); } diff --git a/libraries/shared/src/FloodFill.h b/libraries/shared/src/FloodFill.h index 273c1c4f6e..40a89bfd1b 100644 --- a/libraries/shared/src/FloodFill.h +++ b/libraries/shared/src/FloodFill.h @@ -9,32 +9,31 @@ #ifndef __hifi__FloodFill__ #define __hifi__FloodFill__ -/** - * Line scanning, iterative flood fill algorithm. - * - * The strategy must obey the following contract: - * - * There is an associated cursor that represents a position on the image. - * The member functions 'left(C&)', 'right(C&)', 'up(C&)', and 'down(C&)' - * move it. - * The state of a cursor can be deferred to temporary storage (typically a - * stack or a queue) using the 'defer(C const&)' member function. - * Calling 'deferred(C&)' restores a cursor's state from temporary storage - * and removes it there. - * The 'select(C const&)' and 'process(C const&)' functions control the - * algorithm. The former is called to determine where to go. It may be - * called multiple times but does not have to (and should not) return - * 'true' more than once for a pixel to be selected (will cause memory - * overuse, otherwise). The latter will never be called for a given pixel - * unless previously selected. It may be called multiple times, in which - * case it should return 'true' upon successful processing and 'false' - * when an already processed pixel has been visited. - * - * Note: The terms "image" and "pixel" are used for illustratory purposes - * and mean "undirected graph with 4-connected 2D grid topology" and "node", - * respectively. - * - */ +// +// Line scanning, iterative flood fill algorithm. +// +// The strategy must obey the following contract: +// +// There is an associated cursor that represents a position on the image. +// The member functions 'left(C&)', 'right(C&)', 'up(C&)', and 'down(C&)' +// move it. +// The state of a cursor can be deferred to temporary storage (typically a +// stack or a queue) using the 'defer(C const&)' member function. +// Calling 'deferred(C&)' restores a cursor's state from temporary storage +// and removes it there. +// The 'select(C const&)' and 'process(C const&)' functions control the +// algorithm. The former is called to determine where to go. It may be +// called multiple times but does not have to (and should not) return +// 'true' more than once for a pixel to be selected (will cause memory +// overuse, otherwise). The latter will never be called for a given pixel +// unless previously selected. It may be called multiple times, in which +// case it should return 'true' upon successful processing and 'false' +// when an already processed pixel has been visited. +// +// Note: The terms "image" and "pixel" are used for illustratory purposes +// and mean "undirected graph with 4-connected 2D grid topology" and "node", +// respectively. +// template< class Strategy, typename Cursor > void floodFill(Cursor const& position, Strategy const& strategy = Strategy()); @@ -63,57 +62,39 @@ struct floodFill_impl : Strategy { } Cursor higher, lower, h,l, i; - bool higherFound, lowerFound, hf, lf; do { if (! process(position)) { continue; } - higher = position; higherFound = false; - up(higher); yTest(higher, higherFound); - lower = position; lowerFound = false; - down(lower); yTest(lower, lowerFound); + higher = position; + up(higher); + if (select(higher)) { defer(higher); } + + lower = position; + down(lower); + if (select(lower)) { defer(lower); } i = position, h = higher, l = lower; - hf = higherFound, lf = lowerFound; do { - right(i), right(h), right(l); yTest(h,hf); yTest(l,lf); - } while (selectAndProcess(i)); + right(i), right(h), right(l); + if (select(h)) { defer(h); } + if (select(l)) { defer(l); } + + } while (select(i) && process(i)); i = position, h = higher, l = lower; - hf = higherFound, lf = lowerFound; do { - left(i); left(h); left(l); yTest(h,hf); yTest(l,lf); + left(i); left(h); left(l); + if (select(h)) { defer(h); } + if (select(l)) { defer(l); } - } while (selectAndProcess(i)); + } while (select(i) && process(i)); } while (deferred(position)); } - - bool selectAndProcess(Cursor const& i) { - - if (select(i)) { - - process(i); - return true; - } - return false; - } - - void yTest(Cursor const& i, bool& state) { - - if (! select(i)) { - - state = false; - - } else if (! state) { - - state = true; - defer(i); - } - } }; template< class Strategy, typename Cursor > From 0332b455cbe986e5fced4c847e50bca0c82cfada Mon Sep 17 00:00:00 2001 From: tosh Date: Wed, 24 Apr 2013 13:33:53 +0200 Subject: [PATCH 3/3] removes leftover something and misplaced const-qualification that keeps it from compiling --- injector/src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/injector/src/main.cpp b/injector/src/main.cpp index 61327ec41b..028de6cb04 100644 --- a/injector/src/main.cpp +++ b/injector/src/main.cpp @@ -42,7 +42,7 @@ void usage(void) std::cout << " -c FLOAT,FLOAT,FLOAT,FLOAT X,Y,Z,YAW position in universe where audio will be originating from and direction. Defaults to 0,0,0,0" << std::endl; std::cout << " -a 0-255 Attenuation curve modifier, defaults to 255" << std::endl; std::cout << " -f FILENAME Name of audio source file. Required - RAW format, 22050hz 16bit signed mono" << std::endl; -}; +} bool processParameters(int parameterCount, char* parameterData[]) { @@ -91,9 +91,9 @@ bool processParameters(int parameterCount, char* parameterData[]) } } return true; -};_Position +}; -int main(int argc, const char* argv[]) { +int main(int argc, char* argv[]) { srand(time(0)); int AUDIO_UDP_SEND_PORT = 1500 + (rand() % (int)(1500 - 2000 + 1));