OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Native.cpp File Reference

Using a GPU to create organic-looking 3-dimensional objects in OpenGL ES 3.0. More...

#include <cstdio>
#include <cstdlib>
#include <jni.h>
#include <android/log.h>
#include "Shader.h"
#include "Timer.h"
#include "Matrix.h"
#include "GLES3/gl3.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"
#include <string>
#include <cmath>

Go to the source code of this file.

Macros

#define LOG_TAG   "libNative"
 
#define LOGI(...)   __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
 
#define LOGE(...)   __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
 

Functions

void calc_mvp (Matrix &mvp)
 
void setupGraphics (int width, int height)
 
void renderFrame (void)
 
void cleanup ()
 
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_metaballs_NativeLibrary_init (JNIEnv *env, jclass jcls, jint width, jint height)
 
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_metaballs_NativeLibrary_step (JNIEnv *env, jclass jcls)
 
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_metaballs_NativeLibrary_uninit (JNIEnv *, jclass)
 

Variables

const char * spheres_updater_vert_shader
 
const char * spheres_updater_frag_shader
 
const char * scalar_field_vert_shader
 
const char * scalar_field_frag_shader
 
const char * marching_cubes_cells_vert_shader
 
const char * marching_cubes_cells_frag_shader
 
const char * marching_cubes_triangles_vert_shader
 
const char * marching_cubes_triangles_frag_shader
 
GLfloat model_time = 0.0f
 
const GLuint tesselation_level = 32
 
GLfloat isosurface_level = 12.0f
 
unsigned int window_width = 256
 
unsigned int window_height = 256
 
const GLuint samples_per_axis = tesselation_level
 
const GLuint samples_in_3d_space = samples_per_axis * samples_per_axis * samples_per_axis
 
const GLuint cells_per_axis = samples_per_axis - 1
 
const GLuint cells_in_3d_space = cells_per_axis * cells_per_axis * cells_per_axis
 
const GLuint vertices_per_triangle = 3
 
const GLuint triangles_per_cell = 5
 
const GLuint mc_vertices_per_cell = vertices_per_triangle * triangles_per_cell
 
const GLuint mc_cells_types_count = 256
 
const GLint tri_table [mc_cells_types_count *mc_vertices_per_cell]
 
Timer timer
 
const int n_spheres = 3
 
const int n_sphere_position_components = 4
 
Matrix mvp
 
GLuint spheres_updater_program_id = 0
 
GLuint spheres_updater_vert_shader_id = 0
 
GLuint spheres_updater_frag_shader_id = 0
 
GLuint spheres_updater_sphere_positions_buffer_object_id = 0
 
GLuint spheres_updater_transform_feedback_object_id = 0
 
const GLchar * spheres_updater_uniform_time_name = "time"
 
GLuint spheres_updater_uniform_time_id = 0
 
const GLchar * sphere_position_varying_name = "sphere_position"
 
GLuint scalar_field_program_id = 0
 
GLuint scalar_field_vert_shader_id = 0
 
GLuint scalar_field_frag_shader_id = 0
 
GLuint scalar_field_buffer_object_id = 0
 
GLuint scalar_field_transform_feedback_object_id = 0
 
const GLchar * scalar_field_uniform_samples_per_axis_name = "samples_per_axis"
 
GLuint scalar_field_uniform_samples_per_axis_id = 0
 
const GLchar * scalar_field_uniform_spheres_name = "spheres_uniform_block"
 
GLuint scalar_field_uniform_spheres_id = 0
 
const GLchar * scalar_field_value_varying_name = "scalar_field_value"
 
GLuint scalar_field_texture_object_id = 0
 
GLuint marching_cubes_cells_program_id = 0
 
GLuint marching_cubes_cells_vert_shader_id = 0
 
GLuint marching_cubes_cells_frag_shader_id = 0
 
const GLchar * marching_cubes_cells_uniform_cells_per_axis_name = "cells_per_axis"
 
GLuint marching_cubes_cells_uniform_cells_per_axis_id = 0
 
const GLchar * marching_cubes_cells_uniform_isolevel_name = "iso_level"
 
GLuint marching_cubes_cells_uniform_isolevel_id = 0
 
const GLchar * marching_cubes_cells_uniform_scalar_field_sampler_name = "scalar_field"
 
GLuint marching_cubes_cells_uniform_scalar_field_sampler_id = 0
 
const GLchar * marching_cubes_cells_varying_name = "cell_type_index"
 
GLuint marching_cubes_cells_transform_feedback_object_id = 0
 
