Opengl ES系列学习--蜗牛

本文探讨了一个使用OpenGL ES实现的蜗牛渲染案例,该案例导致GPU达到最高频率,负载高达99%,相比之下,常规相机预览只占3%到10%的负载。作者指出,这显示出对OpenGL ES技术更深入的理解和应用。片段着色器的源码被提及,特别是FragColor和gl_FragCoord变量在像素着色器中的重要作用。下节将继续讨论光照贴图相关内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     今天的这个蜗牛真是太猛了,计算量超大,GPU直接拉到最高频,而且负载99%!!这是什么样的计算量,我们相机使用Opengl ES平时绘制的预览,GPU是最低频,而且负载也只有3%--10%左右,看来我们的技术还不够深,要能真正实现一个功能,正常使用GPU达到这样的频率的话,那才能突显出一定的水平。来看下蜗牛的效果。

     GlSnailRender类的完整源码如下:

package com.opengl.learn.aric;

import android.content.Context;
import android.opengl.GLES32;
import android.opengl.GLSurfaceView;
import android.util.Log;

import com.opengl.learn.OpenGLUtils;
import com.opengl.learn.R;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import static android.opengl.GLES20.GL_ARRAY_BUFFER;
import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES20.GL_DEPTH_BUFFER_BIT;
import static android.opengl.GLES20.GL_DEPTH_TEST;
import static android.opengl.GLES20.GL_FLOAT;
import static android.opengl.GLES20.GL_STATIC_DRAW;
import static android.opengl.GLES20.GL_TEXTURE0;
import static android.opengl.GLES20.GL_TEXTURE1;
import static android.opengl.GLES20.GL_TEXTURE2;
import static android.opengl.GLES20.GL_TEXTURE_2D;
import static android.opengl.GLES20.GL_TRIANGLES;
import static android.opengl.GLES20.glGenBuffers;
import static android.opengl.GLES20.glGetUniformLocation;

public class GlSnailRender implements GLSurfaceView.Renderer {
    private static final String TAG = GlSnailRender.class.getSimpleName();
    private final float[] mVerticesData =
            {
                    -1.0f, 1.0f, 0.0f,
                    -1.0f, -1.0f, 0.0f,
                    1.0f, -1.0f, 0.0f,

                    1.0f, -1.0f, 0.0f,
                    1.0f, 1.0f, 0.0f,
                    -1.0f, 1.0f, 0.0f,
            };

    private static final int BYTES_PER_FLOAT = 4;
    private static final int POSITION_COMPONENT_COUNT = 3;
    private Context mContext;
    private FloatBuffer mVerticesBuffer;
    private int mProgramObject, mVAO, mVBO, iTime, iResolution;
    private int iChannel1, channel1, iChannel2, channel2, iChannel3, channel3;
    private int mWidth, mHeight;
    private long startTime;

    public GlSnailRender(Context context) {
        mContext = context;
        mVerticesBuffer = ByteBuffer.allocateDirect(mVerticesData.length * BYTES_PER_FLOAT)
                .order(ByteOrder.nativeOrder()).asFloatBuffer();
        mVerticesBuffer.put(mVerticesData).position(0);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        mProgramObject = OpenGLUtils.loadProgram(mContext, R.raw.glsea_vertex, R.raw.glsnail_fragment);
        iResolution = glGetUniformLocation(mProgramObject, "iResolution");
        iTime = glGetUniformLocation(mProgramObject, "iTime");
        iChannel1 = glGetUniformLocation(mProgramObject, "iChannel1");
        iChannel2 = glGetUniformLocation(mProgramObject, "iChannel2");
        iChannel3 = glGetUniformLocation(mProgramObject, "iChannel3");

        int[] array = new int[1];
        GLES32.glGenVertexArrays(array.length, array, 0);
        mVAO = array[0];
        array = new int[1];
        glGenBuffers(array.length, array, 0);
        mVBO = array[0];
        Log.e(TAG, "onSurfaceCreated, " + mProgramObject + ", uTime: " + iTime + ", uResolution: " + iResolution);

        GLES32.glBindVertexArray(mVAO);

        mVerticesBuffer.position(0);
        GLES32.glBindBuffer(GL_ARRAY_BUFFER, mVBO);
        GLES32.glBufferData(GL_ARRAY_BUFFER, BYTES_PER_FLOAT * mVerticesData.length, mVerticesBuffer, GL_STATIC_DRAW);
        GLES32.glVertexAttribPointer(0, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, 0);
        GLES32.glEnableVertexAttribArray(0);

        channel1 = OpenGLUtils.loadTexture(mContext, R.mipmap.snail_channel1);
        channel2 = OpenGLUtils.loadTexture(mContext, R.mipmap.snail_channel2);
        channel3 = OpenGLUtils.loadTexture(mContext, R.mipmap.snail_channel3);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        mWidth = width;
        mHeight = height;
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        long now = System.currentTimeMillis();

        if (startTime == 0) {
            startTime = now;
        }

        float time = (now - startTime) / (1000f * 5f);

        GLES32.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        GLES32.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        GLES32.glEnable(GL_DEPTH_TEST);

        GLES32.glUseProgram(mProgramObject);
        GLES32.glUniform1f(iTime, time);
        GLES32.glUniform2f(iResolution, mWidth, mHeight);

        GLES32.glActiveTexture(GL_TEXTURE0);
        GLES32.glBindTexture(GL_TEXTURE_2D, channel1);
        GLES32.glUniform1i(iChannel1, 0);

        GLES32.glActiveTexture(GL_TEXTURE1);
        GLES32.glBindTexture(GL_TEXTURE_2D, channel2);
        GLES32.glUniform1i(iChannel2, 1);

        GLES32.glActiveTexture(GL_TEXTURE2);
        GLES32.glBindTexture(GL_TEXTURE_2D, channel3);
        GLES32.glUniform1i(iChannel3, 2);

        GLES32.glEnableVertexAttribArray(0);
        GLES32.glBindVertexArray(mVAO);
        GLES32.glDrawArrays(GL_TRIANGLES, 0, mVerticesData.length);

        GLES32.glBindVertexArray(0);
        GLES32.glDisableVertexAttribArray(0);
    }
}

     重点还是在片段着色器,网上有些说法也叫像素着色器,不过两个的重点不一样,片段着色器的重点是FragColor;像素着色器的重点是gl_FragCoord,一个变量就可以展开无数种炫丽的效果,像素着色器的魔法也就在gl_FragCoord内建变量中了。片段着色器的源码如下:

// Created by inigo quilez - 2015
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0

// You can buy a metal print of this shader here:
// https://www.redbubble.com/i/metal-print/Snail-by-InigoQuilez/39845499.0JXQP

#version 320 es
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif

// antialiasing - make AA 2, meaning 4x AA, if you have a fast machine
#define AA 1
#define ZERO (min(2, 0)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红-旺永福

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值