Add lighting to animated water ripples.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);
|
||||
sampleBuilder.setMin(LINEAR);
|
||||
sampleBuilder.setMag(LINEAR);
|
||||
sampleBuilder.setWrapS(CLAMP);
|
||||
sampleBuilder.setWrapT(CLAMP);
|
||||
mSampler = sampleBuilder.create();
|
||||
|
||||
ProgramFragment.Builder b;
|
||||
b = new ProgramFragment.Builder(mRS, null, null);
|
||||
b.setTexEnable(true, 0);
|
||||
b.setTexEnvMode(REPLACE, 0);
|
||||
mPfBackground = b.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)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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)" },
|
||||
|
||||
Reference in New Issue
Block a user