示例#1
0
void
dumpTextures(JSONWriter &json, Context &context)
{
    json.beginMember("textures");
    json.beginObject();
    GLint active_texture = GL_TEXTURE0;
    glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);

    GLint max_texture_coords = 0;
    glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);
    GLint max_combined_texture_image_units = 0;
    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_texture_image_units);
    GLint max_units = std::max(max_combined_texture_image_units, max_texture_coords);

    /*
     * At least the Android software GL implementation doesn't return the
     * proper value for this, but rather returns 0. The GL(ES) specification
     * mandates a minimum value of 2, so use this as a fall-back value.
     */
    max_units = std::max(max_units, 2);

    for (GLint unit = 0; unit < max_units; ++unit) {
        GLenum texture = GL_TEXTURE0 + unit;
        glActiveTexture(texture);
        dumpTexture(json, context, GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D);
        dumpTexture(json, context, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D);
        dumpTexture(json, context, GL_TEXTURE_3D, GL_TEXTURE_BINDING_3D);
        dumpTexture(json, context, GL_TEXTURE_RECTANGLE, GL_TEXTURE_BINDING_RECTANGLE);
        dumpTexture(json, context, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP);
    }
    glActiveTexture(active_texture);
    json.endObject();
    json.endMember(); // textures
}
示例#2
0
/**
 * Dump the image of the currently bound read buffer.
 */
