move to vertex array objects

This commit is contained in:
Konstantin Käfer
2014-02-05 18:06:16 +01:00
parent 0a053d944a
commit e30d8eb48f
25 changed files with 294 additions and 147 deletions

View File

@@ -1,6 +1,7 @@
#include <cassert>
#include <algorithm>
#include <llmr/util/std.hpp>
#include <llmr/renderer/painter.hpp>
#include <llmr/renderer/shader-plain.hpp>
@@ -76,7 +77,7 @@ void Painter::changeMatrix(const Tile::ID& id) {
}
void Painter::drawClippingMask() {
switchShader(plainShader);
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
glColorMask(false, false, false, false);
@@ -96,9 +97,13 @@ void Painter::drawClippingMask() {
glStencilMask(0xC0);
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
if (!tileStencilArray) {
tileStencilArray.setup(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
} else {
tileStencilArray.bind();
}
// Draw the clipping mask
tileStencilBuffer.bind();
glVertexAttribPointer(plainShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
glUniform4f(plainShader->u_color, 1.0f, 0.0f, 1.0f, 1.0f);
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
@@ -197,11 +202,11 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
glColorMask(false, false, false, false);
// Draw the actual triangle fan into the stencil buffer.
switchShader(fillShader);
glUseProgram(fillShader->program);
glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data());
// Draw all groups
bucket.drawElements(fillShader->a_pos);
bucket.drawElements(*fillShader);
// Now that we have the stencil mask in the stencil buffer, we can start
// writing to the color buffer.
@@ -215,7 +220,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
// Because we're drawing top-to-bottom, and we update the stencil mask
// below, we have to draw the outline first (!)
if (properties.antialias) {
switchShader(outlineShader);
glUseProgram(outlineShader->program);
glUniformMatrix4fv(outlineShader->u_matrix, 1, GL_FALSE, matrix.data());
glLineWidth(2);
@@ -238,49 +243,53 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
// Draw the entire line
glUniform2f(outlineShader->u_world, transform.fb_width, transform.fb_height);
glLineWidth(2.0f);
bucket.drawVertices(outlineShader->a_pos);
bucket.drawVertices(*outlineShader);
}
// Only draw regions that we marked
glStencilFunc(GL_NOTEQUAL, 0x0, 0x3F);
if (properties.image.size() && style.sprite) {
// Draw texture fill
ImagePosition imagePos = style.sprite->getPosition(properties.image, true);
// TODO:
// // Draw texture fill
// ImagePosition imagePos = style.sprite->getPosition(properties.image, true);
double factor = 8.0 / pow(2, transform.getIntegerZoom() - id.z);
double mix = fmod(transform.getZoom(), 1.0);
vec2<double> imageSize { imagePos.size.x * factor, imagePos.size.y * factor };
// double factor = 8.0 / pow(2, transform.getIntegerZoom() - id.z);
// double mix = fmod(transform.getZoom(), 1.0);
// vec2<double> imageSize { imagePos.size.x * factor, imagePos.size.y * factor };
vec2<double> offset {
fmod(id.x * 4096, imageSize.x),
fmod(id.y * 4096, imageSize.y)
};
// vec2<double> offset {
// fmod(id.x * 4096, imageSize.x),
// fmod(id.y * 4096, imageSize.y)
// };
switchShader(patternShader);
glUniformMatrix4fv(patternShader->u_matrix, 1, GL_FALSE, matrix.data());
glUniform2f(patternShader->u_pattern_size, imageSize.x, imageSize.y);
glUniform2f(patternShader->u_offset, offset.x, offset.y);
glUniform2f(patternShader->u_pattern_tl, imagePos.tl.x, imagePos.tl.y);
glUniform2f(patternShader->u_pattern_br, imagePos.br.x, imagePos.br.y);
glUniform4fv(patternShader->u_color, 1, fill_color.data());
glUniform1f(patternShader->u_mix, mix);
style.sprite->bind(true);
// switchShader(patternShader);
// glUniformMatrix4fv(patternShader->u_matrix, 1, GL_FALSE, matrix.data());
// glUniform2f(patternShader->u_pattern_size, imageSize.x, imageSize.y);
// glUniform2f(patternShader->u_offset, offset.x, offset.y);
// glUniform2f(patternShader->u_pattern_tl, imagePos.tl.x, imagePos.tl.y);
// glUniform2f(patternShader->u_pattern_br, imagePos.br.x, imagePos.br.y);
// glUniform4fv(patternShader->u_color, 1, fill_color.data());
// glUniform1f(patternShader->u_mix, mix);
// style.sprite->bind(true);
// Draw a rectangle that covers the entire viewport.
tileStencilBuffer.bind();
glVertexAttribPointer(patternShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
// // Draw a rectangle that covers the entire viewport.
// tileStencilBuffer.bind();
// glVertexAttribPointer(patternShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
// glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
} else {
// Draw filling rectangle.
switchShader(fillShader);
glUseProgram(fillShader->program);
glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data());
glUniform4fv(fillShader->u_color, 1, fill_color.data());
// Draw a rectangle that covers the entire viewport.
tileStencilBuffer.bind();
glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
if (!tileStencilArray) {
tileStencilArray.setup(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
} else {
tileStencilArray.bind();
}
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
}
@@ -324,42 +333,37 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
// glUniform1f(painter.linepatternShader.u_fade, painter.transform.z % 1.0);
} else {
switchShader(lineShader);
glUseProgram(lineShader->program);
glUniformMatrix4fv(lineShader->u_matrix, 1, GL_FALSE, matrix.data());
glUniformMatrix4fv(lineShader->u_exmatrix, 1, GL_FALSE, exMatrix.data());
// glUniform2fv(painter.lineShader.u_dasharray, properties.dasharray || [1, -1]);
glUniform2f(lineShader->u_dasharray, 1, -1);
}
// TODO: Move this to transform?
const double tilePixelRatio = transform.getScale() / (1 << transform.getIntegerZoom()) / 8;
// TODO: Move this to transform?
const double tilePixelRatio = transform.getScale() / (1 << transform.getIntegerZoom()) / 8;
glUniform2f(lineShader->u_linewidth, outset, inset);
glUniform1f(lineShader->u_ratio, tilePixelRatio);
glUniform1f(lineShader->u_gamma, transform.pixelRatio);
glUniform2f(lineShader->u_linewidth, outset, inset);
glUniform1f(lineShader->u_ratio, tilePixelRatio);
glUniform1f(lineShader->u_gamma, transform.pixelRatio);
// const Color& color = properties.color;
// if (!params.antialiasing) {
// color[3] = Infinity;
// glUniform4fv(lineShader->u_color, color);
// } else {
glUniform4fv(lineShader->u_color, 1, color.data());
// }
// const Color& color = properties.color;
// if (!params.antialiasing) {
// color[3] = Infinity;
// glUniform4fv(lineShader->u_color, color);
// } else {
glUniform4fv(lineShader->u_color, 1, color.data());
// }
glUniform1f(lineShader->u_point, 0);
glUniform1f(lineShader->u_point, 0);
bucket.bind(*lineShader);
bucket.drawLines();
bucket.bind();
char *vertex_index = bucket.vertexOffset();
glVertexAttribPointer(lineShader->a_pos, 2, GL_SHORT, false, 8, vertex_index);
glVertexAttribPointer(lineShader->a_extrude, 2, GL_BYTE, false, 8, vertex_index + 6);
glVertexAttribPointer(lineShader->a_linesofar, 1, GL_SHORT, false, 8, vertex_index + 4);
glDrawArrays(GL_TRIANGLE_STRIP, 0, bucket.size());
if (bucket.geometry.join == JoinType::Round) {
glUniform1f(lineShader->u_point, 1);
glDrawArrays(GL_POINTS, 0, bucket.size());
if (bucket.geometry.join == JoinType::Round) {
glUniform1f(lineShader->u_point, 1);
bucket.drawPoints();
}
}
// statistics
@@ -369,27 +373,31 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
void Painter::renderDebug(const Tile::Ptr& tile) {
// Blend to the front, not the back.
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
// draw tile outline
switchShader(plainShader);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
tileBorderBuffer.bind();
glVertexAttribPointer(plainShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
glUniform4f(plainShader->u_color, 1.0f, 1.0f, 1.0f, 1.0f);
if (!tileBorderArray) {
tileBorderArray.setup(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0));
} else {
tileBorderArray.bind();
}
glUniform4f(plainShader->u_color, 1.0f, 0.0f, 0.0f, 1.0f);
glLineWidth(4.0f);
glDrawArrays(GL_LINE_STRIP, 0, tileBorderBuffer.length());
// draw debug info
switchShader(plainShader);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
tile->debugFontBuffer->bind();
glVertexAttribPointer(plainShader->a_pos, 2, GL_SHORT, GL_FALSE, 0, BUFFER_OFFSET(0));
if (!tile->debugFontArray) {
tile->debugFontArray.setup(*plainShader, tile->debugFontBuffer, BUFFER_OFFSET(0));
} else {
tile->debugFontArray.bind();
}
glUniform4f(plainShader->u_color, 1.0f, 1.0f, 1.0f, 1.0f);
glLineWidth(4.0f);
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer->length());
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.length());
glUniform4f(plainShader->u_color, 0.0f, 0.0f, 0.0f, 1.0f);
glLineWidth(2.0f);
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer->length());
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.length());
// Revert blending mode to blend to the back.
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
@@ -398,30 +406,37 @@ void Painter::renderDebug(const Tile::Ptr& tile) {
void Painter::renderMatte() {
glDisable(GL_STENCIL_TEST);
switchShader(fillShader);
glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, nativeMatrix.data());
Color white = {{ 0.9, 0.9, 0.9, 1 }};
Color white = {{ 1, 1, 1, 1 }};
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, nativeMatrix.data());
if (!matteArray) {
matteArray.setup(*plainShader, matteBuffer, BUFFER_OFFSET(0));
} else {
matteArray.bind();
}
// Draw the clipping mask
matteBuffer.bind();
glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
glUniform4fv(fillShader->u_color, 1, white.data());
glUniform4fv(plainShader->u_color, 1, white.data());
glDrawArrays(GL_TRIANGLES, 0, matteBuffer.length());
glEnable(GL_STENCIL_TEST);
}
void Painter::renderBackground() {
switchShader(fillShader);
glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data());
Color white = {{ 1, 1, 1, 1 }};
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
// Draw the clipping mask
tileStencilBuffer.bind();
glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
glUniform4fv(fillShader->u_color, 1, white.data());
if (!tileStencilArray) {
tileStencilArray.setup(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
} else {
tileStencilArray.bind();
}
glUniform4fv(plainShader->u_color, 1, white.data());
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
}
@@ -431,6 +446,7 @@ void Painter::renderBackground() {
* @return boolean whether the shader was actually switched
*/
bool Painter::switchShader(std::shared_ptr<Shader> shader) {
assert(false);
if (currentShader != shader) {
glUseProgram(shader->program);