1698 lines · 70.2 KB · C++
RawDownload
 void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, const glm::vec3& bottomLeft,                     const glm::vec3& bottomRight, const glm::vec3& topRight,                    const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft,                    const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight,                     const glm::vec4& color, int id) {     #ifdef WANT_DEBUG        qCDebug(renderutils) << "renderQuad() vec3 + texture VBO...";        qCDebug(renderutils) << "    topLeft:" << topLeft;        qCDebug(renderutils) << "    bottomLeft:" << bottomLeft;        qCDebug(renderutils) << "    bottomRight:" << bottomRight;        qCDebug(renderutils) << "    topRight:" << topRight;        qCDebug(renderutils) << "    texCoordTopLeft:" << texCoordTopLeft;        qCDebug(renderutils) << "    texCoordBottomRight:" << texCoordBottomRight;        qCDebug(renderutils) << "    color:" << color;    #endif //def WANT_DEBUG        bool registered = (id != UNKNOWN_ID);    Vec3PairVec4Pair key(Vec3Pair(topLeft, bottomRight),                            Vec4Pair(glm::vec4(texCoordTopLeft.x,texCoordTopLeft.y,texCoordBottomRight.x,texCoordBottomRight.y),                                    color));                                        BatchItemDetails& details = registered ? _registeredQuad3DTextures[id] : _quad3DTextures[key];     // if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed    if (registered && details.isCreated) {        Vec3PairVec4Pair& lastKey = _lastRegisteredQuad3DTexture[id];        if (lastKey != key) {            details.clear();            _lastRegisteredQuad3DTexture[id] = key;            #ifdef WANT_DEBUG                qCDebug(renderutils) << "renderQuad() 3D+texture ... RELEASING REGISTERED";            #endif // def WANT_DEBUG        }        #ifdef WANT_DEBUG        else {            qCDebug(renderutils) << "renderQuad() 3D+texture ... REUSING PREVIOUSLY REGISTERED";        }        #endif // def WANT_DEBUG    }     const int FLOATS_PER_VERTEX = 3 + 3 + 2; // vertices + normals + tex coords    const int VERTICES = 4; // 1 quad = 4 vertices    const int NUM_POS_COORDS = 3;    const int NUM_NORMAL_COORDS = 3;    const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);    const int VERTEX_TEXCOORD_OFFSET = VERTEX_NORMAL_OFFSET + NUM_NORMAL_COORDS * sizeof(float);      if (!details.isCreated) {         details.isCreated = true;        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>();        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;            details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);        details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);        details.streamFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), VERTEX_TEXCOORD_OFFSET);        details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));         details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);        details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);          const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f);        float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {            bottomLeft.x, bottomLeft.y, bottomLeft.z, NORMAL.x, NORMAL.y, NORMAL.z, texCoordBottomLeft.x, texCoordBottomLeft.y,            bottomRight.x, bottomRight.y, bottomRight.z, NORMAL.x, NORMAL.y, NORMAL.z, texCoordBottomRight.x, texCoordBottomRight.y,            topLeft.x, topLeft.y, topLeft.z, NORMAL.x, NORMAL.y, NORMAL.z, texCoordTopLeft.x, texCoordTopLeft.y,            topRight.x, topRight.y, topRight.z, NORMAL.x, NORMAL.y, NORMAL.z, texCoordTopRight.x, texCoordTopRight.y,        };         const int NUM_COLOR_SCALARS_PER_QUAD = 4;        int compactColor = ((int(color.x * 255.0f) & 0xFF)) |                            ((int(color.y * 255.0f) & 0xFF) << 8) |                            ((int(color.z * 255.0f) & 0xFF) << 16) |                            ((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::TRIANGLE_STRIP, 4, 0);} void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color,                                     const float dash_length, const float gap_length, int id) {     bool registered = (id != UNKNOWN_ID);    Vec3PairVec2Pair key(Vec3Pair(start, end), Vec2Pair(glm::vec2(color.x, color.y), glm::vec2(color.z, color.w)));    BatchItemDetails& details = registered ? _registeredDashedLines[id] : _dashedLines[key];     // if this is a registered , and we have buffers, then check to see if the geometry changed and rebuild if needed    if (registered && details.isCreated) {        if (_lastRegisteredDashedLines[id] != key) {            details.clear();            _lastRegisteredDashedLines[id] = key;            #ifdef WANT_DEBUG                qCDebug(renderutils) << "renderDashedLine()... RELEASING REGISTERED";            #endif // def WANT_DEBUG        }    }     if (!details.isCreated) {         int compactColor = ((int(color.x * 255.0f) & 0xFF)) |                           ((int(color.y * 255.0f) & 0xFF) << 8) |                           ((int(color.z * 255.0f) & 0xFF) << 16) |                           ((int(color.w * 255.0f) & 0xFF) << 24);         // draw each line segment with appropriate gaps        const float SEGMENT_LENGTH = dash_length + gap_length;        float length = glm::distance(start, end);        float segmentCount = length / SEGMENT_LENGTH;        int segmentCountFloor = (int)glm::floor(segmentCount);         glm::vec3 segmentVector = (end - start) / segmentCount;        glm::vec3 dashVector = segmentVector / SEGMENT_LENGTH * dash_length;        glm::vec3 gapVector = segmentVector / SEGMENT_LENGTH * gap_length;         const int FLOATS_PER_VERTEX = 3 + 3; // vertices + normals        const int NUM_POS_COORDS = 3;        const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);        details.vertices = (segmentCountFloor + 1) * 2;        details.vertexSize = FLOATS_PER_VERTEX;        details.isCreated = true;                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;         details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);        details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);        details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));         details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);        details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);         int* colorData = new int[details.vertices];        int* colorDataAt = colorData;         float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX];        float* vertex = vertexData;         const glm::vec3 NORMAL(1.0f, 0.0f, 0.0f);        glm::vec3 point = start;        *(vertex++) = point.x;        *(vertex++) = point.y;        *(vertex++) = point.z;        *(vertex++) = NORMAL.x;        *(vertex++) = NORMAL.y;        *(vertex++) = NORMAL.z;        *(colorDataAt++) = compactColor;         for (int i = 0; i < segmentCountFloor; i++) {            point += dashVector;            *(vertex++) = point.x;            *(vertex++) = point.y;            *(vertex++) = point.z;            *(vertex++) = NORMAL.x;            *(vertex++) = NORMAL.y;            *(vertex++) = NORMAL.z;            *(colorDataAt++) = compactColor;             point += gapVector;            *(vertex++) = point.x;            *(vertex++) = point.y;            *(vertex++) = point.z;            *(vertex++) = NORMAL.x;            *(vertex++) = NORMAL.y;            *(vertex++) = NORMAL.z;            *(colorDataAt++) = compactColor;        }        *(vertex++) = end.x;        *(vertex++) = end.y;        *(vertex++) = end.z;        *(vertex++) = NORMAL.x;        *(vertex++) = NORMAL.y;        *(vertex++) = NORMAL.z;        *(colorDataAt++) = compactColor;         details.verticesBuffer->append(sizeof(float) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData);        details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Byte*) colorData);        delete[] vertexData;        delete[] colorData;         #ifdef WANT_DEBUG        if (registered) {            qCDebug(renderutils) << "new registered dashed line buffer made -- _registeredVertices:" << _registeredDashedLines.size();        } else {            qCDebug(renderutils) << "new dashed lines buffer made -- _dashedLines:" << _dashedLines.size();        }        #endif    }     batch.setInputFormat(details.streamFormat);    batch.setInputStream(0, *details.stream);    batch.draw(gpu::LINES, details.vertices, 0);}  int GeometryCache::BatchItemDetails::population = 0; GeometryCache::BatchItemDetails::BatchItemDetails() :    verticesBuffer(NULL),    colorBuffer(NULL),    streamFormat(NULL),    stream(NULL),    vertices(0),    vertexSize(0),    isCreated(false){    population++;    #ifdef WANT_DEBUG        qCDebug(renderutils) << "BatchItemDetails()... population:" << population << "**********************************";    #endif} GeometryCache::BatchItemDetails::BatchItemDetails(const GeometryCache::BatchItemDetails& other) :    verticesBuffer(other.verticesBuffer),    colorBuffer(other.colorBuffer),    streamFormat(other.streamFormat),    stream(other.stream),    vertices(other.vertices),    vertexSize(other.vertexSize),    isCreated(other.isCreated){    population++;    #ifdef WANT_DEBUG        qCDebug(renderutils) << "BatchItemDetails()... population:" << population << "**********************************";    #endif} GeometryCache::BatchItemDetails::~BatchItemDetails() {    population--;    clear();     #ifdef WANT_DEBUG        qCDebug(renderutils) << "~BatchItemDetails()... population:" << population << "**********************************";    #endif} void GeometryCache::BatchItemDetails::clear() {    isCreated = false;    verticesBuffer.reset();    colorBuffer.reset();    streamFormat.reset();    stream.reset();} void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,                                const glm::vec4& color1, const glm::vec4& color2, int id) {                                   bool registered = (id != UNKNOWN_ID);    Vec3Pair key(p1, p2);     BatchItemDetails& details = registered ? _registeredLine3DVBOs[id] : _line3DVBOs[key];     int compactColor1 = ((int(color1.x * 255.0f) & 0xFF)) |                        ((int(color1.y * 255.0f) & 0xFF) << 8) |                        ((int(color1.z * 255.0f) & 0xFF) << 16) |                        ((int(color1.w * 255.0f) & 0xFF) << 24);     int compactColor2 = ((int(color2.x * 255.0f) & 0xFF)) |                        ((int(color2.y * 255.0f) & 0xFF) << 8) |                        ((int(color2.z * 255.0f) & 0xFF) << 16) |                        ((int(color2.w * 255.0f) & 0xFF) << 24);      // if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed    if (registered && details.isCreated) {        Vec3Pair& lastKey = _lastRegisteredLine3D[id];        if (lastKey != key) {            details.clear();            _lastRegisteredLine3D[id] = key;              #ifdef WANT_DEBUG                qCDebug(renderutils) << "renderLine() 3D ... RELEASING REGISTERED line";            #endif // def WANT_DEBUG        }        #ifdef WANT_DEBUG        else {            qCDebug(renderutils) << "renderLine() 3D ... REUSING PREVIOUSLY REGISTERED line";        }        #endif // def WANT_DEBUG    }     const int FLOATS_PER_VERTEX = 3 + 3; // vertices + normals    const int NUM_POS_COORDS = 3;    const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);    const int vertices = 2;    if (!details.isCreated) {         details.isCreated = true;        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;            details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);        details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);        details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));         details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);        details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);         const glm::vec3 NORMAL(1.0f, 0.0f, 0.0f);        float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {            p1.x, p1.y, p1.z, NORMAL.x, NORMAL.y, NORMAL.z,            p2.x, p2.y, p2.z, NORMAL.x, NORMAL.y, NORMAL.z};         const int NUM_COLOR_SCALARS = 2;        int colors[NUM_COLOR_SCALARS] = { compactColor1, compactColor2 };         details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);        details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);         #ifdef WANT_DEBUG            if (id == UNKNOWN_ID) {                qCDebug(renderutils) << "new renderLine() 3D VBO made -- _line3DVBOs.size():" << _line3DVBOs.size();            } else {                qCDebug(renderutils) << "new registered renderLine() 3D VBO made -- _registeredLine3DVBOs.size():" << _registeredLine3DVBOs.size();            }        #endif    }     // this is what it takes to render a quad    batch.setInputFormat(details.streamFormat);    batch.setInputStream(0, *details.stream);    batch.draw(gpu::LINES, 2, 0);} void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2,                                                                const glm::vec4& color1, const glm::vec4& color2, int id) {                                   bool registered = (id != UNKNOWN_ID);    Vec2Pair key(p1, p2);     BatchItemDetails& details = registered ? _registeredLine2DVBOs[id] : _line2DVBOs[key];     int compactColor1 = ((int(color1.x * 255.0f) & 0xFF)) |                        ((int(color1.y * 255.0f) & 0xFF) << 8) |                        ((int(color1.z * 255.0f) & 0xFF) << 16) |                        ((int(color1.w * 255.0f) & 0xFF) << 24);     int compactColor2 = ((int(color2.x * 255.0f) & 0xFF)) |                        ((int(color2.y * 255.0f) & 0xFF) << 8) |                        ((int(color2.z * 255.0f) & 0xFF) << 16) |                        ((int(color2.w * 255.0f) & 0xFF) << 24);      // if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed    if (registered && details.isCreated) {        Vec2Pair& lastKey = _lastRegisteredLine2D[id];        if (lastKey != key) {            details.clear();            _lastRegisteredLine2D[id] = key;            #ifdef WANT_DEBUG                qCDebug(renderutils) << "renderLine() 2D ... RELEASING REGISTERED line";            #endif // def WANT_DEBUG        }        #ifdef WANT_DEBUG        else {            qCDebug(renderutils) << "renderLine() 2D ... REUSING PREVIOUSLY REGISTERED line";        }        #endif // def WANT_DEBUG    }     const int FLOATS_PER_VERTEX = 2;    const int vertices = 2;    if (!details.isCreated) {         details.isCreated = true;        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;            details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);        details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));         details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);        details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);          float vertexBuffer[vertices * FLOATS_PER_VERTEX] = { p1.x, p1.y, p2.x, p2.y };         const int NUM_COLOR_SCALARS = 2;        int colors[NUM_COLOR_SCALARS] = { compactColor1, compactColor2 };         details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);        details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);         #ifdef WANT_DEBUG            if (id == UNKNOWN_ID) {                qCDebug(renderutils) << "new renderLine() 2D VBO made -- _line3DVBOs.size():" << _line2DVBOs.size();            } else {                qCDebug(renderutils) << "new registered renderLine() 2D VBO made -- _registeredLine2DVBOs.size():" << _registeredLine2DVBOs.size();            }        #endif    }     // this is what it takes to render a quad    batch.setInputFormat(details.streamFormat);    batch.setInputStream(0, *details.stream);    batch.draw(gpu::LINES, 2, 0);} void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) {    if (!_standardDrawPipeline) {        auto vs = gpu::Shader::createVertex(std::string(standardTransformPNTC_vert));        auto ps = gpu::Shader::createPixel(std::string(standardDrawTexture_frag));        auto program = gpu::Shader::createProgram(vs, ps);        gpu::Shader::makeProgram((*program));         auto state = std::make_shared<gpu::State>();         // enable decal blend        state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);         _standardDrawPipeline = gpu::Pipeline::create(program, state);          auto stateNoBlend = std::make_shared<gpu::State>();        auto noBlendPS = gpu::StandardShaderLib::getDrawTextureOpaquePS();        auto programNoBlend = gpu::Shader::createProgram(vs, noBlendPS);        gpu::Shader::makeProgram((*programNoBlend));        _standardDrawPipelineNoBlend = gpu::Pipeline::create(programNoBlend, stateNoBlend);    }    if (noBlend) {        batch.setPipeline(_standardDrawPipelineNoBlend);    } else {        batch.setPipeline(_standardDrawPipeline);    }} void GeometryCache::useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bool isLayered) {    if (!_gridPipeline) {        auto vs = gpu::Shader::createVertex(std::string(standardTransformPNTC_vert));        auto ps = gpu::Shader::createPixel(std::string(grid_frag));        auto program = gpu::Shader::createProgram(vs, ps);        gpu::Shader::makeProgram((*program));        _gridSlot = program->getBuffers().findLocation("gridBuffer");         auto stateLayered = std::make_shared<gpu::State>();        stateLayered->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);        _gridPipelineLayered = gpu::Pipeline::create(program, stateLayered);         auto state = std::make_shared<gpu::State>(stateLayered->getValues());        const float DEPTH_BIAS = 0.001f;        state->setDepthBias(DEPTH_BIAS);        state->setDepthTest(true, false, gpu::LESS_EQUAL);        _gridPipeline = gpu::Pipeline::create(program, state);    }     gpu::PipelinePointer pipeline = isLayered ? _gridPipelineLayered : _gridPipeline;    batch.setPipeline(pipeline);    batch.setUniformBuffer(_gridSlot, gridBuffer);}   class SimpleProgramKey {public:    enum FlagBit {        IS_TEXTURED_FLAG = 0,

Lines 1001–1500 of 1698. Previous lines