static inline void
dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format,
                    GLint internalFormat = GL_NONE)
{
    GLint channels = _gl_format_channels(format);

    if (internalFormat == GL_NONE) {
        internalFormat = format;
    }

    Context context;

    json.beginObject();

    // Tell the GUI this is no ordinary object, but an image
    json.writeStringMember("__class__", "image");

    json.writeNumberMember("__width__", width);
    json.writeNumberMember("__height__", height);
    json.writeNumberMember("__depth__", 1);

    json.writeStringMember("__format__", enumToString(internalFormat));

    // Hardcoded for now, but we could chose types more adequate to the
    // texture internal format
    json.writeStringMember("__type__", "uint8");
    json.writeBoolMember("__normalized__", true);
    json.writeNumberMember("__channels__", channels);

    GLenum type = GL_UNSIGNED_BYTE;

#if DEPTH_AS_RGBA
    if (format == GL_DEPTH_COMPONENT) {
        type = GL_UNSIGNED_INT;
        channels = 4;
    }
#endif

    GLubyte *pixels = new GLubyte[width*height*channels];

    // TODO: reset imaging state too
    context.resetPixelPackState();

    glReadPixels(0, 0, width, height, format, type, pixels);

    context.restorePixelPackState();

    json.beginMember("__data__");
    char *pngBuffer;
    int pngBufferSize;
    image::writePixelsToBuffer(pixels, width, height, channels, true, &pngBuffer, &pngBufferSize);
    //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels)
    //          <<", after = "<<pngBufferSize << ", ratio = " << double(width * height * channels * sizeof *pixels)/pngBufferSize;
    json.writeBase64(pngBuffer, pngBufferSize);
    free(pngBuffer);
    json.endMember(); // __data__

    delete [] pixels;
    json.endObject();
}
示例#3
0
void
dumpTextures(JSONWriter &json, ID3D11DeviceContext *pDevice)
{
    json.beginMember("textures");
    json.beginObject();

    ID3D11ShaderResourceView *pShaderResourceViews[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];

    pDevice->VSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
    dumpStageTextures(json, pDevice, "VS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);

    pDevice->HSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
    dumpStageTextures(json, pDevice, "HS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);

    pDevice->DSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
    dumpStageTextures(json, pDevice, "DS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);

    pDevice->GSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
    dumpStageTextures(json, pDevice, "GS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);

    pDevice->PSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
    dumpStageTextures(json, pDevice, "PS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);

    json.endObject();
    json.endMember(); // textures
}
示例#4
0
static inline void
dumpTextures(JSONWriter &json)
{
    json.beginMember("textures");
    json.beginObject();
    GLint active_texture = GL_TEXTURE0;
    glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
    GLint max_texture_coords = 0;
    glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);
    GLint max_combined_texture_image_units = 0;
    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_texture_image_units);
    GLint max_units = std::max(max_combined_texture_image_units, max_texture_coords);
    for (GLint unit = 0; unit < max_units; ++unit) {
        GLenum texture = GL_TEXTURE0 + unit;
        glActiveTexture(texture);
        dumpTexture(json, GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D);
        dumpTexture(json, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D);
        dumpTexture(json, GL_TEXTURE_3D, GL_TEXTURE_BINDING_3D);
        dumpTexture(json, GL_TEXTURE_RECTANGLE, GL_TEXTURE_BINDING_RECTANGLE);
        dumpTexture(json, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP);
    }
    glActiveTexture(active_texture);
    json.endObject();
    json.endMember(); // textures
}
示例#5
0
static void
dumpShaders(JSONWriter &json, ID3D10Device *pDevice)
{
    json.beginMember("shaders");
    json.beginObject();

    com_ptr<ID3D10VertexShader> pVertexShader;
    pDevice->VSGetShader(&pVertexShader);
    if (pVertexShader) {
        dumpShader<ID3D10DeviceChild>(json, "VS", pVertexShader);
    }

    com_ptr<ID3D10GeometryShader> pGeometryShader;
    pDevice->GSGetShader(&pGeometryShader);
    if (pGeometryShader) {
        dumpShader<ID3D10DeviceChild>(json, "GS", pGeometryShader);
    }

    com_ptr<ID3D10PixelShader> pPixelShader;
    pDevice->PSGetShader(&pPixelShader);
    if (pPixelShader) {
        dumpShader<ID3D10DeviceChild>(json, "PS", pPixelShader);
    }

    json.endObject();
    json.endMember(); // shaders
}
示例#6
0
void
dumpTextures(JSONWriter &json, IDirect3DDevice7 *pDevice)
{
    json.beginMember("textures");
    json.beginObject();
    json.endObject();
    json.endMember(); // textures
}
示例#7
0
void
dumpFramebuffer(JSONWriter &json, ID3D11DeviceContext *pDevice)
{
    json.beginMember("framebuffer");
    json.beginObject();

    ID3D11RenderTargetView *pRenderTargetViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
    ID3D11DepthStencilView *pDepthStencilView;
    pDevice->OMGetRenderTargets(ARRAYSIZE(pRenderTargetViews), pRenderTargetViews,
                                &pDepthStencilView);

    for (UINT i = 0; i < ARRAYSIZE(pRenderTargetViews); ++i) {
        if (!pRenderTargetViews[i]) {
            continue;
        }

        image::Image *image;
        DXGI_FORMAT dxgiFormat;
        image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i],
                                         &dxgiFormat);
        if (image) {
            char label[64];
            _snprintf(label, sizeof label, "RENDER_TARGET_%u", i);
            JSONWriter::ImageDesc imgDesc;
            imgDesc.depth = 1;
            imgDesc.format = getDXGIFormatName(dxgiFormat);
            json.beginMember(label);
            json.writeImage(image, imgDesc);
            json.endMember(); // RENDER_TARGET_*
            delete image;
        }

        pRenderTargetViews[i]->Release();
    }

    if (pDepthStencilView) {
        image::Image *image;
        DXGI_FORMAT dxgiFormat;
        image = getDepthStencilViewImage(pDevice, pDepthStencilView,
                                         &dxgiFormat);
        if (image) {
            JSONWriter::ImageDesc imgDesc;
            imgDesc.depth = 1;
            imgDesc.format = getDXGIFormatName(dxgiFormat);
            json.beginMember("DEPTH_STENCIL");
            json.writeImage(image, imgDesc);
            json.endMember();
            delete image;
        }

        pDepthStencilView->Release();
    }

    json.endObject();
    json.endMember(); // framebuffer
}
示例#8
0
static inline void
dumpShaders(JSONWriter &json)
{
    json.beginMember("shaders");
    json.beginObject();
    dumpCurrentProgram(json);
    dumpArbProgram(json, GL_FRAGMENT_PROGRAM_ARB);
    dumpArbProgram(json, GL_VERTEX_PROGRAM_ARB);
    json.endObject();
    json.endMember(); //shaders
}
示例#9
0
static void
dumpProgramUniformsStage(JSONWriter &json, GLint program, const char *stage)
{
    if (program) {
        json.beginMember(stage);
        json.beginObject();
        dumpProgramUniforms(json, program);
        json.endObject();
        json.endMember();
    }
}
示例#10
0
void
dumpFramebuffer(JSONWriter &json, IDirect3DDevice9 *pDevice)
{
    HRESULT hr;

    json.beginMember("framebuffer");
    json.beginObject();

    D3DCAPS9 Caps;
    pDevice->GetDeviceCaps(&Caps);

    for (UINT i = 0; i < Caps.NumSimultaneousRTs; ++i) {
        IDirect3DSurface9 *pRenderTarget = NULL;
        hr = pDevice->GetRenderTarget(i, &pRenderTarget);
        if (FAILED(hr)) {
            continue;
        }

        if (!pRenderTarget) {
            continue;
        }

        image::Image *image;
        image = getRenderTargetImage(pDevice, pRenderTarget);
        if (image) {
            char label[64];
            _snprintf(label, sizeof label, "RENDER_TARGET_%u", i);
            json.beginMember(label);
            json.writeImage(image, "UNKNOWN");
            json.endMember(); // RENDER_TARGET_*
        }

        pRenderTarget->Release();
    }

    IDirect3DSurface9 *pDepthStencil = NULL;
    hr = pDevice->GetDepthStencilSurface(&pDepthStencil);
    if (SUCCEEDED(hr) && pDepthStencil) {
        image::Image *image;
        image = getSurfaceImage(pDevice, pDepthStencil);
        if (image) {
            json.beginMember("DEPTH_STENCIL");
            json.writeImage(image, "UNKNOWN");
            json.endMember(); // RENDER_TARGET_*
        }
    }


    json.endObject();
    json.endMember(); // framebuffer
}
示例#11
0
static void
dumpParameters(JSONWriter &json, ID3D11DeviceContext *pDeviceContext)
{
    // TODO: dump description of current bound state
    json.beginMember("parameters");
    json.beginObject();

    dumpRasterizerState(json, pDeviceContext);
    dumpBlendState(json, pDeviceContext);
    dumpDepthStencilState(json, pDeviceContext);

    json.endObject();
    json.endMember(); // parameters
}
示例#12
0
void
dumpTextures(JSONWriter &json, IDirect3DDevice9 *pDevice)
{
    HRESULT hr;

    json.beginMember("textures");
    json.beginObject();

    for (DWORD Stage = 0; Stage < 16; ++Stage) {
        com_ptr<IDirect3DBaseTexture9> pTexture;
        hr = pDevice->GetTexture(Stage, &pTexture);
        if (FAILED(hr)) {
            continue;
        }

        if (!pTexture) {
            continue;
        }

        D3DRESOURCETYPE Type = pTexture->GetType();

        DWORD NumFaces = Type == D3DRTYPE_CUBETEXTURE ? 6 : 1;
        DWORD NumLevels = pTexture->GetLevelCount();

        for (DWORD Face = 0; Face < NumFaces; ++Face) {
            for (DWORD Level = 0; Level < NumLevels; ++Level) {
                image::Image *image;
                image = getTextureImage(pDevice, pTexture, static_cast<D3DCUBEMAP_FACES>(Face), Level);
                if (image) {
                    char label[128];
                    if (Type == D3DRTYPE_CUBETEXTURE) {
                        _snprintf(label, sizeof label, "PS_RESOURCE_%lu_FACE_%lu_LEVEL_%lu", Stage, Face, Level);
                    } else {
                        _snprintf(label, sizeof label, "PS_RESOURCE_%lu_LEVEL_%lu", Stage, Level);
                    }
                    json.beginMember(label);
                    json.writeImage(image);
                    json.endMember(); // PS_RESOURCE_*
                }
            }
        }
    }

    json.endObject();
    json.endMember(); // textures
}
示例#13
0
void
dumpFramebuffer(JSONWriter &json, ID3D10Device *pDevice)
{
    json.beginMember("framebuffer");
    json.beginObject();

    ID3D10RenderTargetView *pRenderTargetViews[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
    ID3D10DepthStencilView *pDepthStencilView;
    pDevice->OMGetRenderTargets(ARRAYSIZE(pRenderTargetViews), pRenderTargetViews,
                                &pDepthStencilView);

    for (UINT i = 0; i < ARRAYSIZE(pRenderTargetViews); ++i) {
        if (!pRenderTargetViews[i]) {
            continue;
        }

        image::Image *image;
        image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i]);
        if (image) {
            char label[64];
            _snprintf(label, sizeof label, "RENDER_TARGET_%u", i);
            json.beginMember(label);
            json.writeImage(image);
            json.endMember(); // RENDER_TARGET_*
            delete image;
        }

        pRenderTargetViews[i]->Release();
    }

    if (pDepthStencilView) {
        image::Image *image;
        image = getDepthStencilViewImage(pDevice, pDepthStencilView);
        if (image) {
            json.beginMember("DEPTH_STENCIL");
            json.writeImage(image);
            json.endMember();
            delete image;
        }

        pDepthStencilView->Release();
    }

    json.endObject();
    json.endMember(); // framebuffer
}
示例#14
0
/**
 * Dump the image of the currently bound read buffer.
 */
