예제 #1
0
Shader::Shader(const char* name_, const char* vertexSource, const char* fragmentSource, gl::ObjectStore& store, Defines defines)
    : name(name_)
    , program(store.createProgram())
    , vertexShader(store.createShader(GL_VERTEX_SHADER))
    , fragmentShader(store.createShader(GL_FRAGMENT_SHADER))
{
    util::stopwatch stopwatch("shader compilation", Event::Shader);

    if (!compileShader(vertexShader, vertexSource)) {
        Log::Error(Event::Shader, "Vertex shader %s failed to compile: %s", name, vertexSource);
        throw util::ShaderException(std::string { "Vertex shader " } + name + " failed to compile");
    }

    std::string fragment(fragmentSource);
    if (defines & Defines::Overdraw) {
        assert(fragment.find("#ifdef OVERDRAW_INSPECTOR") != std::string::npos);
        fragment.replace(fragment.find_first_of('\n'), 1, "\n#define OVERDRAW_INSPECTOR\n");
    }

    if (!compileShader(fragmentShader, fragment.c_str())) {
        Log::Error(Event::Shader, "Fragment shader %s failed to compile: %s", name, fragmentSource);
        throw util::ShaderException(std::string { "Fragment shader " } + name + " failed to compile");
    }

    // Attach shaders
    MBGL_CHECK_ERROR(glAttachShader(program.get(), vertexShader.get()));
    MBGL_CHECK_ERROR(glAttachShader(program.get(), fragmentShader.get()));

    // Bind attribute variables
    MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_pos, "a_pos"));
    MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_extrude, "a_extrude"));
    MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_offset, "a_offset"));
    MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_data, "a_data"));
    MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_texture_pos, "a_texture_pos"));

    // Link program
    GLint status;
     MBGL_CHECK_ERROR(glLinkProgram(program.get()));

    MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_LINK_STATUS, &status));
    if (status == 0) {
        GLint logLength;
        MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_INFO_LOG_LENGTH, &logLength));
        const auto log = std::make_unique<GLchar[]>(logLength);
        if (logLength > 0) {
            MBGL_CHECK_ERROR(glGetProgramInfoLog(program.get(), logLength, &logLength, log.get()));
            Log::Error(Event::Shader, "Program failed to link: %s", log.get());
        }
        throw util::ShaderException(std::string { "Program " } + name + " failed to link: " + log.get());
    }
}
예제 #2
0
 // Transfers this buffer to the GPU and binds the buffer to the GL context.
 void bind(gl::ObjectStore& store) {
     if (buffer) {
         MBGL_CHECK_ERROR(glBindBuffer(bufferType, *buffer));
     } else {
         buffer = store.createBuffer();
         MBGL_CHECK_ERROR(glBindBuffer(bufferType, *buffer));
         if (array == nullptr) {
             Log::Debug(Event::OpenGL, "Buffer doesn't contain elements");
             pos = 0;
         }
         MBGL_CHECK_ERROR(glBufferData(bufferType, pos, array, GL_STATIC_DRAW));
         if (!retainAfterUpload) {
             cleanup();
         }
     }
 }
예제 #3
0
void FrameHistory::bind(gl::ObjectStore& store) {
    if (!texture) {
        texture = store.createTexture();
        MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
#ifndef GL_ES_VERSION_2_0
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
    } else {
        MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
    }

}
예제 #4
0
void FrameHistory::bind(gl::ObjectStore& store, gl::Config& config, uint32_t unit) {
    if (!texture) {
        texture = store.createTexture();
        config.activeTexture = unit;
        config.texture[unit] = *texture;
#ifndef GL_ES_VERSION_2_0
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
    } else if (config.texture[unit] != *texture) {
        config.activeTexture = unit;
        config.texture[unit] = *texture;
    }
}
예제 #5
0
void SpriteAtlas::bind(bool linear, gl::ObjectStore& objectStore) {
    if (!data) {
        return; // Empty atlas
    }

    if (!texture) {
        texture = objectStore.createTexture();
        MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
#ifndef GL_ES_VERSION_2_0
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
        // We are using clamp to edge here since OpenGL ES doesn't allow GL_REPEAT on NPOT textures.
        // We use those when the pixelRatio isn't a power of two, e.g. on iPhone 6 Plus.
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
        fullUploadRequired = true;
    } else {
        MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
    }

    GLuint filter_val = linear ? GL_LINEAR : GL_NEAREST;
    if (filter_val != filter) {
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_val));
        MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_val));
        filter = filter_val;
    }

    if (dirty) {
        std::lock_guard<std::recursive_mutex> lock(mtx);

        if (fullUploadRequired) {
            MBGL_CHECK_ERROR(glTexImage2D(
                GL_TEXTURE_2D, // GLenum target
                0, // GLint level
                GL_RGBA, // GLint internalformat
                pixelWidth, // GLsizei width
                pixelHeight, // GLsizei height
                0, // GLint border
                GL_RGBA, // GLenum format
                GL_UNSIGNED_BYTE, // GLenum type
                data.get() // const GLvoid * data
            ));
            fullUploadRequired = false;
        } else {
            MBGL_CHECK_ERROR(glTexSubImage2D(
                GL_TEXTURE_2D, // GLenum target
                0, // GLint level
                0, // GLint xoffset
                0, // GLint yoffset
                pixelWidth, // GLsizei width
                pixelHeight, // GLsizei height
                GL_RGBA, // GLenum format
                GL_UNSIGNED_BYTE, // GLenum type
                data.get() // const GLvoid *pixels
            ));
        }

        dirty = false;

#ifndef GL_ES_VERSION_2_0
        // platform::showColorDebugImage("Sprite Atlas", reinterpret_cast<const char*>(data.get()),
        //                               pixelWidth, pixelHeight, pixelWidth, pixelHeight);
#endif
    }
};
예제 #6
0
 Impl(gl::ObjectStore& store) : pool(store.createTexturePool()), availableIDs(gl::TextureMax) {
     std::copy(pool.get().begin(), pool.get().end(), availableIDs.begin());
 }