Skip to content

Commit 1261121

Browse files
committed
repository explorer + smoothing + renderer factory leak
1 parent af232be commit 1261121

File tree

9 files changed

+425
-161
lines changed

9 files changed

+425
-161
lines changed

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ The application does not use any third party library.
1313
* Collada format (DAE): https://en.wikipedia.org/wiki/COLLADA
1414

1515

16-
News (10/10/2020)
16+
News (02/02/2022)
1717
=================
1818

1919
* /¡\ repo moved to the3deers organization + MIT License 2020
20-
* New version released 3.1.0
21-
* Skybox + background extras
22-
* Collada support improved - fixed #147
20+
* New version released 3.2.0
21+
* Repository Explorer improved
22+
* Smoothing implementation fixed
23+
* Fixed memory leak
2324

2425

2526

@@ -192,6 +193,10 @@ ChangeLog
192193

193194
(f) fixed, (i) improved, (n) new feature
194195

196+
- 3.2.0 (02/02/2022)
197+
- (i) repository explorer improved - multiple index files
198+
- (f) smoothing fixed
199+
- (f) fixed renderer memory leak
195200
- 3.1.1 (28/10/2021)
196201
- (f) google play required library upgrades
197202
- (f) spanish menu fixed

app/src/main/java/org/andresoviedo/app/model3D/view/MenuActivity.java

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.andresoviedo.app.model3D.view;
22

33
import android.Manifest;
4+
import android.app.AlertDialog;
45
import android.app.ListActivity;
56
import android.app.ProgressDialog;
67
import android.content.ActivityNotFoundException;
@@ -26,16 +27,18 @@
2627

2728
import java.io.File;
2829
import java.io.IOException;
30+
import java.net.MalformedURLException;
2931
import java.net.URI;
3032
import java.net.URISyntaxException;
33+
import java.net.URL;
3134
import java.util.HashMap;
3235
import java.util.List;
3336
import java.util.Locale;
3437
import java.util.Map;
3538

3639
public class MenuActivity extends ListActivity {
3740

38-
private static final String REPO_URL = "https://github.com/the3deers/android-3D-model-viewer/raw/master/models/index";
41+
private static final URL REPO_URL = createURL("https://github.com/the3deers/android-3D-model-viewer/raw/master/models/index");
3942
private static final int REQUEST_READ_EXTERNAL_STORAGE = 1000;
4043
private static final int REQUEST_INTERNET_ACCESS = 1001;
4144
private static final int REQUEST_READ_CONTENT_PROVIDER = 1002;
@@ -44,7 +47,7 @@ public class MenuActivity extends ListActivity {
4447
private static final int REQUEST_CODE_OPEN_MATERIAL = 1102;
4548
private static final int REQUEST_CODE_OPEN_TEXTURE = 1103;
4649
private static final int REQUEST_CODE_ADD_FILES = 1200;
47-
private static final String SUPPORTED_FILE_TYPES_REGEX = "(?i).*\\.(obj|stl|dae)";
50+
private static final String SUPPORTED_FILE_TYPES_REGEX = "(?i).*\\.(obj|stl|dae|index)";
4851

4952

5053
private enum Action {
@@ -56,6 +59,13 @@ private enum Action {
5659
*/
5760
private Map<String, Object> loadModelParameters = new HashMap<>();
5861

62+
private static URL createURL(String url) {
63+
try {
64+
return new URL(url);
65+
} catch(MalformedURLException e){
66+
throw new RuntimeException(e);
67+
}
68+
}
5969
@Override
6070
protected void onCreate(Bundle savedInstanceState) {
6171
super.onCreate(savedInstanceState);
@@ -127,7 +137,7 @@ private void loadModel() {
127137
if (which == 0) {
128138
loadModelFromAssets();
129139
} else if (which == 1) {
130-
loadModelFromRepository();
140+
loadModelFromRepository(REPO_URL);
131141
} else if (which == 2) {
132142
loadModelFromContentProvider();
133143
} else {
@@ -147,15 +157,16 @@ private void loadModelFromAssets() {
147157
});
148158
}
149159

150-
private void loadModelFromRepository() {
160+
private void loadModelFromRepository(URL url) {
151161
if (AndroidUtils.checkPermission(this, Manifest.permission.INTERNET, REQUEST_INTERNET_ACCESS)) {
152-
new LoadRepoIndexTask().execute();
162+
new LoadRepoIndexTask().execute(url);
153163
}
154164
}
155165

156-
class LoadRepoIndexTask extends AsyncTask<Void, Integer, List<String>> {
166+
class LoadRepoIndexTask extends AsyncTask<URL, Integer, List<String>> {
157167

158168
private final ProgressDialog dialog;
169+
private AlertDialog.Builder chooser;
159170

160171
public LoadRepoIndexTask() {
161172
this.dialog = new ProgressDialog(MenuActivity.this);
@@ -170,8 +181,36 @@ protected void onPreExecute() {
170181
}
171182

172183
@Override
173-
protected List<String> doInBackground(Void... voids) {
174-
return ContentUtils.getIndex(REPO_URL);
184+
protected List<String> doInBackground(URL... urls) {
185+
186+
// model files
187+
final List<String> files = ContentUtils.readLines(urls[0].toString());
188+
189+
// optional icons
190+
Map<String, byte[]> icons = null;
191+
try {
192+
icons = ContentUtils.readFiles(new URL(urls[0].toString()+".icons.zip"));
193+
} catch (MalformedURLException ex) {
194+
Log.e("MenuActivity", ex.getMessage(), ex);
195+
}
196+
197+
// chooser
198+
chooser = ContentUtils.createChooserDialog(MenuActivity.this, "Select file", null,
199+
files, icons, SUPPORTED_FILE_TYPES_REGEX,
200+
(String file) -> {
201+
if (file != null) {
202+
if (file.endsWith(".index")) {
203+
try {
204+
loadModelFromRepository(new URL(file));
205+
} catch (MalformedURLException e) {
206+
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
207+
}
208+
} else {
209+
launchModelRendererActivity(Uri.parse(file));
210+
}
211+
}
212+
});
213+
return files;
175214
}
176215

177216
@Override
@@ -183,13 +222,8 @@ protected void onPostExecute(List<String> strings) {
183222
Toast.makeText(MenuActivity.this, "Couldn't load repo index", Toast.LENGTH_LONG).show();
184223
return;
185224
}
186-
ContentUtils.createChooserDialog(MenuActivity.this, "Select file", null,
187-
strings, SUPPORTED_FILE_TYPES_REGEX,
188-
(String file) -> {
189-
if (file != null) {
190-
launchModelRendererActivity(Uri.parse(file));
191-
}
192-
});
225+
226+
chooser.create().show();
193227
}
194228
}
195229

@@ -239,7 +273,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
239273
loadModelFromContentProvider();
240274
break;
241275
case REQUEST_INTERNET_ACCESS:
242-
loadModelFromRepository();
276+
loadModelFromRepository(REPO_URL);
243277
break;
244278
case REQUEST_CODE_LOAD_MODEL:
245279
if (resultCode != RESULT_OK) {

engine/src/main/java/org/andresoviedo/android_3d_model_engine/drawer/RendererFactory.java

Lines changed: 29 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ public class RendererFactory {
3939
/**
4040
* list of opengl drawers
4141
*/
42-
private Map<String, GLES20Renderer> drawers = new HashMap<>();
43-
44-
private final String[] shaderIdTemp = new String[3];
42+
private Map<Shader, GLES20Renderer> drawers = new HashMap<>();
4543

4644
public RendererFactory(Context context) throws IllegalAccessException, IOException {
4745

@@ -68,17 +66,17 @@ public Renderer getDrawer(Object3DData obj, boolean usingSkyBox, boolean usingTe
6866
boolean isColoured = drawColors && obj != null && (obj.getColorsBuffer() != null || obj
6967
.getColorsBuffer() != null);
7068

71-
final String[] shaderId = getShaderId(usingSkyBox, isAnimated, isUsingLights, isTextured, isColoured);
69+
final Shader shader = getShader(usingSkyBox, isAnimated, isUsingLights, isTextured, isColoured);
7270

7371
// get cached drawer
74-
GLES20Renderer drawer = drawers.get(shaderId[0]);
72+
GLES20Renderer drawer = drawers.get(shader);
7573
if (drawer != null) return drawer;
7674

7775
// build drawer
78-
String vertexShaderCode = shadersCode.get(shaderId[1]);
79-
String fragmentShaderCode = shadersCode.get(shaderId[2]);
76+
String vertexShaderCode = shadersCode.get(shader.vertexShaderCode);
77+
String fragmentShaderCode = shadersCode.get(shader.fragmentShaderCode);
8078
if (vertexShaderCode == null || fragmentShaderCode == null) {
81-
Log.e("RendererFactory", "Shaders not found for " + shaderId[0]);
79+
Log.e("RendererFactory", "Shaders not found for " + shader.id);
8280
return null;
8381
}
8482

@@ -94,119 +92,86 @@ public Renderer getDrawer(Object3DData obj, boolean usingSkyBox, boolean usingTe
9492
Log.v("RendererFactory", "---------- Fragment shader ----------\n");
9593
Log.v("RendererFactory", fragmentShaderCode);
9694
Log.v("RendererFactory", "-------------------------------------\n");
97-
drawer = GLES20Renderer.getInstance(shaderId[0], vertexShaderCode, fragmentShaderCode);
95+
drawer = GLES20Renderer.getInstance(shader.id, vertexShaderCode, fragmentShaderCode);
9896

9997
// cache drawer
100-
drawers.put(shaderId[0], drawer);
98+
drawers.put(shader, drawer);
10199

102100
// return drawer
103101
return drawer;
104102
}
105103

106104
@NonNull
107-
private String[] getShaderId(boolean isUsingSkyBox, boolean isAnimated, boolean isUsingLights, boolean isTextured, boolean
105+
private Shader getShader(boolean isUsingSkyBox, boolean isAnimated, boolean isUsingLights, boolean isTextured, boolean
108106
isColoured) {
109107

110108
if (isUsingSkyBox){
111-
shaderIdTemp[0]="shader_skybox_";
112-
shaderIdTemp[1]="shader_skybox_vert";
113-
shaderIdTemp[2]="shader_skybox_frag";
114-
return shaderIdTemp;
109+
return Shader.SKYBOX;
115110
}
111+
112+
Shader ret = null;
116113
if (isAnimated){
117114
if (isUsingLights){
118115
if (isTextured){
119116
if (isColoured){
120-
shaderIdTemp[0]="shader_anim_light_texture_colors_";
121-
shaderIdTemp[1]="shader_anim_light_texture_colors_vert";
122-
shaderIdTemp[2]="shader_anim_light_texture_colors_frag";
117+
ret = Shader.ANIM_LIGHT_TEXTURE_COLORS;
123118
} else {
124-
shaderIdTemp[0]="shader_anim_light_texture_";
125-
shaderIdTemp[1]="shader_anim_light_texture_vert";
126-
shaderIdTemp[2]="shader_anim_light_texture_frag";
119+
ret = Shader.ANIM_LIGHT_TEXTURE;
127120
}
128121
} else{
129122
if (isColoured){
130-
shaderIdTemp[0]="shader_anim_light_colors_";
131-
shaderIdTemp[1]="shader_anim_light_colors_vert";
132-
shaderIdTemp[2]="shader_anim_light_colors_frag";
123+
ret = Shader.ANIM_LIGHT_COLORS;
133124
} else {
134-
shaderIdTemp[0]="shader_anim_light_";
135-
shaderIdTemp[1]="shader_anim_light_vert";
136-
shaderIdTemp[2]="shader_anim_light_frag";
125+
ret = Shader.ANIM_LIGHT;
137126
}
138127
}
139128
} else{
140129
if (isTextured){
141130
if (isColoured){
142-
shaderIdTemp[0]="shader_anim_texture_colors_";
143-
shaderIdTemp[1]="shader_anim_texture_colors_vert";
144-
shaderIdTemp[2]="shader_anim_texture_colors_frag";
131+
ret = Shader.ANIM_TEXTURE_COLORS;
145132
} else {
146-
shaderIdTemp[0]="shader_anim_texture_";
147-
shaderIdTemp[1]="shader_anim_texture_vert";
148-
shaderIdTemp[2]="shader_anim_texture_frag";
133+
ret = Shader.ANIM_TEXTURE;
149134
}
150135
} else{
151136
if (isColoured){
152-
shaderIdTemp[0]="shader_anim_colors_";
153-
shaderIdTemp[1]="shader_anim_colors_vert";
154-
shaderIdTemp[2]="shader_anim_colors_frag";
137+
ret = Shader.ANIM_COLORS;
155138
} else {
156-
shaderIdTemp[0]="shader_anim_";
157-
shaderIdTemp[1]="shader_anim_vert";
158-
shaderIdTemp[2]="shader_anim_frag";
139+
ret = Shader.ANIM;
159140
}
160141
}
161142
}
162143
} else {
163144
if (isUsingLights){
164145
if (isTextured){
165146
if (isColoured){
166-
shaderIdTemp[0]="shader_light_texture_colors_";
167-
shaderIdTemp[1]="shader_light_texture_colors_vert";
168-
shaderIdTemp[2]="shader_light_texture_colors_frag";
147+
ret = Shader.LIGHT_TEXTURE_COLORS;
169148
} else {
170-
shaderIdTemp[0]="shader_light_texture_";
171-
shaderIdTemp[1]="shader_light_texture_vert";
172-
shaderIdTemp[2]="shader_light_texture_frag";
149+
ret = Shader.LIGHT_TEXTURE;
173150
}
174151
} else{
175152
if (isColoured){
176-
shaderIdTemp[0]="shader_light_colors_";
177-
shaderIdTemp[1]="shader_light_colors_vert";
178-
shaderIdTemp[2]="shader_light_colors_frag";
153+
ret = Shader.LIGHT_COLORS;
179154
} else {
180-
shaderIdTemp[0]="shader_light_";
181-
shaderIdTemp[1]="shader_light_vert";
182-
shaderIdTemp[2]="shader_light_frag";
155+
ret = Shader.LIGHT;
183156
}
184157
}
185158
} else{
186159
if (isTextured){
187160
if (isColoured){
188-
shaderIdTemp[0]="shader_texture_colors_";
189-
shaderIdTemp[1]="shader_texture_colors_vert";
190-
shaderIdTemp[2]="shader_texture_colors_frag";
161+
ret = Shader.TEXTURE_COLORS;
191162
} else{
192-
shaderIdTemp[0]="shader_texture_";
193-
shaderIdTemp[1]="shader_texture_vert";
194-
shaderIdTemp[2]="shader_texture_frag";
163+
ret = Shader.TEXTURE;
195164
}
196165
} else{
197166
if (isColoured){
198-
shaderIdTemp[0]="shader_colors_";
199-
shaderIdTemp[1]="shader_colors_vert";
200-
shaderIdTemp[2]="shader_colors_frag";
167+
ret = Shader.COLORS;
201168
} else{
202-
shaderIdTemp[0]="shader_";
203-
shaderIdTemp[1]="shader_vert";
204-
shaderIdTemp[2]="shader_frag";
169+
ret = Shader.SHADER;
205170
}
206171
}
207172
}
208173
}
209-
return shaderIdTemp;
174+
return ret;
210175
}
211176

212177
public Renderer getBoundingBoxDrawer() {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.andresoviedo.android_3d_model_engine.drawer;
2+
3+
4+
public enum Shader {
5+
6+
SKYBOX("skybox_", "shader_skybox_vert", "shader_skybox_frag"),
7+
ANIM_LIGHT_TEXTURE_COLORS("anim_light_texture_colors_", "shader_anim_light_texture_colors_vert", "shader_anim_light_texture_colors_frag"),
8+
ANIM_LIGHT_TEXTURE("anim_light_texture_", "shader_anim_light_texture_vert", "shader_anim_light_texture_frag"),
9+
ANIM_LIGHT_COLORS("anim_light_colors_", "shader_anim_light_colors_vert", "shader_anim_light_colors_frag"),
10+
ANIM_LIGHT("anim_light_", "shader_anim_light_vert", "shader_anim_light_frag"),
11+
ANIM_TEXTURE_COLORS("anim_texture_colors_", "shader_anim_texture_colors_vert", "shader_anim_texture_colors_frag"),
12+
ANIM_TEXTURE("anim_texture_", "shader_anim_texture_vert", "shader_anim_texture_frag"),
13+
ANIM_COLORS("anim_colors_", "shader_anim_colors_vert", "shader_anim_colors_frag"),
14+
ANIM("anim_", "shader_anim_vert", "shader_anim_frag"),
15+
LIGHT_TEXTURE_COLORS("light_texture_colors_", "shader_light_texture_colors_vert", "shader_light_texture_colors_frag"),
16+
LIGHT_TEXTURE("light_texture_", "shader_light_texture_vert", "shader_light_texture_frag"),
17+
LIGHT_COLORS("light_colors_", "shader_light_colors_vert", "shader_light_colors_frag"),
18+
LIGHT("light_", "shader_light_vert", "shader_light_frag"),
19+
TEXTURE_COLORS("texture_colors_", "shader_texture_colors_vert", "shader_texture_colors_frag"),
20+
TEXTURE("texture_", "shader_texture_vert", "shader_texture_frag"),
21+
COLORS("colors_", "shader_colors_vert", "shader_colors_frag"),
22+
SHADER("default", "shader_vert", "shader_frag");
23+
24+
String id;
25+
String vertexShaderCode;
26+
String fragmentShaderCode;
27+
28+
Shader (String id, String vertexShaderCode, String fragmentShaderCode){
29+
this.id = id;
30+
this.vertexShaderCode = vertexShaderCode;
31+
this.fragmentShaderCode = fragmentShaderCode;
32+
}
33+
}

0 commit comments

Comments
 (0)