fix linejoin drawing on retina

This commit is contained in:
Konstantin Käfer
2014-04-10 11:49:43 -04:00
parent 524c8737e4
commit eb499e77c1
8 changed files with 64 additions and 49 deletions

View File

@@ -24,10 +24,10 @@ public:
~Map();
/* setup */
void setup(float pixelRatio = 1);
void setup();
void loadStyle(const uint8_t *const data, uint32_t bytes);
void loadSettings();
void resize(uint32_t width, uint32_t height, uint32_t fb_width, uint32_t fb_height);
void resize(uint16_t width, uint16_t height, uint16_t fb_width, uint16_t fb_height);
void toggleRaster();
/* callback */

View File

@@ -22,6 +22,8 @@ public:
void updateAnimations();
void cancelAnimations();
void resize(uint16_t width, uint16_t height, uint16_t fb_width, uint16_t fb_height);
// Relative changes
void moveBy(double dx, double dy, double duration = 0);
void scaleBy(double ds, double cx = -1, double cy = -1, double duration = 0);
@@ -55,22 +57,30 @@ public:
// Temporary
box mapCornersToBox(uint32_t z) const;
// More getters
inline uint16_t getWidth() const { return width; }
inline uint16_t getHeight() const { return height; }
inline uint16_t getFramebufferWidth() const { return fb_width; }
inline uint16_t getFramebufferHeight() const { return fb_height; }
inline float getPixelRatio() const { return pixelRatio; }
private:
void setScaleXY(double new_scale, double xn, double yn, double duration = 0);
double pixel_x() const;
double pixel_y() const;
public:
private:
// logical dimensions
uint32_t width = 0;
uint32_t height = 0;
uint16_t width = 0;
uint16_t height = 0;
// physical (framebuffer) dimensions
float fb_width = 0;
float fb_height = 0;
uint16_t fb_width = 0;
uint16_t fb_height = 0;
float pixelRatio = 1;
public:
bool rotating = false;
bool scaling = false;
bool panning = false;

View File

@@ -33,15 +33,16 @@ public:
class Sprite : public std::enable_shared_from_this<Sprite> {
public:
Sprite();
Sprite(float pixelRatio = 1);
void load(const std::string& base_url, float pixelRatio = 1);
void load(const std::string& base_url);
ImagePosition getPosition(const std::string& name, bool repeating = false);
operator bool() const;
public:
const float pixelRatio;
std::shared_ptr<Raster> raster;
private:

View File

@@ -50,10 +50,7 @@ class MBXMapView
{
settings.load();
map.setup([[UIScreen mainScreen] scale]);
CGRect frame = [[UIScreen mainScreen] bounds];
map.resize(frame.size.width, frame.size.height, frame.size.width, frame.size.height);
map.setup();
map.loadSettings();
}
@@ -128,9 +125,12 @@ class MBXMapView
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateRender:) name:MBXNeedsRenderNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateNetworkActivity:) name:MBXUpdateActivityNotification object:nil];
mapView = new MBXMapView();
GLKView *view = (GLKView *)self.view;
CGRect rect = [view frame];
mapView = new MBXMapView();
mapView->init();
mapView->map.resize(rect.size.width, rect.size.height, [view drawableWidth], [view drawableHeight]);
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

View File

