mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 15:43:17 +02:00
Merge branch 'master' into 20639
This commit is contained in:
commit
7749b912ea
67 changed files with 933 additions and 772 deletions
|
@ -70,7 +70,7 @@ void Agent::handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointe
|
|||
// pull out the piggybacked packet and create a new QSharedPointer<NLPacket> for it
|
||||
int piggyBackedSizeWithHeader = packet->getPayloadSize() - statsMessageLength;
|
||||
|
||||
std::unique_ptr<char> buffer = std::unique_ptr<char>(new char[piggyBackedSizeWithHeader]);
|
||||
auto buffer = std::unique_ptr<char[]>(new char[piggyBackedSizeWithHeader]);
|
||||
memcpy(buffer.get(), packet->getPayload() + statsMessageLength, piggyBackedSizeWithHeader);
|
||||
|
||||
auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggyBackedSizeWithHeader, packet->getSenderSockAddr());
|
||||
|
@ -107,6 +107,7 @@ void Agent::handleAudioPacket(QSharedPointer<NLPacket> packet) {
|
|||
}
|
||||
|
||||
const QString AGENT_LOGGING_NAME = "agent";
|
||||
const int PING_INTERVAL = 1000;
|
||||
|
||||
void Agent::run() {
|
||||
ThreadedAssignment::commonInit(AGENT_LOGGING_NAME, NodeType::Agent);
|
||||
|
@ -118,6 +119,10 @@ void Agent::run() {
|
|||
<< NodeType::EntityServer
|
||||
);
|
||||
|
||||
_pingTimer = new QTimer(this);
|
||||
connect(_pingTimer, SIGNAL(timeout()), SLOT(sendPingRequests()));
|
||||
_pingTimer->start(PING_INTERVAL);
|
||||
|
||||
// figure out the URL for the script for this agent assignment
|
||||
QUrl scriptURL;
|
||||
if (_payload.isEmpty()) {
|
||||
|
@ -193,7 +198,27 @@ void Agent::run() {
|
|||
|
||||
void Agent::aboutToFinish() {
|
||||
_scriptEngine.stop();
|
||||
|
||||
|
||||
_pingTimer->stop();
|
||||
delete _pingTimer;
|
||||
|
||||
// our entity tree is going to go away so tell that to the EntityScriptingInterface
|
||||
DependencyManager::get<EntityScriptingInterface>()->setEntityTree(NULL);
|
||||
}
|
||||
|
||||
void Agent::sendPingRequests() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
nodeList->eachMatchingNode([](const SharedNodePointer& node)->bool {
|
||||
switch (node->getType()) {
|
||||
case NodeType::AvatarMixer:
|
||||
case NodeType::AudioMixer:
|
||||
case NodeType::EntityServer:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}, [nodeList](const SharedNodePointer& node) {
|
||||
nodeList->sendPacket(nodeList->constructPingPacket(), *node);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -58,11 +58,13 @@ private slots:
|
|||
void handleAudioPacket(QSharedPointer<NLPacket> packet);
|
||||
void handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode);
|
||||
void handleJurisdictionPacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode);
|
||||
void sendPingRequests();
|
||||
|
||||
private:
|
||||
ScriptEngine _scriptEngine;
|
||||
EntityEditPacketSender _entityEditSender;
|
||||
EntityTreeHeadlessViewer _entityViewer;
|
||||
QTimer* _pingTimer;
|
||||
|
||||
MixedAudioStream _receivedAudioStream;
|
||||
float _lastReceivedAudioLoudness;
|
||||
|
|
|
@ -927,9 +927,9 @@ void AudioMixer::parseSettingsObject(const QJsonObject &settingsObject) {
|
|||
const QString USE_STDEV_FOR_DESIRED_CALC_JSON_KEY = "use_stdev_for_desired_calc";
|
||||
_streamSettings._useStDevForJitterCalc = audioBufferGroupObject[USE_STDEV_FOR_DESIRED_CALC_JSON_KEY].toBool();
|
||||
if (_streamSettings._useStDevForJitterCalc) {
|
||||
qDebug() << "Using Philip's stdev method for jitter calc if dynamic jitter buffers enabled";
|
||||
qDebug() << "Using stdev method for jitter calc if dynamic jitter buffers enabled";
|
||||
} else {
|
||||
qDebug() << "Using Fred's max-gap method for jitter calc if dynamic jitter buffers enabled";
|
||||
qDebug() << "Using max-gap method for jitter calc if dynamic jitter buffers enabled";
|
||||
}
|
||||
|
||||
const QString WINDOW_STARVE_THRESHOLD_JSON_KEY = "window_starve_threshold";
|
||||
|
|
|
@ -38,5 +38,19 @@ if (WIN32)
|
|||
find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_INCLUDE_DIRS GLEW_LIBRARIES GLEW_DLL_PATH)
|
||||
|
||||
add_paths_to_fixup_libs(${GLEW_DLL_PATH})
|
||||
elseif (APPLE)
|
||||
else ()
|
||||
find_path(GLEW_INCLUDE_DIR GL/glew.h)
|
||||
find_library(GLEW_LIBRARY NAMES GLEW glew32 glew glew32s PATH_SUFFIXES lib64)
|
||||
|
||||
set(GLEW_INCLUDE_DIRS ${GLEW_INCLUDE_DIR})
|
||||
set(GLEW_LIBRARIES ${GLEW_LIBRARY})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(GLEW
|
||||
REQUIRED_VARS GLEW_INCLUDE_DIR GLEW_LIBRARY)
|
||||
|
||||
mark_as_advanced(GLEW_INCLUDE_DIR GLEW_LIBRARY)
|
||||
|
||||
endif ()
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ var RAD_TO_DEG = 180.0 / PI;
|
|||
var AZIMUTH_RATE = 90.0;
|
||||
var ALTITUDE_RATE = 200.0;
|
||||
var RADIUS_RATE = 1.0 / 100.0;
|
||||
var PAN_RATE = 50.0;
|
||||
var PAN_RATE = 250.0;
|
||||
|
||||
var Y_AXIS = {
|
||||
x: 0,
|
||||
|
@ -139,7 +139,7 @@ function handlePanMode(dx, dy) {
|
|||
var right = Quat.getRight(Camera.getOrientation());
|
||||
var distance = Vec3.length(vector);
|
||||
|
||||
var dv = Vec3.sum(Vec3.multiply(up, -distance * dy / PAN_RATE), Vec3.multiply(right, distance * dx / PAN_RATE));
|
||||
var dv = Vec3.sum(Vec3.multiply(up, distance * dy / PAN_RATE), Vec3.multiply(right, -distance * dx / PAN_RATE));
|
||||
|
||||
center = Vec3.sum(center, dv);
|
||||
position = Vec3.sum(position, dv);
|
||||
|
|
|
@ -50,7 +50,7 @@ void IceServer::processDatagrams() {
|
|||
while (_serverSocket.hasPendingDatagrams()) {
|
||||
// setup a buffer to read the packet into
|
||||
int packetSizeWithHeader = _serverSocket.pendingDatagramSize();
|
||||
std::unique_ptr<char> buffer = std::unique_ptr<char>(new char[packetSizeWithHeader]);
|
||||
auto buffer = std::unique_ptr<char[]>(new char[packetSizeWithHeader]);
|
||||
|
||||
_serverSocket.readDatagram(buffer.get(), packetSizeWithHeader,
|
||||
sendingSockAddr.getAddressPointer(), sendingSockAddr.getPortPointer());
|
||||
|
|
|
@ -218,33 +218,13 @@ else (APPLE)
|
|||
"${PROJECT_SOURCE_DIR}/resources"
|
||||
$<TARGET_FILE_DIR:${TARGET_NAME}>/resources
|
||||
)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
if (${OPENGL_INCLUDE_DIR})
|
||||
include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}")
|
||||
endif ()
|
||||
|
||||
target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}")
|
||||
|
||||
|
||||
# link target to external libraries
|
||||
if (WIN32)
|
||||
add_dependency_external_projects(glew)
|
||||
find_package(GLEW REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${GLEW_INCLUDE_DIRS})
|
||||
|
||||
target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} wsock32.lib opengl32.lib Winmm.lib)
|
||||
|
||||
if (USE_NSIGHT)
|
||||
# try to find the Nsight package and add it to the build if we find it
|
||||
find_package(NSIGHT)
|
||||
if (NSIGHT_FOUND)
|
||||
include_directories(${NSIGHT_INCLUDE_DIRS})
|
||||
add_definitions(-DNSIGHT_FOUND)
|
||||
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
# target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib)
|
||||
target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib)
|
||||
else (WIN32)
|
||||
# Nothing else required on linux apparently
|
||||
endif()
|
||||
endif (APPLE)
|
||||
|
||||
|
|
|
@ -782,8 +782,9 @@ void Application::initializeGL() {
|
|||
}
|
||||
#endif
|
||||
|
||||
// Where the gpuContext is created and where the TRUE Backend is created and assigned
|
||||
_gpuContext = std::make_shared<gpu::Context>(new gpu::GLBackend());
|
||||
// Where the gpuContext is initialized and where the TRUE Backend is created and assigned
|
||||
gpu::Context::init<gpu::GLBackend>();
|
||||
_gpuContext = std::make_shared<gpu::Context>();
|
||||
|
||||
initDisplay();
|
||||
qCDebug(interfaceapp, "Initialized Display.");
|
||||
|
@ -1010,7 +1011,8 @@ void Application::paintGL() {
|
|||
|
||||
_compositor.displayOverlayTexture(&renderArgs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!OculusManager::isConnected() || OculusManager::allowSwap()) {
|
||||
PROFILE_RANGE(__FUNCTION__ "/bufferSwap");
|
||||
_glWidget->swapBuffers();
|
||||
|
@ -1022,6 +1024,13 @@ void Application::paintGL() {
|
|||
_frameCount++;
|
||||
_numFramesSinceLastResize++;
|
||||
Stats::getInstance()->setRenderDetails(renderArgs._details);
|
||||
|
||||
|
||||
// Reset the gpu::Context Stages
|
||||
// Back to the default framebuffer;
|
||||
gpu::Batch batch;
|
||||
batch.resetStages();
|
||||
renderArgs._context->render(batch);
|
||||
}
|
||||
|
||||
void Application::runTests() {
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#define hifi_GLCanvas_h
|
||||
|
||||
#include <QDebug>
|
||||
#include <gpu/GPUConfig.h>
|
||||
#include <QGLWidget>
|
||||
#include <QTimer>
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ bool ModelPackager::loadModel() {
|
|||
}
|
||||
qCDebug(interfaceapp) << "Reading FBX file : " << _fbxInfo.filePath();
|
||||
QByteArray fbxContents = fbx.readAll();
|
||||
_geometry = readFBX(fbxContents, QVariantHash());
|
||||
_geometry = readFBX(fbxContents, QVariantHash(), _fbxInfo.filePath());
|
||||
|
||||
// make sure we have some basic mappings
|
||||
populateBasicMapping(_mapping, _fbxInfo.filePath(), _geometry);
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
#include <mutex>
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <gpu/GPUConfig.h>
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/Context.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include <DependencyManager.h>
|
||||
|
@ -154,6 +152,7 @@ void Stars::render(RenderArgs* renderArgs, float alpha) {
|
|||
auto state = gpu::StatePointer(new gpu::State());
|
||||
// enable decal blend
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setAntialiasedLineEnable(true); // line smoothing also smooth points
|
||||
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
||||
_starsPipeline.reset(gpu::Pipeline::create(program, state));
|
||||
|
||||
|
@ -207,8 +206,6 @@ void Stars::render(RenderArgs* renderArgs, float alpha) {
|
|||
batch._glUniform1f(_timeSlot, secs);
|
||||
geometryCache->renderUnitCube(batch);
|
||||
|
||||
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
||||
|
||||
static const size_t VERTEX_STRIDE = sizeof(StarVertex);
|
||||
size_t offset = offsetof(StarVertex, position);
|
||||
gpu::BufferView posView(vertexBuffer, offset, vertexBuffer->getSize(), VERTEX_STRIDE, positionElement);
|
||||
|
@ -217,14 +214,11 @@ void Stars::render(RenderArgs* renderArgs, float alpha) {
|
|||
|
||||
// Render the stars
|
||||
batch.setPipeline(_starsPipeline);
|
||||
batch._glEnable(GL_PROGRAM_POINT_SIZE_EXT);
|
||||
batch._glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
batch._glEnable(GL_POINT_SMOOTH);
|
||||
|
||||
batch.setInputFormat(streamFormat);
|
||||
batch.setInputBuffer(VERTICES_SLOT, posView);
|
||||
batch.setInputBuffer(COLOR_SLOT, colView);
|
||||
batch.draw(gpu::Primitive::POINTS, STARFIELD_NUM_STARS);
|
||||
|
||||
|
||||
renderArgs->_context->render(batch);
|
||||
}
|
||||
|
|
|
@ -11,16 +11,16 @@
|
|||
//
|
||||
|
||||
#include "OculusManager.h"
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <QDesktopWidget>
|
||||
#include <QGuiApplication>
|
||||
#include <gpu/GPUConfig.h>
|
||||
#include <QScreen>
|
||||
#include <CursorManager.h>
|
||||
#include <QOpenGLTimerQuery>
|
||||
#include <QGLWidget>
|
||||
|
||||
#include <CursorManager.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <avatar/MyAvatar.h>
|
||||
|
|
|
@ -9,13 +9,14 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "TV3DManager.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include "gpu/GLBackend.h"
|
||||
#include "Application.h"
|
||||
#include <RenderArgs.h>
|
||||
|
||||
#include "TV3DManager.h"
|
||||
#include "Application.h"
|
||||
#include "Menu.h"
|
||||
|
||||
int TV3DManager::_screenWidth = 1;
|
||||
|
@ -63,6 +64,7 @@ void TV3DManager::setFrustum(Camera& whichCamera) {
|
|||
}
|
||||
|
||||
void TV3DManager::configureCamera(Camera& whichCamera, int screenWidth, int screenHeight) {
|
||||
#ifdef THIS_CURRENTLY_BROKEN_WAITING_FOR_DISPLAY_PLUGINS
|
||||
if (screenHeight == 0) {
|
||||
screenHeight = 1; // prevent divide by 0
|
||||
}
|
||||
|
@ -72,6 +74,7 @@ void TV3DManager::configureCamera(Camera& whichCamera, int screenWidth, int scre
|
|||
setFrustum(whichCamera);
|
||||
|
||||
glViewport (0, 0, _screenWidth, _screenHeight); // sets drawing viewport
|
||||
#endif
|
||||
}
|
||||
|
||||
void TV3DManager::display(RenderArgs* renderArgs, Camera& whichCamera) {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
|
||||
class Camera;
|
||||
class RenderArgs;
|
||||
|
||||
struct eyeFrustum {
|
||||
double left;
|
||||
|
|
|
@ -57,7 +57,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
|
|||
|
||||
if (piggybackBytes) {
|
||||
// construct a new packet from the piggybacked one
|
||||
std::unique_ptr<char> buffer = std::unique_ptr<char>(new char[piggybackBytes]);
|
||||
auto buffer = std::unique_ptr<char[]>(new char[piggybackBytes]);
|
||||
memcpy(buffer.get(), packet->getPayload() + statsMessageLength, piggybackBytes);
|
||||
|
||||
auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggybackBytes, packet->getSenderSockAddr());
|
||||
|
|
|
@ -117,7 +117,7 @@ void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) {
|
|||
batch.setProjectionTransform(mat4());
|
||||
batch.setModelTransform(Transform());
|
||||
batch.setViewTransform(Transform());
|
||||
batch._glBindTexture(GL_TEXTURE_2D, _uiTexture);
|
||||
batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _uiTexture);
|
||||
|
||||
geometryCache->renderUnitQuad(batch, glm::vec4(1));
|
||||
}
|
||||
|
|
|
@ -119,19 +119,21 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
|||
|
||||
float angle = startAt;
|
||||
float angleInRadians = glm::radians(angle);
|
||||
glm::vec2 firstInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
|
||||
glm::vec2 firstOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
|
||||
|
||||
points << firstInnerPoint << firstOuterPoint;
|
||||
glm::vec2 mostRecentInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
|
||||
glm::vec2 mostRecentOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
|
||||
|
||||
while (angle < endAt) {
|
||||
angleInRadians = glm::radians(angle);
|
||||
glm::vec2 thisInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
|
||||
glm::vec2 thisOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
|
||||
|
||||
points << thisOuterPoint << thisInnerPoint;
|
||||
points << mostRecentInnerPoint << mostRecentOuterPoint << thisOuterPoint; // first triangle
|
||||
points << mostRecentInnerPoint << thisInnerPoint << thisOuterPoint; // second triangle
|
||||
|
||||
angle += SLICE_ANGLE;
|
||||
|
||||
mostRecentInnerPoint = thisInnerPoint;
|
||||
mostRecentOuterPoint = thisOuterPoint;
|
||||
}
|
||||
|
||||
// get the last slice portion....
|
||||
|
@ -139,13 +141,14 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
|||
angleInRadians = glm::radians(angle);
|
||||
glm::vec2 lastInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
|
||||
glm::vec2 lastOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
|
||||
|
||||
points << lastOuterPoint << lastInnerPoint;
|
||||
|
||||
points << mostRecentInnerPoint << mostRecentOuterPoint << lastOuterPoint; // first triangle
|
||||
points << mostRecentInnerPoint << lastInnerPoint << lastOuterPoint; // second triangle
|
||||
|
||||
geometryCache->updateVertices(_quadVerticesID, points, color);
|
||||
}
|
||||
|
||||
geometryCache->renderVertices(batch, gpu::QUAD_STRIP, _quadVerticesID);
|
||||
geometryCache->renderVertices(batch, gpu::TRIANGLES, _quadVerticesID);
|
||||
|
||||
} else {
|
||||
if (_lineVerticesID == GeometryCache::UNKNOWN_ID) {
|
||||
|
|
|
@ -62,7 +62,7 @@ void AnimationReader::run() {
|
|||
QSharedPointer<Resource> animation = _animation.toStrongRef();
|
||||
if (!animation.isNull()) {
|
||||
QMetaObject::invokeMethod(animation.data(), "setGeometry",
|
||||
Q_ARG(const FBXGeometry&, readFBX(_reply->readAll(), QVariantHash())));
|
||||
Q_ARG(const FBXGeometry&, readFBX(_reply->readAll(), QVariantHash(), _reply->property("url").toString())));
|
||||
}
|
||||
_reply->deleteLater();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <PolyVoxCore/Material.h>
|
||||
|
||||
#include "model/Geometry.h"
|
||||
#include "gpu/GLBackend.h"
|
||||
#include "gpu/Context.h"
|
||||
#include "EntityTreeRenderer.h"
|
||||
#include "RenderablePolyVoxEntityItem.h"
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "RenderableWebEntityItem.h"
|
||||
|
||||
#include <gpu/GPUConfig.h>
|
||||
#include <QMouseEvent>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWindow>
|
||||
|
@ -24,7 +23,7 @@
|
|||
#include <GLMHelpers.h>
|
||||
#include <PathUtils.h>
|
||||
#include <TextureCache.h>
|
||||
#include <gpu/GLBackend.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
#include "EntityTreeRenderer.h"
|
||||
|
||||
|
@ -178,8 +177,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
|||
batch.setModelTransform(getTransformToCenter());
|
||||
bool textured = false, culled = false, emissive = false;
|
||||
if (_texture) {
|
||||
batch._glActiveTexture(GL_TEXTURE0);
|
||||
batch._glBindTexture(GL_TEXTURE_2D, _texture);
|
||||
batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture);
|
||||
textured = emissive = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,8 @@ _glowLevelChanged(false),
|
|||
_localRenderAlphaChanged(false),
|
||||
|
||||
_defaultSettings(true),
|
||||
_naturalDimensions(1.0f, 1.0f, 1.0f)
|
||||
_naturalDimensions(1.0f, 1.0f, 1.0f),
|
||||
_naturalPosition(0.0f, 0.0f, 0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -128,6 +129,11 @@ void EntityItemProperties::setSittingPoints(const QVector<SittingPoint>& sitting
|
|||
}
|
||||
}
|
||||
|
||||
void EntityItemProperties::calculateNaturalPosition(const glm::vec3& min, const glm::vec3& max) {
|
||||
glm::vec3 halfDimension = (max - min) / 2.0f;
|
||||
_naturalPosition = max - halfDimension;
|
||||
}
|
||||
|
||||
bool EntityItemProperties::animationSettingsChanged() const {
|
||||
return _animationSettingsChanged;
|
||||
}
|
||||
|
@ -378,6 +384,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(dimensions);
|
||||
if (!skipDefaults) {
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(naturalDimensions); // gettable, but not settable
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(naturalPosition);
|
||||
}
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(rotation);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(velocity);
|
||||
|
|
|
@ -192,7 +192,10 @@ public:
|
|||
|
||||
const glm::vec3& getNaturalDimensions() const { return _naturalDimensions; }
|
||||
void setNaturalDimensions(const glm::vec3& value) { _naturalDimensions = value; }
|
||||
|
||||
|
||||
const glm::vec3& getNaturalPosition() const { return _naturalPosition; }
|
||||
void calculateNaturalPosition(const glm::vec3& min, const glm::vec3& max);
|
||||
|
||||
const QStringList& getTextureNames() const { return _textureNames; }
|
||||
void setTextureNames(const QStringList& value) { _textureNames = value; }
|
||||
|
||||
|
@ -232,6 +235,7 @@ private:
|
|||
QVector<SittingPoint> _sittingPoints;
|
||||
QStringList _textureNames;
|
||||
glm::vec3 _naturalDimensions;
|
||||
glm::vec3 _naturalPosition;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(EntityItemProperties);
|
||||
|
|
|
@ -118,6 +118,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
|
|||
results.setSittingPoints(geometry->sittingPoints);
|
||||
Extents meshExtents = geometry->getUnscaledMeshExtents();
|
||||
results.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum);
|
||||
results.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,9 +155,9 @@ void ParticleEffectEntityItem::computeAndUpdateDimensions() {
|
|||
float yMin = std::min(yApex, yEnd);
|
||||
|
||||
// times 2 because dimensions are diameters not radii.
|
||||
glm::vec3 dims(2.0f * std::max(fabs(xMin), fabs(xMax)),
|
||||
2.0f * std::max(fabs(yMin), fabs(yMax)),
|
||||
2.0f * std::max(fabs(zMin), fabs(zMax)));
|
||||
glm::vec3 dims(2.0f * std::max(fabsf(xMin), fabsf(xMax)),
|
||||
2.0f * std::max(fabsf(yMin), fabsf(yMax)),
|
||||
2.0f * std::max(fabsf(zMin), fabsf(zMax)));
|
||||
|
||||
EntityItem::setDimensions(dims);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <QTextStream>
|
||||
#include <QtDebug>
|
||||
#include <QtEndian>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
@ -829,6 +830,56 @@ public:
|
|||
std::vector<AttributeData> attributes;
|
||||
};
|
||||
|
||||
gpu::BufferPointer FBXMeshPart::getTrianglesForQuads() const {
|
||||
// if we've been asked for our triangulation of the original quads, but we don't yet have them
|
||||
// then create them now.
|
||||
if (!trianglesForQuadsAvailable) {
|
||||
trianglesForQuadsAvailable = true;
|
||||
|
||||
quadsAsTrianglesIndicesBuffer = std::make_shared<gpu::Buffer>();
|
||||
|
||||
// QVector<int> quadIndices; // original indices from the FBX mesh
|
||||
QVector<quint32> quadsAsTrianglesIndices; // triangle versions of quads converted when first needed
|
||||
const int INDICES_PER_ORIGINAL_QUAD = 4;
|
||||
const int INDICES_PER_TRIANGULATED_QUAD = 6;
|
||||
int numberOfQuads = quadIndices.size() / INDICES_PER_ORIGINAL_QUAD;
|
||||
|
||||
quadsAsTrianglesIndices.resize(numberOfQuads * INDICES_PER_TRIANGULATED_QUAD);
|
||||
|
||||
int originalIndex = 0;
|
||||
int triangulatedIndex = 0;
|
||||
for (int fromQuad = 0; fromQuad < numberOfQuads; fromQuad++) {
|
||||
int i0 = quadIndices[originalIndex + 0];
|
||||
int i1 = quadIndices[originalIndex + 1];
|
||||
int i2 = quadIndices[originalIndex + 2];
|
||||
int i3 = quadIndices[originalIndex + 3];
|
||||
|
||||
// Sam's recommended triangle slices
|
||||
// Triangle tri1 = { v0, v1, v3 };
|
||||
// Triangle tri2 = { v1, v2, v3 };
|
||||
// NOTE: Random guy on the internet's recommended triangle slices
|
||||
// Triangle tri1 = { v0, v1, v2 };
|
||||
// Triangle tri2 = { v2, v3, v0 };
|
||||
|
||||
quadsAsTrianglesIndices[triangulatedIndex + 0] = i0;
|
||||
quadsAsTrianglesIndices[triangulatedIndex + 1] = i1;
|
||||
quadsAsTrianglesIndices[triangulatedIndex + 2] = i3;
|
||||
|
||||
quadsAsTrianglesIndices[triangulatedIndex + 3] = i1;
|
||||
quadsAsTrianglesIndices[triangulatedIndex + 4] = i2;
|
||||
quadsAsTrianglesIndices[triangulatedIndex + 5] = i3;
|
||||
|
||||
originalIndex += INDICES_PER_ORIGINAL_QUAD;
|
||||
triangulatedIndex += INDICES_PER_TRIANGULATED_QUAD;
|
||||
}
|
||||
|
||||
trianglesForQuadsIndicesCount = INDICES_PER_TRIANGULATED_QUAD * numberOfQuads;
|
||||
quadsAsTrianglesIndicesBuffer->append(quadsAsTrianglesIndices.size() * sizeof(quint32), (gpu::Byte*)quadsAsTrianglesIndices.data());
|
||||
|
||||
}
|
||||
return quadsAsTrianglesIndicesBuffer;
|
||||
}
|
||||
|
||||
void appendIndex(MeshData& data, QVector<int>& indices, int index) {
|
||||
if (index >= data.polygonIndices.size()) {
|
||||
return;
|
||||
|
@ -1088,7 +1139,6 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) {
|
|||
appendIndex(data, part.quadIndices, beginIndex++);
|
||||
appendIndex(data, part.quadIndices, beginIndex++);
|
||||
appendIndex(data, part.quadIndices, beginIndex++);
|
||||
|
||||
} else {
|
||||
for (int nextIndex = beginIndex + 1;; ) {
|
||||
appendIndex(data, part.triangleIndices, beginIndex);
|
||||
|
@ -1454,9 +1504,21 @@ void buildModelMesh(ExtractedMesh& extracted) {
|
|||
}
|
||||
#endif // USE_MODEL_MESH
|
||||
|
||||
QByteArray fileOnUrl(const QByteArray& filenameString, const QString& url) {
|
||||
QString path = QFileInfo(url).path();
|
||||
QByteArray filename = filenameString;
|
||||
QFileInfo checkFile(path + "/" + filename.replace('\\', '/'));
|
||||
//check if the file exists at the RelativeFileName
|
||||
if (checkFile.exists() && checkFile.isFile()) {
|
||||
filename = filename.replace('\\', '/');
|
||||
} else {
|
||||
// there is no texture at the fbx dir with the filename added. Assume it is in the fbx dir.
|
||||
filename = filename.mid(qMax(filename.lastIndexOf('\\'), filename.lastIndexOf('/')) + 1);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) {
|
||||
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
|
||||
QHash<QString, ExtractedMesh> meshes;
|
||||
QHash<QString, QString> modelIDsToNames;
|
||||
QHash<QString, int> meshIDsToMeshIndices;
|
||||
|
@ -1781,9 +1843,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
TextureParam tex;
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
if (subobject.name == "RelativeFilename") {
|
||||
// trim off any path information
|
||||
QByteArray filename = subobject.properties.at(0).toByteArray();
|
||||
filename = filename.mid(qMax(filename.lastIndexOf('\\'), filename.lastIndexOf('/')) + 1);
|
||||
filename = fileOnUrl(filename, url);
|
||||
textureFilenames.insert(getID(object.properties), filename);
|
||||
} else if (subobject.name == "TextureName") {
|
||||
// trim the name from the timestamp
|
||||
|
@ -1857,7 +1918,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
foreach (const FBXNode& subobject, object.children) {
|
||||
if (subobject.name == "RelativeFilename") {
|
||||
filename = subobject.properties.at(0).toByteArray();
|
||||
filename = filename.mid(qMax(filename.lastIndexOf('\\'), filename.lastIndexOf('/')) + 1);
|
||||
filename = fileOnUrl(filename, url);
|
||||
|
||||
} else if (subobject.name == "Content" && !subobject.properties.isEmpty()) {
|
||||
content = subobject.properties.at(0).toByteArray();
|
||||
|
@ -2717,12 +2778,12 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
return geometry;
|
||||
}
|
||||
|
||||
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) {
|
||||
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
|
||||
QBuffer buffer(const_cast<QByteArray*>(&model));
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
return readFBX(&buffer, mapping, loadLightmaps, lightmapLevel);
|
||||
return readFBX(&buffer, mapping, url, loadLightmaps, lightmapLevel);
|
||||
}
|
||||
|
||||
FBXGeometry readFBX(QIODevice* device, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) {
|
||||
return extractFBXGeometry(parseFBX(device), mapping, loadLightmaps, lightmapLevel);
|
||||
FBXGeometry readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
|
||||
return extractFBXGeometry(parseFBX(device), mapping, url, loadLightmaps, lightmapLevel);
|
||||
}
|
||||
|
|
|
@ -109,9 +109,10 @@ public:
|
|||
class FBXMeshPart {
|
||||
public:
|
||||
|
||||
QVector<int> quadIndices;
|
||||
QVector<int> triangleIndices;
|
||||
|
||||
QVector<int> quadIndices; // original indices from the FBX mesh
|
||||
QVector<int> triangleIndices; // original indices from the FBX mesh
|
||||
mutable gpu::BufferPointer quadsAsTrianglesIndicesBuffer;
|
||||
|
||||
glm::vec3 diffuseColor;
|
||||
glm::vec3 specularColor;
|
||||
glm::vec3 emissiveColor;
|
||||
|
@ -126,6 +127,10 @@ public:
|
|||
|
||||
QString materialID;
|
||||
model::MaterialPointer _material;
|
||||
mutable bool trianglesForQuadsAvailable = false;
|
||||
mutable int trianglesForQuadsIndicesCount = 0;
|
||||
|
||||
gpu::BufferPointer getTrianglesForQuads() const;
|
||||
};
|
||||
|
||||
/// A single mesh (with optional blendshapes) extracted from an FBX document.
|
||||
|
@ -271,10 +276,10 @@ Q_DECLARE_METATYPE(FBXGeometry)
|
|||
|
||||
/// Reads FBX geometry from the supplied model and mapping data.
|
||||
/// \exception QString if an error occurs in parsing
|
||||
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
||||
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
||||
|
||||
/// Reads FBX geometry from the supplied model and mapping data.
|
||||
/// \exception QString if an error occurs in parsing
|
||||
FBXGeometry readFBX(QIODevice* device, const QVariantHash& mapping, bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
||||
FBXGeometry readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
||||
|
||||
#endif // hifi_FBXReader_h
|
||||
|
|
|
@ -21,23 +21,26 @@ elseif (WIN32)
|
|||
|
||||
if (USE_NSIGHT)
|
||||
# try to find the Nsight package and add it to the build if we find it
|
||||
# note that this will also enable NSIGHT profilers in all the projects linking gpu
|
||||
find_package(NSIGHT)
|
||||
if (NSIGHT_FOUND)
|
||||
include_directories(${NSIGHT_INCLUDE_DIRS})
|
||||
add_definitions(-DNSIGHT_FOUND)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${NSIGHT_INCLUDE_DIRS})
|
||||
target_compile_definitions(${TARGET_NAME} PUBLIC NSIGHT_FOUND)
|
||||
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
|
||||
endif ()
|
||||
endif()
|
||||
elseif (ANDROID)
|
||||
target_link_libraries(${TARGET_NAME} "-lGLESv3" "-lEGL")
|
||||
else ()
|
||||
find_package(GLEW REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${GLEW_INCLUDE_DIRS})
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
if (${OPENGL_INCLUDE_DIR})
|
||||
include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}")
|
||||
endif ()
|
||||
|
||||
target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}")
|
||||
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${OPENGL_INCLUDE_DIR})
|
||||
|
||||
target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" "${OPENGL_LIBRARY}")
|
||||
|
||||
endif (APPLE)
|
||||
|
|
|
@ -8,13 +8,9 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include <string.h>
|
||||
|
||||
#include "Batch.h"
|
||||
#include "GPUConfig.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
|
||||
#if defined(NSIGHT_FOUND)
|
||||
#include "nvToolsExt.h"
|
||||
|
@ -288,15 +284,7 @@ void Batch::getQuery(const QueryPointer& query) {
|
|||
_params.push_back(_queries.cache(query));
|
||||
}
|
||||
|
||||
void push_back(Batch::Params& params, const vec3& v) {
|
||||
params.push_back(v.x);
|
||||
params.push_back(v.y);
|
||||
params.push_back(v.z);
|
||||
void Batch::resetStages() {
|
||||
ADD_COMMAND(resetStages);
|
||||
}
|
||||
|
||||
void push_back(Batch::Params& params, const vec4& v) {
|
||||
params.push_back(v.x);
|
||||
params.push_back(v.y);
|
||||
params.push_back(v.z);
|
||||
params.push_back(v.a);
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
void setResourceTexture(uint32 slot, const TexturePointer& view);
|
||||
void setResourceTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView
|
||||
|
||||
// Framebuffer Stage
|
||||
// Ouput Stage
|
||||
void setFramebuffer(const FramebufferPointer& framebuffer);
|
||||
|
||||
// Clear framebuffer layers
|
||||
|
@ -113,34 +113,17 @@ public:
|
|||
void endQuery(const QueryPointer& query);
|
||||
void getQuery(const QueryPointer& query);
|
||||
|
||||
// Reset the stage caches and states
|
||||
void resetStages();
|
||||
|
||||
// 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
|
||||
// For now, instead of calling the raw gl Call, use the equivalent call on the batch so the call is beeing recorded
|
||||
// THe implementation of these functions is in GLBackend.cpp
|
||||
|
||||
void _glEnable(unsigned int cap);
|
||||
void _glDisable(unsigned int cap);
|
||||
void _glActiveBindTexture(unsigned int unit, unsigned int target, unsigned int texture);
|
||||
|
||||
void _glEnableClientState(unsigned int array);
|
||||
void _glDisableClientState(unsigned int array);
|
||||
|
||||
void _glCullFace(unsigned int mode);
|
||||
void _glAlphaFunc(unsigned int func, float ref);
|
||||
|
||||
void _glDepthFunc(unsigned int func);
|
||||
void _glDepthMask(unsigned char flag);
|
||||
void _glDepthRange(float zNear, float zFar);
|
||||
|
||||
void _glBindBuffer(unsigned int target, unsigned int buffer);
|
||||
|
||||
void _glBindTexture(unsigned int target, unsigned int texture);
|
||||
void _glActiveTexture(unsigned int texture);
|
||||
void _glTexParameteri(unsigned int target, unsigned int pname, int param);
|
||||
|
||||
void _glDrawBuffers(int n, const unsigned int* bufs);
|
||||
|
||||
void _glUseProgram(unsigned int program);
|
||||
void _glUniform1i(int location, int v0);
|
||||
void _glUniform1f(int location, float v0);
|
||||
void _glUniform2f(int location, float v0, float v1);
|
||||
|
@ -150,9 +133,6 @@ public:
|
|||
void _glUniform4iv(int location, int count, const int* value);
|
||||
void _glUniformMatrix4fv(int location, int count, unsigned char transpose, const float* value);
|
||||
|
||||
void _glEnableVertexAttribArray(int location);
|
||||
void _glDisableVertexAttribArray(int location);
|
||||
|
||||
void _glColor4f(float red, float green, float blue, float alpha);
|
||||
void _glLineWidth(float width);
|
||||
|
||||
|
@ -186,31 +166,13 @@ public:
|
|||
COMMAND_endQuery,
|
||||
COMMAND_getQuery,
|
||||
|
||||
COMMAND_resetStages,
|
||||
|
||||
// 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
|
||||
COMMAND_glEnable,
|
||||
COMMAND_glDisable,
|
||||
COMMAND_glActiveBindTexture,
|
||||
|
||||
COMMAND_glEnableClientState,
|
||||
COMMAND_glDisableClientState,
|
||||
|
||||
COMMAND_glCullFace,
|
||||
COMMAND_glAlphaFunc,
|
||||
|
||||
COMMAND_glDepthFunc,
|
||||
COMMAND_glDepthMask,
|
||||
COMMAND_glDepthRange,
|
||||
|
||||
COMMAND_glBindBuffer,
|
||||
|
||||
COMMAND_glBindTexture,
|
||||
COMMAND_glActiveTexture,
|
||||
COMMAND_glTexParameteri,
|
||||
|
||||
COMMAND_glDrawBuffers,
|
||||
|
||||
COMMAND_glUseProgram,
|
||||
COMMAND_glUniform1i,
|
||||
COMMAND_glUniform1f,
|
||||
COMMAND_glUniform2f,
|
||||
|
@ -220,9 +182,6 @@ public:
|
|||
COMMAND_glUniform4iv,
|
||||
COMMAND_glUniformMatrix4fv,
|
||||
|
||||
COMMAND_glEnableVertexAttribArray,
|
||||
COMMAND_glDisableVertexAttribArray,
|
||||
|
||||
COMMAND_glColor4f,
|
||||
COMMAND_glLineWidth,
|
||||
|
||||
|
|
|
@ -21,10 +21,9 @@
|
|||
<@def VERSION_HEADER #version 120
|
||||
#extension GL_EXT_gpu_shader4 : enable@>
|
||||
<@else@>
|
||||
<@def GPU_FEATURE_PROFILE GPU_LEGACY@>
|
||||
<@def GPU_TRANSFORM_PROFILE GPU_LEGACY@>
|
||||
<@def VERSION_HEADER #version 120
|
||||
#extension GL_EXT_gpu_shader4 : enable@>
|
||||
<@def GPU_FEATURE_PROFILE GPU_CORE@>
|
||||
<@def GPU_TRANSFORM_PROFILE GPU_CORE@>
|
||||
<@def VERSION_HEADER #version 430 compatibility@>
|
||||
<@endif@>
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -10,13 +10,16 @@
|
|||
//
|
||||
#include "Context.h"
|
||||
|
||||
// this include should disappear! as soon as the gpu::Context is in place
|
||||
#include "GLBackend.h"
|
||||
|
||||
using namespace gpu;
|
||||
|
||||
Context::Context(Backend* backend) :
|
||||
_backend(backend) {
|
||||
Context::CreateBackend Context::_createBackendCallback = nullptr;
|
||||
Context::MakeProgram Context::_makeProgramCallback = nullptr;
|
||||
std::once_flag Context::_initialized;
|
||||
|
||||
Context::Context() {
|
||||
if (_createBackendCallback) {
|
||||
_backend.reset(_createBackendCallback());
|
||||
}
|
||||
}
|
||||
|
||||
Context::Context(const Context& context) {
|
||||
|
@ -26,8 +29,8 @@ Context::~Context() {
|
|||
}
|
||||
|
||||
bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings) {
|
||||
if (shader.isProgram()) {
|
||||
return GLBackend::makeProgram(shader, bindings);
|
||||
if (shader.isProgram() && _makeProgramCallback) {
|
||||
return _makeProgramCallback(shader, bindings);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -45,3 +48,4 @@ void Context::syncCache() {
|
|||
void Context::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) {
|
||||
_backend->downloadFramebuffer(srcFramebuffer, region, destImage);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define hifi_gpu_Context_h
|
||||
|
||||
#include <assert.h>
|
||||
#include <mutex>
|
||||
|
||||
#include "Batch.h"
|
||||
|
||||
|
@ -26,13 +27,12 @@ namespace gpu {
|
|||
|
||||
class Backend {
|
||||
public:
|
||||
|
||||
virtual~ Backend() {};
|
||||
|
||||
virtual void render(Batch& batch) = 0;
|
||||
virtual void syncCache() = 0;
|
||||
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
|
||||
|
||||
|
||||
class TransformObject {
|
||||
public:
|
||||
Mat4 _model;
|
||||
|
@ -118,7 +118,21 @@ protected:
|
|||
|
||||
class Context {
|
||||
public:
|
||||
Context(Backend* backend);
|
||||
typedef Backend* (*CreateBackend)();
|
||||
typedef bool (*MakeProgram)(Shader& shader, const Shader::BindingSet& bindings);
|
||||
|
||||
|
||||
// This one call must happen before any context is created or used (Shader::MakeProgram) in order to setup the Backend and any singleton data needed
|
||||
template <class T>
|
||||
static void init() {
|
||||
std::call_once(_initialized, [] {
|
||||
_createBackendCallback = T::createBackend;
|
||||
_makeProgramCallback = T::makeProgram;
|
||||
T::init();
|
||||
});
|
||||
}
|
||||
|
||||
Context();
|
||||
~Context();
|
||||
|
||||
void render(Batch& batch);
|
||||
|
@ -132,13 +146,17 @@ public:
|
|||
protected:
|
||||
Context(const Context& context);
|
||||
|
||||
std::unique_ptr<Backend> _backend;
|
||||
|
||||
// This function can only be called by "static Shader::makeProgram()"
|
||||
// makeProgramShader(...) make a program shader ready to be used in a Batch.
|
||||
// It compiles the sub shaders, link them and defines the Slots and their bindings.
|
||||
// If the shader passed is not a program, nothing happens.
|
||||
static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings = Shader::BindingSet());
|
||||
static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings);
|
||||
|
||||
std::unique_ptr<Backend> _backend;
|
||||
static CreateBackend _createBackendCallback;
|
||||
static MakeProgram _makeProgramCallback;
|
||||
static std::once_flag _initialized;
|
||||
|
||||
friend class Shader;
|
||||
};
|
||||
|
|
|
@ -213,9 +213,6 @@ enum Primitive {
|
|||
TRIANGLES,
|
||||
TRIANGLE_STRIP,
|
||||
TRIANGLE_FAN,
|
||||
QUADS,
|
||||
QUAD_STRIP,
|
||||
|
||||
NUM_PRIMITIVES,
|
||||
};
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include <mutex>
|
||||
#include "GPULogging.h"
|
||||
#include "GLBackendShared.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
using namespace gpu;
|
||||
|
@ -46,28 +46,10 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_endQuery),
|
||||
(&::gpu::GLBackend::do_getQuery),
|
||||
|
||||
(&::gpu::GLBackend::do_glEnable),
|
||||
(&::gpu::GLBackend::do_glDisable),
|
||||
(&::gpu::GLBackend::do_resetStages),
|
||||
|
||||
(&::gpu::GLBackend::do_glEnableClientState),
|
||||
(&::gpu::GLBackend::do_glDisableClientState),
|
||||
(&::gpu::GLBackend::do_glActiveBindTexture),
|
||||
|
||||
(&::gpu::GLBackend::do_glCullFace),
|
||||
(&::gpu::GLBackend::do_glAlphaFunc),
|
||||
|
||||
(&::gpu::GLBackend::do_glDepthFunc),
|
||||
(&::gpu::GLBackend::do_glDepthMask),
|
||||
(&::gpu::GLBackend::do_glDepthRange),
|
||||
|
||||
(&::gpu::GLBackend::do_glBindBuffer),
|
||||
|
||||
(&::gpu::GLBackend::do_glBindTexture),
|
||||
(&::gpu::GLBackend::do_glActiveTexture),
|
||||
(&::gpu::GLBackend::do_glTexParameteri),
|
||||
|
||||
(&::gpu::GLBackend::do_glDrawBuffers),
|
||||
|
||||
(&::gpu::GLBackend::do_glUseProgram),
|
||||
(&::gpu::GLBackend::do_glUniform1i),
|
||||
(&::gpu::GLBackend::do_glUniform1f),
|
||||
(&::gpu::GLBackend::do_glUniform2f),
|
||||
|
@ -77,19 +59,11 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_glUniform4iv),
|
||||
(&::gpu::GLBackend::do_glUniformMatrix4fv),
|
||||
|
||||
(&::gpu::GLBackend::do_glEnableVertexAttribArray),
|
||||
(&::gpu::GLBackend::do_glDisableVertexAttribArray),
|
||||
|
||||
(&::gpu::GLBackend::do_glColor4f),
|
||||
(&::gpu::GLBackend::do_glLineWidth),
|
||||
};
|
||||
|
||||
GLBackend::GLBackend() :
|
||||
_input(),
|
||||
_transform(),
|
||||
_pipeline(),
|
||||
_output()
|
||||
{
|
||||
void GLBackend::init() {
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [] {
|
||||
qCDebug(gpulogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION));
|
||||
|
@ -115,6 +89,13 @@ GLBackend::GLBackend() :
|
|||
#endif
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
GLenum err = glewInit();
|
||||
if (GLEW_OK != err) {
|
||||
/* Problem: glewInit failed, something is seriously wrong. */
|
||||
qCDebug(gpulogging, "Error: %s\n", glewGetErrorString(err));
|
||||
}
|
||||
qCDebug(gpulogging, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
|
||||
|
||||
// TODO: Write the correct code for Linux...
|
||||
/* if (wglewGetExtension("WGL_EXT_swap_control")) {
|
||||
int swapInterval = wglGetSwapIntervalEXT();
|
||||
|
@ -122,12 +103,25 @@ GLBackend::GLBackend() :
|
|||
}*/
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
Backend* GLBackend::createBackend() {
|
||||
return new GLBackend();
|
||||
}
|
||||
|
||||
GLBackend::GLBackend() :
|
||||
_input(),
|
||||
_transform(),
|
||||
_pipeline(),
|
||||
_output()
|
||||
{
|
||||
initInput();
|
||||
initTransform();
|
||||
}
|
||||
|
||||
GLBackend::~GLBackend() {
|
||||
resetStages();
|
||||
|
||||
killInput();
|
||||
killTransform();
|
||||
}
|
||||
|
@ -246,6 +240,22 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) {
|
|||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void GLBackend::do_resetStages(Batch& batch, uint32 paramOffset) {
|
||||
resetStages();
|
||||
}
|
||||
|
||||
void GLBackend::resetStages() {
|
||||
resetInputStage();
|
||||
resetPipelineStage();
|
||||
resetTransformStage();
|
||||
resetUniformStage();
|
||||
resetResourceStage();
|
||||
resetOutputStage();
|
||||
resetQueryStage();
|
||||
|
||||
(void) 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
|
||||
|
@ -255,211 +265,24 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) {
|
|||
//#define DO_IT_NOW(call, offset) runLastCommand();
|
||||
#define DO_IT_NOW(call, offset)
|
||||
|
||||
|
||||
void Batch::_glEnable(GLenum cap) {
|
||||
ADD_COMMAND_GL(glEnable);
|
||||
|
||||
_params.push_back(cap);
|
||||
|
||||
DO_IT_NOW(_glEnable, 1);
|
||||
}
|
||||
void GLBackend::do_glEnable(Batch& batch, uint32 paramOffset) {
|
||||
glEnable(batch._params[paramOffset]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glDisable(GLenum cap) {
|
||||
ADD_COMMAND_GL(glDisable);
|
||||
|
||||
_params.push_back(cap);
|
||||
|
||||
DO_IT_NOW(_glDisable, 1);
|
||||
}
|
||||
void GLBackend::do_glDisable(Batch& batch, uint32 paramOffset) {
|
||||
glDisable(batch._params[paramOffset]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glEnableClientState(GLenum array) {
|
||||
ADD_COMMAND_GL(glEnableClientState);
|
||||
|
||||
_params.push_back(array);
|
||||
|
||||
DO_IT_NOW(_glEnableClientState, 1);
|
||||
}
|
||||
void GLBackend::do_glEnableClientState(Batch& batch, uint32 paramOffset) {
|
||||
glEnableClientState(batch._params[paramOffset]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glDisableClientState(GLenum array) {
|
||||
ADD_COMMAND_GL(glDisableClientState);
|
||||
|
||||
_params.push_back(array);
|
||||
|
||||
DO_IT_NOW(_glDisableClientState, 1);
|
||||
}
|
||||
void GLBackend::do_glDisableClientState(Batch& batch, uint32 paramOffset) {
|
||||
glDisableClientState(batch._params[paramOffset]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glCullFace(GLenum mode) {
|
||||
ADD_COMMAND_GL(glCullFace);
|
||||
|
||||
_params.push_back(mode);
|
||||
|
||||
DO_IT_NOW(_glCullFace, 1);
|
||||
}
|
||||
void GLBackend::do_glCullFace(Batch& batch, uint32 paramOffset) {
|
||||
glCullFace(batch._params[paramOffset]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glAlphaFunc(GLenum func, GLclampf ref) {
|
||||
ADD_COMMAND_GL(glAlphaFunc);
|
||||
|
||||
_params.push_back(ref);
|
||||
_params.push_back(func);
|
||||
|
||||
DO_IT_NOW(_glAlphaFunc, 2);
|
||||
}
|
||||
void GLBackend::do_glAlphaFunc(Batch& batch, uint32 paramOffset) {
|
||||
glAlphaFunc(
|
||||
batch._params[paramOffset + 1]._uint,
|
||||
batch._params[paramOffset + 0]._float);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glDepthFunc(GLenum func) {
|
||||
ADD_COMMAND_GL(glDepthFunc);
|
||||
|
||||
_params.push_back(func);
|
||||
|
||||
DO_IT_NOW(_glDepthFunc, 1);
|
||||
}
|
||||
void GLBackend::do_glDepthFunc(Batch& batch, uint32 paramOffset) {
|
||||
glDepthFunc(batch._params[paramOffset]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glDepthMask(GLboolean flag) {
|
||||
ADD_COMMAND_GL(glDepthMask);
|
||||
|
||||
_params.push_back(flag);
|
||||
|
||||
DO_IT_NOW(_glDepthMask, 1);
|
||||
}
|
||||
void GLBackend::do_glDepthMask(Batch& batch, uint32 paramOffset) {
|
||||
glDepthMask(batch._params[paramOffset]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glDepthRange(GLfloat zNear, GLfloat zFar) {
|
||||
ADD_COMMAND_GL(glDepthRange);
|
||||
|
||||
_params.push_back(zFar);
|
||||
_params.push_back(zNear);
|
||||
|
||||
DO_IT_NOW(_glDepthRange, 2);
|
||||
}
|
||||
void GLBackend::do_glDepthRange(Batch& batch, uint32 paramOffset) {
|
||||
glDepthRange(
|
||||
batch._params[paramOffset + 1]._float,
|
||||
batch._params[paramOffset + 0]._float);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glBindBuffer(GLenum target, GLuint buffer) {
|
||||
ADD_COMMAND_GL(glBindBuffer);
|
||||
|
||||
_params.push_back(buffer);
|
||||
_params.push_back(target);
|
||||
|
||||
DO_IT_NOW(_glBindBuffer, 2);
|
||||
}
|
||||
void GLBackend::do_glBindBuffer(Batch& batch, uint32 paramOffset) {
|
||||
glBindBuffer(
|
||||
batch._params[paramOffset + 1]._uint,
|
||||
batch._params[paramOffset + 0]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glBindTexture(GLenum target, GLuint texture) {
|
||||
ADD_COMMAND_GL(glBindTexture);
|
||||
void Batch::_glActiveBindTexture(GLenum unit, GLenum target, GLuint texture) {
|
||||
ADD_COMMAND_GL(glActiveBindTexture);
|
||||
|
||||
_params.push_back(texture);
|
||||
_params.push_back(target);
|
||||
_params.push_back(unit);
|
||||
|
||||
DO_IT_NOW(_glBindTexture, 2);
|
||||
|
||||
DO_IT_NOW(_glActiveBindTexture, 3);
|
||||
}
|
||||
void GLBackend::do_glBindTexture(Batch& batch, uint32 paramOffset) {
|
||||
void GLBackend::do_glActiveBindTexture(Batch& batch, uint32 paramOffset) {
|
||||
glActiveTexture(batch._params[paramOffset + 2]._uint);
|
||||
glBindTexture(
|
||||
batch._params[paramOffset + 1]._uint,
|
||||
batch._params[paramOffset + 0]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glActiveTexture(GLenum texture) {
|
||||
ADD_COMMAND_GL(glActiveTexture);
|
||||
|
||||
_params.push_back(texture);
|
||||
|
||||
DO_IT_NOW(_glActiveTexture, 1);
|
||||
}
|
||||
void GLBackend::do_glActiveTexture(Batch& batch, uint32 paramOffset) {
|
||||
glActiveTexture(batch._params[paramOffset]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||
ADD_COMMAND_GL(glTexParameteri);
|
||||
|
||||
_params.push_back(param);
|
||||
_params.push_back(pname);
|
||||
_params.push_back(target);
|
||||
|
||||
DO_IT_NOW(glTexParameteri, 3);
|
||||
}
|
||||
void GLBackend::do_glTexParameteri(Batch& batch, uint32 paramOffset) {
|
||||
glTexParameteri(batch._params[paramOffset + 2]._uint,
|
||||
batch._params[paramOffset + 1]._uint,
|
||||
batch._params[paramOffset + 0]._int);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glDrawBuffers(GLsizei n, const GLenum* bufs) {
|
||||
ADD_COMMAND_GL(glDrawBuffers);
|
||||
|
||||
_params.push_back(cacheData(n * sizeof(GLenum), bufs));
|
||||
_params.push_back(n);
|
||||
|
||||
DO_IT_NOW(_glDrawBuffers, 2);
|
||||
}
|
||||
void GLBackend::do_glDrawBuffers(Batch& batch, uint32 paramOffset) {
|
||||
glDrawBuffers(
|
||||
batch._params[paramOffset + 1]._uint,
|
||||
(const GLenum*)batch.editData(batch._params[paramOffset + 0]._uint));
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glUseProgram(GLuint program) {
|
||||
ADD_COMMAND_GL(glUseProgram);
|
||||
|
||||
_params.push_back(program);
|
||||
|
||||
DO_IT_NOW(_glUseProgram, 1);
|
||||
}
|
||||
void GLBackend::do_glUseProgram(Batch& batch, uint32 paramOffset) {
|
||||
|
||||
_pipeline._program = batch._params[paramOffset]._uint;
|
||||
// for this call we still want to execute the glUseProgram in the order of the glCOmmand to avoid any issue
|
||||
_pipeline._invalidProgram = false;
|
||||
glUseProgram(_pipeline._program);
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glUniform1i(GLint location, GLint v0) {
|
||||
if (location < 0) {
|
||||
return;
|
||||
|
@ -660,30 +483,6 @@ void GLBackend::do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset) {
|
|||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glEnableVertexAttribArray(GLint location) {
|
||||
ADD_COMMAND_GL(glEnableVertexAttribArray);
|
||||
|
||||
_params.push_back(location);
|
||||
|
||||
DO_IT_NOW(_glEnableVertexAttribArray, 1);
|
||||
}
|
||||
void GLBackend::do_glEnableVertexAttribArray(Batch& batch, uint32 paramOffset) {
|
||||
glEnableVertexAttribArray(batch._params[paramOffset]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glDisableVertexAttribArray(GLint location) {
|
||||
ADD_COMMAND_GL(glDisableVertexAttribArray);
|
||||
|
||||
_params.push_back(location);
|
||||
|
||||
DO_IT_NOW(_glDisableVertexAttribArray, 1);
|
||||
}
|
||||
void GLBackend::do_glDisableVertexAttribArray(Batch& batch, uint32 paramOffset) {
|
||||
glDisableVertexAttribArray(batch._params[paramOffset]._uint);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
|
||||
ADD_COMMAND_GL(glColor4f);
|
||||
|
||||
|
|
|
@ -18,16 +18,21 @@
|
|||
#include "GPUConfig.h"
|
||||
|
||||
#include "Context.h"
|
||||
#include "Batch.h"
|
||||
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class GLBackend : public Backend {
|
||||
public:
|
||||
|
||||
// Context Backend static interface required
|
||||
friend class Context;
|
||||
static void init();
|
||||
static Backend* createBackend();
|
||||
static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings);
|
||||
|
||||
explicit GLBackend(bool syncCache);
|
||||
GLBackend();
|
||||
public:
|
||||
|
||||
virtual ~GLBackend();
|
||||
|
||||
virtual void render(Batch& batch);
|
||||
|
@ -49,7 +54,6 @@ public:
|
|||
|
||||
static void checkGLStackStable(std::function<void()> f);
|
||||
|
||||
static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings = Shader::BindingSet());
|
||||
|
||||
|
||||
class GLBuffer : public GPUObject {
|
||||
|
@ -91,9 +95,9 @@ public:
|
|||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_CORE)
|
||||
#else
|
||||
GLuint _transformObject_model = -1;
|
||||
GLuint _transformCamera_viewInverse = -1;
|
||||
GLuint _transformCamera_viewport = -1;
|
||||
GLint _transformObject_model = -1;
|
||||
GLint _transformCamera_viewInverse = -1;
|
||||
GLint _transformCamera_viewport = -1;
|
||||
#endif
|
||||
|
||||
GLShader();
|
||||
|
@ -195,8 +199,17 @@ public:
|
|||
static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS;
|
||||
static const int MAX_NUM_INPUT_BUFFERS = 16;
|
||||
|
||||
uint32 getNumInputBuffers() const { return _input._buffersState.size(); }
|
||||
uint32 getNumInputBuffers() const { return _input._invalidBuffers.size(); }
|
||||
|
||||
// this is the maximum per shader stage on the low end apple
|
||||
// TODO make it platform dependant at init time
|
||||
static const int MAX_NUM_UNIFORM_BUFFERS = 12;
|
||||
uint32 getMaxNumUniformBuffers() const { return MAX_NUM_UNIFORM_BUFFERS; }
|
||||
|
||||
// this is the maximum per shader stage on the low end apple
|
||||
// TODO make it platform dependant at init time
|
||||
static const int MAX_NUM_RESOURCE_TEXTURES = 16;
|
||||
uint32 getMaxNumResourceTextures() const { return MAX_NUM_RESOURCE_TEXTURES; }
|
||||
|
||||
// The State setters called by the GLState::Commands when a new state is assigned
|
||||
void do_setStateFillMode(int32 mode);
|
||||
|
@ -250,12 +263,16 @@ protected:
|
|||
void killInput();
|
||||
void syncInputStateCache();
|
||||
void updateInput();
|
||||
void resetInputStage();
|
||||
struct InputStageState {
|
||||
bool _invalidFormat = true;
|
||||
Stream::FormatPointer _format;
|
||||
|
||||
typedef std::bitset<MAX_NUM_ATTRIBUTES> ActivationCache;
|
||||
ActivationCache _attributeActivation;
|
||||
|
||||
typedef std::bitset<MAX_NUM_INPUT_BUFFERS> BuffersState;
|
||||
BuffersState _buffersState;
|
||||
BuffersState _invalidBuffers;
|
||||
|
||||
Buffers _buffers;
|
||||
Offsets _bufferOffsets;
|
||||
|
@ -266,23 +283,20 @@ protected:
|
|||
Offset _indexBufferOffset;
|
||||
Type _indexBufferType;
|
||||
|
||||
typedef std::bitset<MAX_NUM_ATTRIBUTES> ActivationCache;
|
||||
ActivationCache _attributeActivation;
|
||||
|
||||
GLuint _defaultVAO;
|
||||
|
||||
InputStageState() :
|
||||
_invalidFormat(true),
|
||||
_format(0),
|
||||
_buffersState(0),
|
||||
_buffers(_buffersState.size(), BufferPointer(0)),
|
||||
_bufferOffsets(_buffersState.size(), 0),
|
||||
_bufferStrides(_buffersState.size(), 0),
|
||||
_bufferVBOs(_buffersState.size(), 0),
|
||||
_attributeActivation(0),
|
||||
_invalidBuffers(0),
|
||||
_buffers(_invalidBuffers.size(), BufferPointer(0)),
|
||||
_bufferOffsets(_invalidBuffers.size(), 0),
|
||||
_bufferStrides(_invalidBuffers.size(), 0),
|
||||
_bufferVBOs(_invalidBuffers.size(), 0),
|
||||
_indexBuffer(0),
|
||||
_indexBufferOffset(0),
|
||||
_indexBufferType(UINT32),
|
||||
_attributeActivation(0),
|
||||
_defaultVAO(0)
|
||||
{}
|
||||
} _input;
|
||||
|
@ -298,6 +312,7 @@ protected:
|
|||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||
void syncTransformStateCache();
|
||||
void updateTransform();
|
||||
void resetTransformStage();
|
||||
struct TransformStageState {
|
||||
TransformObject _transformObject;
|
||||
TransformCamera _transformCamera;
|
||||
|
@ -330,12 +345,31 @@ protected:
|
|||
|
||||
// Uniform Stage
|
||||
void do_setUniformBuffer(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void releaseUniformBuffer(int slot);
|
||||
void resetUniformStage();
|
||||
struct UniformStageState {
|
||||
Buffers _buffers;
|
||||
|
||||
UniformStageState():
|
||||
_buffers(MAX_NUM_UNIFORM_BUFFERS, nullptr)
|
||||
{}
|
||||
} _uniform;
|
||||
|
||||
// Resource Stage
|
||||
void do_setResourceTexture(Batch& batch, uint32 paramOffset);
|
||||
|
||||
struct UniformStageState {
|
||||
|
||||
};
|
||||
|
||||
void releaseResourceTexture(int slot);
|
||||
void resetResourceStage();
|
||||
struct ResourceStageState {
|
||||
Textures _textures;
|
||||
|
||||
ResourceStageState():
|
||||
_textures(MAX_NUM_RESOURCE_TEXTURES, nullptr)
|
||||
{}
|
||||
|
||||
} _resource;
|
||||
|
||||
// Pipeline Stage
|
||||
void do_setPipeline(Batch& batch, uint32 paramOffset);
|
||||
void do_setStateBlendFactor(Batch& batch, uint32 paramOffset);
|
||||
|
@ -349,6 +383,7 @@ protected:
|
|||
void syncPipelineStateCache();
|
||||
// Grab the actual gl state into it's gpu::State equivalent. THis is used by the above call syncPipleineStateCache()
|
||||
void getCurrentGLState(State::Data& state);
|
||||
void resetPipelineStage();
|
||||
|
||||
struct PipelineStageState {
|
||||
|
||||
|
@ -388,6 +423,7 @@ protected:
|
|||
|
||||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||
void syncOutputStateCache();
|
||||
void resetOutputStage();
|
||||
|
||||
struct OutputStageState {
|
||||
|
||||
|
@ -402,31 +438,20 @@ protected:
|
|||
void do_endQuery(Batch& batch, uint32 paramOffset);
|
||||
void do_getQuery(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void resetQueryStage();
|
||||
struct QueryStageState {
|
||||
|
||||
};
|
||||
|
||||
// Reset stages
|
||||
void do_resetStages(Batch& batch, uint32 paramOffset);
|
||||
void resetStages();
|
||||
|
||||
// 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
|
||||
void do_glEnable(Batch& batch, uint32 paramOffset);
|
||||
void do_glDisable(Batch& batch, uint32 paramOffset);
|
||||
void do_glActiveBindTexture(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glEnableClientState(Batch& batch, uint32 paramOffset);
|
||||
void do_glDisableClientState(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glCullFace(Batch& batch, uint32 paramOffset);
|
||||
void do_glAlphaFunc(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glDepthFunc(Batch& batch, uint32 paramOffset);
|
||||
void do_glDepthMask(Batch& batch, uint32 paramOffset);
|
||||
void do_glDepthRange(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glBindBuffer(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glBindTexture(Batch& batch, uint32 paramOffset);
|
||||
void do_glActiveTexture(Batch& batch, uint32 paramOffset);
|
||||
void do_glTexParameteri(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glDrawBuffers(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glUseProgram(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform1i(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform1f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform2f(Batch& batch, uint32 paramOffset);
|
||||
|
@ -436,9 +461,6 @@ protected:
|
|||
void do_glUniform4iv(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glEnableVertexAttribArray(Batch& batch, uint32 paramOffset);
|
||||
void do_glDisableVertexAttribArray(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glColor4f(Batch& batch, uint32 paramOffset);
|
||||
void do_glLineWidth(Batch& batch, uint32 paramOffset);
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ void GLBackend::do_setInputBuffer(Batch& batch, uint32 paramOffset) {
|
|||
}
|
||||
|
||||
if (isModified) {
|
||||
_input._buffersState.set(channel);
|
||||
_input._invalidBuffers.set(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ void GLBackend::updateInput() {
|
|||
_stats._ISNumFormatChanges++;
|
||||
}
|
||||
|
||||
if (_input._buffersState.any()) {
|
||||
if (_input._invalidBuffers.any()) {
|
||||
int numBuffers = _input._buffers.size();
|
||||
auto buffer = _input._buffers.data();
|
||||
auto vbo = _input._bufferVBOs.data();
|
||||
|
@ -162,7 +162,7 @@ void GLBackend::updateInput() {
|
|||
auto stride = _input._bufferStrides.data();
|
||||
|
||||
for (int bufferNum = 0; bufferNum < numBuffers; bufferNum++) {
|
||||
if (_input._buffersState.test(bufferNum)) {
|
||||
if (_input._invalidBuffers.test(bufferNum)) {
|
||||
glBindVertexBuffer(bufferNum, (*vbo), (*offset), (*stride));
|
||||
}
|
||||
buffer++;
|
||||
|
@ -170,11 +170,11 @@ void GLBackend::updateInput() {
|
|||
offset++;
|
||||
stride++;
|
||||
}
|
||||
_input._buffersState.reset();
|
||||
_input._invalidBuffers.reset();
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
#else
|
||||
if (_input._invalidFormat || _input._buffersState.any()) {
|
||||
if (_input._invalidFormat || _input._invalidBuffers.any()) {
|
||||
|
||||
if (_input._invalidFormat) {
|
||||
InputStageState::ActivationCache newActivation;
|
||||
|
@ -232,7 +232,7 @@ void GLBackend::updateInput() {
|
|||
if ((channelIt).first < buffers.size()) {
|
||||
int bufferNum = (channelIt).first;
|
||||
|
||||
if (_input._buffersState.test(bufferNum) || _input._invalidFormat) {
|
||||
if (_input._invalidBuffers.test(bufferNum) || _input._invalidFormat) {
|
||||
// GLuint vbo = gpu::GLBackend::getBufferID((*buffers[bufferNum]));
|
||||
GLuint vbo = _input._bufferVBOs[bufferNum];
|
||||
if (boundVBO != vbo) {
|
||||
|
@ -240,7 +240,7 @@ void GLBackend::updateInput() {
|
|||
(void) CHECK_GL_ERROR();
|
||||
boundVBO = vbo;
|
||||
}
|
||||
_input._buffersState[bufferNum] = false;
|
||||
_input._invalidBuffers[bufferNum] = false;
|
||||
|
||||
for (unsigned int i = 0; i < channel._slots.size(); i++) {
|
||||
const Stream::Attribute& attrib = attributes.at(channel._slots[i]);
|
||||
|
@ -285,6 +285,51 @@ void GLBackend::updateInput() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void GLBackend::resetInputStage() {
|
||||
// Reset index buffer
|
||||
_input._indexBufferType = UINT32;
|
||||
_input._indexBufferOffset = 0;
|
||||
_input._indexBuffer.reset();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
(void) CHECK_GL_ERROR();
|
||||
|
||||
|
||||
#if defined(SUPPORT_VAO)
|
||||
// TODO
|
||||
#else
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
size_t i = 0;
|
||||
#if defined(SUPPORT_LEGACY_OPENGL)
|
||||
for (; i < NUM_CLASSIC_ATTRIBS; i++) {
|
||||
glDisableClientState(attributeSlotToClassicAttribName[i]);
|
||||
}
|
||||
glVertexPointer(4, GL_FLOAT, 0, 0);
|
||||
glNormalPointer(GL_FLOAT, 0, 0);
|
||||
glColorPointer(4, GL_FLOAT, 0, 0);
|
||||
glTexCoordPointer(4, GL_FLOAT, 0, 0);
|
||||
#endif
|
||||
|
||||
for (; i < _input._attributeActivation.size(); i++) {
|
||||
glDisableVertexAttribArray(i);
|
||||
glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reset vertex buffer and format
|
||||
_input._format.reset();
|
||||
_input._invalidFormat = false;
|
||||
_input._attributeActivation.reset();
|
||||
|
||||
for (int i = 0; i < _input._buffers.size(); i++) {
|
||||
_input._buffers[i].reset();
|
||||
_input._bufferOffsets[i] = 0;
|
||||
_input._bufferStrides[i] = 0;
|
||||
_input._bufferVBOs[i] = 0;
|
||||
}
|
||||
_input._invalidBuffers.reset();
|
||||
|
||||
}
|
||||
|
||||
void GLBackend::do_setIndexBuffer(Batch& batch, uint32 paramOffset) {
|
||||
_input._indexBufferType = (Type) batch._params[paramOffset + 2]._uint;
|
||||
|
|
|
@ -177,6 +177,13 @@ void GLBackend::syncOutputStateCache() {
|
|||
_output._framebuffer.reset();
|
||||
}
|
||||
|
||||
void GLBackend::resetOutputStage() {
|
||||
if (_output._framebuffer) {
|
||||
_output._framebuffer.reset();
|
||||
_output._drawFBO = 0;
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GLBackend::do_setFramebuffer(Batch& batch, uint32 paramOffset) {
|
||||
auto framebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint);
|
||||
|
@ -206,12 +213,21 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) {
|
|||
if (masks & Framebuffer::BUFFER_STENCIL) {
|
||||
glClearStencil(stencil);
|
||||
glmask |= GL_STENCIL_BUFFER_BIT;
|
||||
// TODO: we will probably need to also check the write mask of stencil like we do
|
||||
// for depth buffer, but as would say a famous Fez owner "We'll cross that bridge when we come to it"
|
||||
}
|
||||
|
||||
bool restoreDepthMask = false;
|
||||
if (masks & Framebuffer::BUFFER_DEPTH) {
|
||||
glClearDepth(depth);
|
||||
glmask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
bool cacheDepthMask = _pipeline._stateCache.depthTest.getWriteMask();
|
||||
if (!cacheDepthMask) {
|
||||
restoreDepthMask = true;
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<GLenum> drawBuffers;
|
||||
if (masks & Framebuffer::BUFFER_COLORS) {
|
||||
|
@ -245,6 +261,11 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) {
|
|||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
// Restore write mask meaning turn back off
|
||||
if (restoreDepthMask) {
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
|
||||
// Restore the color draw buffers only if a frmaebuffer is bound
|
||||
if (_output._framebuffer && !drawBuffers.empty()) {
|
||||
auto glFramebuffer = syncGPUObject(*_output._framebuffer);
|
||||
|
|
|
@ -164,15 +164,74 @@ void GLBackend::updatePipeline() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void GLBackend::resetPipelineStage() {
|
||||
// First reset State to default
|
||||
State::Signature resetSignature(0);
|
||||
resetPipelineState(resetSignature);
|
||||
_pipeline._state = nullptr;
|
||||
_pipeline._invalidState = false;
|
||||
|
||||
// Second the shader side
|
||||
_pipeline._invalidProgram = false;
|
||||
_pipeline._program = 0;
|
||||
_pipeline._pipeline.reset();
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
|
||||
void GLBackend::releaseUniformBuffer(int slot) {
|
||||
#if (GPU_FEATURE_PROFILE == GPU_CORE)
|
||||
auto& buf = _uniform._buffers[slot];
|
||||
if (buf) {
|
||||
auto* object = Backend::getGPUObject<GLBackend::GLBuffer>(*buf);
|
||||
if (object) {
|
||||
GLuint bo = object->_buffer;
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, slot, 0); // RELEASE
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
buf.reset();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLBackend::resetUniformStage() {
|
||||
for (int i = 0; i < _uniform._buffers.size(); i++) {
|
||||
releaseUniformBuffer(i);
|
||||
}
|
||||
}
|
||||
|
||||
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 (GPU_FEATURE_PROFILE == GPU_CORE)
|
||||
GLuint bo = getBufferID(*uniformBuffer);
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, slot, bo, rangeStart, rangeSize);
|
||||
if (!uniformBuffer) {
|
||||
releaseUniformBuffer(slot);
|
||||
return;
|
||||
}
|
||||
|
||||
// check cache before thinking
|
||||
if (_uniform._buffers[slot] == uniformBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sync BufferObject
|
||||
auto* object = GLBackend::syncGPUObject(*uniformBuffer);
|
||||
if (object) {
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, slot, object->_buffer, rangeStart, rangeSize);
|
||||
|
||||
_uniform._buffers[slot] = uniformBuffer;
|
||||
(void) CHECK_GL_ERROR();
|
||||
} else {
|
||||
releaseResourceTexture(slot);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
// because we rely on the program uniform mechanism we need to have
|
||||
// the program bound, thank you MacOSX Legacy profile.
|
||||
|
@ -184,19 +243,49 @@ void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
|
|||
// NOT working so we ll stick to the uniform float array until we move to core profile
|
||||
// GLuint bo = getBufferID(*uniformBuffer);
|
||||
//glUniformBufferEXT(_shader._program, slot, bo);
|
||||
#endif
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLBackend::releaseResourceTexture(int slot) {
|
||||
auto& tex = _resource._textures[slot];
|
||||
if (tex) {
|
||||
auto* object = Backend::getGPUObject<GLBackend::GLTexture>(*tex);
|
||||
if (object) {
|
||||
GLuint to = object->_texture;
|
||||
GLuint target = object->_target;
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(target, 0); // RELEASE
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
tex.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void GLBackend::resetResourceStage() {
|
||||
for (int i = 0; i < _resource._textures.size(); i++) {
|
||||
releaseResourceTexture(i);
|
||||
}
|
||||
}
|
||||
|
||||
void GLBackend::do_setResourceTexture(Batch& batch, uint32 paramOffset) {
|
||||
GLuint slot = batch._params[paramOffset + 1]._uint;
|
||||
TexturePointer uniformTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
|
||||
TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
|
||||
|
||||
if (!uniformTexture) {
|
||||
if (!resourceTexture) {
|
||||
releaseResourceTexture(slot);
|
||||
return;
|
||||
}
|
||||
// check cache before thinking
|
||||
if (_resource._textures[slot] == resourceTexture) {
|
||||
return;
|
||||
}
|
||||
|
||||
GLTexture* object = GLBackend::syncGPUObject(*uniformTexture);
|
||||
// Always make sure the GLObject is in sync
|
||||
GLTexture* object = GLBackend::syncGPUObject(*resourceTexture);
|
||||
if (object) {
|
||||
GLuint to = object->_texture;
|
||||
GLuint target = object->_target;
|
||||
|
@ -205,7 +294,10 @@ void GLBackend::do_setResourceTexture(Batch& batch, uint32 paramOffset) {
|
|||
|
||||
(void) CHECK_GL_ERROR();
|
||||
|
||||
_resource._textures[slot] = resourceTexture;
|
||||
|
||||
} else {
|
||||
releaseResourceTexture(slot);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "GPULogging.h"
|
||||
#include "GLBackendShared.h"
|
||||
|
||||
|
||||
|
@ -104,3 +103,7 @@ void GLBackend::do_getQuery(Batch& batch, uint32 paramOffset) {
|
|||
(void)CHECK_GL_ERROR();
|
||||
}
|
||||
}
|
||||
|
||||
void GLBackend::resetQueryStage() {
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "GPULogging.h"
|
||||
#include "GLBackendShared.h"
|
||||
#include "Format.h"
|
||||
|
||||
|
@ -542,7 +541,12 @@ ElementResource getFormatFromGLUniform(GLenum gltype) {
|
|||
};
|
||||
|
||||
|
||||
int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers) {
|
||||
int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,
|
||||
Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers
|
||||
#if (GPU_FEATURE_PROFILE == GPU_LEGACY)
|
||||
, Shader::SlotSet& fakeBuffers
|
||||
#endif
|
||||
) {
|
||||
GLint uniformsCount = 0;
|
||||
|
||||
#if (GPU_FEATURE_PROFILE == GPU_LEGACY)
|
||||
|
@ -583,6 +587,15 @@ int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, S
|
|||
}
|
||||
|
||||
if (elementResource._resource == Resource::BUFFER) {
|
||||
#if (GPU_FEATURE_PROFILE == GPU_LEGACY)
|
||||
// if in legacy profile, we fake the uniform buffer with an array
|
||||
// this is where we detect it assuming it's explicitely assinged a binding
|
||||
auto requestedBinding = slotBindings.find(std::string(sname));
|
||||
if (requestedBinding != slotBindings.end()) {
|
||||
// found one buffer!
|
||||
fakeBuffers.insert(Shader::Slot(sname, location, elementResource._element, elementResource._resource));
|
||||
}
|
||||
#endif
|
||||
uniforms.insert(Shader::Slot(sname, location, elementResource._element, elementResource._resource));
|
||||
} else {
|
||||
// For texture/Sampler, the location is the actual binding value
|
||||
|
@ -640,14 +653,13 @@ int makeUniformBlockSlots(GLuint glprogram, const Shader::BindingSet& slotBindin
|
|||
GLchar name[NAME_LENGTH];
|
||||
GLint length = 0;
|
||||
GLint size = 0;
|
||||
GLenum type = 0;
|
||||
GLint binding = -1;
|
||||
|
||||
glGetActiveUniformBlockiv(glprogram, i, GL_UNIFORM_BLOCK_NAME_LENGTH, &length);
|
||||
glGetActiveUniformBlockName(glprogram, i, NAME_LENGTH, &length, name);
|
||||
glGetActiveUniformBlockiv(glprogram, i, GL_UNIFORM_BLOCK_BINDING, &binding);
|
||||
glGetActiveUniformBlockiv(glprogram, i, GL_UNIFORM_BLOCK_DATA_SIZE, &size);
|
||||
|
||||
|
||||
GLuint blockIndex = glGetUniformBlockIndex(glprogram, name);
|
||||
|
||||
// CHeck if there is a requested binding for this block
|
||||
|
@ -738,8 +750,12 @@ bool GLBackend::makeProgram(Shader& shader, const Shader::BindingSet& slotBindin
|
|||
Shader::SlotSet uniforms;
|
||||
Shader::SlotSet textures;
|
||||
Shader::SlotSet samplers;
|
||||
#if (GPU_FEATURE_PROFILE == GPU_CORE)
|
||||
makeUniformSlots(object->_program, slotBindings, uniforms, textures, samplers);
|
||||
|
||||
#else
|
||||
makeUniformSlots(object->_program, slotBindings, uniforms, textures, samplers, buffers);
|
||||
#endif
|
||||
|
||||
Shader::SlotSet inputs;
|
||||
makeInputSlots(object->_program, slotBindings, inputs);
|
||||
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
#ifndef hifi_gpu_GLBackend_Shared_h
|
||||
#define hifi_gpu_GLBackend_Shared_h
|
||||
|
||||
#include "GLBackend.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "Batch.h"
|
||||
#include "GPULogging.h"
|
||||
#include "GLBackend.h"
|
||||
|
||||
static const GLenum _primitiveToGLmode[gpu::NUM_PRIMITIVES] = {
|
||||
GL_POINTS,
|
||||
|
@ -24,8 +23,6 @@ static const GLenum _primitiveToGLmode[gpu::NUM_PRIMITIVES] = {
|
|||
GL_TRIANGLES,
|
||||
GL_TRIANGLE_STRIP,
|
||||
GL_TRIANGLE_FAN,
|
||||
GL_QUADS,
|
||||
GL_QUAD_STRIP,
|
||||
};
|
||||
|
||||
static const GLenum _elementTypeToGLType[gpu::NUM_TYPES] = {
|
||||
|
|
|
@ -482,9 +482,15 @@ void GLBackend::syncPipelineStateCache() {
|
|||
State::Data state;
|
||||
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
|
||||
// Point size is always on
|
||||
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
||||
glEnable(GL_PROGRAM_POINT_SIZE_EXT);
|
||||
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
|
||||
getCurrentGLState(state);
|
||||
State::Signature signature = State::evalSignature(state);
|
||||
|
||||
|
||||
_pipeline._stateCache = state;
|
||||
_pipeline._stateSignatureCache = signature;
|
||||
}
|
||||
|
|
|
@ -184,4 +184,6 @@ void GLBackend::updateTransform() {
|
|||
_transform._invalidView = _transform._invalidProj = _transform._invalidModel = _transform._invalidViewport = false;
|
||||
}
|
||||
|
||||
|
||||
void GLBackend::resetTransformStage() {
|
||||
|
||||
}
|
||||
|
|
|
@ -34,11 +34,11 @@
|
|||
#elif defined(ANDROID)
|
||||
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
|
||||
#define GPU_FEATURE_PROFILE GPU_LEGACY
|
||||
#define GPU_TRANSFORM_PROFILE GPU_LEGACY
|
||||
#include <GL/glew.h>
|
||||
|
||||
#define GPU_FEATURE_PROFILE GPU_CORE
|
||||
#define GPU_TRANSFORM_PROFILE GPU_CORE
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
LINE_STRIP,
|
||||
TRIANGLES,
|
||||
TRIANGLE_STRIP,
|
||||
QUADS,
|
||||
QUADS, // NOTE: These must be translated to triangles before rendering
|
||||
QUAD_STRIP,
|
||||
|
||||
NUM_TOPOLOGIES,
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
|
||||
#include <bitset>
|
||||
#include <map>
|
||||
#include <qurl.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "gpu/Resource.h"
|
||||
#include "gpu/Texture.h"
|
||||
|
||||
#include <qurl.h>
|
||||
|
||||
namespace model {
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ std::unique_ptr<NLPacket> NLPacket::create(PacketType::Value type, qint64 size)
|
|||
return packet;
|
||||
}
|
||||
|
||||
std::unique_ptr<NLPacket> NLPacket::fromReceivedPacket(std::unique_ptr<char> data, qint64 size,
|
||||
std::unique_ptr<NLPacket> NLPacket::fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size,
|
||||
const HifiSockAddr& senderSockAddr) {
|
||||
// Fail with null data
|
||||
Q_ASSERT(data);
|
||||
|
@ -85,7 +85,7 @@ NLPacket::NLPacket(const NLPacket& other) : Packet(other) {
|
|||
|
||||
}
|
||||
|
||||
NLPacket::NLPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr) :
|
||||
NLPacket::NLPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr) :
|
||||
Packet(std::move(data), size, senderSockAddr)
|
||||
{
|
||||
adjustPayloadStartAndCapacity();
|
||||
|
|
|
@ -20,7 +20,7 @@ class NLPacket : public Packet {
|
|||
Q_OBJECT
|
||||
public:
|
||||
static std::unique_ptr<NLPacket> create(PacketType::Value type, qint64 size = -1);
|
||||
static std::unique_ptr<NLPacket> fromReceivedPacket(std::unique_ptr<char> data, qint64 size,
|
||||
static std::unique_ptr<NLPacket> fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size,
|
||||
const HifiSockAddr& senderSockAddr);
|
||||
// Provided for convenience, try to limit use
|
||||
static std::unique_ptr<NLPacket> createCopy(const NLPacket& other);
|
||||
|
@ -45,7 +45,7 @@ protected:
|
|||
|
||||
NLPacket(PacketType::Value type);
|
||||
NLPacket(PacketType::Value type, qint64 size);
|
||||
NLPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr);
|
||||
NLPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr);
|
||||
NLPacket(const NLPacket& other);
|
||||
|
||||
void readSourceID();
|
||||
|
|
|
@ -243,7 +243,7 @@ void PacketReceiver::processDatagrams() {
|
|||
while (nodeList && nodeList->getNodeSocket().hasPendingDatagrams()) {
|
||||
// setup a buffer to read the packet into
|
||||
int packetSizeWithHeader = nodeList->getNodeSocket().pendingDatagramSize();
|
||||
std::unique_ptr<char> buffer = std::unique_ptr<char>(new char[packetSizeWithHeader]);
|
||||
auto buffer = std::unique_ptr<char[]>(new char[packetSizeWithHeader]);
|
||||
|
||||
// if we're supposed to drop this packet then break out here
|
||||
if (_shouldDropPackets) {
|
||||
|
|
|
@ -31,7 +31,7 @@ std::unique_ptr<Packet> Packet::create(PacketType::Value type, qint64 size) {
|
|||
return packet;
|
||||
}
|
||||
|
||||
std::unique_ptr<Packet> Packet::fromReceivedPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr) {
|
||||
std::unique_ptr<Packet> Packet::fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr) {
|
||||
// Fail with invalid size
|
||||
Q_ASSERT(size >= 0);
|
||||
|
||||
|
@ -82,7 +82,7 @@ Packet::Packet(PacketType::Value type, qint64 size) :
|
|||
}
|
||||
}
|
||||
|
||||
Packet::Packet(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr) :
|
||||
Packet::Packet(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr) :
|
||||
_packetSize(size),
|
||||
_packet(std::move(data)),
|
||||
_senderSockAddr(senderSockAddr)
|
||||
|
@ -110,7 +110,7 @@ Packet& Packet::operator=(const Packet& other) {
|
|||
_type = other._type;
|
||||
|
||||
_packetSize = other._packetSize;
|
||||
_packet = std::unique_ptr<char>(new char[_packetSize]);
|
||||
_packet = std::unique_ptr<char[]>(new char[_packetSize]);
|
||||
memcpy(_packet.get(), other._packet.get(), _packetSize);
|
||||
|
||||
_payloadStart = _packet.get() + (other._payloadStart - other._packet.get());
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
static const qint64 PACKET_WRITE_ERROR;
|
||||
|
||||
static std::unique_ptr<Packet> create(PacketType::Value type, qint64 size = -1);
|
||||
static std::unique_ptr<Packet> fromReceivedPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr);
|
||||
static std::unique_ptr<Packet> fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr);
|
||||
|
||||
// Provided for convenience, try to limit use
|
||||
static std::unique_ptr<Packet> createCopy(const Packet& other);
|
||||
|
@ -88,7 +88,7 @@ public:
|
|||
|
||||
protected:
|
||||
Packet(PacketType::Value type, qint64 size);
|
||||
Packet(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr);
|
||||
Packet(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr);
|
||||
Packet(const Packet& other);
|
||||
Packet& operator=(const Packet& other);
|
||||
Packet(Packet&& other);
|
||||
|
@ -109,7 +109,7 @@ protected:
|
|||
PacketVersion _version; // Packet version
|
||||
|
||||
qint64 _packetSize = 0; // Total size of the allocated memory
|
||||
std::unique_ptr<char> _packet; // Allocated memory
|
||||
std::unique_ptr<char[]> _packet; // Allocated memory
|
||||
|
||||
char* _payloadStart = nullptr; // Start of the payload
|
||||
qint64 _payloadCapacity = 0; // Total capacity of the payload
|
||||
|
|
|
@ -9,15 +9,12 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include <gpu/GLBackend.h>
|
||||
|
||||
#include <glm/gtc/random.hpp>
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
#include "gpu/StandardShaderLib.h"
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
|
@ -164,7 +161,7 @@ const gpu::PipelinePointer& AmbientOcclusion::getBlendPipeline() {
|
|||
|
||||
// Blend on transparent
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_COLOR, gpu::State::BLEND_OP_ADD, gpu::State::DEST_COLOR);
|
||||
gpu::State::INV_SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::SRC_ALPHA);
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_blendPipeline.reset(gpu::Pipeline::create(program, state));
|
||||
|
@ -176,7 +173,6 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons
|
|||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
RenderArgs* args = renderContext->args;
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
gpu::Batch batch;
|
||||
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <gpu/GPUConfig.h>
|
||||
#include <PathUtils.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/Context.h>
|
||||
#include <gpu/StandardShaderLib.h>
|
||||
#include <PathUtils.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "AbstractViewStateInterface.h"
|
||||
#include "GeometryCache.h"
|
||||
|
@ -291,7 +291,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
locations = &_directionalAmbientSphereLightCascadedShadowMapLocations;
|
||||
}
|
||||
batch.setPipeline(program);
|
||||
batch._glUniform3fv(locations->shadowDistances, 1, (const GLfloat*) &_viewState->getShadowDistances());
|
||||
batch._glUniform3fv(locations->shadowDistances, 1, (const float*) &_viewState->getShadowDistances());
|
||||
|
||||
} else {
|
||||
if (useSkyboxCubemap) {
|
||||
|
@ -325,7 +325,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
sh = (*_skybox->getCubemap()->getIrradiance());
|
||||
}
|
||||
for (int i =0; i <gpu::SphericalHarmonics::NUM_COEFFICIENTS; i++) {
|
||||
batch._glUniform4fv(locations->ambientSphere + i, 1, (const GLfloat*) (&sh) + i * 4);
|
||||
batch._glUniform4fv(locations->ambientSphere + i, 1, (const float*) (&sh) + i * 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,7 +340,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) {
|
||||
batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer());
|
||||
}
|
||||
batch._glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat));
|
||||
batch._glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
|
||||
}
|
||||
|
||||
float left, right, bottom, top, nearVal, farVal;
|
||||
|
@ -419,9 +419,9 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
batch._glUniform2f(_pointLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
|
||||
batch._glUniform2f(_pointLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
|
||||
|
||||
batch._glUniformMatrix4fv(_pointLightLocations.invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat));
|
||||
batch._glUniformMatrix4fv(_pointLightLocations.invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
|
||||
|
||||
batch._glUniformMatrix4fv(_pointLightLocations.texcoordMat, 1, false, reinterpret_cast< const GLfloat* >(&texcoordMat));
|
||||
batch._glUniformMatrix4fv(_pointLightLocations.texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
|
||||
|
||||
for (auto lightID : _pointLights) {
|
||||
auto& light = _allocatedLights[lightID];
|
||||
|
@ -467,9 +467,9 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
batch._glUniform2f(_spotLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
|
||||
batch._glUniform2f(_spotLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
|
||||
|
||||
batch._glUniformMatrix4fv(_spotLightLocations.invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat));
|
||||
batch._glUniformMatrix4fv(_spotLightLocations.invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
|
||||
|
||||
batch._glUniformMatrix4fv(_spotLightLocations.texcoordMat, 1, false, reinterpret_cast< const GLfloat* >(&texcoordMat));
|
||||
batch._glUniformMatrix4fv(_spotLightLocations.texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
|
||||
|
||||
for (auto lightID : _spotLights) {
|
||||
auto light = _allocatedLights[lightID];
|
||||
|
@ -489,7 +489,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
if ((eyeHalfPlaneDistance > -nearRadius) &&
|
||||
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) {
|
||||
coneParam.w = 0.0f;
|
||||
batch._glUniform4fv(_spotLightLocations.coneParam, 1, reinterpret_cast< const GLfloat* >(&coneParam));
|
||||
batch._glUniform4fv(_spotLightLocations.coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
||||
|
||||
Transform model;
|
||||
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
|
||||
|
@ -509,7 +509,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
batch.setViewTransform(viewMat);
|
||||
} else {
|
||||
coneParam.w = 1.0f;
|
||||
batch._glUniform4fv(_spotLightLocations.coneParam, 1, reinterpret_cast< const GLfloat* >(&coneParam));
|
||||
batch._glUniform4fv(_spotLightLocations.coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
||||
|
||||
Transform model;
|
||||
model.setTranslation(light->getPosition());
|
||||
|
@ -595,9 +595,9 @@ void DeferredLightingEffect::loadLightProgram(const char* vertSource, const char
|
|||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), 3));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), 4));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), 5));
|
||||
const GLint LIGHT_GPU_SLOT = 3;
|
||||
const int LIGHT_GPU_SLOT = 3;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT));
|
||||
const GLint ATMOSPHERE_GPU_SLOT = 4;
|
||||
const int ATMOSPHERE_GPU_SLOT = 4;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("atmosphereBufferUnit"), ATMOSPHERE_GPU_SLOT));
|
||||
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
@ -614,13 +614,8 @@ void DeferredLightingEffect::loadLightProgram(const char* vertSource, const char
|
|||
locations.texcoordMat = program->getUniforms().findLocation("texcoordMat");
|
||||
locations.coneParam = program->getUniforms().findLocation("coneParam");
|
||||
|
||||
#if (GPU_FEATURE_PROFILE == GPU_CORE)
|
||||
locations.lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
|
||||
locations.atmosphereBufferUnit = program->getBuffers().findLocation("atmosphereBufferUnit");
|
||||
#else
|
||||
locations.lightBufferUnit = program->getUniforms().findLocation("lightBuffer");
|
||||
locations.atmosphereBufferUnit = program->getUniforms().findLocation("atmosphereBufferUnit");
|
||||
#endif
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
if (lightVolume) {
|
||||
|
@ -677,10 +672,10 @@ model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
|
|||
int ringFloatOffset = slices * 3;
|
||||
|
||||
|
||||
GLfloat* vertexData = new GLfloat[verticesSize];
|
||||
GLfloat* vertexRing0 = vertexData;
|
||||
GLfloat* vertexRing1 = vertexRing0 + ringFloatOffset;
|
||||
GLfloat* vertexRing2 = vertexRing1 + ringFloatOffset;
|
||||
float* vertexData = new float[verticesSize];
|
||||
float* vertexRing0 = vertexData;
|
||||
float* vertexRing1 = vertexRing0 + ringFloatOffset;
|
||||
float* vertexRing2 = vertexRing1 + ringFloatOffset;
|
||||
|
||||
for (int i = 0; i < slices; i++) {
|
||||
float theta = TWO_PI * i / slices;
|
||||
|
@ -746,7 +741,7 @@ model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
|
|||
*(index++) = capVertex;
|
||||
}
|
||||
|
||||
_spotLightMesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(sizeof(GLushort) * indices, (gpu::Byte*) indexData), gpu::Element::INDEX_UINT16));
|
||||
_spotLightMesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(sizeof(unsigned short) * indices, (gpu::Byte*) indexData), gpu::Element::INDEX_UINT16));
|
||||
delete[] indexData;
|
||||
|
||||
model::Mesh::Part part(0, indices, 0, model::Mesh::TRIANGLES);
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <QMap>
|
||||
#include <QQueue>
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/GPUConfig.h>
|
||||
#include "RenderUtilsLogging.h"
|
||||
|
||||
static QQueue<gpu::FramebufferPointer> _cachedFramebuffers;
|
||||
|
|
|
@ -9,22 +9,22 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// include this before QOpenGLBuffer, which includes an earlier version of OpenGL
|
||||
#include "GeometryCache.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/GLBackend.h>
|
||||
|
||||
#include <FSTReader.h>
|
||||
#include <NumericalConstants.h>
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/GLBackend.h>
|
||||
|
||||
#include "TextureCache.h"
|
||||
#include "RenderUtilsLogging.h"
|
||||
#include "GeometryCache.h"
|
||||
|
||||
#include "standardTransformPNTC_vert.h"
|
||||
#include "standardDrawTexture_frag.h"
|
||||
|
@ -1012,12 +1012,12 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 2; // vertices
|
||||
const int vertices = 4;
|
||||
const int VERTICES = 4; // 1 quad = 4 vertices
|
||||
|
||||
if (!details.isCreated) {
|
||||
|
||||
details.isCreated = true;
|
||||
details.vertices = vertices;
|
||||
details.vertices = VERTICES;
|
||||
details.vertexSize = FLOATS_PER_VERTEX;
|
||||
|
||||
auto verticesBuffer = std::make_shared<gpu::Buffer>();
|
||||
|
@ -1037,11 +1037,12 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
|
||||
|
||||
|
||||
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
|
||||
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
|
||||
minCorner.x, minCorner.y,
|
||||
maxCorner.x, minCorner.y,
|
||||
minCorner.x, maxCorner.y,
|
||||
maxCorner.x, maxCorner.y,
|
||||
minCorner.x, maxCorner.y };
|
||||
};
|
||||
|
||||
const int NUM_COLOR_SCALARS_PER_QUAD = 4;
|
||||
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
|
||||
|
@ -1050,14 +1051,13 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
((int(color.w * 255.0f) & 0xFF) << 24);
|
||||
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
}
|
||||
|
||||
batch.setInputFormat(details.streamFormat);
|
||||
batch.setInputStream(0, *details.stream);
|
||||
batch.draw(gpu::QUADS, 4, 0);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderUnitCube(gpu::Batch& batch) {
|
||||
|
@ -1102,23 +1102,25 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 2 * 2; // text coords & vertices
|
||||
const int vertices = 4;
|
||||
const int VERTICES = 4; // 1 quad = 4 vertices
|
||||
const int NUM_POS_COORDS = 2;
|
||||
const int VERTEX_TEXCOORD_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
|
||||
if (!details.isCreated) {
|
||||
|
||||
details.isCreated = true;
|
||||
details.vertices = vertices;
|
||||
details.vertices = VERTICES;
|
||||
details.vertexSize = FLOATS_PER_VERTEX;
|
||||
|
||||
auto verticesBuffer = std::make_shared<gpu::Buffer>();
|
||||
auto colorBuffer = std::make_shared<gpu::Buffer>();
|
||||
|
||||
auto streamFormat = std::make_shared<gpu::Stream::Format>();
|
||||
auto stream = std::make_shared<gpu::BufferStream>();
|
||||
|
||||
details.verticesBuffer = verticesBuffer;
|
||||
details.colorBuffer = colorBuffer;
|
||||
|
||||
details.streamFormat = streamFormat;
|
||||
details.stream = stream;
|
||||
|
||||
|
@ -1130,11 +1132,12 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
|
||||
|
||||
|
||||
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
|
||||
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
|
||||
minCorner.x, minCorner.y, texCoordMinCorner.x, texCoordMinCorner.y,
|
||||
maxCorner.x, minCorner.y, texCoordMaxCorner.x, texCoordMinCorner.y,
|
||||
minCorner.x, maxCorner.y, texCoordMinCorner.x, texCoordMaxCorner.y,
|
||||
maxCorner.x, maxCorner.y, texCoordMaxCorner.x, texCoordMaxCorner.y,
|
||||
minCorner.x, maxCorner.y, texCoordMinCorner.x, texCoordMaxCorner.y };
|
||||
};
|
||||
|
||||
|
||||
const int NUM_COLOR_SCALARS_PER_QUAD = 4;
|
||||
|
@ -1144,14 +1147,13 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
((int(color.w * 255.0f) & 0xFF) << 24);
|
||||
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
}
|
||||
|
||||
batch.setInputFormat(details.streamFormat);
|
||||
batch.setInputStream(0, *details.stream);
|
||||
batch.draw(gpu::QUADS, 4, 0);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id) {
|
||||
|
@ -1177,21 +1179,23 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
|
|||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 3; // vertices
|
||||
const int vertices = 4;
|
||||
const int VERTICES = 4; // 1 quad = 4 vertices
|
||||
|
||||
if (!details.isCreated) {
|
||||
|
||||
details.isCreated = true;
|
||||
details.vertices = vertices;
|
||||
details.vertices = VERTICES;
|
||||
details.vertexSize = FLOATS_PER_VERTEX;
|
||||
|
||||
auto verticesBuffer = std::make_shared<gpu::Buffer>();
|
||||
auto colorBuffer = std::make_shared<gpu::Buffer>();
|
||||
|
||||
auto streamFormat = std::make_shared<gpu::Stream::Format>();
|
||||
auto stream = std::make_shared<gpu::BufferStream>();
|
||||
|
||||
details.verticesBuffer = verticesBuffer;
|
||||
details.colorBuffer = colorBuffer;
|
||||
|
||||
details.streamFormat = streamFormat;
|
||||
details.stream = stream;
|
||||
|
||||
|
@ -1202,11 +1206,12 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
|
|||
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
|
||||
|
||||
|
||||
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
|
||||
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
|
||||
minCorner.x, minCorner.y, minCorner.z,
|
||||
maxCorner.x, minCorner.y, minCorner.z,
|
||||
minCorner.x, maxCorner.y, maxCorner.z,
|
||||
maxCorner.x, maxCorner.y, maxCorner.z,
|
||||
minCorner.x, maxCorner.y, maxCorner.z };
|
||||
};
|
||||
|
||||
const int NUM_COLOR_SCALARS_PER_QUAD = 4;
|
||||
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
|
||||
|
@ -1215,14 +1220,13 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
|
|||
((int(color.w * 255.0f) & 0xFF) << 24);
|
||||
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
}
|
||||
|
||||
batch.setInputFormat(details.streamFormat);
|
||||
batch.setInputStream(0, *details.stream);
|
||||
batch.draw(gpu::QUADS, 4, 0);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, const glm::vec3& bottomLeft,
|
||||
|
@ -1267,14 +1271,14 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
|
|||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 3 + 2; // 3d vertices + text coords
|
||||
const int vertices = 4;
|
||||
const int VERTICES = 4; // 1 quad = 4 vertices
|
||||
const int NUM_POS_COORDS = 3;
|
||||
const int VERTEX_TEXCOORD_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
|
||||
if (!details.isCreated) {
|
||||
|
||||
details.isCreated = true;
|
||||
details.vertices = vertices;
|
||||
details.vertices = VERTICES;
|
||||
details.vertexSize = FLOATS_PER_VERTEX; // NOTE: this isn't used for BatchItemDetails maybe we can get rid of it
|
||||
|
||||
auto verticesBuffer = std::make_shared<gpu::Buffer>();
|
||||
|
@ -1295,10 +1299,10 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
|
|||
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
|
||||
|
||||
|
||||
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
|
||||
topLeft.x, topLeft.y, topLeft.z, texCoordTopLeft.x, texCoordTopLeft.y,
|
||||
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
|
||||
bottomLeft.x, bottomLeft.y, bottomLeft.z, texCoordBottomLeft.x, texCoordBottomLeft.y,
|
||||
bottomRight.x, bottomRight.y, bottomRight.z, texCoordBottomRight.x, texCoordBottomRight.y,
|
||||
topLeft.x, topLeft.y, topLeft.z, texCoordTopLeft.x, texCoordTopLeft.y,
|
||||
topRight.x, topRight.y, topRight.z, texCoordTopRight.x, texCoordTopRight.y,
|
||||
};
|
||||
|
||||
|
@ -1315,7 +1319,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
|
|||
|
||||
batch.setInputFormat(details.streamFormat);
|
||||
batch.setInputStream(0, *details.stream);
|
||||
batch.draw(gpu::QUADS, 4, 0);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id) {
|
||||
|
@ -1998,7 +2002,7 @@ void GeometryReader::run() {
|
|||
} else if (_url.path().toLower().endsWith("palaceoforinthilian4.fbx")) {
|
||||
lightmapLevel = 3.5f;
|
||||
}
|
||||
fbxgeo = readFBX(_reply, _mapping, grabLightmaps, lightmapLevel);
|
||||
fbxgeo = readFBX(_reply, _mapping, _url.path(), grabLightmaps, lightmapLevel);
|
||||
} else if (_url.path().toLower().endsWith(".obj")) {
|
||||
fbxgeo = OBJReader().readOBJ(_reply, _mapping, &_url);
|
||||
}
|
||||
|
|
|
@ -18,20 +18,18 @@
|
|||
|
||||
#include <CapsuleShape.h>
|
||||
#include <GeometryUtil.h>
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/GLBackend.h>
|
||||
#include <PathUtils.h>
|
||||
#include <PerfStat.h>
|
||||
#include "PhysicsEntity.h"
|
||||
#include <ShapeCollider.h>
|
||||
#include <SphereShape.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <render/Scene.h>
|
||||
#include <gpu/Batch.h>
|
||||
|
||||
#include "AbstractViewStateInterface.h"
|
||||
#include "AnimationHandle.h"
|
||||
#include "DeferredLightingEffect.h"
|
||||
#include "Model.h"
|
||||
#include "RenderUtilsLogging.h"
|
||||
|
||||
#include "model_vert.h"
|
||||
#include "model_shadow_vert.h"
|
||||
|
@ -96,7 +94,7 @@ Model::~Model() {
|
|||
}
|
||||
|
||||
Model::RenderPipelineLib Model::_renderPipelineLib;
|
||||
const GLint MATERIAL_GPU_SLOT = 3;
|
||||
const int MATERIAL_GPU_SLOT = 3;
|
||||
|
||||
void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
||||
gpu::ShaderPointer& vertexShader,
|
||||
|
@ -189,13 +187,9 @@ void Model::RenderPipelineLib::initLocations(gpu::ShaderPointer& program, Model:
|
|||
locations.specularTextureUnit = program->getTextures().findLocation("specularMap");
|
||||
locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap");
|
||||
|
||||
#if (GPU_FEATURE_PROFILE == GPU_CORE)
|
||||
locations.materialBufferUnit = program->getBuffers().findLocation("materialBuffer");
|
||||
locations.lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
|
||||
#else
|
||||
locations.materialBufferUnit = program->getUniforms().findLocation("materialBuffer");
|
||||
locations.lightBufferUnit = program->getUniforms().findLocation("lightBuffer");
|
||||
#endif
|
||||
|
||||
locations.clusterMatrices = program->getUniforms().findLocation("clusterMatrices");
|
||||
|
||||
locations.clusterIndices = program->getInputs().findLocation("clusterIndices");;
|
||||
|
@ -2102,8 +2096,11 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
|
|||
}
|
||||
|
||||
if (part.quadIndices.size() > 0) {
|
||||
batch.drawIndexed(gpu::QUADS, part.quadIndices.size(), offset);
|
||||
batch.setIndexBuffer(gpu::UINT32, part.getTrianglesForQuads(), 0);
|
||||
batch.drawIndexed(gpu::TRIANGLES, part.trianglesForQuadsIndicesCount, 0);
|
||||
|
||||
offset += part.quadIndices.size() * sizeof(int);
|
||||
batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); // restore this in case there are triangles too
|
||||
}
|
||||
|
||||
if (part.triangleIndices.size() > 0) {
|
||||
|
|
|
@ -11,12 +11,10 @@
|
|||
//
|
||||
#include "RenderDeferredTask.h"
|
||||
|
||||
#include <gpu/GPUConfig.h>
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/Context.h>
|
||||
#include <PerfStat.h>
|
||||
#include <RenderArgs.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
#include "FramebufferCache.h"
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
@ -113,9 +111,6 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
_drawHitEffectJobIndex = _jobs.size() -1;
|
||||
|
||||
|
||||
_jobs.push_back(Job(new ResetGLState::JobModel()));
|
||||
|
||||
|
||||
// Give ourselves 3 frmaes of timer queries
|
||||
_timerQueries.push_back(std::make_shared<gpu::Query>());
|
||||
_timerQueries.push_back(std::make_shared<gpu::Query>());
|
||||
|
|
|
@ -16,16 +16,15 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/random.hpp>
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/GLBackend.h>
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QPainter>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
#include <qimagereader.h>
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
|
||||
|
||||
|
||||
#include "RenderUtilsLogging.h"
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
// Based on NVidia HBAO implementation in D3D11
|
||||
// http://www.nvidia.co.uk/object/siggraph-2008-HBAO.html
|
||||
|
||||
varying vec2 varTexcoord;
|
||||
|
||||
uniform sampler2D depthTexture;
|
||||
|
@ -30,80 +33,213 @@ uniform float g_intensity;
|
|||
uniform float bufferWidth;
|
||||
uniform float bufferHeight;
|
||||
|
||||
#define SAMPLE_COUNT 4
|
||||
const float PI = 3.14159265;
|
||||
|
||||
float getRandom(vec2 uv) {
|
||||
const vec2 FocalLen = vec2(1.0, 1.0);
|
||||
|
||||
const vec2 LinMAD = vec2(0.1-10.0, 0.1+10.0) / (2.0*0.1*10.0);
|
||||
|
||||
const vec2 AORes = vec2(1024.0, 768.0);
|
||||
const vec2 InvAORes = vec2(1.0/1024.0, 1.0/768.0);
|
||||
const vec2 NoiseScale = vec2(1024.0, 768.0) / 4.0;
|
||||
|
||||
const float AOStrength = 1.9;
|
||||
const float R = 0.3;
|
||||
const float R2 = 0.3*0.3;
|
||||
const float NegInvR2 = - 1.0 / (0.3*0.3);
|
||||
const float TanBias = tan(30.0 * PI / 180.0);
|
||||
const float MaxRadiusPixels = 50.0;
|
||||
|
||||
const int NumDirections = 6;
|
||||
const int NumSamples = 4;
|
||||
|
||||
float ViewSpaceZFromDepth(float d){
|
||||
// [0,1] -> [-1,1] clip space
|
||||
d = d * 2.0 - 1.0;
|
||||
|
||||
// Get view space Z
|
||||
return -1.0 / (LinMAD.x * d + LinMAD.y);
|
||||
}
|
||||
|
||||
vec3 UVToViewSpace(vec2 uv, float z){
|
||||
//uv = UVToViewA * uv + UVToViewB;
|
||||
return vec3(uv * z, z);
|
||||
}
|
||||
|
||||
vec3 GetViewPos(vec2 uv){
|
||||
float z = ViewSpaceZFromDepth(texture2D(depthTexture, uv).r);
|
||||
return UVToViewSpace(uv, z);
|
||||
}
|
||||
|
||||
vec3 GetViewPosPoint(ivec2 uv){
|
||||
vec2 coord = vec2(gl_FragCoord.xy) + uv;
|
||||
//float z = texelFetch(texture0, coord, 0).r;
|
||||
float z = texture2D(depthTexture, uv).r;
|
||||
return UVToViewSpace(uv, z);
|
||||
}
|
||||
|
||||
float TanToSin(float x){
|
||||
return x * inversesqrt(x*x + 1.0);
|
||||
}
|
||||
|
||||
float InvLength(vec2 V){
|
||||
return inversesqrt(dot(V,V));
|
||||
}
|
||||
|
||||
float Tangent(vec3 V){
|
||||
return V.z * InvLength(V.xy);
|
||||
}
|
||||
|
||||
float BiasedTangent(vec3 V){
|
||||
return V.z * InvLength(V.xy) + TanBias;
|
||||
}
|
||||
|
||||
float Tangent(vec3 P, vec3 S){
|
||||
return -(P.z - S.z) * InvLength(S.xy - P.xy);
|
||||
}
|
||||
|
||||
float Length2(vec3 V){
|
||||
return dot(V,V);
|
||||
}
|
||||
|
||||
vec3 MinDiff(vec3 P, vec3 Pr, vec3 Pl){
|
||||
vec3 V1 = Pr - P;
|
||||
vec3 V2 = P - Pl;
|
||||
return (Length2(V1) < Length2(V2)) ? V1 : V2;
|
||||
}
|
||||
|
||||
vec2 SnapUVOffset(vec2 uv){
|
||||
return round(uv * AORes) * InvAORes;
|
||||
}
|
||||
|
||||
float Falloff(float d2){
|
||||
return d2 * NegInvR2 + 1.0f;
|
||||
}
|
||||
|
||||
float HorizonOcclusion( vec2 deltaUV, vec3 P, vec3 dPdu, vec3 dPdv, float randstep, float numSamples){
|
||||
float ao = 0;
|
||||
|
||||
// Offset the first coord with some noise
|
||||
vec2 uv = varTexcoord + SnapUVOffset(randstep*deltaUV);
|
||||
deltaUV = SnapUVOffset( deltaUV );
|
||||
|
||||
// Calculate the tangent vector
|
||||
vec3 T = deltaUV.x * dPdu + deltaUV.y * dPdv;
|
||||
|
||||
// Get the angle of the tangent vector from the viewspace axis
|
||||
float tanH = BiasedTangent(T);
|
||||
float sinH = TanToSin(tanH);
|
||||
|
||||
float tanS;
|
||||
float d2;
|
||||
vec3 S;
|
||||
|
||||
// Sample to find the maximum angle
|
||||
for(float s = 1; s <= numSamples; ++s){
|
||||
uv += deltaUV;
|
||||
S = GetViewPos(uv);
|
||||
tanS = Tangent(P, S);
|
||||
d2 = Length2(S - P);
|
||||
|
||||
// Is the sample within the radius and the angle greater?
|
||||
if(d2 < R2 && tanS > tanH)
|
||||
{
|
||||
float sinS = TanToSin(tanS);
|
||||
// Apply falloff based on the distance
|
||||
ao += Falloff(d2) * (sinS - sinH);
|
||||
|
||||
tanH = tanS;
|
||||
sinH = sinS;
|
||||
}
|
||||
}
|
||||
return ao;
|
||||
}
|
||||
|
||||
vec2 RotateDirections(vec2 Dir, vec2 CosSin){
|
||||
return vec2(Dir.x*CosSin.x - Dir.y*CosSin.y, Dir.x*CosSin.y + Dir.y*CosSin.x);
|
||||
}
|
||||
|
||||
void ComputeSteps(inout vec2 stepSizeUv, inout float numSteps, float rayRadiusPix, float rand){
|
||||
// Avoid oversampling if numSteps is greater than the kernel radius in pixels
|
||||
numSteps = min(NumSamples, rayRadiusPix);
|
||||
|
||||
// Divide by Ns+1 so that the farthest samples are not fully attenuated
|
||||
float stepSizePix = rayRadiusPix / (numSteps + 1);
|
||||
|
||||
// Clamp numSteps if it is greater than the max kernel footprint
|
||||
float maxNumSteps = MaxRadiusPixels / stepSizePix;
|
||||
if (maxNumSteps < numSteps)
|
||||
{
|
||||
// Use dithering to avoid AO discontinuities
|
||||
numSteps = floor(maxNumSteps + rand);
|
||||
numSteps = max(numSteps, 1);
|
||||
stepSizePix = MaxRadiusPixels / numSteps;
|
||||
}
|
||||
|
||||
// Step size in uv space
|
||||
stepSizeUv = stepSizePix * InvAORes;
|
||||
}
|
||||
|
||||
float getRandom(vec2 uv){
|
||||
return fract(sin(dot(uv.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec3 sampleKernel[4] = { vec3(0.2, 0.0, 0.0),
|
||||
vec3(0.0, 0.2, 0.0),
|
||||
vec3(0.0, 0.0, 0.2),
|
||||
vec3(0.2, 0.2, 0.2) };
|
||||
void main(void){
|
||||
float numDirections = NumDirections;
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
vec3 P, Pr, Pl, Pt, Pb;
|
||||
P = GetViewPos(varTexcoord);
|
||||
|
||||
vec3 eyeDir = vec3(0.0, 0.0, -3.0);
|
||||
vec3 cameraPositionWorldSpace;
|
||||
<$transformEyeToWorldDir(cam, eyeDir, cameraPositionWorldSpace)$>
|
||||
// Sample neighboring pixels
|
||||
Pr = GetViewPos(varTexcoord + vec2( InvAORes.x, 0));
|
||||
Pl = GetViewPos(varTexcoord + vec2(-InvAORes.x, 0));
|
||||
Pt = GetViewPos(varTexcoord + vec2( 0, InvAORes.y));
|
||||
Pb = GetViewPos(varTexcoord + vec2( 0,-InvAORes.y));
|
||||
|
||||
vec4 depthColor = texture2D(depthTexture, varTexcoord);
|
||||
// Calculate tangent basis vectors using the minimum difference
|
||||
vec3 dPdu = MinDiff(P, Pr, Pl);
|
||||
vec3 dPdv = MinDiff(P, Pt, Pb) * (AORes.y * InvAORes.x);
|
||||
|
||||
// z in non linear range [0,1]
|
||||
float depthVal = depthColor.r;
|
||||
// conversion into NDC [-1,1]
|
||||
float zNDC = depthVal * 2.0 - 1.0;
|
||||
float n = 1.0; // the near plane
|
||||
float f = 30.0; // the far plane
|
||||
float l = -1.0; // left
|
||||
float r = 1.0; // right
|
||||
float b = -1.0; // bottom
|
||||
float t = 1.0; // top
|
||||
|
||||
// conversion into eye space
|
||||
float zEye = 2*f*n / (zNDC*(f-n)-(f+n));
|
||||
// Converting from pixel coordinates to NDC
|
||||
float xNDC = gl_FragCoord.x/bufferWidth * 2.0 - 1.0;
|
||||
float yNDC = gl_FragCoord.y/bufferHeight * 2.0 - 1.0;
|
||||
// Unprojecting X and Y from NDC to eye space
|
||||
float xEye = -zEye*(xNDC*(r-l)+(r+l))/(2.0*n);
|
||||
float yEye = -zEye*(yNDC*(t-b)+(t+b))/(2.0*n);
|
||||
vec3 currentFragEyeSpace = vec3(xEye, yEye, zEye);
|
||||
vec3 currentFragWorldSpace;
|
||||
<$transformEyeToWorldDir(cam, currentFragEyeSpace, currentFragWorldSpace)$>
|
||||
|
||||
vec3 cameraToPositionRay = normalize(currentFragWorldSpace - cameraPositionWorldSpace);
|
||||
vec3 origin = cameraToPositionRay * depthVal + cameraPositionWorldSpace;
|
||||
|
||||
vec3 normal = normalize(texture2D(normalTexture, varTexcoord).xyz);
|
||||
//normal = normalize(normal * normalMatrix);
|
||||
|
||||
vec3 rvec = vec3(getRandom(varTexcoord.xy), getRandom(varTexcoord.yx), getRandom(varTexcoord.xx)) * 2.0 - 1.0;
|
||||
vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
|
||||
vec3 bitangent = cross(normal, tangent);
|
||||
mat3 tbn = mat3(tangent, bitangent, normal);
|
||||
|
||||
float occlusion = 0.0;
|
||||
|
||||
for (int i = 0; i < SAMPLE_COUNT; ++i) {
|
||||
vec3 samplePos = origin + (tbn * sampleKernel[i]) * g_sample_rad;
|
||||
vec4 offset = cam._projectionViewUntranslated * vec4(samplePos, 1.0);
|
||||
|
||||
offset.xy = (offset.xy / offset.w) * 0.5 + 0.5;
|
||||
float depth = length(samplePos - cameraPositionWorldSpace);
|
||||
|
||||
float sampleDepthVal = texture2D(depthTexture, offset.xy).r;
|
||||
|
||||
float rangeDelta = abs(depthVal - sampleDepthVal);
|
||||
float rangeCheck = smoothstep(0.0, 1.0, g_sample_rad / rangeDelta);
|
||||
|
||||
occlusion += rangeCheck * step(sampleDepthVal, depth);
|
||||
}
|
||||
|
||||
occlusion = 1.0 - occlusion / float(SAMPLE_COUNT);
|
||||
occlusion = clamp(pow(occlusion, g_intensity), 0.0, 1.0);
|
||||
gl_FragColor = vec4(vec3(occlusion), 1.0);
|
||||
}
|
||||
// Get the random samples from the noise function
|
||||
vec3 random = vec3(getRandom(varTexcoord.xy), getRandom(varTexcoord.yx), getRandom(varTexcoord.xx));
|
||||
|
||||
// Calculate the projected size of the hemisphere
|
||||
vec2 rayRadiusUV = 0.5 * R * FocalLen / -P.z;
|
||||
float rayRadiusPix = rayRadiusUV.x * AORes.x;
|
||||
|
||||
float ao = 1.0;
|
||||
|
||||
// Make sure the radius of the evaluated hemisphere is more than a pixel
|
||||
if(rayRadiusPix > 1.0){
|
||||
ao = 0.0;
|
||||
float numSteps;
|
||||
vec2 stepSizeUV;
|
||||
|
||||
// Compute the number of steps
|
||||
ComputeSteps(stepSizeUV, numSteps, rayRadiusPix, random.z);
|
||||
|
||||
float alpha = 2.0 * PI / numDirections;
|
||||
|
||||
// Calculate the horizon occlusion of each direction
|
||||
for(float d = 0; d < numDirections; ++d){
|
||||
float theta = alpha * d;
|
||||
|
||||
// Apply noise to the direction
|
||||
vec2 dir = RotateDirections(vec2(cos(theta), sin(theta)), random.xy);
|
||||
vec2 deltaUV = dir * stepSizeUV;
|
||||
|
||||
// Sample the pixels along the direction
|
||||
ao += HorizonOcclusion( deltaUV,
|
||||
P,
|
||||
dPdu,
|
||||
dPdv,
|
||||
random.z,
|
||||
numSteps);
|
||||
}
|
||||
|
||||
// Average the results and produce the final AO
|
||||
ao = 1.0 - ao / numDirections * AOStrength;
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(vec3(ao), 1.0);
|
||||
}
|
|
@ -21,9 +21,6 @@ uniform sampler2D blurredOcclusionTexture;
|
|||
void main(void) {
|
||||
vec4 occlusionColor = texture2D(blurredOcclusionTexture, varTexcoord);
|
||||
|
||||
if(occlusionColor.r > 0.8 && occlusionColor.r <= 1.0) {
|
||||
gl_FragColor = vec4(vec3(0.0), 0.0);
|
||||
} else {
|
||||
gl_FragColor = vec4(vec3(occlusionColor.r), 1.0);
|
||||
}
|
||||
gl_FragColor = vec4(vec3(0.0), occlusionColor.r);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,12 @@ struct TextureVertex {
|
|||
TextureVertex(const glm::vec2& pos, const glm::vec2& tex) : pos(pos), tex(tex) {}
|
||||
};
|
||||
|
||||
static const int NUMBER_OF_INDICES_PER_QUAD = 6; // 1 quad = 2 triangles
|
||||
static const int VERTICES_PER_QUAD = 4; // 1 quad = 4 vertices
|
||||
|
||||
struct QuadBuilder {
|
||||
TextureVertex vertices[4];
|
||||
TextureVertex vertices[VERTICES_PER_QUAD];
|
||||
|
||||
QuadBuilder(const glm::vec2& min, const glm::vec2& size,
|
||||
const glm::vec2& texMin, const glm::vec2& texSize) {
|
||||
// min = bottomLeft
|
||||
|
@ -249,6 +253,9 @@ void Font::setupGPU() {
|
|||
void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2& bounds) {
|
||||
_verticesBuffer = std::make_shared<gpu::Buffer>();
|
||||
_numVertices = 0;
|
||||
_indicesBuffer = std::make_shared<gpu::Buffer>();
|
||||
_numIndices = 0;
|
||||
|
||||
_lastStringRendered = str;
|
||||
_lastBounds = bounds;
|
||||
|
||||
|
@ -284,10 +291,28 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2
|
|||
if (!isNewLine) {
|
||||
for (auto c : token) {
|
||||
auto glyph = _glyphs[c];
|
||||
quint16 verticesOffset = _numVertices;
|
||||
|
||||
QuadBuilder qd(glyph, advance - glm::vec2(0.0f, _ascent));
|
||||
_verticesBuffer->append(sizeof(QuadBuilder), (const gpu::Byte*)&qd);
|
||||
_numVertices += 4;
|
||||
|
||||
// Sam's recommended triangle slices
|
||||
// Triangle tri1 = { v0, v1, v3 };
|
||||
// Triangle tri2 = { v1, v2, v3 };
|
||||
// NOTE: Random guy on the internet's recommended triangle slices
|
||||
// Triangle tri1 = { v0, v1, v2 };
|
||||
// Triangle tri2 = { v2, v3, v0 };
|
||||
quint16 indices[NUMBER_OF_INDICES_PER_QUAD];
|
||||
indices[0] = verticesOffset + 0;
|
||||
indices[1] = verticesOffset + 1;
|
||||
indices[2] = verticesOffset + 3;
|
||||
indices[3] = verticesOffset + 1;
|
||||
indices[4] = verticesOffset + 2;
|
||||
indices[5] = verticesOffset + 3;
|
||||
_indicesBuffer->append(sizeof(indices), (const gpu::Byte*)indices);
|
||||
_numIndices += NUMBER_OF_INDICES_PER_QUAD;
|
||||
|
||||
|
||||
// Advance by glyph size
|
||||
advance.x += glyph.d;
|
||||
|
@ -318,5 +343,6 @@ void Font::drawString(gpu::Batch& batch, float x, float y, const QString& str, c
|
|||
|
||||
batch.setInputFormat(_format);
|
||||
batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
||||
batch.draw(gpu::QUADS, _numVertices, 0);
|
||||
batch.setIndexBuffer(gpu::UINT16, _indicesBuffer, 0);
|
||||
batch.drawIndexed(gpu::TRIANGLES, _numIndices, 0);
|
||||
}
|
||||
|
|
|
@ -64,8 +64,10 @@ private:
|
|||
gpu::TexturePointer _texture;
|
||||
gpu::Stream::FormatPointer _format;
|
||||
gpu::BufferPointer _verticesBuffer;
|
||||
gpu::BufferPointer _indicesBuffer;
|
||||
gpu::BufferStreamPointer _stream;
|
||||
unsigned int _numVertices = 0;
|
||||
unsigned int _numIndices = 0;
|
||||
|
||||
int _fontLoc = -1;
|
||||
int _outlineLoc = -1;
|
||||
|
|
|
@ -15,15 +15,11 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/Context.h>
|
||||
#include <gpu/GPUConfig.h>
|
||||
#include <gpu/GPULogging.h>
|
||||
|
||||
#include <ViewFrustum.h>
|
||||
#include <RenderArgs.h>
|
||||
|
||||
#include <gpu/Context.h>
|
||||
|
||||
#include "drawItemBounds_vert.h"
|
||||
#include "drawItemBounds_frag.h"
|
||||
#include "drawItemStatus_vert.h"
|
||||
|
@ -152,17 +148,17 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex
|
|||
const unsigned int VEC3_ADRESS_OFFSET = 3;
|
||||
|
||||
for (int i = 0; i < nbItems; i++) {
|
||||
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const GLfloat*) (itemAABox + i));
|
||||
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
||||
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i));
|
||||
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
||||
|
||||
batch.draw(gpu::LINES, 24, 0);
|
||||
}
|
||||
|
||||
batch.setPipeline(getDrawItemStatusPipeline());
|
||||
for (int i = 0; i < nbItems; i++) {
|
||||
batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const GLfloat*) (itemAABox + i));
|
||||
batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
||||
batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const GLint*) (itemStatus + i));
|
||||
batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i));
|
||||
batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
||||
batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const int*) (itemStatus + i));
|
||||
|
||||
batch.draw(gpu::TRIANGLES, 24, 0);
|
||||
}
|
||||
|
@ -171,4 +167,4 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex
|
|||
args->_context->syncCache();
|
||||
renderContext->args->_context->syncCache();
|
||||
args->_context->render((batch));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,10 @@
|
|||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/Context.h>
|
||||
#include <gpu/GPUConfig.h>
|
||||
#include <PerfStat.h>
|
||||
#include <RenderArgs.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
using namespace render;
|
||||
|
||||
|
@ -216,46 +214,6 @@ void render::renderItems(const SceneContextPointer& sceneContext, const RenderCo
|
|||
}
|
||||
}
|
||||
|
||||
void addClearStateCommands(gpu::Batch& batch) {
|
||||
batch._glDepthMask(true);
|
||||
batch._glDepthFunc(GL_LESS);
|
||||
batch._glDisable(GL_CULL_FACE);
|
||||
|
||||
batch._glActiveTexture(GL_TEXTURE0 + 1);
|
||||
batch._glBindTexture(GL_TEXTURE_2D, 0);
|
||||
batch._glActiveTexture(GL_TEXTURE0 + 2);
|
||||
batch._glBindTexture(GL_TEXTURE_2D, 0);
|
||||
batch._glActiveTexture(GL_TEXTURE0 + 3);
|
||||
batch._glBindTexture(GL_TEXTURE_2D, 0);
|
||||
batch._glActiveTexture(GL_TEXTURE0);
|
||||
batch._glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
|
||||
// deactivate vertex arrays after drawing
|
||||
batch._glDisableClientState(GL_NORMAL_ARRAY);
|
||||
batch._glDisableClientState(GL_VERTEX_ARRAY);
|
||||
batch._glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
batch._glDisableClientState(GL_COLOR_ARRAY);
|
||||
batch._glDisableVertexAttribArray(gpu::Stream::TANGENT);
|
||||
batch._glDisableVertexAttribArray(gpu::Stream::SKIN_CLUSTER_INDEX);
|
||||
batch._glDisableVertexAttribArray(gpu::Stream::SKIN_CLUSTER_WEIGHT);
|
||||
|
||||
// bind with 0 to switch back to normal operation
|
||||
batch._glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
batch._glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
batch._glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Back to no program
|
||||
batch._glUseProgram(0);
|
||||
}
|
||||
void ResetGLState::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
|
||||
gpu::Batch theBatch;
|
||||
addClearStateCommands(theBatch);
|
||||
assert(renderContext->args);
|
||||
renderContext->args->_context->render(theBatch);
|
||||
}
|
||||
|
||||
void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
|
|
|
@ -260,14 +260,6 @@ public:
|
|||
typedef Job::Model<DrawBackground> JobModel;
|
||||
};
|
||||
|
||||
class ResetGLState {
|
||||
public:
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
|
||||
|
||||
typedef Job::Model<ResetGLState> JobModel;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DrawSceneTask : public Task {
|
||||
public:
|
||||
|
|
|
@ -8,30 +8,35 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include <QWindow>
|
||||
#include <QFile>
|
||||
#include <QTime>
|
||||
#include <QImage>
|
||||
#include <QTimer>
|
||||
#include <QElapsedTimer>
|
||||
#include <QOpenGLContext>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QResizeEvent>
|
||||
#include <QLoggingCategory>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QApplication>
|
||||
#include <QOpenGLDebugLogger>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QElapsedTimer>
|
||||
#include <QFile>
|
||||
#include <QImage>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include <gpu/Context.h>
|
||||
#include <gpu/GLBackend.h>
|
||||
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLContext>
|
||||
#include <QOpenGLDebugLogger>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QResizeEvent>
|
||||
#include <QTime>
|
||||
#include <QTimer>
|
||||
#include <QWindow>
|
||||
|
||||
|
||||
|
||||
#include <PathUtils.h>
|
||||
|
||||
class RateCounter {
|
||||
std::vector<float> times;
|
||||
|
@ -119,6 +124,10 @@ public:
|
|||
show();
|
||||
makeCurrent();
|
||||
|
||||
gpu::Context::init<gpu::GLBackend>();
|
||||
|
||||
|
||||
|
||||
{
|
||||
QOpenGLDebugLogger* logger = new QOpenGLDebugLogger(this);
|
||||
logger->initialize(); // initializes in the current context, i.e. ctx
|
||||
|
@ -130,23 +139,6 @@ public:
|
|||
}
|
||||
qDebug() << (const char*)glGetString(GL_VERSION);
|
||||
|
||||
#ifdef WIN32
|
||||
glewExperimental = true;
|
||||
GLenum err = glewInit();
|
||||
if (GLEW_OK != err) {
|
||||
/* Problem: glewInit failed, something is seriously wrong. */
|
||||
const GLubyte * errStr = glewGetErrorString(err);
|
||||
qDebug("Error: %s\n", errStr);
|
||||
}
|
||||
qDebug("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
|
||||
|
||||
if (wglewGetExtension("WGL_EXT_swap_control")) {
|
||||
int swapInterval = wglGetSwapIntervalEXT();
|
||||
qDebug("V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF"));
|
||||
}
|
||||
glGetError();
|
||||
#endif
|
||||
|
||||
//_textRenderer[0] = TextRenderer::getInstance(SANS_FONT_FAMILY, 12, false);
|
||||
//_textRenderer[1] = TextRenderer::getInstance(SERIF_FONT_FAMILY, 12, false,
|
||||
// TextRenderer::SHADOW_EFFECT);
|
||||
|
|
|
@ -38,7 +38,7 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, FBXGeometry& result) {
|
|||
if (filename.toLower().endsWith(".obj")) {
|
||||
result = OBJReader().readOBJ(fbxContents, QVariantHash());
|
||||
} else if (filename.toLower().endsWith(".fbx")) {
|
||||
result = readFBX(fbxContents, QVariantHash());
|
||||
result = readFBX(fbxContents, QVariantHash(), filename);
|
||||
} else {
|
||||
qDebug() << "unknown file extension";
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue