Herramientas de usuario

Herramientas del sitio


wiki2:oglpipeline

OpenGL Pipeline

OpenGL Pipeline Básico

Load pixels in memory

Android version

float[] tableVerticesWithTriangles = {
        // Triangle 1
        0, 0.5f,
        -0.5f,  0,
        0.5f,  0,
 
        // Triangle 2
        0, 0,
        0.5f, -0.5f,
        -0.5f,  -0.5f
};
 
vertexData = ByteBuffer
        .allocateDirect(tableVerticesWithTriangles.length * BYTES_PER_FLOAT)
        .order(ByteOrder.nativeOrder())
        .asFloatBuffer();
 
vertexData.put(tableVerticesWithTriangles);

Change the area where we are gonna render

@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
    glViewport(0, 0, width, height);
}

Coding vertex shader

attribute vec4 a_Position;
void main()
{
    gl_Position = a_Position;
    gl_PointSize = 10.0;
}

Coding fragment shader

precision mediump float;
uniform vec4 u_Color;
void main()
{
    gl_FragColor = u_Color;
}

Compiling shaders

private int compileShader(int type, String shaderCode) {
    final int shaderObjectId = glCreateShader(type);
    if (shaderObjectId == 0) {
        Log.w(TAG, "Could not create new shader.");
        return 0;
    }
 
    glShaderSource(shaderObjectId, shaderCode);
    glCompileShader(shaderObjectId);
    final int[] compileStatus = new int[1];
    glGetShaderiv(shaderObjectId, GL_COMPILE_STATUS, compileStatus, 0);
 
    Log.v(TAG, "Results of compiling source:" + "\n" + shaderCode + "\n:"  + glGetShaderInfoLog(shaderObjectId));
 
    if (compileStatus[0] == 0) {
        glDeleteShader(shaderObjectId);
        Log.w(TAG, "Compilation of shader failed.");
        return 0;
    }
    Log.w(TAG, "Compilation of shader was good.");
    return shaderObjectId;
}
public int linkProgram(int vertexShaderId, int fragmentShaderId) {
    final int programObjectId = glCreateProgram();
    if (programObjectId == 0) {
        Log.w(TAG, "Could not create new program");
        return 0;
    }
 
    glAttachShader(programObjectId, vertexShaderId);
    glAttachShader(programObjectId, fragmentShaderId);
    glLinkProgram(programObjectId);
 
    final int[] linkStatus = new int[1];
    glGetProgramiv(programObjectId, GL_LINK_STATUS, linkStatus, 0);
    Log.v(TAG, "Results of linking program:\n" + glGetProgramInfoLog(programObjectId));
    if (linkStatus[0] == 0) {
        glDeleteProgram(programObjectId);
        Log.w(TAG, "Linking of program failed.");
        return 0;
    }
 
    glValidateProgram(programObjectId);
    final int[] validateStatus = new int[1];
    glGetProgramiv(programObjectId, GL_VALIDATE_STATUS, validateStatus, 0);
    Log.v(TAG, "Results of validating program: " + validateStatus[0]
            + "\nLog:" + glGetProgramInfoLog(programObjectId));
    if (validateStatus[0] == 0) {
        Log.w(TAG, "Validation program failed.");
        return 0;
    }
 
    return programObjectId;
}

Initialize values

  • Set the color to clear the screen
  • Obtain the shaders code in string format
  • Link and use the shader program
  • As we are working with fixed triangles, assign shader variable values
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
String vertexShaderSource = Utils.ResourcesReader(context, R.raw.vertex);
String fragmentShaderSource = Utils.ResourcesReader(context, R.raw.fragment);
 
int vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);
int fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
program = linkProgram(vertexShader, fragmentShader);
glUseProgram(program);
 
uColorLocation = glGetUniformLocation(program, U_COLOR);
aPositionLocation = glGetAttribLocation(program, A_POSITION);
vertexData.position(0);
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
        false, 0, vertexData);
glEnableVertexAttribArray(aPositionLocation);

Render

glClear(GL_COLOR_BUFFER_BIT);
 
glUniform4f(uColorLocation, 1.0f, 0f, 0f, 1.0f);
glDrawArrays(GL_TRIANGLES, 0, 3);
 
glUniform4f(uColorLocation, 0.0f, 0f, 1f, 1.0f);
glDrawArrays(GL_TRIANGLES, 3, 3);

Functional examples

Color

Define vertices, color and indexs

float[] tableVerticesWithTriangles = {
        // x, y          r,g,b
        0, 0.5f,         1,0,0,
        -0.5f,  0,       0,1,0,
        0.5f,  0,        0,0,1
};
 
