Skip to content

Commit 68de152

Browse files
committed
#176 gltf normal map + emissive map
1 parent e5c67e4 commit 68de152

File tree

9 files changed

+193
-56
lines changed

9 files changed

+193
-56
lines changed
-2.82 MB
Loading
194 KB
Loading

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

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,9 @@ public void draw(Object3DData obj, float[] pMatrix, float[] vMatrix, int drawMod
169169
int mTextureHandle = -1;
170170
if (supportsTextures()) {
171171
if (textureId != -1) {
172-
setTexture(textureId);
172+
setTexture(textureId, "u_Texture", 0);
173173
mTextureHandle = setVBO("a_TexCoordinate", obj.getTextureBuffer(), TEXTURE_COORDS_PER_VERTEX);
174+
setFeatureFlag("u_Textured", true);
174175
}
175176
}
176177

@@ -278,32 +279,29 @@ private boolean supportsTextures() {
278279
return features.contains("a_TexCoordinate");
279280
}
280281

281-
private void setTextured(boolean textured) {
282-
int handle = GLES20.glGetUniformLocation(mProgram, "u_Textured");
282+
private void setFeatureFlag(String variableName, boolean enabled) {
283+
int handle = GLES20.glGetUniformLocation(mProgram, variableName);
283284
GLUtil.checkGlError("glGetUniformLocation");
284285

285-
GLES20.glUniform1i(handle, textured? 1 : 0);
286+
GLES20.glUniform1i(handle, enabled ? 1 : 0);
286287
GLUtil.checkGlError("glUniform1i");
287288
}
288289

289-
private void setTexture(int textureId) {
290-
int mTextureUniformHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture");
290+
private void setTexture(int textureId, String variableName, int shaderIndex) {
291+
int mTextureUniformHandle = GLES20.glGetUniformLocation(mProgram, variableName);
291292
GLUtil.checkGlError("glGetUniformLocation");
292293

293294
// Set the active texture unit to texture unit 0.
294-
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
295+
GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + shaderIndex);
295296
GLUtil.checkGlError("glActiveTexture");
296297

297298
// Bind to the texture in OpenGL
298299
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
299300
GLUtil.checkGlError("glBindTexture");
300301

301302
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
302-
GLES20.glUniform1i(mTextureUniformHandle, 0);
303+
GLES20.glUniform1i(mTextureUniformHandle, shaderIndex);
303304
GLUtil.checkGlError("glUniform1i");
304-
305-
// toggle texture feature on
306-
setTextured(true);
307305
}
308306

309307
private void setTextureCube(int textureId) {
@@ -484,7 +482,7 @@ private void drawObjectElement(Object3DData obj, int drawMode, int drawBufferTyp
484482

485483
// default is no textured
486484
if (supportsTextures()){
487-
setTextured(false);
485+
setFeatureFlag("u_Textured", false);
488486
}
489487

490488
if (element.getMaterial() != null) {
@@ -493,7 +491,19 @@ private void drawObjectElement(Object3DData obj, int drawMode, int drawBufferTyp
493491
obj.getColor() != null ? obj.getColor() : DEFAULT_COLOR, "vColor");
494492
}
495493
if (element.getMaterial().getTextureId() != -1 && supportsTextures()) {
496-
setTexture(element.getMaterial().getTextureId());
494+
setTexture(element.getMaterial().getTextureId(), "u_Texture", 0);
495+
setFeatureFlag("u_Textured",true);
496+
}
497+
498+
if (element.getMaterial().getNormalTextureId() != -1 && supportsTextures()) {
499+
setTexture(element.getMaterial().getNormalTextureId(), "u_NormalTexture", 1);
500+
setFeatureFlag("u_NormalTextured",true);
501+
}
502+
503+
if (obj.getMaterial().getEmissiveTextureId() != -1){
504+
// set normal texture
505+
setTexture(obj.getMaterial().getEmissiveTextureId(), "u_EmissiveTexture", 2);
506+
setFeatureFlag("u_EmissiveTextured", true);
497507
}
498508
}
499509

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ public Renderer getDrawer(Object3DData obj, boolean usingSkyBox, boolean usingTe
8686
vertexShaderCode = vertexShaderCode.replace("const int MAX_JOINTS = 60;","const int MAX_JOINTS = gl_MaxVertexUniformVectors > 60 ? 60 : gl_MaxVertexUniformVectors;");
8787

8888
// create drawer
89-
Log.v("RendererFactory", "\n---------- Vertex shader ----------\n");
89+
/*Log.v("RendererFactory", "\n---------- Vertex shader ----------\n");
9090
Log.v("RendererFactory", vertexShaderCode);
9191
Log.v("RendererFactory", "---------- Fragment shader ----------\n");
9292
Log.v("RendererFactory", fragmentShaderCode);
93-
Log.v("RendererFactory", "-------------------------------------\n");
93+
Log.v("RendererFactory", "-------------------------------------\n");*/
9494
drawer = GLES20Renderer.getInstance(shader.id, vertexShaderCode, fragmentShaderCode);
9595

9696
// cache drawer

engine/src/main/java/org/andresoviedo/android_3d_model_engine/model/Material.java

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@ public class Material {
2020
private float alpha = 1.0f;
2121

2222
// texture info
23-
private Bitmap bitmap;
23+
private Bitmap colorTexture;
2424
private String textureFile;
2525
private byte[] textureData;
26+
private Bitmap normalTexture;
27+
private Bitmap emissiveTexture;
2628

2729
// // Loaded by ModelRenderer (GLThread)
2830
private int textureId = -1;
31+
private int normalTextureId = -1;
32+
private int emissiveTextureId = -1;
2933
private float[] color;
3034

3135
public Material() {
@@ -85,12 +89,20 @@ public void setSpecular(float[] specular) {
8589
this.specular = specular;
8690
}
8791

88-
public void setBitmap(Bitmap bitmap){
89-
this.bitmap = bitmap;
92+
public void setColorTexture(Bitmap colorTexture){
93+
this.colorTexture = colorTexture;
9094
}
9195

92-
public Bitmap getBitmap() {
93-
return this.bitmap;
96+
public Bitmap getColorTexture() {
97+
return this.colorTexture;
98+
}
99+
100+
public Bitmap getNormalTexture() {
101+
return normalTexture;
102+
}
103+
104+
public void setNormalTexture(Bitmap normalTexture) {
105+
this.normalTexture = normalTexture;
94106
}
95107

96108
public String getTextureFile() {
@@ -117,6 +129,30 @@ public void setTextureId(int textureId) {
117129
this.textureId = textureId;
118130
}
119131

132+
public int getNormalTextureId() {
133+
return normalTextureId;
134+
}
135+
136+
public void setNormalTextureId(int normalTextureId) {
137+
this.normalTextureId = normalTextureId;
138+
}
139+
140+
public Bitmap getEmissiveTexture() {
141+
return emissiveTexture;
142+
}
143+
144+
public void setEmissiveTexture(Bitmap emissiveTexture) {
145+
this.emissiveTexture = emissiveTexture;
146+
}
147+
148+
public int getEmissiveTextureId() {
149+
return emissiveTextureId;
150+
}
151+
152+
public void setEmissiveTextureId(int emissiveTextureId) {
153+
this.emissiveTextureId = emissiveTextureId;
154+
}
155+
120156
public float[] getColor(){
121157
if (this.color == null){
122158
this.color = new float[]{1f,1f,1f,1f};

engine/src/main/java/org/andresoviedo/android_3d_model_engine/services/gltf/GltfLoader.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,35 @@ private Object3DData loadMeshPrimitive(MeshModel meshModel, MeshPrimitiveModel m
169169
Log.i("GltfLoader", "Decoding bitmap... " + materialModel.getBaseColorTexture().getName());
170170
try {
171171
Bitmap bitmap = GLUtil.loadBitmap(new ByteBufferInputStream(imageData));
172-
material.setBitmap(bitmap);
172+
material.setColorTexture(bitmap);
173+
} catch (Exception e) {
174+
Log.i("GltfLoader", "Issue decoding bitmap... " + materialModel.getBaseColorTexture().getName());
175+
}
176+
}
177+
178+
// map normal map
179+
if (materialModel.getNormalTexture() != null) {
180+
ByteBuffer imageData = materialModel.getNormalTexture().getImageModel().getImageData();
181+
182+
Log.i("GltfLoader", "Decoding bitmap... " + materialModel.getNormalTexture().getName());
183+
try {
184+
Bitmap bitmap = GLUtil.loadBitmap(new ByteBufferInputStream(imageData));
185+
material.setNormalTexture(bitmap);
186+
} catch (Exception e) {
187+
Log.i("GltfLoader", "Issue decoding bitmap... " + materialModel.getBaseColorTexture().getName());
188+
}
189+
}
190+
191+
// map emmissive map
192+
193+
// map normal map
194+
if (materialModel.getEmissiveTexture() != null) {
195+
ByteBuffer imageData = materialModel.getEmissiveTexture().getImageModel().getImageData();
196+
197+
Log.i("GltfLoader", "Decoding bitmap... " + materialModel.getEmissiveTexture().getName());
198+
try {
199+
Bitmap bitmap = GLUtil.loadBitmap(new ByteBufferInputStream(imageData));
200+
material.setEmissiveTexture(bitmap);
173201
} catch (Exception e) {
174202
Log.i("GltfLoader", "Issue decoding bitmap... " + materialModel.getBaseColorTexture().getName());
175203
}

engine/src/main/java/org/andresoviedo/android_3d_model_engine/view/ModelRenderer.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,17 +664,43 @@ private void drawObject(float[] viewMatrix, float[] projectionMatrix, float[] li
664664
// pre-conditions
665665
if (element.getMaterial() == null) continue;
666666

667+
// load normal map
668+
if (element.getMaterial().getNormalTextureId() == -1 &&
669+
element.getMaterial().getNormalTexture() != null){
670+
671+
// log event
672+
Log.i("ModelRenderer", "Binding normal map... " + element.getMaterial().getName());
673+
674+
// bind bitmap
675+
int handler = GLUtil.loadTexture(element.getMaterial().getNormalTexture());
676+
677+
element.getMaterial().setNormalTextureId(handler);
678+
}
679+
680+
// load normal map
681+
if (element.getMaterial().getEmissiveTextureId() == -1 &&
682+
element.getMaterial().getEmissiveTexture() != null){
683+
684+
// log event
685+
Log.i("ModelRenderer", "Binding normal map... " + element.getMaterial().getName());
686+
687+
// bind bitmap
688+
int handler = GLUtil.loadTexture(element.getMaterial().getEmissiveTexture());
689+
690+
element.getMaterial().setEmissiveTextureId(handler);
691+
}
692+
667693
// check if the texture was already bound
668694
textureId = textures.get(element.getMaterial());
669695
if (textureId != null) continue;
670696

671-
if (element.getMaterial().getBitmap() != null){
697+
if (element.getMaterial().getColorTexture() != null){
672698

673699
// log event
674700
Log.i("ModelRenderer", "Binding material... " + element.getMaterial());
675701

676702
// bind bitmap
677-
textureId = GLUtil.loadTexture(element.getMaterial().getBitmap());
703+
textureId = GLUtil.loadTexture(element.getMaterial().getColorTexture());
678704
}
679705
else if (element.getMaterial().getTextureData() != null){
680706

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,75 @@
11
precision mediump float;
22

33
// colors
4-
varying vec4 v_Color;
4+
uniform vec4 vColor;
55
uniform vec4 vColorMask;
66

77
// texture
88
uniform bool u_Textured;
99
uniform sampler2D u_Texture;
1010
varying vec2 v_TexCoordinate;
1111

12+
// lights
13+
uniform vec3 u_LightPos;
14+
uniform vec3 u_cameraPos;
15+
16+
varying vec3 v_Model;
17+
varying vec3 v_Normal;
18+
varying vec3 v_Light;
19+
20+
// normalMap
21+
uniform bool u_NormalTextured;
22+
uniform sampler2D u_NormalTexture;
23+
24+
// emissiveMap
25+
uniform bool u_EmissiveTextured;
26+
uniform sampler2D u_EmissiveTexture;
27+
1228
void main(){
13-
vec4 color = v_Color;
29+
30+
vec3 normal = v_Normal;
31+
if (u_NormalTextured){
32+
33+
// obtain normal from normal map in range [0,1]
34+
vec3 nmap = texture2D(u_NormalTexture, v_TexCoordinate).rgb;
35+
36+
// transform normal vector to range [-1,1]
37+
normal = normalize(v_Normal + normalize(nmap * 2.0 - 1.0));
38+
39+
// normal = normalize(nmap * 2.0 - 1.0);
40+
}
41+
42+
// Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
43+
// pointing in the same direction then it will get max illumination.
44+
// float diffuse = max(dot(v_Light, normal),0.0); // --> lights only on camera in front of face
45+
float diffuse = max(dot(v_Light, normal),0.0);
46+
47+
// Attenuate the light based on distance.
48+
float distance = distance(u_LightPos,v_Model);
49+
distance = 1.0 / (1.0 + distance * 0.05);
50+
diffuse = diffuse * distance;
51+
52+
// specular light
53+
vec3 viewDir = normalize(u_cameraPos - v_Model);
54+
vec3 reflectDir = reflect(-v_Light, normal);
55+
float specular = pow(max(dot(reflectDir, viewDir),0.0),32.0);
56+
57+
// ambient light
58+
float ambient = 0.5;
59+
60+
// Multiply the color by the illumination level. It will be interpolated across the triangle.
61+
vec4 color = vColor * min((diffuse + specular + ambient),1.0);
62+
1463
if (u_Textured && length(vec3(color)) > 0.0){
15-
gl_FragColor = color * texture2D(u_Texture, v_TexCoordinate) * vColorMask;
64+
color = color * texture2D(u_Texture, v_TexCoordinate);
1665
} else if (u_Textured){
17-
gl_FragColor = texture2D(u_Texture, v_TexCoordinate) * vColorMask;
18-
} else {
19-
gl_FragColor = color * vColorMask;
66+
color = texture2D(u_Texture, v_TexCoordinate);
67+
}
68+
69+
if (u_EmissiveTextured){
70+
color = color + texture2D(u_EmissiveTexture, v_TexCoordinate);
2071
}
21-
gl_FragColor[3] = color[3] * vColorMask[3];
72+
73+
gl_FragColor = color * vColorMask;
74+
gl_FragColor[3] = vColor[3] * vColorMask[3];
2275
}

0 commit comments

Comments
 (0)