问题描述
我刚刚开始学习Android的OpenGL和画线,当我有一个奇怪的问题。所有我想要做的是汲取基于手指运动的线。现在,当我开始刷我总是一条线从原点(0,0)如下因素我的议案。
下面的图片:
箭头符号我的手指运动,并在原点(红圈)开始行是提到行如下因素我的整个运动。
不要被困扰的COORDS阵列我知道这是不是最好的做法,但我debuged整个PROGRAMM,不能FINDE涉及该阵列的任何错误。
我也许应该提及的是,ArrayList中包含点我所有的生成点。
我想这出为现在退出一段时间,但我真的坚持任何建议可能是有益的。
这是我的整个呈现类。
公共类HelloOpenGLES20Renderer实现GLSurfaceView.Renderer {
私人FloatBuffer triangleVB;
私人诠释mProgram;
私人诠释maPositionHandle;
公众的ArrayList< PointWrapper>点;私人诠释muMVPMatrixHandle;
私人浮动[] = mMVPMatrix新的浮动[16];
私人浮动[] = mMMatrix新的浮动[16];
私人浮动[] = mVMatrix新的浮动[16];
私人浮动[] = mProjMatrix新的浮动[16];
私人诠释[] =视新INT [4];私人的ArrayList<浮球GT;坐标;浮动[] = COORDS新的浮动[100000]。布尔第一;
私人诠释柜台;
去年私人PointWrapper;私人最终字符串vertexShader code =
//这个矩阵的成员变量提供了一个钩来操作
//使用该顶点着色器中的物体的坐标
统一mat4 uMVPMatrix; \\ n+属性vec4 vPosition; \\ n+无效的主要(){\\ n+//矩阵必须被包括作为GL_POSITION的改性剂
GL_POSITION = uMVPMatrix * vPosition; \\ n+
} \\ n;私人最终字符串fragmentShader code =precision mediump浮动; \\ n
+无效的主要(){\\ n
+gl_FragColor = vec4(0.63671875,0.76953125,0.22265625,1.0); \\ n
+} \\ n;私人诠释loadShader(整型,字符串着色器code){ //创建一个顶点着色器类型(GLES20.GL_VERTEX_SHADER)
//或片段着色器类型(GLES20.GL_FRAGMENT_SHADER)
INT着色器= GLES20.glCreateShader(类型); //添加源$ C $ C着色器和编译
GLES20.glShaderSource(着色,着色器code);
GLES20.glCompileShader(着色器); 返回着色器;
}公共HelloOpenGLES20Renderer(){
点=新的ArrayList< PointWrapper>();
第一= TRUE;
this.counter = 0;
最后=新PointWrapper(); 协调=新的ArrayList<浮球GT;();
}私人浮动[] convertCoordinates(PointWrapper F){
浮动[] =矢量新的浮动[4];
GLU.gluUnProject(f.point.x,f.point.y,0.0,mVMatrix,0,mProjMatrix,
0,视口,0,向量,0); 返回向量;
}私人无效initShapes(){
ArrayList的< PointWrapper> points2 =新的ArrayList< PointWrapper>(点);
浮动[]载体;
如果(!points2.isEmpty()){
如果(points2.size()%2 == 1){
points2.remove(points2.size() - 1);
} 的for(int i =计数器/ 2; I< points2.size();我++){ 矢量= convertCoordinates(points2.get(I));
COORDS [计数器] =矢量[0] /矢量[3];
COORDS [计数器+ 1] = -1 *(矢量[1] /矢量[3]); 计数器=计数器+ 2;
}
} //初始化顶点缓冲区为三角形
ByteBuffer的VBB = ByteBuffer.allocateDirect(
//(每浮子#坐标值* 4个字节)
Coords.length * 4);
vbb.order(ByteOrder.nativeOrder()); //使用设备硬件的本地
//字节顺序
triangleVB = vbb.asFloatBuffer(); //创建一个从浮点缓冲区
// ByteBuffer的
triangleVB.put(COORDS); //添加坐标的
// FloatBuffer
triangleVB.position(0); //设置缓冲区读取第一个坐标}公共无效onSurfaceCreated(GL10不用,EGLConfig配置){ //设置背景框的颜色
GLES20.glClearColor(0.5F,0.5F,0.5F,1.0F); //初始化三角形顶点数组
// initShapes(); INT vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShader code);
INT fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShader code); mProgram = GLES20.glCreateProgram(); //创建空的OpenGL程序
GLES20.glAttachShader(mProgram,vertexShader); //添加顶点着色器
//编程
GLES20.glAttachShader(mProgram,fragmentShader); //添加片段
//着色器程序
GLES20.glLinkProgram(mProgram); //创建OpenGL的可执行程序 //获取处理的顶点着色器的vPosition成员
maPositionHandle = GLES20.glGetAttribLocation(mProgramvPosition);
}公共无效onDrawFrame(GL10未使用){ //重绘背景颜色
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); initShapes(); //添加程序的OpenGL环境
GLES20.glUseProgram(mProgram); // prepare三角形数据
GLES20.glVertexAttribPointer(maPositionHandle,2,GLES20.GL_FLOAT,
假,0,triangleVB);
GLES20.glEnableVertexAttribArray(maPositionHandle); //应用一个模型视图投影变换
Matrix.multiplyMM(mMVPMatrix,0,mProjMatrix,0,mVMatrix,0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle,1,假,mMVPMatrix,0); GLES20.glLineWidth(1006米); GLES20.glDrawArrays(GLES20.GL_LINE_STRIP,0,计数器);
}公共无效onSurfaceChanged(GL10未使用的,诠释的宽度,高度INT){
GLES20.glViewport(0,0,宽度,高度); 流通股比例=(浮点)宽/高;
视[0] = 0;
视口[1] = 0;
视[2] =宽度;
视[3] =高度; //这个投影矩阵应用于目标座标
//在onDrawFrame()方法
Matrix.frustumM(mProjMatrix,0,-ratio,比率,-1,1,3,7); muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramuMVPMatrix); Matrix.setLookAtM(mVMatrix,0,0,0,-3,0F,0F,0F,0F,1.0F,0.0);
}
}
我在此先感谢
的for(int i =计数器/ 2; I< points2.size();我++){ 矢量= convertCoordinates(points2.get(I));
COORDS [计数器] =矢量[0] /矢量[3];
COORDS [计数器+ 1] = -1 *(矢量[1] /矢量[3]); 计数器=计数器+ 2;
}
您已经intialized COORDS持有100000花车和它他们初始化为0。在这种循环的最后迭代有反与你有你的数组中设置花车的数量。
您通过什么调用glDrawArrays应该是顶点画的数量。所以在这种情况下,一半的柜台。
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP,0,计数器);
您的for循环是在阵列的末尾添加'反'的(0,0)的顶点/ 2个额外的金额。最快的解决将是通过反'/ 2调用glDrawArrays但我建议更明确的办法。
numOfVertices = points2.size(); //进行实地
INT计数器= 0; //使局部
的for(int i = 0; I< numOfVertices;我++){
矢量= convertCoordinates(points2.get(I));
COORDS [计数器] =矢量[0] /矢量[3];
COORDS [计数器+ 1] = -1 *(矢量[1] /矢量[3]);
计数器=计数器+ 2;
}
然后
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP,0,numOfVertices);
I've just started learning OpenGL for Android and I'm having a weird problem when drawing lines. All i want to do is to draw a line based on a finger motion. Now as soon as I start swiping I always get a line folowing my motion from the origin(0,0).
here a picture:
http://imageshack.us/photo/my-images/137/screenshot2012061312174.jpg/
The arrow symbols my finger motion and the line starting in the origin (red circle) is the mentioned line folowing my entire motion.
Don't get bothered with the Coords array I know this isn't best practice but I debuged the entire programm and couldn't finde any bugs involving this array.
I probably should mention that the ArrayList points contains all my generated points.
I'm trying to figure this out for quit a while now but I'm really stuck any suggestion could be helpfull
This is my entire render class.
public class HelloOpenGLES20Renderer implements GLSurfaceView.Renderer {
private FloatBuffer triangleVB;
private int mProgram;
private int maPositionHandle;
public ArrayList<PointWrapper> points;
private int muMVPMatrixHandle;
private float[] mMVPMatrix = new float[16];
private float[] mMMatrix = new float[16];
private float[] mVMatrix = new float[16];
private float[] mProjMatrix = new float[16];
private int[] viewport = new int[4];
private ArrayList<Float> coordinates;
float[] Coords = new float[100000];
boolean first;
private int counter;
private PointWrapper last;
private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix; \n" +
"attribute vec4 vPosition; \n" + "void main(){ \n" +
// the matrix must be included as a modifier of gl_Position
" gl_Position = uMVPMatrix * vPosition; \n" +
"} \n";
private final String fragmentShaderCode = "precision mediump float; \n"
+ "void main(){ \n"
+ " gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n"
+ "} \n";
private int loadShader(int type, String shaderCode) {
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
public HelloOpenGLES20Renderer() {
points = new ArrayList<PointWrapper>();
first = true;
this.counter = 0;
last = new PointWrapper();
coordinates = new ArrayList<Float>();
}
private float[] convertCoordinates(PointWrapper f) {
float[] vector = new float[4];
GLU.gluUnProject(f.point.x, f.point.y, 0.0f, mVMatrix, 0, mProjMatrix,
0, viewport, 0, vector, 0);
return vector;
}
private void initShapes() {
ArrayList<PointWrapper> points2 = new ArrayList<PointWrapper>(points);
float[] vector;
if (!points2.isEmpty()) {
if(points2.size()%2==1){
points2.remove(points2.size()-1);
}
for (int i = counter/2; i < points2.size(); i++) {
vector = convertCoordinates(points2.get(i));
Coords[counter] = vector[0] / vector[3];
Coords[counter+1] = -1 * (vector[1] / vector[3]);
counter= counter+2;
}
}
// initialize vertex Buffer for triangle
ByteBuffer vbb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
Coords.length * 4);
vbb.order(ByteOrder.nativeOrder());// use the device hardware's native
// byte order
triangleVB = vbb.asFloatBuffer(); // create a floating point buffer from
// the ByteBuffer
triangleVB.put(Coords); // add the coordinates to the
// FloatBuffer
triangleVB.position(0); // set the buffer to read the first coordinate
}
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
// Set the background frame color
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
// initialize the triangle vertex array
// initShapes();
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader
// to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment
// shader to program
GLES20.glLinkProgram(mProgram); // creates OpenGL program executables
// get handle to the vertex shader's vPosition member
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
}
public void onDrawFrame(GL10 unused) {
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
initShapes();
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// Prepare the triangle data
GLES20.glVertexAttribPointer(maPositionHandle, 2, GLES20.GL_FLOAT,
false, 0, triangleVB);
GLES20.glEnableVertexAttribArray(maPositionHandle);
// Apply a ModelView Projection transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glLineWidth(5f);
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, counter);
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
viewport[0] = 0;
viewport[1] = 0;
viewport[2] = width;
viewport[3] = height;
// this projection matrix is applied to object coodinates
// in the onDrawFrame() method
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
}
}
my thanks in advance
for (int i = counter/2; i < points2.size(); i++) {
vector = convertCoordinates(points2.get(i));
Coords[counter] = vector[0] / vector[3];
Coords[counter+1] = -1 * (vector[1] / vector[3]);
counter= counter+2;
}
You have intialized Coords to hold 100000 floats and it initializes them to 0. In this loop the last iteration has 'counter' with the number of floats you have set in your array.
What you pass to glDrawArrays should be the number of VERTICES to draw. so in this case half of 'counter'.
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, counter);
Your for-loop is adding 'counter'/2 extra amount of (0,0) vertices at the end of your array. the quickest fix would be to pass 'counter'/ 2 to glDrawArrays but I'd suggest a clearer approach.
numOfVertices = points2.size(); //make field
int counter = 0; //make local
for (int i = 0; i < numOfVertices; i++) {
vector = convertCoordinates(points2.get(i));
Coords[counter] = vector[0] / vector[3];
Coords[counter+1] = -1 * (vector[1] / vector[3]);
counter= counter+2;
}
and then
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, numOfVertices);
这篇关于基于运动的OpenGL ES 2.0绘图线,线总是从原点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!