android native 使用opengl es画点线面图形(纯c++)

2023-11-16

一、首先需要对EGL进行初始化:

void Renderer::initEGL()
{
    const EGLint attribs[] =
    { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8,
            EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_NONE };
    EGLint width, height, format;
    EGLint numConfigs;
    EGLConfig config;
    EGLSurface surface;
    EGLContext context;

    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    eglInitialize(display, 0, 0);

    eglChooseConfig(display, attribs, &config, 1, &numConfigs);

    //instance->surface = eglCreateWindowSurface(instance->display, instance->config[0], WindowTypes, NULL);
    surface = eglCreateWindowSurface(display, config, mWindow, NULL);
    EGLint attrs[] =
    { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
    context = eglCreateContext(display, config, NULL, attrs);

    if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
    {
        printf("------EGL-FALSE\n");
        return;
    }

    eglQuerySurface(display, surface, EGL_WIDTH, &width);
    eglQuerySurface(display, surface, EGL_HEIGHT, &height);

    mDisplay = display;
    mSurface = surface;
    mContext = context;
    mWidth = width;
    mHeight = height;
    printf("width:%d, height:%d\n", mWidth, mHeight);

}

EGL 是 OpenGL ES 和底层 Native 平台视窗系统之间的接口,主要是为了保证opengl es的平台独立性,EGL可以理解为一块一块画布,提供给

OpengGL ES来绘图。

display用来获取默认的显示设备,可以理解为显示屏幕。surface可以理解为使用native创建的java层中的surface。

比较重要的是:eglMakeCurrent(display, surface, surface, context),主要告诉设备在这个surface上面绘制图像,经过测试,创建多个surface,

然后决定在哪个surface上面绘制图像就由这个函数来决定。


二、模仿java层的glsurface进行初始化以及绘制:

void Renderer::nativeSurfaceCreated()
{
    printf("nativeSurfaceCreated\n");
    int program = 0;
    
    glClearColor(0.0f, 0.0f, 0.0f, 0.3f);
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);

    program = glutil->createProgram(vertexShaderCode, fragmentShaderCode);
    glUseProgram(program);
    aColorLocation = glGetAttribLocation(program, A_COLOR);
    aPositionLocation = glGetAttribLocation(program, A_POSITION);
    glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, STRIDE, tableVerticesWithTriangles);
    
    glEnableVertexAttribArray(aPositionLocation);
    glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT, false, STRIDE, tableVerticesWithTriangles + POSITION_COMPONENT_COUNT);
    glEnableVertexAttribArray(aColorLocation);
}

glClearColor主要是把画布初始化设置颜色,参数就是RGBA,范围都是0.0-1.0,后面的glClear(GL_COLOR_BUFFER_BIT)才是绘制的主要

函数;

createProgram是自己写的作为编译连接glsl语言,主要就是运行在GPU上面的语言,主要的顶点以及颜色信息就是在这个里面运算渲染;

aColorLocation就是获取program中的句柄,使用glVertexAttribPointer对其进行赋值交给GPU去运算,告诉GPU渲染的颜色,COLOR_COMPONENET

是读取颜色的长度,也就是在后面的数组中读取颜色,STRIDE也是自己定义的每次读取需要偏移的位数,最后一个参数是确定从哪里开始读取;

aPositionLocation是告诉GPU在哪些顶点去渲染;

glEnableVertexAttribArray就是使句柄生效。

void Renderer::nativeSurfaceChanged(EGLint width, EGLint height)
{
    glViewport(0, 0, width, height);
}
这个可以理解为java层的Render中的SurfaceChanged;

void Renderer::nativeDraw()
{
    //printf("nativeDraw!!!\n");
    //glClearColor(0.3f, 0.0f, 0.0f, 0.3f);
    glClear(GL_COLOR_BUFFER_BIT);
    
    glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
    glDrawArrays(GL_LINES, 6, 2);
    glDrawArrays(GL_POINTS, 8, 2);
    glDrawArrays(GL_POINTS, 9, 1);
}
const GLfloat tableVerticesWithTriangles[] =
{
     0.0f,  0.0f, 1.0f, 1.0f, 1.0f,
    -0.5f, -0.5f, 0.7f, 0.7f, 0.7f,
     0.5f, -0.5f, 0.7f, 0.7f, 0.7f,
     0.5f,  0.5f, 0.7f, 0.7f, 0.7f,
    -0.5f,  0.5f, 0.7f, 0.7f, 0.7f,
    -0.5f, -0.5f, 0.7f, 0.7f, 0.7f,

    // Line 1
    -0.5f, 0.0f, 1.0f, 1.0f, 1.0f,
     0.5f, 0.0f, 0.0f, 0.0f, 0.0f,

    // Mallets
    0.0f, -0.25f, 1.0f, 0.0f, 0.0f,
    0.0f,  0.25f, 0.0f, 1.0f, 0.0f
};
这个就是具体绘制的函数,首先绘制两个三角形,在本程序中就是绘制了一个长方形,从以上的数组中第0个开始的六个点确定了这两个三角形

的位置信息,也就是(0.0f, 0.0f),( -0.5f,-0.5),(0.5, -0.5),(0.5, 0.5),(-0.5,0.5),(-0.5, -0.5),偏移量是由上面的surfaceCreate

中已经确定,每个点后面的三个值是RGB值,A默认为1;

这个就是最终运行效果图:

后面贴一下主要的代码:

/*main.cpp*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <sys/prctl.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>

#include "GLUtil.h"
#include "Renderer.h"

using namespace android;

int main(int argc, char ** argv)
{
    Renderer * mRenderer = NULL;
    
    mRenderer = new Renderer();

    //mRenderer->start();
    EGLNativeWindowType WindowTypes = (EGLNativeWindowType) mRenderer->glutil->getNativeWindow(800, 600, 100, 100, 0);
    mRenderer->requestInitEGL(WindowTypes);

    while(1)
        mRenderer->requestRenderFrame();
    
    mRenderer->requestDestroy();
    ANativeWindow_release(WindowTypes);
    delete mRenderer;
    return 0;
}
Render.cpp:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <sys/prctl.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <GLES3/gl3.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>

#include "GLUtil.h"
#include "Renderer.h"

const char * vertexShaderCode = 
    "attribute vec4 a_Position;"
    "attribute vec4 a_Color;"
    "varying vec4 v_Color;"
    "void main(){"
        "v_Color = a_Color;"
        "gl_Position = a_Position;"
        "gl_PointSize = 10.0;}";

const char * fragmentShaderCode =         
        "precision mediump float;"
        "varying vec4 v_Color;"
        "void main(){"
            "gl_FragColor = v_Color;}";

#define COLOR_COMPONENT_COUNT 3
#define POSITION_COMPONENT_COUNT 2
#define STRIDE ((COLOR_COMPONENT_COUNT + POSITION_COMPONENT_COUNT) * 4)
#define A_COLOR "a_Color"
#define A_POSITION "a_Position"

const GLfloat tableVerticesWithTriangles[] =
{
     0.0f,  0.0f, 1.0f, 1.0f, 1.0f,
    -0.5f, -0.5f, 0.7f, 0.7f, 0.7f,
     0.5f, -0.5f, 0.7f, 0.7f, 0.7f,
     0.5f,  0.5f, 0.7f, 0.7f, 0.7f,
    -0.5f,  0.5f, 0.7f, 0.7f, 0.7f,
    -0.5f, -0.5f, 0.7f, 0.7f, 0.7f,

    // Line 1
    -0.5f, 0.0f, 1.0f, 1.0f, 1.0f,
     0.5f, 0.0f, 0.0f, 0.0f, 0.0f,

    // Mallets
    0.0f, -0.25f, 1.0f, 0.0f, 0.0f,
    0.0f,  0.25f, 0.0f, 1.0f, 0.0f
};

Renderer::Renderer()
{
    //pthread_mutex_init(&mMutex, NULL);
    //pthread_cond_init(&mCondVar, NULL);
    mDisplay = EGL_NO_DISPLAY;
    mSurface = EGL_NO_SURFACE;
    mContext = EGL_NO_CONTEXT;
    glutil = new GLUtil();
}

Renderer::~Renderer()
{
    //pthread_mutex_destroy(&mMutex);
    //pthread_cond_destroy(&mCondVar);
}

void Renderer::start()
{
    pthread_create(&mThread, NULL, startRenderThread, this);
}

void Renderer::requestInitEGL(EGLNativeWindowType pWindow)
{
    //pthread_mutex_lock(&mMutex);
    mWindow = pWindow;
    //mEnumRenderEvent = RE_SURFACE_CHANGED;
    initEGL();
    nativeSurfaceCreated();
    nativeSurfaceChanged(mWidth, mHeight);

    //pthread_mutex_unlock(&mMutex);
    //pthread_cond_signal(&mCondVar);
}
void Renderer::requestRenderFrame()
{
    //pthread_mutex_lock(&mMutex);
    mEnumRenderEvent = RE_DRAW_FRAME;
    nativeDraw();
    eglSwapBuffers(mDisplay, mSurface);
    //pthread_mutex_unlock(&mMutex);
    //pthread_cond_signal(&mCondVar);
}

void Renderer::requestDestroy()
{
    //pthread_mutex_lock(&mMutex);
    //mEnumRenderEvent = RE_EXIT;
    terminateDisplay();
    mISRenderering = false;
    //pthread_mutex_unlock(&mMutex);
    //pthread_cond_signal(&mCondVar);
}

void Renderer::onRenderThreadRun()
{
    mISRenderering = true;
    while (mISRenderering)
    {
        //pthread_mutex_lock(&mMutex);
        // 姣忓畬鎴愪竴涓簨浠跺氨wait鍦ㄨ繖閲岀洿鍒版湁鍏朵粬浜嬩欢鍞ら啋
        //pthread_cond_wait(&mCondVar, &mMutex);

        printf("-------this mEnumRenderEvent is %d\n", mEnumRenderEvent);
        switch (mEnumRenderEvent)
        {
            case RE_SURFACE_CHANGED:
                printf("-------case RE_SURFACE_CHANGED\n");
                //mEnumRenderEvent = RE_NONE;
                //pthread_mutex_unlock(&mMutex);
                initEGL();
                nativeSurfaceCreated();
                nativeSurfaceChanged(mWidth, mHeight);
                break;
            case RE_DRAW_FRAME:
                //mEnumRenderEvent = RE_NONE;
                //pthread_mutex_unlock(&mMutex);
                // draw
                nativeDraw();
                eglSwapBuffers(mDisplay, mSurface);
                break;
            case RE_EXIT:
                //mEnumRenderEvent = RE_NONE;
                //pthread_mutex_unlock(&mMutex);
                terminateDisplay();
                mISRenderering = false;
                break;
            //default:
                //mEnumRenderEvent = RE_NONE;
                //pthread_mutex_unlock(&mMutex);
        }
    }
}
void *Renderer::startRenderThread(void * pVoid)
{
    Renderer * render = (Renderer*) pVoid;
    render->onRenderThreadRun();

    return NULL;
}

void Renderer::initEGL()
{
    const EGLint attribs[] =
    { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8,
            EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_NONE };
    EGLint width, height, format;
    EGLint numConfigs;
    EGLConfig config;
    EGLSurface surface;
    EGLContext context;

    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    eglInitialize(display, 0, 0);

    eglChooseConfig(display, attribs, &config, 1, &numConfigs);

    //instance->surface = eglCreateWindowSurface(instance->display, instance->config[0], WindowTypes, NULL);
    surface = eglCreateWindowSurface(display, config, mWindow, NULL);
    EGLint attrs[] =
    { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
    context = eglCreateContext(display, config, NULL, attrs);

    if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
    {
        printf("------EGL-FALSE\n");
        return;
    }

    eglQuerySurface(display, surface, EGL_WIDTH, &width);
    eglQuerySurface(display, surface, EGL_HEIGHT, &height);

    mDisplay = display;
    mSurface = surface;
    mContext = context;
    mWidth = width;
    mHeight = height;
    printf("width:%d, height:%d\n", mWidth, mHeight);

}

void Renderer::terminateDisplay()
{
    if (mDisplay != EGL_NO_DISPLAY)
    {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
                EGL_NO_CONTEXT);
        if (mContext != EGL_NO_CONTEXT)
        {
            eglDestroyContext(mDisplay, mContext);
        }
        if (mSurface != EGL_NO_SURFACE)
        {
            eglDestroySurface(mDisplay, mSurface);
        }
        eglTerminate(mDisplay);
    }

    mDisplay = EGL_NO_DISPLAY;
    mSurface = EGL_NO_SURFACE;
    mContext = EGL_NO_CONTEXT;
}
int program = 0;
int angle = 0;
void Renderer::nativeSurfaceCreated()
{
#if 1
    printf("nativeSurfaceCreated\n");
    int program = 0;
    
    glClearColor(0.0f, 0.0f, 0.0f, 0.3f);
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);

    program = glutil->createProgram(vertexShaderCode, fragmentShaderCode);
    glUseProgram(program);
    aColorLocation = glGetAttribLocation(program, A_COLOR);
    aPositionLocation = glGetAttribLocation(program, A_POSITION);
    glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, STRIDE, tableVerticesWithTriangles);
    
    glEnableVertexAttribArray(aPositionLocation);
    glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT, false, STRIDE, tableVerticesWithTriangles + POSITION_COMPONENT_COUNT);
    glEnableVertexAttribArray(aColorLocation);
#else
    //int program = 0;
    glClearColor(0.0f, 0.0f, 0.0f, 0.3f);
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    program = glutil->createProgram(vertexShaderCode, fragmentShaderCode);
    //glViewport(0, 0, width, height);

    glUseProgram(program);
#endif
}

void Renderer::nativeSurfaceChanged(EGLint width, EGLint height)
{
    glViewport(0, 0, width, height);
}

void Renderer::nativeDraw()
{
    //printf("nativeDraw!!!\n");
    //glClearColor(0.3f, 0.0f, 0.0f, 0.3f);
    glClear(GL_COLOR_BUFFER_BIT);
    
    glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
    glDrawArrays(GL_LINES, 6, 2);
    glDrawArrays(GL_POINTS, 8, 2);
    glDrawArrays(GL_POINTS, 9, 1);
}
EGLNativeWindowType GLUtil::getNativeWindow(int width, int hight, int position_x, int position_y, int type)
{
    DisplayInfo dinfo;
    
    mComposerClient = new SurfaceComposerClient();
    sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
                        ISurfaceComposer::eDisplayIdMain));

    status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
    printf("w=%d,h=%d,xdpi=%f,ydpi=%f,fps=%f,ds=%f\n", 
                dinfo.w, dinfo.h, dinfo.xdpi, dinfo.ydpi, dinfo.fps, dinfo.density);

    mSurfaceControl = mComposerClient->createSurface(
        String8("Test Surface"),
        dinfo.w, dinfo.h,
        PIXEL_FORMAT_RGBA_8888, 0);

    SurfaceComposerClient::openGlobalTransaction();
    mSurfaceControl->setLayer(100000);//设定Z坐标
    mSurfaceControl->setPosition(position_x, position_y);
    mSurfaceControl->setSize(width, hight);

    SurfaceComposerClient::closeGlobalTransaction();

    sp<ANativeWindow> window = mSurfaceControl->getSurface();

    return window.get();
}


void GLUtil::disposeNativeWindow(void)
{
    if (mComposerClient != NULL) 
    {
        mComposerClient->dispose();
        mComposerClient = NULL;
        mSurfaceControl = NULL;
    }
}

以上代码为部分代码,程序的编译需要在android源码编译环境中编译,这个会比较麻烦,我提供一个编译好的可以试着在android中运行一下,

看看效果:opengl_test

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android native 使用opengl es画点线面图形(纯c++) 的相关文章

  • EGL Context 创建

    继续 EGL context 创建的分析 eglInitialize 来看 EGL10 eglInitialize 的实现 com google android gles jni EGLImpl 中 xff0c 这个方法的实现如下 xff1
  • EGL在PC和移动端上的支持共享上下文环境情况

    PC端 xff1a 不支持共享上下文 移动端 xff1a 支持共享上下文
  • OpenGL ES 3.0 开发(一)

    什么是 OpenGLES OpenGLES 全称 OpenGL for Embedded Systems 是三维图形应用程序接口 OpenGL 的子集 本质上是一个跨编程语言 跨平台的编程接口规范 主要应用于嵌入式设备 如手机 平板等 由科
  • Android中opengles,egl库的结构

    目录 egl opengl es的软硬件实现 需要的库 库的分工 加载模块 软件实现模块 硬件实现模块 egl opengl es的软硬件实现 需要的库 算是android中的egl库 用来加载具体的实现 软件实现或者硬件实现 system
  • Cocos2dx-OpenGL ES2.0教程:初识MVP(3)

    在上一篇文章中 我在介绍vertex shader的时候挖了一个坑 CC MVPMatrix 它其实是一个uniform 每一个cocos2d x预定义的shader都包含有这个uniform 但是如果你在shader里面不使用这个变量的话
  • Mali GPU OpenGL ES 应用性能优化--测试+定位+优化流程

    1 使用DS 5 Streamline定位瓶颈 DS 5 Streamline要求GPU驱动启用性能测试 在Mali GPU驱动中激活性能测试对性能影响微不足道 1 1 DS 5 Streamline简介 可使用DS 5 Streamlin
  • GLSL(着色器语言)

    GLSL 着色器语言 简介 OpenGLES的着色器语言GLSL是一种高级的图形化编程语言 其源自应用广泛的C语言 与传统的c语言不同的是 它提供了更加丰富的针对于图像处理的原生类型 诸如向量 矩阵之类 OpenGLES 主要包含以下特性
  • android native 使用opengl es画点线面图形(纯c++)

    一 首先需要对EGL进行初始化 void Renderer initEGL const EGLint attribs EGL SURFACE TYPE EGL WINDOW BIT EGL BLUE SIZE 8 EGL GREEN SIZ
  • 【OPENGLES】opengles-jni实例1

    首先 说明下为什么要用jni实现opengl es 在进行移动端图像算法开发的过程中 需要完成对大量的数据进行处理 opengl是在进行图形渲染或者大批量图像运算处理时有着很大的优势 如果能够在算法库开发中加入opengl 则对于提升算法运
  • Cocos2dx-OpenGL ES2.0教程:编写自己的shader(2)

    在上篇文章中 我给大家介绍了如何在cocos2d x里面绘制一个三角形 当时我们使用的是cocos2d x引擎自带的shader和一些辅助函数 在本文中 我将演示一下如何编写自己的shader 同时 我们还会介绍VBO 顶点缓冲区对象 和V
  • 在Android下初始化Native OpenGL ES

    在上一篇文章中 介绍了在Android Native层初始化EGL及OpenGL ES的方法 其中 大量代码花费在EGL的初始化上面 非常的麻烦 在本文中 将展示利用GLSurfaceView来代替我们手动初始化EGL的过程 用GLSurf
  • OpenGL ES 2.0升级到3.0配置win32环境以及编译所遇bug

    安装win32平台的OpenGL ES 3 0模拟器 一 安装3 0模拟器 一般用32位的 https developer arm com products software development tools graphics devel
  • 如何在android ndk中使用GraphicBuffer

    我问这个问题是参考我的问题的答案如何提高android中opengl es的显示性能 我试图构建使用 GraphicBuffer 和 ndk r9d 的代码 但它说 GraphicBuffer 没有在此范围内声明 对于eglCreateIm
  • 创建窗口表面失败:EGL_BAD_MATCH?

    Android 版本是 2 2 1 设备是三星 Galaxy II 完整的崩溃日志是 java lang RuntimeException createWindowSurface failed EGL BAD MATCH at androi
  • 使用 GraphicBuffers 快速读取纹理

    我正在编写一些使用着色器在 Android 上运行一些 GPGPU 代码的代码 通常是一个Framebuffer使用因此计算结果存储在纹理中 输入数据通常也是纹理 为了提高性能 最好摆脱glTexImage2D and glReadPixe
  • Android EGL/OpenGL ES 帧率卡顿

    TL DR 即使根本不进行任何绘制 在 Android 设备上的 OpenGL ES 渲染线程上保持 60Hz 的更新率似乎也是不可能的 神秘的峰值经常出现 在底部的代码中演示 而我为找出原因或如何导致的一切努力都导致了死胡同 在使用自定义
  • GBM 上的 EGLDisplay

    我想通过 EGL 创建 OpenGL 上下文 由于我实际上不会绘图 所以我想将 Pbuffers 与 GBM 平台结合使用 这是代码 C99 include
  • EGL 链接器错误

    我正在尝试在 Ubuntu Trusty 系统上使用 g 4 9 1 链接一个非常简单的 GLES2 和 EGL 程序 我正在使用台面库 我收到 EGL 函数的链接器错误 test cpp text 0x342 undefined refe
  • 在 Android 中选择 EGL 配置的正确方法是什么?

    我正在使用自己的 GLSurfaceView 并且一段时间以来一直在努力解决与 EGL 配置选择器相关的崩溃问题 似乎通过调用请求 RGB 565setEGLConfigChooser 5 6 5 0 16 0 应该是最受支持的 然而 使用
  • OPENGL ES 不工作:无当前上下文

    我尝试了 OpenGL ES2 for Android 一书中所示的程序 但它不起作用 我已经在Odroid E 三星s3 三星y 三星star上进行了测试 the gl version suported returns 2 but i g

随机推荐

  • 标识符和关键字的规则

    大家好 我是耀曜 这段事件没有怎么更新文章 主要是最近换工作 有一年的工作经验 说白了就是一个初级Java后端开发的新手 这段时间面了很多家 我也很纳闷问的都是基础差不多都忘掉了的 以后这段事间耀曜会发布一些关于面试的问题的总结 希望对看到
  • Android 数据的保存,检索,删除之Cursor

    今天遇到的一个问题是如何将数据删除后 将原来的id也相应的做改变呢 如果说对其id值进行逐个修改这也是可以的 但是当数据增多的时候 我们这么做就会很大程度上的降低程序的性能 所以我们想到的就是不要根据id的检索来获取数据库中的值 因为这样做
  • face-api.js中加入MTCNN:进一步支持使用JS实时进行人脸跟踪和识别

    如果你现在正在阅读这篇文章 那么你可能已经阅读了我的介绍文章 JS使用者福音 在浏览器中运行人脸识别 或者之前使用过face api js 如果你还没有听说过face api js 我建议你先阅读介绍文章再回来阅读本文 和往常一样 本文中为
  • C++实现顺序表与链表

    C 实现顺序表与链表 一 顺序表 之前已经对顺序表有了了解 需要注意的是读者如果疑惑以下代码没有实现头插与头删 是因为代码中任意插入与删除这两个函数可以实现此功能 下面有测试代码 读者也可以自行测试 代码如下 include
  • 手把手教你安装MINIGUI编程环境 (MINIGUI版本3.2.0)

    0 MINIGUI MiniGUI 是一款面向嵌入式系统的高级窗口系统 Windowing System 和图形用户界面 Graphical User Interface GUI 支持系统 由魏永明先生于 1998 年底开始开发 2002
  • Pycharm如何选择自动打开或不打开最近项目

    如下图
  • 【Milvus的安装和使用】

    0 介绍 milvus是一个用于存储 index索引和管理巨量由深度学习网络或者其他模型生成embedding vectors的工具 不同于常见的关系型数据库用来处理结构化数据 Milvus被设计用来处理由非结构化数据 如图像 音频等 生成
  • 超链接打不开是什么原因html,超链接打不开是什么原因

    演示工具 电脑型号 华硕adolbook14 2020 系统版本 windows10 具体原因及解决方法 1 如果是链接到本地文件的超链接无法打开 可能是相对路径和绝对路径的问题 绝对地址 是有完全的路径 如果超链接的路径写错了 就无法打开
  • java 源码欣赏,Logback源码赏析-日志按时间滚动(切割)

    引言 用过Logback的同学们大多都知道Logback日志框架可以自动按照某个时间点切割日志的功能 但了解其中工作原理的同学可能并不是很多 楼主今天就带领各位了解一下其中的核心源码 本文的示例引用了Logback 1 1 7版的源码 举个
  • 60 KVM Skylark虚拟机混部-安装和配置

    文章目录 60 KVM Skylark虚拟机混部 安装和配置 60 1 安装Skylark 60 1 1 硬件要求 60 1 2 软件要求 60 1 3 安装方法 60 2 配置Skylark 60 2 1 日志 60 2 2 功耗干扰控制
  • FPGA UART仿真

    摘自威三学员尤凯元 tb文件 Copyright c 2014 2019 All rights reserved Author Youkaiyuan v3eduyky 126 com wechat 15921999232 File tb t
  • 微信支付sign签名工具类

    secretKey为商户平台设置的密钥key params为非空参数集合 public static String genSignature String secretKey Map
  • ubuntu从内核源代码编译内核及替换内核

    1 下载ubuntu对应的linux内核源代码 apt catch search linux source 查看当前linux内核版本 apt get install linux source lt 对应的内核版本好 gt 下载对应的lin
  • 不列颠哥伦比亚大学推出面向硕士生和博士生的区块链项目

    点击上方 蓝色字 可关注我们 暴走时评 加拿大领先的研究型大学之一 不列颠哥伦比亚大学 UBC 正在为研究生推出获得区块链技术教育的途径 该项目计划专注于四个领域 健康与保健 清洁能源 监管技术和土着居民问题 并将于明年1月正式启动 作者
  • 解决PytestUnknownMarkWarning: Unknown pytest.mark.pre - is this a typo?

    问题描述 在pytest框架中 执行标记的用例时 出现了如下提示 PytestUnknownMarkWarning Unknown pytest mark pre is this a typo 这个提示的大致意思是pytest找不到标记 发
  • &1的用法

    看到不少大神都喜欢用 1来判断一些东西 但是作为渣渣的我总是不理解这个 1到底是有什么作用 今天写了程序看了一下 其实是判断奇偶用的 如果是奇数 其结果为1 偶数结果为false 我在这里想吐槽一下 大神为什么不直接mod2判断呢 incl
  • NO.18 什么是拜占庭将军问题

    本文是转载 转载自苏神的博客 原文地址 https www jianshu com p 5fea30b25f0a 拜占庭将军问题很多人可能听过 但不知道是什么意思 本文从非专业的角度来讲讲 拜占庭将军问题到底是说什么的 拜占庭将军问题 By
  • Vue全局自定义指令 和 局部自定义指令

    文章目录 自定义指令 Vue全局自定义指令 Vue局部自定义指令 Vue钩子函数 Vue钩子函数传参数详解 钩子函数简写或者合并 自定义指令 除了Vue核心的内置指令 例如 v model 和 v show等 以外 Vue也允许自己定义指令
  • Parsing error Unexpected token错误解决方案

    问题描述 import动态导入 将js文件单独打包时 webpack打包错误 import test then res gt 文件加载成功 console log res mul 2 5 catch gt console log 文件加载失
  • android native 使用opengl es画点线面图形(纯c++)

    一 首先需要对EGL进行初始化 void Renderer initEGL const EGLint attribs EGL SURFACE TYPE EGL WINDOW BIT EGL BLUE SIZE 8 EGL GREEN SIZ