mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 15:00:36 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into modelSceneRendering
This commit is contained in:
commit
d7d7db4494
17 changed files with 221 additions and 167 deletions
|
@ -1125,12 +1125,12 @@ var toolBar = (function () {
|
||||||
browseModelsButton,
|
browseModelsButton,
|
||||||
loadURLMenuItem,
|
loadURLMenuItem,
|
||||||
loadFileMenuItem,
|
loadFileMenuItem,
|
||||||
menuItemWidth = 125,
|
menuItemWidth,
|
||||||
menuItemOffset,
|
menuItemOffset,
|
||||||
menuItemHeight,
|
menuItemHeight,
|
||||||
menuItemMargin = 5,
|
menuItemMargin = 5,
|
||||||
menuTextColor = { red: 255, green: 255, blue: 255 },
|
menuTextColor = { red: 255, green: 255, blue: 255 },
|
||||||
menuBackgoundColor = { red: 18, green: 66, blue: 66 };
|
menuBackgroundColor = { red: 18, green: 66, blue: 66 };
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL);
|
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL);
|
||||||
|
@ -1167,9 +1167,8 @@ var toolBar = (function () {
|
||||||
loadURLMenuItem = Overlays.addOverlay("text", {
|
loadURLMenuItem = Overlays.addOverlay("text", {
|
||||||
x: newModelButton.x - menuItemWidth,
|
x: newModelButton.x - menuItemWidth,
|
||||||
y: newModelButton.y + menuItemOffset,
|
y: newModelButton.y + menuItemOffset,
|
||||||
width: menuItemWidth,
|
|
||||||
height: menuItemHeight,
|
height: menuItemHeight,
|
||||||
backgroundColor: menuBackgoundColor,
|
backgroundColor: menuBackgroundColor,
|
||||||
topMargin: menuItemMargin,
|
topMargin: menuItemMargin,
|
||||||
text: "Model URL",
|
text: "Model URL",
|
||||||
alpha: 0.9,
|
alpha: 0.9,
|
||||||
|
@ -1179,15 +1178,19 @@ var toolBar = (function () {
|
||||||
loadFileMenuItem = Overlays.addOverlay("text", {
|
loadFileMenuItem = Overlays.addOverlay("text", {
|
||||||
x: newModelButton.x - menuItemWidth,
|
x: newModelButton.x - menuItemWidth,
|
||||||
y: newModelButton.y + menuItemOffset + menuItemHeight,
|
y: newModelButton.y + menuItemOffset + menuItemHeight,
|
||||||
width: menuItemWidth,
|
|
||||||
height: menuItemHeight,
|
height: menuItemHeight,
|
||||||
backgroundColor: menuBackgoundColor,
|
backgroundColor: menuBackgroundColor,
|
||||||
topMargin: menuItemMargin,
|
topMargin: menuItemMargin,
|
||||||
text: "Model File",
|
text: "Model File",
|
||||||
alpha: 0.9,
|
alpha: 0.9,
|
||||||
visible: false
|
visible: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
menuItemWidth = Math.max(Overlays.textWidth(loadURLMenuItem, "Model URL"),
|
||||||
|
Overlays.textWidth(loadFileMenuItem, "Model File")) + 20;
|
||||||
|
Overlays.editOverlay(loadURLMenuItem, { width: menuItemWidth });
|
||||||
|
Overlays.editOverlay(loadFileMenuItem, { width: menuItemWidth });
|
||||||
|
|
||||||
newCubeButton = toolBar.addTool({
|
newCubeButton = toolBar.addTool({
|
||||||
imageURL: toolIconUrl + "add-cube.svg",
|
imageURL: toolIconUrl + "add-cube.svg",
|
||||||
subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
||||||
|
|
|
@ -89,12 +89,12 @@ var toolBar = (function () {
|
||||||
browseModelsButton,
|
browseModelsButton,
|
||||||
loadURLMenuItem,
|
loadURLMenuItem,
|
||||||
loadFileMenuItem,
|
loadFileMenuItem,
|
||||||
menuItemWidth = 125,
|
menuItemWidth,
|
||||||
menuItemOffset,
|
menuItemOffset,
|
||||||
menuItemHeight,
|
menuItemHeight,
|
||||||
menuItemMargin = 5,
|
menuItemMargin = 5,
|
||||||
menuTextColor = { red: 255, green: 255, blue: 255 },
|
menuTextColor = { red: 255, green: 255, blue: 255 },
|
||||||
menuBackgoundColor = { red: 18, green: 66, blue: 66 };
|
menuBackgroundColor = { red: 18, green: 66, blue: 66 };
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL);
|
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL);
|
||||||
|
@ -131,9 +131,8 @@ var toolBar = (function () {
|
||||||
loadURLMenuItem = Overlays.addOverlay("text", {
|
loadURLMenuItem = Overlays.addOverlay("text", {
|
||||||
x: newModelButton.x - menuItemWidth,
|
x: newModelButton.x - menuItemWidth,
|
||||||
y: newModelButton.y + menuItemOffset,
|
y: newModelButton.y + menuItemOffset,
|
||||||
width: menuItemWidth,
|
|
||||||
height: menuItemHeight,
|
height: menuItemHeight,
|
||||||
backgroundColor: menuBackgoundColor,
|
backgroundColor: menuBackgroundColor,
|
||||||
topMargin: menuItemMargin,
|
topMargin: menuItemMargin,
|
||||||
text: "Model URL",
|
text: "Model URL",
|
||||||
alpha: 0.9,
|
alpha: 0.9,
|
||||||
|
@ -143,15 +142,19 @@ var toolBar = (function () {
|
||||||
loadFileMenuItem = Overlays.addOverlay("text", {
|
loadFileMenuItem = Overlays.addOverlay("text", {
|
||||||
x: newModelButton.x - menuItemWidth,
|
x: newModelButton.x - menuItemWidth,
|
||||||
y: newModelButton.y + menuItemOffset + menuItemHeight,
|
y: newModelButton.y + menuItemOffset + menuItemHeight,
|
||||||
width: menuItemWidth,
|
|
||||||
height: menuItemHeight,
|
height: menuItemHeight,
|
||||||
backgroundColor: menuBackgoundColor,
|
backgroundColor: menuBackgroundColor,
|
||||||
topMargin: menuItemMargin,
|
topMargin: menuItemMargin,
|
||||||
text: "Model File",
|
text: "Model File",
|
||||||
alpha: 0.9,
|
alpha: 0.9,
|
||||||
visible: false
|
visible: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
menuItemWidth = Math.max(Overlays.textWidth(loadURLMenuItem, "Model URL"),
|
||||||
|
Overlays.textWidth(loadFileMenuItem, "Model File")) + 20;
|
||||||
|
Overlays.editOverlay(loadURLMenuItem, { width: menuItemWidth });
|
||||||
|
Overlays.editOverlay(loadFileMenuItem, { width: menuItemWidth });
|
||||||
|
|
||||||
newCubeButton = toolBar.addTool({
|
newCubeButton = toolBar.addTool({
|
||||||
imageURL: toolIconUrl + "add-cube.svg",
|
imageURL: toolIconUrl + "add-cube.svg",
|
||||||
subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
||||||
|
|
|
@ -160,7 +160,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
_lastQueriedViewFrustum(),
|
_lastQueriedViewFrustum(),
|
||||||
_lastQueriedTime(usecTimestampNow()),
|
_lastQueriedTime(usecTimestampNow()),
|
||||||
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
||||||
_viewTransform(new gpu::Transform()),
|
_viewTransform(),
|
||||||
_scaleMirror(1.0f),
|
_scaleMirror(1.0f),
|
||||||
_rotateMirror(0.0f),
|
_rotateMirror(0.0f),
|
||||||
_raiseMirror(0.0f),
|
_raiseMirror(0.0f),
|
||||||
|
@ -2911,13 +2911,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||||
// Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation
|
// Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation
|
||||||
// the viewTransofmr object is updatded with the correct values and saved,
|
// the viewTransofmr object is updatded with the correct values and saved,
|
||||||
// this is what is used for rendering the Entities and avatars
|
// this is what is used for rendering the Entities and avatars
|
||||||
gpu::Transform viewTransform;
|
Transform viewTransform;
|
||||||
viewTransform.setTranslation(whichCamera.getPosition());
|
viewTransform.setTranslation(whichCamera.getPosition());
|
||||||
viewTransform.setRotation(rotation);
|
viewTransform.setRotation(rotation);
|
||||||
viewTransform.postTranslate(eyeOffsetPos);
|
viewTransform.postTranslate(eyeOffsetPos);
|
||||||
viewTransform.postRotate(eyeOffsetOrient);
|
viewTransform.postRotate(eyeOffsetOrient);
|
||||||
if (whichCamera.getMode() == CAMERA_MODE_MIRROR) {
|
if (whichCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
viewTransform.setScale(gpu::Transform::Vec3(-1.0f, 1.0f, 1.0f));
|
viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f));
|
||||||
}
|
}
|
||||||
setViewTransform(viewTransform);
|
setViewTransform(viewTransform);
|
||||||
|
|
||||||
|
@ -3117,8 +3117,8 @@ void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTransl
|
||||||
_viewMatrixTranslation = viewMatrixTranslation;
|
_viewMatrixTranslation = viewMatrixTranslation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setViewTransform(const gpu::Transform& view) {
|
void Application::setViewTransform(const Transform& view) {
|
||||||
(*_viewTransform) = view;
|
_viewTransform = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::loadTranslatedViewMatrix(const glm::vec3& translation) {
|
void Application::loadTranslatedViewMatrix(const glm::vec3& translation) {
|
||||||
|
|
|
@ -232,8 +232,8 @@ public:
|
||||||
const glm::vec3& getViewMatrixTranslation() const { return _viewMatrixTranslation; }
|
const glm::vec3& getViewMatrixTranslation() const { return _viewMatrixTranslation; }
|
||||||
void setViewMatrixTranslation(const glm::vec3& translation) { _viewMatrixTranslation = translation; }
|
void setViewMatrixTranslation(const glm::vec3& translation) { _viewMatrixTranslation = translation; }
|
||||||
|
|
||||||
const gpu::TransformPointer& getViewTransform() const { return _viewTransform; }
|
const Transform& getViewTransform() const { return _viewTransform; }
|
||||||
void setViewTransform(const gpu::Transform& view);
|
void setViewTransform(const Transform& view);
|
||||||
|
|
||||||
/// if you need to access the application settings, use lockSettings()/unlockSettings()
|
/// if you need to access the application settings, use lockSettings()/unlockSettings()
|
||||||
QSettings* lockSettings() { _settingsMutex.lock(); return _settings; }
|
QSettings* lockSettings() { _settingsMutex.lock(); return _settings; }
|
||||||
|
@ -526,7 +526,7 @@ private:
|
||||||
QRect _mirrorViewRect;
|
QRect _mirrorViewRect;
|
||||||
RearMirrorTools* _rearMirrorTools;
|
RearMirrorTools* _rearMirrorTools;
|
||||||
|
|
||||||
gpu::TransformPointer _viewTransform;
|
Transform _viewTransform;
|
||||||
glm::mat4 _untranslatedViewMatrix;
|
glm::mat4 _untranslatedViewMatrix;
|
||||||
glm::vec3 _viewMatrixTranslation;
|
glm::vec3 _viewMatrixTranslation;
|
||||||
glm::mat4 _projectionMatrix;
|
glm::mat4 _projectionMatrix;
|
||||||
|
|
|
@ -135,19 +135,19 @@ void Batch::setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset
|
||||||
_params.push_back(type);
|
_params.push_back(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setModelTransform(const TransformPointer& model) {
|
void Batch::setModelTransform(const Transform& model) {
|
||||||
ADD_COMMAND(setModelTransform);
|
ADD_COMMAND(setModelTransform);
|
||||||
|
|
||||||
_params.push_back(_transforms.cache(model));
|
_params.push_back(_transforms.cache(model));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setViewTransform(const TransformPointer& view) {
|
void Batch::setViewTransform(const Transform& view) {
|
||||||
ADD_COMMAND(setViewTransform);
|
ADD_COMMAND(setViewTransform);
|
||||||
|
|
||||||
_params.push_back(_transforms.cache(view));
|
_params.push_back(_transforms.cache(view));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setProjectionTransform(const TransformPointer& proj) {
|
void Batch::setProjectionTransform(const Transform& proj) {
|
||||||
ADD_COMMAND(setProjectionTransform);
|
ADD_COMMAND(setProjectionTransform);
|
||||||
|
|
||||||
_params.push_back(_transforms.cache(proj));
|
_params.push_back(_transforms.cache(proj));
|
||||||
|
|
|
@ -50,10 +50,6 @@ enum Primitive {
|
||||||
NUM_PRIMITIVES,
|
NUM_PRIMITIVES,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ::Transform Transform;
|
|
||||||
typedef QSharedPointer< ::gpu::Transform > TransformPointer;
|
|
||||||
typedef std::vector< TransformPointer > Transforms;
|
|
||||||
|
|
||||||
class Batch {
|
class Batch {
|
||||||
public:
|
public:
|
||||||
typedef Stream::Slot Slot;
|
typedef Stream::Slot Slot;
|
||||||
|
@ -87,9 +83,9 @@ public:
|
||||||
// finaly projected into the clip space by the projection transform
|
// finaly projected into the clip space by the projection transform
|
||||||
// WARNING: ViewTransform transform from eye space to world space, its inverse is composed
|
// WARNING: ViewTransform transform from eye space to world space, its inverse is composed
|
||||||
// with the ModelTransformu to create the equivalent of the glModelViewMatrix
|
// with the ModelTransformu to create the equivalent of the glModelViewMatrix
|
||||||
void setModelTransform(const TransformPointer& model);
|
void setModelTransform(const Transform& model);
|
||||||
void setViewTransform(const TransformPointer& view);
|
void setViewTransform(const Transform& view);
|
||||||
void setProjectionTransform(const TransformPointer& proj);
|
void setProjectionTransform(const Transform& proj);
|
||||||
|
|
||||||
|
|
||||||
// TODO: As long as we have gl calls explicitely issued from interface
|
// TODO: As long as we have gl calls explicitely issued from interface
|
||||||
|
@ -258,35 +254,35 @@ public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Cache {
|
class Cache {
|
||||||
public:
|
public:
|
||||||
typedef QSharedPointer<T> Pointer;
|
typedef T Data;
|
||||||
Pointer _pointer;
|
Data _data;
|
||||||
Cache<T>(const Pointer& pointer) : _pointer(pointer) {}
|
Cache<T>(const Data& data) : _data(data) {}
|
||||||
|
|
||||||
class Vector {
|
class Vector {
|
||||||
public:
|
public:
|
||||||
std::vector< Cache<T> > _pointers;
|
std::vector< Cache<T> > _items;
|
||||||
|
|
||||||
uint32 cache(const Pointer& pointer) {
|
uint32 cache(const Data& data) {
|
||||||
uint32 offset = _pointers.size();
|
uint32 offset = _items.size();
|
||||||
_pointers.push_back(Cache<T>(pointer));
|
_items.push_back(Cache<T>(data));
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pointer get(uint32 offset) {
|
Data get(uint32 offset) {
|
||||||
if (offset >= _pointers.size()) {
|
if (offset >= _items.size()) {
|
||||||
return Pointer();
|
return Data();
|
||||||
}
|
}
|
||||||
return (_pointers.data() + offset)->_pointer;
|
return (_items.data() + offset)->_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
_pointers.clear();
|
_items.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Cache<Buffer>::Vector BufferCaches;
|
typedef Cache<BufferPointer>::Vector BufferCaches;
|
||||||
typedef Cache<Stream::Format>::Vector StreamFormatCaches;
|
typedef Cache<Stream::FormatPointer>::Vector StreamFormatCaches;
|
||||||
typedef Cache<Transform>::Vector TransformCaches;
|
typedef Cache<Transform>::Vector TransformCaches;
|
||||||
|
|
||||||
typedef unsigned char Byte;
|
typedef unsigned char Byte;
|
||||||
|
|
|
@ -113,15 +113,7 @@ static const GLenum _elementTypeToGLType[NUM_TYPES]= {
|
||||||
|
|
||||||
|
|
||||||
GLBackend::GLBackend() :
|
GLBackend::GLBackend() :
|
||||||
_needInputFormatUpdate(true),
|
_input(),
|
||||||
_inputFormat(0),
|
|
||||||
_inputBuffersState(0),
|
|
||||||
_inputBuffers(_inputBuffersState.size(), BufferPointer(0)),
|
|
||||||
_inputBufferOffsets(_inputBuffersState.size(), 0),
|
|
||||||
_inputBufferStrides(_inputBuffersState.size(), 0),
|
|
||||||
_indexBuffer(0),
|
|
||||||
_indexBufferOffset(0),
|
|
||||||
_inputAttributeActivation(0),
|
|
||||||
_transform()
|
_transform()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -203,9 +195,9 @@ void GLBackend::do_drawIndexed(Batch& batch, uint32 paramOffset) {
|
||||||
uint32 numIndices = batch._params[paramOffset + 1]._uint;
|
uint32 numIndices = batch._params[paramOffset + 1]._uint;
|
||||||
uint32 startIndex = batch._params[paramOffset + 0]._uint;
|
uint32 startIndex = batch._params[paramOffset + 0]._uint;
|
||||||
|
|
||||||
GLenum glType = _elementTypeToGLType[_indexBufferType];
|
GLenum glType = _elementTypeToGLType[_input._indexBufferType];
|
||||||
|
|
||||||
glDrawElements(mode, numIndices, glType, reinterpret_cast<GLvoid*>(startIndex + _indexBufferOffset));
|
glDrawElements(mode, numIndices, glType, reinterpret_cast<GLvoid*>(startIndex + _input._indexBufferOffset));
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,9 +212,9 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) {
|
||||||
void GLBackend::do_setInputFormat(Batch& batch, uint32 paramOffset) {
|
void GLBackend::do_setInputFormat(Batch& batch, uint32 paramOffset) {
|
||||||
Stream::FormatPointer format = batch._streamFormats.get(batch._params[paramOffset]._uint);
|
Stream::FormatPointer format = batch._streamFormats.get(batch._params[paramOffset]._uint);
|
||||||
|
|
||||||
if (format != _inputFormat) {
|
if (format != _input._format) {
|
||||||
_inputFormat = format;
|
_input._format = format;
|
||||||
_needInputFormatUpdate = true;
|
_input._invalidFormat = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,10 +225,10 @@ void GLBackend::do_setInputBuffer(Batch& batch, uint32 paramOffset) {
|
||||||
uint32 channel = batch._params[paramOffset + 3]._uint;
|
uint32 channel = batch._params[paramOffset + 3]._uint;
|
||||||
|
|
||||||
if (channel < getNumInputBuffers()) {
|
if (channel < getNumInputBuffers()) {
|
||||||
_inputBuffers[channel] = buffer;
|
_input._buffers[channel] = buffer;
|
||||||
_inputBufferOffsets[channel] = offset;
|
_input._bufferOffsets[channel] = offset;
|
||||||
_inputBufferStrides[channel] = stride;
|
_input._bufferStrides[channel] = stride;
|
||||||
_inputBuffersState.set(channel);
|
_input._buffersState.set(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,14 +244,14 @@ static const GLenum attributeSlotToClassicAttribName[NUM_CLASSIC_ATTRIBS] = {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void GLBackend::updateInput() {
|
void GLBackend::updateInput() {
|
||||||
if (_needInputFormatUpdate || _inputBuffersState.any()) {
|
if (_input._invalidFormat || _input._buffersState.any()) {
|
||||||
|
|
||||||
if (_needInputFormatUpdate) {
|
if (_input._invalidFormat) {
|
||||||
InputActivationCache newActivation;
|
InputStageState::ActivationCache newActivation;
|
||||||
|
|
||||||
// Check expected activation
|
// Check expected activation
|
||||||
if (_inputFormat) {
|
if (_input._format) {
|
||||||
const Stream::Format::AttributeMap& attributes = _inputFormat->getAttributes();
|
const Stream::Format::AttributeMap& attributes = _input._format->getAttributes();
|
||||||
for (Stream::Format::AttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); it++) {
|
for (Stream::Format::AttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); it++) {
|
||||||
const Stream::Attribute& attrib = (*it).second;
|
const Stream::Attribute& attrib = (*it).second;
|
||||||
newActivation.set(attrib._slot);
|
newActivation.set(attrib._slot);
|
||||||
|
@ -269,7 +261,7 @@ void GLBackend::updateInput() {
|
||||||
// Manage Activation what was and what is expected now
|
// Manage Activation what was and what is expected now
|
||||||
for (unsigned int i = 0; i < newActivation.size(); i++) {
|
for (unsigned int i = 0; i < newActivation.size(); i++) {
|
||||||
bool newState = newActivation[i];
|
bool newState = newActivation[i];
|
||||||
if (newState != _inputAttributeActivation[i]) {
|
if (newState != _input._attributeActivation[i]) {
|
||||||
#if defined(SUPPORT_LEGACY_OPENGL)
|
#if defined(SUPPORT_LEGACY_OPENGL)
|
||||||
if (i < NUM_CLASSIC_ATTRIBS) {
|
if (i < NUM_CLASSIC_ATTRIBS) {
|
||||||
if (newState) {
|
if (newState) {
|
||||||
|
@ -290,31 +282,31 @@ void GLBackend::updateInput() {
|
||||||
}
|
}
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
|
|
||||||
_inputAttributeActivation.flip(i);
|
_input._attributeActivation.flip(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now we need to bind the buffers and assign the attrib pointers
|
// now we need to bind the buffers and assign the attrib pointers
|
||||||
if (_inputFormat) {
|
if (_input._format) {
|
||||||
const Buffers& buffers = _inputBuffers;
|
const Buffers& buffers = _input._buffers;
|
||||||
const Offsets& offsets = _inputBufferOffsets;
|
const Offsets& offsets = _input._bufferOffsets;
|
||||||
const Offsets& strides = _inputBufferStrides;
|
const Offsets& strides = _input._bufferStrides;
|
||||||
|
|
||||||
const Stream::Format::AttributeMap& attributes = _inputFormat->getAttributes();
|
const Stream::Format::AttributeMap& attributes = _input._format->getAttributes();
|
||||||
|
|
||||||
for (Stream::Format::ChannelMap::const_iterator channelIt = _inputFormat->getChannels().begin();
|
for (Stream::Format::ChannelMap::const_iterator channelIt = _input._format->getChannels().begin();
|
||||||
channelIt != _inputFormat->getChannels().end();
|
channelIt != _input._format->getChannels().end();
|
||||||
channelIt++) {
|
channelIt++) {
|
||||||
const Stream::Format::ChannelMap::value_type::second_type& channel = (*channelIt).second;
|
const Stream::Format::ChannelMap::value_type::second_type& channel = (*channelIt).second;
|
||||||
if ((*channelIt).first < buffers.size()) {
|
if ((*channelIt).first < buffers.size()) {
|
||||||
int bufferNum = (*channelIt).first;
|
int bufferNum = (*channelIt).first;
|
||||||
|
|
||||||
if (_inputBuffersState.test(bufferNum) || _needInputFormatUpdate) {
|
if (_input._buffersState.test(bufferNum) || _input._invalidFormat) {
|
||||||
GLuint vbo = gpu::GLBackend::getBufferID((*buffers[bufferNum]));
|
GLuint vbo = gpu::GLBackend::getBufferID((*buffers[bufferNum]));
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
_inputBuffersState[bufferNum] = false;
|
_input._buffersState[bufferNum] = false;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < channel._slots.size(); i++) {
|
for (unsigned int i = 0; i < channel._slots.size(); i++) {
|
||||||
const Stream::Attribute& attrib = attributes.at(channel._slots[i]);
|
const Stream::Attribute& attrib = attributes.at(channel._slots[i]);
|
||||||
|
@ -354,7 +346,7 @@ void GLBackend::updateInput() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// everything format related should be in sync now
|
// everything format related should be in sync now
|
||||||
_needInputFormatUpdate = false;
|
_input._invalidFormat = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Fancy version GL4.4
|
/* TODO: Fancy version GL4.4
|
||||||
|
@ -415,10 +407,10 @@ void GLBackend::updateInput() {
|
||||||
|
|
||||||
|
|
||||||
void GLBackend::do_setIndexBuffer(Batch& batch, uint32 paramOffset) {
|
void GLBackend::do_setIndexBuffer(Batch& batch, uint32 paramOffset) {
|
||||||
_indexBufferType = (Type) batch._params[paramOffset + 2]._uint;
|
_input._indexBufferType = (Type) batch._params[paramOffset + 2]._uint;
|
||||||
BufferPointer indexBuffer = batch._buffers.get(batch._params[paramOffset + 1]._uint);
|
BufferPointer indexBuffer = batch._buffers.get(batch._params[paramOffset + 1]._uint);
|
||||||
_indexBufferOffset = batch._params[paramOffset + 0]._uint;
|
_input._indexBufferOffset = batch._params[paramOffset + 0]._uint;
|
||||||
_indexBuffer = indexBuffer;
|
_input._indexBuffer = indexBuffer;
|
||||||
if (indexBuffer) {
|
if (indexBuffer) {
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferID(*indexBuffer));
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferID(*indexBuffer));
|
||||||
} else {
|
} else {
|
||||||
|
@ -430,30 +422,18 @@ void GLBackend::do_setIndexBuffer(Batch& batch, uint32 paramOffset) {
|
||||||
// Transform Stage
|
// Transform Stage
|
||||||
|
|
||||||
void GLBackend::do_setModelTransform(Batch& batch, uint32 paramOffset) {
|
void GLBackend::do_setModelTransform(Batch& batch, uint32 paramOffset) {
|
||||||
TransformPointer modelTransform = batch._transforms.get(batch._params[paramOffset]._uint);
|
_transform._model = batch._transforms.get(batch._params[paramOffset]._uint);
|
||||||
|
_transform._invalidModel = true;
|
||||||
if (_transform._model.isNull() || (modelTransform != _transform._model)) {
|
|
||||||
_transform._model = modelTransform;
|
|
||||||
_transform._invalidModel = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_setViewTransform(Batch& batch, uint32 paramOffset) {
|
void GLBackend::do_setViewTransform(Batch& batch, uint32 paramOffset) {
|
||||||
TransformPointer viewTransform = batch._transforms.get(batch._params[paramOffset]._uint);
|
_transform._view = batch._transforms.get(batch._params[paramOffset]._uint);
|
||||||
|
_transform._invalidView = true;
|
||||||
if (_transform._view.isNull() || (viewTransform != _transform._view)) {
|
|
||||||
_transform._view = viewTransform;
|
|
||||||
_transform._invalidView = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_setProjectionTransform(Batch& batch, uint32 paramOffset) {
|
void GLBackend::do_setProjectionTransform(Batch& batch, uint32 paramOffset) {
|
||||||
TransformPointer projectionTransform = batch._transforms.get(batch._params[paramOffset]._uint);
|
_transform._projection = batch._transforms.get(batch._params[paramOffset]._uint);
|
||||||
|
_transform._invalidProj = true;
|
||||||
if (_transform._projection.isNull() || (projectionTransform != _transform._projection)) {
|
|
||||||
_transform._projection = projectionTransform;
|
|
||||||
_transform._invalidProj = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::updateTransform() {
|
void GLBackend::updateTransform() {
|
||||||
|
@ -468,28 +448,28 @@ void GLBackend::updateTransform() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_transform._invalidModel || _transform._invalidView) {
|
if (_transform._invalidModel || _transform._invalidView) {
|
||||||
if (!_transform._model.isNull()) {
|
if (!_transform._model.isIdentity()) {
|
||||||
if (_transform._lastMode != GL_MODELVIEW) {
|
if (_transform._lastMode != GL_MODELVIEW) {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
_transform._lastMode = GL_MODELVIEW;
|
_transform._lastMode = GL_MODELVIEW;
|
||||||
}
|
}
|
||||||
Transform::Mat4 modelView;
|
Transform::Mat4 modelView;
|
||||||
if (!_transform._view.isNull()) {
|
if (!_transform._view.isIdentity()) {
|
||||||
Transform mvx;
|
Transform mvx;
|
||||||
Transform::inverseMult(mvx, (*_transform._view), (*_transform._model));
|
Transform::inverseMult(mvx, _transform._view, _transform._model);
|
||||||
mvx.getMatrix(modelView);
|
mvx.getMatrix(modelView);
|
||||||
} else {
|
} else {
|
||||||
_transform._model->getMatrix(modelView);
|
_transform._model.getMatrix(modelView);
|
||||||
}
|
}
|
||||||
glLoadMatrixf(reinterpret_cast< const GLfloat* >(&modelView));
|
glLoadMatrixf(reinterpret_cast< const GLfloat* >(&modelView));
|
||||||
} else {
|
} else {
|
||||||
if (!_transform._view.isNull()) {
|
if (!_transform._view.isIdentity()) {
|
||||||
if (_transform._lastMode != GL_MODELVIEW) {
|
if (_transform._lastMode != GL_MODELVIEW) {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
_transform._lastMode = GL_MODELVIEW;
|
_transform._lastMode = GL_MODELVIEW;
|
||||||
}
|
}
|
||||||
Transform::Mat4 modelView;
|
Transform::Mat4 modelView;
|
||||||
_transform._view->getInverseMatrix(modelView);
|
_transform._view.getInverseMatrix(modelView);
|
||||||
glLoadMatrixf(reinterpret_cast< const GLfloat* >(&modelView));
|
glLoadMatrixf(reinterpret_cast< const GLfloat* >(&modelView));
|
||||||
} else {
|
} else {
|
||||||
// TODO: eventually do something about the matrix when neither view nor model is specified?
|
// TODO: eventually do something about the matrix when neither view nor model is specified?
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS;
|
static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS;
|
||||||
static const int MAX_NUM_INPUT_BUFFERS = 16;
|
static const int MAX_NUM_INPUT_BUFFERS = 16;
|
||||||
|
|
||||||
uint32 getNumInputBuffers() const { return _inputBuffersState.size(); }
|
uint32 getNumInputBuffers() const { return _input._buffersState.size(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -62,22 +62,39 @@ protected:
|
||||||
void do_setInputFormat(Batch& batch, uint32 paramOffset);
|
void do_setInputFormat(Batch& batch, uint32 paramOffset);
|
||||||
void do_setInputBuffer(Batch& batch, uint32 paramOffset);
|
void do_setInputBuffer(Batch& batch, uint32 paramOffset);
|
||||||
void do_setIndexBuffer(Batch& batch, uint32 paramOffset);
|
void do_setIndexBuffer(Batch& batch, uint32 paramOffset);
|
||||||
|
|
||||||
void updateInput();
|
void updateInput();
|
||||||
bool _needInputFormatUpdate;
|
struct InputStageState {
|
||||||
Stream::FormatPointer _inputFormat;
|
bool _invalidFormat;
|
||||||
typedef std::bitset<MAX_NUM_INPUT_BUFFERS> InputBuffersState;
|
Stream::FormatPointer _format;
|
||||||
InputBuffersState _inputBuffersState;
|
|
||||||
|
|
||||||
Buffers _inputBuffers;
|
typedef std::bitset<MAX_NUM_INPUT_BUFFERS> BuffersState;
|
||||||
Offsets _inputBufferOffsets;
|
BuffersState _buffersState;
|
||||||
Offsets _inputBufferStrides;
|
|
||||||
|
|
||||||
BufferPointer _indexBuffer;
|
Buffers _buffers;
|
||||||
Offset _indexBufferOffset;
|
Offsets _bufferOffsets;
|
||||||
Type _indexBufferType;
|
Offsets _bufferStrides;
|
||||||
|
|
||||||
typedef std::bitset<MAX_NUM_ATTRIBUTES> InputActivationCache;
|
BufferPointer _indexBuffer;
|
||||||
InputActivationCache _inputAttributeActivation;
|
Offset _indexBufferOffset;
|
||||||
|
Type _indexBufferType;
|
||||||
|
|
||||||
|
typedef std::bitset<MAX_NUM_ATTRIBUTES> ActivationCache;
|
||||||
|
ActivationCache _attributeActivation;
|
||||||
|
|
||||||
|
InputStageState() :
|
||||||
|
_invalidFormat(true),
|
||||||
|
_format(0),
|
||||||
|
_buffersState(0),
|
||||||
|
_buffers(_buffersState.size(), BufferPointer(0)),
|
||||||
|
_bufferOffsets(_buffersState.size(), 0),
|
||||||
|
_bufferStrides(_buffersState.size(), 0),
|
||||||
|
_indexBuffer(0),
|
||||||
|
_indexBufferOffset(0),
|
||||||
|
_indexBufferType(UINT32),
|
||||||
|
_attributeActivation(0)
|
||||||
|
{}
|
||||||
|
} _input;
|
||||||
|
|
||||||
// Transform Stage
|
// Transform Stage
|
||||||
void do_setModelTransform(Batch& batch, uint32 paramOffset);
|
void do_setModelTransform(Batch& batch, uint32 paramOffset);
|
||||||
|
@ -86,9 +103,9 @@ protected:
|
||||||
|
|
||||||
void updateTransform();
|
void updateTransform();
|
||||||
struct TransformStageState {
|
struct TransformStageState {
|
||||||
TransformPointer _model;
|
Transform _model;
|
||||||
TransformPointer _view;
|
Transform _view;
|
||||||
TransformPointer _projection;
|
Transform _projection;
|
||||||
bool _invalidModel;
|
bool _invalidModel;
|
||||||
bool _invalidView;
|
bool _invalidView;
|
||||||
bool _invalidProj;
|
bool _invalidProj;
|
||||||
|
@ -96,9 +113,9 @@ protected:
|
||||||
GLenum _lastMode;
|
GLenum _lastMode;
|
||||||
|
|
||||||
TransformStageState() :
|
TransformStageState() :
|
||||||
_model(0),
|
_model(),
|
||||||
_view(0),
|
_view(),
|
||||||
_projection(0),
|
_projection(),
|
||||||
_invalidModel(true),
|
_invalidModel(true),
|
||||||
_invalidView(true),
|
_invalidView(true),
|
||||||
_invalidProj(true),
|
_invalidProj(true),
|
||||||
|
|
|
@ -567,11 +567,11 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
|
|
||||||
// Capture the view matrix once for the rendering of this model
|
// Capture the view matrix once for the rendering of this model
|
||||||
if (_transforms.empty()) {
|
if (_transforms.empty()) {
|
||||||
_transforms.push_back(gpu::TransformPointer(new gpu::Transform()));
|
_transforms.push_back(Transform());
|
||||||
}
|
}
|
||||||
(*_transforms[0]) = gpu::Transform((*Application::getInstance()->getViewTransform()));
|
_transforms[0] = Application::getInstance()->getViewTransform();
|
||||||
// apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space)
|
// apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space)
|
||||||
_transforms[0]->preTranslate(-_translation);
|
_transforms[0].preTranslate(-_translation);
|
||||||
|
|
||||||
batch.setViewTransform(_transforms[0]);
|
batch.setViewTransform(_transforms[0]);
|
||||||
|
|
||||||
|
@ -1493,10 +1493,10 @@ void Model::setupBatchTransform(gpu::Batch& batch) {
|
||||||
|
|
||||||
// Capture the view matrix once for the rendering of this model
|
// Capture the view matrix once for the rendering of this model
|
||||||
if (_transforms.empty()) {
|
if (_transforms.empty()) {
|
||||||
_transforms.push_back(gpu::TransformPointer(new gpu::Transform()));
|
_transforms.push_back(Transform());
|
||||||
}
|
}
|
||||||
(*_transforms[0]) = gpu::Transform((*Application::getInstance()->getViewTransform()));
|
_transforms[0] = Application::getInstance()->getViewTransform();
|
||||||
_transforms[0]->preTranslate(-_translation);
|
_transforms[0].preTranslate(-_translation);
|
||||||
batch.setViewTransform(_transforms[0]);
|
batch.setViewTransform(_transforms[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2117,10 +2117,9 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
|
||||||
if (state.clusterMatrices.size() > 1) {
|
if (state.clusterMatrices.size() > 1) {
|
||||||
GLBATCH(glUniformMatrix4fv)(skinLocations->clusterMatrices, state.clusterMatrices.size(), false,
|
GLBATCH(glUniformMatrix4fv)(skinLocations->clusterMatrices, state.clusterMatrices.size(), false,
|
||||||
(const float*)state.clusterMatrices.constData());
|
(const float*)state.clusterMatrices.constData());
|
||||||
batch.setModelTransform(gpu::TransformPointer());
|
batch.setModelTransform(Transform());
|
||||||
} else {
|
} else {
|
||||||
gpu::TransformPointer modelTransform(new gpu::Transform(state.clusterMatrices[0]));
|
batch.setModelTransform(Transform(state.clusterMatrices[0]));
|
||||||
batch.setModelTransform(modelTransform);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh.blendshapes.isEmpty()) {
|
if (mesh.blendshapes.isEmpty()) {
|
||||||
|
|
|
@ -283,7 +283,7 @@ private:
|
||||||
QUrl _url;
|
QUrl _url;
|
||||||
|
|
||||||
gpu::Buffers _blendedVertexBuffers;
|
gpu::Buffers _blendedVertexBuffers;
|
||||||
gpu::Transforms _transforms;
|
std::vector<Transform> _transforms;
|
||||||
gpu::Batch _renderBatch;
|
gpu::Batch _renderBatch;
|
||||||
|
|
||||||
QVector<QVector<QSharedPointer<Texture> > > _dilatedTextures;
|
QVector<QVector<QSharedPointer<Texture> > > _dilatedTextures;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <typeinfo>
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Menu.h>
|
#include <Menu.h>
|
||||||
|
|
||||||
|
@ -360,3 +361,19 @@ bool Overlays::isLoaded(unsigned int id) {
|
||||||
return overlay->isLoaded();
|
return overlay->isLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Overlays::textWidth(unsigned int id, const QString& text) const {
|
||||||
|
Overlay* thisOverlay = _overlays2D[id];
|
||||||
|
if (thisOverlay) {
|
||||||
|
if (typeid(*thisOverlay) == typeid(TextOverlay)) {
|
||||||
|
return static_cast<TextOverlay*>(thisOverlay)->textWidth(text);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
thisOverlay = _overlays3D[id];
|
||||||
|
if (thisOverlay) {
|
||||||
|
if (typeid(*thisOverlay) == typeid(Text3DOverlay)) {
|
||||||
|
return static_cast<Text3DOverlay*>(thisOverlay)->textWidth(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
|
@ -65,6 +65,10 @@ public slots:
|
||||||
/// returns whether the overlay's assets are loaded or not
|
/// returns whether the overlay's assets are loaded or not
|
||||||
bool isLoaded(unsigned int id);
|
bool isLoaded(unsigned int id);
|
||||||
|
|
||||||
|
/// returns the width of the given text in the specified overlay if it is a text overlay: in pixels if it is a 2D text
|
||||||
|
/// overlay; in meters if it is a 3D text overlay
|
||||||
|
float textWidth(unsigned int id, const QString& text) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMap<unsigned int, Overlay*> _overlays2D;
|
QMap<unsigned int, Overlay*> _overlays2D;
|
||||||
QMap<unsigned int, Overlay*> _overlays3D;
|
QMap<unsigned int, Overlay*> _overlays3D;
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 };
|
const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 };
|
||||||
const float DEFAULT_MARGIN = 0.1f;
|
const float DEFAULT_MARGIN = 0.1f;
|
||||||
|
const int FIXED_FONT_POINT_SIZE = 40;
|
||||||
|
const float LINE_SCALE_RATIO = 1.2f;
|
||||||
|
|
||||||
Text3DOverlay::Text3DOverlay() :
|
Text3DOverlay::Text3DOverlay() :
|
||||||
_backgroundColor(DEFAULT_BACKGROUND_COLOR),
|
_backgroundColor(DEFAULT_BACKGROUND_COLOR),
|
||||||
|
@ -87,11 +89,10 @@ void Text3DOverlay::render(RenderArgs* args) {
|
||||||
glVertex3f(-halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
glVertex3f(-halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
const int FIXED_FONT_POINT_SIZE = 40;
|
|
||||||
const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 40.0f; // this is a ratio determined through experimentation
|
const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 40.0f; // this is a ratio determined through experimentation
|
||||||
|
|
||||||
|
// Same font properties as textWidth()
|
||||||
TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE);
|
TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE);
|
||||||
float LINE_SCALE_RATIO = 1.2f;
|
|
||||||
float maxHeight = (float)textRenderer->calculateHeight("Xy") * LINE_SCALE_RATIO;
|
float maxHeight = (float)textRenderer->calculateHeight("Xy") * LINE_SCALE_RATIO;
|
||||||
|
|
||||||
float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight;
|
float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight;
|
||||||
|
@ -179,4 +180,9 @@ void Text3DOverlay::setProperties(const QScriptValue& properties) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Text3DOverlay::textWidth(const QString& text) const {
|
||||||
|
QFont font(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); // Same font properties as render()
|
||||||
|
QFontMetrics fontMetrics(font);
|
||||||
|
float scaleFactor = _lineHeight * LINE_SCALE_RATIO / (float)FIXED_FONT_POINT_SIZE;
|
||||||
|
return scaleFactor * (float)fontMetrics.width(qPrintable(text));
|
||||||
|
}
|
||||||
|
|
|
@ -48,6 +48,8 @@ public:
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
|
||||||
|
float textWidth(const QString& text) const; // Meters
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void enableClipPlane(GLenum plane, float x, float y, float z, float w);
|
void enableClipPlane(GLenum plane, float x, float y, float z, float w);
|
||||||
|
|
||||||
|
|
|
@ -66,9 +66,8 @@ void TextOverlay::render(RenderArgs* args) {
|
||||||
glVertex2f(_bounds.left(), _bounds.bottom());
|
glVertex2f(_bounds.left(), _bounds.bottom());
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
//TextRenderer(const char* family, int pointSize = -1, int weight = -1, bool italic = false,
|
// Same font properties as textWidth()
|
||||||
// EffectType effect = NO_EFFECT, int effectThickness = 1);
|
TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT);
|
||||||
TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, _fontSize, 50);
|
|
||||||
|
|
||||||
const int leftAdjust = -1; // required to make text render relative to left edge of bounds
|
const int leftAdjust = -1; // required to make text render relative to left edge of bounds
|
||||||
const int topAdjust = -2; // required to make text render relative to top edge of bounds
|
const int topAdjust = -2; // required to make text render relative to top edge of bounds
|
||||||
|
@ -126,3 +125,8 @@ void TextOverlay::setProperties(const QScriptValue& properties) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float TextOverlay::textWidth(const QString& text) const {
|
||||||
|
QFont font(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT); // Same font properties as render()
|
||||||
|
QFontMetrics fontMetrics(font);
|
||||||
|
return fontMetrics.width(qPrintable(text));
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 };
|
const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 };
|
||||||
const int DEFAULT_MARGIN = 10;
|
const int DEFAULT_MARGIN = 10;
|
||||||
const int DEFAULT_FONTSIZE = 11;
|
const int DEFAULT_FONTSIZE = 11;
|
||||||
|
const int DEFAULT_FONT_WEIGHT = 50;
|
||||||
|
|
||||||
class TextOverlay : public Overlay2D {
|
class TextOverlay : public Overlay2D {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -53,6 +54,8 @@ public:
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
|
||||||
|
float textWidth(const QString& text) const; // Pixels
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QString _text;
|
QString _text;
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class Transform {
|
class Transform {
|
||||||
public:
|
public:
|
||||||
typedef glm::mat4 Mat4;
|
typedef glm::mat4 Mat4;
|
||||||
|
@ -30,16 +32,16 @@ public:
|
||||||
typedef glm::quat Quat;
|
typedef glm::quat Quat;
|
||||||
|
|
||||||
Transform() :
|
Transform() :
|
||||||
_translation(0),
|
|
||||||
_rotation(1.0f, 0, 0, 0),
|
_rotation(1.0f, 0, 0, 0),
|
||||||
_scale(1.0f),
|
_scale(1.0f),
|
||||||
|
_translation(0),
|
||||||
_flags(FLAG_CACHE_INVALID_BITSET) // invalid cache
|
_flags(FLAG_CACHE_INVALID_BITSET) // invalid cache
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Transform(const Transform& transform) :
|
Transform(const Transform& transform) :
|
||||||
_translation(transform._translation),
|
|
||||||
_rotation(transform._rotation),
|
_rotation(transform._rotation),
|
||||||
_scale(transform._scale),
|
_scale(transform._scale),
|
||||||
|
_translation(transform._translation),
|
||||||
_flags(transform._flags)
|
_flags(transform._flags)
|
||||||
{
|
{
|
||||||
invalidCache();
|
invalidCache();
|
||||||
|
@ -49,6 +51,15 @@ public:
|
||||||
}
|
}
|
||||||
~Transform() {}
|
~Transform() {}
|
||||||
|
|
||||||
|
Transform& operator=(const Transform& transform) {
|
||||||
|
_rotation = transform._rotation;
|
||||||
|
_scale = transform._scale;
|
||||||
|
_translation = transform._translation;
|
||||||
|
_flags = transform._flags;
|
||||||
|
invalidCache();
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
void setIdentity();
|
void setIdentity();
|
||||||
|
|
||||||
const Vec3& getTranslation() const;
|
const Vec3& getTranslation() const;
|
||||||
|
@ -89,7 +100,6 @@ public:
|
||||||
// Left will be inversed before the multiplication
|
// Left will be inversed before the multiplication
|
||||||
static Transform& inverseMult(Transform& result, const Transform& left, const Transform& right);
|
static Transform& inverseMult(Transform& result, const Transform& left, const Transform& right);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
enum Flag {
|
enum Flag {
|
||||||
|
@ -111,14 +121,15 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
// TRS
|
// TRS
|
||||||
Vec3 _translation;
|
|
||||||
Quat _rotation;
|
Quat _rotation;
|
||||||
Vec3 _scale;
|
Vec3 _scale;
|
||||||
|
Vec3 _translation;
|
||||||
|
|
||||||
mutable Flags _flags;
|
mutable Flags _flags;
|
||||||
|
|
||||||
// Cached transform
|
// Cached transform
|
||||||
mutable Mat4 _matrix;
|
// TODO: replace this auto ptr by a "unique ptr" as soon as we are compiling in C++11
|
||||||
|
mutable std::auto_ptr<Mat4> _matrix;
|
||||||
|
|
||||||
bool isCacheInvalid() const { return _flags[FLAG_CACHE_INVALID]; }
|
bool isCacheInvalid() const { return _flags[FLAG_CACHE_INVALID]; }
|
||||||
void validCache() const { _flags.set(FLAG_CACHE_INVALID, false); }
|
void validCache() const { _flags.set(FLAG_CACHE_INVALID, false); }
|
||||||
|
@ -135,6 +146,7 @@ protected:
|
||||||
void flagNonUniform() { _flags.set(FLAG_NON_UNIFORM, true); }
|
void flagNonUniform() { _flags.set(FLAG_NON_UNIFORM, true); }
|
||||||
|
|
||||||
void updateCache() const;
|
void updateCache() const;
|
||||||
|
Mat4& getCachedMatrix(Mat4& result) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void Transform::setIdentity() {
|
inline void Transform::setIdentity() {
|
||||||
|
@ -271,8 +283,25 @@ inline void Transform::postScale(const Vec3& scale) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Transform::Mat4& Transform::getMatrix(Transform::Mat4& result) const {
|
inline Transform::Mat4& Transform::getMatrix(Transform::Mat4& result) const {
|
||||||
updateCache();
|
if (isRotating()) {
|
||||||
result = _matrix;
|
Mat3 rot = glm::mat3_cast(_rotation);
|
||||||
|
|
||||||
|
if (isScaling()) {
|
||||||
|
rot[0] *= _scale.x;
|
||||||
|
rot[1] *= _scale.y;
|
||||||
|
rot[2] *= _scale.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
result[0] = Vec4(rot[0], 0.f);
|
||||||
|
result[1] = Vec4(rot[1], 0.f);
|
||||||
|
result[2] = Vec4(rot[2], 0.f);
|
||||||
|
} else {
|
||||||
|
result[0] = Vec4(_scale.x, 0.f, 0.f, 0.f);
|
||||||
|
result[1] = Vec4(0.f, _scale.y, 0.f, 0.f);
|
||||||
|
result[2] = Vec4(0.f, 0.f, _scale.z, 0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
result[3] = Vec4(_translation, 1.0f);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,27 +398,18 @@ inline Transform& Transform::inverseMult( Transform& result, const Transform& le
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Transform::Mat4& Transform::getCachedMatrix(Transform::Mat4& result) const {
|
||||||
|
updateCache();
|
||||||
|
result = (*_matrix);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
inline void Transform::updateCache() const {
|
inline void Transform::updateCache() const {
|
||||||
if (isCacheInvalid()) {
|
if (isCacheInvalid()) {
|
||||||
if (isRotating()) {
|
if (!_matrix.get()) {
|
||||||
Mat3 rot = glm::mat3_cast(_rotation);
|
_matrix.reset(new Mat4());
|
||||||
|
|
||||||
if (isScaling()) {
|
|
||||||
rot[0] *= _scale.x;
|
|
||||||
rot[1] *= _scale.y;
|
|
||||||
rot[2] *= _scale.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
_matrix[0] = Vec4(rot[0], 0.f);
|
|
||||||
_matrix[1] = Vec4(rot[1], 0.f);
|
|
||||||
_matrix[2] = Vec4(rot[2], 0.f);
|
|
||||||
} else {
|
|
||||||
_matrix[0] = Vec4(_scale.x, 0.f, 0.f, 0.f);
|
|
||||||
_matrix[1] = Vec4(0.f, _scale.y, 0.f, 0.f);
|
|
||||||
_matrix[2] = Vec4(0.f, 0.f, _scale.z, 0.f);
|
|
||||||
}
|
}
|
||||||
|
getMatrix((*_matrix));
|
||||||
_matrix[3] = Vec4(_translation, 1.0f);
|
|
||||||
validCache();
|
validCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue