Merge commit 'goog/master' into merge_master
This commit is contained in:
@ -960,6 +960,8 @@ void compileElement__generic(ogles_context_t* c,
|
||||
v->index = first;
|
||||
first &= vertex_cache_t::INDEX_MASK;
|
||||
const GLubyte* vp = c->arrays.vertex.element(first);
|
||||
v->obj.z = 0;
|
||||
v->obj.w = 0x10000;
|
||||
c->arrays.vertex.fetch(c, v->obj.v, vp);
|
||||
c->arrays.mvp_transform(&c->transforms.mvp, &v->clip, &v->obj);
|
||||
c->arrays.perspective(c, v);
|
||||
@ -975,6 +977,8 @@ void compileElements__generic(ogles_context_t* c,
|
||||
do {
|
||||
v->flags = 0;
|
||||
v->index = first++;
|
||||
v->obj.z = 0;
|
||||
v->obj.w = 0x10000;
|
||||
c->arrays.vertex.fetch(c, v->obj.v, vp);
|
||||
c->arrays.mvp_transform(mvp, &v->clip, &v->obj);
|
||||
c->arrays.perspective(c, v);
|
||||
|
@ -38,13 +38,14 @@ static void lightVertex(ogles_context_t* c, vertex_t* v);
|
||||
static void lightVertexMaterial(ogles_context_t* c, vertex_t* v);
|
||||
|
||||
static inline void vscale3(GLfixed* d, const GLfixed* m, GLfixed s);
|
||||
static inline void vsub3w(GLfixed* d, const GLfixed* a, const GLfixed* b);
|
||||
|
||||
static __attribute__((noinline))
|
||||
void vnorm3(GLfixed* d, const GLfixed* a);
|
||||
|
||||
static inline void vsa3(GLfixed* d,
|
||||
const GLfixed* m, GLfixed s, const GLfixed* a);
|
||||
static inline void vss3(GLfixed* d,
|
||||
const GLfixed* m, GLfixed s, const GLfixed* a);
|
||||
static inline void vmla3(GLfixed* d,
|
||||
const GLfixed* m0, const GLfixed* m1, const GLfixed* a);
|
||||
static inline void vmul3(GLfixed* d,
|
||||
@ -151,18 +152,10 @@ void vsa3(GLfixed* d, const GLfixed* m, GLfixed s, const GLfixed* a) {
|
||||
}
|
||||
|
||||
static inline
|
||||
void vsub3w(GLfixed* d, const GLfixed* a, const GLfixed* b) {
|
||||
const GLfixed wa = a[3];
|
||||
const GLfixed wb = b[3];
|
||||
if (ggl_likely(wa == wb)) {
|
||||
d[0] = a[0] - b[0];
|
||||
d[1] = a[1] - b[1];
|
||||
d[2] = a[2] - b[2];
|
||||
} else {
|
||||
d[0] = gglMulSubx(a[0], wb, gglMulx(b[0], wa));
|
||||
d[1] = gglMulSubx(a[1], wb, gglMulx(b[1], wa));
|
||||
d[2] = gglMulSubx(a[2], wb, gglMulx(b[2], wa));
|
||||
}
|
||||
void vss3(GLfixed* d, const GLfixed* m, GLfixed s, const GLfixed* a) {
|
||||
d[0] = gglMulSubx(m[0], s, a[0]);
|
||||
d[1] = gglMulSubx(m[1], s, a[1]);
|
||||
d[2] = gglMulSubx(m[2], s, a[2]);
|
||||
}
|
||||
|
||||
static inline
|
||||
@ -227,7 +220,7 @@ static inline void validate_light_mvi(ogles_context_t* c)
|
||||
const int i = 31 - gglClz(en);
|
||||
en &= ~(1<<i);
|
||||
light_t& l = c->lighting.lights[i];
|
||||
c->transforms.mvui.point3(&c->transforms.mvui,
|
||||
c->transforms.mvui.point4(&c->transforms.mvui,
|
||||
&l.objPosition, &l.position);
|
||||
vnorm3(l.normalizedObjPosition.v, l.objPosition.v);
|
||||
}
|
||||
@ -318,6 +311,11 @@ void lightVertexMaterial(ogles_context_t* c, vertex_t* v)
|
||||
vmul3(l.implicitAmbient.v, material.ambient.v, l.ambient.v);
|
||||
vmul3(l.implicitDiffuse.v, material.diffuse.v, l.diffuse.v);
|
||||
vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v);
|
||||
// this is just a flag to tell if we have a specular component
|
||||
l.implicitSpecular.v[3] =
|
||||
l.implicitSpecular.r |
|
||||
l.implicitSpecular.g |
|
||||
l.implicitSpecular.b;
|
||||
}
|
||||
// emission and ambient for the whole scene
|
||||
vmla3( c->lighting.implicitSceneEmissionAndAmbient.v,
|
||||
@ -343,7 +341,11 @@ void lightVertex(ogles_context_t* c, vertex_t* v)
|
||||
vec4_t n;
|
||||
c->arrays.normal.fetch(c, n.v,
|
||||
c->arrays.normal.element(v->index & vertex_cache_t::INDEX_MASK));
|
||||
if (c->transforms.rescaleNormals == GL_NORMALIZE)
|
||||
|
||||
// TODO: right now we handle GL_RESCALE_NORMALS as if ti were
|
||||
// GL_NORMALIZE. We could optimize this by scaling mvui
|
||||
// appropriately instead.
|
||||
if (c->transforms.rescaleNormals)
|
||||
vnorm3(n.v, n.v);
|
||||
|
||||
const material_t& material = c->lighting.front;
|
||||
@ -360,7 +362,8 @@ void lightVertex(ogles_context_t* c, vertex_t* v)
|
||||
|
||||
// compute vertex-to-light vector
|
||||
if (ggl_unlikely(l.position.w)) {
|
||||
vsub3w(d.v, l.objPosition.v, v->obj.v);
|
||||
// lightPos/1.0 - vertex/vertex.w == lightPos*vertex.w - vertex
|
||||
vss3(d.v, l.objPosition.v, v->obj.w, v->obj.v);
|
||||
sqDist = dot3(d.v, d.v);
|
||||
vscale3(d.v, d.v, gglSqrtRecipx(sqDist));
|
||||
} else {
|
||||
|
@ -55,7 +55,7 @@ static void normal__nop(transform_t const*, vec4_t* c, vec4_t const* o);
|
||||
static void point2__generic(transform_t const*, vec4_t* c, vec4_t const* o);
|
||||
static void point3__generic(transform_t const*, vec4_t* c, vec4_t const* o);
|
||||
static void point4__generic(transform_t const*, vec4_t* c, vec4_t const* o);
|
||||
static void normal__generic(transform_t const*, vec4_t* c, vec4_t const* o);
|
||||
static void point4__mvui(transform_t const*, vec4_t* c, vec4_t const* o);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
#if 0
|
||||
@ -209,7 +209,8 @@ void mvui_transform_t::picker()
|
||||
{
|
||||
flags = 0;
|
||||
ops = OP_ALL;
|
||||
point3 = normal__generic;
|
||||
point3 = point4__mvui;
|
||||
point4 = point4__mvui;
|
||||
}
|
||||
|
||||
void transform_t::dump(const char* what)
|
||||
@ -596,66 +597,19 @@ void transform_state_t::update_mvit()
|
||||
|
||||
void transform_state_t::update_mvui()
|
||||
{
|
||||
GLfloat r[16];
|
||||
const GLfloat* const mv = modelview.top().elements();
|
||||
|
||||
/*
|
||||
When transforming normals, we can use the upper 3x3 matrix, see:
|
||||
http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node26.html
|
||||
*/
|
||||
|
||||
// Also note that:
|
||||
// l(obj) = tr(M).l(eye) for infinite light
|
||||
// l(obj) = inv(M).l(eye) for local light
|
||||
|
||||
const uint32_t ops = modelview.top_ops() & ~OP_TRANSLATE;
|
||||
if (ggl_likely((!(ops & ~OP_ROTATE)) ||
|
||||
(rescaleNormals && modelview.isRigidBody()))) {
|
||||
// if the modelview matrix is a rigid body transformation
|
||||
// (translation, rotation, uniform scaling), then we can bypass
|
||||
// the inverse by transposing the matrix.
|
||||
GLfloat rescale = 1.0f;
|
||||
if (rescaleNormals == GL_RESCALE_NORMAL) {
|
||||
if (!(ops & ~OP_UNIFORM_SCALE)) {
|
||||
rescale = reciprocalf(mv[I(0,0)]);
|
||||
} else {
|
||||
rescale = rsqrtf(
|
||||
sqrf(mv[I(2,0)]) + sqrf(mv[I(2,1)]) + sqrf(mv[I(2,2)]));
|
||||
}
|
||||
}
|
||||
GLfixed* const x = mvui.matrix.m;
|
||||
for (int i=0 ; i<3 ; i++) {
|
||||
x[I(i,0)] = gglFloatToFixed(mv[I(0,i)] * rescale);
|
||||
x[I(i,1)] = gglFloatToFixed(mv[I(1,i)] * rescale);
|
||||
x[I(i,2)] = gglFloatToFixed(mv[I(2,i)] * rescale);
|
||||
}
|
||||
mvui.picker();
|
||||
return;
|
||||
}
|
||||
|
||||
GLfloat r[3][3];
|
||||
r[0][0] = det22(mv[I(1,1)], mv[I(2,1)], mv[I(1,2)], mv[I(2,2)]);
|
||||
r[0][1] =ndet22(mv[I(0,1)], mv[I(2,1)], mv[I(0,2)], mv[I(2,2)]);
|
||||
r[0][2] = det22(mv[I(0,1)], mv[I(1,1)], mv[I(0,2)], mv[I(1,2)]);
|
||||
r[1][0] =ndet22(mv[I(1,0)], mv[I(2,0)], mv[I(1,2)], mv[I(2,2)]);
|
||||
r[1][1] = det22(mv[I(0,0)], mv[I(2,0)], mv[I(0,2)], mv[I(2,2)]);
|
||||
r[1][2] =ndet22(mv[I(0,0)], mv[I(1,0)], mv[I(0,2)], mv[I(1,2)]);
|
||||
r[2][0] = det22(mv[I(1,0)], mv[I(2,0)], mv[I(1,1)], mv[I(2,1)]);
|
||||
r[2][1] =ndet22(mv[I(0,0)], mv[I(2,0)], mv[I(0,1)], mv[I(2,1)]);
|
||||
r[2][2] = det22(mv[I(0,0)], mv[I(1,0)], mv[I(0,1)], mv[I(1,1)]);
|
||||
|
||||
GLfloat rdet;
|
||||
if (rescaleNormals == GL_RESCALE_NORMAL) {
|
||||
rdet = rsqrtf(sqrf(r[0][2]) + sqrf(r[1][2]) + sqrf(r[2][2]));
|
||||
} else {
|
||||
rdet = reciprocalf(
|
||||
r[0][0]*mv[I(0,0)] + r[0][1]*mv[I(1,0)] + r[0][2]*mv[I(2,0)]);
|
||||
}
|
||||
// TODO: we need a faster invert, especially for when the modelview
|
||||
// is a rigid-body matrix
|
||||
invert(r, mv);
|
||||
|
||||
GLfixed* const x = mvui.matrix.m;
|
||||
for (int i=0 ; i<3 ; i++) {
|
||||
x[I(i,0)] = gglFloatToFixed(r[i][0] * rdet);
|
||||
x[I(i,1)] = gglFloatToFixed(r[i][1] * rdet);
|
||||
x[I(i,2)] = gglFloatToFixed(r[i][2] * rdet);
|
||||
for (int i=0 ; i<4 ; i++) {
|
||||
x[I(i,0)] = gglFloatToFixed(r[I(i,0)]);
|
||||
x[I(i,1)] = gglFloatToFixed(r[I(i,1)]);
|
||||
x[I(i,2)] = gglFloatToFixed(r[I(i,2)]);
|
||||
x[I(i,4)] = gglFloatToFixed(r[I(i,3)]);
|
||||
}
|
||||
mvui.picker();
|
||||
}
|
||||
@ -783,14 +737,19 @@ void point4__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
|
||||
lhs->w = mla4(rx, m[ 3], ry, m[ 7], rz, m[11], rw, m[15]);
|
||||
}
|
||||
|
||||
void normal__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
|
||||
void point4__mvui(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
|
||||
// this used for transforming light positions back to object space.
|
||||
// Lights have 3 components positions, so w is always 1.
|
||||
// however, it is used as a switch for directional lights, so we need
|
||||
// to preserve it.
|
||||
const GLfixed* const m = mx->matrix.m;
|
||||
const GLfixed rx = rhs->x;
|
||||
const GLfixed ry = rhs->y;
|
||||
const GLfixed rz = rhs->z;
|
||||
lhs->x = mla3(rx, m[ 0], ry, m[ 4], rz, m[ 8]);
|
||||
lhs->y = mla3(rx, m[ 1], ry, m[ 5], rz, m[ 9]);
|
||||
lhs->z = mla3(rx, m[ 2], ry, m[ 6], rz, m[10]);
|
||||
lhs->x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]);
|
||||
lhs->y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]);
|
||||
lhs->z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]);
|
||||
lhs->w = rhs->w;
|
||||
}
|
||||
|
||||
|
||||
|
11
opengl/tests/lighting1709/Android.mk
Normal file
11
opengl/tests/lighting1709/Android.mk
Normal file
@ -0,0 +1,11 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||
|
||||
LOCAL_PACKAGE_NAME := LightingTest
|
||||
LOCAL_CERTIFICATE := platform
|
||||
|
||||
include $(BUILD_PACKAGE)
|
13
opengl/tests/lighting1709/AndroidManifest.xml
Normal file
13
opengl/tests/lighting1709/AndroidManifest.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.lightingtest">
|
||||
|
||||
<application>
|
||||
<activity android:name="ClearActivity" android:label="LightingTest">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (C) 2007 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.
|
||||
*/
|
||||
|
||||
package com.android.lightingtest;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
public class ClearActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mGLView = new ClearGLSurfaceView(this);
|
||||
setContentView(mGLView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mGLView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mGLView.onResume();
|
||||
}
|
||||
private GLSurfaceView mGLView;
|
||||
}
|
||||
|
||||
class ClearGLSurfaceView extends GLSurfaceView {
|
||||
public ClearGLSurfaceView(Context context) {
|
||||
super(context);
|
||||
mRenderer = new ClearRenderer();
|
||||
setRenderer(mRenderer);
|
||||
}
|
||||
|
||||
ClearRenderer mRenderer;
|
||||
}
|
||||
|
||||
class ClearRenderer implements GLSurfaceView.Renderer {
|
||||
public ClearRenderer() {
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
// Do nothing special.
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int w, int h) {
|
||||
// Compute the projection matrix
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
|
||||
// Compute the boundaries of the frustum
|
||||
float fl = (float) (-(w / 2)) / 288;
|
||||
float fr = (float) (w / 2) / 288;
|
||||
float ft = (float) (h / 2) / 288;
|
||||
float fb = (float) (-(h / 2)) / 288;
|
||||
|
||||
// Set the view frustum
|
||||
gl.glFrustumf(fl, fr, fb, ft, 1.0f, 2000.0f);
|
||||
|
||||
// Set the viewport dimensions
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
gl.glViewport(0, 0, w, h);
|
||||
}
|
||||
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
final float lightOff[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
final float lightAmbient[] = {5.0f, 0.0f, 0.0f, 1.0f};
|
||||
final float lightDiffuse[] = {0.0f, 2.0f, 0.0f, 0.0f};
|
||||
final float lightPosSpot[] = {0.0f, 0.0f, -8.0f, 1.0f};
|
||||
|
||||
final float pos[] = {
|
||||
-5.0f, -1.5f, 0.0f,
|
||||
0.0f, -1.5f, 0.0f,
|
||||
5.0f, -1.5f, 0.0f,
|
||||
};
|
||||
|
||||
final float v[] = new float[9];
|
||||
ByteBuffer vbb = ByteBuffer.allocateDirect(v.length*4);
|
||||
vbb.order(ByteOrder.nativeOrder());
|
||||
FloatBuffer vb = vbb.asFloatBuffer();
|
||||
|
||||
gl.glDisable(GL10.GL_DITHER);
|
||||
|
||||
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);
|
||||
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);
|
||||
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, lightOff, 0);
|
||||
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPosSpot, 0);
|
||||
gl.glEnable(GL10.GL_LIGHT0);
|
||||
|
||||
gl.glEnable(GL10.GL_LIGHTING);
|
||||
|
||||
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glNormal3f(0, 0, 1);
|
||||
|
||||
|
||||
// draw first 3 triangles, without using transforms
|
||||
for (int i=0 ; i<3 ; i++) {
|
||||
v[0] = -1; v[1] =-1; v[2] = -10;
|
||||
v[3] = 0; v[4] = 1; v[5] = -10;
|
||||
v[6] = 1; v[7] =-1; v[8] = -10;
|
||||
for (int j=0 ; j<3 ; j++) {
|
||||
v[j*3+0] -= pos[i*3+0];
|
||||
v[j*3+1] -= pos[i*3+1];
|
||||
v[j*3+2] -= pos[i*3+2];
|
||||
}
|
||||
vb.put(v).position(0);
|
||||
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vb);
|
||||
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);
|
||||
}
|
||||
|
||||
// draw the 2nd batch this time with transforms
|
||||
v[0] = -1; v[1] =-1; v[2] = -10;
|
||||
v[3] = 0; v[4] = 1; v[5] = -10;
|
||||
v[6] = 1; v[7] =-1; v[8] = -10;
|
||||
vb.put(v).position(0);
|
||||
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vb);
|
||||
|
||||
// draw lower left triangle
|
||||
gl.glPushMatrix();
|
||||
gl.glTranslatef(pos[0], pos[1], pos[2]);
|
||||
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);
|
||||
gl.glPopMatrix();
|
||||
|
||||
// draw lower middle triangle
|
||||
gl.glPushMatrix();
|
||||
gl.glTranslatef(pos[3], pos[4], pos[5]);
|
||||
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);
|
||||
gl.glPopMatrix();
|
||||
|
||||
// draw lower right triangle
|
||||
gl.glPushMatrix();
|
||||
gl.glTranslatef(pos[6], pos[7], pos[8]);
|
||||
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);
|
||||
gl.glPopMatrix();
|
||||
}
|
||||
|
||||
public int[] getConfigSpec() {
|
||||
int[] configSpec = { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
|
||||
return configSpec;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user