zoukankan      html  css  js  c++  java
  • PPAPI中使用Chromium的3D图形接口

    使用PPAPI的Graphics 3D接口做了一个小演示样例,鼠标点击插件区域。绘制颜色,效果与ppapi_simple相似。

    foruok原创,如需转载请关注foruok的微信订阅号“程序视界”联系foruok。

    项目

    项目与VS2013编译最简单的PPAPI插件这篇文章里说的ppapi_simple相似。

    附加包括路径有些不同,例如以下:

    • E:sourcesCEF2526chromiumsrc
    • E:sourcesCEF2526chromiumsrcppapilibglinclude

    附加库路径例如以下:

    • E:sourcesCEF2526chromiumsrccefinary_distribcef_binary_3.2526.1364.gf6bf57b_windows32Release
    • E:sourcesCEF2526chromiumsrcoutReleaseobjppapi

    链接ppapi_gles2.lib,在E:sourcesCEF2526chromiumsrcoutReleaseobjppapi文件夹下。

    须要新建一个c文件:ppapi_hello_gles.c。

    代码生成里链接的执行库选择MD。

    源代码

    ppapi_hello_gles.c内容例如以下:

    /* Copyright (c) 2016 foruok. All rights reserved.
    * 欢迎关注我的微信订阅号“程序视界”
    */
    #include <stdint.h>
    #include <stdlib.h>
    #include <string.h>
    #include <Windows.h>
    #include <tchar.h>
    
    #include "ppapi/c/pp_completion_callback.h"
    #include "ppapi/c/pp_errors.h"
    #include "ppapi/c/pp_instance.h"
    #include "ppapi/c/pp_module.h"
    #include "ppapi/c/pp_rect.h"
    #include "ppapi/c/pp_var.h"
    #include "ppapi/c/ppb.h"
    #include "ppapi/c/ppb_core.h"
    #include "ppapi/c/ppb_instance.h"
    #include "ppapi/c/ppb_view.h"
    #include "ppapi/c/ppp.h"
    #include "ppapi/c/ppp_instance.h"
    #include "ppapi/c/ppb_input_event.h"
    #include "ppapi/c/ppp_input_event.h"
    #include "ppapi/c/ppb_graphics_3d.h"
    #include "ppapi/c/ppb_opengles2.h"
    #include "ppapi/lib/gl/include/GLES2/gl2.h"
    #include "ppapi/lib/gl/gles2/gl2ext_ppapi.h"
    
    PPB_GetInterface g_get_browser_interface = NULL;
    
    const PPB_Core* g_core_interface;
    const PPB_Graphics3D* g_graphics_3d_interface;
    const PPB_Instance* g_instance_interface;
    const PPB_View* g_view_interface;
    const PPB_InputEvent *g_input_interface;
    const PPB_MouseInputEvent *g_mouse_interface;
    
    /* PPP_Instance implementation -----------------------------------------------*/
    
    typedef struct InstanceInfo {
        PP_Instance pp_instance;
        struct PP_Size last_size;
        PP_Resource graphics;
    
        struct InstanceInfo* next;
    } InstanceInfo;
    
    /** Linked list of all live instances. */
    struct InstanceInfo* all_instances = NULL;
    
    /** Returns a refed resource corresponding to the created graphics 3d. */
    PP_Resource MakeAndBindGraphics3D(PP_Instance instance,
        const struct PP_Size* size) {
        PP_Resource graphics;
        int32_t attribs[] = { PP_GRAPHICS3DATTRIB_WIDTH, 800,
            PP_GRAPHICS3DATTRIB_HEIGHT, 800,
            PP_GRAPHICS3DATTRIB_NONE };
        graphics = g_graphics_3d_interface->Create(instance, 0, attribs);
        if (!graphics)
            return 0;
    
        if (!g_instance_interface->BindGraphics(instance, graphics)) {
            g_core_interface->ReleaseResource(graphics);
            return 0;
        }
    
        glSetCurrentContextPPAPI(graphics);
    
        return graphics;
    }
    
    void ReinitializeGraphics3D(void *user_data, int32_t result)
    {
        InstanceInfo *inst = (InstanceInfo*)user_data;
        inst->graphics = MakeAndBindGraphics3D(inst->pp_instance, &inst->last_size);
        if (inst->graphics != 0)
        {
            glSetCurrentContextPPAPI(inst->graphics);
            OutputDebugString(_T("reinitialize graphics 3d context sucess
    "));
        }
    }
    
    void FlushCompletionCallback(void* user_data, int32_t result) {
        /* Don't need to do anything here. */
        if (result == PP_ERROR_CONTEXT_LOST)
        {
            OutputDebugString(_T("PP_ERROR_CONTEXT_LOST"));
            //reinitialize context
            g_core_interface->CallOnMainThread(0, PP_MakeCompletionCallback(ReinitializeGraphics3D, user_data), 0);
        }
    }
    
    unsigned int g_colors[4] =  { 0xFF0000FF, 0xFFFF00FF, 0xFF00FFFF, 0xFF2AFE00 };
    unsigned int g_color_index = 0;
    #define GETA(clr) ((clr >> 24) & 0xFF)
    #define GETR(clr) ((clr >> 16) & 0xFF)
    #define GETG(clr) ((clr >> 8) & 0xFF)
    #define GETB(clr) (clr & 0xFF)
    
    void Repaint(struct InstanceInfo* instance, const struct PP_Size* size) {
        /* Ensure the graphics 3d is ready. */
        if (!instance->graphics) {
            instance->graphics = MakeAndBindGraphics3D(instance->pp_instance, size);
            if (!instance->graphics)
                return;
        }
    
        g_color_index++;
        if (g_color_index >= sizeof(g_colors) / sizeof(g_colors[0])) g_color_index = 0;
    
        struct PP_CompletionCallback callback = {
            FlushCompletionCallback, instance, PP_COMPLETIONCALLBACK_FLAG_NONE,
        };
    
        glViewport(0, 0, instance->last_size.width, instance->last_size.height);
        glClearColor(GETR(g_colors[g_color_index]),
            GETG(g_colors[g_color_index]),
            GETB(g_colors[g_color_index]),
            GETA(g_colors[g_color_index]));
    
        glClear(GL_COLOR_BUFFER_BIT);
        g_graphics_3d_interface->SwapBuffers(instance->graphics, callback);
    }
    
    /** Returns the info for the given instance, or NULL if it's not found. */
    struct InstanceInfo* FindInstance(PP_Instance instance) {
        struct InstanceInfo* cur = all_instances;
        while (cur) {
            if (cur->pp_instance == instance)
                return cur;
            cur = cur->next;
        }
        return NULL;
    }
    
    PP_Bool Instance_DidCreate(PP_Instance instance,
        uint32_t argc,
        const char* argn[],
        const char* argv[]) {
        struct InstanceInfo* info =
            (struct InstanceInfo*)calloc(1, sizeof(struct InstanceInfo));
        info->pp_instance = instance;
    
        /* Insert into linked list of live instances. */
        info->next = all_instances;
        all_instances = info;
    
        g_input_interface->RequestInputEvents(instance, PP_INPUTEVENT_CLASS_MOUSE);
        g_input_interface->RequestFilteringInputEvents(instance, PP_INPUTEVENT_CLASS_MOUSE);
    
        OutputDebugString(_T("Instance_DidCreate
    "));
    
        return PP_TRUE;
    }
    
    void Instance_DidDestroy(PP_Instance instance) {
        /* Find the matching item in the linked list, delete it, and patch the
        * links.
        */
        struct InstanceInfo** prev_ptr = &all_instances;
        struct InstanceInfo* cur = all_instances;
        while (cur) {
            if (instance == cur->pp_instance) {
                *prev_ptr = cur->next;
                g_core_interface->ReleaseResource(cur->graphics);
                free(cur);
                return;
            }
            prev_ptr = &cur->next;
            cur = cur->next;
        }
    }
    
    void Instance_DidChangeView(PP_Instance pp_instance,
        PP_Resource view) {
        struct PP_Rect position;
        struct InstanceInfo* info = FindInstance(pp_instance);
        if (!info)
            return;
    
        if (g_view_interface->GetRect(view, &position) == PP_FALSE)
            return;
    
        if (info->last_size.width != position.size.width ||
            info->last_size.height != position.size.height) {
            info->last_size.width = position.size.width;
            info->last_size.height = position.size.height;
            /* Got a resize, repaint the plugin. */
            Repaint(info, &position.size);
        }
    
        OutputDebugString(_T("Instance_DidChangeView
    "));
    }
    
    void Instance_DidChangeFocus(PP_Instance pp_instance, PP_Bool has_focus) {
    }
    
    PP_Bool Instance_HandleDocumentLoad(PP_Instance pp_instance,
        PP_Resource pp_url_loader) {
        return PP_FALSE;
    }
    
    static PPP_Instance instance_interface = {
        &Instance_DidCreate,
        &Instance_DidDestroy,
        &Instance_DidChangeView,
        &Instance_DidChangeFocus,
        &Instance_HandleDocumentLoad
    };
    
    PP_Bool InputEvent_HandleInputEvent(PP_Instance instance, PP_Resource input_event)
    {
        struct PP_Point pt;
        TCHAR szLog[512] = { 0 };
        switch (g_input_interface->GetType(input_event))
        {
        case PP_INPUTEVENT_TYPE_MOUSEDOWN:
            pt = g_mouse_interface->GetPosition(input_event);
            _stprintf_s(szLog, 512, _T("InputEvent_HandleInputEvent, mouse down at [%d, %d]
    "), pt.x, pt.y);
            OutputDebugString(szLog);
            break;
        default:
            return PP_FALSE;
        }
        struct InstanceInfo* info = FindInstance(instance);
        if (info && info->last_size.width > 0)
        {
            Repaint(info, &info->last_size);
        }
        return PP_TRUE;
    }
    
    static PPP_InputEvent input_interface = {
        &InputEvent_HandleInputEvent
    };
    
    /* Global entrypoints --------------------------------------------------------*/
    
    PP_EXPORT int32_t PPP_InitializeModule(PP_Module module,
        PPB_GetInterface get_browser_interface) {
        g_get_browser_interface = get_browser_interface;
    
        g_core_interface = (const PPB_Core*)
            get_browser_interface(PPB_CORE_INTERFACE);
        g_instance_interface = (const PPB_Instance*)
            get_browser_interface(PPB_INSTANCE_INTERFACE);
        g_graphics_3d_interface = (const PPB_Graphics3D*)
            get_browser_interface(PPB_GRAPHICS_3D_INTERFACE);
        g_view_interface = (const PPB_View*)
            get_browser_interface(PPB_VIEW_INTERFACE);
        g_input_interface = (const PPB_InputEvent*)get_browser_interface(PPB_INPUT_EVENT_INTERFACE);
        g_mouse_interface = (const PPB_MouseInputEvent*)get_browser_interface(PPB_MOUSE_INPUT_EVENT_INTERFACE);
    
        if (!g_core_interface || !g_instance_interface ||
            !g_graphics_3d_interface || !g_view_interface ||
            !g_input_interface || !g_mouse_interface)
            return -1;
    
        if (GL_TRUE != glInitializePPAPI(get_browser_interface))
            return -1;
    
        OutputDebugString(_T("PPP_InitializeModule
    "));
        return PP_OK;
    }
    
    PP_EXPORT void PPP_ShutdownModule() {
    }
    
    PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
        if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
        {
            OutputDebugString(_T("PPP_GetInterface, instance_interface
    "));
            return &instance_interface;
        }
        else if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0)
        {
            OutputDebugString(_T("PPP_GetInterface, input_interface
    "));
            return &input_interface;
        }
    
        return NULL;
    }
    

    代码的基本结构和ppapi_simple相似。不同的是使用了Graphics 3D接口。以下是代码中使用Graphics 3D接口的步骤:

    • 在PPP_InitializeModule中获取PPB_GRAPHICS_3D_INTERFACE接口
    • 在PPP_InitializeModule中调用glInitializePPAPI()来初始化PPAPI相关的gl环境
    • MakeAndBindGraphics3D函数创建Graphics 3D context并将其与插件实例对象绑定
    • 调用glSetCurrentContextPPAPI给ppapi的gl接口设置上下文
    • Repaint里面使用gles的接口画图

    这个演示样例只通过glClear来清除颜色缓冲区来达到变换颜色的效果。

    后面会进一步使用gles的API绘制点儿东西。

    其它參考文章:

  • 相关阅读:
    [BetterExplained]书写是为了更好的思考
    java 连接 mysql 数据库 ..password [yes]问题
    学习密度与专注力
    抠鼻屎的方法
    张飞流水账(摘)
    用 C 语言 连接 mysql (问题已解决)
    编程的首要原则(s)是什么?
    Tomat源码学习(二)(转载)
    [BetterExplained]为什么你应该(从现在开始就)写博客
    事件 代理 练习
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7058334.html
Copyright © 2011-2022 走看看