用skia实现2D绘制
skia是谷歌的一个开源2D引擎,用来实现利用CPU实现2D图形绘制。
下面是老朽写的一个例程,实现功能如下:
1.窗口的创建
2.图片解码
3.在窗口的任意位置绘制指定大小和透明度的图片
4.绘制文字
因为对OpenGL熟悉,所以不怎么喜欢用SDL,而是采用OpenGL创建绘制窗口。先由glfw创建窗口,然后skia负责渲染,最后opengl只负责将skia传过来的pixel画出来。
main函数如下
//
// Created by czh on 18-10-31.
//#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "window.h"
#include "dconfig.h"Window blizzard(SCREEN_WIDTH, SCREEN_HEIGHT);void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mode) {if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);if (key >= 0 && key < 1024) {if (action == GLFW_PRESS)blizzard.keys[key] = GL_TRUE;else if (action == GLFW_RELEASE)blizzard.keys[key] = GL_FALSE;}
}int main() {glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);GLFWwindow *window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Blizzard", nullptr, nullptr);glfwMakeContextCurrent(window);glfwSetKeyCallback(window, keyCallback);gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);blizzard.init();while (!glfwWindowShouldClose(window)) {clock_t start = clock();glClearColor(0.0f, 0.0f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);blizzard.processInput();blizzard.update();blizzard.render(window);glfwSwapBuffers(window);glfwPollEvents();
#define FPS 1000/33clock_t end = clock();int time_ms = (double) (end - start) / CLOCKS_PER_SEC * 1000;printf("#Render time: %d\n", time_ms);if ((FPS - time_ms) > 0) {usleep((FPS - time_ms) * 1000);}}glfwTerminate();return 0;
}
下面是头文件window.h
//
// Created by czh on 18-10-31.
//#ifndef OPENGL_PRO_WINDOW_H
#define OPENGL_PRO_WINDOW_H#include <game.h>
#include "calib/zhu.h"
#include <calib/checkerborad.h>
#include <calib/colormap.h>
#include <calib/zhang.h>
#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkPicture.h>
#include <SkTypeface.h>
#include <SkStream.h>
#include <SkCodec.h>
#include <SkAndroidCodec.h>
#include <SkImage.h>class Window : public Game {
public:SpriteRenderer *spriteRender;sk_sp<SkTypeface> font;SkBitmap bmMaster;sk_sp<SkImage> image;SkCanvas *canvas;sk_sp<SkImage> imageServant;SkBitmap bmServant;cv::VideoCapture capture;Window(GLuint width, GLuint height);void init();void destory();void processInput();void update();void render(GLFWwindow *window);SkBitmap loadTexture2DToSkBitmap( std::string file);sk_sp<SkImage> loadTexture2DToSkImage(std::string file);void draw(SkCanvas *canvas, sk_sp<SkImage> image, int posX, int posY, int sizeX, int sizeY, uchar alpha = 0xff);void draw(SkCanvas *canvas, SkBitmap bitmap, int posX, int posY, int sizeX, int sizeY, uchar alpha = 0xff);void drawFront(SkCanvas *canvas, std::string text, int posX, int posY, float size, uint color, uchar alpha = 0xff);
};#endif //OPENGL_PRO_WINDOW_H
最后是window.cpp
//
// Created by czh on 18-10-31.
//#include "window.h"Window::Window(GLuint width, GLuint height) : Game(width, height) {canvas = nullptr;
}void Window::init() {StatusManager::renderMode = Render_2D;StatusManager::init();this->state = GAME_ACTIVE;ResourceManager::loadShader("sprite", ResourceManager::defaultVshader2D, ResourceManager::defaultFshader2D);spriteRender = new SpriteRenderer();spriteRender->init(ResourceManager::getShader("sprite"));glm::mat4 projection = glm::mat4(1.0f);projection = glm::ortho(0.0f, static_cast<GLfloat>(this->width), static_cast<GLfloat>(this->height), 0.0f,-1.0f, 1.0f);glm::mat4 model = glm::mat4(1.0f);model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));//movemodel = glm::rotate(model, glm::radians(0.0f), glm::vec3(0.0f, 0.0f, 1.0f));//rotatemodel = glm::scale(model, glm::vec3(SCREEN_WIDTH, SCREEN_HEIGHT, 1.0f)); //scaleResourceManager::getShader("sprite").setMatrix4("projection", projection);ResourceManager::getShader("sprite").setMatrix4("model", model);ResourceManager::getShader("sprite").setVector3f("spriteColor", glm::vec3(1.0, 1.0, 1.0));bmMaster.allocPixels(SkImageInfo::Make(1920, 720, kN32_SkColorType, kPremul_SkAlphaType));bmMaster.eraseColor(0xFF000000);canvas = new SkCanvas(bmMaster);//imageServant = loadTexture2DToSkImage("../res/colorMap.png");bmServant = loadTexture2DToSkBitmap("../res/colorMap.png");
}void Window::destory() {Game::destroy();
}void Window::processInput() {}SkBitmap Window::loadTexture2DToSkBitmap(std::string file) {clock_t start = clock();SkBitmap bitmap;SkString path(file.c_str());sk_sp<SkData> data = SkData::MakeFromFileName(path.c_str());if (!data) {printf("Missing file %s", path.c_str());}auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)));SkImageInfo info = codec->getInfo();bitmap.allocPixels(SkImageInfo::Make(info.width(), info.height(), kN32_SkColorType, kPremul_SkAlphaType));SkCodec::Result result = codec->getPixels(info, bitmap.getPixels(), bitmap.rowBytes());if (result == SkCodec::kSuccess) {printf("#Codec success\n");} else {printf("#Codec failure\n");}clock_t end = clock();int time_ms = (double) (end - start) / CLOCKS_PER_SEC * 1000;printf("#loadTexture2DToSkBitmap time: %d\n", time_ms);return bitmap;
}sk_sp<SkImage> Window::loadTexture2DToSkImage(std::string file) {clock_t start = clock();sk_sp<SkData> data = SkData::MakeFromFileName(file.c_str());sk_sp<SkImage> image = SkImage::MakeFromEncoded(data);clock_t end = clock();int time_ms = (double) (end - start) / CLOCKS_PER_SEC * 1000;printf("#loadTexture2DToSkImage time: %d\n", time_ms);return image;
}void Window::draw(SkCanvas *canvas, sk_sp<SkImage> image, int posX, int posY, int sizeX, int sizeY, uchar alpha) {SkRect rect;rect.setXYWH(posX, posY, posX + sizeX, posY + sizeY);SkPaint paint;paint.setAlpha(alpha);canvas->drawImageRect(image, rect, &paint);
}void Window::draw(SkCanvas *canvas, SkBitmap bitmap, int posX, int posY, int sizeX, int sizeY, uchar alpha) {SkRect rect;rect.setXYWH(posX, posY, posX + sizeX, posY + sizeY);SkPaint paint;paint.setAlpha(alpha);canvas->drawBitmapRect(bitmap, rect, &paint);
}void Window::drawFront(SkCanvas *canvas, std::string text, int posX, int posY, float size, uint color, uchar alpha) {SkPaint paint;paint.setARGB(uchar(color >> 24), uchar(color >> 16), uchar(color >> 8), (uchar)color);paint.setTypeface(SkTypeface::MakeFromFile("../res/fangsong.ttf"));paint.setTextSize(size);paint.setAlpha(alpha);std::string title(text.c_str());canvas->drawText(title.c_str(), title.length(), posX, posY, paint);
}void Window::update() {canvas->clear(0x00000000);static int i = 0;//1.0 decode with bitmapdraw(canvas, bmServant, 0, 0, 1920, 720, 0xff);drawFront(canvas, "abcd12341234哈哈哈", 100, 50, 25, 0xffff0000, 0xff);ResourceManager::loadTexture2D("codec_data", (uchar *) bmMaster.getPixels(), bmMaster.width(), bmMaster.height(), 4);//2.0 decode with image//draw(canvas, imageServant, 0, 0, 1920, 720, 0xff);//drawFront(canvas, "123456789", 100, 50, 25, 0xffff0000, 0xff);//ResourceManager::loadTexture2D("codec_data", (uchar *) bmMaster.getPixels(), bmMaster.width(), bmMaster.height(), 4);
}void Window::render(GLFWwindow *window) {if (this->state == GAME_ACTIVE) {spriteRender->drawSprite(ResourceManager::getTexture2D("codec_data"));usleep(1000 * 30);}
}
效果如图
用skia实现2D绘制相关推荐
- Github 每日精选:可在Java 中绑定 skia 的 2D 图形库Skija;自动对对联系统seq2seq-couplet
大家好,我是开源菌!天气转凉,有点不想打字,但依然阻挡不了我给大家安利开源项目的冲动.刚刚瞄了一眼今天的榜单,重新上架的 youtube-dl 插件再次登顶第一宝座,好不威风. 1.Skija:可在J ...
- 2d绘制 c# dx_C# 从零开始写 SharpDx 应用 绘制基础图形
本文告诉大家通过 SharpDx 画出简单的 2D 界面 本文属于 SharpDx 系列 博客,建议从头开始读 本文分为两步,第一步是初始化,第二步才是画界面 初始化 先创建 RenderForm 用 ...
- 微信小程序 canvas type = 2d 绘制海报心得(包括怎么绘制图片和圆角图片和圆角矩形等)
微信小程序 canvas type=2d 使用心得 为了方便这里我封装成了一个component 然后说说怎么使用最新的方法(使用方法类似于html中的canvas可以进行参考)获取--canvas ...
- 使用Java 2D绘制黑白太极图案
一:基本原理 利用Java 2D的Area对象对绘制形状几何操作的支持,完成太极图案的绘制,使用Paint来 完成对不同颜色的填充.Java 2D图形API Area对Shape支持四种几何操作: - ...
- 微信小程序canvas 2d 绘制图片与文字 导出图片
wxml内容 如下 <canvas id="myCanvas" type="2d"style="width: {{ canvas.width } ...
- 小程序 canvas 2d 绘制海报
效果图 canvas api 准备 绘制图片 context.drawImage(image, dx, dy, dWidth, dHeight); image:绘制在Canvas上的元素,可以是各类C ...
- 小程序 canvas 2d 绘制图片并保存
获取canvas实例,使用的官方的代码.用一个变量canvas保存实例,后续保存时会调用. data () {return {canvas: null // 实例} }, onReady() {con ...
- Unity 依据Polygon Collider 2D 绘制 mesh
参考文章: mesh的简介 创建mesh 简单多边形三角化(暴力)(削耳朵) 偶尔需要依据多边形创建平面mesh,所以在网上浏览了很多资料,再修修补补才凑出一段代码. [ContextMenu(&qu ...
- Quart 2D 绘制图形简单总结
0 CGContextRef context = UIGraphicsGetCurrentContext(); 设置上下文 1 CGContextMoveToPoint 开始画线 2 CGConte ...
最新文章
- Protocol Buffers 在 iOS 中的使用
- jQuery 事件绑定
- python中5个json库的速度对比
- threadpoolexecutor参数_ThreadPoolExecutor的使用
- angularjs--控制器的显示与隐示使用
- Terracotta - 分布式共享对象
- 1、java 的安装及资料下载
- brctl 命令详解
- 为什么闹钟设置了却不响_手机闹钟不响是怎么回事 怎么设置闹钟【图文】
- plot函数二维绘图
- 照片制作手机壳,定制手机壳diy需要什么设备?
- 卡尔曼滤波Kalman Filtering:介绍
- 保姆式RecyclerView下拉刷新、上拉加载更多Kotlin
- 气象绘图(二)——散点图
- 玩转百度即用API(5)——空气质量指数查询
- 基于android平台的条码扫描软件的设计与实现,基于android平台的条码扫描软件的设计与实现...
- 细述个人建站那点心酸往事
- ico图标和制作网站(比特虫)
- java计算三角形的外心_hdu 6006(java 大数,三角形的外心)
- eclipse如何去掉无用的validation、优化eclipse