//// GL41BackendInput.cpp// libraries/gpu/src/gpu//// Created by Sam Gateau on 3/8/2015.// Copyright 2014 High Fidelity, Inc.//// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html//#include "GL41Backend.h" using namespace gpu;using namespace gpu::gl41; void GL41Backend::resetInputStage() { Parent::resetInputStage(); glBindBuffer(GL_ARRAY_BUFFER, 0); for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) { glDisableVertexAttribArray(i); glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); }} void GL41Backend::updateInput() { bool isStereoNow = isStereo(); // track stereo state change potentially happening wihtout changing the input format // this is a rare case requesting to invalid the format#ifdef GPU_STEREO_DRAWCALL_INSTANCED _input._invalidFormat |= (isStereoNow != _input._lastUpdateStereoState);#endif _input._lastUpdateStereoState = isStereoNow; if (_input._invalidFormat || _input._invalidBuffers.any()) { auto format = acquire(_input._format); if (_input._invalidFormat) { InputStageState::ActivationCache newActivation; _stats._ISNumFormatChanges++; // Check expected activation if (format) { for (auto& it : format->getAttributes()) { const Stream::Attribute& attrib = (it).second; uint8_t locationCount = attrib._element.getLocationCount(); for (int i = 0; i < locationCount; ++i) { newActivation.set(attrib._slot + i); } } } // Manage Activation what was and what is expected now for (unsigned int i = 0; i < newActivation.size(); i++) { bool newState = newActivation[i]; if (newState != _input._attributeActivation[i]) { if (newState) { glEnableVertexAttribArray(i); } else { glDisableVertexAttribArray(i); } (void)CHECK_GL_ERROR(); _input._attributeActivation.flip(i); } } } // now we need to bind the buffers and assign the attrib pointers if (format) { const auto& buffers = _input._buffers; const auto& offsets = _input._bufferOffsets; const auto& strides = _input._bufferStrides; const auto& attributes = format->getAttributes(); const auto& inputChannels = format->getChannels(); int numInvalids = (int)_input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; GLuint boundVBO = 0; for (auto& channelIt : inputChannels) { const Stream::Format::ChannelMap::value_type::second_type& channel = (channelIt).second; if ((channelIt).first < buffers.size()) { int bufferNum = (channelIt).first; if (_input._invalidBuffers.test(bufferNum) || _input._invalidFormat) { // GLuint vbo = gpu::GL41Backend::getBufferID((*buffers[bufferNum])); GLuint vbo = _input._bufferVBOs[bufferNum]; if (boundVBO != vbo) { glBindBuffer(GL_ARRAY_BUFFER, vbo); (void)CHECK_GL_ERROR(); boundVBO = vbo; } _input._invalidBuffers[bufferNum] = false; for (unsigned int i = 0; i < channel._slots.size(); i++) { const Stream::Attribute& attrib = attributes.at(channel._slots[i]); GLuint slot = attrib._slot; GLuint count = attrib._element.getLocationScalarCount(); uint8_t locationCount = attrib._element.getLocationCount(); GLenum type = gl::ELEMENT_TYPE_TO_GL[attrib._element.getType()]; // GLenum perLocationStride = strides[bufferNum]; GLenum perLocationStride = attrib._element.getLocationSize(); GLuint stride = (GLuint)strides[bufferNum]; uintptr_t pointer = (uintptr_t)(attrib._offset + offsets[bufferNum]); GLboolean isNormalized = attrib._element.isNormalized(); for (size_t locNum = 0; locNum < locationCount; ++locNum) { if (attrib._element.isInteger()) { glVertexAttribIPointer(slot + (GLuint)locNum, count, type, stride, reinterpret_cast<GLvoid*>(pointer + perLocationStride * (GLuint)locNum)); } else { glVertexAttribPointer(slot + (GLuint)locNum, count, type, isNormalized, stride, reinterpret_cast<GLvoid*>(pointer + perLocationStride * (GLuint)locNum)); }#ifdef GPU_STEREO_DRAWCALL_INSTANCED glVertexAttribDivisor(slot + (GLuint)locNum, attrib._frequency * (isStereoNow ? 2 : 1));#else glVertexAttribDivisor(slot + (GLuint)locNum, attrib._frequency);#endif } (void)CHECK_GL_ERROR(); } } } } } // everything format related should be in sync now _input._invalidFormat = false; }}
//
// GL41BackendInput.cpp
// libraries/gpu/src/gpu
//
// Created by Sam Gateau on 3/8/2015.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "GL41Backend.h"
using namespace gpu;
using namespace gpu::gl41;
void GL41Backend::resetInputStage() {
Parent::resetInputStage();
glBindBuffer(GL_ARRAY_BUFFER, 0);
for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) {
glDisableVertexAttribArray(i);
glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0);
}
}
void GL41Backend::updateInput() {
bool isStereoNow = isStereo();
// track stereo state change potentially happening wihtout changing the input format
// this is a rare case requesting to invalid the format
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
_input._invalidFormat |= (isStereoNow != _input._lastUpdateStereoState);
#endif
_input._lastUpdateStereoState = isStereoNow;
if (_input._invalidFormat || _input._invalidBuffers.any()) {
auto format = acquire(_input._format);
if (_input._invalidFormat) {
InputStageState::ActivationCache newActivation;
_stats._ISNumFormatChanges++;
// Check expected activation
if (format) {
for (auto& it : format->getAttributes()) {
const Stream::Attribute& attrib = (it).second;
uint8_t locationCount = attrib._element.getLocationCount();
for (int i = 0; i < locationCount; ++i) {
newActivation.set(attrib._slot + i);
}
}
}
// Manage Activation what was and what is expected now
for (unsigned int i = 0; i < newActivation.size(); i++) {
bool newState = newActivation[i];
if (newState != _input._attributeActivation[i]) {
if (newState) {
glEnableVertexAttribArray(i);
} else {
glDisableVertexAttribArray(i);
}
(void)CHECK_GL_ERROR();
_input._attributeActivation.flip(i);
}
}
}
// now we need to bind the buffers and assign the attrib pointers
if (format) {
const auto& buffers = _input._buffers;
const auto& offsets = _input._bufferOffsets;
const auto& strides = _input._bufferStrides;
const auto& attributes = format->getAttributes();
const auto& inputChannels = format->getChannels();
int numInvalids = (int)_input._invalidBuffers.count();
_stats._ISNumInputBufferChanges += numInvalids;
GLuint boundVBO = 0;
for (auto& channelIt : inputChannels) {
const Stream::Format::ChannelMap::value_type::second_type& channel = (channelIt).second;
if ((channelIt).first < buffers.size()) {
int bufferNum = (channelIt).first;
if (_input._invalidBuffers.test(bufferNum) || _input._invalidFormat) {
// GLuint vbo = gpu::GL41Backend::getBufferID((*buffers[bufferNum]));
GLuint vbo = _input._bufferVBOs[bufferNum];
if (boundVBO != vbo) {
glBindBuffer(GL_ARRAY_BUFFER, vbo);
(void)CHECK_GL_ERROR();
boundVBO = vbo;
}
_input._invalidBuffers[bufferNum] = false;
for (unsigned int i = 0; i < channel._slots.size(); i++) {
const Stream::Attribute& attrib = attributes.at(channel._slots[i]);
GLuint slot = attrib._slot;
GLuint count = attrib._element.getLocationScalarCount();
uint8_t locationCount = attrib._element.getLocationCount();
GLenum type = gl::ELEMENT_TYPE_TO_GL[attrib._element.getType()];
// GLenum perLocationStride = strides[bufferNum];
GLenum perLocationStride = attrib._element.getLocationSize();
GLuint stride = (GLuint)strides[bufferNum];
uintptr_t pointer = (uintptr_t)(attrib._offset + offsets[bufferNum]);
GLboolean isNormalized = attrib._element.isNormalized();
for (size_t locNum = 0; locNum < locationCount; ++locNum) {
if (attrib._element.isInteger()) {
glVertexAttribIPointer(slot + (GLuint)locNum, count, type, stride,
reinterpret_cast<GLvoid*>(pointer + perLocationStride * (GLuint)locNum));
} else {
glVertexAttribPointer(slot + (GLuint)locNum, count, type, isNormalized, stride,
reinterpret_cast<GLvoid*>(pointer + perLocationStride * (GLuint)locNum));
}
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
glVertexAttribDivisor(slot + (GLuint)locNum, attrib._frequency * (isStereoNow ? 2 : 1));
#else
glVertexAttribDivisor(slot + (GLuint)locNum, attrib._frequency);
#endif
}
(void)CHECK_GL_ERROR();
}
}
}
}
}
// everything format related should be in sync now
_input._invalidFormat = false;
}
}