Update Rectangle, Grid, and Billboard overlays to use batches

This commit is contained in:
Ryan Huffman 2015-06-16 16:44:33 -07:00
parent 8241a2170b
commit d47f5a2abb
3 changed files with 274 additions and 175 deletions

View file

@ -43,72 +43,88 @@ void BillboardOverlay::render(RenderArgs* args) {
return;
}
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
glm::quat rotation;
if (_isFacingAvatar) {
// rotate about vertical to face the camera
rotation = Application::getInstance()->getCamera()->getRotation();
rotation *= glm::angleAxis(glm::pi<float>(), glm::vec3(0.0f, 1.0f, 0.0f));
rotation *= getRotation();
} else {
rotation = getRotation();
}
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
float imageWidth = _texture->getWidth();
float imageHeight = _texture->getHeight();
glBindTexture(GL_TEXTURE_2D, _texture->getID());
QRect fromImage;
if (_fromImage.isNull()) {
fromImage.setX(0);
fromImage.setY(0);
fromImage.setWidth(imageWidth);
fromImage.setHeight(imageHeight);
} else {
float scaleX = imageWidth / _texture->getOriginalWidth();
float scaleY = imageHeight / _texture->getOriginalHeight();
glPushMatrix(); {
glTranslatef(_position.x, _position.y, _position.z);
glm::quat rotation;
if (_isFacingAvatar) {
// rotate about vertical to face the camera
rotation = Application::getInstance()->getCamera()->getRotation();
rotation *= glm::angleAxis(glm::pi<float>(), glm::vec3(0.0f, 1.0f, 0.0f));
rotation *= getRotation();
} else {
rotation = getRotation();
}
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glScalef(_scale, _scale, _scale);
fromImage.setX(scaleX * _fromImage.x());
fromImage.setY(scaleY * _fromImage.y());
fromImage.setWidth(scaleX * _fromImage.width());
fromImage.setHeight(scaleY * _fromImage.height());
}
const float MAX_COLOR = 255.0f;
xColor color = getColor();
float alpha = getAlpha();
float maxSize = glm::max(fromImage.width(), fromImage.height());
float x = fromImage.width() / (2.0f * maxSize);
float y = -fromImage.height() / (2.0f * maxSize);
float imageWidth = _texture->getWidth();
float imageHeight = _texture->getHeight();
glm::vec2 topLeft(-x, -y);
glm::vec2 bottomRight(x, y);
glm::vec2 texCoordTopLeft(fromImage.x() / imageWidth, fromImage.y() / imageHeight);
glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width()) / imageWidth,
(fromImage.y() + fromImage.height()) / imageHeight);
QRect fromImage;
if (_fromImage.isNull()) {
fromImage.setX(0);
fromImage.setY(0);
fromImage.setWidth(imageWidth);
fromImage.setHeight(imageHeight);
} else {
float scaleX = imageWidth / _texture->getOriginalWidth();
float scaleY = imageHeight / _texture->getOriginalHeight();
const float MAX_COLOR = 255.0f;
xColor color = getColor();
float alpha = getAlpha();
fromImage.setX(scaleX * _fromImage.x());
fromImage.setY(scaleY * _fromImage.y());
fromImage.setWidth(scaleX * _fromImage.width());
fromImage.setHeight(scaleY * _fromImage.height());
}
auto batch = args->_batch;
float maxSize = glm::max(fromImage.width(), fromImage.height());
float x = fromImage.width() / (2.0f * maxSize);
float y = -fromImage.height() / (2.0f * maxSize);
if (batch) {
Transform transform;
transform.setTranslation(_position);
transform.setRotation(rotation);
transform.setScale(_scale);
glm::vec2 topLeft(-x, -y);
glm::vec2 bottomRight(x, y);
glm::vec2 texCoordTopLeft(fromImage.x() / imageWidth, fromImage.y() / imageHeight);
glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width()) / imageWidth,
(fromImage.y() + fromImage.height()) / imageHeight);
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
batch->setModelTransform(transform);
batch->setUniformTexture(0, _texture->getGPUTexture());
DependencyManager::get<GeometryCache>()->renderQuad(*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha));
} else {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
} glPopMatrix();
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
glBindTexture(GL_TEXTURE_2D, _texture->getID());
glBindTexture(GL_TEXTURE_2D, 0);
glPushMatrix(); {
glTranslatef(_position.x, _position.y, _position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glScalef(_scale, _scale, _scale);
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha));
} glPopMatrix();
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
void BillboardOverlay::setProperties(const QScriptValue &properties) {

View file

@ -36,87 +36,128 @@ void Grid3DOverlay::render(RenderArgs* args) {
return; // do nothing if we're not visible
}
if (!_gridProgram.isLinked()) {
if (!_gridProgram.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/grid.vert")) {
qDebug() << "Failed to compile: " + _gridProgram.log();
return;
}
if (!_gridProgram.addShaderFromSourceFile(QGLShader::Fragment, PathUtils::resourcesPath() + "shaders/grid.frag")) {
qDebug() << "Failed to compile: " + _gridProgram.log();
return;
}
if (!_gridProgram.link()) {
qDebug() << "Failed to link: " + _gridProgram.log();
return;
}
}
// Render code largely taken from MetavoxelEditor::render()
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glPushMatrix();
glm::quat rotation = getRotation();
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glLineWidth(1.5f);
// center the grid around the camera position on the plane
glm::vec3 rotated = glm::inverse(rotation) * Application::getInstance()->getCamera()->getPosition();
float spacing = _minorGridWidth;
float alpha = getAlpha();
xColor color = getColor();
glm::vec3 position = getPosition();
const int MINOR_GRID_DIVISIONS = 200;
const int MAJOR_GRID_DIVISIONS = 100;
const float MAX_COLOR = 255.0f;
// center the grid around the camera position on the plane
glm::vec3 rotated = glm::inverse(_rotation) * Application::getInstance()->getCamera()->getPosition();
float spacing = _minorGridWidth;
float alpha = getAlpha();
xColor color = getColor();
glm::vec4 gridColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
_gridProgram.bind();
auto batch = args->_batch;
// Minor grid
glPushMatrix();
{
glTranslatef(_minorGridWidth * (floorf(rotated.x / spacing) - MINOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MINOR_GRID_DIVISIONS / 2), position.z);
if (batch) {
Transform transform;
transform.setRotation(_rotation);
float scale = MINOR_GRID_DIVISIONS * spacing;
glScalef(scale, scale, scale);
DependencyManager::get<GeometryCache>()->renderGrid(MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS, gridColor);
// Minor grid
{
batch->_glLineWidth(1.0f);
auto position = glm::vec3(_minorGridWidth * (floorf(rotated.x / spacing) - MINOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MINOR_GRID_DIVISIONS / 2),
_position.z);
float scale = MINOR_GRID_DIVISIONS * spacing;
transform.setTranslation(position);
transform.setScale(scale);
batch->setModelTransform(transform);
DependencyManager::get<GeometryCache>()->renderGrid(*batch, MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS, gridColor);
}
// Major grid
{
batch->_glLineWidth(4.0f);
spacing *= _majorGridEvery;
auto position = glm::vec3(spacing * (floorf(rotated.x / spacing) - MAJOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MAJOR_GRID_DIVISIONS / 2),
_position.z);
float scale = MAJOR_GRID_DIVISIONS * spacing;
transform.setTranslation(position);
transform.setScale(scale);
batch->setModelTransform(transform);
DependencyManager::get<GeometryCache>()->renderGrid(*batch, MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor);
}
} else {
if (!_gridProgram.isLinked()) {
if (!_gridProgram.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/grid.vert")) {
qDebug() << "Failed to compile: " + _gridProgram.log();
return;
}
if (!_gridProgram.addShaderFromSourceFile(QGLShader::Fragment, PathUtils::resourcesPath() + "shaders/grid.frag")) {
qDebug() << "Failed to compile: " + _gridProgram.log();
return;
}
if (!_gridProgram.link()) {
qDebug() << "Failed to link: " + _gridProgram.log();
return;
}
}
// Render code largely taken from MetavoxelEditor::render()
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glPushMatrix();
glm::quat rotation = getRotation();
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glLineWidth(1.5f);
glm::vec3 position = getPosition();
_gridProgram.bind();
// Minor grid
glPushMatrix();
{
glTranslatef(_minorGridWidth * (floorf(rotated.x / spacing) - MINOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MINOR_GRID_DIVISIONS / 2), position.z);
float scale = MINOR_GRID_DIVISIONS * spacing;
glScalef(scale, scale, scale);
DependencyManager::get<GeometryCache>()->renderGrid(MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS, gridColor);
}
glPopMatrix();
// Major grid
glPushMatrix();
{
glLineWidth(4.0f);
spacing *= _majorGridEvery;
glTranslatef(spacing * (floorf(rotated.x / spacing) - MAJOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MAJOR_GRID_DIVISIONS / 2), position.z);
float scale = MAJOR_GRID_DIVISIONS * spacing;
glScalef(scale, scale, scale);
DependencyManager::get<GeometryCache>()->renderGrid(MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor);
}
glPopMatrix();
_gridProgram.release();
glPopMatrix();
glEnable(GL_LIGHTING);
glDepthMask(GL_TRUE);
}
glPopMatrix();
// Major grid
glPushMatrix();
{
glLineWidth(4.0f);
spacing *= _majorGridEvery;
glTranslatef(spacing * (floorf(rotated.x / spacing) - MAJOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MAJOR_GRID_DIVISIONS / 2), position.z);
float scale = MAJOR_GRID_DIVISIONS * spacing;
glScalef(scale, scale, scale);
DependencyManager::get<GeometryCache>()->renderGrid(MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor);
}
glPopMatrix();
_gridProgram.release();
glPopMatrix();
glEnable(GL_LIGHTING);
glDepthMask(GL_TRUE);
}
void Grid3DOverlay::setProperties(const QScriptValue& properties) {

View file

@ -41,74 +41,116 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
const float MAX_COLOR = 255.0f;
glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glDisable(GL_LIGHTING);
glm::vec3 position = getPosition();
glm::vec3 center = getCenter();
glm::vec2 dimensions = getDimensions();
glm::vec2 halfDimensions = dimensions * 0.5f;
glm::quat rotation = getRotation();
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
auto batch = args->_batch;
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glPushMatrix();
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
//glScalef(dimensions.x, dimensions.y, 1.0f);
if (batch) {
Transform transform;
transform.setTranslation(position);
transform.setRotation(rotation);
glLineWidth(_lineWidth);
batch->setModelTransform(transform);
if (getIsSolid()) {
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f);
DependencyManager::get<GeometryCache>()->renderQuad(*batch, topLeft, bottomRight, rectangleColor);
} else {
auto geometryCache = DependencyManager::get<GeometryCache>();
if (getIsDashedLine()) {
glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f);
glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f);
// for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line...
if (getIsSolid()) {
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f);
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, rectangleColor);
geometryCache->renderDashedLine(*batch, point1, point2, rectangleColor);
geometryCache->renderDashedLine(*batch, point2, point3, rectangleColor);
geometryCache->renderDashedLine(*batch, point3, point4, rectangleColor);
geometryCache->renderDashedLine(*batch, point4, point1, rectangleColor);
} else {
if (getIsDashedLine()) {
if (halfDimensions != _previousHalfDimensions) {
QVector<glm::vec3> border;
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
geometryCache->updateVertices(_geometryCacheID, border, rectangleColor);
glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f);
glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f);
geometryCache->renderDashedLine(point1, point2, rectangleColor);
geometryCache->renderDashedLine(point2, point3, rectangleColor);
geometryCache->renderDashedLine(point3, point4, rectangleColor);
geometryCache->renderDashedLine(point4, point1, rectangleColor);
} else {
if (halfDimensions != _previousHalfDimensions) {
QVector<glm::vec3> border;
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
geometryCache->updateVertices(_geometryCacheID, border, rectangleColor);
_previousHalfDimensions = halfDimensions;
}
geometryCache->renderVertices(gpu::LINE_STRIP, _geometryCacheID);
_previousHalfDimensions = halfDimensions;
}
geometryCache->renderVertices(*batch, gpu::LINE_STRIP, _geometryCacheID);
}
}
} else {
glDisable(GL_LIGHTING);
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glPushMatrix();
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
//glScalef(dimensions.x, dimensions.y, 1.0f);
glLineWidth(_lineWidth);
auto geometryCache = DependencyManager::get<GeometryCache>();
// for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line...
if (getIsSolid()) {
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f);
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, rectangleColor);
} else {
if (getIsDashedLine()) {
glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f);
glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f);
geometryCache->renderDashedLine(point1, point2, rectangleColor);
geometryCache->renderDashedLine(point2, point3, rectangleColor);
geometryCache->renderDashedLine(point3, point4, rectangleColor);
geometryCache->renderDashedLine(point4, point1, rectangleColor);
} else {
if (halfDimensions != _previousHalfDimensions) {
QVector<glm::vec3> border;
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
geometryCache->updateVertices(_geometryCacheID, border, rectangleColor);
_previousHalfDimensions = halfDimensions;
}
geometryCache->renderVertices(gpu::LINE_STRIP, _geometryCacheID);
}
}
glPopMatrix();
glPopMatrix();
glPopMatrix();
if (glower) {
delete glower;
if (glower) {
delete glower;
}
}
}