mirror of
https://github.com/lubosz/overte.git
synced 2025-04-19 16:44:04 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into camera-display
Conflicts: examples/editEntities.js
This commit is contained in:
commit
0105906dc7
127 changed files with 4156 additions and 1305 deletions
|
@ -12,6 +12,10 @@ if (POLICY CMP0043)
|
|||
cmake_policy(SET CMP0043 OLD)
|
||||
endif ()
|
||||
|
||||
if (POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 OLD)
|
||||
endif ()
|
||||
|
||||
project(hifi)
|
||||
add_definitions(-DGLM_FORCE_RADIANS)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ include_glm()
|
|||
|
||||
# link in the shared libraries
|
||||
link_hifi_libraries(
|
||||
audio avatars octree voxels fbx entities metavoxels
|
||||
audio avatars octree voxels gpu model fbx entities metavoxels
|
||||
networking animation shared script-engine embedded-webserver
|
||||
physics
|
||||
)
|
||||
|
@ -15,4 +15,4 @@ if (UNIX)
|
|||
target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS})
|
||||
endif (UNIX)
|
||||
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
||||
|
|
83
cmake/macros/AutoScribeShader.cmake
Executable file
83
cmake/macros/AutoScribeShader.cmake
Executable file
|
@ -0,0 +1,83 @@
|
|||
#
|
||||
# AutoScribeShader.cmake
|
||||
#
|
||||
# Created by Sam Gateau on 12/17/14.
|
||||
# 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
|
||||
#
|
||||
|
||||
function(AUTOSCRIBE_SHADER SHADER_FILE)
|
||||
|
||||
# Grab include files
|
||||
foreach(includeFile ${ARGN})
|
||||
list(APPEND SHADER_INCLUDE_FILES ${includeFile})
|
||||
endforeach()
|
||||
|
||||
#Extract the unique include shader paths
|
||||
foreach(SHADER_INCLUDE ${SHADER_INCLUDE_FILES})
|
||||
get_filename_component(INCLUDE_DIR ${SHADER_INCLUDE} PATH)
|
||||
list(APPEND SHADER_INCLUDES_PATHS ${INCLUDE_DIR})
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
|
||||
|
||||
# make the scribe include arguments
|
||||
set(SCRIBE_INCLUDES)
|
||||
foreach(INCLUDE_PATH ${SHADER_INCLUDES_PATHS})
|
||||
set(SCRIBE_INCLUDES ${SCRIBE_INCLUDES} -I ${INCLUDE_PATH}/)
|
||||
endforeach()
|
||||
|
||||
# Define the final name of the generated shader file
|
||||
get_filename_component(SHADER_TARGET ${SHADER_FILE} NAME_WE)
|
||||
get_filename_component(SHADER_EXT ${SHADER_FILE} EXT)
|
||||
if(SHADER_EXT STREQUAL .slv)
|
||||
set(SHADER_TARGET ${SHADER_TARGET}_vert.h)
|
||||
elseif(${SHADER_EXT} STREQUAL .slf)
|
||||
set(SHADER_TARGET ${SHADER_TARGET}_frag.h)
|
||||
endif()
|
||||
|
||||
# Target dependant Custom rule on the SHADER_FILE
|
||||
if (APPLE)
|
||||
set(GLPROFILE MAC_GL)
|
||||
set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
|
||||
|
||||
add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE})
|
||||
else (APPLE)
|
||||
set(GLPROFILE PC_GL)
|
||||
set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
|
||||
|
||||
add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE})
|
||||
endif()
|
||||
|
||||
#output the generated file name
|
||||
set(AUTOSCRIBE_SHADER_RETURN ${SHADER_TARGET} PARENT_SCOPE)
|
||||
|
||||
file(GLOB INCLUDE_FILES ${SHADER_TARGET})
|
||||
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(AUTOSCRIBE_SHADER_LIB)
|
||||
|
||||
file(GLOB_RECURSE SHADER_INCLUDE_FILES src/*.slh)
|
||||
file(GLOB_RECURSE SHADER_SOURCE_FILES src/*.slv src/*.slf)
|
||||
|
||||
#message(${SHADER_INCLUDE_FILES})
|
||||
foreach(SHADER_FILE ${SHADER_SOURCE_FILES})
|
||||
AUTOSCRIBE_SHADER(${SHADER_FILE} ${SHADER_INCLUDE_FILES})
|
||||
list(APPEND AUTOSCRIBE_SHADER_SRC ${AUTOSCRIBE_SHADER_RETURN})
|
||||
endforeach()
|
||||
#message(${AUTOSCRIBE_SHADER_SRC})
|
||||
|
||||
if (WIN32)
|
||||
source_group("Shaders" FILES ${SHADER_INCLUDE_FILES})
|
||||
source_group("Shaders" FILES ${SHADER_SOURCE_FILES})
|
||||
source_group("Shaders" FILES ${AUTOSCRIBE_SHADER_SRC})
|
||||
endif()
|
||||
|
||||
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${SHADER_INCLUDE_FILES})
|
||||
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${SHADER_SOURCE_FILES})
|
||||
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${AUTOSCRIBE_SHADER_SRC})
|
||||
|
||||
endmacro()
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# LinkSharedDependencies.cmake
|
||||
# IncludeDependencyIncludes.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
# Copyright 2014 High Fidelity, Inc.
|
||||
|
@ -9,7 +9,7 @@
|
|||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(LINK_SHARED_DEPENDENCIES)
|
||||
macro(INCLUDE_DEPENDENCY_INCLUDES)
|
||||
if (${TARGET_NAME}_DEPENDENCY_INCLUDES)
|
||||
list(REMOVE_DUPLICATES ${TARGET_NAME}_DEPENDENCY_INCLUDES)
|
||||
|
||||
|
@ -19,4 +19,4 @@ macro(LINK_SHARED_DEPENDENCIES)
|
|||
|
||||
# set the property on this target so it can be retreived by targets linking to us
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_INCLUDES "${${TARGET_NAME}_DEPENDENCY_INCLUDES}")
|
||||
endmacro(LINK_SHARED_DEPENDENCIES)
|
||||
endmacro(INCLUDE_DEPENDENCY_INCLUDES)
|
|
@ -16,7 +16,7 @@ macro(SETUP_HIFI_LIBRARY)
|
|||
set(LIB_SRCS ${LIB_SRCS})
|
||||
|
||||
# create a library and set the property so it can be referenced later
|
||||
add_library(${TARGET_NAME} ${LIB_SRCS} ${AUTOMTC_SRC})
|
||||
add_library(${TARGET_NAME} ${LIB_SRCS} ${AUTOMTC_SRC} ${AUTOSCRIBE_SHADER_LIB_SRC})
|
||||
|
||||
set(${TARGET_NAME}_DEPENDENCY_QT_MODULES ${ARGN})
|
||||
list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES Core)
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
#
|
||||
# FindGLUT.cmake
|
||||
#
|
||||
# Try to find GLUT library and include path.
|
||||
# Once done this will define
|
||||
#
|
||||
# GLUT_FOUND
|
||||
# GLUT_INCLUDE_DIRS
|
||||
# GLUT_LIBRARIES
|
||||
#
|
||||
# Created on 2/6/2014 by Stephen Birarda
|
||||
# Copyright 2014 High Fidelity, Inc.
|
||||
#
|
||||
# Adapted from FindGLUT.cmake available in tlorach's OpenGLText Repository
|
||||
# https://raw.github.com/tlorach/OpenGLText/master/cmake/FindGLUT.cmake
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
|
||||
hifi_library_search_hints("freeglut")
|
||||
|
||||
if (WIN32)
|
||||
set(GLUT_HINT_DIRS "${FREEGLUT_SEARCH_DIRS} ${OPENGL_INCLUDE_DIR}")
|
||||
|
||||
find_path(GLUT_INCLUDE_DIRS GL/glut.h PATH_SUFFIXES include HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
find_library(GLUT_LIBRARY freeglut PATH_SUFFIXES lib HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
else ()
|
||||
find_path(GLUT_INCLUDE_DIRS GL/glut.h PATH_SUFFIXES include HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
find_library(GLUT_LIBRARY glut PATH_SUFFIXES lib HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
endif ()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
set(GLUT_LIBRARIES "${GLUT_LIBRARY}" "${XMU_LIBRARY}" "${XI_LIBRARY}")
|
||||
|
||||
if (UNIX)
|
||||
find_library(XI_LIBRARY Xi PATH_SUFFIXES lib HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
find_library(XMU_LIBRARY Xmu PATH_SUFFIXES lib HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
|
||||
find_package_handle_standard_args(GLUT DEFAULT_MSG GLUT_INCLUDE_DIRS GLUT_LIBRARIES XI_LIBRARY XMU_LIBRARY)
|
||||
else ()
|
||||
find_package_handle_standard_args(GLUT DEFAULT_MSG GLUT_INCLUDE_DIRS GLUT_LIBRARIES)
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(GLUT_INCLUDE_DIRS GLUT_LIBRARIES GLUT_LIBRARY XI_LIBRARY XMU_LIBRARY FREEGLUT_SEARCH_DIRS)
|
|
@ -52,4 +52,4 @@ include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
|
|||
# append OpenSSL to our list of libraries to link
|
||||
target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES})
|
||||
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
|
@ -494,8 +494,12 @@ var mouseHasMovedSincePress = false;
|
|||
|
||||
function mousePressEvent(event) {
|
||||
mouseHasMovedSincePress = false;
|
||||
mouseCapturedByTool = false;
|
||||
|
||||
if (toolBar.mousePressEvent(event) || cameraManager.mousePressEvent(event) || progressDialog.mousePressEvent(event)) {
|
||||
if (toolBar.mousePressEvent(event) || cameraManager.mousePressEvent(event)
|
||||
|| progressDialog.mousePressEvent(event) || gridTool.mousePressEvent(event)) {
|
||||
|
||||
mouseCapturedByTool = true;
|
||||
return;
|
||||
}
|
||||
if (isActive) {
|
||||
|
@ -519,6 +523,7 @@ function mousePressEvent(event) {
|
|||
}
|
||||
|
||||
var highlightedEntityID = { isKnownID: false };
|
||||
var mouseCapturedByTool = false;
|
||||
|
||||
function mouseMoveEvent(event) {
|
||||
mouseHasMovedSincePress = true;
|
||||
|
@ -563,6 +568,9 @@ function mouseReleaseEvent(event) {
|
|||
if (isActive && selectionManager.hasSelection()) {
|
||||
tooltip.show(false);
|
||||
}
|
||||
if (mouseCapturedByTool) {
|
||||
return;
|
||||
}
|
||||
|
||||
cameraManager.mouseReleaseEvent(event);
|
||||
|
||||
|
|
|
@ -13,34 +13,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function(){
|
||||
this.oldColor = {};
|
||||
this.oldColorKnown = false;
|
||||
this.storeOldColor = function(entityID) {
|
||||
var oldProperties = Entities.getEntityProperties(entityID);
|
||||
this.oldColor = oldProperties.color;
|
||||
this.oldColorKnown = true;
|
||||
print("storing old color... this.oldColor=" + this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue);
|
||||
};
|
||||
|
||||
this.preload = function(entityID) {
|
||||
print("preload");
|
||||
this.storeOldColor(entityID);
|
||||
};
|
||||
|
||||
this.hoverEnterEntity = function(entityID, mouseEvent) {
|
||||
print("hoverEnterEntity");
|
||||
if (!this.oldColorKnown) {
|
||||
this.storeOldColor(entityID);
|
||||
}
|
||||
Entities.editEntity(entityID, { color: { red: 0, green: 255, blue: 255} });
|
||||
};
|
||||
this.hoverLeaveEntity = function(entityID, mouseEvent) {
|
||||
print("hoverLeaveEntity");
|
||||
if (this.oldColorKnown) {
|
||||
print("leave restoring old color... this.oldColor="
|
||||
+ this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue);
|
||||
Entities.editEntity(entityID, { color: this.oldColor });
|
||||
}
|
||||
};
|
||||
})
|
||||
(function() {
|
||||
Script.include("changeColorOnHoverClass.js");
|
||||
return new ChangeColorOnHover();
|
||||
})
|
||||
|
|
55
examples/entityScripts/changeColorOnHoverClass.js
Normal file
55
examples/entityScripts/changeColorOnHoverClass.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// changeColorOnHover.js
|
||||
// examples/entityScripts
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 11/1/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// This is an example of an entity script which when assigned to a non-model entity like a box or sphere, will
|
||||
// change the color of the entity when you hover over it. This script uses the JavaScript prototype/class functionality
|
||||
// to construct an object that has methods for hoverEnterEntity and hoverLeaveEntity;
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
ChangeColorOnHover = function(){
|
||||
this.oldColor = {};
|
||||
this.oldColorKnown = false;
|
||||
};
|
||||
|
||||
ChangeColorOnHover.prototype = {
|
||||
|
||||
storeOldColor: function(entityID) {
|
||||
var oldProperties = Entities.getEntityProperties(entityID);
|
||||
this.oldColor = oldProperties.color;
|
||||
this.oldColorKnown = true;
|
||||
print("storing old color... this.oldColor=" + this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue);
|
||||
},
|
||||
|
||||
preload: function(entityID) {
|
||||
print("preload");
|
||||
this.storeOldColor(entityID);
|
||||
},
|
||||
|
||||
hoverEnterEntity: function(entityID, mouseEvent) {
|
||||
print("hoverEnterEntity");
|
||||
if (!this.oldColorKnown) {
|
||||
this.storeOldColor(entityID);
|
||||
}
|
||||
Entities.editEntity(entityID, { color: { red: 0, green: 255, blue: 255} });
|
||||
},
|
||||
|
||||
|
||||
hoverLeaveEntity: function(entityID, mouseEvent) {
|
||||
print("hoverLeaveEntity");
|
||||
if (this.oldColorKnown) {
|
||||
print("leave restoring old color... this.oldColor="
|
||||
+ this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue);
|
||||
Entities.editEntity(entityID, { color: this.oldColor });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -27,10 +27,12 @@
|
|||
};
|
||||
|
||||
this.enterEntity = function(entityID) {
|
||||
print("enterEntity("+entityID.id+")");
|
||||
playSound();
|
||||
};
|
||||
|
||||
this.leaveEntity = function(entityID) {
|
||||
print("leaveEntity("+entityID.id+")");
|
||||
playSound();
|
||||
};
|
||||
})
|
||||
|
|
|
@ -1,167 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script>
|
||||
function loaded() {
|
||||
var gridColor = { red: 0, green: 0, blue: 0 };
|
||||
var gridColors = [
|
||||
{ red: 0, green: 0, blue: 0 },
|
||||
{ red: 255, green: 255, blue: 255 },
|
||||
{ red: 255, green: 0, blue: 0 },
|
||||
{ red: 0, green: 255, blue: 0},
|
||||
{ red: 0, green: 0, blue: 255 },
|
||||
];
|
||||
|
||||
elPosY = document.getElementById("horiz-y");
|
||||
elMinorSpacing = document.getElementById("minor-spacing");
|
||||
elMajorSpacing = document.getElementById("major-spacing");
|
||||
elSnapToGrid = document.getElementById("snap-to-grid");
|
||||
elHorizontalGridVisible = document.getElementById("horiz-grid-visible");
|
||||
elMoveToSelection = document.getElementById("move-to-selection");
|
||||
elMoveToAvatar = document.getElementById("move-to-avatar");
|
||||
|
||||
if (window.EventBridge !== undefined) {
|
||||
EventBridge.scriptEventReceived.connect(function(data) {
|
||||
data = JSON.parse(data);
|
||||
|
||||
if (data.origin) {
|
||||
var origin = data.origin;
|
||||
elPosY.value = origin.y.toFixed(2);
|
||||
}
|
||||
|
||||
if (data.minorGridSpacing !== undefined) {
|
||||
elMinorSpacing.value = data.minorGridSpacing;
|
||||
}
|
||||
|
||||
if (data.majorGridEvery !== undefined) {
|
||||
elMajorSpacing.value = data.majorGridEvery;
|
||||
}
|
||||
|
||||
if (data.gridColor) {
|
||||
gridColor = data.gridColor;
|
||||
}
|
||||
|
||||
if (data.snapToGrid !== undefined) {
|
||||
elSnapToGrid.checked = data.snapToGrid == true;
|
||||
}
|
||||
|
||||
if (data.visible !== undefined) {
|
||||
elHorizontalGridVisible.checked = data.visible == true;
|
||||
}
|
||||
});
|
||||
|
||||
function emitUpdate() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "update",
|
||||
origin: {
|
||||
y: elPosY.value,
|
||||
},
|
||||
minorGridSpacing: elMinorSpacing.value,
|
||||
majorGridEvery: elMajorSpacing.value,
|
||||
gridColor: gridColor,
|
||||
snapToGrid: elSnapToGrid.checked,
|
||||
visible: elHorizontalGridVisible.checked,
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
elPosY.addEventListener("change", emitUpdate);
|
||||
elMinorSpacing.addEventListener("change", emitUpdate);
|
||||
elMajorSpacing.addEventListener("change", emitUpdate);
|
||||
elSnapToGrid.addEventListener("change", emitUpdate);
|
||||
elHorizontalGridVisible.addEventListener("change", emitUpdate);
|
||||
|
||||
elMoveToAvatar.addEventListener("click", function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "action",
|
||||
action: "moveToAvatar",
|
||||
}));
|
||||
});
|
||||
elMoveToSelection.addEventListener("click", function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "action",
|
||||
action: "moveToSelection",
|
||||
}));
|
||||
});
|
||||
|
||||
var gridColorBox = document.getElementById('grid-color');
|
||||
|
||||
for (var i = 0; i < gridColors.length; i++) {
|
||||
var colors = gridColors[i];
|
||||
var box = document.createElement('div');
|
||||
box.setAttribute('class', 'color-box');
|
||||
box.style.background = 'rgb(' + colors.red + ', ' + colors.green + ', ' + colors.blue + ')';
|
||||
document.getElementById("grid-colors").appendChild(box);
|
||||
box.addEventListener("click", function(color) {
|
||||
return function() {
|
||||
gridColor = color;
|
||||
emitUpdate();
|
||||
}
|
||||
}({ red: colors.red, green: colors.green, blue: colors.blue }));
|
||||
}
|
||||
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'init' }));
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload='loaded();'>
|
||||
<div class="section-header">
|
||||
<label>Horizontal Grid</label>
|
||||
</div>
|
||||
|
||||
<div class="grid-section">
|
||||
|
||||
<div class="property-section">
|
||||
<label>Visible</label>
|
||||
<span>
|
||||
<input type='checkbox' id="horiz-grid-visible">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Snap to grid</label>
|
||||
<span>
|
||||
<input type='checkbox' id="snap-to-grid">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div id="horizontal-position" class="property-section">
|
||||
<label>Position (Y Axis)</label>
|
||||
<span>
|
||||
<input type='number' id="horiz-y" class="number" value="0.0" step="0.1"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Minor Grid Size</label>
|
||||
<span>
|
||||
<input type='number' id="minor-spacing" min="0" step="0.01", ></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Major Grid Every</label>
|
||||
<span>
|
||||
<input type='number' id="major-spacing" min="2" step="1", ></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Grid Color</label>
|
||||
<span id="grid-colors"></span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<span>
|
||||
<input type="button" id="move-to-selection" value="Move to Selection">
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<span>
|
||||
<input type="button" id="move-to-avatar" value="Move to Avatar">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,35 +1,35 @@
|
|||
Grid = function(opts) {
|
||||
var that = {};
|
||||
|
||||
var color = { red: 100, green: 152, blue: 203 };
|
||||
var gridColor = { red: 100, green: 152, blue: 203 };
|
||||
var colors = [
|
||||
{ red: 0, green: 255, blue: 0 },
|
||||
{ red: 255, green: 255, blue: 255 },
|
||||
{ red: 0, green: 0, blue: 0 },
|
||||
{ red: 0, green: 0, blue: 255 },
|
||||
{ red: 255, green: 0, blue: 0 },
|
||||
];
|
||||
var colorIndex = 0;
|
||||
var gridAlpha = 1.0;
|
||||
var origin = { x: 0, y: 0, z: 0 };
|
||||
var majorGridEvery = 5;
|
||||
var minorGridSpacing = 0.2;
|
||||
var minorGridWidth = 0.2;
|
||||
var halfSize = 40;
|
||||
var yOffset = 0.001;
|
||||
|
||||
var worldSize = 16384;
|
||||
|
||||
var minorGridWidth = 0.5;
|
||||
var majorGridWidth = 1.5;
|
||||
|
||||
var snapToGrid = false;
|
||||
|
||||
var gridOverlay = Overlays.addOverlay("grid", {
|
||||
position: { x: 0 , y: 0, z: 0 },
|
||||
visible: true,
|
||||
color: { red: 0, green: 0, blue: 128 },
|
||||
color: colors[0],
|
||||
alpha: 1.0,
|
||||
rotation: Quat.fromPitchYawRollDegrees(90, 0, 0),
|
||||
minorGridWidth: 0.1,
|
||||
majorGridEvery: 2,
|
||||
});
|
||||
|
||||
that.getMinorIncrement = function() { return minorGridSpacing; };
|
||||
that.getMajorIncrement = function() { return minorGridSpacing * majorGridEvery; };
|
||||
|
||||
that.visible = false;
|
||||
that.enabled = false;
|
||||
|
||||
|
@ -37,13 +37,39 @@ Grid = function(opts) {
|
|||
return origin;
|
||||
}
|
||||
|
||||
that.getMinorIncrement = function() { return minorGridWidth; };
|
||||
that.getMajorIncrement = function() { return minorGridWidth * majorGridEvery; };
|
||||
|
||||
that.getMinorGridWidth = function() { return minorGridWidth; };
|
||||
that.setMinorGridWidth = function(value) {
|
||||
minorGridWidth = value;
|
||||
updateGrid();
|
||||
};
|
||||
|
||||
that.getMajorGridEvery = function() { return majorGridEvery; };
|
||||
that.setMajorGridEvery = function(value) {
|
||||
majorGridEvery = value;
|
||||
updateGrid();
|
||||
};
|
||||
|
||||
that.getColorIndex = function() { return colorIndex; };
|
||||
that.setColorIndex = function(value) {
|
||||
colorIndex = value;
|
||||
updateGrid();
|
||||
};
|
||||
|
||||
that.getSnapToGrid = function() { return snapToGrid; };
|
||||
that.setSnapToGrid = function(value) {
|
||||
snapToGrid = value;
|
||||
that.emitUpdate();
|
||||
};
|
||||
|
||||
that.setEnabled = function(enabled) {
|
||||
that.enabled = enabled;
|
||||
updateGrid();
|
||||
}
|
||||
|
||||
that.getVisible = function() { return that.visible; };
|
||||
that.setVisible = function(visible, noUpdate) {
|
||||
that.visible = visible;
|
||||
updateGrid();
|
||||
|
@ -78,7 +104,7 @@ Grid = function(opts) {
|
|||
dimensions = { x: 0, y: 0, z: 0 };
|
||||
}
|
||||
|
||||
var spacing = majorOnly ? (minorGridSpacing * majorGridEvery) : minorGridSpacing;
|
||||
var spacing = majorOnly ? (minorGridWidth * majorGridEvery) : minorGridWidth;
|
||||
|
||||
position = Vec3.subtract(position, origin);
|
||||
|
||||
|
@ -94,7 +120,7 @@ Grid = function(opts) {
|
|||
return delta;
|
||||
}
|
||||
|
||||
var spacing = majorOnly ? (minorGridSpacing * majorGridEvery) : minorGridSpacing;
|
||||
var spacing = majorOnly ? (minorGridWidth * majorGridEvery) : minorGridWidth;
|
||||
|
||||
var snappedDelta = {
|
||||
x: Math.round(delta.x / spacing) * spacing,
|
||||
|
@ -121,12 +147,11 @@ Grid = function(opts) {
|
|||
if (that.onUpdate) {
|
||||
that.onUpdate({
|
||||
origin: origin,
|
||||
minorGridSpacing: minorGridSpacing,
|
||||
minorGridWidth: minorGridWidth,
|
||||
majorGridEvery: majorGridEvery,
|
||||
gridSize: halfSize,
|
||||
visible: that.visible,
|
||||
snapToGrid: snapToGrid,
|
||||
gridColor: gridColor,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -144,16 +169,16 @@ Grid = function(opts) {
|
|||
that.setPosition(pos, true);
|
||||
}
|
||||
|
||||
if (data.minorGridSpacing) {
|
||||
minorGridSpacing = data.minorGridSpacing;
|
||||
if (data.minorGridWidth) {
|
||||
minorGridWidth = data.minorGridWidth;
|
||||
}
|
||||
|
||||
if (data.majorGridEvery) {
|
||||
majorGridEvery = data.majorGridEvery;
|
||||
}
|
||||
|
||||
if (data.gridColor) {
|
||||
gridColor = data.gridColor;
|
||||
if (data.colorIndex !== undefined) {
|
||||
colorIndex = data.colorIndex;
|
||||
}
|
||||
|
||||
if (data.gridSize) {
|
||||
|
@ -171,10 +196,10 @@ Grid = function(opts) {
|
|||
Overlays.editOverlay(gridOverlay, {
|
||||
position: { x: origin.y, y: origin.y, z: -origin.y },
|
||||
visible: that.visible && that.enabled,
|
||||
minorGridWidth: minorGridSpacing,
|
||||
minorGridWidth: minorGridWidth,
|
||||
majorGridEvery: majorGridEvery,
|
||||
color: gridColor,
|
||||
alpha: gridAlpha,
|
||||
color: colors[colorIndex],
|
||||
alpha: gridAlpha,
|
||||
});
|
||||
|
||||
that.emitUpdate();
|
||||
|
@ -199,46 +224,269 @@ Grid = function(opts) {
|
|||
GridTool = function(opts) {
|
||||
var that = {};
|
||||
|
||||
var UI_URL = HIFI_PUBLIC_BUCKET + "images/tools/grid-toolbar.svg";
|
||||
var UI_WIDTH = 854;
|
||||
var UI_HEIGHT = 37;
|
||||
|
||||
var horizontalGrid = opts.horizontalGrid;
|
||||
var verticalGrid = opts.verticalGrid;
|
||||
var listeners = [];
|
||||
|
||||
var url = Script.resolvePath('html/gridControls.html');
|
||||
var webView = new WebWindow('Grid', url, 200, 280);
|
||||
var uiOverlays = {};
|
||||
var allOverlays = [];
|
||||
|
||||
horizontalGrid.addListener(function(data) {
|
||||
webView.eventBridge.emitScriptEvent(JSON.stringify(data));
|
||||
selectionDisplay.updateHandles();
|
||||
});
|
||||
function addUIOverlay(key, overlay, x, y, width, height) {
|
||||
uiOverlays[key] = {
|
||||
overlay: overlay,
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height,
|
||||
};
|
||||
allOverlays.push(overlay);
|
||||
}
|
||||
|
||||
webView.eventBridge.webEventReceived.connect(function(data) {
|
||||
data = JSON.parse(data);
|
||||
if (data.type == "init") {
|
||||
horizontalGrid.emitUpdate();
|
||||
} else if (data.type == "update") {
|
||||
horizontalGrid.update(data);
|
||||
for (var i = 0; i < listeners.length; i++) {
|
||||
listeners[i](data);
|
||||
}
|
||||
} else if (data.type == "action") {
|
||||
var action = data.action;
|
||||
if (action == "moveToAvatar") {
|
||||
grid.setPosition(MyAvatar.position);
|
||||
} else if (action == "moveToSelection") {
|
||||
var newPosition = selectionManager.worldPosition;
|
||||
newPosition = Vec3.subtract(newPosition, { x: 0, y: selectionManager.worldDimensions.y * 0.5, z: 0 });
|
||||
grid.setPosition(newPosition);
|
||||
}
|
||||
var lastKnownWindowWidth = null;
|
||||
function repositionUI() {
|
||||
if (lastKnownWindowWidth == Window.innerWidth) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
that.addListener = function(callback) {
|
||||
listeners.push(callback);
|
||||
lastKnownWindowWidth = Window.innerWidth;
|
||||
var x = Window.innerWidth / 2 - UI_WIDTH / 2;
|
||||
var y = 10;
|
||||
|
||||
for (var key in uiOverlays) {
|
||||
info = uiOverlays[key];
|
||||
Overlays.editOverlay(info.overlay, {
|
||||
x: x + info.x,
|
||||
y: y + info.y,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// "Spritesheet" is laid out horizontally in this order
|
||||
var UI_SPRITE_LIST = [
|
||||
{ name: "gridText", width: 54 },
|
||||
{ name: "visibleCheckbox", width: 60 },
|
||||
{ name: "snapToGridCheckbox", width: 105 },
|
||||
|
||||
{ name: "color0", width: 27 },
|
||||
{ name: "color1", width: 27 },
|
||||
{ name: "color2", width: 27 },
|
||||
{ name: "color3", width: 27 },
|
||||
{ name: "color4", width: 27 },
|
||||
|
||||
{ name: "minorGridIcon", width: 34 },
|
||||
{ name: "minorGridDecrease", width: 25 },
|
||||
{ name: "minorGridInput", width: 26 },
|
||||
{ name: "minorGridIncrease", width: 25 },
|
||||
|
||||
{ name: "majorGridIcon", width: 40 },
|
||||
{ name: "majorGridDecrease", width: 25 },
|
||||
{ name: "majorGridInput", width: 26 },
|
||||
{ name: "majorGridIncrease", width: 25 },
|
||||
|
||||
{ name: "yPositionLabel", width: 160 },
|
||||
{ name: "moveToLabel", width: 54 },
|
||||
{ name: "moveToAvatar", width: 26 },
|
||||
{ name: "moveToSelection", width: 34 },
|
||||
];
|
||||
|
||||
// Add all overlays from spritesheet
|
||||
var baseOverlay = null;
|
||||
var x = 0;
|
||||
for (var i = 0; i < UI_SPRITE_LIST.length; i++) {
|
||||
var info = UI_SPRITE_LIST[i];
|
||||
|
||||
var props = {
|
||||
imageURL: UI_URL,
|
||||
subImage: { x: x, y: 0, width: info.width, height: UI_HEIGHT },
|
||||
width: info.width,
|
||||
height: UI_HEIGHT,
|
||||
alpha: 1.0,
|
||||
visible: false,
|
||||
};
|
||||
|
||||
var overlay;
|
||||
if (baseOverlay == null) {
|
||||
overlay = Overlays.addOverlay("image", {
|
||||
imageURL: UI_URL,
|
||||
});
|
||||
baseOverlay = overlay;
|
||||
} else {
|
||||
overlay = Overlays.cloneOverlay(baseOverlay);
|
||||
}
|
||||
|
||||
Overlays.editOverlay(overlay, props);
|
||||
|
||||
addUIOverlay(info.name, overlay, x, 0, info.width, UI_HEIGHT);
|
||||
|
||||
x += info.width;
|
||||
}
|
||||
|
||||
// Add Text overlays
|
||||
var textProperties = {
|
||||
color: { red: 255, green: 255, blue: 255 },
|
||||
topMargin: 6,
|
||||
leftMargin: 4,
|
||||
alpha: 1,
|
||||
backgroundAlpha: 0,
|
||||
text: "",
|
||||
font: { size: 12 },
|
||||
visible: false,
|
||||
};
|
||||
var minorGridWidthText = Overlays.addOverlay("text", textProperties);
|
||||
var majorGridEveryText = Overlays.addOverlay("text", textProperties);
|
||||
var yPositionText = Overlays.addOverlay("text", textProperties);
|
||||
|
||||
addUIOverlay('minorGridWidthText', minorGridWidthText, 414, 8, 24, 24);
|
||||
addUIOverlay('majorGridEveryText', majorGridEveryText, 530, 8, 24, 24);
|
||||
addUIOverlay('yPositionText', yPositionText, 660, 8, 24, 24);
|
||||
|
||||
var NUM_COLORS = 5;
|
||||
function updateColorIndex(index) {
|
||||
if (index < 0 || index >= NUM_COLORS) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0 ; i < NUM_COLORS; i++) {
|
||||
var info = uiOverlays['color' + i];
|
||||
Overlays.editOverlay(info.overlay, {
|
||||
subImage: {
|
||||
x: info.x,
|
||||
y: i == index ? UI_HEIGHT : 0,
|
||||
width: info.width,
|
||||
height: info.height,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateGridVisible(value) {
|
||||
var info = uiOverlays.visibleCheckbox;
|
||||
Overlays.editOverlay(info.overlay, {
|
||||
subImage: {
|
||||
x: info.x,
|
||||
y: value ? UI_HEIGHT : 0,
|
||||
width: info.width,
|
||||
height: info.height,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateSnapToGrid(value) {
|
||||
var info = uiOverlays.snapToGridCheckbox;
|
||||
Overlays.editOverlay(info.overlay, {
|
||||
subImage: {
|
||||
x: info.x,
|
||||
y: value ? UI_HEIGHT : 0,
|
||||
width: info.width,
|
||||
height: info.height,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateMinorGridWidth(value) {
|
||||
Overlays.editOverlay(minorGridWidthText, {
|
||||
text: value.toFixed(1),
|
||||
});
|
||||
}
|
||||
|
||||
function updateMajorGridEvery(value) {
|
||||
Overlays.editOverlay(majorGridEveryText, {
|
||||
text: value,
|
||||
});
|
||||
}
|
||||
|
||||
function updateYPosition(value) {
|
||||
Overlays.editOverlay(yPositionText, {
|
||||
text: value.toFixed(2),
|
||||
});
|
||||
}
|
||||
|
||||
function updateOverlays() {
|
||||
updateGridVisible(horizontalGrid.getVisible());
|
||||
updateSnapToGrid(horizontalGrid.getSnapToGrid());
|
||||
updateColorIndex(horizontalGrid.getColorIndex());
|
||||
|
||||
updateMinorGridWidth(horizontalGrid.getMinorGridWidth());
|
||||
updateMajorGridEvery(horizontalGrid.getMajorGridEvery());
|
||||
|
||||
updateYPosition(horizontalGrid.getOrigin().y);
|
||||
}
|
||||
|
||||
that.setVisible = function(visible) {
|
||||
webView.setVisible(visible);
|
||||
for (var i = 0; i < allOverlays.length; i++) {
|
||||
Overlays.editOverlay(allOverlays[i], { visible: visible });
|
||||
}
|
||||
}
|
||||
|
||||
that.mousePressEvent = function(event) {
|
||||
var overlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y });
|
||||
|
||||
if (allOverlays.indexOf(overlay) >= 0) {
|
||||
if (overlay == uiOverlays.color0.overlay) {
|
||||
horizontalGrid.setColorIndex(0);
|
||||
} else if (overlay == uiOverlays.color1.overlay) {
|
||||
horizontalGrid.setColorIndex(1);
|
||||
} else if (overlay == uiOverlays.color2.overlay) {
|
||||
horizontalGrid.setColorIndex(2);
|
||||
} else if (overlay == uiOverlays.color3.overlay) {
|
||||
horizontalGrid.setColorIndex(3);
|
||||
} else if (overlay == uiOverlays.color4.overlay) {
|
||||
horizontalGrid.setColorIndex(4);
|
||||
} else if (overlay == uiOverlays.visibleCheckbox.overlay) {
|
||||
horizontalGrid.setVisible(!horizontalGrid.getVisible());
|
||||
} else if (overlay == uiOverlays.snapToGridCheckbox.overlay) {
|
||||
horizontalGrid.setSnapToGrid(!horizontalGrid.getSnapToGrid());
|
||||
} else if (overlay == uiOverlays.moveToAvatar.overlay) {
|
||||
horizontalGrid.setPosition(MyAvatar.position);
|
||||
} else if (overlay == uiOverlays.moveToSelection.overlay) {
|
||||
var newPosition = selectionManager.worldPosition;
|
||||
newPosition = Vec3.subtract(newPosition, { x: 0, y: selectionManager.worldDimensions.y * 0.5, z: 0 });
|
||||
horizontalGrid.setPosition(newPosition);
|
||||
} else if (overlay == uiOverlays.minorGridDecrease.overlay) {
|
||||
var newValue = Math.max(0.1, horizontalGrid.getMinorGridWidth() - 0.1);
|
||||
horizontalGrid.setMinorGridWidth(newValue);
|
||||
} else if (overlay == uiOverlays.minorGridIncrease.overlay) {
|
||||
horizontalGrid.setMinorGridWidth(horizontalGrid.getMinorGridWidth() + 0.1);
|
||||
} else if (overlay == uiOverlays.majorGridDecrease.overlay) {
|
||||
var newValue = Math.max(2, horizontalGrid.getMajorGridEvery() - 1);
|
||||
horizontalGrid.setMajorGridEvery(newValue);
|
||||
} else if (overlay == uiOverlays.majorGridIncrease.overlay) {
|
||||
horizontalGrid.setMajorGridEvery(horizontalGrid.getMajorGridEvery() + 1);
|
||||
} else if (overlay == uiOverlays.yPositionLabel.overlay) {
|
||||
var newValue = Window.prompt("Y Position:", horizontalGrid.getOrigin().y.toFixed(4));
|
||||
if (newValue !== null) {
|
||||
var y = parseFloat(newValue)
|
||||
if (isNaN(y)) {
|
||||
Window.alert("Invalid position");
|
||||
} else {
|
||||
horizontalGrid.setPosition({ x: 0, y: y, z: 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clicking anywhere within the toolbar will "consume" this press event
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
Script.scriptEnding.connect(function() {
|
||||
for (var i = 0; i < allOverlays.length; i++) {
|
||||
Overlays.deleteOverlay(allOverlays[i]);
|
||||
}
|
||||
});
|
||||
Script.update.connect(repositionUI);
|
||||
|
||||
horizontalGrid.addListener(function() {
|
||||
selectionDisplay.updateHandles();
|
||||
updateOverlays();
|
||||
});
|
||||
|
||||
updateOverlays();
|
||||
repositionUI();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
|
|
@ -274,19 +274,11 @@ modelUploader = (function () {
|
|||
}
|
||||
}
|
||||
|
||||
if (view.string(0, 18) === "Kaydara FBX Binary") {
|
||||
previousNodeFilename = "";
|
||||
|
||||
index = 27;
|
||||
while (index < view.byteLength - 39 && !EOF) {
|
||||
parseBinaryFBX();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
readTextFBX();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function readModel() {
|
||||
|
|
|
@ -6,4 +6,4 @@ setup_hifi_project(Network)
|
|||
# link the shared hifi libraries
|
||||
link_hifi_libraries(networking shared)
|
||||
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
|
@ -107,7 +107,7 @@ endif()
|
|||
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM})
|
||||
|
||||
# link required hifi libraries
|
||||
link_hifi_libraries(shared octree voxels gpu fbx metavoxels networking entities avatars audio animation script-engine physics
|
||||
link_hifi_libraries(shared octree voxels gpu model fbx metavoxels networking entities avatars audio animation script-engine physics
|
||||
render-utils entities-renderer)
|
||||
|
||||
# find any optional and required libraries
|
||||
|
@ -194,11 +194,10 @@ if (APPLE)
|
|||
# link in required OS X frameworks and include the right GL headers
|
||||
find_library(CoreAudio CoreAudio)
|
||||
find_library(CoreFoundation CoreFoundation)
|
||||
find_library(GLUT GLUT)
|
||||
find_library(OpenGL OpenGL)
|
||||
find_library(AppKit AppKit)
|
||||
|
||||
target_link_libraries(${TARGET_NAME} ${CoreAudio} ${CoreFoundation} ${GLUT} ${OpenGL} ${AppKit})
|
||||
target_link_libraries(${TARGET_NAME} ${CoreAudio} ${CoreFoundation} ${OpenGL} ${AppKit})
|
||||
|
||||
# install command for OS X bundle
|
||||
INSTALL(TARGETS ${TARGET_NAME}
|
||||
|
@ -214,15 +213,12 @@ else (APPLE)
|
|||
)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(GLUT REQUIRED)
|
||||
|
||||
include_directories(SYSTEM "${GLUT_INCLUDE_DIRS}")
|
||||
|
||||
if (${OPENGL_INCLUDE_DIR})
|
||||
include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}")
|
||||
endif ()
|
||||
|
||||
target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}" "${GLUT_LIBRARIES}")
|
||||
target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}")
|
||||
|
||||
# link target to external libraries
|
||||
if (WIN32)
|
||||
|
@ -246,4 +242,4 @@ else (APPLE)
|
|||
endif (APPLE)
|
||||
|
||||
# link any dependencies bubbled up from our linked dependencies
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -130,7 +130,7 @@ static QTimer* idleTimer = NULL;
|
|||
const QString CHECK_VERSION_URL = "https://highfidelity.io/latestVersion.xml";
|
||||
const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/hifi.skipversion";
|
||||
|
||||
const QString DEFAULT_SCRIPTS_JS_URL = "http://public.highfidelity.io/scripts/defaultScripts.js";
|
||||
const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js";
|
||||
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
||||
QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message);
|
||||
|
@ -3626,16 +3626,6 @@ void Application::setMenuShortcutsEnabled(bool enabled) {
|
|||
setShortcutsEnabled(_window->menuBar(), enabled);
|
||||
}
|
||||
|
||||
void Application::uploadModel(ModelType modelType) {
|
||||
ModelUploader* uploader = new ModelUploader(modelType);
|
||||
QThread* thread = new QThread();
|
||||
thread->connect(uploader, SIGNAL(destroyed()), SLOT(quit()));
|
||||
thread->connect(thread, SIGNAL(finished()), SLOT(deleteLater()));
|
||||
uploader->connect(thread, SIGNAL(started()), SLOT(send()));
|
||||
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void Application::updateWindowTitle(){
|
||||
|
||||
QString buildVersion = " (build " + applicationVersion() + ")";
|
||||
|
@ -4191,15 +4181,19 @@ void Application::toggleRunningScriptsWidget() {
|
|||
}
|
||||
|
||||
void Application::uploadHead() {
|
||||
uploadModel(HEAD_MODEL);
|
||||
ModelUploader::uploadHead();
|
||||
}
|
||||
|
||||
void Application::uploadSkeleton() {
|
||||
uploadModel(SKELETON_MODEL);
|
||||
ModelUploader::uploadSkeleton();
|
||||
}
|
||||
|
||||
void Application::uploadAttachment() {
|
||||
uploadModel(ATTACHMENT_MODEL);
|
||||
ModelUploader::uploadAttachment();
|
||||
}
|
||||
|
||||
void Application::uploadEntity() {
|
||||
ModelUploader::uploadEntity();
|
||||
}
|
||||
|
||||
void Application::openUrl(const QUrl& url) {
|
||||
|
|
|
@ -374,6 +374,7 @@ public slots:
|
|||
void uploadHead();
|
||||
void uploadSkeleton();
|
||||
void uploadAttachment();
|
||||
void uploadEntity();
|
||||
|
||||
void openUrl(const QUrl& url);
|
||||
|
||||
|
@ -459,8 +460,6 @@ private:
|
|||
|
||||
void setMenuShortcutsEnabled(bool enabled);
|
||||
|
||||
void uploadModel(ModelType modelType);
|
||||
|
||||
static void attachNewHeadToNode(Node *newNode);
|
||||
static void* networkReceive(void* args); // network receive thread
|
||||
|
||||
|
|
|
@ -1306,21 +1306,13 @@ void Audio::renderToolBox(int x, int y, bool boxed) {
|
|||
} else {
|
||||
glColor3f(0.41f, 0.41f, 0.41f);
|
||||
}
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex2f(boxBounds.left(), boxBounds.top());
|
||||
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex2f(boxBounds.right(), boxBounds.top());
|
||||
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2f(boxBounds.right(), boxBounds.bottom());
|
||||
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex2f(boxBounds.left(), boxBounds.bottom());
|
||||
|
||||
glEnd();
|
||||
glm::vec2 topLeft(boxBounds.left(), boxBounds.top());
|
||||
glm::vec2 bottomRight(boxBounds.right(), boxBounds.bottom());
|
||||
glm::vec2 texCoordTopLeft(1,1);
|
||||
glm::vec2 texCoordBottomRight(0,0);
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
|
||||
}
|
||||
|
||||
_iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE);
|
||||
|
@ -1345,21 +1337,14 @@ void Audio::renderToolBox(int x, int y, bool boxed) {
|
|||
}
|
||||
|
||||
glColor3f(_iconColor, _iconColor, _iconColor);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glm::vec2 topLeft(_iconBounds.left(), _iconBounds.top());
|
||||
glm::vec2 bottomRight(_iconBounds.right(), _iconBounds.bottom());
|
||||
glm::vec2 texCoordTopLeft(1,1);
|
||||
glm::vec2 texCoordBottomRight(0,0);
|
||||
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex2f(_iconBounds.left(), _iconBounds.top());
|
||||
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex2f(_iconBounds.right(), _iconBounds.top());
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(_iconBounds.right(), _iconBounds.bottom());
|
||||
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex2f(_iconBounds.left(), _iconBounds.bottom());
|
||||
|
||||
glEnd();
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
|
||||
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
@ -1702,14 +1687,7 @@ void Audio::renderScope(int width, int height) {
|
|||
void Audio::renderBackground(const float* color, int x, int y, int width, int height) {
|
||||
|
||||
glColor4fv(color);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x + width, y);
|
||||
glVertex2i(x + width, y + height);
|
||||
glVertex2i(x , y + height);
|
||||
|
||||
glEnd();
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(x, y, width, height);
|
||||
glColor4f(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,11 +12,12 @@
|
|||
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include "Hair.h"
|
||||
|
||||
#include "Util.h"
|
||||
#include "world.h"
|
||||
|
||||
#include "Hair.h"
|
||||
|
||||
|
||||
const float HAIR_DAMPING = 0.99f;
|
||||
const float CONSTRAINT_RELAXATION = 10.0f;
|
||||
const float HAIR_ACCELERATION_COUPLING = 0.045f;
|
||||
|
|
|
@ -189,10 +189,14 @@ Menu::Menu() :
|
|||
SLOT(toggleAddressBar()));
|
||||
|
||||
addDisabledActionAndSeparator(fileMenu, "Upload Avatar Model");
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadHead, 0, Application::getInstance(), SLOT(uploadHead()));
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadSkeleton, 0, Application::getInstance(), SLOT(uploadSkeleton()));
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadHead, 0,
|
||||
Application::getInstance(), SLOT(uploadHead()));
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadSkeleton, 0,
|
||||
Application::getInstance(), SLOT(uploadSkeleton()));
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadAttachment, 0,
|
||||
Application::getInstance(), SLOT(uploadAttachment()));
|
||||
Application::getInstance(), SLOT(uploadAttachment()));
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadEntity, 0,
|
||||
Application::getInstance(), SLOT(uploadEntity()));
|
||||
addDisabledActionAndSeparator(fileMenu, "Settings");
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings()));
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsExport, 0, this, SLOT(exportSettings()));
|
||||
|
|
|
@ -482,6 +482,7 @@ namespace MenuOption {
|
|||
const QString TransmitterDrive = "Transmitter Drive";
|
||||
const QString TurnWithHead = "Turn using Head";
|
||||
const QString UploadAttachment = "Upload Attachment Model";
|
||||
const QString UploadEntity = "Upload Entity Model";
|
||||
const QString UploadHead = "Upload Head Model";
|
||||
const QString UploadSkeleton = "Upload Skeleton Model";
|
||||
const QString UserInterface = "User Interface";
|
||||
|
|
|
@ -55,7 +55,8 @@ static const QString MODEL_URL = "/api/v1/models";
|
|||
|
||||
static const QString SETTING_NAME = "LastModelUploadLocation";
|
||||
|
||||
static const int MAX_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||
static const long long BYTES_PER_MEGABYTES = 1024 * 1024;
|
||||
static const unsigned long long MAX_SIZE = 50 * 1024 * BYTES_PER_MEGABYTES; // 50 GB (Virtually remove limit)
|
||||
static const int MAX_TEXTURE_SIZE = 1024;
|
||||
static const int TIMEOUT = 1000;
|
||||
static const int MAX_CHECK = 30;
|
||||
|
@ -63,6 +64,32 @@ static const int MAX_CHECK = 30;
|
|||
static const int QCOMPRESS_HEADER_POSITION = 0;
|
||||
static const int QCOMPRESS_HEADER_SIZE = 4;
|
||||
|
||||
void ModelUploader::uploadModel(ModelType modelType) {
|
||||
ModelUploader* uploader = new ModelUploader(modelType);
|
||||
QThread* thread = new QThread();
|
||||
thread->connect(uploader, SIGNAL(destroyed()), SLOT(quit()));
|
||||
thread->connect(thread, SIGNAL(finished()), SLOT(deleteLater()));
|
||||
uploader->connect(thread, SIGNAL(started()), SLOT(send()));
|
||||
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void ModelUploader::uploadHead() {
|
||||
uploadModel(HEAD_MODEL);
|
||||
}
|
||||
|
||||
void ModelUploader::uploadSkeleton() {
|
||||
uploadModel(SKELETON_MODEL);
|
||||
}
|
||||
|
||||
void ModelUploader::uploadAttachment() {
|
||||
uploadModel(ATTACHMENT_MODEL);
|
||||
}
|
||||
|
||||
void ModelUploader::uploadEntity() {
|
||||
uploadModel(ENTITY_MODEL);
|
||||
}
|
||||
|
||||
ModelUploader::ModelUploader(ModelType modelType) :
|
||||
_lodCount(-1),
|
||||
_texturesCount(-1),
|
||||
|
@ -148,6 +175,91 @@ bool ModelUploader::zip() {
|
|||
FBXGeometry geometry = readFBX(fbxContents, QVariantHash());
|
||||
|
||||
// make sure we have some basic mappings
|
||||
populateBasicMapping(mapping, filename, geometry);
|
||||
|
||||
// open the dialog to configure the rest
|
||||
ModelPropertiesDialog properties(_modelType, mapping, basePath, geometry);
|
||||
if (properties.exec() == QDialog::Rejected) {
|
||||
return false;
|
||||
}
|
||||
mapping = properties.getMapping();
|
||||
|
||||
QByteArray nameField = mapping.value(NAME_FIELD).toByteArray();
|
||||
QString urlBase;
|
||||
if (!nameField.isEmpty()) {
|
||||
QHttpPart textPart;
|
||||
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"model_name\"");
|
||||
textPart.setBody(nameField);
|
||||
_dataMultiPart->append(textPart);
|
||||
urlBase = S3_URL + "/models/" + MODEL_TYPE_NAMES[_modelType] + "/" + nameField;
|
||||
_url = urlBase + ".fst";
|
||||
|
||||
} else {
|
||||
QMessageBox::warning(NULL,
|
||||
QString("ModelUploader::zip()"),
|
||||
QString("Model name is missing in the .fst file."),
|
||||
QMessageBox::Ok);
|
||||
qDebug() << "[Warning] " << QString("Model name is missing in the .fst file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray texdirField = mapping.value(TEXDIR_FIELD).toByteArray();
|
||||
QString texDir;
|
||||
_textureBase = urlBase + "/textures/";
|
||||
if (!texdirField.isEmpty()) {
|
||||
texDir = basePath + "/" + texdirField;
|
||||
QFileInfo texInfo(texDir);
|
||||
if (!texInfo.exists() || !texInfo.isDir()) {
|
||||
QMessageBox::warning(NULL,
|
||||
QString("ModelUploader::zip()"),
|
||||
QString("Texture directory could not be found."),
|
||||
QMessageBox::Ok);
|
||||
qDebug() << "[Warning] " << QString("Texture directory could not be found.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QVariantHash lodField = mapping.value(LOD_FIELD).toHash();
|
||||
for (QVariantHash::const_iterator it = lodField.constBegin(); it != lodField.constEnd(); it++) {
|
||||
QFileInfo lod(basePath + "/" + it.key());
|
||||
if (!lod.exists() || !lod.isFile()) { // Check existence
|
||||
QMessageBox::warning(NULL,
|
||||
QString("ModelUploader::zip()"),
|
||||
QString("LOD file %1 could not be found.").arg(lod.fileName()),
|
||||
QMessageBox::Ok);
|
||||
qDebug() << "[Warning] " << QString("FBX file %1 could not be found.").arg(lod.fileName());
|
||||
}
|
||||
// Compress and copy
|
||||
if (!addPart(lod.filePath(), QString("lod%1").arg(++_lodCount))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Write out, compress and copy the fst
|
||||
if (!addPart(*fst, writeMapping(mapping), QString("fst"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compress and copy the fbx
|
||||
if (!addPart(fbx, fbxContents, "fbx")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!addTextures(texDir, geometry)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QHttpPart textPart;
|
||||
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data;"
|
||||
" name=\"model_category\"");
|
||||
textPart.setBody(MODEL_TYPE_NAMES[_modelType]);
|
||||
_dataMultiPart->append(textPart);
|
||||
|
||||
_readyToSend = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModelUploader::populateBasicMapping(QVariantHash& mapping, QString filename, FBXGeometry geometry) {
|
||||
if (!mapping.contains(NAME_FIELD)) {
|
||||
mapping.insert(NAME_FIELD, QFileInfo(filename).baseName());
|
||||
}
|
||||
|
@ -162,11 +274,11 @@ bool ModelUploader::zip() {
|
|||
QVariantHash joints = mapping.value(JOINT_FIELD).toHash();
|
||||
if (!joints.contains("jointEyeLeft")) {
|
||||
joints.insert("jointEyeLeft", geometry.jointIndices.contains("jointEyeLeft") ? "jointEyeLeft" :
|
||||
(geometry.jointIndices.contains("EyeLeft") ? "EyeLeft" : "LeftEye"));
|
||||
(geometry.jointIndices.contains("EyeLeft") ? "EyeLeft" : "LeftEye"));
|
||||
}
|
||||
if (!joints.contains("jointEyeRight")) {
|
||||
joints.insert("jointEyeRight", geometry.jointIndices.contains("jointEyeRight") ? "jointEyeRight" :
|
||||
geometry.jointIndices.contains("EyeRight") ? "EyeRight" : "RightEye");
|
||||
geometry.jointIndices.contains("EyeRight") ? "EyeRight" : "RightEye");
|
||||
}
|
||||
if (!joints.contains("jointNeck")) {
|
||||
joints.insert("jointNeck", geometry.jointIndices.contains("jointNeck") ? "jointNeck" : "Neck");
|
||||
|
@ -250,87 +362,6 @@ bool ModelUploader::zip() {
|
|||
blendshapes.insertMulti("Sneer", QVariantList() << "Squint_Right" << 0.5);
|
||||
mapping.insert(BLENDSHAPE_FIELD, blendshapes);
|
||||
}
|
||||
|
||||
// open the dialog to configure the rest
|
||||
ModelPropertiesDialog properties(_modelType, mapping, basePath, geometry);
|
||||
if (properties.exec() == QDialog::Rejected) {
|
||||
return false;
|
||||
}
|
||||
mapping = properties.getMapping();
|
||||
|
||||
QByteArray nameField = mapping.value(NAME_FIELD).toByteArray();
|
||||
QString urlBase;
|
||||
if (!nameField.isEmpty()) {
|
||||
QHttpPart textPart;
|
||||
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"model_name\"");
|
||||
textPart.setBody(nameField);
|
||||
_dataMultiPart->append(textPart);
|
||||
urlBase = S3_URL + "/models/" + MODEL_TYPE_NAMES[_modelType] + "/" + nameField;
|
||||
_url = urlBase + ".fst";
|
||||
|
||||
} else {
|
||||
QMessageBox::warning(NULL,
|
||||
QString("ModelUploader::zip()"),
|
||||
QString("Model name is missing in the .fst file."),
|
||||
QMessageBox::Ok);
|
||||
qDebug() << "[Warning] " << QString("Model name is missing in the .fst file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray texdirField = mapping.value(TEXDIR_FIELD).toByteArray();
|
||||
QString texDir;
|
||||
_textureBase = urlBase + "/textures/";
|
||||
if (!texdirField.isEmpty()) {
|
||||
texDir = basePath + "/" + texdirField;
|
||||
QFileInfo texInfo(texDir);
|
||||
if (!texInfo.exists() || !texInfo.isDir()) {
|
||||
QMessageBox::warning(NULL,
|
||||
QString("ModelUploader::zip()"),
|
||||
QString("Texture directory could not be found."),
|
||||
QMessageBox::Ok);
|
||||
qDebug() << "[Warning] " << QString("Texture directory could not be found.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QVariantHash lodField = mapping.value(LOD_FIELD).toHash();
|
||||
for (QVariantHash::const_iterator it = lodField.constBegin(); it != lodField.constEnd(); it++) {
|
||||
QFileInfo lod(basePath + "/" + it.key());
|
||||
if (!lod.exists() || !lod.isFile()) { // Check existence
|
||||
QMessageBox::warning(NULL,
|
||||
QString("ModelUploader::zip()"),
|
||||
QString("LOD file %1 could not be found.").arg(lod.fileName()),
|
||||
QMessageBox::Ok);
|
||||
qDebug() << "[Warning] " << QString("FBX file %1 could not be found.").arg(lod.fileName());
|
||||
}
|
||||
// Compress and copy
|
||||
if (!addPart(lod.filePath(), QString("lod%1").arg(++_lodCount))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Write out, compress and copy the fst
|
||||
if (!addPart(*fst, writeMapping(mapping), QString("fst"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compress and copy the fbx
|
||||
if (!addPart(fbx, fbxContents, "fbx")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!addTextures(texDir, geometry)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QHttpPart textPart;
|
||||
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data;"
|
||||
" name=\"model_category\"");
|
||||
textPart.setBody(MODEL_TYPE_NAMES[_modelType]);
|
||||
_dataMultiPart->append(textPart);
|
||||
|
||||
_readyToSend = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModelUploader::send() {
|
||||
|
@ -590,9 +621,9 @@ bool ModelUploader::addPart(const QFile& file, const QByteArray& contents, const
|
|||
if (_totalSize > MAX_SIZE) {
|
||||
QMessageBox::warning(NULL,
|
||||
QString("ModelUploader::zip()"),
|
||||
QString("Model too big, over %1 Bytes.").arg(MAX_SIZE),
|
||||
QString("Model too big, over %1 MB.").arg(MAX_SIZE / BYTES_PER_MEGABYTES),
|
||||
QMessageBox::Ok);
|
||||
qDebug() << "[Warning] " << QString("Model too big, over %1 Bytes.").arg(MAX_SIZE);
|
||||
qDebug() << "[Warning] " << QString("Model too big, over %1 MB.").arg(MAX_SIZE / BYTES_PER_MEGABYTES);
|
||||
return false;
|
||||
}
|
||||
qDebug() << "Current model size: " << _totalSize;
|
||||
|
@ -613,8 +644,8 @@ ModelPropertiesDialog::ModelPropertiesDialog(ModelType modelType, const QVariant
|
|||
_modelType(modelType),
|
||||
_originalMapping(originalMapping),
|
||||
_basePath(basePath),
|
||||
_geometry(geometry) {
|
||||
|
||||
_geometry(geometry)
|
||||
{
|
||||
setWindowTitle("Set Model Properties");
|
||||
|
||||
QFormLayout* form = new QFormLayout();
|
||||
|
@ -629,33 +660,35 @@ ModelPropertiesDialog::ModelPropertiesDialog(ModelType modelType, const QVariant
|
|||
_scale->setMaximum(FLT_MAX);
|
||||
_scale->setSingleStep(0.01);
|
||||
|
||||
if (_modelType == ATTACHMENT_MODEL) {
|
||||
QHBoxLayout* translation = new QHBoxLayout();
|
||||
form->addRow("Translation:", translation);
|
||||
translation->addWidget(_translationX = createTranslationBox());
|
||||
translation->addWidget(_translationY = createTranslationBox());
|
||||
translation->addWidget(_translationZ = createTranslationBox());
|
||||
form->addRow("Pivot About Center:", _pivotAboutCenter = new QCheckBox());
|
||||
form->addRow("Pivot Joint:", _pivotJoint = createJointBox());
|
||||
connect(_pivotAboutCenter, SIGNAL(toggled(bool)), SLOT(updatePivotJoint()));
|
||||
_pivotAboutCenter->setChecked(true);
|
||||
|
||||
} else {
|
||||
form->addRow("Left Eye Joint:", _leftEyeJoint = createJointBox());
|
||||
form->addRow("Right Eye Joint:", _rightEyeJoint = createJointBox());
|
||||
form->addRow("Neck Joint:", _neckJoint = createJointBox());
|
||||
}
|
||||
if (_modelType == SKELETON_MODEL) {
|
||||
form->addRow("Root Joint:", _rootJoint = createJointBox());
|
||||
form->addRow("Lean Joint:", _leanJoint = createJointBox());
|
||||
form->addRow("Head Joint:", _headJoint = createJointBox());
|
||||
form->addRow("Left Hand Joint:", _leftHandJoint = createJointBox());
|
||||
form->addRow("Right Hand Joint:", _rightHandJoint = createJointBox());
|
||||
|
||||
form->addRow("Free Joints:", _freeJoints = new QVBoxLayout());
|
||||
QPushButton* newFreeJoint = new QPushButton("New Free Joint");
|
||||
_freeJoints->addWidget(newFreeJoint);
|
||||
connect(newFreeJoint, SIGNAL(clicked(bool)), SLOT(createNewFreeJoint()));
|
||||
if (_modelType != ENTITY_MODEL) {
|
||||
if (_modelType == ATTACHMENT_MODEL) {
|
||||
QHBoxLayout* translation = new QHBoxLayout();
|
||||
form->addRow("Translation:", translation);
|
||||
translation->addWidget(_translationX = createTranslationBox());
|
||||
translation->addWidget(_translationY = createTranslationBox());
|
||||
translation->addWidget(_translationZ = createTranslationBox());
|
||||
form->addRow("Pivot About Center:", _pivotAboutCenter = new QCheckBox());
|
||||
form->addRow("Pivot Joint:", _pivotJoint = createJointBox());
|
||||
connect(_pivotAboutCenter, SIGNAL(toggled(bool)), SLOT(updatePivotJoint()));
|
||||
_pivotAboutCenter->setChecked(true);
|
||||
|
||||
} else {
|
||||
form->addRow("Left Eye Joint:", _leftEyeJoint = createJointBox());
|
||||
form->addRow("Right Eye Joint:", _rightEyeJoint = createJointBox());
|
||||
form->addRow("Neck Joint:", _neckJoint = createJointBox());
|
||||
}
|
||||
if (_modelType == SKELETON_MODEL) {
|
||||
form->addRow("Root Joint:", _rootJoint = createJointBox());
|
||||
form->addRow("Lean Joint:", _leanJoint = createJointBox());
|
||||
form->addRow("Head Joint:", _headJoint = createJointBox());
|
||||
form->addRow("Left Hand Joint:", _leftHandJoint = createJointBox());
|
||||
form->addRow("Right Hand Joint:", _rightHandJoint = createJointBox());
|
||||
|
||||
form->addRow("Free Joints:", _freeJoints = new QVBoxLayout());
|
||||
QPushButton* newFreeJoint = new QPushButton("New Free Joint");
|
||||
_freeJoints->addWidget(newFreeJoint);
|
||||
connect(newFreeJoint, SIGNAL(clicked(bool)), SLOT(createNewFreeJoint()));
|
||||
}
|
||||
}
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok |
|
||||
|
@ -683,38 +716,40 @@ QVariantHash ModelPropertiesDialog::getMapping() const {
|
|||
}
|
||||
mapping.insert(JOINT_INDEX_FIELD, jointIndices);
|
||||
|
||||
QVariantHash joints = mapping.value(JOINT_FIELD).toHash();
|
||||
if (_modelType == ATTACHMENT_MODEL) {
|
||||
glm::vec3 pivot;
|
||||
if (_pivotAboutCenter->isChecked()) {
|
||||
pivot = (_geometry.meshExtents.minimum + _geometry.meshExtents.maximum) * 0.5f;
|
||||
|
||||
} else if (_pivotJoint->currentIndex() != 0) {
|
||||
pivot = extractTranslation(_geometry.joints.at(_pivotJoint->currentIndex() - 1).transform);
|
||||
if (_modelType != ENTITY_MODEL) {
|
||||
QVariantHash joints = mapping.value(JOINT_FIELD).toHash();
|
||||
if (_modelType == ATTACHMENT_MODEL) {
|
||||
glm::vec3 pivot;
|
||||
if (_pivotAboutCenter->isChecked()) {
|
||||
pivot = (_geometry.meshExtents.minimum + _geometry.meshExtents.maximum) * 0.5f;
|
||||
|
||||
} else if (_pivotJoint->currentIndex() != 0) {
|
||||
pivot = extractTranslation(_geometry.joints.at(_pivotJoint->currentIndex() - 1).transform);
|
||||
}
|
||||
mapping.insert(TRANSLATION_X_FIELD, -pivot.x * _scale->value() + _translationX->value());
|
||||
mapping.insert(TRANSLATION_Y_FIELD, -pivot.y * _scale->value() + _translationY->value());
|
||||
mapping.insert(TRANSLATION_Z_FIELD, -pivot.z * _scale->value() + _translationZ->value());
|
||||
|
||||
} else {
|
||||
insertJointMapping(joints, "jointEyeLeft", _leftEyeJoint->currentText());
|
||||
insertJointMapping(joints, "jointEyeRight", _rightEyeJoint->currentText());
|
||||
insertJointMapping(joints, "jointNeck", _neckJoint->currentText());
|
||||
}
|
||||
mapping.insert(TRANSLATION_X_FIELD, -pivot.x * _scale->value() + _translationX->value());
|
||||
mapping.insert(TRANSLATION_Y_FIELD, -pivot.y * _scale->value() + _translationY->value());
|
||||
mapping.insert(TRANSLATION_Z_FIELD, -pivot.z * _scale->value() + _translationZ->value());
|
||||
|
||||
} else {
|
||||
insertJointMapping(joints, "jointEyeLeft", _leftEyeJoint->currentText());
|
||||
insertJointMapping(joints, "jointEyeRight", _rightEyeJoint->currentText());
|
||||
insertJointMapping(joints, "jointNeck", _neckJoint->currentText());
|
||||
}
|
||||
if (_modelType == SKELETON_MODEL) {
|
||||
insertJointMapping(joints, "jointRoot", _rootJoint->currentText());
|
||||
insertJointMapping(joints, "jointLean", _leanJoint->currentText());
|
||||
insertJointMapping(joints, "jointHead", _headJoint->currentText());
|
||||
insertJointMapping(joints, "jointLeftHand", _leftHandJoint->currentText());
|
||||
insertJointMapping(joints, "jointRightHand", _rightHandJoint->currentText());
|
||||
|
||||
mapping.remove(FREE_JOINT_FIELD);
|
||||
for (int i = 0; i < _freeJoints->count() - 1; i++) {
|
||||
QComboBox* box = static_cast<QComboBox*>(_freeJoints->itemAt(i)->widget()->layout()->itemAt(0)->widget());
|
||||
mapping.insertMulti(FREE_JOINT_FIELD, box->currentText());
|
||||
if (_modelType == SKELETON_MODEL) {
|
||||
insertJointMapping(joints, "jointRoot", _rootJoint->currentText());
|
||||
insertJointMapping(joints, "jointLean", _leanJoint->currentText());
|
||||
insertJointMapping(joints, "jointHead", _headJoint->currentText());
|
||||
insertJointMapping(joints, "jointLeftHand", _leftHandJoint->currentText());
|
||||
insertJointMapping(joints, "jointRightHand", _rightHandJoint->currentText());
|
||||
|
||||
mapping.remove(FREE_JOINT_FIELD);
|
||||
for (int i = 0; i < _freeJoints->count() - 1; i++) {
|
||||
QComboBox* box = static_cast<QComboBox*>(_freeJoints->itemAt(i)->widget()->layout()->itemAt(0)->widget());
|
||||
mapping.insertMulti(FREE_JOINT_FIELD, box->currentText());
|
||||
}
|
||||
}
|
||||
mapping.insert(JOINT_FIELD, joints);
|
||||
}
|
||||
mapping.insert(JOINT_FIELD, joints);
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
@ -729,32 +764,35 @@ void ModelPropertiesDialog::reset() {
|
|||
_scale->setValue(_originalMapping.value(SCALE_FIELD).toDouble());
|
||||
|
||||
QVariantHash jointHash = _originalMapping.value(JOINT_FIELD).toHash();
|
||||
if (_modelType == ATTACHMENT_MODEL) {
|
||||
_translationX->setValue(_originalMapping.value(TRANSLATION_X_FIELD).toDouble());
|
||||
_translationY->setValue(_originalMapping.value(TRANSLATION_Y_FIELD).toDouble());
|
||||
_translationZ->setValue(_originalMapping.value(TRANSLATION_Z_FIELD).toDouble());
|
||||
_pivotAboutCenter->setChecked(true);
|
||||
_pivotJoint->setCurrentIndex(0);
|
||||
|
||||
} else {
|
||||
setJointText(_leftEyeJoint, jointHash.value("jointEyeLeft").toString());
|
||||
setJointText(_rightEyeJoint, jointHash.value("jointEyeRight").toString());
|
||||
setJointText(_neckJoint, jointHash.value("jointNeck").toString());
|
||||
}
|
||||
if (_modelType == SKELETON_MODEL) {
|
||||
setJointText(_rootJoint, jointHash.value("jointRoot").toString());
|
||||
setJointText(_leanJoint, jointHash.value("jointLean").toString());
|
||||
setJointText(_headJoint, jointHash.value("jointHead").toString());
|
||||
setJointText(_leftHandJoint, jointHash.value("jointLeftHand").toString());
|
||||
setJointText(_rightHandJoint, jointHash.value("jointRightHand").toString());
|
||||
|
||||
while (_freeJoints->count() > 1) {
|
||||
delete _freeJoints->itemAt(0)->widget();
|
||||
|
||||
if (_modelType != ENTITY_MODEL) {
|
||||
if (_modelType == ATTACHMENT_MODEL) {
|
||||
_translationX->setValue(_originalMapping.value(TRANSLATION_X_FIELD).toDouble());
|
||||
_translationY->setValue(_originalMapping.value(TRANSLATION_Y_FIELD).toDouble());
|
||||
_translationZ->setValue(_originalMapping.value(TRANSLATION_Z_FIELD).toDouble());
|
||||
_pivotAboutCenter->setChecked(true);
|
||||
_pivotJoint->setCurrentIndex(0);
|
||||
|
||||
} else {
|
||||
setJointText(_leftEyeJoint, jointHash.value("jointEyeLeft").toString());
|
||||
setJointText(_rightEyeJoint, jointHash.value("jointEyeRight").toString());
|
||||
setJointText(_neckJoint, jointHash.value("jointNeck").toString());
|
||||
}
|
||||
foreach (const QVariant& joint, _originalMapping.values(FREE_JOINT_FIELD)) {
|
||||
QString jointName = joint.toString();
|
||||
if (_geometry.jointIndices.contains(jointName)) {
|
||||
createNewFreeJoint(jointName);
|
||||
if (_modelType == SKELETON_MODEL) {
|
||||
setJointText(_rootJoint, jointHash.value("jointRoot").toString());
|
||||
setJointText(_leanJoint, jointHash.value("jointLean").toString());
|
||||
setJointText(_headJoint, jointHash.value("jointHead").toString());
|
||||
setJointText(_leftHandJoint, jointHash.value("jointLeftHand").toString());
|
||||
setJointText(_rightHandJoint, jointHash.value("jointRightHand").toString());
|
||||
|
||||
while (_freeJoints->count() > 1) {
|
||||
delete _freeJoints->itemAt(0)->widget();
|
||||
}
|
||||
foreach (const QVariant& joint, _originalMapping.values(FREE_JOINT_FIELD)) {
|
||||
QString jointName = joint.toString();
|
||||
if (_geometry.jointIndices.contains(jointName)) {
|
||||
createNewFreeJoint(jointName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,13 +33,15 @@ class ModelUploader : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ModelUploader(ModelType type);
|
||||
~ModelUploader();
|
||||
static void uploadModel(ModelType modelType);
|
||||
|
||||
public slots:
|
||||
void send();
|
||||
static void uploadHead();
|
||||
static void uploadSkeleton();
|
||||
static void uploadAttachment();
|
||||
static void uploadEntity();
|
||||
|
||||
private slots:
|
||||
void send();
|
||||
void checkJSON(QNetworkReply& requestReply);
|
||||
void uploadUpdate(qint64 bytesSent, qint64 bytesTotal);
|
||||
void uploadSuccess(QNetworkReply& requestReply);
|
||||
|
@ -48,12 +50,21 @@ private slots:
|
|||
void processCheck();
|
||||
|
||||
private:
|
||||
ModelUploader(ModelType type);
|
||||
~ModelUploader();
|
||||
|
||||
void populateBasicMapping(QVariantHash& mapping, QString filename, FBXGeometry geometry);
|
||||
bool zip();
|
||||
bool addTextures(const QString& texdir, const FBXGeometry& geometry);
|
||||
bool addPart(const QString& path, const QString& name, bool isTexture = false);
|
||||
bool addPart(const QFile& file, const QByteArray& contents, const QString& name, bool isTexture = false);
|
||||
|
||||
QString _url;
|
||||
QString _textureBase;
|
||||
QSet<QByteArray> _textureFilenames;
|
||||
int _lodCount;
|
||||
int _texturesCount;
|
||||
int _totalSize;
|
||||
unsigned long _totalSize;
|
||||
ModelType _modelType;
|
||||
bool _readyToSend;
|
||||
|
||||
|
@ -64,12 +75,6 @@ private:
|
|||
|
||||
QDialog* _progressDialog;
|
||||
QProgressBar* _progressBar;
|
||||
|
||||
|
||||
bool zip();
|
||||
bool addTextures(const QString& texdir, const FBXGeometry& geometry);
|
||||
bool addPart(const QString& path, const QString& name, bool isTexture = false);
|
||||
bool addPart(const QFile& file, const QByteArray& contents, const QString& name, bool isTexture = false);
|
||||
};
|
||||
|
||||
/// A dialog that allows customization of various model properties.
|
||||
|
|
|
@ -130,38 +130,10 @@ void renderCollisionOverlay(int width, int height, float magnitude, float red, f
|
|||
const float MIN_VISIBLE_COLLISION = 0.01f;
|
||||
if (magnitude > MIN_VISIBLE_COLLISION) {
|
||||
glColor4f(red, blue, green, magnitude);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(0, 0);
|
||||
glVertex2d(width, 0);
|
||||
glVertex2d(width, height);
|
||||
glVertex2d(0, height);
|
||||
glEnd();
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(0, 0, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int numSides) {
|
||||
glm::vec3 perp1 = glm::vec3(surfaceNormal.y, surfaceNormal.z, surfaceNormal.x);
|
||||
glm::vec3 perp2 = glm::vec3(surfaceNormal.z, surfaceNormal.x, surfaceNormal.y);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
|
||||
for (int i=0; i<numSides+1; i++) {
|
||||
float r = ((float)i / (float)numSides) * TWO_PI;
|
||||
float s = radius * sinf(r);
|
||||
float c = radius * cosf(r);
|
||||
glVertex3f
|
||||
(
|
||||
position.x + perp1.x * s + perp2.x * c,
|
||||
position.y + perp1.y * s + perp2.y * c,
|
||||
position.z + perp1.z * s + perp2.z * c
|
||||
);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
void renderBevelCornersRect(int x, int y, int width, int height, int bevelDistance) {
|
||||
glBegin(GL_POLYGON);
|
||||
|
||||
|
|
|
@ -633,17 +633,14 @@ void Avatar::renderBillboard() {
|
|||
glScalef(size, size, size);
|
||||
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(-1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex2f(1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex2f(1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex2f(-1.0f, 1.0f);
|
||||
glEnd();
|
||||
|
||||
glm::vec2 topLeft(-1.0f, -1.0f);
|
||||
glm::vec2 bottomRight(1.0f, 1.0f);
|
||||
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
|
||||
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
|
||||
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
|
@ -682,14 +679,16 @@ float Avatar::calculateDisplayNameScaleFactor(const glm::vec3& textPosition, boo
|
|||
|
||||
double textWindowHeight;
|
||||
|
||||
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
|
||||
float windowSizeX = glCanvas->getDeviceWidth();
|
||||
float windowSizeY = glCanvas->getDeviceHeight();
|
||||
|
||||
GLint viewportMatrix[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewportMatrix);
|
||||
glm::dmat4 modelViewMatrix;
|
||||
float windowSizeX = viewportMatrix[2] - viewportMatrix[0];
|
||||
float windowSizeY = viewportMatrix[3] - viewportMatrix[1];
|
||||
|
||||
glm::dmat4 projectionMatrix;
|
||||
Application::getInstance()->getModelViewMatrix(&modelViewMatrix);
|
||||
Application::getInstance()->getProjectionMatrix(&projectionMatrix);
|
||||
|
||||
|
||||
glm::dvec4 p0 = modelViewMatrix * glm::dvec4(testPoint0, 1.0);
|
||||
p0 = projectionMatrix * p0;
|
||||
|
|
|
@ -84,10 +84,8 @@ void SixenseManager::initialize() {
|
|||
#ifdef HAVE_SIXENSE
|
||||
|
||||
if (!_isInitialized) {
|
||||
_lastMovement = 0;
|
||||
_amountMoved = glm::vec3(0.0f);
|
||||
_lowVelocityFilter = false;
|
||||
|
||||
_controllersAtBase = true;
|
||||
_calibrationState = CALIBRATION_STATE_IDLE;
|
||||
// By default we assume the _neckBase (in orb frame) is as high above the orb
|
||||
// as the "torso" is below it.
|
||||
|
@ -146,15 +144,11 @@ void SixenseManager::setFilter(bool filter) {
|
|||
|
||||
void SixenseManager::update(float deltaTime) {
|
||||
#ifdef HAVE_SIXENSE
|
||||
Hand* hand = Application::getInstance()->getAvatar()->getHand();
|
||||
if (_isInitialized && _isEnabled) {
|
||||
// if the controllers haven't been moved in a while, disable
|
||||
const unsigned int MOVEMENT_DISABLE_SECONDS = 3;
|
||||
if (usecTimestampNow() - _lastMovement > (MOVEMENT_DISABLE_SECONDS * USECS_PER_SECOND)) {
|
||||
Hand* hand = Application::getInstance()->getAvatar()->getHand();
|
||||
for (std::vector<PalmData>::iterator it = hand->getPalms().begin(); it != hand->getPalms().end(); it++) {
|
||||
it->setActive(false);
|
||||
}
|
||||
_lastMovement = usecTimestampNow();
|
||||
// Disable the hands (and return to default pose) if both controllers are at base station
|
||||
for (std::vector<PalmData>::iterator it = hand->getPalms().begin(); it != hand->getPalms().end(); it++) {
|
||||
it->setActive(!_controllersAtBase);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -172,8 +166,6 @@ void SixenseManager::update(float deltaTime) {
|
|||
_hydrasConnected = true;
|
||||
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra");
|
||||
}
|
||||
MyAvatar* avatar = Application::getInstance()->getAvatar();
|
||||
Hand* hand = avatar->getHand();
|
||||
|
||||
#ifdef __APPLE__
|
||||
SixenseBaseFunction sixenseGetMaxControllers =
|
||||
|
@ -192,7 +184,7 @@ void SixenseManager::update(float deltaTime) {
|
|||
SixenseTakeIntAndSixenseControllerData sixenseGetNewestData =
|
||||
(SixenseTakeIntAndSixenseControllerData) _sixenseLibrary->resolve("sixenseGetNewestData");
|
||||
#endif
|
||||
|
||||
int numControllersAtBase = 0;
|
||||
int numActiveControllers = 0;
|
||||
for (int i = 0; i < maxControllers && numActiveControllers < 2; i++) {
|
||||
if (!sixenseIsControllerEnabled(i)) {
|
||||
|
@ -221,14 +213,11 @@ void SixenseManager::update(float deltaTime) {
|
|||
qDebug("Found new Sixense controller, ID %i", data->controller_index);
|
||||
}
|
||||
|
||||
palm->setActive(true);
|
||||
|
||||
// Read controller buttons and joystick into the hand
|
||||
palm->setControllerButtons(data->buttons);
|
||||
palm->setTrigger(data->trigger);
|
||||
palm->setJoystick(data->joystick_x, data->joystick_y);
|
||||
|
||||
|
||||
// Emulate the mouse so we can use scripts
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) {
|
||||
emulateMouse(palm, numActiveControllers - 1);
|
||||
|
@ -238,6 +227,12 @@ void SixenseManager::update(float deltaTime) {
|
|||
glm::vec3 position(data->pos[0], data->pos[1], data->pos[2]);
|
||||
position *= METERS_PER_MILLIMETER;
|
||||
|
||||
// Check to see if this hand/controller is on the base
|
||||
const float CONTROLLER_AT_BASE_DISTANCE = 0.075f;
|
||||
if (glm::length(position) < CONTROLLER_AT_BASE_DISTANCE) {
|
||||
numControllersAtBase++;
|
||||
}
|
||||
|
||||
// Transform the measured position into body frame.
|
||||
glm::vec3 neck = _neckBase;
|
||||
// Zeroing y component of the "neck" effectively raises the measured position a little bit.
|
||||
|
@ -274,14 +269,6 @@ void SixenseManager::update(float deltaTime) {
|
|||
palm->setRawRotation(rotation);
|
||||
}
|
||||
|
||||
// use the velocity to determine whether there's any movement (if the hand isn't new)
|
||||
const float MOVEMENT_DISTANCE_THRESHOLD = 0.003f;
|
||||
_amountMoved += rawVelocity * deltaTime;
|
||||
if (glm::length(_amountMoved) > MOVEMENT_DISTANCE_THRESHOLD && foundHand) {
|
||||
_lastMovement = usecTimestampNow();
|
||||
_amountMoved = glm::vec3(0.0f);
|
||||
}
|
||||
|
||||
// Store the one fingertip in the palm structure so we can track velocity
|
||||
const float FINGER_LENGTH = 0.3f; // meters
|
||||
const glm::vec3 FINGER_VECTOR(0.0f, 0.0f, FINGER_LENGTH);
|
||||
|
@ -298,7 +285,7 @@ void SixenseManager::update(float deltaTime) {
|
|||
if (numActiveControllers == 2) {
|
||||
updateCalibration(controllers);
|
||||
}
|
||||
|
||||
_controllersAtBase = (numControllersAtBase == 2);
|
||||
}
|
||||
#endif // HAVE_SIXENSE
|
||||
}
|
||||
|
|
|
@ -91,8 +91,6 @@ private:
|
|||
bool _isInitialized;
|
||||
bool _isEnabled;
|
||||
bool _hydrasConnected;
|
||||
quint64 _lastMovement;
|
||||
glm::vec3 _amountMoved;
|
||||
|
||||
// for mouse emulation with the two controllers
|
||||
bool _triggerPressed[2];
|
||||
|
@ -101,6 +99,7 @@ private:
|
|||
int _oldY[2];
|
||||
|
||||
bool _lowVelocityFilter;
|
||||
bool _controllersAtBase;
|
||||
};
|
||||
|
||||
#endif // hifi_SixenseManager_h
|
||||
|
|
|
@ -116,9 +116,8 @@ void AddressBarDialog::setupUI() {
|
|||
|
||||
void AddressBarDialog::showEvent(QShowEvent* event) {
|
||||
_goButton->setIcon(QIcon(PathUtils::resourcesPath() + ADDRESSBAR_GO_BUTTON_ICON));
|
||||
_addressLineEdit->setText(AddressManager::getInstance().currentAddress().toString());
|
||||
_addressLineEdit->setText(QString());
|
||||
_addressLineEdit->setFocus();
|
||||
_addressLineEdit->selectAll();
|
||||
FramelessDialog::showEvent(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -106,23 +106,17 @@ bool raySphereIntersect(const glm::vec3 &dir, const glm::vec3 &origin, float r,
|
|||
}
|
||||
|
||||
void renderReticle(glm::quat orientation, float alpha) {
|
||||
glm::vec3 topLeft = getPoint(reticleSize / 2.0f, -reticleSize / 2.0f);
|
||||
glm::vec3 topRight = getPoint(-reticleSize / 2.0f, -reticleSize / 2.0f);
|
||||
glm::vec3 bottomLeft = getPoint(reticleSize / 2.0f, reticleSize / 2.0f);
|
||||
glm::vec3 bottomRight = getPoint(-reticleSize / 2.0f, reticleSize / 2.0f);
|
||||
|
||||
glPushMatrix(); {
|
||||
glm::vec3 axis = glm::axis(orientation);
|
||||
glRotatef(glm::degrees(glm::angle(orientation)), axis.x, axis.y, axis.z);
|
||||
|
||||
glBegin(GL_QUADS); {
|
||||
glColor4f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], alpha);
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex3f(topLeft.x, topLeft.y, topLeft.z);
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex3f(bottomLeft.x, bottomLeft.y, bottomLeft.z);
|
||||
glTexCoord2f(1.0f, 1.0f); glVertex3f(bottomRight.x, bottomRight.y, bottomRight.z);
|
||||
glTexCoord2f(0.0f, 1.0f); glVertex3f(topRight.x, topRight.y, topRight.z);
|
||||
} glEnd();
|
||||
glm::vec3 topLeft = getPoint(reticleSize / 2.0f, -reticleSize / 2.0f);
|
||||
glm::vec3 topRight = getPoint(-reticleSize / 2.0f, -reticleSize / 2.0f);
|
||||
glm::vec3 bottomLeft = getPoint(reticleSize / 2.0f, reticleSize / 2.0f);
|
||||
glm::vec3 bottomRight = getPoint(-reticleSize / 2.0f, reticleSize / 2.0f);
|
||||
glColor4f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], alpha);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomLeft, bottomRight, topRight,
|
||||
glm::vec2(0.0f, 0.0f), glm::vec2(1.0f, 0.0f),
|
||||
glm::vec2(1.0f, 1.0f), glm::vec2(0.0f, 1.0f));
|
||||
} glPopMatrix();
|
||||
}
|
||||
|
||||
|
@ -231,13 +225,14 @@ void ApplicationOverlay::displayOverlayTexture() {
|
|||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glBegin(GL_QUADS); {
|
||||
glColor4f(1.0f, 1.0f, 1.0f, _alpha);
|
||||
glTexCoord2f(0, 0); glVertex2i(0, glCanvas->getDeviceHeight());
|
||||
glTexCoord2f(1, 0); glVertex2i(glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight());
|
||||
glTexCoord2f(1, 1); glVertex2i(glCanvas->getDeviceWidth(), 0);
|
||||
glTexCoord2f(0, 1); glVertex2i(0, 0);
|
||||
} glEnd();
|
||||
glColor4f(1.0f, 1.0f, 1.0f, _alpha);
|
||||
glm::vec2 topLeft(0.0f, 0.0f);
|
||||
glm::vec2 bottomRight(glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight());
|
||||
glm::vec2 texCoordTopLeft(0.0f, 1.0f);
|
||||
glm::vec2 texCoordBottomRight(1.0f, 0.0f);
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
|
||||
|
||||
} glPopMatrix();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
@ -372,15 +367,13 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as
|
|||
GLfloat x = -halfQuadWidth;
|
||||
GLfloat y = -halfQuadHeight;
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + quadHeight, -distance);
|
||||
glTexCoord2f(1.0f, 1.0f); glVertex3f(x + quadWidth, y + quadHeight, -distance);
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex3f(x + quadWidth, y, -distance);
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, -distance);
|
||||
|
||||
glEnd();
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(glm::vec3(x, y + quadHeight, -distance),
|
||||
glm::vec3(x + quadWidth, y + quadHeight, -distance),
|
||||
glm::vec3(x + quadWidth, y, -distance),
|
||||
glm::vec3(x, y, -distance),
|
||||
glm::vec2(0.0f, 1.0f), glm::vec2(1.0f, 1.0f),
|
||||
glm::vec2(1.0f, 0.0f), glm::vec2(0.0f, 0.0f));
|
||||
|
||||
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
|
||||
if (_crosshairTexture == 0) {
|
||||
|
@ -396,17 +389,15 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as
|
|||
const float mouseX = (application->getMouseX() / (float)glCanvas->width()) * quadWidth;
|
||||
const float mouseY = (1.0 - (application->getMouseY() / (float)glCanvas->height())) * quadHeight;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2]);
|
||||
|
||||
glTexCoord2d(0.0f, 0.0f); glVertex3f(x + mouseX, y + mouseY, -distance);
|
||||
glTexCoord2d(1.0f, 0.0f); glVertex3f(x + mouseX + reticleSize, y + mouseY, -distance);
|
||||
glTexCoord2d(1.0f, 1.0f); glVertex3f(x + mouseX + reticleSize, y + mouseY - reticleSize, -distance);
|
||||
glTexCoord2d(0.0f, 1.0f); glVertex3f(x + mouseX, y + mouseY - reticleSize, -distance);
|
||||
|
||||
glEnd();
|
||||
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(glm::vec3(x + mouseX, y + mouseY, -distance),
|
||||
glm::vec3(x + mouseX + reticleSize, y + mouseY, -distance),
|
||||
glm::vec3(x + mouseX + reticleSize, y + mouseY - reticleSize, -distance),
|
||||
glm::vec3(x + mouseX, y + mouseY - reticleSize, -distance),
|
||||
glm::vec2(0.0f, 0.0f), glm::vec2(1.0f, 0.0f),
|
||||
glm::vec2(1.0f, 1.0f), glm::vec2(0.0f, 1.0f));
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glPopMatrix();
|
||||
|
@ -660,16 +651,16 @@ void ApplicationOverlay::renderControllerPointers() {
|
|||
mouseX -= reticleSize / 2.0f;
|
||||
mouseY += reticleSize / 2.0f;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2]);
|
||||
|
||||
glTexCoord2d(0.0f, 0.0f); glVertex2i(mouseX, mouseY);
|
||||
glTexCoord2d(1.0f, 0.0f); glVertex2i(mouseX + reticleSize, mouseY);
|
||||
glTexCoord2d(1.0f, 1.0f); glVertex2i(mouseX + reticleSize, mouseY - reticleSize);
|
||||
glTexCoord2d(0.0f, 1.0f); glVertex2i(mouseX, mouseY - reticleSize);
|
||||
glm::vec2 topLeft(mouseX, mouseY);
|
||||
glm::vec2 bottomRight(mouseX + reticleSize, mouseY - reticleSize);
|
||||
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
|
||||
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
|
||||
|
||||
glEnd();
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -752,13 +743,13 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool
|
|||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
glColor4f(1.0f, 1.0f, 1.0f, _alpha);
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(bottomLeft, bottomRight, topRight, topLeft,
|
||||
glm::vec2(magnifyULeft, magnifyVBottom),
|
||||
glm::vec2(magnifyURight, magnifyVBottom),
|
||||
glm::vec2(magnifyURight, magnifyVTop),
|
||||
glm::vec2(magnifyULeft, magnifyVTop));
|
||||
|
||||
glBegin(GL_QUADS); {
|
||||
glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(bottomLeft.x, bottomLeft.y, bottomLeft.z);
|
||||
glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(bottomRight.x, bottomRight.y, bottomRight.z);
|
||||
glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(topRight.x, topRight.y, topRight.z);
|
||||
glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(topLeft.x, topLeft.y, topLeft.z);
|
||||
} glEnd();
|
||||
} glPopMatrix();
|
||||
}
|
||||
|
||||
|
@ -837,7 +828,6 @@ void ApplicationOverlay::renderAudioMeter() {
|
|||
|
||||
audio->renderStats(WHITE_TEXT, glCanvas->width(), glCanvas->height());
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
if (isClipping) {
|
||||
glColor3f(1, 0, 0);
|
||||
} else {
|
||||
|
@ -848,10 +838,7 @@ void ApplicationOverlay::renderAudioMeter() {
|
|||
|
||||
glColor3f(0, 0, 0);
|
||||
// Draw audio meter background Quad
|
||||
glVertex2i(AUDIO_METER_X, audioMeterY);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_WIDTH, audioMeterY);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_WIDTH, audioMeterY + AUDIO_METER_HEIGHT);
|
||||
glVertex2i(AUDIO_METER_X, audioMeterY + AUDIO_METER_HEIGHT);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X, audioMeterY, AUDIO_METER_WIDTH, AUDIO_METER_HEIGHT);
|
||||
|
||||
if (audioLevel > AUDIO_RED_START) {
|
||||
if (!isClipping) {
|
||||
|
@ -860,12 +847,14 @@ void ApplicationOverlay::renderAudioMeter() {
|
|||
glColor3f(1, 1, 1);
|
||||
}
|
||||
// Draw Red Quad
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START, audioMeterY + AUDIO_METER_INSET);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START,
|
||||
audioMeterY + AUDIO_METER_INSET,
|
||||
audioLevel - AUDIO_RED_START,
|
||||
AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
|
||||
|
||||
audioLevel = AUDIO_RED_START;
|
||||
}
|
||||
|
||||
if (audioLevel > AUDIO_GREEN_START) {
|
||||
if (!isClipping) {
|
||||
glColor3fv(AUDIO_METER_GREEN);
|
||||
|
@ -873,10 +862,11 @@ void ApplicationOverlay::renderAudioMeter() {
|
|||
glColor3f(1, 1, 1);
|
||||
}
|
||||
// Draw Green Quad
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START, audioMeterY + AUDIO_METER_INSET);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START,
|
||||
audioMeterY + AUDIO_METER_INSET,
|
||||
audioLevel - AUDIO_GREEN_START,
|
||||
AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
|
||||
|
||||
audioLevel = AUDIO_GREEN_START;
|
||||
}
|
||||
// Draw Blue Quad
|
||||
|
@ -886,11 +876,9 @@ void ApplicationOverlay::renderAudioMeter() {
|
|||
glColor3f(1, 1, 1);
|
||||
}
|
||||
// Draw Blue (low level) quad
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, audioMeterY + AUDIO_METER_INSET);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
|
||||
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
|
||||
glEnd();
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET,
|
||||
audioMeterY + AUDIO_METER_INSET,
|
||||
audioLevel, AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
|
||||
}
|
||||
|
||||
void ApplicationOverlay::renderStatsAndLogs() {
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
|
||||
#include <cstdio>
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <GeometryCache.h>
|
||||
|
||||
#include "BandwidthMeter.h"
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
|
@ -92,13 +95,7 @@ void BandwidthMeter::setColorRGBA(unsigned c) {
|
|||
}
|
||||
|
||||
void BandwidthMeter::renderBox(int x, int y, int w, int h) {
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x + w, y);
|
||||
glVertex2i(x + w, y + h);
|
||||
glVertex2i(x, y + h);
|
||||
glEnd();
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(x, y, w, h);
|
||||
}
|
||||
|
||||
void BandwidthMeter::renderVerticalLine(int x, int y, int h) {
|
||||
|
|
|
@ -12,16 +12,19 @@
|
|||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QFileInfo>
|
||||
#include <QHeaderView>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QThread>
|
||||
#include <QUrl>
|
||||
#include <qurlquery.h>
|
||||
#include <QUrlQuery>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#include <NetworkAccessManager.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
#include "ModelsBrowser.h"
|
||||
|
||||
const char* MODEL_TYPE_NAMES[] = { "entities", "heads", "skeletons", "attachments" };
|
||||
|
|
|
@ -140,22 +140,14 @@ void RearMirrorTools::displayIcon(QRect bounds, QRect iconBounds, GLuint texture
|
|||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
glBegin(GL_QUADS);
|
||||
{
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2f(iconBounds.left(), iconBounds.bottom());
|
||||
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex2f(iconBounds.left(), iconBounds.top());
|
||||
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex2f(iconBounds.right(), iconBounds.top());
|
||||
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex2f(iconBounds.right(), iconBounds.bottom());
|
||||
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glm::vec2 topLeft(iconBounds.left(), iconBounds.top());
|
||||
glm::vec2 bottomRight(iconBounds.right(), iconBounds.bottom());
|
||||
glm::vec2 texCoordTopLeft(0.0f, 1.0f);
|
||||
glm::vec2 texCoordBottomRight(1.0f, 0.0f);
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
|
|
@ -154,16 +154,13 @@ void Stats::resetWidth(int width, int horizontalOffset) {
|
|||
|
||||
// translucent background box that makes stats more readable
|
||||
void Stats::drawBackground(unsigned int rgba, int x, int y, int width, int height) {
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(((rgba >> 24) & 0xff) / 255.0f,
|
||||
((rgba >> 16) & 0xff) / 255.0f,
|
||||
((rgba >> 8) & 0xff) / 255.0f,
|
||||
(rgba & 0xff) / 255.0f);
|
||||
glVertex3f(x, y, 0);
|
||||
glVertex3f(x + width, y, 0);
|
||||
glVertex3f(x + width, y + height, 0);
|
||||
glVertex3f(x , y + height, 0);
|
||||
glEnd();
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(x, y, width, height);
|
||||
|
||||
glColor4f(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -96,21 +96,16 @@ void BillboardOverlay::render(RenderArgs* args) {
|
|||
xColor color = getColor();
|
||||
float alpha = getAlpha();
|
||||
glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
||||
glBegin(GL_QUADS); {
|
||||
glTexCoord2f((float)_fromImage.x() / (float)_size.width(),
|
||||
(float)_fromImage.y() / (float)_size.height());
|
||||
|
||||
glm::vec2 topLeft(-x, -y);
|
||||
glm::vec2 bottomRight(x, y);
|
||||
glm::vec2 texCoordTopLeft((float)_fromImage.x() / (float)_size.width(),
|
||||
(float)_fromImage.y() / (float)_size.height());
|
||||
glm::vec2 texCoordBottomRight(((float)_fromImage.x() + (float)_fromImage.width()) / (float)_size.width(),
|
||||
((float)_fromImage.y() + (float)_fromImage.height()) / _size.height());
|
||||
|
||||
glVertex2f(-x, -y);
|
||||
glTexCoord2f(((float)_fromImage.x() + (float)_fromImage.width()) / (float)_size.width(),
|
||||
(float)_fromImage.y() / (float)_size.height());
|
||||
glVertex2f(x, -y);
|
||||
glTexCoord2f(((float)_fromImage.x() + (float)_fromImage.width()) / (float)_size.width(),
|
||||
((float)_fromImage.y() + (float)_fromImage.height()) / _size.height());
|
||||
glVertex2f(x, y);
|
||||
glTexCoord2f((float)_fromImage.x() / (float)_size.width(),
|
||||
((float)_fromImage.y() + (float)_fromImage.height()) / (float)_size.height());
|
||||
glVertex2f(-x, y);
|
||||
} glEnd();
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
|
||||
|
||||
}
|
||||
} glPopMatrix();
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#include <QGLWidget>
|
||||
#include <QPainter>
|
||||
#include <QSvgRenderer>
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "ImageOverlay.h"
|
||||
|
@ -100,27 +103,21 @@ void ImageOverlay::render(RenderArgs* args) {
|
|||
float w = fromImage.width() / imageWidth; // ?? is this what we want? not sure
|
||||
float h = fromImage.height() / imageHeight;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
if (_renderImage) {
|
||||
glTexCoord2f(x, 1.0f - y);
|
||||
}
|
||||
glVertex2f(_bounds.left(), _bounds.top());
|
||||
int left = _bounds.left();
|
||||
int right = _bounds.right() + 1;
|
||||
int top = _bounds.top();
|
||||
int bottom = _bounds.bottom() + 1;
|
||||
|
||||
if (_renderImage) {
|
||||
glTexCoord2f(x + w, 1.0f - y);
|
||||
}
|
||||
glVertex2f(_bounds.right(), _bounds.top());
|
||||
glm::vec2 topLeft(left, top);
|
||||
glm::vec2 bottomRight(right, bottom);
|
||||
glm::vec2 texCoordTopLeft(x, 1.0f - y);
|
||||
glm::vec2 texCoordBottomRight(x + w, 1.0f - (y + h));
|
||||
|
||||
if (_renderImage) {
|
||||
glTexCoord2f(x + w, 1.0f - (y + h));
|
||||
}
|
||||
glVertex2f(_bounds.right(), _bounds.bottom());
|
||||
|
||||
if (_renderImage) {
|
||||
glTexCoord2f(x, 1.0f - (y + h));
|
||||
}
|
||||
glVertex2f(_bounds.left(), _bounds.bottom());
|
||||
glEnd();
|
||||
if (_renderImage) {
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
|
||||
} else {
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
if (_renderImage) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <QGLWidget>
|
||||
|
||||
#include <GeometryCache.h>
|
||||
#include <GlowEffect.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
|
@ -66,14 +67,9 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
|
|||
|
||||
// for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line...
|
||||
if (getIsSolid()) {
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glVertex3f(-halfDimensions.x, 0.0f, -halfDimensions.y);
|
||||
glVertex3f(halfDimensions.x, 0.0f, -halfDimensions.y);
|
||||
glVertex3f(halfDimensions.x, 0.0f, halfDimensions.y);
|
||||
glVertex3f(-halfDimensions.x, 0.0f, halfDimensions.y);
|
||||
|
||||
glEnd();
|
||||
glm::vec3 topLeft(-halfDimensions.x, 0.0f, -halfDimensions.y);
|
||||
glm::vec3 bottomRight(halfDimensions.x, 0.0f, halfDimensions.y);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight);
|
||||
} else {
|
||||
if (getIsDashedLine()) {
|
||||
|
||||
|
|
|
@ -100,12 +100,9 @@ void Text3DOverlay::render(RenderArgs* args) {
|
|||
|
||||
const float SLIGHTLY_BEHIND = -0.005f;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glVertex3f(halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glVertex3f(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glVertex3f(-halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glEnd();
|
||||
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight);
|
||||
|
||||
const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 40.0f; // this is a ratio determined through experimentation
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include "InterfaceConfig.h"
|
||||
|
||||
#include <QGLWidget>
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <TextRenderer.h>
|
||||
|
||||
|
@ -70,12 +73,14 @@ void TextOverlay::render(RenderArgs* args) {
|
|||
glColor4f(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, backgroundColor.blue / MAX_COLOR,
|
||||
getBackgroundAlpha());
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(_bounds.left(), _bounds.top());
|
||||
glVertex2f(_bounds.right(), _bounds.top());
|
||||
glVertex2f(_bounds.right(), _bounds.bottom());
|
||||
glVertex2f(_bounds.left(), _bounds.bottom());
|
||||
glEnd();
|
||||
int left = _bounds.left();
|
||||
int right = _bounds.right() + 1;
|
||||
int top = _bounds.top();
|
||||
int bottom = _bounds.bottom() + 1;
|
||||
|
||||
glm::vec2 topLeft(left, top);
|
||||
glm::vec2 bottomRight(right, bottom);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight);
|
||||
|
||||
// Same font properties as textSize()
|
||||
TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT);
|
||||
|
|
|
@ -3,7 +3,7 @@ set(TARGET_NAME animation)
|
|||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library(Network Script)
|
||||
|
||||
link_hifi_libraries(shared fbx)
|
||||
link_hifi_libraries(shared gpu model fbx)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -12,16 +12,18 @@
|
|||
#include "AnimationCache.h"
|
||||
#include "AnimationLoop.h"
|
||||
|
||||
const float AnimationLoop::MAXIMUM_POSSIBLE_FRAME = 100000.0f;
|
||||
|
||||
AnimationLoop::AnimationLoop() :
|
||||
_fps(30.0f),
|
||||
_loop(false),
|
||||
_hold(false),
|
||||
_startAutomatically(false),
|
||||
_firstFrame(0.0f),
|
||||
_lastFrame(FLT_MAX),
|
||||
_lastFrame(MAXIMUM_POSSIBLE_FRAME),
|
||||
_running(false),
|
||||
_frameIndex(0.0f),
|
||||
_maxFrameIndexHint(FLT_MAX)
|
||||
_maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -53,10 +55,9 @@ AnimationLoop::AnimationLoop(float fps, bool loop, bool hold, bool startAutomati
|
|||
void AnimationLoop::simulate(float deltaTime) {
|
||||
_frameIndex += deltaTime * _fps;
|
||||
|
||||
|
||||
// If we knew the number of frames from the animation, we'd consider using it here
|
||||
// animationGeometry.animationFrames.size()
|
||||
float maxFrame = _maxFrameIndexHint;
|
||||
float maxFrame = _maxFrameIndexHint;
|
||||
float endFrameIndex = qMin(_lastFrame, maxFrame - (_loop ? 0.0f : 1.0f));
|
||||
float startFrameIndex = qMin(_firstFrame, endFrameIndex);
|
||||
if ((!_loop && (_frameIndex < startFrameIndex || _frameIndex > endFrameIndex)) || startFrameIndex == endFrameIndex) {
|
||||
|
|
|
@ -16,6 +16,8 @@ class AnimationDetails;
|
|||
|
||||
class AnimationLoop {
|
||||
public:
|
||||
static const float MAXIMUM_POSSIBLE_FRAME;
|
||||
|
||||
AnimationLoop();
|
||||
AnimationLoop(const AnimationDetails& animationDetails);
|
||||
AnimationLoop(float fps, bool loop, bool hold, bool startAutomatically, float firstFrame,
|
||||
|
@ -33,10 +35,10 @@ public:
|
|||
void setStartAutomatically(bool startAutomatically);
|
||||
bool getStartAutomatically() const { return _startAutomatically; }
|
||||
|
||||
void setFirstFrame(float firstFrame) { _firstFrame = firstFrame; }
|
||||
void setFirstFrame(float firstFrame) { _firstFrame = glm::clamp(firstFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); }
|
||||
float getFirstFrame() const { return _firstFrame; }
|
||||
|
||||
void setLastFrame(float lastFrame) { _lastFrame = lastFrame; }
|
||||
void setLastFrame(float lastFrame) { _lastFrame = glm::clamp(lastFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); }
|
||||
float getLastFrame() const { return _lastFrame; }
|
||||
|
||||
void setRunning(bool running);
|
||||
|
@ -45,7 +47,7 @@ public:
|
|||
void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(frameIndex, _firstFrame, _lastFrame); }
|
||||
float getFrameIndex() const { return _frameIndex; }
|
||||
|
||||
void setMaxFrameIndexHint(float value) { _maxFrameIndexHint = value; }
|
||||
void setMaxFrameIndexHint(float value) { _maxFrameIndexHint = glm::clamp(value, 0.0f, MAXIMUM_POSSIBLE_FRAME); }
|
||||
float getMaxFrameIndexHint() const { return _maxFrameIndexHint; }
|
||||
|
||||
void start() { setRunning(true); }
|
||||
|
|
|
@ -7,5 +7,5 @@ include_glm()
|
|||
|
||||
link_hifi_libraries(networking shared)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -5,8 +5,7 @@ setup_hifi_library(Network Script)
|
|||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared octree voxels networking physics)
|
||||
include_hifi_library_headers(fbx)
|
||||
link_hifi_libraries(audio shared octree voxels networking physics gpu model fbx)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -3,5 +3,5 @@ set(TARGET_NAME embedded-webserver)
|
|||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library(Network)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -5,7 +5,7 @@ setup_hifi_library(Widgets OpenGL Network Script)
|
|||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared gpu script-engine)
|
||||
link_hifi_libraries(shared gpu script-engine render-utils)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -62,6 +62,7 @@ EntityTreeRenderer::~EntityTreeRenderer() {
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::clear() {
|
||||
leaveAllEntities();
|
||||
foreach (const EntityItemID& entityID, _entityScripts.keys()) {
|
||||
checkAndCallUnload(entityID);
|
||||
}
|
||||
|
@ -82,8 +83,7 @@ void EntityTreeRenderer::init() {
|
|||
|
||||
// make sure our "last avatar position" is something other than our current position, so that on our
|
||||
// first chance, we'll check for enter/leave entity events.
|
||||
glm::vec3 avatarPosition = _viewState->getAvatarPosition();
|
||||
_lastAvatarPosition = avatarPosition + glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity);
|
||||
connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::checkAndCallPreload);
|
||||
|
@ -97,13 +97,15 @@ QScriptValue EntityTreeRenderer::loadEntityScript(const EntityItemID& entityItem
|
|||
}
|
||||
|
||||
|
||||
QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorText) {
|
||||
QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL) {
|
||||
QUrl url(scriptMaybeURLorText);
|
||||
|
||||
// If the url is not valid, this must be script text...
|
||||
if (!url.isValid()) {
|
||||
isURL = false;
|
||||
return scriptMaybeURLorText;
|
||||
}
|
||||
isURL = true;
|
||||
|
||||
QString scriptContents; // assume empty
|
||||
|
||||
|
@ -173,7 +175,8 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) {
|
|||
return QScriptValue(); // no script
|
||||
}
|
||||
|
||||
QString scriptContents = loadScriptContents(entityScript);
|
||||
bool isURL = false; // loadScriptContents() will tell us if this is a URL or just text.
|
||||
QString scriptContents = loadScriptContents(entityScript, isURL);
|
||||
|
||||
QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(scriptContents);
|
||||
if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
|
||||
|
@ -184,6 +187,9 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) {
|
|||
return QScriptValue(); // invalid script
|
||||
}
|
||||
|
||||
if (isURL) {
|
||||
_entitiesScriptEngine->setParentURL(entity->getScript());
|
||||
}
|
||||
QScriptValue entityScriptConstructor = _entitiesScriptEngine->evaluate(scriptContents);
|
||||
|
||||
if (!entityScriptConstructor.isFunction()) {
|
||||
|
@ -197,6 +203,10 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) {
|
|||
EntityScriptDetails newDetails = { entityScript, entityScriptObject };
|
||||
_entityScripts[entityID] = newDetails;
|
||||
|
||||
if (isURL) {
|
||||
_entitiesScriptEngine->setParentURL("");
|
||||
}
|
||||
|
||||
return entityScriptObject; // newly constructed
|
||||
}
|
||||
|
||||
|
@ -287,6 +297,27 @@ void EntityTreeRenderer::checkEnterLeaveEntities() {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::leaveAllEntities() {
|
||||
if (_tree) {
|
||||
_tree->lockForWrite(); // so that our scripts can do edits if they want
|
||||
|
||||
// for all of our previous containing entities, if they are no longer containing then send them a leave event
|
||||
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
|
||||
emit leaveEntity(entityID);
|
||||
QScriptValueList entityArgs = createEntityArgs(entityID);
|
||||
QScriptValue entityScript = loadEntityScript(entityID);
|
||||
if (entityScript.property("leaveEntity").isValid()) {
|
||||
entityScript.property("leaveEntity").call(entityScript, entityArgs);
|
||||
}
|
||||
}
|
||||
_currentEntitiesInside.clear();
|
||||
|
||||
// make sure our "last avatar position" is something other than our current position, so that on our
|
||||
// first chance, we'll check for enter/leave entity events.
|
||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
_tree->unlock();
|
||||
}
|
||||
}
|
||||
void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) {
|
||||
if (_tree) {
|
||||
Model::startScene(renderSide);
|
||||
|
|
|
@ -129,6 +129,7 @@ private:
|
|||
|
||||
QScriptValueList createEntityArgs(const EntityItemID& entityID);
|
||||
void checkEnterLeaveEntities();
|
||||
void leaveAllEntities();
|
||||
glm::vec3 _lastAvatarPosition;
|
||||
QVector<EntityItemID> _currentEntitiesInside;
|
||||
|
||||
|
@ -138,7 +139,7 @@ private:
|
|||
QScriptValue loadEntityScript(EntityItem* entity);
|
||||
QScriptValue loadEntityScript(const EntityItemID& entityItemID);
|
||||
QScriptValue getPreviouslyLoadedEntityScript(const EntityItemID& entityItemID);
|
||||
QString loadScriptContents(const QString& scriptMaybeURLorText);
|
||||
QString loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL);
|
||||
QScriptValueList createMouseEventArgs(const EntityItemID& entityID, QMouseEvent* event, unsigned int deviceID);
|
||||
QScriptValueList createMouseEventArgs(const EntityItemID& entityID, const MouseEvent& mouseEvent);
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include <GeometryCache.h>
|
||||
#include <PerfStat.h>
|
||||
#include <TextRenderer.h>
|
||||
|
||||
|
@ -51,12 +53,9 @@ void RenderableTextEntityItem::render(RenderArgs* args) {
|
|||
|
||||
const float SLIGHTLY_BEHIND = -0.005f;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glVertex3f(halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glVertex3f(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glVertex3f(-halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glEnd();
|
||||
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight);
|
||||
|
||||
const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 40.0f; // this is a ratio determined through experimentation
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ setup_hifi_library(Network Script)
|
|||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared octree fbx networking animation physics)
|
||||
link_hifi_libraries(avatars shared octree gpu model fbx networking animation physics)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -144,6 +144,13 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) {
|
|||
penetration = collision->_penetration;
|
||||
entityB = static_cast<EntityItem*>(collision->_extraData);
|
||||
|
||||
// The collision _extraData should be a valid entity, but if for some reason
|
||||
// it's NULL then continue with a warning.
|
||||
if (!entityB) {
|
||||
qDebug() << "UNEXPECTED - we have a collision with missing _extraData. Something went wrong down below!";
|
||||
continue; // skip this loop pass if the entity is NULL
|
||||
}
|
||||
|
||||
// don't collide entities with unknown IDs,
|
||||
if (!entityB->isKnownID()) {
|
||||
continue; // skip this loop pass if the entity has an unknown ID
|
||||
|
|
|
@ -585,8 +585,12 @@ bool EntityTreeElement::findShapeCollisions(const Shape* shape, CollisionList& c
|
|||
if (shape != otherCollisionShape && !ignoreForCollisions) {
|
||||
if (ShapeCollider::collideShapes(shape, otherCollisionShape, collisions)) {
|
||||
CollisionInfo* lastCollision = collisions.getLastCollision();
|
||||
lastCollision->_extraData = entity;
|
||||
atLeastOneCollision = true;
|
||||
if (lastCollision) {
|
||||
lastCollision->_extraData = entity;
|
||||
atLeastOneCollision = true;
|
||||
} else {
|
||||
qDebug() << "UNEXPECTED - ShapeCollider::collideShapes() returned true, but no lastCollision.";
|
||||
}
|
||||
}
|
||||
}
|
||||
++entityItr;
|
||||
|
|
|
@ -401,6 +401,19 @@ void ModelEntityItem::setAnimationURL(const QString& url) {
|
|||
_animationURL = url;
|
||||
}
|
||||
|
||||
void ModelEntityItem::setAnimationFrameIndex(float value) {
|
||||
#ifdef WANT_DEBUG
|
||||
if (isAnimatingSomething()) {
|
||||
qDebug() << "ModelEntityItem::setAnimationFrameIndex()";
|
||||
qDebug() << " value:" << value;
|
||||
qDebug() << " was:" << _animationLoop.getFrameIndex();
|
||||
qDebug() << " model URL:" << getModelURL();
|
||||
qDebug() << " animation URL:" << getAnimationURL();
|
||||
}
|
||||
#endif
|
||||
_animationLoop.setFrameIndex(value);
|
||||
}
|
||||
|
||||
void ModelEntityItem::setAnimationSettings(const QString& value) {
|
||||
// the animations setting is a JSON string that may contain various animation settings.
|
||||
// if it includes fps, frameIndex, or running, those values will be parsed out and
|
||||
|
@ -416,6 +429,17 @@ void ModelEntityItem::setAnimationSettings(const QString& value) {
|
|||
|
||||
if (settingsMap.contains("frameIndex")) {
|
||||
float frameIndex = settingsMap["frameIndex"].toFloat();
|
||||
#ifdef WANT_DEBUG
|
||||
if (isAnimatingSomething()) {
|
||||
qDebug() << "ModelEntityItem::setAnimationSettings() calling setAnimationFrameIndex()...";
|
||||
qDebug() << " model URL:" << getModelURL();
|
||||
qDebug() << " animation URL:" << getAnimationURL();
|
||||
qDebug() << " settings:" << value;
|
||||
qDebug() << " settingsMap[frameIndex]:" << settingsMap["frameIndex"];
|
||||
qDebug(" frameIndex: %20.5f", frameIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
setAnimationFrameIndex(frameIndex);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
void setModelURL(const QString& url) { _modelURL = url; }
|
||||
void setAnimationURL(const QString& url);
|
||||
static const float DEFAULT_ANIMATION_FRAME_INDEX;
|
||||
void setAnimationFrameIndex(float value) { _animationLoop.setFrameIndex(value); }
|
||||
void setAnimationFrameIndex(float value);
|
||||
void setAnimationSettings(const QString& value);
|
||||
|
||||
static const bool DEFAULT_ANIMATION_IS_PLAYING;
|
||||
|
|
|
@ -5,11 +5,11 @@ setup_hifi_library()
|
|||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared networking octree voxels)
|
||||
link_hifi_libraries(shared gpu model networking octree voxels)
|
||||
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}")
|
||||
target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -24,8 +24,10 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
class QIODevice;
|
||||
#include <model/Geometry.h>
|
||||
#include <model/Material.h>
|
||||
|
||||
class QIODevice;
|
||||
class FBXNode;
|
||||
|
||||
typedef QList<FBXNode> FBXNodeList;
|
||||
|
@ -131,6 +133,7 @@ public:
|
|||
FBXTexture emissiveTexture;
|
||||
|
||||
QString materialID;
|
||||
model::MaterialPointer _material;
|
||||
};
|
||||
|
||||
/// A single mesh (with optional blendshapes) extracted from an FBX document.
|
||||
|
@ -159,6 +162,8 @@ public:
|
|||
|
||||
bool hasSpecularTexture() const;
|
||||
bool hasEmissiveTexture() const;
|
||||
|
||||
model::Mesh _mesh;
|
||||
};
|
||||
|
||||
/// A single animation frame extracted from an FBX document.
|
||||
|
|
|
@ -19,7 +19,7 @@ elseif (WIN32)
|
|||
# we're using static GLEW, so define GLEW_STATIC
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
|
||||
target_link_libraries(${TARGET_NAME} opengl32.lib)
|
||||
target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} opengl32.lib)
|
||||
|
||||
# need to bubble up the GLEW_INCLUDE_DIRS
|
||||
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${GLEW_INCLUDE_DIRS}")
|
||||
|
@ -44,5 +44,5 @@ else ()
|
|||
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${OPENGL_INCLUDE_DIR}")
|
||||
endif (APPLE)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -107,6 +107,19 @@ void Batch::setInputFormat(const Stream::FormatPointer& format) {
|
|||
_params.push_back(_streamFormats.cache(format));
|
||||
}
|
||||
|
||||
void Batch::setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride) {
|
||||
ADD_COMMAND(setInputBuffer);
|
||||
|
||||
_params.push_back(stride);
|
||||
_params.push_back(offset);
|
||||
_params.push_back(_buffers.cache(buffer));
|
||||
_params.push_back(channel);
|
||||
}
|
||||
|
||||
void Batch::setInputBuffer(Slot channel, const BufferView& view) {
|
||||
setInputBuffer(channel, view._buffer, view._offset, Offset(view._stride));
|
||||
}
|
||||
|
||||
void Batch::setInputStream(Slot startChannel, const BufferStream& stream) {
|
||||
if (stream.getNumBuffers()) {
|
||||
const Buffers& buffers = stream.getBuffers();
|
||||
|
@ -118,15 +131,6 @@ void Batch::setInputStream(Slot startChannel, const BufferStream& stream) {
|
|||
}
|
||||
}
|
||||
|
||||
void Batch::setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride) {
|
||||
ADD_COMMAND(setInputBuffer);
|
||||
|
||||
_params.push_back(stride);
|
||||
_params.push_back(offset);
|
||||
_params.push_back(_buffers.cache(buffer));
|
||||
_params.push_back(channel);
|
||||
}
|
||||
|
||||
void Batch::setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset) {
|
||||
ADD_COMMAND(setIndexBuffer);
|
||||
|
||||
|
@ -153,3 +157,17 @@ void Batch::setProjectionTransform(const Transform& proj) {
|
|||
_params.push_back(_transforms.cache(proj));
|
||||
}
|
||||
|
||||
void Batch::setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size) {
|
||||
ADD_COMMAND(setUniformBuffer);
|
||||
|
||||
_params.push_back(size);
|
||||
_params.push_back(offset);
|
||||
_params.push_back(_buffers.cache(buffer));
|
||||
_params.push_back(slot);
|
||||
}
|
||||
|
||||
void Batch::setUniformBuffer(uint32 slot, const BufferView& view) {
|
||||
setUniformBuffer(slot, view._buffer, view._offset, view._size);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -72,8 +72,9 @@ public:
|
|||
// IndexBuffer
|
||||
void setInputFormat(const Stream::FormatPointer& format);
|
||||
|
||||
void setInputStream(Slot startChannel, const BufferStream& stream); // not a command, just unroll into a loop of setInputBuffer
|
||||
void setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride);
|
||||
void setInputBuffer(Slot channel, const BufferView& buffer); // not a command, just a shortcut from a BufferView
|
||||
void setInputStream(Slot startChannel, const BufferStream& stream); // not a command, just unroll into a loop of setInputBuffer
|
||||
|
||||
void setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset);
|
||||
|
||||
|
@ -87,6 +88,9 @@ public:
|
|||
void setViewTransform(const Transform& view);
|
||||
void setProjectionTransform(const Transform& proj);
|
||||
|
||||
// Shader Stage
|
||||
void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size);
|
||||
void setUniformBuffer(uint32 slot, const BufferView& view); // not a command, just a shortcut from a BufferView
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
|
@ -117,6 +121,7 @@ public:
|
|||
void _glUseProgram(GLuint program);
|
||||
void _glUniform1f(GLint location, GLfloat v0);
|
||||
void _glUniform2f(GLint location, GLfloat v0, GLfloat v1);
|
||||
void _glUniform4fv(GLint location, GLsizei count, const GLfloat* value);
|
||||
void _glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
|
||||
void _glMatrixMode(GLenum mode);
|
||||
|
@ -161,6 +166,8 @@ public:
|
|||
COMMAND_setViewTransform,
|
||||
COMMAND_setProjectionTransform,
|
||||
|
||||
COMMAND_setUniformBuffer,
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
|
@ -187,6 +194,7 @@ public:
|
|||
COMMAND_glUseProgram,
|
||||
COMMAND_glUniform1f,
|
||||
COMMAND_glUniform2f,
|
||||
COMMAND_glUniform4fv,
|
||||
COMMAND_glUniformMatrix4fv,
|
||||
|
||||
COMMAND_glMatrixMode,
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#define hifi_gpu_Context_h
|
||||
|
||||
#include <assert.h>
|
||||
#include "GPUConfig.h"
|
||||
|
||||
#include "Resource.h"
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
#define hifi_gpu_Format_h
|
||||
|
||||
#include <assert.h>
|
||||
#include "GPUConfig.h"
|
||||
|
||||
|
||||
namespace gpu {
|
||||
|
||||
|
@ -94,7 +92,8 @@ static const int DIMENSION_COUNT[NUM_DIMENSIONS] = {
|
|||
// Semantic of an Element
|
||||
// Provide information on how to use the element
|
||||
enum Semantic {
|
||||
RGB = 0,
|
||||
RAW = 0, // used as RAW memory
|
||||
RGB,
|
||||
RGBA,
|
||||
XYZ,
|
||||
XYZW,
|
||||
|
@ -104,6 +103,8 @@ enum Semantic {
|
|||
DIR_XYZ,
|
||||
UV,
|
||||
R8,
|
||||
INDEX, //used by index buffer of a mesh
|
||||
PART, // used by part buffer of a mesh
|
||||
|
||||
NUM_SEMANTICS,
|
||||
};
|
||||
|
@ -119,7 +120,7 @@ public:
|
|||
_type(type)
|
||||
{}
|
||||
Element() :
|
||||
_semantic(R8),
|
||||
_semantic(RAW),
|
||||
_dimension(SCALAR),
|
||||
_type(INT8)
|
||||
{}
|
||||
|
|
|
@ -31,6 +31,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_setViewTransform),
|
||||
(&::gpu::GLBackend::do_setProjectionTransform),
|
||||
|
||||
(&::gpu::GLBackend::do_setUniformBuffer),
|
||||
|
||||
(&::gpu::GLBackend::do_glEnable),
|
||||
(&::gpu::GLBackend::do_glDisable),
|
||||
|
||||
|
@ -54,6 +56,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_glUseProgram),
|
||||
(&::gpu::GLBackend::do_glUniform1f),
|
||||
(&::gpu::GLBackend::do_glUniform2f),
|
||||
(&::gpu::GLBackend::do_glUniform4fv),
|
||||
(&::gpu::GLBackend::do_glUniformMatrix4fv),
|
||||
|
||||
(&::gpu::GLBackend::do_glMatrixMode),
|
||||
|
@ -483,6 +486,25 @@ void GLBackend::updateTransform() {
|
|||
}
|
||||
}
|
||||
|
||||
void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
|
||||
GLuint slot = batch._params[paramOffset + 3]._uint;
|
||||
BufferPointer uniformBuffer = batch._buffers.get(batch._params[paramOffset + 2]._uint);
|
||||
GLintptr rangeStart = batch._params[paramOffset + 1]._uint;
|
||||
GLsizeiptr rangeSize = batch._params[paramOffset + 0]._uint;
|
||||
#if defined(Q_OS_MAC)
|
||||
GLfloat* data = (GLfloat*) (uniformBuffer->getData() + rangeStart);
|
||||
glUniform4fv(slot, rangeSize / sizeof(GLfloat[4]), data);
|
||||
#else
|
||||
GLuint bo = getBufferID(*uniformBuffer);
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, slot, bo, rangeStart, rangeSize);
|
||||
|
||||
// glUniformBufferEXT(_shader._program, slot, bo);
|
||||
|
||||
//glBindBufferBase(GL_UNIFORM_BUFFER, slot, bo);
|
||||
#endif
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
|
@ -672,7 +694,10 @@ void Batch::_glUseProgram(GLuint program) {
|
|||
DO_IT_NOW(_glUseProgram, 1);
|
||||
}
|
||||
void GLBackend::do_glUseProgram(Batch& batch, uint32 paramOffset) {
|
||||
glUseProgram(batch._params[paramOffset]._uint);
|
||||
|
||||
_shader._program = batch._params[paramOffset]._uint;
|
||||
glUseProgram(_shader._program);
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
|
@ -708,6 +733,25 @@ void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) {
|
|||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
|
||||
ADD_COMMAND_GL(glUniform4fv);
|
||||
|
||||
const int VEC4_SIZE = 4 * sizeof(float);
|
||||
_params.push_back(cacheData(count * VEC4_SIZE, value));
|
||||
_params.push_back(count);
|
||||
_params.push_back(location);
|
||||
|
||||
DO_IT_NOW(_glUniform4fv, 3);
|
||||
}
|
||||
void GLBackend::do_glUniform4fv(Batch& batch, uint32 paramOffset) {
|
||||
glUniform4fv(
|
||||
batch._params[paramOffset + 2]._int,
|
||||
batch._params[paramOffset + 1]._uint,
|
||||
(const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint));
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
ADD_COMMAND_GL(glUniformMatrix4fv);
|
||||
|
||||
|
|
|
@ -122,6 +122,19 @@ protected:
|
|||
_lastMode(GL_TEXTURE) {}
|
||||
} _transform;
|
||||
|
||||
// Shader Stage
|
||||
void do_setUniformBuffer(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void updateShader();
|
||||
struct ShaderStageState {
|
||||
|
||||
GLuint _program;
|
||||
|
||||
ShaderStageState() :
|
||||
_program(0) {}
|
||||
} _shader;
|
||||
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
|
@ -148,6 +161,7 @@ protected:
|
|||
void do_glUseProgram(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform1f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform2f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform4fv(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glMatrixMode(Batch& batch, uint32 paramOffset);
|
||||
|
|
|
@ -67,6 +67,26 @@ Resource::Sysmem::Sysmem(Size size, const Byte* bytes) :
|
|||
}
|
||||
}
|
||||
|
||||
Resource::Sysmem::Sysmem(const Sysmem& sysmem) :
|
||||
_stamp(0),
|
||||
_size(0),
|
||||
_data(NULL)
|
||||
{
|
||||
if (sysmem.getSize() > 0) {
|
||||
_size = allocateMemory(&_data, sysmem.getSize());
|
||||
if (_size >= sysmem.getSize()) {
|
||||
if (sysmem.readData()) {
|
||||
memcpy(_data, sysmem.readData(), sysmem.getSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Resource::Sysmem& Resource::Sysmem::operator=(const Sysmem& sysmem) {
|
||||
setData(sysmem.getSize(), sysmem.readData());
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Resource::Sysmem::~Sysmem() {
|
||||
deallocateMemory( _data, _size );
|
||||
_data = NULL;
|
||||
|
@ -75,7 +95,7 @@ Resource::Sysmem::~Sysmem() {
|
|||
|
||||
Resource::Size Resource::Sysmem::allocate(Size size) {
|
||||
if (size != _size) {
|
||||
Byte* newData = 0;
|
||||
Byte* newData = NULL;
|
||||
Size newSize = 0;
|
||||
if (size > 0) {
|
||||
Size allocated = allocateMemory(&newData, size);
|
||||
|
@ -96,7 +116,7 @@ Resource::Size Resource::Sysmem::allocate(Size size) {
|
|||
|
||||
Resource::Size Resource::Sysmem::resize(Size size) {
|
||||
if (size != _size) {
|
||||
Byte* newData = 0;
|
||||
Byte* newData = NULL;
|
||||
Size newSize = 0;
|
||||
if (size > 0) {
|
||||
Size allocated = allocateMemory(&newData, size);
|
||||
|
@ -152,19 +172,35 @@ Resource::Size Resource::Sysmem::append(Size size, const Byte* bytes) {
|
|||
|
||||
Buffer::Buffer() :
|
||||
Resource(),
|
||||
_sysmem(NULL),
|
||||
_sysmem(new Sysmem()),
|
||||
_gpuObject(NULL) {
|
||||
_sysmem = new Sysmem();
|
||||
}
|
||||
|
||||
Buffer::Buffer(Size size, const Byte* bytes) :
|
||||
Resource(),
|
||||
_sysmem(new Sysmem(size, bytes)),
|
||||
_gpuObject(NULL) {
|
||||
}
|
||||
|
||||
Buffer::Buffer(const Buffer& buf) :
|
||||
Resource(),
|
||||
_sysmem(new Sysmem(buf.getSysmem())),
|
||||
_gpuObject(NULL) {
|
||||
}
|
||||
|
||||
Buffer& Buffer::operator=(const Buffer& buf) {
|
||||
(*_sysmem) = buf.getSysmem();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
if (_sysmem) {
|
||||
delete _sysmem;
|
||||
_sysmem = 0;
|
||||
_sysmem = NULL;
|
||||
}
|
||||
if (_gpuObject) {
|
||||
delete _gpuObject;
|
||||
_gpuObject = 0;
|
||||
_gpuObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,15 @@
|
|||
#define hifi_gpu_Resource_h
|
||||
|
||||
#include <assert.h>
|
||||
#include "GPUConfig.h"
|
||||
|
||||
#include "Format.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QSharedPointer>
|
||||
#ifdef _DEBUG
|
||||
#include <QDebug>
|
||||
#endif
|
||||
|
||||
namespace gpu {
|
||||
|
||||
|
@ -29,7 +31,7 @@ typedef int Stamp;
|
|||
class Resource {
|
||||
public:
|
||||
typedef unsigned char Byte;
|
||||
typedef unsigned int Size;
|
||||
typedef unsigned int Size;
|
||||
|
||||
static const Size NOT_ALLOCATED = -1;
|
||||
|
||||
|
@ -47,6 +49,8 @@ protected:
|
|||
|
||||
Sysmem();
|
||||
Sysmem(Size size, const Byte* bytes);
|
||||
Sysmem(const Sysmem& sysmem); // deep copy of the sysmem buffer
|
||||
Sysmem& operator=(const Sysmem& sysmem); // deep copy of the sysmem buffer
|
||||
~Sysmem();
|
||||
|
||||
Size getSize() const { return _size; }
|
||||
|
@ -78,10 +82,8 @@ protected:
|
|||
inline const Byte* readData() const { return _data; }
|
||||
inline Byte* editData() { _stamp++; return _data; }
|
||||
|
||||
template< typename T >
|
||||
const T* read() const { return reinterpret_cast< T* > ( _data ); }
|
||||
template< typename T >
|
||||
T* edit() { _stamp++; return reinterpret_cast< T* > ( _data ); }
|
||||
template< typename T > const T* read() const { return reinterpret_cast< T* > ( _data ); }
|
||||
template< typename T > T* edit() { _stamp++; return reinterpret_cast< T* > ( _data ); }
|
||||
|
||||
// Access the current version of the sysmem, used to compare if copies are in sync
|
||||
inline Stamp getStamp() const { return _stamp; }
|
||||
|
@ -90,9 +92,6 @@ protected:
|
|||
static void deallocateMemory(Byte* memDeallocated, Size size);
|
||||
|
||||
private:
|
||||
Sysmem(const Sysmem& sysmem) {}
|
||||
Sysmem &operator=(const Sysmem& other) {return *this;}
|
||||
|
||||
Stamp _stamp;
|
||||
Size _size;
|
||||
Byte* _data;
|
||||
|
@ -104,12 +103,15 @@ class Buffer : public Resource {
|
|||
public:
|
||||
|
||||
Buffer();
|
||||
Buffer(const Buffer& buf);
|
||||
Buffer(Size size, const Byte* bytes);
|
||||
Buffer(const Buffer& buf); // deep copy of the sysmem buffer
|
||||
Buffer& operator=(const Buffer& buf); // deep copy of the sysmem buffer
|
||||
~Buffer();
|
||||
|
||||
// The size in bytes of data stored in the buffer
|
||||
Size getSize() const { return getSysmem().getSize(); }
|
||||
const Byte* getData() const { return getSysmem().readData(); }
|
||||
Byte* editData() { return editSysmem().editData(); }
|
||||
|
||||
// Resize the buffer
|
||||
// Keep previous data [0 to min(pSize, mSize)]
|
||||
|
@ -130,7 +132,7 @@ public:
|
|||
|
||||
// Access the sysmem object.
|
||||
const Sysmem& getSysmem() const { assert(_sysmem); return (*_sysmem); }
|
||||
|
||||
Sysmem& editSysmem() { assert(_sysmem); return (*_sysmem); }
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -138,8 +140,6 @@ protected:
|
|||
|
||||
mutable GPUObject* _gpuObject;
|
||||
|
||||
Sysmem& editSysmem() { assert(_sysmem); return (*_sysmem); }
|
||||
|
||||
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||
GPUObject* getGPUObject() const { return _gpuObject; }
|
||||
|
@ -149,6 +149,277 @@ protected:
|
|||
|
||||
typedef QSharedPointer<Buffer> BufferPointer;
|
||||
typedef std::vector< BufferPointer > Buffers;
|
||||
|
||||
|
||||
class BufferView {
|
||||
public:
|
||||
typedef Resource::Size Size;
|
||||
typedef int Index;
|
||||
|
||||
BufferPointer _buffer;
|
||||
Size _offset;
|
||||
Size _size;
|
||||
Element _element;
|
||||
uint16 _stride;
|
||||
|
||||
BufferView() :
|
||||
_buffer(NULL),
|
||||
_offset(0),
|
||||
_size(0),
|
||||
_element(gpu::SCALAR, gpu::UINT8, gpu::RAW),
|
||||
_stride(1)
|
||||
{};
|
||||
|
||||
BufferView(const Element& element) :
|
||||
_buffer(NULL),
|
||||
_offset(0),
|
||||
_size(0),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
|
||||
// create the BufferView and own the Buffer
|
||||
BufferView(Buffer* newBuffer, const Element& element = Element(gpu::SCALAR, gpu::UINT8, gpu::RAW)) :
|
||||
_buffer(newBuffer),
|
||||
_offset(0),
|
||||
_size(newBuffer->getSize()),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
BufferView(const BufferPointer& buffer, const Element& element = Element(gpu::SCALAR, gpu::UINT8, gpu::RAW)) :
|
||||
_buffer(buffer),
|
||||
_offset(0),
|
||||
_size(buffer->getSize()),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
BufferView(const BufferPointer& buffer, Size offset, Size size, const Element& element = Element(gpu::SCALAR, gpu::UINT8, gpu::RAW)) :
|
||||
_buffer(buffer),
|
||||
_offset(offset),
|
||||
_size(size),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
~BufferView() {}
|
||||
BufferView(const BufferView& view) = default;
|
||||
BufferView& operator=(const BufferView& view) = default;
|
||||
|
||||
Size getNumElements() const { return _size / _element.getSize(); }
|
||||
|
||||
//Template iterator with random access on the buffer sysmem
|
||||
template<typename T>
|
||||
class Iterator : public std::iterator<std::random_access_iterator_tag, T, Index, T*, T&>
|
||||
{
|
||||
public:
|
||||
|
||||
Iterator(T* ptr = NULL) { _ptr = ptr; }
|
||||
Iterator(const Iterator<T>& iterator) = default;
|
||||
~Iterator() {}
|
||||
|
||||
Iterator<T>& operator=(const Iterator<T>& iterator) = default;
|
||||
Iterator<T>& operator=(T* ptr) {
|
||||
_ptr = ptr;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
if(_ptr)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const Iterator<T>& iterator) const { return (_ptr == iterator.getConstPtr()); }
|
||||
bool operator!=(const Iterator<T>& iterator) const { return (_ptr != iterator.getConstPtr()); }
|
||||
|
||||
Iterator<T>& operator+=(const Index& movement) {
|
||||
_ptr += movement;
|
||||
return (*this);
|
||||
}
|
||||
Iterator<T>& operator-=(const Index& movement) {
|
||||
_ptr -= movement;
|
||||
return (*this);
|
||||
}
|
||||
Iterator<T>& operator++() {
|
||||
++_ptr;
|
||||
return (*this);
|
||||
}
|
||||
Iterator<T>& operator--() {
|
||||
--_ptr;
|
||||
return (*this);
|
||||
}
|
||||
Iterator<T> operator++(Index) {
|
||||
auto temp(*this);
|
||||
++_ptr;
|
||||
return temp;
|
||||
}
|
||||
Iterator<T> operator--(Index) {
|
||||
auto temp(*this);
|
||||
--_ptr;
|
||||
return temp;
|
||||
}
|
||||
Iterator<T> operator+(const Index& movement) {
|
||||
auto oldPtr = _ptr;
|
||||
_ptr += movement;
|
||||
auto temp(*this);
|
||||
_ptr = oldPtr;
|
||||
return temp;
|
||||
}
|
||||
Iterator<T> operator-(const Index& movement) {
|
||||
auto oldPtr = _ptr;
|
||||
_ptr -= movement;
|
||||
auto temp(*this);
|
||||
_ptr = oldPtr;
|
||||
return temp;
|
||||
}
|
||||
|
||||
Index operator-(const Iterator<T>& iterator) { return (iterator.getPtr() - this->getPtr())/sizeof(T); }
|
||||
|
||||
T& operator*(){return *_ptr;}
|
||||
const T& operator*()const{return *_ptr;}
|
||||
T* operator->(){return _ptr;}
|
||||
|
||||
T* getPtr()const{return _ptr;}
|
||||
const T* getConstPtr()const{return _ptr;}
|
||||
|
||||
protected:
|
||||
|
||||
T* _ptr;
|
||||
};
|
||||
|
||||
template <typename T> Iterator<T> begin() { return Iterator<T>(&edit<T>(0)); }
|
||||
template <typename T> Iterator<T> end() { return Iterator<T>(&edit<T>(getNum<T>())); }
|
||||
template <typename T> Iterator<const T> cbegin() const { return Iterator<const T>(&get<T>(0)); }
|
||||
template <typename T> Iterator<const T> cend() const { return Iterator<const T>(&get<T>(getNum<T>())); }
|
||||
|
||||
// the number of elements of the specified type fitting in the view size
|
||||
template <typename T> Index getNum() const {
|
||||
return Index(_size / sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T> const T& get() const {
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - _offset)) {
|
||||
qDebug() << "Accessing buffer in non allocated memory, element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - _offset);
|
||||
}
|
||||
if (sizeof(T) > _size) {
|
||||
qDebug() << "Accessing buffer outside the BufferView range, element size = " << sizeof(T) << " when bufferView size = " << _size;
|
||||
}
|
||||
#endif
|
||||
const T* t = (reinterpret_cast<const T*> (_buffer->getData() + _offset));
|
||||
return *(t);
|
||||
}
|
||||
|
||||
template <typename T> T& edit() {
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - _offset)) {
|
||||
qDebug() << "Accessing buffer in non allocated memory, element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - _offset);
|
||||
}
|
||||
if (sizeof(T) > _size) {
|
||||
qDebug() << "Accessing buffer outside the BufferView range, element size = " << sizeof(T) << " when bufferView size = " << _size;
|
||||
}
|
||||
#endif
|
||||
T* t = (reinterpret_cast<T*> (_buffer->editData() + _offset));
|
||||
return *(t);
|
||||
}
|
||||
|
||||
template <typename T> const T& get(const Index index) const {
|
||||
Resource::Size elementOffset = index * sizeof(T) + _offset;
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - elementOffset)) {
|
||||
qDebug() << "Accessing buffer in non allocated memory, index = " << index << ", element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - elementOffset);
|
||||
}
|
||||
if (index > getNum<T>()) {
|
||||
qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum<T>();
|
||||
}
|
||||
#endif
|
||||
return *(reinterpret_cast<const T*> (_buffer->getData() + elementOffset));
|
||||
}
|
||||
|
||||
template <typename T> T& edit(const Index index) const {
|
||||
Resource::Size elementOffset = index * sizeof(T) + _offset;
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - elementOffset)) {
|
||||
qDebug() << "Accessing buffer in non allocated memory, index = " << index << ", element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - elementOffset);
|
||||
}
|
||||
if (index > getNum<T>()) {
|
||||
qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum<T>();
|
||||
}
|
||||
#endif
|
||||
return *(reinterpret_cast<T*> (_buffer->editData() + elementOffset));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// TODO: For now TextureView works with Buffer as a place holder for the Texture.
|
||||
// The overall logic should be about the same except that the Texture will be a real GL Texture under the hood
|
||||
class TextureView {
|
||||
public:
|
||||
typedef Resource::Size Size;
|
||||
typedef int Index;
|
||||
|
||||
BufferPointer _buffer;
|
||||
Size _offset;
|
||||
Size _size;
|
||||
Element _element;
|
||||
uint16 _stride;
|
||||
|
||||
TextureView() :
|
||||
_buffer(NULL),
|
||||
_offset(0),
|
||||
_size(0),
|
||||
_element(gpu::VEC3, gpu::UINT8, gpu::RGB),
|
||||
_stride(1)
|
||||
{};
|
||||
|
||||
TextureView(const Element& element) :
|
||||
_buffer(NULL),
|
||||
_offset(0),
|
||||
_size(0),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
|
||||
// create the BufferView and own the Buffer
|
||||
TextureView(Buffer* newBuffer, const Element& element) :
|
||||
_buffer(newBuffer),
|
||||
_offset(0),
|
||||
_size(newBuffer->getSize()),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
TextureView(const BufferPointer& buffer, const Element& element) :
|
||||
_buffer(buffer),
|
||||
_offset(0),
|
||||
_size(buffer->getSize()),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
TextureView(const BufferPointer& buffer, Size offset, Size size, const Element& element) :
|
||||
_buffer(buffer),
|
||||
_offset(offset),
|
||||
_size(size),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
~TextureView() {}
|
||||
TextureView(const TextureView& view) = default;
|
||||
TextureView& operator=(const TextureView& view) = default;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ void Stream::Format::evaluateCache() {
|
|||
_elementTotalSize = 0;
|
||||
for(AttributeMap::iterator it = _attributes.begin(); it != _attributes.end(); it++) {
|
||||
Attribute& attrib = (*it).second;
|
||||
Channel& channel = _channels[attrib._channel];
|
||||
ChannelInfo& channel = _channels[attrib._channel];
|
||||
channel._slots.push_back(attrib._slot);
|
||||
channel._stride = std::max(channel._stride, attrib.getSize() + attrib._offset);
|
||||
channel._netSize += attrib.getSize();
|
||||
|
@ -41,7 +41,7 @@ BufferStream::BufferStream() :
|
|||
BufferStream::~BufferStream() {
|
||||
}
|
||||
|
||||
void BufferStream::addBuffer(BufferPointer& buffer, Offset offset, Offset stride) {
|
||||
void BufferStream::addBuffer(const BufferPointer& buffer, Offset offset, Offset stride) {
|
||||
_buffers.push_back(buffer);
|
||||
_offsets.push_back(offset);
|
||||
_strides.push_back(stride);
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#define hifi_gpu_Stream_h
|
||||
|
||||
#include <assert.h>
|
||||
#include "GPUConfig.h"
|
||||
|
||||
#include "Resource.h"
|
||||
#include "Format.h"
|
||||
|
@ -83,16 +82,16 @@ public:
|
|||
public:
|
||||
typedef std::map< Slot, Attribute > AttributeMap;
|
||||
|
||||
class Channel {
|
||||
class ChannelInfo {
|
||||
public:
|
||||
std::vector< Slot > _slots;
|
||||
std::vector< Offset > _offsets;
|
||||
Offset _stride;
|
||||
uint32 _netSize;
|
||||
|
||||
Channel() : _stride(0), _netSize(0) {}
|
||||
ChannelInfo() : _stride(0), _netSize(0) {}
|
||||
};
|
||||
typedef std::map< Slot, Channel > ChannelMap;
|
||||
typedef std::map< Slot, ChannelInfo > ChannelMap;
|
||||
|
||||
Format() :
|
||||
_attributes(),
|
||||
|
@ -104,6 +103,7 @@ public:
|
|||
|
||||
uint8 getNumChannels() const { return _channels.size(); }
|
||||
const ChannelMap& getChannels() const { return _channels; }
|
||||
const Offset getChannelStride(Slot channel) const { return _channels.at(channel)._stride; }
|
||||
|
||||
uint32 getElementTotalSize() const { return _elementTotalSize; }
|
||||
|
||||
|
@ -131,7 +131,7 @@ public:
|
|||
BufferStream();
|
||||
~BufferStream();
|
||||
|
||||
void addBuffer(BufferPointer& buffer, Offset offset, Offset stride);
|
||||
void addBuffer(const BufferPointer& buffer, Offset offset, Offset stride);
|
||||
|
||||
const Buffers& getBuffers() const { return _buffers; }
|
||||
const Offsets& getOffsets() const { return _offsets; }
|
||||
|
|
|
@ -10,5 +10,5 @@ link_hifi_libraries(shared networking)
|
|||
|
||||
include_glm()
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -353,7 +353,7 @@ void DatagramSequencer::sendRecordLost(const SendRecord& record) {
|
|||
if (_packetDropCount == 0 || record.packetNumber == _lastPacketDropped + 1) {
|
||||
_packetDropCount++;
|
||||
_lastPacketDropped = record.packetNumber;
|
||||
const int CONSECUTIVE_DROPS_BEFORE_REDUCTION = 3;
|
||||
const int CONSECUTIVE_DROPS_BEFORE_REDUCTION = 1;
|
||||
if (_packetDropCount >= CONSECUTIVE_DROPS_BEFORE_REDUCTION && record.packetNumber >= _packetRateDecreasePacketNumber) {
|
||||
_packetsPerGroup = qMax(_packetsPerGroup * 0.5f, 1.0f);
|
||||
_slowStartThreshold = _packetsPerGroup;
|
||||
|
|
11
libraries/model/CMakeLists.txt
Executable file
11
libraries/model/CMakeLists.txt
Executable file
|
@ -0,0 +1,11 @@
|
|||
set(TARGET_NAME model)
|
||||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library()
|
||||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared gpu)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
141
libraries/model/src/model/Geometry.cpp
Executable file
141
libraries/model/src/model/Geometry.cpp
Executable file
|
@ -0,0 +1,141 @@
|
|||
//
|
||||
// Geometry.cpp
|
||||
// libraries/model/src/model
|
||||
//
|
||||
// Created by Sam Gateau on 12/5/2014.
|
||||
// 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 "Geometry.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace model;
|
||||
|
||||
Mesh::Mesh() :
|
||||
_vertexBuffer(gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)),
|
||||
_indexBuffer(gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::INDEX)),
|
||||
_partBuffer(gpu::Element(gpu::VEC4, gpu::UINT32, gpu::PART)) {
|
||||
}
|
||||
|
||||
Mesh::Mesh(const Mesh& mesh) :
|
||||
_vertexFormat(mesh._vertexFormat),
|
||||
_vertexBuffer(mesh._vertexBuffer),
|
||||
_attributeBuffers(mesh._attributeBuffers),
|
||||
_indexBuffer(mesh._indexBuffer),
|
||||
_partBuffer(mesh._partBuffer) {
|
||||
}
|
||||
|
||||
Mesh::~Mesh() {
|
||||
}
|
||||
|
||||
void Mesh::setVertexBuffer(const BufferView& buffer) {
|
||||
_vertexBuffer = buffer;
|
||||
evalVertexFormat();
|
||||
}
|
||||
|
||||
void Mesh::addAttribute(Slot slot, const BufferView& buffer) {
|
||||
_attributeBuffers[slot] = buffer;
|
||||
evalVertexFormat();
|
||||
}
|
||||
|
||||
void Mesh::evalVertexFormat() {
|
||||
VertexFormat vf;
|
||||
int channelNum = 0;
|
||||
if (hasVertexData()) {
|
||||
vf.setAttribute(gpu::Stream::POSITION, channelNum, _vertexBuffer._element, 0);
|
||||
channelNum++;
|
||||
}
|
||||
for (auto attrib : _attributeBuffers) {
|
||||
vf.setAttribute(attrib.first, channelNum, attrib.second._element, 0);
|
||||
channelNum++;
|
||||
}
|
||||
|
||||
_vertexFormat = vf;
|
||||
}
|
||||
|
||||
void Mesh::setIndexBuffer(const BufferView& buffer) {
|
||||
_indexBuffer = buffer;
|
||||
}
|
||||
|
||||
void Mesh::setPartBuffer(const BufferView& buffer) {
|
||||
_partBuffer = buffer;
|
||||
}
|
||||
|
||||
const Box Mesh::evalPartBound(int partNum) const {
|
||||
Box box;
|
||||
if (partNum < _partBuffer.getNum<Part>()) {
|
||||
const Part& part = _partBuffer.get<Part>(partNum);
|
||||
auto index = _indexBuffer.cbegin<Index>();
|
||||
index += part._startIndex;
|
||||
auto endIndex = index;
|
||||
endIndex += part._numIndices;
|
||||
auto vertices = &_vertexBuffer.get<Vec3>(part._baseVertex);
|
||||
for (;index != endIndex; index++) {
|
||||
// skip primitive restart indices
|
||||
if ((*index) != PRIMITIVE_RESTART_INDEX) {
|
||||
box += vertices[(*index)];
|
||||
}
|
||||
}
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
const Box Mesh::evalPartBounds(int partStart, int partEnd, Boxes& bounds) const {
|
||||
Box totalBound;
|
||||
auto part = _partBuffer.cbegin<Part>() + partStart;
|
||||
auto partItEnd = _partBuffer.cbegin<Part>() + partEnd;
|
||||
|
||||
for (;part != partItEnd; part++) {
|
||||
|
||||
Box partBound;
|
||||
auto index = _indexBuffer.cbegin<uint>() + (*part)._startIndex;
|
||||
auto endIndex = index + (*part)._numIndices;
|
||||
auto vertices = &_vertexBuffer.get<Vec3>((*part)._baseVertex);
|
||||
for (;index != endIndex; index++) {
|
||||
// skip primitive restart indices
|
||||
if ((*index) != PRIMITIVE_RESTART_INDEX) {
|
||||
partBound += vertices[(*index)];
|
||||
}
|
||||
}
|
||||
|
||||
totalBound += partBound;
|
||||
}
|
||||
return totalBound;
|
||||
}
|
||||
|
||||
const gpu::BufferStream Mesh::makeBufferStream() const {
|
||||
gpu::BufferStream stream;
|
||||
|
||||
int channelNum = 0;
|
||||
if (hasVertexData()) {
|
||||
stream.addBuffer(_vertexBuffer._buffer, _vertexBuffer._offset, _vertexFormat.getChannelStride(channelNum));
|
||||
channelNum++;
|
||||
}
|
||||
for (auto attrib : _attributeBuffers) {
|
||||
BufferView& view = attrib.second;
|
||||
stream.addBuffer(view._buffer, view._offset, _vertexFormat.getChannelStride(channelNum));
|
||||
channelNum++;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
Geometry::Geometry() {
|
||||
}
|
||||
|
||||
Geometry::Geometry(const Geometry& geometry):
|
||||
_mesh(geometry._mesh),
|
||||
_boxes(geometry._boxes) {
|
||||
}
|
||||
|
||||
Geometry::~Geometry() {
|
||||
}
|
||||
|
||||
void Geometry::setMesh(const MeshPointer& mesh) {
|
||||
_mesh = mesh;
|
||||
}
|
||||
|
150
libraries/model/src/model/Geometry.h
Executable file
150
libraries/model/src/model/Geometry.h
Executable file
|
@ -0,0 +1,150 @@
|
|||
//
|
||||
// Geometry.h
|
||||
// libraries/model/src/model
|
||||
//
|
||||
// Created by Sam Gateau on 12/5/2014.
|
||||
// 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
|
||||
//
|
||||
#ifndef hifi_model_Geometry_h
|
||||
#define hifi_model_Geometry_h
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "AABox.h"
|
||||
|
||||
#include "gpu/Resource.h"
|
||||
#include "gpu/Stream.h"
|
||||
|
||||
namespace model {
|
||||
typedef gpu::BufferView::Index Index;
|
||||
typedef gpu::BufferView BufferView;
|
||||
typedef AABox Box;
|
||||
typedef std::vector< Box > Boxes;
|
||||
|
||||
class Mesh {
|
||||
public:
|
||||
const static Index PRIMITIVE_RESTART_INDEX = -1;
|
||||
|
||||
typedef gpu::BufferView BufferView;
|
||||
typedef std::vector< BufferView > BufferViews;
|
||||
|
||||
typedef gpu::Stream::Slot Slot;
|
||||
typedef gpu::Stream::Format VertexFormat;
|
||||
typedef std::map< Slot, BufferView > BufferViewMap;
|
||||
|
||||
typedef glm::vec3 Vec3;
|
||||
|
||||
Mesh();
|
||||
Mesh(const Mesh& mesh);
|
||||
Mesh& operator= (const Mesh& mesh) = default;
|
||||
virtual ~Mesh();
|
||||
|
||||
// Vertex buffer
|
||||
void setVertexBuffer(const BufferView& buffer);
|
||||
const BufferView& getVertexBuffer() const { return _vertexBuffer; }
|
||||
uint getNumVertices() const { return _vertexBuffer.getNumElements(); }
|
||||
bool hasVertexData() const { return !_vertexBuffer._buffer.isNull(); }
|
||||
|
||||
// Attribute Buffers
|
||||
int getNumAttributes() const { return _attributeBuffers.size(); }
|
||||
void addAttribute(Slot slot, const BufferView& buffer);
|
||||
|
||||
// Stream format
|
||||
const VertexFormat& getVertexFormat() const { return _vertexFormat; }
|
||||
|
||||
// Index Buffer
|
||||
void setIndexBuffer(const BufferView& buffer);
|
||||
const BufferView& getIndexBuffer() const { return _indexBuffer; }
|
||||
uint getNumIndices() const { return _indexBuffer.getNumElements(); }
|
||||
|
||||
// Access vertex position value
|
||||
const Vec3& getPos3(Index index) const { return _vertexBuffer.get<Vec3>(index); }
|
||||
|
||||
enum Topology {
|
||||
POINTS = 0,
|
||||
LINES,
|
||||
LINE_STRIP,
|
||||
TRIANGLES,
|
||||
TRIANGLE_STRIP,
|
||||
QUADS,
|
||||
QUAD_STRIP,
|
||||
|
||||
NUM_TOPOLOGIES,
|
||||
};
|
||||
|
||||
// Subpart of a mesh, describing the toplogy of the surface
|
||||
class Part {
|
||||
public:
|
||||
Index _startIndex;
|
||||
Index _numIndices;
|
||||
Index _baseVertex;
|
||||
Topology _topology;
|
||||
|
||||
Part() :
|
||||
_startIndex(0),
|
||||
_numIndices(0),
|
||||
_baseVertex(0),
|
||||
_topology(TRIANGLES)
|
||||
{}
|
||||
Part(Index startIndex, Index numIndices, Index baseVertex, Topology topology) :
|
||||
_startIndex(startIndex),
|
||||
_numIndices(numIndices),
|
||||
_baseVertex(baseVertex),
|
||||
_topology(topology)
|
||||
{}
|
||||
};
|
||||
|
||||
void setPartBuffer(const BufferView& buffer);
|
||||
const BufferView& getPartBuffer() const { return _partBuffer; }
|
||||
uint getNumParts() const { return _partBuffer.getNumElements(); }
|
||||
|
||||
// evaluate the bounding box of A part
|
||||
const Box evalPartBound(int partNum) const;
|
||||
// evaluate the bounding boxes of the parts in the range [start, end[ and fill the bounds parameter
|
||||
// the returned box is the bounding box of ALL the evaluated part bounds.
|
||||
const Box evalPartBounds(int partStart, int partEnd, Boxes& bounds) const;
|
||||
|
||||
|
||||
// Generate a BufferStream on the mesh vertices and attributes
|
||||
const gpu::BufferStream makeBufferStream() const;
|
||||
|
||||
protected:
|
||||
|
||||
VertexFormat _vertexFormat;
|
||||
|
||||
BufferView _vertexBuffer;
|
||||
BufferViewMap _attributeBuffers;
|
||||
|
||||
BufferView _indexBuffer;
|
||||
|
||||
BufferView _partBuffer;
|
||||
|
||||
void evalVertexFormat();
|
||||
|
||||
};
|
||||
typedef QSharedPointer< Mesh > MeshPointer;
|
||||
|
||||
|
||||
class Geometry {
|
||||
public:
|
||||
|
||||
Geometry();
|
||||
Geometry(const Geometry& geometry);
|
||||
~Geometry();
|
||||
|
||||
void setMesh(const MeshPointer& mesh);
|
||||
const MeshPointer& getMesh() const { return _mesh; }
|
||||
|
||||
protected:
|
||||
|
||||
MeshPointer _mesh;
|
||||
BufferView _boxes;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
92
libraries/model/src/model/Material.cpp
Executable file
92
libraries/model/src/model/Material.cpp
Executable file
|
@ -0,0 +1,92 @@
|
|||
//
|
||||
// Material.cpp
|
||||
// libraries/model/src/model
|
||||
//
|
||||
// Created by Sam Gateau on 12/10/2014.
|
||||
// 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 "Material.h"
|
||||
|
||||
using namespace model;
|
||||
|
||||
Material::Material() :
|
||||
_flags(0),
|
||||
_schemaBuffer(),
|
||||
_textureMap() {
|
||||
|
||||
// only if created from nothing shall we create the Buffer to store the properties
|
||||
Schema schema;
|
||||
_schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Buffer::Byte*) &schema));
|
||||
|
||||
|
||||
}
|
||||
|
||||
Material::Material(const Material& material) :
|
||||
_flags(material._flags),
|
||||
_schemaBuffer(material._schemaBuffer),
|
||||
_textureMap(material._textureMap) {
|
||||
}
|
||||
|
||||
Material& Material::operator= (const Material& material) {
|
||||
_flags = (material._flags);
|
||||
_schemaBuffer = (material._schemaBuffer);
|
||||
_textureMap = (material._textureMap);
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Material::~Material() {
|
||||
}
|
||||
|
||||
void Material::setDiffuse(const Color& diffuse) {
|
||||
if (glm::any(glm::greaterThan(diffuse, Color(0.0f)))) {
|
||||
_flags.set(DIFFUSE_BIT);
|
||||
} else {
|
||||
_flags.reset(DIFFUSE_BIT);
|
||||
}
|
||||
_schemaBuffer.edit<Schema>()._diffuse = diffuse;
|
||||
}
|
||||
|
||||
void Material::setSpecular(const Color& specular) {
|
||||
if (glm::any(glm::greaterThan(specular, Color(0.0f)))) {
|
||||
_flags.set(SPECULAR_BIT);
|
||||
} else {
|
||||
_flags.reset(SPECULAR_BIT);
|
||||
}
|
||||
_schemaBuffer.edit<Schema>()._specular = specular;
|
||||
}
|
||||
|
||||
void Material::setEmissive(const Color& emissive) {
|
||||
if (glm::any(glm::greaterThan(emissive, Color(0.0f)))) {
|
||||
_flags.set(EMISSIVE_BIT);
|
||||
} else {
|
||||
_flags.reset(EMISSIVE_BIT);
|
||||
}
|
||||
_schemaBuffer.edit<Schema>()._emissive = emissive;
|
||||
}
|
||||
|
||||
void Material::setShininess(float shininess) {
|
||||
if (shininess > 0.0f) {
|
||||
_flags.set(SHININESS_BIT);
|
||||
} else {
|
||||
_flags.reset(SHININESS_BIT);
|
||||
}
|
||||
_schemaBuffer.edit<Schema>()._shininess = shininess;
|
||||
}
|
||||
|
||||
void Material::setOpacity(float opacity) {
|
||||
if (opacity >= 1.0f) {
|
||||
_flags.reset(TRANSPARENT_BIT);
|
||||
} else {
|
||||
_flags.set(TRANSPARENT_BIT);
|
||||
}
|
||||
_schemaBuffer.edit<Schema>()._opacity = opacity;
|
||||
}
|
||||
|
||||
void Material::setTextureView(MapChannel channel, const TextureView& view) {
|
||||
_flags.set(DIFFUSE_MAP_BIT + channel);
|
||||
_textureMap[channel] = view;
|
||||
}
|
114
libraries/model/src/model/Material.h
Executable file
114
libraries/model/src/model/Material.h
Executable file
|
@ -0,0 +1,114 @@
|
|||
//
|
||||
// Material.h
|
||||
// libraries/model/src/model
|
||||
//
|
||||
// Created by Sam Gateau on 12/10/2014.
|
||||
// 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
|
||||
//
|
||||
#ifndef hifi_model_Material_h
|
||||
#define hifi_model_Material_h
|
||||
|
||||
#include <bitset>
|
||||
#include <map>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "gpu/Resource.h"
|
||||
|
||||
namespace model {
|
||||
typedef gpu::BufferView UniformBufferView;
|
||||
typedef gpu::TextureView TextureView;
|
||||
|
||||
class Material {
|
||||
public:
|
||||
|
||||
typedef glm::vec3 Color;
|
||||
|
||||
enum MapChannel {
|
||||
DIFFUSE_MAP = 0,
|
||||
SPECULAR_MAP,
|
||||
SHININESS_MAP,
|
||||
EMISSIVE_MAP,
|
||||
OPACITY_MAP,
|
||||
NORMAL_MAP,
|
||||
|
||||
NUM_MAPS,
|
||||
};
|
||||
typedef std::map<MapChannel, TextureView> TextureMap;
|
||||
|
||||
enum FlagBit {
|
||||
DIFFUSE_BIT = 0,
|
||||
SPECULAR_BIT,
|
||||
SHININESS_BIT,
|
||||
EMISSIVE_BIT,
|
||||
TRANSPARENT_BIT,
|
||||
|
||||
DIFFUSE_MAP_BIT,
|
||||
SPECULAR_MAP_BIT,
|
||||
SHININESS_MAP_BIT,
|
||||
EMISSIVE_MAP_BIT,
|
||||
OPACITY_MAP_BIT,
|
||||
NORMAL_MAP_BIT,
|
||||
|
||||
NUM_FLAGS,
|
||||
};
|
||||
typedef std::bitset<NUM_FLAGS> Flags;
|
||||
|
||||
Material();
|
||||
Material(const Material& material);
|
||||
Material& operator= (const Material& material);
|
||||
virtual ~Material();
|
||||
|
||||
const Color& getEmissive() const { return _schemaBuffer.get<Schema>()._emissive; }
|
||||
const Color& getDiffuse() const { return _schemaBuffer.get<Schema>()._diffuse; }
|
||||
const Color& getSpecular() const { return _schemaBuffer.get<Schema>()._specular; }
|
||||
float getShininess() const { return _schemaBuffer.get<Schema>()._shininess; }
|
||||
float getOpacity() const { return _schemaBuffer.get<Schema>()._opacity; }
|
||||
|
||||
void setDiffuse(const Color& diffuse);
|
||||
void setSpecular(const Color& specular);
|
||||
void setEmissive(const Color& emissive);
|
||||
void setShininess(float shininess);
|
||||
void setOpacity(float opacity);
|
||||
|
||||
// Schema to access the attribute values of the material
|
||||
class Schema {
|
||||
public:
|
||||
|
||||
Color _diffuse;
|
||||
float _opacity;
|
||||
Color _specular;
|
||||
float _shininess;
|
||||
Color _emissive;
|
||||
float _spare0;
|
||||
|
||||
Schema() :
|
||||
_diffuse(0.5f),
|
||||
_opacity(1.0f),
|
||||
_specular(0.03f),
|
||||
_shininess(0.1f),
|
||||
_emissive(0.0f)
|
||||
{}
|
||||
};
|
||||
|
||||
const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; }
|
||||
|
||||
void setTextureView(MapChannel channel, const TextureView& texture);
|
||||
const TextureMap& getTextureMap() const { return _textureMap; }
|
||||
|
||||
const Schema* getSchema() const { return &_schemaBuffer.get<Schema>(); }
|
||||
protected:
|
||||
|
||||
Flags _flags;
|
||||
UniformBufferView _schemaBuffer;
|
||||
TextureMap _textureMap;
|
||||
|
||||
};
|
||||
typedef QSharedPointer< Material > MaterialPointer;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -28,5 +28,5 @@ target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES} ${TBB_LIBRARIES})
|
|||
# append libcuckoo includes to our list of includes to bubble
|
||||
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${TBB_INCLUDE_DIRS}")
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -147,28 +147,21 @@ QUdpSocket& LimitedNodeList::getDTLSSocket() {
|
|||
}
|
||||
|
||||
void LimitedNodeList::changeSocketBufferSizes(int numBytes) {
|
||||
// change the socket send buffer size to be 1MB
|
||||
int oldBufferSize = 0;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
int sizeOfInt = sizeof(oldBufferSize);
|
||||
#else
|
||||
unsigned int sizeOfInt = sizeof(oldBufferSize);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int bufferOpt = (i == 0) ? SO_SNDBUF : SO_RCVBUF;
|
||||
|
||||
getsockopt(_nodeSocket.socketDescriptor(), SOL_SOCKET, bufferOpt, reinterpret_cast<char*>(&oldBufferSize), &sizeOfInt);
|
||||
|
||||
setsockopt(_nodeSocket.socketDescriptor(), SOL_SOCKET, bufferOpt, reinterpret_cast<const char*>(&numBytes),
|
||||
sizeof(numBytes));
|
||||
|
||||
QString bufferTypeString = (i == 0) ? "send" : "receive";
|
||||
|
||||
QAbstractSocket::SocketOption bufferOpt;
|
||||
QString bufferTypeString;
|
||||
if (i == 0) {
|
||||
bufferOpt = QAbstractSocket::SendBufferSizeSocketOption;
|
||||
bufferTypeString = "send";
|
||||
|
||||
} else {
|
||||
bufferOpt = QAbstractSocket::ReceiveBufferSizeSocketOption;
|
||||
bufferTypeString = "receive";
|
||||
}
|
||||
int oldBufferSize = _nodeSocket.socketOption(bufferOpt).toInt();
|
||||
if (oldBufferSize < numBytes) {
|
||||
int newBufferSize = 0;
|
||||
getsockopt(_nodeSocket.socketDescriptor(), SOL_SOCKET, bufferOpt, reinterpret_cast<char*>(&newBufferSize), &sizeOfInt);
|
||||
_nodeSocket.setSocketOption(bufferOpt, numBytes);
|
||||
int newBufferSize = _nodeSocket.socketOption(bufferOpt).toInt();
|
||||
|
||||
qDebug() << "Changed socket" << bufferTypeString << "buffer size from" << oldBufferSize << "to"
|
||||
<< newBufferSize << "bytes";
|
||||
|
|
|
@ -15,5 +15,5 @@ include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}")
|
|||
# append ZLIB and OpenSSL to our list of libraries to link
|
||||
target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -189,6 +189,9 @@ void OctreePersistThread::backup() {
|
|||
quint64 intervalToBackup = _backupInterval * MSECS_TO_USECS;
|
||||
|
||||
if (sinceLastBackup > intervalToBackup) {
|
||||
qDebug() << "Time since last backup [" << sinceLastBackup << "] exceeds backup interval ["
|
||||
<< intervalToBackup << "] doing backup now...";
|
||||
|
||||
struct tm* localTime = localtime(&_lastPersistTime);
|
||||
|
||||
QString backupFileName;
|
||||
|
@ -213,6 +216,8 @@ void OctreePersistThread::backup() {
|
|||
} else {
|
||||
qDebug() << "ERROR in backing up persist file...";
|
||||
}
|
||||
|
||||
_lastBackup = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,5 +15,5 @@ link_hifi_libraries(shared)
|
|||
## append BULLET to our list of libraries to link
|
||||
#list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${BULLET_LIBRARIES}")
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
set(TARGET_NAME render-utils)
|
||||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library(Widgets OpenGL Network Script)
|
||||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared gpu)
|
||||
|
||||
if (WIN32)
|
||||
find_package(GLUT REQUIRED)
|
||||
include_directories(SYSTEM "${GLUT_INCLUDE_DIRS}")
|
||||
endif ()
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
set(TARGET_NAME render-utils)
|
||||
|
||||
AUTOSCRIBE_SHADER_LIB()
|
||||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library(Widgets OpenGL Network Script)
|
||||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(animation fbx shared gpu)
|
||||
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
22
libraries/render-utils/src/Config.slh
Executable file
22
libraries/render-utils/src/Config.slh
Executable file
|
@ -0,0 +1,22 @@
|
|||
<!
|
||||
// Config.slh
|
||||
// interface/src
|
||||
//
|
||||
// Created by Sam Gateau on 12/17/14.
|
||||
// Copyright 2013 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
|
||||
!>
|
||||
<@if not CONFIG_SLH@>
|
||||
<@def CONFIG_SLH@>
|
||||
|
||||
<@if GLPROFILE == PC_GL @>
|
||||
<@def VERSION_HEADER #version 330 compatibility@>
|
||||
<@elif GLPROFILE == MAC_GL @>
|
||||
<@def VERSION_HEADER #version 120@>
|
||||
<@else@>
|
||||
<@def VERSION_HEADER #version 120@>
|
||||
<@endif@>
|
||||
|
||||
<@endif@>
|
|
@ -661,7 +661,290 @@ void GeometryCache::renderWireCube(float size) {
|
|||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight) {
|
||||
Vec2Pair key(topLeft, bottomRight);
|
||||
VerticesIndices& vbo = _quad2DVBOs[key];
|
||||
const int FLOATS_PER_VERTEX = 2;
|
||||
const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat);
|
||||
const int vertices = 4;
|
||||
const int indices = 4;
|
||||
if (vbo.first == 0) {
|
||||
int vertexPoints = vertices * FLOATS_PER_VERTEX;
|
||||
GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices, no normals because we're a 2D quad
|
||||
GLfloat* vertex = vertexData;
|
||||
static GLubyte cannonicalIndices[indices] = {0, 1, 2, 3};
|
||||
|
||||
vertex[0] = topLeft.x;
|
||||
vertex[1] = topLeft.y;
|
||||
vertex[2] = bottomRight.x;
|
||||
vertex[3] = topLeft.y;
|
||||
vertex[4] = bottomRight.x;
|
||||
vertex[5] = bottomRight.y;
|
||||
vertex[6] = topLeft.x;
|
||||
vertex[7] = bottomRight.y;
|
||||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
GLushort* index = indexData;
|
||||
for (int i = 0; i < indices; i++) {
|
||||
index[i] = cannonicalIndices[i];
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << "new quad VBO made -- _quad2DVBOs.size():" << _quad2DVBOs.size();
|
||||
#endif
|
||||
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
}
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(FLOATS_PER_VERTEX, GL_FLOAT, FLOATS_PER_VERTEX * sizeof(float), 0);
|
||||
glDrawRangeElementsEXT(GL_QUADS, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
void GeometryCache::renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight,
|
||||
const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomRight) {
|
||||
Vec2PairPair key(Vec2Pair(topLeft, bottomRight), Vec2Pair(texCoordTopLeft, texCoordBottomRight));
|
||||
|
||||
VerticesIndices& vbo = _quad2DTextureVBOs[key];
|
||||
const int FLOATS_PER_VERTEX = 2 * 2; // text coords & vertices
|
||||
const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat);
|
||||
const int vertices = 4;
|
||||
const int indices = 4;
|
||||
if (vbo.first == 0) {
|
||||
int vertexPoints = vertices * FLOATS_PER_VERTEX;
|
||||
GLfloat* vertexData = new GLfloat[vertexPoints]; // text coords & vertices
|
||||
GLfloat* vertex = vertexData;
|
||||
static GLubyte cannonicalIndices[indices] = {0, 1, 2, 3};
|
||||
int v = 0;
|
||||
|
||||
vertex[v++] = topLeft.x;
|
||||
vertex[v++] = topLeft.y;
|
||||
vertex[v++] = texCoordTopLeft.x;
|
||||
vertex[v++] = texCoordTopLeft.y;
|
||||
|
||||
vertex[v++] = bottomRight.x;
|
||||
vertex[v++] = topLeft.y;
|
||||
vertex[v++] = texCoordBottomRight.x;
|
||||
vertex[v++] = texCoordTopLeft.y;
|
||||
|
||||
vertex[v++] = bottomRight.x;
|
||||
vertex[v++] = bottomRight.y;
|
||||
vertex[v++] = texCoordBottomRight.x;
|
||||
vertex[v++] = texCoordBottomRight.y;
|
||||
|
||||
vertex[v++] = topLeft.x;
|
||||
vertex[v++] = bottomRight.y;
|
||||
vertex[v++] = texCoordTopLeft.x;
|
||||
vertex[v++] = texCoordBottomRight.y;
|
||||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
GLushort* index = indexData;
|
||||
for (int i = 0; i < indices; i++) {
|
||||
index[i] = cannonicalIndices[i];
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << "new quad + texture VBO made -- _quad2DTextureVBOs.size():" << _quad2DTextureVBOs.size();
|
||||
#endif
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
}
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glVertexPointer(2, GL_FLOAT, NUM_BYTES_PER_VERTEX, 0);
|
||||
glTexCoordPointer(2, GL_FLOAT, NUM_BYTES_PER_VERTEX, (const void *)(2 * sizeof(float)));
|
||||
|
||||
glDrawRangeElementsEXT(GL_QUADS, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomRight) {
|
||||
Vec3Pair key(topLeft, bottomRight);
|
||||
VerticesIndices& vbo = _quad3DVBOs[key];
|
||||
const int FLOATS_PER_VERTEX = 3;
|
||||
const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat);
|
||||
const int vertices = 4;
|
||||
const int indices = 4;
|
||||
if (vbo.first == 0) {
|
||||
int vertexPoints = vertices * FLOATS_PER_VERTEX;
|
||||
GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices
|
||||
GLfloat* vertex = vertexData;
|
||||
static GLubyte cannonicalIndices[indices] = {0, 1, 2, 3};
|
||||
int v = 0;
|
||||
|
||||
vertex[v++] = topLeft.x;
|
||||
vertex[v++] = topLeft.y;
|
||||
vertex[v++] = topLeft.z;
|
||||
|
||||
vertex[v++] = bottomRight.x;
|
||||
vertex[v++] = topLeft.y;
|
||||
vertex[v++] = topLeft.z;
|
||||
|
||||
vertex[v++] = bottomRight.x;
|
||||
vertex[v++] = bottomRight.y;
|
||||
vertex[v++] = bottomRight.z;
|
||||
|
||||
vertex[v++] = topLeft.x;
|
||||
vertex[v++] = bottomRight.y;
|
||||
vertex[v++] = bottomRight.z;
|
||||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
GLushort* index = indexData;
|
||||
for (int i = 0; i < indices; i++) {
|
||||
index[i] = cannonicalIndices[i];
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << "new quad VBO made -- _quad3DVBOs.size():" << _quad3DVBOs.size();
|
||||
#endif
|
||||
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
}
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(FLOATS_PER_VERTEX, GL_FLOAT, FLOATS_PER_VERTEX * sizeof(float), 0);
|
||||
glDrawRangeElementsEXT(GL_QUADS, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomLeft,
|
||||
const glm::vec3& bottomRight, const glm::vec3& topRight,
|
||||
const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft,
|
||||
const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight) {
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << "renderQuad() vec3 + texture VBO...";
|
||||
qDebug() << " topLeft:" << topLeft;
|
||||
qDebug() << " bottomLeft:" << bottomLeft;
|
||||
qDebug() << " bottomRight:" << bottomRight;
|
||||
qDebug() << " topRight:" << topRight;
|
||||
qDebug() << " texCoordTopLeft:" << texCoordTopLeft;
|
||||
qDebug() << " texCoordBottomRight:" << texCoordBottomRight;
|
||||
#endif //def WANT_DEBUG
|
||||
|
||||
Vec3PairVec2Pair key(Vec3Pair(topLeft, bottomRight), Vec2Pair(texCoordTopLeft, texCoordBottomRight));
|
||||
|
||||
VerticesIndices& vbo = _quad3DTextureVBOs[key];
|
||||
const int FLOATS_PER_VERTEX = 5; // text coords & vertices
|
||||
const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat);
|
||||
const int vertices = 4;
|
||||
const int indices = 4;
|
||||
if (vbo.first == 0) {
|
||||
int vertexPoints = vertices * FLOATS_PER_VERTEX;
|
||||
GLfloat* vertexData = new GLfloat[vertexPoints]; // text coords & vertices
|
||||
GLfloat* vertex = vertexData;
|
||||
static GLubyte cannonicalIndices[indices] = {0, 1, 2, 3};
|
||||
int v = 0;
|
||||
|
||||
vertex[v++] = topLeft.x;
|
||||
vertex[v++] = topLeft.y;
|
||||
vertex[v++] = topLeft.z;
|
||||
vertex[v++] = texCoordTopLeft.x;
|
||||
vertex[v++] = texCoordTopLeft.y;
|
||||
|
||||
vertex[v++] = bottomLeft.x;
|
||||
vertex[v++] = bottomLeft.y;
|
||||
vertex[v++] = bottomLeft.z;
|
||||
vertex[v++] = texCoordBottomLeft.x;
|
||||
vertex[v++] = texCoordBottomLeft.y;
|
||||
|
||||
vertex[v++] = bottomRight.x;
|
||||
vertex[v++] = bottomRight.y;
|
||||
vertex[v++] = bottomRight.z;
|
||||
vertex[v++] = texCoordBottomRight.x;
|
||||
vertex[v++] = texCoordBottomRight.y;
|
||||
|
||||
vertex[v++] = topRight.x;
|
||||
vertex[v++] = topRight.y;
|
||||
vertex[v++] = topRight.z;
|
||||
vertex[v++] = texCoordTopRight.x;
|
||||
vertex[v++] = texCoordTopRight.y;
|
||||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
GLushort* index = indexData;
|
||||
for (int i = 0; i < indices; i++) {
|
||||
index[i] = cannonicalIndices[i];
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << " _quad3DTextureVBOs.size():" << _quad3DTextureVBOs.size();
|
||||
#endif
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
}
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, NUM_BYTES_PER_VERTEX, 0);
|
||||
glTexCoordPointer(2, GL_FLOAT, NUM_BYTES_PER_VERTEX, (const void *)(3 * sizeof(float)));
|
||||
|
||||
glDrawRangeElementsEXT(GL_QUADS, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback, bool delayLoad) {
|
||||
return getResource(url, fallback, delayLoad).staticCast<NetworkGeometry>();
|
||||
}
|
||||
|
|
|
@ -31,6 +31,50 @@ class NetworkGeometry;
|
|||
class NetworkMesh;
|
||||
class NetworkTexture;
|
||||
|
||||
|
||||
typedef QPair<glm::vec2, glm::vec2> Vec2Pair;
|
||||
typedef QPair<Vec2Pair, Vec2Pair> Vec2PairPair;
|
||||
typedef QPair<glm::vec3, glm::vec3> Vec3Pair;
|
||||
typedef QPair<Vec3Pair, Vec2Pair> Vec3PairVec2Pair;
|
||||
|
||||
inline uint qHash(const glm::vec2& v, uint seed) {
|
||||
// multiply by prime numbers greater than the possible size
|
||||
return qHash(v.x + 5009 * v.y, seed);
|
||||
}
|
||||
|
||||
inline uint qHash(const Vec2Pair& v, uint seed) {
|
||||
// multiply by prime numbers greater than the possible size
|
||||
return qHash(v.first.x + 5009 * v.first.y + 5011 * v.second.x + 5021 * v.second.y, seed);
|
||||
}
|
||||
|
||||
inline uint qHash(const Vec2PairPair& v, uint seed) {
|
||||
// multiply by prime numbers greater than the possible size
|
||||
return qHash(v.first.first.x + 5009 * v.first.first.y
|
||||
+ 5011 * v.first.second.x + 5021 * v.first.second.y
|
||||
+ 5023 * v.second.first.x + 5039 * v.second.first.y
|
||||
+ 5051 * v.second.second.x + 5059 * v.second.second.y, seed);
|
||||
}
|
||||
|
||||
inline uint qHash(const glm::vec3& v, uint seed) {
|
||||
// multiply by prime numbers greater than the possible size
|
||||
return qHash(v.x + 5009 * v.y + 5011 * v.z, seed);
|
||||
}
|
||||
|
||||
inline uint qHash(const Vec3Pair& v, uint seed) {
|
||||
// multiply by prime numbers greater than the possible size
|
||||
return qHash(v.first.x + 5009 * v.first.y + 5011 * v.first.z
|
||||
+ 5021 * v.second.x + 5023 * v.second.y + 5039 * v.second.z, seed);
|
||||
}
|
||||
|
||||
inline uint qHash(const Vec3PairVec2Pair& v, uint seed) {
|
||||
// multiply by prime numbers greater than the possible size
|
||||
return qHash(v.first.first.x + 5009 * v.first.first.y + 5011 * v.first.first.z +
|
||||
5021 * v.first.second.x + 5023 * v.first.second.y + 5039 * v.first.second.z +
|
||||
5051 * v.second.first.x + 5059 * v.second.first.y +
|
||||
5077 * v.second.second.x + 5081 * v.second.second.y, seed);
|
||||
}
|
||||
|
||||
|
||||
/// Stores cached geometry.
|
||||
class GeometryCache : public ResourceCache {
|
||||
Q_OBJECT
|
||||
|
@ -46,6 +90,24 @@ public:
|
|||
void renderSolidCube(float size);
|
||||
void renderWireCube(float size);
|
||||
|
||||
|
||||
void renderQuad(int x, int y, int width, int height) { renderQuad(glm::vec2(x,y), glm::vec2(x + width, y + height)); }
|
||||
void renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight);
|
||||
|
||||
void renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight,
|
||||
const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomRight);
|
||||
|
||||
|
||||
void renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomRight);
|
||||
|
||||
//void renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomRight,
|
||||
// const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomRight);
|
||||
|
||||
void renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomLeft,
|
||||
const glm::vec3& bottomRight, const glm::vec3& topRight,
|
||||
const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft,
|
||||
const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight);
|
||||
|
||||
/// Loads geometry from the specified URL.
|
||||
/// \param fallback a fallback URL to load if the desired one is unavailable
|
||||
/// \param delayLoad if true, don't load the geometry immediately; wait until load is first requested
|
||||
|
@ -70,6 +132,11 @@ private:
|
|||
QHash<IntPair, VerticesIndices> _coneVBOs;
|
||||
QHash<float, VerticesIndices> _wireCubeVBOs;
|
||||
QHash<float, VerticesIndices> _solidCubeVBOs;
|
||||
QHash<Vec2Pair, VerticesIndices> _quad2DVBOs;
|
||||
QHash<Vec2PairPair, VerticesIndices> _quad2DTextureVBOs;
|
||||
QHash<Vec3Pair, VerticesIndices> _quad3DVBOs;
|
||||
QHash<Vec3PairVec2Pair, VerticesIndices> _quad3DTextureVBOs;
|
||||
|
||||
QHash<IntPair, QOpenGLBuffer> _gridBuffers;
|
||||
|
||||
QHash<QUrl, QWeakPointer<NetworkGeometry> > _networkGeometry;
|
||||
|
|
|
@ -35,6 +35,26 @@
|
|||
#include "GlowEffect.h"
|
||||
#include "Model.h"
|
||||
|
||||
#include "model_vert.h"
|
||||
#include "model_shadow_vert.h"
|
||||
#include "model_normal_map_vert.h"
|
||||
#include "model_lightmap_vert.h"
|
||||
#include "model_lightmap_normal_map_vert.h"
|
||||
#include "skin_model_vert.h"
|
||||
#include "skin_model_shadow_vert.h"
|
||||
#include "skin_model_normal_map_vert.h"
|
||||
|
||||
#include "model_frag.h"
|
||||
#include "model_shadow_frag.h"
|
||||
#include "model_normal_map_frag.h"
|
||||
#include "model_normal_specular_map_frag.h"
|
||||
#include "model_specular_map_frag.h"
|
||||
#include "model_lightmap_frag.h"
|
||||
#include "model_lightmap_normal_map_frag.h"
|
||||
#include "model_lightmap_normal_specular_map_frag.h"
|
||||
#include "model_lightmap_specular_map_frag.h"
|
||||
#include "model_translucent_frag.h"
|
||||
|
||||
|
||||
#define GLBATCH( call ) batch._##call
|
||||
//#define GLBATCH( call ) call
|
||||
|
@ -233,110 +253,71 @@ void Model::initJointTransforms() {
|
|||
|
||||
void Model::init() {
|
||||
if (!_program.isLinked()) {
|
||||
_program.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/model.vert");
|
||||
_program.addShaderFromSourceFile(QGLShader::Fragment, PathUtils::resourcesPath() + "shaders/model.frag");
|
||||
|
||||
_program.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
|
||||
_program.addShaderFromSourceCode(QGLShader::Fragment, model_frag);
|
||||
initProgram(_program, _locations);
|
||||
|
||||
_normalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/model_normal_map.vert");
|
||||
_normalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_normal_map.frag");
|
||||
|
||||
initProgram(_normalMapProgram, _normalMapLocations);
|
||||
|
||||
_specularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/model.vert");
|
||||
_specularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_specular_map.frag");
|
||||
|
||||
initProgram(_specularMapProgram, _specularMapLocations);
|
||||
|
||||
_normalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/model_normal_map.vert");
|
||||
_normalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_normal_specular_map.frag");
|
||||
|
||||
initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations);
|
||||
|
||||
_translucentProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/model.vert");
|
||||
_translucentProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_translucent.frag");
|
||||
|
||||
initProgram(_translucentProgram, _translucentLocations);
|
||||
|
||||
// Lightmap
|
||||
_lightmapProgram.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/model_lightmap.vert");
|
||||
_lightmapProgram.addShaderFromSourceFile(QGLShader::Fragment, PathUtils::resourcesPath() + "shaders/model_lightmap.frag");
|
||||
|
||||
initProgram(_lightmapProgram, _lightmapLocations);
|
||||
|
||||
_lightmapNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/model_lightmap_normal_map.vert");
|
||||
_lightmapNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_lightmap_normal_map.frag");
|
||||
|
||||
initProgram(_lightmapNormalMapProgram, _lightmapNormalMapLocations);
|
||||
|
||||
_lightmapSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/model_lightmap.vert");
|
||||
_lightmapSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_lightmap_specular_map.frag");
|
||||
|
||||
initProgram(_lightmapSpecularMapProgram, _lightmapSpecularMapLocations);
|
||||
|
||||
_lightmapNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/model_lightmap_normal_map.vert");
|
||||
_lightmapNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_lightmap_normal_specular_map.frag");
|
||||
|
||||
initProgram(_lightmapNormalSpecularMapProgram, _lightmapNormalSpecularMapLocations);
|
||||
// end lightmap
|
||||
|
||||
|
||||
_shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/model_shadow.vert");
|
||||
_shadowProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_shadow.frag");
|
||||
|
||||
_skinProgram.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/skin_model.vert");
|
||||
_skinProgram.addShaderFromSourceFile(QGLShader::Fragment, PathUtils::resourcesPath() + "shaders/model.frag");
|
||||
|
||||
initSkinProgram(_skinProgram, _skinLocations);
|
||||
|
||||
_skinNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/skin_model_normal_map.vert");
|
||||
_skinNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_normal_map.frag");
|
||||
|
||||
initSkinProgram(_skinNormalMapProgram, _skinNormalMapLocations);
|
||||
|
||||
_skinSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/skin_model.vert");
|
||||
_skinSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_specular_map.frag");
|
||||
|
||||
initSkinProgram(_skinSpecularMapProgram, _skinSpecularMapLocations);
|
||||
|
||||
_skinNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/skin_model_normal_map.vert");
|
||||
_skinNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_normal_specular_map.frag");
|
||||
|
||||
initSkinProgram(_skinNormalSpecularMapProgram, _skinNormalSpecularMapLocations);
|
||||
|
||||
_skinShadowProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/skin_model_shadow.vert");
|
||||
_skinShadowProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_shadow.frag");
|
||||
|
||||
initSkinProgram(_skinShadowProgram, _skinShadowLocations);
|
||||
|
||||
_skinTranslucentProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
PathUtils::resourcesPath() + "shaders/skin_model.vert");
|
||||
_skinTranslucentProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
PathUtils::resourcesPath() + "shaders/model_translucent.frag");
|
||||
|
||||
_normalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_normal_map_vert);
|
||||
_normalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_map_frag);
|
||||
initProgram(_normalMapProgram, _normalMapLocations);
|
||||
|
||||
_specularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
|
||||
_specularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_specular_map_frag);
|
||||
initProgram(_specularMapProgram, _specularMapLocations);
|
||||
|
||||
_normalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_normal_map_vert);
|
||||
_normalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_specular_map_frag);
|
||||
initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations);
|
||||
|
||||
_translucentProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
|
||||
_translucentProgram.addShaderFromSourceCode(QGLShader::Fragment, model_translucent_frag);
|
||||
initProgram(_translucentProgram, _translucentLocations);
|
||||
|
||||
// Lightmap
|
||||
_lightmapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_vert);
|
||||
_lightmapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_frag);
|
||||
initProgram(_lightmapProgram, _lightmapLocations);
|
||||
|
||||
_lightmapNormalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_normal_map_vert);
|
||||
_lightmapNormalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_normal_map_frag);
|
||||
initProgram(_lightmapNormalMapProgram, _lightmapNormalMapLocations);
|
||||
|
||||
_lightmapSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_vert);
|
||||
_lightmapSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_specular_map_frag);
|
||||
initProgram(_lightmapSpecularMapProgram, _lightmapSpecularMapLocations);
|
||||
|
||||
_lightmapNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_normal_map_vert);
|
||||
_lightmapNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_normal_specular_map_frag);
|
||||
initProgram(_lightmapNormalSpecularMapProgram, _lightmapNormalSpecularMapLocations);
|
||||
// end lightmap
|
||||
|
||||
|
||||
_shadowProgram.addShaderFromSourceCode(QGLShader::Vertex, model_shadow_vert);
|
||||
_shadowProgram.addShaderFromSourceCode(QGLShader::Fragment, model_shadow_frag);
|
||||
|
||||
_skinProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_vert);
|
||||
_skinProgram.addShaderFromSourceCode(QGLShader::Fragment, model_frag);
|
||||
initSkinProgram(_skinProgram, _skinLocations);
|
||||
|
||||
_skinNormalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_normal_map_vert);
|
||||
_skinNormalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_map_frag);
|
||||
initSkinProgram(_skinNormalMapProgram, _skinNormalMapLocations);
|
||||
|
||||
_skinSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
|
||||
_skinSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_specular_map_frag);
|
||||
initSkinProgram(_skinSpecularMapProgram, _skinSpecularMapLocations);
|
||||
|
||||
_skinNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_normal_map_vert);
|
||||
_skinNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_specular_map_frag);
|
||||
initSkinProgram(_skinNormalSpecularMapProgram, _skinNormalSpecularMapLocations);
|
||||
|
||||
_skinShadowProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_shadow_vert);
|
||||
_skinShadowProgram.addShaderFromSourceCode(QGLShader::Fragment, model_shadow_frag);
|
||||
initSkinProgram(_skinShadowProgram, _skinShadowLocations);
|
||||
|
||||
|
||||
_skinTranslucentProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_vert);
|
||||
_skinTranslucentProgram.addShaderFromSourceCode(QGLShader::Fragment, model_translucent_frag);
|
||||
initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,17 +10,16 @@
|
|||
//
|
||||
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include "GeometryCache.h"
|
||||
|
||||
#include "RenderUtil.h"
|
||||
|
||||
void renderFullscreenQuad(float sMin, float sMax, float tMin, float tMax) {
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(sMin, tMin);
|
||||
glVertex2f(-1.0f, -1.0f);
|
||||
glTexCoord2f(sMax, tMin);
|
||||
glVertex2f(1.0f, -1.0f);
|
||||
glTexCoord2f(sMax, tMax);
|
||||
glVertex2f(1.0f, 1.0f);
|
||||
glTexCoord2f(sMin, tMax);
|
||||
glVertex2f(-1.0f, 1.0f);
|
||||
glEnd();
|
||||
glm::vec2 topLeft(-1.0f, -1.0f);
|
||||
glm::vec2 bottomRight(1.0f, 1.0f);
|
||||
glm::vec2 texCoordTopLeft(sMin, tMin);
|
||||
glm::vec2 texCoordBottomRight(sMax, tMax);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
|
||||
}
|
||||
|
|
|
@ -81,9 +81,6 @@ int TextRenderer::draw(int x, int y, const char* str, float alpha) {
|
|||
((int(currentColor[2] * 255.0f) & 0xFF) << 16) |
|
||||
((int(currentColor[3] * 255.0f) & 0xFF) << 24);
|
||||
|
||||
// TODO: Remove that code once we test for performance improvments
|
||||
//glEnable(GL_TEXTURE_2D);
|
||||
|
||||
int maxHeight = 0;
|
||||
for (const char* ch = str; *ch != 0; ch++) {
|
||||
const Glyph& glyph = getGlyph(*ch);
|
||||
|
@ -111,20 +108,6 @@ int TextRenderer::draw(int x, int y, const char* str, float alpha) {
|
|||
float bt = glyph.location().y() * scale;
|
||||
float tt = (glyph.location().y() + glyph.bounds().height()) * scale;
|
||||
|
||||
// TODO: Remove that code once we test for performance improvments
|
||||
/*
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(ls, bt);
|
||||
glVertex2f(left, bottom);
|
||||
glTexCoord2f(rs, bt);
|
||||
glVertex2f(right, bottom);
|
||||
glTexCoord2f(rs, tt);
|
||||
glVertex2f(right, top);
|
||||
glTexCoord2f(ls, tt);
|
||||
glVertex2f(left, top);
|
||||
glEnd();
|
||||
*/
|
||||
|
||||
const int NUM_COORDS_SCALARS_PER_GLYPH = 16;
|
||||
float vertexBuffer[NUM_COORDS_SCALARS_PER_GLYPH] = { leftBottom.x, leftBottom.y, ls, bt,
|
||||
rightTop.x, leftBottom.y, rs, bt,
|
||||
|
@ -152,10 +135,6 @@ int TextRenderer::draw(int x, int y, const char* str, float alpha) {
|
|||
drawBatch();
|
||||
clearBatch();
|
||||
|
||||
// TODO: Remove that code once we test for performance improvments
|
||||
// glBindTexture(GL_TEXTURE_2D, 0);
|
||||
// glDisable(GL_TEXTURE_2D);
|
||||
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
|
|
6
interface/resources/shaders/model.frag → libraries/render-utils/src/model.slf
Normal file → Executable file
6
interface/resources/shaders/model.frag → libraries/render-utils/src/model.slf
Normal file → Executable file
|
@ -1,6 +1,6 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model.frag
|
||||
// fragment shader
|
||||
//
|
6
interface/resources/shaders/model.vert → libraries/render-utils/src/model.slv
Normal file → Executable file
6
interface/resources/shaders/model.vert → libraries/render-utils/src/model.slv
Normal file → Executable file
|
@ -1,6 +1,6 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model.vert
|
||||
// vertex shader
|
||||
//
|
5
interface/resources/shaders/model_lightmap.frag → libraries/render-utils/src/model_lightmap.slf
Normal file → Executable file
5
interface/resources/shaders/model_lightmap.frag → libraries/render-utils/src/model_lightmap.slf
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
#version 120
|
||||
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap.frag
|
||||
// fragment shader
|
5
interface/resources/shaders/model_lightmap.vert → libraries/render-utils/src/model_lightmap.slv
Normal file → Executable file
5
interface/resources/shaders/model_lightmap.vert → libraries/render-utils/src/model_lightmap.slv
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
#version 120
|
||||
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap.vert
|
||||
// vertex shader
|
5
interface/resources/shaders/model_lightmap_normal_map.frag → libraries/render-utils/src/model_lightmap_normal_map.slf
Normal file → Executable file
5
interface/resources/shaders/model_lightmap_normal_map.frag → libraries/render-utils/src/model_lightmap_normal_map.slf
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
#version 120
|
||||
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_normal_map.frag
|
||||
// fragment shader
|
5
interface/resources/shaders/model_lightmap_normal_map.vert → libraries/render-utils/src/model_lightmap_normal_map.slv
Normal file → Executable file
5
interface/resources/shaders/model_lightmap_normal_map.vert → libraries/render-utils/src/model_lightmap_normal_map.slv
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
#version 120
|
||||
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_normal_map.vert
|
||||
// vertex shader
|
|
@ -1,5 +1,6 @@
|
|||
#version 120
|
||||
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_normal_specular_map.frag
|
||||
// fragment shader
|
5
interface/resources/shaders/model_lightmap_specular_map.frag → libraries/render-utils/src/model_lightmap_specular_map.slf
Normal file → Executable file
5
interface/resources/shaders/model_lightmap_specular_map.frag → libraries/render-utils/src/model_lightmap_specular_map.slf
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
#version 120
|
||||
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_specular_map.frag
|
||||
// fragment shader
|
5
interface/resources/shaders/model_normal_map.frag → libraries/render-utils/src/model_normal_map.slf
Normal file → Executable file
5
interface/resources/shaders/model_normal_map.frag → libraries/render-utils/src/model_normal_map.slf
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
#version 120
|
||||
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_normal_map.frag
|
||||
// fragment shader
|
81
interface/resources/shaders/model_normal_map.vert → libraries/render-utils/src/model_normal_map.slv
Normal file → Executable file
81
interface/resources/shaders/model_normal_map.vert → libraries/render-utils/src/model_normal_map.slv
Normal file → Executable file
|
@ -1,40 +1,41 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 10/14/13.
|
||||
// Copyright 2013 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
|
||||
//
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
||||
// the tangent vector
|
||||
attribute vec3 tangent;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
// the interpolated tangent
|
||||
varying vec4 interpolatedTangent;
|
||||
|
||||
void main(void) {
|
||||
// transform and store the normal and tangent for interpolation
|
||||
interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0);
|
||||
interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0);
|
||||
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 10/14/13.
|
||||
// Copyright 2013 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
|
||||
//
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
||||
// the tangent vector
|
||||
attribute vec3 tangent;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
// the interpolated tangent
|
||||
varying vec4 interpolatedTangent;
|
||||
|
||||
void main(void) {
|
||||
// transform and store the normal and tangent for interpolation
|
||||
interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0);
|
||||
interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0);
|
||||
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
5
interface/resources/shaders/model_normal_specular_map.frag → libraries/render-utils/src/model_normal_specular_map.slf
Normal file → Executable file
5
interface/resources/shaders/model_normal_specular_map.frag → libraries/render-utils/src/model_normal_specular_map.slf
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
#version 120
|
||||
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_normal_specular_map.frag
|
||||
// fragment shader
|
5
interface/resources/shaders/model_shadow.frag → libraries/render-utils/src/model_shadow.slf
Normal file → Executable file
5
interface/resources/shaders/model_shadow.frag → libraries/render-utils/src/model_shadow.slf
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
#version 120
|
||||
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_shadow.frag
|
||||
// fragment shader
|
35
interface/resources/shaders/model_shadow.vert → libraries/render-utils/src/model_shadow.slv
Normal file → Executable file
35
interface/resources/shaders/model_shadow.vert → libraries/render-utils/src/model_shadow.slv
Normal file → Executable file
|
@ -1,17 +1,18 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model_shadow.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 3/24/14.
|
||||
// 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
|
||||
//
|
||||
|
||||
void main(void) {
|
||||
// just use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_shadow.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 3/24/14.
|
||||
// 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
|
||||
//
|
||||
|
||||
void main(void) {
|
||||
// just use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
5
interface/resources/shaders/model_specular_map.frag → libraries/render-utils/src/model_specular_map.slf
Normal file → Executable file
5
interface/resources/shaders/model_specular_map.frag → libraries/render-utils/src/model_specular_map.slf
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
#version 120
|
||||
|
||||
<@include Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_specular_map.frag
|
||||
// fragment shader
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue