PPAPI中使用Chromium的3D图形接口

来源:互联网 发布:巴枪中通数据采集系统 编辑:程序博客网 时间:2024/05/22 09:45

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

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

项目

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

附加包含路径有些不同,如下:

  • E:\sources\CEF\2526\chromium\src\
  • E:\sources\CEF\2526\chromium\src\ppapi\lib\gl\include

附加库路径如下:

  • E:\sources\CEF\2526\chromium\src\cef\binary_distrib\cef_binary_3.2526.1364.gf6bf57b_windows32\Release
  • E:\sources\CEF\2526\chromium\src\out\Release\obj\ppapi

链接ppapi_gles2.lib,在E:\sources\CEF\2526\chromium\src\out\Release\obj\ppapi目录下。

需要新建一个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\r\n"));    }}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\r\n"));    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\r\n"));}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]\r\n"), 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\r\n"));    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\r\n"));        return &instance_interface;    }    else if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0)    {        OutputDebugString(_T("PPP_GetInterface, input_interface\r\n"));        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绘制点儿东西。

其他参考文章:

  • CEF Windows开发环境搭建
  • CEF加载PPAPI插件
  • VS2013编译最简单的PPAPI插件
  • 理解PPAPI的设计
  • PPAPI插件与浏览器的交互过程
  • Windows下从源码编译CEF
  • 编译PPAPI的media_stream_video示例
  • PPAPI插件的绘图与输入事件处理
  • 在PPAPI插件中创建本地窗口
  • PPAPI插件与浏览器的通信
  • Windows下从源码编译Skia
  • 在PPAPI插件中使用Skia绘图
  • 加载DLL中的图片资源生成Skia中的SkBitmap对象
  • PPAPI+Skia实现的涂鸦板
1 0
原创粉丝点击