summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Guy <romainguy@android.com>2009-08-06 22:52:13 -0700
committerRomain Guy <romainguy@android.com>2009-08-06 22:52:13 -0700
commitb62627ea336db2a4f423596c2a0f482f91690fd7 (patch)
tree5caf138d69aaf3dabe529fd9ae85bf0f48cdd3c0
parentf8e136dcd0a4ba415f2cb8b18c1abfe46cf3512f (diff)
downloadframeworks_base-b62627ea336db2a4f423596c2a0f482f91690fd7.zip
frameworks_base-b62627ea336db2a4f423596c2a0f482f91690fd7.tar.gz
frameworks_base-b62627ea336db2a4f423596c2a0f482f91690fd7.tar.bz2
Add lighting to animated water ripples.
-rw-r--r--libs/rs/java/Fall/res/raw/fall.c209
-rw-r--r--libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java129
-rw-r--r--libs/rs/java/Fall/src/com/android/fall/rs/FallView.java17
-rw-r--r--libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java4
-rw-r--r--libs/rs/rsProgramVertex.cpp2
-rw-r--r--libs/rs/rsScriptC_Lib.cpp63
6 files changed, 384 insertions, 40 deletions
diff --git a/libs/rs/java/Fall/res/raw/fall.c b/libs/rs/java/Fall/res/raw/fall.c
index 76847e0..267b3ea 100644
--- a/libs/rs/java/Fall/res/raw/fall.c
+++ b/libs/rs/java/Fall/res/raw/fall.c
@@ -1,10 +1,215 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#pragma version(1)
#pragma stateVertex(PVBackground)
#pragma stateFragment(PFBackground)
-#pragma stateFragmentStore(PSBackground)
+#pragma stateFragmentStore(PFSBackground)
+
+#define RSID_STATE 0
+#define RSID_FRAME_COUNT 0
+#define RSID_WIDTH 1
+#define RSID_HEIGHT 2
+#define RSID_MESH_WIDTH 3
+#define RSID_MESH_HEIGHT 4
+#define RSID_RIPPLE_MAP_SIZE 5
+#define RSID_RIPPLE_INDEX 6
+#define RSID_DROP_X 7
+#define RSID_DROP_Y 8
+
+#define RSID_TEXTURES 1
+
+#define RSID_RIPPLE_MAP 2
+
+#define RSID_REFRACTION_MAP 3
+
+#define REFRACTION 1.333f
+#define DAMP 4
+
+#define DROP_RADIUS 2
+// The higher, the smaller the ripple
+#define RIPPLE_HEIGHT 10.0f
+
+int offset(int x, int y, int width) {
+ return x + 1 + (y + 1) * (width + 2);
+}
+
+void drop(int x, int y, int r) {
+ int width = loadI32(RSID_STATE, RSID_MESH_WIDTH);
+ int height = loadI32(RSID_STATE, RSID_MESH_HEIGHT);
+
+ if (x < r) x = r;
+ if (y < r) y = r;
+ if (x >= width - r) x = width - r - 1;
+ if (y >= height - r) x = height - r - 1;
+
+ x = width - x;
+
+ int rippleMapSize = loadI32(RSID_STATE, RSID_RIPPLE_MAP_SIZE);
+ int index = loadI32(RSID_STATE, RSID_RIPPLE_INDEX);
+ int origin = offset(0, 0, width);
+
+ int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin);
+ int sqr = r * r;
+
+ int h = 0;
+ for ( ; h < r; h++) {
+ int sqv = h * h;
+ int yn = origin + (y - h) * (width + 2);
+ int yp = origin + (y + h) * (width + 2);
+ int w = 0;
+ for ( ; w < r; w++) {
+ int squ = w * w;
+ if (squ + sqv < sqr) {
+ int v = -sqrtf((sqr - (squ + sqv)) << 16);
+ current[yn + x + w] = v;
+ current[yp + x + w] = v;
+ current[yn + x - w] = v;
+ current[yp + x - w] = v;
+ }
+ }
+ }
+}
+
+void updateRipples() {
+ int rippleMapSize = loadI32(RSID_STATE, RSID_RIPPLE_MAP_SIZE);
+ int width = loadI32(RSID_STATE, RSID_MESH_WIDTH);
+ int height = loadI32(RSID_STATE, RSID_MESH_HEIGHT);
+ int index = loadI32(RSID_STATE, RSID_RIPPLE_INDEX);
+ int origin = offset(0, 0, width);
+
+ int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin);
+ int* next = loadArrayI32(RSID_RIPPLE_MAP, (1 - index) * rippleMapSize + origin);
+
+ storeI32(RSID_STATE, RSID_RIPPLE_INDEX, 1 - index);
+
+ int a = 1;
+ int b = width + 2;
+ int h = height;
+ while (h) {
+ int w = width;
+ while (w) {
+ int droplet = ((current[-b] + current[b] + current[-a] + current[a]) >> 1) - next[0];
+ droplet -= (droplet >> DAMP);
+ next[0] = droplet;
+ current++;
+ next++;
+ w--;
+ }
+ current += 2;
+ next += 2;
+ h--;
+ }
+}
+
+void generateRipples() {
+ int rippleMapSize = loadI32(RSID_STATE, RSID_RIPPLE_MAP_SIZE);
+ int width = loadI32(RSID_STATE, RSID_MESH_WIDTH);
+ int height = loadI32(RSID_STATE, RSID_MESH_HEIGHT);
+ int index = loadI32(RSID_STATE, RSID_RIPPLE_INDEX);
+ int origin = offset(0, 0, width);
+
+ int b = width + 2;
+
+ int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin);
+ float *vertices = loadTriangleMeshVerticesF(NAMED_mesh);
+
+ int h = height - 1;
+ while (h >= 0) {
+ int w = width - 1;
+ int wave = current[0];
+ int offset = h * width;
+ while (w >= 0) {
+ int nextWave = current[1];
+ int dx = nextWave - wave;
+ int dy = current[b] - wave;
+
+ // Update Z coordinate of the vertex
+ vertices[(offset + w) * 8 + 7] = (dy / 512.0f) / RIPPLE_HEIGHT;
+
+ w--;
+ current++;
+ wave = nextWave;
+ }
+ h--;
+ current += 2;
+ }
+
+ // Compute the normals for lighting
+ int y = 0;
+ for ( ; y < height; y++) {
+ int x = 0;
+ int yOffset = y * width;
+ for ( ; x < width; x++) {
+ // V1
+ float v1x = vertices[(yOffset + x) * 8 + 5];
+ float v1y = vertices[(yOffset + x) * 8 + 6];
+ float v1z = vertices[(yOffset + x) * 8 + 7];
+
+ // V2
+ float v2x = vertices[(yOffset + x + 1) * 8 + 5];
+ float v2y = vertices[(yOffset + x + 1) * 8 + 6];
+ float v2z = vertices[(yOffset + x + 1) * 8 + 7];
+
+ // V3
+ float v3x = vertices[(yOffset + width + x) * 8 + 5];
+ float v3y = vertices[(yOffset + width + x) * 8 + 6];
+ float v3z = vertices[(yOffset + width + x) * 8 + 7];
+
+ // N1
+ float n1x = v2x - v1x;
+ float n1y = v2y - v1y;
+ float n1z = v2z - v1z;
+
+ // N2
+ float n2x = v3x - v1x;
+ float n2y = v3y - v1y;
+ float n2z = v3z - v1z;
+
+ // N1 x N2
+ float n3x = n1y * n2z - n1z * n2y;
+ float n3y = n1z * n2x - n1x * n2z;
+ float n3z = n1x * n2y - n1y * n2x;
+
+ // Normalize
+ float len = magf3(n3x, n3y, n3z);
+ n3x /= len;
+ n3y /= len;
+ n3z /= len;
+
+ vertices[(yOffset + x) * 8 + 0] = -n3x;
+ vertices[(yOffset + x) * 8 + 1] = -n3y;
+ vertices[(yOffset + x) * 8 + 2] = -n3z;
+ }
+ }
+}
int main(int index) {
- color(1.0f, 0.0f, 0.0f, 1.0f);
+ int dropX = loadI32(RSID_STATE, RSID_DROP_X);
+ if (dropX != -1) {
+ int dropY = loadI32(RSID_STATE, RSID_DROP_Y);
+ drop(dropX, dropY, DROP_RADIUS);
+ storeI32(RSID_STATE, RSID_DROP_X, -1);
+ storeI32(RSID_STATE, RSID_DROP_Y, -1);
+ }
+
+ updateRipples();
+ generateRipples();
+ updateTriangleMesh(NAMED_mesh);
+
+ ambient(0.0f, 0.1f, 0.9f, 1.0f);
+ diffuse(0.0f, 0.1f, 0.9f, 1.0f);
drawTriangleMesh(NAMED_mesh);
return 1;
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java b/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
index 155bb6f..542f67c 100644
--- a/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
+++ b/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
@@ -25,6 +25,7 @@ import android.renderscript.ProgramVertex;
import android.renderscript.Allocation;
import android.renderscript.Sampler;
import android.renderscript.Element;
+import android.renderscript.Light;
import static android.renderscript.Sampler.Value.LINEAR;
import static android.renderscript.Sampler.Value.CLAMP;
import static android.renderscript.ProgramStore.DepthFunc.*;
@@ -38,16 +39,26 @@ import android.graphics.Bitmap;
import java.util.TimeZone;
class FallRS {
- private static final int MESH_RESOLUTION = 32;
+ private static final int MESH_RESOLUTION = 48;
private static final int RSID_STATE = 0;
private static final int RSID_STATE_FRAMECOUNT = 0;
private static final int RSID_STATE_WIDTH = 1;
private static final int RSID_STATE_HEIGHT = 2;
-
+ private static final int RSID_STATE_MESH_WIDTH = 3;
+ private static final int RSID_STATE_MESH_HEIGHT = 4;
+ private static final int RSID_STATE_RIPPLE_MAP_SIZE = 5;
+ private static final int RSID_STATE_RIPPLE_INDEX = 6;
+ private static final int RSID_STATE_DROP_X = 7;
+ private static final int RSID_STATE_DROP_Y = 8;
+
private static final int RSID_TEXTURES = 1;
private static final int TEXTURES_COUNT = 0;
+ private static final int RSID_RIPPLE_MAP = 2;
+
+ private static final int RSID_REFRACTION_MAP = 3;
+
private Resources mResources;
private RenderScript mRS;
private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
@@ -61,6 +72,7 @@ class FallRS {
private ProgramStore mPfsBackground;
private ProgramVertex mPvBackground;
private ProgramVertex.MatrixAllocation mPvOrthoAlloc;
+ private Light mLight;
private Allocation mTexturesIDs;
private Allocation[] mTextures;
@@ -68,6 +80,11 @@ class FallRS {
private Allocation mState;
private RenderScript.TriangleMesh mMesh;
+ private int mMeshWidth;
+ private int mMeshHeight;
+
+ private Allocation mRippleMap;
+ private Allocation mRefractionMap;
public FallRS(int width, int height) {
mWidth = width;
@@ -96,6 +113,9 @@ class FallRS {
mState.destroy();
mTextureBufferIDs = null;
mMesh.destroy();
+ mLight.destroy();
+ mRippleMap.destroy();
+ mRefractionMap.destroy();
}
@Override
@@ -111,8 +131,9 @@ class FallRS {
createProgramVertex();
createProgramFragmentStore();
createProgramFragment();
- createScriptStructures();
createMesh();
+ createScriptStructures();
+ loadTextures();
ScriptC.Builder sb = new ScriptC.Builder(mRS);
sb.setScript(mResources, R.raw.fall);
@@ -121,16 +142,17 @@ class FallRS {
mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
mScript.setTimeZone(TimeZone.getDefault().getID());
- loadSkyTextures();
mScript.bindAllocation(mState, RSID_STATE);
mScript.bindAllocation(mTexturesIDs, RSID_TEXTURES);
+ mScript.bindAllocation(mRippleMap, RSID_RIPPLE_MAP);
+ mScript.bindAllocation(mRefractionMap, RSID_REFRACTION_MAP);
mRS.contextBindRootScript(mScript);
}
private void createMesh() {
final RenderScript rs = mRS;
- rs.triangleMeshBegin(Element.XYZ_F32, Element.INDEX_16);
+ rs.triangleMeshBegin(Element.NORM_ST_XYZ_F32, Element.INDEX_16);
int wResolution;
int hResolution;
@@ -146,13 +168,20 @@ class FallRS {
hResolution = MESH_RESOLUTION;
}
- final float quadWidth = width / (float) wResolution;
- final float quadHeight = height / (float) hResolution;
+ final float glHeight = 2.0f * height / (float) width;
+ final float quadWidth = 2.0f / (float) wResolution;
+ final float quadHeight = glHeight / (float) hResolution;
+ wResolution += 2;
+ hResolution += 2;
+
for (int y = 0; y <= hResolution; y++) {
- final float yOffset = y * quadHeight;
+ final float yOffset = y * quadHeight - glHeight / 2.0f - quadHeight;
for (int x = 0; x <= wResolution; x++) {
- rs.triangleMeshAddVertex_XYZ(x * quadWidth, yOffset, 0.0f);
+ rs.triangleMeshAddVertex_XYZ_ST_NORM(
+ -1.0f + x * quadWidth - quadWidth, yOffset, 0.0f,
+ x / (float) wResolution, y / (float) wResolution,
+ 0.0f, 0.0f, -1.0f);
}
}
@@ -167,18 +196,41 @@ class FallRS {
mMesh = rs.triangleMeshCreate();
mMesh.setName("mesh");
+
+ mMeshWidth = wResolution + 1;
+ mMeshHeight = hResolution + 1;
}
private void createScriptStructures() {
- final int[] data = new int[3];
+ final int rippleMapSize = (mMeshWidth + 2) * (mMeshHeight + 2);
+
+ final int[] data = new int[9];
mState = Allocation.createSized(mRS, USER_I32, data.length);
data[RSID_STATE_FRAMECOUNT] = 0;
data[RSID_STATE_WIDTH] = mWidth;
data[RSID_STATE_HEIGHT] = mHeight;
+ data[RSID_STATE_MESH_WIDTH] = mMeshWidth;
+ data[RSID_STATE_MESH_HEIGHT] = mMeshHeight;
+ data[RSID_STATE_RIPPLE_MAP_SIZE] = rippleMapSize;
+ data[RSID_STATE_RIPPLE_INDEX] = 0;
+ data[RSID_STATE_DROP_X] = mMeshWidth / 2;
+ data[RSID_STATE_DROP_Y] = mMeshHeight / 2;
mState.data(data);
+
+ final int[] rippleMap = new int[rippleMapSize * 2];
+ mRippleMap = Allocation.createSized(mRS, USER_I32, rippleMap.length);
+
+ final int[] refractionMap = new int[513];
+ float ir = 1.0f / 1.333f;
+ for (int i = 0; i < refractionMap.length; i++) {
+ float d = (float) Math.tan(Math.asin(Math.sin(Math.atan(i * (1.0f / 256.0f))) * ir));
+ refractionMap[i] = (int) Math.floor(d * (1 << 16) + 0.5f);
+ }
+ mRefractionMap = Allocation.createSized(mRS, USER_I32, refractionMap.length);
+ mRefractionMap.data(refractionMap);
}
- private void loadSkyTextures() {
+ private void loadTextures() {
mTextureBufferIDs = new int[TEXTURES_COUNT];
mTextures = new Allocation[TEXTURES_COUNT];
mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT);
@@ -215,42 +267,49 @@ class FallRS {
}
private void createProgramFragment() {
- Sampler.Builder bs = new Sampler.Builder(mRS);
- bs.setMin(LINEAR);
- bs.setMag(LINEAR);
- bs.setWrapS(CLAMP);
- bs.setWrapT(CLAMP);
- mSampler = bs.create();
-
- ProgramFragment.Builder b;
- b = new ProgramFragment.Builder(mRS, null, null);
- b.setTexEnable(true, 0);
- b.setTexEnvMode(REPLACE, 0);
- mPfBackground = b.create();
+ Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);
+ sampleBuilder.setMin(LINEAR);
+ sampleBuilder.setMag(LINEAR);
+ sampleBuilder.setWrapS(CLAMP);
+ sampleBuilder.setWrapT(CLAMP);
+ mSampler = sampleBuilder.create();
+
+ ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null);
+ builder.setTexEnable(true, 0);
+ builder.setTexEnvMode(REPLACE, 0);
+ mPfBackground = builder.create();
mPfBackground.setName("PFBackground");
mPfBackground.bindSampler(mSampler, 0);
}
private void createProgramFragmentStore() {
- ProgramStore.Builder b;
- b = new ProgramStore.Builder(mRS, null, null);
-
- b.setDepthFunc(ALWAYS);
- b.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
- b.setDitherEnable(true);
- b.setDepthMask(false);
- mPfsBackground = b.create();
+ ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null);
+ builder.setDepthFunc(LESS);
+ builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+ builder.setDitherEnable(true);
+ builder.setDepthMask(true);
+ mPfsBackground = builder.create();
mPfsBackground.setName("PFSBackground");
}
private void createProgramVertex() {
mPvOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS);
- mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
+ mPvOrthoAlloc.setupProjectionNormalized(mWidth, mHeight);
- ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
- pvb.setTextureMatrixEnable(true);
- mPvBackground = pvb.create();
+ mLight = new Light.Builder(mRS).create();
+ mLight.setPosition(0.0f, 0.0f, -1.0f);
+
+ ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null);
+ builder.setTextureMatrixEnable(true);
+ builder.addLight(mLight);
+ mPvBackground = builder.create();
mPvBackground.bindAllocation(mPvOrthoAlloc);
mPvBackground.setName("PVBackground");
}
+
+ public void addDrop(float x, float y) {
+ mState.subData1D(RSID_STATE_DROP_X, 2, new int[] {
+ (int) ((x / mWidth) * mMeshWidth), (int) ((y / mHeight) * mMeshHeight)
+ });
+ }
}
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java b/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java
index ebbdba5..bb793c8 100644
--- a/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java
+++ b/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java
@@ -19,6 +19,7 @@ package com.android.fall.rs;
import android.content.Context;
import android.view.SurfaceHolder;
+import android.view.MotionEvent;
import android.renderscript.RenderScript;
import android.renderscript.RSSurfaceView;
@@ -41,4 +42,20 @@ class FallView extends RSSurfaceView {
public void surfaceDestroyed(SurfaceHolder holder) {
if (mRender != null) mRender.destroy();
}
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_MOVE:
+ mRender.addDrop(event.getX(), event.getY());
+ try {
+ Thread.sleep(16);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ break;
+ }
+ return true;
+ }
}
diff --git a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
index a32739c..6c17967 100644
--- a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
+++ b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
@@ -123,7 +123,7 @@ class GrassRS {
createProgramFragmentStore();
createProgramFragment();
createScriptStructures();
- loadSkyTextures();
+ loadTextures();
ScriptC.Builder sb = new ScriptC.Builder(mRS);
sb.setScript(mResources, R.raw.grass);
@@ -172,7 +172,7 @@ class GrassRS {
blades[index + BLADE_STRUCT_B] = random(0.65f) + 0.35f;
}
- private void loadSkyTextures() {
+ private void loadTextures() {
mTextureBufferIDs = new int[TEXTURES_COUNT];
mTextures = new Allocation[TEXTURES_COUNT];
mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT);
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index c66e488..6ef5456 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -63,7 +63,7 @@ void ProgramVertex::setupGL(ProgramVertexState *state)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (mLightCount) {
- int v = 1;
+ int v = 0;
glEnable(GL_LIGHTING);
glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v);
for (uint32_t ct = 0; ct < mLightCount; ct++) {
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index b7c66e2..b17121f 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -75,6 +75,25 @@ static int32_t* SC_loadArrayI32(uint32_t bank, uint32_t offset)
return i + offset;
}
+static float* SC_loadTriangleMeshVerticesF(RsTriangleMesh mesh)
+{
+ TriangleMesh *tm = static_cast<TriangleMesh *>(mesh);
+ void *vp = tm->mVertexData;
+ float *f = static_cast<float *>(vp);
+ return f;
+}
+
+static void SC_updateTriangleMesh(RsTriangleMesh mesh)
+{
+ TriangleMesh *tm = static_cast<TriangleMesh *>(mesh);
+ glBindBuffer(GL_ARRAY_BUFFER, tm->mBufferObjects[0]);
+ glBufferData(GL_ARRAY_BUFFER, tm->mVertexDataSize, tm->mVertexData, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, tm->mIndexDataSize, tm->mIndexData, GL_STATIC_DRAW);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}
static uint32_t SC_loadU32(uint32_t bank, uint32_t offset)
{
@@ -584,6 +603,36 @@ static void SC_color(float r, float g, float b, float a)
glColor4f(r, g, b, a);
}
+static void SC_ambient(float r, float g, float b, float a)
+{
+ GLfloat params[] = { r, g, b, a };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, params);
+}
+
+static void SC_diffuse(float r, float g, float b, float a)
+{
+ GLfloat params[] = { r, g, b, a };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, params);
+}
+
+static void SC_specular(float r, float g, float b, float a)
+{
+ GLfloat params[] = { r, g, b, a };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, params);
+}
+
+static void SC_emission(float r, float g, float b, float a)
+{
+ GLfloat params[] = { r, g, b, a };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, params);
+}
+
+static void SC_shininess(float r, float g, float b, float a)
+{
+ GLfloat params[] = { r, g, b, a };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, params);
+}
+
static void SC_hsb(float h, float s, float b, float a)
{
float red = 0.0f;
@@ -712,6 +761,10 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
"void", "(int, int, float *)" },
{ "storeMatrix", (void *)&SC_storeMatrix,
"void", "(int, int, float *)" },
+ { "loadTriangleMeshVerticesF", (void *)&SC_loadTriangleMeshVerticesF,
+ "float*", "(int)" },
+ { "updateTriangleMesh", (void *)&SC_updateTriangleMesh,
+ "void", "(int)" },
// math
{ "sinf", (void *)&sinf,
@@ -859,6 +912,16 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
"void", "(float, float, float, float)" },
{ "hsb", (void *)&SC_hsb,
"void", "(float, float, float, float)" },
+ { "ambient", (void *)&SC_ambient,
+ "void", "(float, float, float, float)" },
+ { "diffuse", (void *)&SC_diffuse,
+ "void", "(float, float, float, float)" },
+ { "specular", (void *)&SC_specular,
+ "void", "(float, float, float, float)" },
+ { "emission", (void *)&SC_emission,
+ "void", "(float, float, float, float)" },
+ { "shininess", (void *)&SC_shininess,
+ "void", "(float, float, float, float)" },
{ "uploadToTexture", (void *)&SC_uploadToTexture,
"void", "(int, int)" },