2013-04-16 12 views
16

Jeśli mam niestandardowy mechanizm renderujący w OpenGL ES przygotowane:Jaki jest najprostszy sposób, aby narysować linię przy użyciu OpenGL ES (Android)

public void onDrawFrame(GL10 gl) 
{ 
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
    // here i want to draw line from [0, 0, 0] to [1, 0, 0] 
} 

Jaki jest najprostszy i najkrótszy sposób narysować linię?

W zwykłym OpenGL to:

glBegin(GL_LINES); 
    glVertex3f(0, 0, 0); 
    glVertex3f(1, 0, 0); 
glEnd(); 

Ale w jaki sposób można uzyskać ten sam efekt z OpenGL ES?

+0

Sprawdź np. http://stackoverflow.com/questions/11015374/opengl-es-2-0-drawing-line-based-on-motion-line-always-starts-in-origin Nie musisz mieć rzeczy z matrycy, lub nawet program/shader w celu rysowania czarnych linii. Ale istnieje potrzeba poprawienia buforów w celu użycia gl.drawElements (GL.LINES, xxx); –

Odpowiedz

34

Jestem nowy w OpenGL ES 2.0, ale stworzyłem klasę linii.

public class Line { 
    private FloatBuffer VertexBuffer; 

    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;" + 

     "attribute vec4 vPosition;" + 
     "void main() {" + 
     // the matrix must be included as a modifier of gl_Position 
     " gl_Position = uMVPMatrix * vPosition;" + 
     "}"; 

    private final String FragmentShaderCode = 
     "precision mediump float;" + 
     "uniform vec4 vColor;" + 
     "void main() {" + 
     " gl_FragColor = vColor;" + 
     "}"; 

    protected int GlProgram; 
    protected int PositionHandle; 
    protected int ColorHandle; 
    protected int MVPMatrixHandle; 

    // number of coordinates per vertex in this array 
    static final int COORDS_PER_VERTEX = 3; 
    static float LineCoords[] = { 
     0.0f, 0.0f, 0.0f, 
     1.0f, 0.0f, 0.0f 
    }; 

    private final int VertexCount = LineCoords.length/COORDS_PER_VERTEX; 
    private final int VertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex 

    // Set color with red, green, blue and alpha (opacity) values 
    float color[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 

    public Line() { 
     // initialize vertex byte buffer for shape coordinates 
     ByteBuffer bb = ByteBuffer.allocateDirect(
      // (number of coordinate values * 4 bytes per float) 
      LineCoords.length * 4); 
     // use the device hardware's native byte order 
     bb.order(ByteOrder.nativeOrder()); 

     // create a floating point buffer from the ByteBuffer 
     VertexBuffer = bb.asFloatBuffer(); 
     // add the coordinates to the FloatBuffer 
     VertexBuffer.put(LineCoords); 
     // set the buffer to read the first coordinate 
     VertexBuffer.position(0); 

     int vertexShader = ArRenderer.loadShader(GLES20.GL_VERTEX_SHADER, VertexShaderCode); 
     int fragmentShader = ArRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, FragmentShaderCode); 

     GlProgram = GLES20.glCreateProgram();    // create empty OpenGL ES Program 
     GLES20.glAttachShader(GlProgram, vertexShader); // add the vertex shader to program 
     GLES20.glAttachShader(GlProgram, fragmentShader); // add the fragment shader to program 
     GLES20.glLinkProgram(GlProgram);     // creates OpenGL ES program executables 
    } 

    public void SetVerts(float v0, float v1, float v2, float v3, float v4, float v5) { 
     LineCoords[0] = v0; 
     LineCoords[1] = v1; 
     LineCoords[2] = v2; 
     LineCoords[3] = v3; 
     LineCoords[4] = v4; 
     LineCoords[5] = v5; 

     VertexBuffer.put(LineCoords); 
     // set the buffer to read the first coordinate 
     VertexBuffer.position(0); 
    } 

    public void SetColor(float red, float green, float blue, float alpha) { 
     color[0] = red; 
     color[1] = green; 
     color[2] = blue; 
     color[3] = alpha; 
    } 