GLuint marching_cubes_cells_types_buffer_id = 0
 
GLuint marching_cubes_cells_types_texture_object_id = 0
 
GLuint marching_cubes_triangles_program_id = 0
 
GLuint marching_cubes_triangles_frag_shader_id = 0
 
GLuint marching_cubes_triangles_vert_shader_id = 0
 
const GLchar * marching_cubes_triangles_uniform_samples_per_axis_name = "samples_per_axis"
 
GLuint marching_cubes_triangles_uniform_samples_per_axis_id = 0
 
const GLchar * marching_cubes_triangles_uniform_isolevel_name = "iso_level"
 
GLuint marching_cubes_triangles_uniform_isolevel_id = 0
 
const GLchar * marching_cubes_triangles_uniform_time_name = "time"
 
GLuint marching_cubes_triangles_uniform_time_id = 0
 
const GLchar * marching_cubes_triangles_uniform_mvp_name = "mvp"
 
GLuint marching_cubes_triangles_uniform_mvp_id = 0
 
const GLchar * marching_cubes_triangles_uniform_cell_types_sampler_name = "cell_types"
 
GLuint marching_cubes_triangles_uniform_cell_types_sampler_id = 0
 
const GLchar * marching_cubes_triangles_uniform_scalar_field_sampler_name = "scalar_field"
 
GLuint marching_cubes_triangles_uniform_scalar_field_sampler_id = 0
 
const GLchar * marching_cubes_triangles_uniform_sphere_positions_name = "sphere_positions_uniform_block"
 
GLuint marching_cubes_triangles_uniform_sphere_positions_id = 0
 
const GLchar * marching_cubes_triangles_uniform_tri_table_sampler_name = "tri_table"
 
GLuint marching_cubes_triangles_uniform_tri_table_sampler_id = 0
 
GLuint marching_cubes_triangles_lookup_table_texture_id = 0
 
GLuint marching_cubes_triangles_vao_id = 0
 

Detailed Description

Using a GPU to create organic-looking 3-dimensional objects in OpenGL ES 3.0.

This tutorial demonstrates how a GPU can be used to render organic-looking 3D objects using OpenGL ES 3.0's transform feedback feature. All calculations are implemented on the GPU's shader processors. Surface triangulation is performed using the Marching Cubes algorithm. The Phong model is used for lighting metaball objects. 3D textures are used to provide access to three dimentional arrays in shaders.

For more information please see documentation.

Definition in file Native.cpp.

Macro Definition Documentation

#define LOG_TAG   "libNative"

Definition at line 52 of file Native.cpp.

#define LOGE (   ...)    __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

Definition at line 54 of file Native.cpp.

#define LOGI (   ...)    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

Definition at line 53 of file Native.cpp.

Function Documentation

void calc_mvp ( Matrix mvp)

Calculates combined model view and projection matrix.

Parameters
mvpcombined mvp matrix

Definition at line 1220 of file Native.cpp.

void cleanup ( )

Deinitialises OpenGL ES environment.

Definition at line 1719 of file Native.cpp.

JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_metaballs_NativeLibrary_init ( JNIEnv *  env,
jclass  jcls,
jint  width,
jint  height 
)

Definition at line 1749 of file Native.cpp.

JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_metaballs_NativeLibrary_step ( JNIEnv *  env,
jclass  jcls 
)

Definition at line 1756 of file Native.cpp.

JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_metaballs_NativeLibrary_uninit ( JNIEnv *  ,
jclass   
)

Definition at line 1763 of file Native.cpp.

void renderFrame ( void  )

Draws one frame.

Definition at line 1536 of file Native.cpp.

void setupGraphics ( int  width,
int  height 
)

Initialises OpenGL ES and model environments.

Parameters
widthwindow width reported by operating system
heightwindow width reported by operating system

Definition at line 1256 of file Native.cpp.

Variable Documentation

const GLuint cells_in_3d_space = cells_per_axis * cells_per_axis * cells_per_axis

Amount of cells in 3D space.

Definition at line 777 of file Native.cpp.

const GLuint cells_per_axis = samples_per_axis - 1

Amount of cells per each axis.

Definition at line 776 of file Native.cpp.

GLfloat isosurface_level = 12.0f

Scalar field's isosurface level.

Definition at line 769 of file Native.cpp.

const char* marching_cubes_cells_frag_shader
Initial value:
= "#version 300 es\n"
"\n"
"/** Shader entry point. */\n"
"void main()\n"
"{\n"
"}\n"

Dummy fragment shader for a program object to successfully link. Fragment shader is not used in this stage, but needed for a program object to successfully link.

Definition at line 371 of file Native.cpp.

GLuint marching_cubes_cells_frag_shader_id = 0

Fragment shader id for cell splitting stage.

Definition at line 1131 of file Native.cpp.

GLuint marching_cubes_cells_program_id = 0

Program object id for cell splitting stage.

Definition at line 1127 of file Native.cpp.

GLuint marching_cubes_cells_transform_feedback_object_id = 0

Id of transform feedback object to keep cell types buffer binding.

Definition at line 1152 of file Native.cpp.

GLuint marching_cubes_cells_types_buffer_id = 0

Id of a buffer object to hold result cell type data.

Definition at line 1155 of file Native.cpp.

GLuint marching_cubes_cells_types_texture_object_id = 0

Id of a texture object to hold result cell type data.

Definition at line 1158 of file Native.cpp.

GLuint marching_cubes_cells_uniform_cells_per_axis_id = 0

Location of cells_per_axis uniform.

Definition at line 1136 of file Native.cpp.

const GLchar* marching_cubes_cells_uniform_cells_per_axis_name = "cells_per_axis"

Name of cells_per_axis uniform.

Definition at line 1134 of file Native.cpp.

GLuint marching_cubes_cells_uniform_isolevel_id = 0

Location of iso_level uniform.

Definition at line 1141 of file Native.cpp.

const GLchar* marching_cubes_cells_uniform_isolevel_name = "iso_level"

Name of iso_level uniform.

Definition at line 1139 of file Native.cpp.

GLuint marching_cubes_cells_uniform_scalar_field_sampler_id = 0

Location of scalar_field uniform.

Definition at line 1146 of file Native.cpp.

const GLchar* marching_cubes_cells_uniform_scalar_field_sampler_name = "scalar_field"

Name of scalar_field uniform.

Definition at line 1144 of file Native.cpp.

const GLchar* marching_cubes_cells_varying_name = "cell_type_index"

Cell_type_index output variable's name.

Definition at line 1149 of file Native.cpp.

const char* marching_cubes_cells_vert_shader

The Marching Cube algorithm cell splitting stage vertex shader.

In this vertex shader we analyse the isosurface in each cell of space and assign one of 256 possible types to each cell. The cell type data for each cell is returned in cell_type_index output variable.

Definition at line 250 of file Native.cpp.

GLuint marching_cubes_cells_vert_shader_id = 0

Vertex shader id for cell splitting stage.

Definition at line 1129 of file Native.cpp.

const char* marching_cubes_triangles_frag_shader

In this shader we render triangles emitted by the mc_triangles_generator_shader vertex shader. The shader uses one directional light source in Phong lighting model. The light source moves on spherical surface around metaballs.

Definition at line 696 of file Native.cpp.

GLuint marching_cubes_triangles_frag_shader_id = 0

Vertex shader id for marching cubes algorthim's for rendering stage.

Definition at line 1165 of file Native.cpp.

GLuint marching_cubes_triangles_lookup_table_texture_id = 0

Id of a texture object to hold triangle look-up table data.

Definition at line 1210 of file Native.cpp.

GLuint marching_cubes_triangles_program_id = 0

Program object id for marching cubes algorthim's for rendering stage.

Definition at line 1163 of file Native.cpp.

GLuint marching_cubes_triangles_uniform_cell_types_sampler_id = 0

Location of cell_types uniform.

Definition at line 1192 of file Native.cpp.

const GLchar* marching_cubes_triangles_uniform_cell_types_sampler_name = "cell_types"

Name of cell_types uniform.

Definition at line 1190 of file Native.cpp.

GLuint marching_cubes_triangles_uniform_isolevel_id = 0

Location of iso_level uniform.

Definition at line 1177 of file Native.cpp.

const GLchar* marching_cubes_triangles_uniform_isolevel_name = "iso_level"

Name of iso_level uniform.

Definition at line 1175 of file Native.cpp.

GLuint marching_cubes_triangles_uniform_mvp_id = 0

Location of mvp uniform.

Definition at line 1187 of file Native.cpp.

const GLchar* marching_cubes_triangles_uniform_mvp_name = "mvp"

Name of mvp uniform.

Definition at line 1185 of file Native.cpp.

GLuint marching_cubes_triangles_uniform_samples_per_axis_id = 0

Location of samples_per_axis uniform.

Definition at line 1172 of file Native.cpp.

const GLchar* marching_cubes_triangles_uniform_samples_per_axis_name = "samples_per_axis"

Name of samples_per_axis uniform.

Definition at line 1170 of file Native.cpp.

GLuint marching_cubes_triangles_uniform_scalar_field_sampler_id = 0

Location of scalar_field uniform.

Definition at line 1197 of file Native.cpp.

const GLchar* marching_cubes_triangles_uniform_scalar_field_sampler_name = "scalar_field"

Name of scalar_field uniform.

Definition at line 1195 of file Native.cpp.

GLuint marching_cubes_triangles_uniform_sphere_positions_id = 0

Index of sphere_positions_uniform_block uniform block.

Definition at line 1202 of file Native.cpp.

const GLchar* marching_cubes_triangles_uniform_sphere_positions_name = "sphere_positions_uniform_block"

Name of sphere_positions_uniform_block uniform block.

Definition at line 1200 of file Native.cpp.

GLuint marching_cubes_triangles_uniform_time_id = 0

Location of time uniform.

Definition at line 1182 of file Native.cpp.

const GLchar* marching_cubes_triangles_uniform_time_name = "time"

Name of time uniform.

Definition at line 1180 of file Native.cpp.

GLuint marching_cubes_triangles_uniform_tri_table_sampler_id = 0

Location of tri_table uniform.

Definition at line 1207 of file Native.cpp.

const GLchar* marching_cubes_triangles_uniform_tri_table_sampler_name = "tri_table"

Name of tri_table uniform.

Definition at line 1205 of file Native.cpp.

GLuint marching_cubes_triangles_vao_id = 0

Id of vertex array object.

Definition at line 1213 of file Native.cpp.

const char* marching_cubes_triangles_vert_shader

The vertex shader generates a set of triangles for each cell appropriate for the cell type.

In this shader we generate exactly (3 vertices * 5 triangles per cell * amount of cells the scalar field is split to) triangle vertices. A one shader instance processes only one triangle vertex. Due to requirement for a vertex shader instance to issue a vertex, it issues a vertex in any case, including a dummy triangles, but the dummy triangles has all vertices set to point O and will not be rendered.

Definition at line 388 of file Native.cpp.

GLuint marching_cubes_triangles_vert_shader_id = 0

Fragment shader id for marching cubes algorthim's for rendering stage.

Definition at line 1167 of file Native.cpp.

const GLuint mc_cells_types_count = 256

Amount of cell types.

Definition at line 781 of file Native.cpp.

const GLuint mc_vertices_per_cell = vertices_per_triangle * triangles_per_cell

Amount of vertices in tri_table representing triangles by vertices for one cell.

Definition at line 780 of file Native.cpp.

GLfloat model_time = 0.0f

Time (in seconds), increased each rendering iteration.

Definition at line 767 of file Native.cpp.

Matrix mvp

Matrix that transforms vertices from model space to perspective projected world space.

Definition at line 1068 of file Native.cpp.

const int n_sphere_position_components = 4

Amount of components in sphere position varying.

Definition at line 1065 of file Native.cpp.

const int n_spheres = 3

Amount of spheres defining scalar field. This value should be synchronized between all files.

Definition at line 1062 of file Native.cpp.

const GLuint samples_in_3d_space = samples_per_axis * samples_per_axis * samples_per_axis

Amount of samples in 3D space.

Definition at line 775 of file Native.cpp.

const GLuint samples_per_axis = tesselation_level

Amount of samples we break scalar space into (per each axis).

Definition at line 774 of file Native.cpp.

GLuint scalar_field_buffer_object_id = 0

Buffer object id to store calculated values of scalar field.

Definition at line 1103 of file Native.cpp.

const char* scalar_field_frag_shader
Initial value:
= "#version 300 es\n"
"\n"
"/** Shader entry point. */\n"
"void main()\n"
"{\n"
"}\n"

Dummy fragment shader for a program object to successfully link. Fragment shader is not used in this stage, but needed for a program object to successfully link.

Definition at line 236 of file Native.cpp.

GLuint scalar_field_frag_shader_id = 0

Fragment shader id for scalar field generator stage.

Definition at line 1100 of file Native.cpp.

GLuint scalar_field_program_id = 0

Program object id for scalar field generator stage.

Definition at line 1096 of file Native.cpp.

GLuint scalar_field_texture_object_id = 0

Id of a 3D texture object storing scalar field data.

Definition at line 1122 of file Native.cpp.

GLuint scalar_field_transform_feedback_object_id = 0

Id of transform feedback object to keep scalar field buffer binding.

Definition at line 1106 of file Native.cpp.

GLuint scalar_field_uniform_samples_per_axis_id = 0

Location of samples_per_axis uniform.

Definition at line 1111 of file Native.cpp.

const GLchar* scalar_field_uniform_samples_per_axis_name = "samples_per_axis"

Name of samples_per_axis uniform.

Definition at line 1109 of file Native.cpp.

GLuint scalar_field_uniform_spheres_id = 0

Index of uniform block storing sphere data.

Definition at line 1116 of file Native.cpp.

const GLchar* scalar_field_uniform_spheres_name = "spheres_uniform_block"

Name of uniform block storing sphere data.

Definition at line 1114 of file Native.cpp.

const GLchar* scalar_field_value_varying_name = "scalar_field_value"

Scalar_field_value output variable's name.

Definition at line 1119 of file Native.cpp.

const char* scalar_field_vert_shader

This vertex shader calculates a scalar field and stores it in the scalar_field_value output variable. As input data we use sphere positions calculated in a previous stage and passed into the shader as a uniform block.

Definition at line 126 of file Native.cpp.

GLuint scalar_field_vert_shader_id = 0

Vertex shader id for scalar field generator stage.

Definition at line 1098 of file Native.cpp.

const GLchar* sphere_position_varying_name = "sphere_position"

Sphere position output variable's name.

Definition at line 1091 of file Native.cpp.

const char* spheres_updater_frag_shader
Initial value:
= "#version 300 es\n"
"\n"
"/** Shader entry point. */\n"
"void main()\n"
"{\n"
"}\n"

Dummy fragment shader for a program object to successfully link. Fragment shader is not used in this stage, but needed for a program object to successfully link.

Definition at line 114 of file Native.cpp.

GLuint spheres_updater_frag_shader_id = 0

Fragment shader id for sphere update stage.

Definition at line 1077 of file Native.cpp.

GLuint spheres_updater_program_id = 0

Program object id for sphere update stage.

Definition at line 1073 of file Native.cpp.

GLuint spheres_updater_sphere_positions_buffer_object_id = 0

Buffer object id to store calculated sphere positions.

Definition at line 1080 of file Native.cpp.

GLuint spheres_updater_transform_feedback_object_id = 0

Id of transform feedback object to keep sphere update stage buffer bindings.

Definition at line 1083 of file Native.cpp.

GLuint spheres_updater_uniform_time_id = 0

Location of time uniform for sphere positions update stage.

Definition at line 1088 of file Native.cpp.

const GLchar* spheres_updater_uniform_time_name = "time"

Name of time uniform for sphere positions update stage.

Definition at line 1086 of file Native.cpp.

const char* spheres_updater_vert_shader

In this vertex shader we calculate the sphere positions according to the specified time moment. The shader contains an initial sphere positions and data required to calculate the sphere positions. Each shader instance updates one sphere position, which is returned in the sphere_position output variable.

Definition at line 64 of file Native.cpp.

GLuint spheres_updater_vert_shader_id = 0

Vertex shader id for sphere update stage.

Definition at line 1075 of file Native.cpp.

const GLuint tesselation_level = 32

Level of details you would like to split model into. Please use values from th range [8..256].

Definition at line 768 of file Native.cpp.

Timer timer

Instance of a timer to measure time moments.

Definition at line 1059 of file Native.cpp.

const GLint tri_table[mc_cells_types_count *mc_vertices_per_cell]

The array that is used for cell triangularization. Each row in table represents one cell type. Each cell type contains up to 5 triangles. Each triangle is defined by 3 sequential vertices. These vertices are "middle" points of the cell edges specified in this table. For example cell type 0 (see first line) does not define any triangles, while cell type 1 (see second line) defines one triangle consisting of "middle" points of edges 0,8 and 3 of a cell. "Middle" points are base points and can be moved closer to edge beginning point or edge ending point. Edge numeration is according to the Marching Cubes algorithm. There are exactly 256 cell types due to each vertex having only 2 states: it can be below isosurface or above. Thus (having 8 corners for each cubic cell) we have 2^8 = 256 cell types.

Table data taken from http://paulbourke.net/geometry/polygonise/

Definition at line 797 of file Native.cpp.

const GLuint triangles_per_cell = 5

Amount of triangles that can be generated for a single cell by the Marching Cubes algorithm.

Definition at line 779 of file Native.cpp.

const GLuint vertices_per_triangle = 3

Amount of vertices that defines one triangle.

Definition at line 778 of file Native.cpp.

unsigned int window_height = 256

Window height resolution (pixels).

Definition at line 771 of file Native.cpp.

unsigned int window_width = 256

Window width resolution (pixels).

Definition at line 770 of file Native.cpp.