码迷,mamicode.com
首页 > Windows程序 > 详细

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

时间:2016-01-22 22:12:34      阅读:421      评论:0      收藏:0      [点我收藏+]

标签:

使用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绘制点儿东西。

其他参考文章:

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

标签:

原文地址:http://blog.csdn.net/foruok/article/details/50563676

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!