多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
使用PPAPI的Graphics 3D接口做了一个小示例,鼠标点击插件区域,绘制颜色,效果与ppapi_simple类似。 > foruok原创,如需转载请关注foruok的微信订阅号“程序视界”联系foruok。 # 项目 项目与[**VS2013编译最简单的PPAPI插件**](http://blog.csdn.net/foruok/article/details/50485461)这篇文章里说的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开发环境搭建**](http://blog.csdn.net/foruok/article/details/50468642) - [**CEF加载PPAPI插件**](http://blog.csdn.net/foruok/article/details/50485448) - [**VS2013编译最简单的PPAPI插件**](http://blog.csdn.net/foruok/article/details/50485461) - [**理解PPAPI的设计**](http://blog.csdn.net/foruok/article/details/50486788) - [**PPAPI插件与浏览器的交互过程**](http://blog.csdn.net/foruok/article/details/50494061) - [**Windows下从源码编译CEF**](http://blog.csdn.net/foruok/article/details/50498740) - [**编译PPAPI的media_stream_video示例**](http://blog.csdn.net/foruok/article/details/50498873) - [**PPAPI插件的绘图与输入事件处理**](http://blog.csdn.net/foruok/article/details/50499813) - [**在PPAPI插件中创建本地窗口**](http://blog.csdn.net/foruok/article/details/50513228) - [**PPAPI插件与浏览器的通信**](http://blog.csdn.net/foruok/article/details/50513315) - [**Windows下从源码编译Skia**](http://blog.csdn.net/foruok/article/details/50524726) - [**在PPAPI插件中使用Skia绘图**](http://blog.csdn.net/foruok/article/details/50526110) - [**加载DLL中的图片资源生成Skia中的SkBitmap对象**](http://blog.csdn.net/foruok/article/details/50543762) - [**PPAPI+Skia实现的涂鸦板**](http://blog.csdn.net/foruok/article/details/50547737)