Working on oculus overlay code

This commit is contained in:
Brad Davis 2015-06-11 00:50:24 -07:00
parent c77c41405d
commit ac0fc5d974
2 changed files with 117 additions and 146 deletions

View file

@ -301,7 +301,6 @@ gpu::PipelinePointer ApplicationOverlay::getDrawPipeline() {
// Draws the FBO texture for the screen // Draws the FBO texture for the screen
void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) { void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) {
if (_alpha == 0.0f) { if (_alpha == 0.0f) {
return; return;
} }
@ -312,37 +311,21 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) {
} }
//FIXME - doesn't work
renderArgs->_context->syncCache(); renderArgs->_context->syncCache();
glViewport(0, 0, qApp->getDeviceSize().width(), qApp->getDeviceSize().height());
gpu::Batch batch; gpu::Batch batch;
Transform model;
//DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true); //DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true);
batch.setPipeline(getDrawPipeline()); batch.setPipeline(getDrawPipeline());
batch.setModelTransform(Transform()); batch.setModelTransform(Transform());
batch.setProjectionTransform(mat4()); batch.setProjectionTransform(mat4());
batch.setViewTransform(Transform()); batch.setViewTransform(model);
batch.setUniformTexture(0, _crosshairTexture); batch._glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture());
batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
DependencyManager::get<GeometryCache>()->renderUnitQuad(batch, vec4(vec3(1), _alpha)); DependencyManager::get<GeometryCache>()->renderUnitQuad(batch, vec4(vec3(1), _alpha));
renderArgs->_context->render(batch);
return;
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glViewport(0, 0, qApp->getDeviceSize().width(), qApp->getDeviceSize().height());
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
{
glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture());
DependencyManager::get<GeometryCache>()->renderUnitQuad(vec4(vec3(1), _alpha));
//draw the mouse pointer //draw the mouse pointer
glm::vec2 canvasSize = qApp->getCanvasSize(); glm::vec2 canvasSize = qApp->getCanvasSize();
@ -352,40 +335,53 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) {
mousePosition *= 2.0f; mousePosition *= 2.0f;
mousePosition -= 1.0f; mousePosition -= 1.0f;
mousePosition.y *= -1.0f; mousePosition.y *= -1.0f;
mat4 mouseMv = glm::translate(mat4(), vec3(mousePosition, 0)); model.setTranslation(vec3(mousePosition, 0));
// Scale the mouse based on the canvasSize (NOT the device size,
// we don't want a smaller mouse on retina displays)
glm::vec2 mouseSize = 32.0f / canvasSize; glm::vec2 mouseSize = 32.0f / canvasSize;
mouseMv = glm::scale(mouseMv, vec3(mouseSize, 1.0f)); model.setScale(vec3(mouseSize, 1.0f));
batch.setModelTransform(model);
// Push the resulting matrix into modelview batch.setUniformTexture(0, _crosshairTexture);
glLoadMatrixf(glm::value_ptr(mouseMv));
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f }; glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f };
DependencyManager::get<GeometryCache>()->renderUnitQuad(reticleColor); DependencyManager::get<GeometryCache>()->renderUnitQuad(batch, vec4(1));
} renderArgs->_context->render(batch);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
} }
static gpu::BufferPointer _hemiVertices;
static gpu::BufferPointer _hemiIndices;
static int _hemiIndexCount{ 0 };
// Draws the FBO texture for Oculus rift. // Draws the FBO texture for Oculus rift.
void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera& whichCamera) { void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera& whichCamera) {
if (_alpha == 0.0f) { if (_alpha == 0.0f) {
return; return;
} }
_overlays.buildVBO(_textureFov, _textureAspectRatio, 80, 80); auto geometryCache = DependencyManager::get<GeometryCache>();
glDisable(GL_DEPTH_TEST); gpu::Batch batch;
glDisable(GL_LIGHTING); //DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true);
glEnable(GL_BLEND); batch.setPipeline(getDrawPipeline());
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); batch._glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D); batch._glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture());
glActiveTexture(GL_TEXTURE0); batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glMatrixMode(GL_MODELVIEW); batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glLoadIdentity(); batch.setProjectionTransform(whichCamera.getProjection());
batch.setViewTransform(Transform());
Transform model;
model.setTranslation(vec3(0.0f, 0.0f, -2.0f));
batch.setModelTransform(model);
// FIXME doesn't work
drawSphereSection(batch);
// works...
geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha));
renderArgs->_context->render(batch);
// batch.setUniformTexture(0, gpu::TexturePointer());
// geometryCache->renderSolidCube(batch, 0.5f, vec4(1));
/*
// The camera here contains only the head pose relative to the avatar position // The camera here contains only the head pose relative to the avatar position
vec3 pos = whichCamera.getPosition(); vec3 pos = whichCamera.getPosition();
quat rot = whichCamera.getOrientation(); quat rot = whichCamera.getOrientation();
@ -394,6 +390,7 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera
glLoadMatrixf(glm::value_ptr(glm::inverse(overlayXfm))); glLoadMatrixf(glm::value_ptr(glm::inverse(overlayXfm)));
glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture()); glBindTexture(GL_TEXTURE_2D, _framebufferObject->texture());
_overlays.render(); _overlays.render();
*/
//Update and draw the magnifiers //Update and draw the magnifiers
/* /*
@ -423,11 +420,11 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera
}); });
} }
} }
*/
if (!Application::getInstance()->isMouseHidden()) { if (!Application::getInstance()->isMouseHidden()) {
renderPointersOculus(); renderPointersOculus();
} }
*/
} }
// Draws the FBO texture for 3DTV. // Draws the FBO texture for 3DTV.
@ -1104,109 +1101,102 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() {
} }
} }
ApplicationOverlay::TexturedHemisphere::TexturedHemisphere() :
_vertices(0),
_indices(0),
_vbo(0, 0) {
}
ApplicationOverlay::TexturedHemisphere::~TexturedHemisphere() { void ApplicationOverlay::buildHemiVertices(
cleanupVBO(); const float fov, const float aspectRatio, const int slices, const int stacks) {
}
void ApplicationOverlay::TexturedHemisphere::buildVBO(const float fov,
const float aspectRatio,
const int slices,
const int stacks) {
static float textureFOV = 0.0f, textureAspectRatio = 1.0f; static float textureFOV = 0.0f, textureAspectRatio = 1.0f;
if (textureFOV == fov && textureAspectRatio == aspectRatio) { if (_hemiVerticesID != GeometryCache::UNKNOWN_ID && textureFOV == fov && textureAspectRatio == aspectRatio) {
return; return;
} }
textureFOV = fov; textureFOV = fov;
textureAspectRatio = aspectRatio; textureAspectRatio = aspectRatio;
auto geometryCache = DependencyManager::get<GeometryCache>();
if (_hemiVerticesID == GeometryCache::UNKNOWN_ID) {
_hemiVerticesID = geometryCache->allocateID();
}
_hemiVertices = gpu::BufferPointer(new gpu::Buffer());
_hemiIndices = gpu::BufferPointer(new gpu::Buffer());
if (fov >= PI) { if (fov >= PI) {
qDebug() << "TexturedHemisphere::buildVBO(): FOV greater or equal than Pi will create issues"; qDebug() << "TexturedHemisphere::buildVBO(): FOV greater or equal than Pi will create issues";
} }
// Cleanup old VBO if necessary
cleanupVBO();
//UV mapping source: http://www.mvps.org/directx/articles/spheremap.htm //UV mapping source: http://www.mvps.org/directx/articles/spheremap.htm
// Compute number of vertices needed vec3 pos;
_vertices = slices * stacks;
// Compute vertices positions and texture UV coordinate // Compute vertices positions and texture UV coordinate
TextureVertex* vertexData = new TextureVertex[_vertices]; // Create and write to buffer
TextureVertex* vertexPtr = &vertexData[0]; //_hemiVertices->(sizeof(vec3) + sizeof(vec2) + sizeof(vec4)) * stacks * slices);
for (int i = 0; i < stacks; i++) { for (int i = 0; i < stacks; i++) {
float stacksRatio = (float)i / (float)(stacks - 1); // First stack is 0.0f, last stack is 1.0f float stacksRatio = (float)i / (float)(stacks - 1); // First stack is 0.0f, last stack is 1.0f
// abs(theta) <= fov / 2.0f // abs(theta) <= fov / 2.0f
float pitch = -fov * (stacksRatio - 0.5f); float pitch = -fov * (stacksRatio - 0.5f);
for (int j = 0; j < slices; j++) { for (int j = 0; j < slices; j++) {
float slicesRatio = (float)j / (float)(slices - 1); // First slice is 0.0f, last slice is 1.0f float slicesRatio = (float)j / (float)(slices - 1); // First slice is 0.0f, last slice is 1.0f
// abs(phi) <= fov * aspectRatio / 2.0f // abs(phi) <= fov * aspectRatio / 2.0f
float yaw = -fov * aspectRatio * (slicesRatio - 0.5f); float yaw = -fov * aspectRatio * (slicesRatio - 0.5f);
pos = getPoint(yaw, pitch);
vertexPtr->position = getPoint(yaw, pitch); _hemiVertices->append(sizeof(pos), (gpu::Byte*)&pos);
vertexPtr->uv.x = slicesRatio; _hemiVertices->append(sizeof(vec2), (gpu::Byte*)&vec2(slicesRatio, stacksRatio));
vertexPtr->uv.y = stacksRatio; _hemiVertices->append(sizeof(vec4), (gpu::Byte*)&vec4(1));
vertexPtr++;
} }
} }
// Create and write to buffer
glGenBuffers(1, &_vbo.first);
glBindBuffer(GL_ARRAY_BUFFER, _vbo.first);
static const int BYTES_PER_VERTEX = sizeof(TextureVertex);
glBufferData(GL_ARRAY_BUFFER, _vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
delete[] vertexData;
// Compute number of indices needed // Compute number of indices needed
static const int VERTEX_PER_TRANGLE = 3; static const int VERTEX_PER_TRANGLE = 3;
static const int TRIANGLE_PER_RECTANGLE = 2; static const int TRIANGLE_PER_RECTANGLE = 2;
int numberOfRectangles = (slices - 1) * (stacks - 1); int numberOfRectangles = (slices - 1) * (stacks - 1);
_indices = numberOfRectangles * TRIANGLE_PER_RECTANGLE * VERTEX_PER_TRANGLE; _hemiIndexCount = numberOfRectangles * TRIANGLE_PER_RECTANGLE * VERTEX_PER_TRANGLE;
// Compute indices order // Compute indices order
GLushort* indexData = new GLushort[_indices]; std::vector<GLushort> indices;
GLushort* indexPtr = indexData;
for (int i = 0; i < stacks - 1; i++) { for (int i = 0; i < stacks - 1; i++) {
for (int j = 0; j < slices - 1; j++) { for (int j = 0; j < slices - 1; j++) {
GLushort bottomLeftIndex = i * slices + j; GLushort bottomLeftIndex = i * slices + j;
GLushort bottomRightIndex = bottomLeftIndex + 1; GLushort bottomRightIndex = bottomLeftIndex + 1;
GLushort topLeftIndex = bottomLeftIndex + slices; GLushort topLeftIndex = bottomLeftIndex + slices;
GLushort topRightIndex = topLeftIndex + 1; GLushort topRightIndex = topLeftIndex + 1;
// FIXME make a z-order curve for better vertex cache locality
indices.push_back(topLeftIndex);
indices.push_back(bottomLeftIndex);
indices.push_back(topRightIndex);
*(indexPtr++) = topLeftIndex; indices.push_back(topRightIndex);
*(indexPtr++) = bottomLeftIndex; indices.push_back(bottomLeftIndex);
*(indexPtr++) = topRightIndex; indices.push_back(bottomRightIndex);
*(indexPtr++) = topRightIndex;
*(indexPtr++) = bottomLeftIndex;
*(indexPtr++) = bottomRightIndex;
} }
} }
// Create and write to buffer _hemiIndices->append(sizeof(GLushort) * indices.size(), (gpu::Byte*)&indices[0]);
glGenBuffers(1, &_vbo.second);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vbo.second);
static const int BYTES_PER_INDEX = sizeof(GLushort);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices * BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
delete[] indexData;
} }
void ApplicationOverlay::TexturedHemisphere::cleanupVBO() {
if (_vbo.first != 0) { void ApplicationOverlay::drawSphereSection(gpu::Batch& batch) {
glDeleteBuffers(1, &_vbo.first); buildHemiVertices(_textureFov, _textureAspectRatio, 80, 80);
_vbo.first = 0; static const int VERTEX_DATA_SLOT = 0;
} static const int TEXTURE_DATA_SLOT = 1;
if (_vbo.second != 0) { static const int COLOR_DATA_SLOT = 2;
glDeleteBuffers(1, &_vbo.second); gpu::Stream::FormatPointer streamFormat(new gpu::Stream::Format()); // 1 for everyone
_vbo.second = 0; streamFormat->setAttribute(gpu::Stream::POSITION, VERTEX_DATA_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
} streamFormat->setAttribute(gpu::Stream::TEXCOORD, TEXTURE_DATA_SLOT, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), sizeof(vec3));
streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_DATA_SLOT, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::RGBA), sizeof(vec3) + sizeof(vec2));
batch.setInputFormat(streamFormat);
static const int VERTEX_STRIDE = sizeof(vec3) + sizeof(vec2) + sizeof(vec4);
gpu::BufferView posView(_hemiVertices, 0, _hemiVertices->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::POSITION)._element);
gpu::BufferView uvView(_hemiVertices, sizeof(vec3), _hemiVertices->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::TEXCOORD)._element);
gpu::BufferView colView(_hemiVertices, sizeof(vec3) + sizeof(vec2), _hemiVertices->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::COLOR)._element);
batch.setInputBuffer(VERTEX_DATA_SLOT, posView);
batch.setInputBuffer(TEXTURE_DATA_SLOT, uvView);
batch.setInputBuffer(COLOR_DATA_SLOT, colView);
batch.setIndexBuffer(gpu::UINT16, _hemiIndices, 0);
batch.drawIndexed(gpu::TRIANGLES, _hemiIndexCount);
} }
GLuint ApplicationOverlay::getOverlayTexture() { GLuint ApplicationOverlay::getOverlayTexture() {
return _framebufferObject->texture(); return _framebufferObject->texture();
} }
@ -1234,6 +1224,7 @@ void ApplicationOverlay::buildFramebufferObject() {
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
/*
//Renders a hemisphere with texture coordinates. //Renders a hemisphere with texture coordinates.
void ApplicationOverlay::TexturedHemisphere::render() { void ApplicationOverlay::TexturedHemisphere::render() {
if (_vbo.first == 0 || _vbo.second == 0) { if (_vbo.first == 0 || _vbo.second == 0) {
@ -1261,7 +1252,7 @@ void ApplicationOverlay::TexturedHemisphere::render() {
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
} }
*/
glm::vec2 ApplicationOverlay::directionToSpherical(const glm::vec3& direction) { glm::vec2 ApplicationOverlay::directionToSpherical(const glm::vec3& direction) {
glm::vec2 result; glm::vec2 result;
// Compute yaw // Compute yaw

View file

@ -67,28 +67,8 @@ public:
static glm::vec2 sphericalToScreen(const glm::vec2 & sphericalPos); static glm::vec2 sphericalToScreen(const glm::vec2 & sphericalPos);
private: private:
// Interleaved vertex data void buildHemiVertices(const float fov, const float aspectRatio, const int slices, const int stacks);
struct TextureVertex { void drawSphereSection(gpu::Batch& batch);
glm::vec3 position;
glm::vec2 uv;
};
typedef QPair<GLuint, GLuint> VerticesIndices;
class TexturedHemisphere {
public:
TexturedHemisphere();
~TexturedHemisphere();
void buildVBO(const float fov, const float aspectRatio, const int slices, const int stacks);
void render();
private:
void cleanupVBO();
GLuint _vertices;
GLuint _indices;
VerticesIndices _vbo;
};
float _hmdUIAngularSize = DEFAULT_HMD_UI_ANGULAR_SIZE; float _hmdUIAngularSize = DEFAULT_HMD_UI_ANGULAR_SIZE;
QOpenGLFramebufferObject* _framebufferObject; QOpenGLFramebufferObject* _framebufferObject;
@ -106,10 +86,10 @@ private:
void buildFramebufferObject(); void buildFramebufferObject();
TexturedHemisphere _overlays;
float _textureFov; float _textureFov;
float _textureAspectRatio; float _textureAspectRatio;
int _hemiVerticesID{ GeometryCache::UNKNOWN_ID };
enum Reticles { MOUSE, LEFT_CONTROLLER, RIGHT_CONTROLLER, NUMBER_OF_RETICLES }; enum Reticles { MOUSE, LEFT_CONTROLLER, RIGHT_CONTROLLER, NUMBER_OF_RETICLES };
bool _reticleActive[NUMBER_OF_RETICLES]; bool _reticleActive[NUMBER_OF_RETICLES];