    public void draw(float[] mvpMatrix) { 
     // Add program to OpenGL ES environment 
     GLES20.glUseProgram(GlProgram); 

     // get handle to vertex shader's vPosition member 
     PositionHandle = GLES20.glGetAttribLocation(GlProgram, "vPosition"); 

     // Enable a handle to the triangle vertices 
     GLES20.glEnableVertexAttribArray(PositionHandle); 

     // Prepare the triangle coordinate data 
     GLES20.glVertexAttribPointer(PositionHandle, COORDS_PER_VERTEX, 
           GLES20.GL_FLOAT, false, 
           VertexStride, VertexBuffer); 

     // get handle to fragment shader's vColor member 
     ColorHandle = GLES20.glGetUniformLocation(GlProgram, "vColor"); 

     // Set color for drawing the triangle 
     GLES20.glUniform4fv(ColorHandle, 1, color, 0); 

     // get handle to shape's transformation matrix 
     MVPMatrixHandle = GLES20.glGetUniformLocation(GlProgram, "uMVPMatrix"); 
     ArRenderer.checkGlError("glGetUniformLocation"); 

     // Apply the projection and view transformation 
     GLES20.glUniformMatrix4fv(MVPMatrixHandle, 1, false, mvpMatrix, 0); 
     ArRenderer.checkGlError("glUniformMatrix4fv"); 

     // Draw the triangle 
     GLES20.glDrawArrays(GLES20.GL_LINES, 0, VertexCount); 

     // Disable vertex array 
     GLES20.glDisableVertexAttribArray(PositionHandle); 
    } 
} 

A potem w moim Render klasa tworzę obiektów liniowych i do pojemnika tak się zwrócić w ciągu przez powtarzanie przedmiotów i wywołanie metody Line.draw w onDrawFrame.

Oto niektóre linie tworzę dokonać horyzoncie

Line eastHorz = new Line(); 
    eastHorz.SetVerts(10f, 10f, 0f, 10f, -10f, 0f); 
    eastHorz.SetColor(.8f, .8f, 0f, 1.0f); 
    Line northHorz = new Line(); 
    northHorz.SetVerts(-10f, 10f, 0f, 10f, 10f, 0f); 
    northHorz.SetColor(0.8f, 0.8f, 0f, 1.0f); 
    Line westHorz = new Line(); 
    westHorz.SetVerts(-10f, -10f, 0f, -10f, 10f, 0f); 
    westHorz.SetColor(0.8f, 0.8f, 0f, 1.0f); 
    Line southHorz = new Line(); 
    southHorz.SetVerts(-10f, -10f, 0f, 10f, -10f, 0f); 
    southHorz.SetColor(0.8f, 0.8f, 0f, 1.0f); 
    Lines.add(eastHorz); 
    Lines.add(northHorz); 
    Lines.add(westHorz); 
    Lines.add(southHorz); 
+12

Nie mogę się nadziwić, ile wysiłku potrzeba, by narysować linię w OpenGLES2 niż OpenGL. 6 linii staje się kilkadziesiąt :( – zyzof

+0

co to jest ArRenderer proszę – Sun

+0

Ravi - ArRenderer jest moją klasą renderowania, o której wspomniałem powyżej, zawiera linie, położenie kamery itp. I implementuje GLSurfaceView.Renderer. Metoda loadShader to: \t public static int loadShader (int typ ciąg shaderCode) { \t // utworzyć rodzaj werteksach (GLES20.GL_VERTEX_SHADER) \t // lub typu cieniującego fragmenty (GLES20.GL_FRAGMENT_SHADER) \t Int moduł cieniujący = GLES20.glCreateShader (typ); \t // dodaj kod źródłowy do modułu cieniującego i skompiluj go \t GLES20.glShaderSource (moduł cieniujący, tryb shadera); \t GLES20.glCompileShader (moduł cieniujący); \t moduł cieniujący powrotu; \t} –

8

Thanks Rodney Lambert dla linii klasy udało Ci usług. Jednak to również byłoby miło, aby zapewnić prostsze połączenia w onDrawFrame, coś jak:

Line vertLine = new Line(); 
vertLine.SetVerts(-0.5f, 0.5f, 0f, -0.5f, -0.5f, 0f); 
vertLine.SetColor(.8f, .8f, 0f, 1.0f); 
vertLine.draw(mMVPMatrix); 

vertLine.SetVerts (-0.5f, 0.5f, 0F, -0.5f, -0.5f, 0F) ;

tworzy zdecydowanie linię widoczną wewnątrz rzutni

+5

_Nice italics_! –