Android OpenGL 教程——窗口初始化&绘制矩形

上节介绍了 Native 工程初始化,但是我们的窗口什么都没有,这节我们将 NativeActivity 创建的 window 绑定到 OpenGL 创建的 display 的 surface 上,并且绘制背景颜色和三角形,通过三角形绘制出一个矩形

显示系统创建

void Render::initRenderer(android_app *pApp) {
    LOGI("initRenderer !")
    // 选择您的渲染属性
    constexpr EGLint attribs[] = {
            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
            EGL_BLUE_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_RED_SIZE, 8,
            EGL_DEPTH_SIZE, 24,
            EGL_NONE
    };

    // Android 上的默认显示可能就是您想要的
    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(display, nullptr, nullptr);

    // 找出有多少个配置
    EGLint numConfigs;
    eglChooseConfig(display, attribs, nullptr, 0, &numConfigs);
    // 获取配置列表
    std::unique_ptr<EGLConfig[]> supportedConfigs(new EGLConfig[numConfigs]);
    eglChooseConfig(display, attribs, supportedConfigs.get(), numConfigs, &numConfigs);

    // 找到我们喜欢的配置。
    // 如果我们不关心配置中的其他任何内容,可能会只获取第一个。
    // 否则就加入你自己的启发式
    config_ = *std::find_if(
            supportedConfigs.get(),
            supportedConfigs.get() + numConfigs,
            [&display](const EGLConfig &config) {
                EGLint red, green, blue, depth;
                if (eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red)
                    && eglGetConfigAttrib(display, config, EGL_GREEN_SIZE,
                                          &green)
                    && eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,
                                          &blue)
                    && eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE,
                                          &depth)) {
                    LOGI("Found config with: %d , %d , %d , %d", red,
                         green, blue, depth);
                    return red == 8 && green == 8 && blue == 8 &&
                           depth == 24;
                }
                return false;
            }
    );
    LOGI("Found %d Configs", numConfigs)

    // 创建 GLES 3 上下文
    EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
    EGLContext context = eglCreateContext(display, config_, nullptr, contextAttribs);
    display_ = display;
    context_ = context;
    // 检查系统上的 openGL
    auto opengl_info = {GL_VENDOR, GL_RENDERER, GL_VERSION, GL_EXTENSIONS};
    for (auto name: opengl_info) {
        auto info = glGetString(name);
        LOGI("OpenGL Info: %s", info);
    }
    initSurface(pApp);
    LOGI("init completed!")

}
void Render::initSurface(android_app *pApp) {
    // 创建合适的 window surface
    surface_ = eglCreateWindowSurface(display_, config_, pApp->window, nullptr);
    //获取一些窗口指标
    if (eglMakeCurrent(display_, surface_, surface_, context_) == EGL_FALSE) {
        LOGW("Unable to eglMakeCurrent")
        return;
    }
    eglQuerySurface(display_, surface_, EGL_WIDTH, &width_);
    eglQuerySurface(display_, surface_, EGL_HEIGHT, &height_);
    LOGI("QuerySurface : width = %d , height = %d", width_, height_)
}

绘制

绘制背景色

void BackgroundLayer::draw(Render *render) {
    glClearColor(state.x / (float) render->width_,
                 state.angle,
                 state.y / (float) render->height_,
                 1);
    glClear(GL_COLOR_BUFFER_BIT);
}

绘制三角形

初始化

class TriangleLayer : public Layer {
    void handleInput(AInputEvent *event);

    void draw(Render *render);

private:
    unsigned int VBO = 0, VAO = 0 , VEO = 0;
    bool isInit = false;
    float* color = new float [0.0f,0.0f,0.0f,1.f];
    float dis = 0.005f;

    void init() {
        if (isInit) {
            return;
        }
        isInit = true;
        // 初始化代码(只运行一次 (除非你的物体频繁改变))
        float vertices[] = {
                0.5f, 0.5f, 0.0f,   // 右上角
                0.5f, -0.5f, 0.0f,  // 右下角
                -0.5f, -0.5f, 0.0f, // 左下角
                -0.5f, 0.5f, 0.0f   // 左上角
        };
        unsigned int indices[] = {
                1, 2, 3  // 第二个三角形
        };
        //创建 VAO,VBO,VEO
        glGenBuffers(1, &VBO);
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VEO);
        // 绑定VAO
        glBindVertexArray(VAO);
        // 绑定缓冲,填充数据,把顶点数组复制到缓冲中供OpenGL使用
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        // 绑定索引,填充索引数据
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VEO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices),indices,GL_STATIC_DRAW);
        // 设置顶点属性指针
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0);
        glEnableVertexAttribArray(0);
        // 解绑
        glBindBuffer(GL_ARRAY_BUFFER,0);
        glBindVertexArray(0);
    }

public:
    TriangleLayer() {
    }
    ~TriangleLayer(){
        glDeleteBuffers(1,&VAO);
        glDeleteBuffers(1,&VBO);
        glDeleteBuffers(1,&VEO);
    }

};

绘制

void TriangleLayer::draw(Render *render) {
    // 绘制物体
    init();
    render->shader_->use();

    // 更新uniform颜色
    color[0] = color[0] + dis;
    color[1] = color[1] + dis;
    if (color[1] >= 1.0f) {
        color[0] = 1.0f;
        color[1] = 1.0f;
        dis = -0.005f;
    } else if (color[1] <= 0.0f) {
        color[0] = 0.0f;
        color[1] = 0.0f;
        dis = 0.005f;
    }
//    int vertexColorLocation = render->shader_->getUniformLocation("ourColor");
//    glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
//    glUniform4f(vertexColorLocation, color[0], color[1], color[2], color[3]);
//    glUniform4fv(vertexColorLocation,0,color);
//    glUniform4fv(vertexColorLocation,1,color);
    render->shader_->setFloat("ourColor",0,color);
    render->shader_->setFloat("ourColor",1,color);

    glBindVertexArray(VAO);
//    glDrawArrays(GL_TRIANGLES, 0, 3);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
    glBindVertexArray(0);
}

绘制矩形

 只需要将三角形的索引改为6个即可

class TriangleLayer : public Layer {

    void init() {
        ......
        unsigned int indices[] = {
                // 注意索引从0开始!
                // 此例的索引(0,1,2,3)就是顶点数组vertices的下标,
                // 这样可以由下标代表顶点组合成矩形
                0, 1, 3, // 第一个三角形
                1, 2, 3  // 第二个三角形
        };
        ......
    }

};

绘制

void TriangleLayer::draw(Render *render) {
    ......
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    ......
}

源码:OpenGLDemo#triangle

你好,三角形

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值