static inline void
dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format)
{
    GLint channels = __gl_format_channels(format);

    json.beginObject();

    // Tell the GUI this is no ordinary object, but an image
    json.writeStringMember("__class__", "image");

    json.writeNumberMember("__width__", width);
    json.writeNumberMember("__height__", height);
    json.writeNumberMember("__depth__", 1);

    // Hardcoded for now, but we could chose types more adequate to the
    // texture internal format
    json.writeStringMember("__type__", "uint8");
    json.writeBoolMember("__normalized__", true);
    json.writeNumberMember("__channels__", channels);

    GLubyte *pixels = new GLubyte[width*height*channels];

    resetPixelPackState();

    glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels);

    restorePixelPackState();

    json.beginMember("__data__");
    char *pngBuffer;
    int pngBufferSize;
    Image::writePixelsToBuffer(pixels, width, height, channels, false, &pngBuffer, &pngBufferSize);
    //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels)
    //          <<", after = "<<pngBufferSize << ", ratio = " << double(width * height * channels * sizeof *pixels)/pngBufferSize;
    json.writeBase64(pngBuffer, pngBufferSize);
    free(pngBuffer);
    json.endMember(); // __data__

    delete [] pixels;
    json.endObject();
}
示例#15
0
static void
dumpShaders(JSONWriter &json, ID3D11DeviceContext *pDeviceContext)
{
    json.beginMember("shaders");
    json.beginObject();

    com_ptr<ID3D11VertexShader> pVertexShader;
    pDeviceContext->VSGetShader(&pVertexShader, NULL, NULL);
    if (pVertexShader) {
        dumpShader<ID3D11DeviceChild>(json, "VS", pVertexShader);
    }

    com_ptr<ID3D11HullShader> pHullShader;
    pDeviceContext->HSGetShader(&pHullShader, NULL, NULL);
    if (pHullShader) {
        dumpShader<ID3D11DeviceChild>(json, "HS", pHullShader);
    }

    com_ptr<ID3D11DomainShader> pDomainShader;
    pDeviceContext->DSGetShader(&pDomainShader, NULL, NULL);
    if (pDomainShader) {
        dumpShader<ID3D11DeviceChild>(json, "DS", pDomainShader);
    }

    com_ptr<ID3D11GeometryShader> pGeometryShader;
    pDeviceContext->GSGetShader(&pGeometryShader, NULL, NULL);
    if (pGeometryShader) {
        dumpShader<ID3D11DeviceChild>(json, "GS", pGeometryShader);
    }

    com_ptr<ID3D11PixelShader> pPixelShader;
    pDeviceContext->PSGetShader(&pPixelShader, NULL, NULL);
    if (pPixelShader) {
        dumpShader<ID3D11DeviceChild>(json, "PS", pPixelShader);
    }

    json.endObject();
    json.endMember(); // shaders
}
示例#16
0
void
dumpFramebuffer(JSONWriter &json, IDirect3DDevice7 *pDevice)
{
    HRESULT hr;

    json.beginMember("framebuffer");
    json.beginObject();

    com_ptr<IDirectDrawSurface7> pRenderTarget;
    hr = pDevice->GetRenderTarget(&pRenderTarget);
    if (SUCCEEDED(hr) && pRenderTarget) {
        image::Image *image;
        image = getSurfaceImage(pDevice, pRenderTarget);
        if (image) {
            json.beginMember("RENDER_TARGET_0");
            json.writeImage(image);
            json.endMember(); // RENDER_TARGET_*
        }

        // Search for a depth-stencil attachment
        DDSCAPS2 ddsCaps;
        ZeroMemory(&ddsCaps, sizeof ddsCaps);
        ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
        com_ptr<IDirectDrawSurface7> pDepthStencil;
        hr = pRenderTarget->GetAttachedSurface(&ddsCaps, &pDepthStencil);
        if (SUCCEEDED(hr) && pDepthStencil) {
            std::cerr << "found ZS!!\n";
            image = getSurfaceImage(pDevice, pDepthStencil);
            if (image) {
                json.beginMember("DEPTH_STENCIL");
                json.writeImage(image);
                json.endMember(); // DEPTH_STENCIL
            }
        }
    }

    json.endObject();
    json.endMember(); // framebuffer
}
示例#17
0
static void
dumpShaders(JSONWriter &json, IDirect3DDevice9 *pDevice)
{
    json.beginMember("shaders");

    HRESULT hr;
    json.beginObject();

    com_ptr<IDirect3DVertexShader9> pVertexShader;
    hr = pDevice->GetVertexShader(&pVertexShader);
    if (SUCCEEDED(hr)) {
        dumpShader<IDirect3DVertexShader9>(json, "vertex", pVertexShader);
    }

    com_ptr<IDirect3DPixelShader9> pPixelShader;
    hr = pDevice->GetPixelShader(&pPixelShader);
    if (SUCCEEDED(hr)) {
        dumpShader<IDirect3DPixelShader9>(json, "pixel", pPixelShader);
    }

    json.endObject();
    json.endMember(); // shaders
}
示例#18
0
static inline void
dumpTextureImage(JSONWriter &json, GLenum target, GLint level)
{
    GLint width, height = 1, depth = 1;

    width = 0;
    glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);

    if (target != GL_TEXTURE_1D) {
        height = 0;
        glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
        if (target == GL_TEXTURE_3D) {
            depth = 0;
            glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
        }
    }

    if (width <= 0 || height <= 0 || depth <= 0) {
        return;
    } else {
        char label[512];

        GLint active_texture = GL_TEXTURE0;
        glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
        snprintf(label, sizeof label, "%s, %s, level = %i", enumToString(active_texture), enumToString(target), level);

        json.beginMember(label);

        json.beginObject();

        // Tell the GUI this is no ordinary object, but an image
        json.writeStringMember("__class__", "image");

        json.writeNumberMember("__width__", width);
        json.writeNumberMember("__height__", height);
        json.writeNumberMember("__depth__", depth);

        // Hardcoded for now, but we could chose types more adequate to the
        // texture internal format
        json.writeStringMember("__type__", "uint8");
        json.writeBoolMember("__normalized__", true);
        json.writeNumberMember("__channels__", 4);

        GLubyte *pixels = new GLubyte[depth*width*height*4];

        resetPixelPackState();

        glGetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

        restorePixelPackState();

        json.beginMember("__data__");
        char *pngBuffer;
        int pngBufferSize;
        Image::writePixelsToBuffer(pixels, width, height, 4, false, &pngBuffer, &pngBufferSize);
        json.writeBase64(pngBuffer, pngBufferSize);
        free(pngBuffer);
        json.endMember(); // __data__

        delete [] pixels;
        json.endObject();
    }
}
示例#19
0
static inline void
dumpTransformFeedback(JSONWriter &json, GLint program)
{
    GLint transform_feedback_varyings = 0;
    glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, &transform_feedback_varyings);
    if (!transform_feedback_varyings) {
        return;
    }

    GLint max_name_length = 0;
    glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_name_length);
    std::vector<GLchar> name(max_name_length);

    GLint buffer_mode = GL_INTERLEAVED_ATTRIBS;
    glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, &buffer_mode);

    std::vector<TransformFeedbackAttrib> attribs(transform_feedback_varyings);

    // Calculate the offsets and strides of each attribute according to
    // the value of GL_TRANSFORM_FEEDBACK_BUFFER_MODE
    GLsizei cum_attrib_offset = 0;
    for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) {
        TransformFeedbackAttrib & attrib = attribs[slot];

        GLsizei length = 0;
        GLsizei size = 0;
        GLenum type = GL_NONE;
        glGetTransformFeedbackVarying(program, slot, max_name_length, &length, &size, &type, &name[0]);

        attrib.name = &name[0];

        const AttribDesc & desc = attrib.desc = AttribDesc(type, size);
        if (!desc) {
            return;
        }

        attrib.size = desc.arrayStride;

        switch (buffer_mode) {
        case GL_INTERLEAVED_ATTRIBS:
            attrib.offset = cum_attrib_offset;
            break;
        case GL_SEPARATE_ATTRIBS:
            attrib.offset = 0;
            attrib.stride = desc.arrayStride;
            break;
        default:
            assert(0);
            attrib.offset = 0;
            attrib.stride = 0;
        }

        cum_attrib_offset += desc.arrayStride;
    }
    if (buffer_mode == GL_INTERLEAVED_ATTRIBS) {
        for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) {
            TransformFeedbackAttrib & attrib = attribs[slot];
            attrib.stride = cum_attrib_offset;
        }
    }

    GLint previous_tbo = 0;
    glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &previous_tbo);

    // Map the buffers and calculate how many vertices can they hold
    // XXX: We currently limit to 1024, or things can get significantly slow.
    unsigned numVertices = 16*1024;
    for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) {
        TransformFeedbackAttrib & attrib = attribs[slot];
        attrib.map = NULL;
        if (slot == 0 || buffer_mode != GL_INTERLEAVED_ATTRIBS) {
            GLint tbo = 0;
            glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, slot, &tbo);
            if (!tbo) {
                numVertices = 0;
                continue;
            }

            GLint start = 0;
            glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_START, slot, &start);
            GLint size = 0;
            glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, slot, &size);

            glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo);

            if (size == 0) {
                glGetBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &size);
                assert(size >= start);
                size -= start;
            }

            unsigned numAttribVertices = calcNumElements(size,
                                         attrib.offset,
                                         attrib.size,
                                         attrib.stride);
            numVertices = std::min(numVertices, numAttribVertices);

            attrib.map = (const GLbyte *)glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY) + start;
        } else {
            attrib.map = attribs[0].map;
        }
    }

    // Actually dump the vertices
    json.beginMember("GL_TRANSFORM_FEEDBACK");
    json.beginArray();
    for (unsigned vertex = 0; vertex < numVertices; ++vertex) {
        json.beginObject();
        for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) {
            TransformFeedbackAttrib & attrib = attribs[slot];
            if (!attrib.map) {
                continue;
            }

            const AttribDesc & desc = attrib.desc;
            assert(desc);

            const GLbyte *vertex_data = attrib.map + attrib.stride*vertex + attrib.offset;
            dumpAttribArray(json, attrib.name, desc, vertex_data);
        }
        json.endObject();
    }
    json.endArray();
    json.endMember();

    // Unmap the buffers
    for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) {
        TransformFeedbackAttrib & attrib = attribs[slot];
        if (slot == 0 || buffer_mode != GL_INTERLEAVED_ATTRIBS) {
            if (!attrib.map) {
                continue;
            }

            GLint tbo = 0;
            glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, slot, &tbo);
            assert(tbo);

            glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo);

            glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
        }
    }

    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, previous_tbo);
}
示例#20
0
void
dumpShadersUniforms(JSONWriter &json, Context &context)
{
    GLint pipeline = 0;
    GLint vertex_program = 0;
    GLint fragment_program = 0;
    GLint geometry_program = 0;
    GLint tess_control_program = 0;
    GLint tess_evaluation_program = 0;
    GLint compute_program = 0;

    if (!context.ES) {
        glGetIntegerv(GL_PROGRAM_PIPELINE_BINDING, &pipeline);
        if (pipeline) {
            glGetProgramPipelineiv(pipeline, GL_VERTEX_SHADER, &vertex_program);
            glGetProgramPipelineiv(pipeline, GL_FRAGMENT_SHADER, &fragment_program);
            glGetProgramPipelineiv(pipeline, GL_GEOMETRY_SHADER, &geometry_program);
            glGetProgramPipelineiv(pipeline, GL_TESS_CONTROL_SHADER, &tess_control_program);
            glGetProgramPipelineiv(pipeline, GL_TESS_EVALUATION_SHADER, &tess_evaluation_program);
            glGetProgramPipelineiv(pipeline, GL_COMPUTE_SHADER, &compute_program);
        }
    }

    GLint program = 0;
    if (!pipeline) {
        glGetIntegerv(GL_CURRENT_PROGRAM, &program);
    }

    json.beginMember("shaders");
    json.beginObject();
    if (pipeline) {
        dumpProgram(json, vertex_program);
        dumpProgram(json, fragment_program);
        dumpProgram(json, geometry_program);
        dumpProgram(json, tess_control_program);
        dumpProgram(json, tess_evaluation_program);
        dumpProgram(json, compute_program);
    } else if (program) {
        dumpProgram(json, program);
    } else {
        dumpArbProgram(json, GL_FRAGMENT_PROGRAM_ARB);
        dumpArbProgram(json, GL_VERTEX_PROGRAM_ARB);
    }
    json.endObject();
    json.endMember(); // shaders

    json.beginMember("uniforms");
    json.beginObject();
    if (pipeline) {
        dumpProgramUniformsStage(json, vertex_program, "GL_VERTEX_SHADER");
        dumpProgramUniformsStage(json, fragment_program, "GL_FRAGMENT_SHADER");
        dumpProgramUniformsStage(json, geometry_program, "GL_GEOMETRY_SHADER");
        dumpProgramUniformsStage(json, tess_control_program, "GL_TESS_CONTROL_SHADER");
        dumpProgramUniformsStage(json, tess_evaluation_program, "GL_TESS_EVALUATION_SHADER");
        dumpProgramUniformsStage(json, compute_program, "GL_COMPUTE_SHADER");
    } else if (program) {
        dumpProgramUniforms(json, program);
    } else {
        dumpArbProgramUniforms(json, GL_FRAGMENT_PROGRAM_ARB, "fp.");
        dumpArbProgramUniforms(json, GL_VERTEX_PROGRAM_ARB, "vp.");
    }
    json.endObject();
    json.endMember(); // uniforms

    json.beginMember("buffers");
    json.beginObject();
    if (program) {
        dumpTransformFeedback(json, program);
    }
    json.endObject();
    json.endMember(); // buffers
}
示例#21
0
static inline void
dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint level)
{
    ImageDesc desc;
    if (!getActiveTextureLevelDesc(context, target, level, desc)) {
        return;
    }

    char label[512];

    GLint active_texture = GL_TEXTURE0;
    glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
    snprintf(label, sizeof label, "%s, %s, level = %d",
             enumToString(active_texture), enumToString(target), level);

    json.beginMember(label);

    json.beginObject();

    GLuint channels;
    GLenum format;
    if (!context.ES && isDepthFormat(desc.internalFormat)) {
       format = GL_DEPTH_COMPONENT;
       channels = 1;
    } else {
       format = GL_RGBA;
       channels = 4;
    }

    // Tell the GUI this is no ordinary object, but an image
    json.writeStringMember("__class__", "image");

    json.writeNumberMember("__width__", desc.width);
    json.writeNumberMember("__height__", desc.height);
    json.writeNumberMember("__depth__", desc.depth);

    json.writeStringMember("__format__", enumToString(desc.internalFormat));

    // Hardcoded for now, but we could chose types more adequate to the
    // texture internal format
    json.writeStringMember("__type__", "uint8");
    json.writeBoolMember("__normalized__", true);
    json.writeNumberMember("__channels__", channels);

    GLubyte *pixels = new GLubyte[desc.depth*desc.width*desc.height*channels];

    context.resetPixelPackState();

    if (context.ES) {
        getTexImageOES(target, level, desc, pixels);
    } else {
        glGetTexImage(target, level, format, GL_UNSIGNED_BYTE, pixels);
    }

    context.restorePixelPackState();

    json.beginMember("__data__");
    char *pngBuffer;
    int pngBufferSize;
    image::writePixelsToBuffer(pixels, desc.width, desc.height, channels, true, &pngBuffer, &pngBufferSize);
    json.writeBase64(pngBuffer, pngBufferSize);
    free(pngBuffer);
    json.endMember(); // __data__

    delete [] pixels;
    json.endObject();
}
示例#22
0
void
dumpFramebuffer(JSONWriter &json, Context &context)
{
    json.beginMember("framebuffer");
    json.beginObject();

    GLint boundDrawFbo = 0, boundReadFbo = 0;
    glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundDrawFbo);
    glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFbo);
    if (!boundDrawFbo) {
        dumpDrawableImages(json, context);
    } else if (context.ES) {
        dumpFramebufferAttachments(json, context, GL_FRAMEBUFFER);
    } else {
        GLint colorRb = 0, stencilRb = 0, depthRb = 0;
        GLint draw_buffer0 = GL_NONE;
        glGetIntegerv(GL_DRAW_BUFFER0, &draw_buffer0);
        bool multisample = false;

        GLint boundRb = 0;
        glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundRb);

        GLint object_type;
        glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, draw_buffer0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
        if (object_type == GL_RENDERBUFFER) {
            glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, draw_buffer0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &colorRb);
            glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
            GLint samples = 0;
            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
            if (samples) {
                multisample = true;
            }
        }

        glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
        if (object_type == GL_RENDERBUFFER) {
            glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthRb);
            glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
            GLint samples = 0;
            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
            if (samples) {
                multisample = true;
            }
        }

        glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
        if (object_type == GL_RENDERBUFFER) {
            glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &stencilRb);
            glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
            GLint samples = 0;
            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
            if (samples) {
                multisample = true;
            }
        }

        glBindRenderbuffer(GL_RENDERBUFFER, boundRb);

        GLuint rbs[3];
        GLint numRbs = 0;
        GLuint fboCopy = 0;

        if (multisample) {
            // glReadPixels doesnt support multisampled buffers so we need
            // to blit the fbo to a temporary one
            fboCopy = downsampledFramebuffer(context,
                                             boundDrawFbo, draw_buffer0,
                                             colorRb, depthRb, stencilRb,
                                             rbs, &numRbs);
        }

        dumpFramebufferAttachments(json, context, GL_DRAW_FRAMEBUFFER);

        if (multisample) {
            glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb);
            glDeleteRenderbuffers(numRbs, rbs);
            glDeleteFramebuffers(1, &fboCopy);
        }

        glBindFramebuffer(GL_READ_FRAMEBUFFER, boundReadFbo);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundDrawFbo);
    }

    json.endObject();
    json.endMember(); // framebuffer
}