@@ -25,15 +25,9 @@ Map::~Map() {
settings.sync();
}
void Map::setup(float pixelRatio) {
void Map::setup() {
painter.setup();
pixel_ratio = pixelRatio;
style.sprite = std::make_shared<Sprite>();
style.sprite->load(kSpriteURL, pixel_ratio);
style.loadJSON(resources::style, resources::style_size);
}
@@ -50,13 +44,15 @@ void Map::loadSettings() {
update();
}
void Map::resize(uint32_t width, uint32_t height, uint32_t fb_width, uint32_t fb_height) {
transform.width = width;
transform.height = height;
transform.fb_width = fb_width;
transform.fb_height = fb_height;
transform.pixelRatio = pixel_ratio;
void Map::resize(uint16_t width, uint16_t height, uint16_t fb_width, uint16_t fb_height) {
transform.resize(width, height, fb_width, fb_height);
painter.resize(fb_width, fb_height);
if (!style.sprite || style.sprite->pixelRatio) {
style.sprite = std::make_shared<Sprite>(transform.getPixelRatio());
style.sprite->load(kSpriteURL);
}
update();
}
@@ -177,8 +173,8 @@ void Map::setAngle(double angle, double x, double y, double duration) {
double dx = 0, dy = 0;
if (x >= 0 && y >= 0) {
dx = (transform.width / 2) - x;
dy = (transform.height / 2) - y;
dx = (transform.getWidth() / 2) - x;
dy = (transform.getWidth() / 2) - y;
transform.moveBy(dx, dy, duration);
}

View File

@@ -34,6 +34,14 @@ void Transform::cancelAnimations() {
animations.clear();
}
void Transform::resize(uint16_t w, uint16_t h, uint16_t fb_w, uint16_t fb_h) {
width = w;
height = h;
fb_width = fb_w;
fb_height = fb_h;
pixelRatio = (float)fb_w / (float)w;
}
void Transform::moveBy(double dx, double dy, double duration) {
double xn = x + cos(angle) * dx + sin(angle) * dy;
double yn = y + cos(angle) * dy + sin(-angle) * dx;

View File

@@ -101,7 +101,7 @@ void Painter::depthMask(bool value) {
void Painter::changeMatrix() {
// Initialize projection matrix
matrix::ortho(projMatrix, 0, transform.width, transform.height, 0, 0, 1);
matrix::ortho(projMatrix, 0, transform.getWidth(), transform.getHeight(), 0, 0, 1);
// The extrusion matrix.
matrix::identity(extrudeMatrix);
@@ -270,7 +270,10 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
outlineShader->setColor(stroke_color);
// Draw the entire line
outlineShader->setWorld({{ transform.fb_width, transform.fb_height }});
outlineShader->setWorld({{
static_cast<float>(transform.getFramebufferWidth()),
static_cast<float>(transform.getFramebufferHeight())
}});
glDepthRange(strata, 1.0f);
bucket.drawVertices(*outlineShader);
} else if (fringeline) {
@@ -350,10 +353,9 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
// Draw the entire line
outlineShader->setWorld({{
transform.fb_width,
transform.fb_height
}
});
static_cast<float>(transform.getFramebufferWidth()),
static_cast<float>(transform.getFramebufferHeight())
}});
glDepthRange(strata + strata_epsilon, 1.0f);
bucket.drawVertices(*outlineShader);
@@ -391,17 +393,17 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
linejoinShader->setMatrix(matrix);
linejoinShader->setColor(color);
linejoinShader->setWorld({{
transform.fb_width * 0.5f,
transform.fb_height * 0.5f
transform.getFramebufferWidth() * 0.5f,
transform.getFramebufferHeight() * 0.5f
}
});
linejoinShader->setLineWidth({{
((outset - 0.25f) * transform.pixelRatio),
((inset - 0.25f) * transform.pixelRatio)
((outset - 0.25f) * transform.getPixelRatio()),
((inset - 0.25f) * transform.getPixelRatio())
}
});
float pointSize = ceil(transform.pixelRatio * outset * 2.0);
float pointSize = ceil(transform.getPixelRatio() * outset * 2.0);
#if defined(GL_ES_VERSION_2_0)
linejoinShader->setSize(pointSize);
#else
@@ -467,7 +469,7 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co
pointShader->setMatrix(matrix);
pointShader->setImage(0);
pointShader->setColor(color);
const float pointSize = properties.size * 1.4142135623730951 * transform.pixelRatio;
const float pointSize = properties.size * 1.4142135623730951 * transform.getPixelRatio();
#if defined(GL_ES_VERSION_2_0)
pointShader->setSize(pointSize);
#else
@@ -513,7 +515,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
glyphAtlas.bind();
textShader->setTextureSize({{ static_cast<float>(glyphAtlas.width), static_cast<float>(glyphAtlas.height) }});
textShader->setGamma(2.5f / fontSize / transform.pixelRatio);
textShader->setGamma(2.5f / fontSize / transform.getPixelRatio());
// Convert the -pi..pi to an int8 range.
float angle = round((transform.getAngle() + rotate) / M_PI * 128);
@@ -595,16 +597,16 @@ void Painter::renderDebug(const TileData::Ptr& tile_data) {
// draw tile outline
tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0));
plainShader->setColor(1.0f, 0.0f, 0.0f, 1.0f);
lineWidth(4.0f * transform.pixelRatio);
lineWidth(4.0f * transform.getPixelRatio());
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index());
// draw debug info
tile_data->debugFontArray.bind(*plainShader, tile_data->debugFontBuffer, BUFFER_OFFSET(0));
plainShader->setColor(1.0f, 1.0f, 1.0f, 1.0f);
lineWidth(4.0f * transform.pixelRatio);
lineWidth(4.0f * transform.getPixelRatio());
glDrawArrays(GL_LINES, 0, (GLsizei)tile_data->debugFontBuffer.index());
plainShader->setColor(0.0f, 0.0f, 0.0f, 1.0f);
lineWidth(2.0f * transform.pixelRatio);
lineWidth(2.0f * transform.getPixelRatio());
glDrawArrays(GL_LINES, 0, (GLsizei)tile_data->debugFontBuffer.index());
glEnable(GL_DEPTH_TEST);

View File

@@ -20,11 +20,9 @@ ImagePosition::ImagePosition(const vec2<uint16_t>& size, vec2<float> tl, vec2<fl
tl(tl),
br(br) {}
Sprite::Sprite() {
raster = std::make_shared<Raster>();
}
Sprite::Sprite(float pixelRatio) : pixelRatio(pixelRatio), raster(std::make_shared<Raster>()) {}
void Sprite::load(const std::string& base_url, float pixelRatio) {
void Sprite::load(const std::string& base_url) {
std::shared_ptr<Sprite> sprite = shared_from_this();
auto complete = [sprite]() {