vertexData = ByteBuffer
        .allocateDirect(tableVerticesWithTriangles.length * BYTES_PER_FLOAT)
        .order(ByteOrder.nativeOrder())
        .asFloatBuffer();
vertexData.put(tableVerticesWithTriangles);
 
byte[] tableIndices = {0, 1, 2};
indexArray =  ByteBuffer.allocateDirect(3).put(tableIndices);

Shaders

Vertex Shader

attribute vec4 a_Position;  
attribute vec4 a_Color;

varying vec4 v_Color;

void main()                    
{                            
    v_Color = a_Color;
    gl_Position = a_Position;
}

Fragment Shader

precision mediump float; 				
varying vec4 v_Color;      	   								
  
void main()                    		
{                              	
    gl_FragColor = v_Color;                                  		
}

Render

  • Obtain the attributes location for color and position.
  • Write color and position (in this case this step could be performed only once).
  • Enable them.
  • Draw them.
// next step is really important in java
vertexData.position(0);
indexArray.position(0);
 
glClear(GL_COLOR_BUFFER_BIT);
 
aColorLocation = glGetAttribLocation(program, A_COLOR);
aPositionLocation = glGetAttribLocation(program, A_POSITION);
 
 
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
        false, STRIDE, vertexData);
glEnableVertexAttribArray(aPositionLocation);
 
vertexData.position(POSITION_COMPONENT_COUNT);
glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT,
        false, STRIDE, vertexData);
glEnableVertexAttribArray(aColorLocation);
 
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, indexArray);
 
glDisableVertexAttribArray(aPositionLocation);
glDisableVertexAttribArray(aColorLocation);

Constant values

private static final int BYTES_PER_FLOAT = 4;
private static final int POSITION_COMPONENT_COUNT = 2;
private static final int COLOR_COMPONENT_COUNT = 3;
private static final int STRIDE = (POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT) * BYTES_PER_FLOAT;

Example

Transformaciones y proyecciones

Texturas

Cargar texturas

  1. Read the texture.
  2. Bind the texture.
  3. Set filtering: a default must be set, or the texture will be black.
  4. Load the bitmap into the bound texture with texImage2D.
  5. Unbind from the texture with glBindTexture(GL_TEXTURE_2D, 0).
public static int loadTexture(Context context, int resourceId) {
    final int[] textureObjectIds = new int[1];
    glGenTextures(1, textureObjectIds, 0);
    if (textureObjectIds[0] == 0) {
        Log.w(TAG, "Could not generate a new OpenGL texture object.");
        return 0;
    }
 
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inScaled = false;
    final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options);
    if (bitmap == null) {
        Log.w(TAG, "Resource ID " + resourceId + " could not be decoded.");
        glDeleteTextures(1, textureObjectIds, 0);
        return 0;
    }
    glBindTexture(GL_TEXTURE_2D, textureObjectIds[0]);
 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
    texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    bitmap.recycle();
 
    Log.w(TAG, "Texture loaded");
 
    return textureObjectIds[0];
}

Podríamos cargar mipmaps:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);

Shaders

Vertex

attribute vec4 a_Position;
attribute vec2 a_TextureCoordinates;
varying vec2 v_TextureCoordinates;

void main()
{
    v_TextureCoordinates = a_TextureCoordinates;
    gl_Position = a_Position;
}

Fragment

precision mediump float;
uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;

void main()
{
    gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
}

When render

vertexData.position(0);
indexArray.position(0);
 
glClear(GL_COLOR_BUFFER_BIT);
 
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
        false, STRIDE, vertexData);
 
vertexData.position(POSITION_COMPONENT_COUNT);
glVertexAttribPointer(aTextCoordLocation, TEXTURE_COORDINATES_COMPONENT_COUNT, GL_FLOAT,
        false, STRIDE, vertexData);
 
glEnableVertexAttribArray(aPositionLocation);
glEnableVertexAttribArray(aTextCoordLocation);
 
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(uTextureUnitLocation, 0);
 
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, indexArray);
 
glDisableVertexAttribArray(aPositionLocation);
glDisableVertexAttribArray(aTextCoordLocation);

Setting these values:

float[] tableVerticesWithTriangles = {
        // x, y          s,t
        0, 0.5f,         0.5f,0,
        -0.5f,  0,       0,1,
        0.5f,  0,        1,1
};

And these constants:

private static final int BYTES_PER_FLOAT = 4;
private static final int POSITION_COMPONENT_COUNT = 2;
private static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2;
private static final int STRIDE = (POSITION_COMPONENT_COUNT + TEXTURE_COORDINATES_COMPONENT_COUNT) * BYTES_PER_FLOAT;

Code

Luces

wiki2/oglpipeline.txt · Última modificación: 2020/05/09 09:25 (editor externo)