Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions cgeDemo/src/main/java/org/wysaid/cgeDemo/ChartGLRenderer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.wysaid.cgeDemo;

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

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

public class ChartGLRenderer implements GLSurfaceView.Renderer {

public volatile float[] chartData = new float[ChartWaveForm.BUFFER_SIZE];
private int width;
private int height;
private Context context;
private ChartWaveForm lineChart;

public ChartGLRenderer(Context context) {
this.context = context;
lineChart = new ChartWaveForm();
}

@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
//lineChart = new LineChart();
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
this.width = width;
this.height = height;
//Prevent a divide by 0 by making height =1
if (height == 0) {
height = 1;
}
Log.d("执行到这", "ChartSurfaceView---Width =="+width+"----Height =="+height);
//Reset current viewport
gl.glViewport(0, 0, width, height);
//Select Projection Matrix
gl.glMatrixMode(GL10.GL_PROJECTION);
//Reset Projection Matrix
gl.glLoadIdentity();
//Calculate The Aspect Ratio Of The Window
//Log.d("Chart Ratio2 "," width " +width + " H " + height);
//void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
//fovy是眼睛上下睁开的幅度,角度值,值越小,视野范围越狭小(眯眼),值越大,视野范围越宽阔(睁开铜铃般的大眼);
//zNear表示近裁剪面到眼睛的距离,zFar表示远裁剪面到眼睛的距离,注意zNear和zFar不能设置设置为负值(你怎么看到眼睛后面的东西)。
//aspect表示裁剪面的宽w高h比,这个影响到视野的截面有多大。
GLU.gluPerspective(gl, 50.0f, (float) height * 2.0f / (float) width, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
}

@Override
public void onDrawFrame(GL10 gl) {
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
//Move 5 units into the screen is the same as moving the camera 5 units away
gl.glTranslatef(0.0f, 0.0f, -3.0f);
this.lineChart.setResolution(width, height);
this.lineChart.setChartData(chartData);
lineChart.draw(gl);
}
}
111 changes: 111 additions & 0 deletions cgeDemo/src/main/java/org/wysaid/cgeDemo/ChartGLSurfaceView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package org.wysaid.cgeDemo;

import android.content.Context;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;

public class ChartGLSurfaceView extends GLSurfaceView {

//线程标志位
private boolean isUpdating = false;
//渲染Renderer
private ChartGLRenderer mRenderer;
//y坐标数组
private float[] datapoints = new float[ChartWaveForm.BUFFER_SIZE];

public ChartGLSurfaceView(Context context) {
super(context);
//设置EGL配置选择
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
//设置处于屏幕最前边
this.setZOrderOnTop(true); //necessary
getHolder().setFormat(PixelFormat.TRANSLUCENT);
// Set the Renderer for drawing on the GLSurfaceView
mRenderer = new ChartGLRenderer(context);
setRenderer(mRenderer);
//初始化
for (int i = 0; i < datapoints.length; i++) {
datapoints[i] = 0;
}
setChartData(datapoints);
// Render the view only when there is a change in the drawing data,有变化时绘制
//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
new Thread(new Task()).start();
}

/**
* 设置数据源
* @param datapoints
*/
public void setChartData(float[] datapoints) {
// L.d("执行到这","decodeThread---02");
if (datapoints != null && datapoints.length > 0) {
isUpdating = true;
this.datapoints = datapoints.clone();
// float gMaxValue = getMax(datapoints);
// float gMinValue = getMin(datapoints);
// for (int i = 0; i < this.datapoints.length; i++) {
// this.datapoints[i] = (((datapoints[i] - gMinValue) * (1.0f - (-1.0f)) / (gMaxValue - gMinValue)) + (-1));
//// L.d("执行到这","this.datapoints[i]=="+String.valueOf(this.datapoints[i]));
// }
isUpdating = false;
// L.d("执行到这","gMaxValue==="+gMaxValue+"---gMinValue==="+gMinValue);
}
}

/**
* 获取数组最大值
* @param array
* @return
*/
private float getMax(float[] array) {
if(array != null && array.length > 0){
float max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
return max;
} else {
return 0f;
}
}

/**
* 获取数组最小值
* @param array
* @return
*/
private float getMin(float[] array) {
if(array != null && array.length > 0){
float min = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] < min) {
min = array[i];
}
}
return min;
} else {
return 0f;
}
}

class Task implements Runnable {
@Override
public void run() {
while (true) {
if (!isUpdating) {
mRenderer.chartData = datapoints;
requestRender();
}
// try {
// Thread.sleep(30);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
}

}
89 changes: 89 additions & 0 deletions cgeDemo/src/main/java/org/wysaid/cgeDemo/ChartWaveForm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package org.wysaid.cgeDemo;

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

import javax.microedition.khronos.opengles.GL10;

public class ChartWaveForm {

//缓冲区长度,点数
public final static int BUFFER_SIZE = 1570464;//VideoPlayerGLSurfaceView.mViewWidth*VideoPlayerGLSurfaceView.mViewHeight=984*1596=1570464
//缓冲区数组
private float[] mChartDatas = new float[BUFFER_SIZE];
//缓冲区缓存
private FloatBuffer vertexBuffer;
//顶点坐标数组
private float[] vertices = new float[BUFFER_SIZE * 3];
//绘图区域
private int width, height;

public ChartWaveForm() {

}

/**
* 根据缓冲区数组 封装 顶点坐标数组
*/
private void drawRealtimeChart() {
//坐标系xyz,屏幕中心为原点坐标(0,0,0),左上角为(-1,1,0),右下角(1,-1,0),坐标值有问题?好窄
float span = 20.0f / 984;//VideoPlayerGLSurfaceView.mViewWidth=984
//vertices的0,3,6……位置放x坐标值
//vertices的1,4,7……位置放y坐标值
//vertices的2,5,8……位置放z坐标值,平面图,默认为0
for (int i = 0; i < BUFFER_SIZE; i++) {

vertices[i * 3] = -10 + (i % 984) * span;//VideoPlayerGLSurfaceView.mViewWidth=984
// vertices[i * 3] = -10 + i * span;
// L.d("执行到这", "X轴坐标==" + vertices[i * 3]);

vertices[i * 3 + 1] = mChartDatas[i];

vertices[i * 3 + 2] = 0.0f;
}
}

/**
* 开辟对应的缓冲区存放顶点坐标数组
*/
private void vertexGenerate() {
//一个浮点数在内存中占4个字节,在内存中开辟指定长度的缓冲区,用来存放顶点坐标数组
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
//设置字节处理规则,大端模式或者小端模式,设置为默认
vertexByteBuffer.order(ByteOrder.nativeOrder());
//将内存中分配的字节缓冲区转换成浮点数缓冲区
vertexBuffer = vertexByteBuffer.asFloatBuffer();
//存放顶点坐标数组
vertexBuffer.put(vertices);
//复位缓冲区,position指向0,第一个数据
vertexBuffer.position(0);
}

public void setResolution(int width, int height) {
this.width = width;
this.height = height;
}

public void setChartData(float[] chartData) {
this.mChartDatas = chartData;
drawRealtimeChart();
vertexGenerate();
}

public void draw(GL10 gl) {
gl.glViewport(0, 0, width, height);
// bind the previously generated texture 顶点绘图
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// set the color for the triangle 设置绘图颜色
gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Point to our vertex buffer 设置顶点数据,3代表XYZ坐标系
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
// Line width
gl.glPointSize(2.5f);
// Draw the vertices as triangle strip,顶点之间的连接模式
gl.glDrawArrays(GL10.GL_POINTS, 0, vertices.length / 3);
//Disable the client state before leaving 关闭顶点设置
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
96 changes: 96 additions & 0 deletions cgeDemo/src/main/java/org/wysaid/cgeDemo/HistogramView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@

package org.wysaid.cgeDemo;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.view.View;

public class HistogramView extends View implements Handler.Callback {
static final private String TAG = "HistogramView";

private static final int HISTOGRAM = 0;

private Paint paint;
private Handler handler;
// private Converter converter;
private Configuration config;

private int width;
private int height;
private float max;

private float[] histogram;
private long count;

// HistogramView
public HistogramView(Context context) {
super(context);
paint = new Paint();
handler = new Handler(this);
// converter = new Converter(getContext());
}

// onSizeChanged
@Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
width = w;
height = h;

config = getResources().getConfiguration();
}

// onDraw
@Override
public void onDraw(Canvas canvas) {
if (histogram == null) return;

canvas.drawColor(Color.BLACK);

float xscale = (float) width / 256;
float yscale = (float) height / 10000;

paint.setStrokeWidth(xscale);
paint.setColor(Color.WHITE);

for (int x = 0; x < 256; x++) {
float xpos = x * xscale;
float ypos;
if (histogram[x] < 10000) {
ypos = histogram[x] * yscale;
} else {
ypos = 10000 * yscale;
}
canvas.drawLine(xpos, height, xpos + xscale, height - ypos, paint);
}
}

public void onPreviewFrame(float[] data, VideoPlayerGLSurfaceView view) {
if (data != null) {
// if (count++ % 2 == 0) {
Message message = handler.obtainMessage(HISTOGRAM, view.getViewWidth(), view.getViewheight(), data);
message.sendToTarget();
// }
}
}

@Override
public boolean handleMessage(Message message) {
// process incoming messages here
histogram = (float[]) message.obj;
// int width = message.arg1;
// int height = message.arg2;
// byte[] data = (byte[]) message.obj;
//
// byte[] pixels = converter.convertToRGB(data, width, height);
// histogram =
// converter.luminanceHistogram(data, width, height);
// converter.histogram(pixels, width, height);
invalidate();
return true;
}
}
Loading