Use native Matrix4 instead of float[16]
This commit is contained in:
parent
af80759dae
commit
f262efee7f
489
jni/gl/utils.c
489
jni/gl/utils.c
@ -9,13 +9,16 @@
|
||||
|
||||
static const char TAG[] = "org.oscim.utils.GLUtils";
|
||||
|
||||
static void nativeClassInit(JNIEnv *_env) {
|
||||
static void
|
||||
nativeClassInit(JNIEnv *_env)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void JNI(init)(JNIEnv *env, jclass* clazz) {
|
||||
nativeClassInit(env);
|
||||
__android_log_print(ANDROID_LOG_INFO, TAG, "all initialized");
|
||||
void JNI(init)(JNIEnv *env, jclass* clazz)
|
||||
{
|
||||
nativeClassInit(env);
|
||||
__android_log_print(ANDROID_LOG_INFO, TAG, "all initialized");
|
||||
}
|
||||
|
||||
#undef JNI
|
||||
@ -25,196 +28,217 @@ void JNI(init)(JNIEnv *env, jclass* clazz) {
|
||||
#define MAT_SIZE 16 * sizeof(float)
|
||||
|
||||
static const float identity[] =
|
||||
{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
|
||||
{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
|
||||
|
||||
static inline void multiplyMM(float* r, const float* lhs, const float* rhs);
|
||||
static inline void
|
||||
multiplyMM(float* r, const float* lhs, const float* rhs);
|
||||
|
||||
static inline void mx4transform(float x, float y, float z, float w,
|
||||
const float* pM, float* pDest);
|
||||
static inline void
|
||||
setRotateM(float* rm, int rmOffset, float a, float x, float y, float z);
|
||||
|
||||
static void setRotateM(float* rm, int rmOffset, float a, float x, float y,
|
||||
float z);
|
||||
static void transposeM(float* mTrans, int mTransOffset, float* m, int mOffset);
|
||||
static inline void
|
||||
transposeM(float* mTrans, int mTransOffset, float* m, int mOffset);
|
||||
|
||||
static inline void matrix4_proj(float* mat, float* vec);
|
||||
static inline void
|
||||
matrix4_proj(float* mat, float* vec);
|
||||
|
||||
jlong JNI(alloc)(JNIEnv *env, jclass* clazz) {
|
||||
return (long) calloc(16, sizeof(float));
|
||||
|
||||
jlong JNI(alloc)(JNIEnv *env, jclass* clazz)
|
||||
{
|
||||
return (long) calloc(16, sizeof(float));
|
||||
}
|
||||
|
||||
void JNI(delete)(JNIEnv* env, jclass* clazz, jlong ptr) {
|
||||
free(CAST(ptr));
|
||||
void JNI(delete)(JNIEnv* env, jclass* clazz, jlong ptr)
|
||||
{
|
||||
free(CAST(ptr));
|
||||
}
|
||||
|
||||
void JNI(setAsUniform)(JNIEnv* env, jclass* clazz, jlong ptr, jint location) {
|
||||
float* m = CAST(ptr);
|
||||
void JNI(setAsUniform)(JNIEnv* env, jclass* clazz, jlong ptr, jint location)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
|
||||
glUniformMatrix4fv((GLint) location, (GLsizei) 1, (GLboolean) 0,
|
||||
(GLfloat *) m);
|
||||
glUniformMatrix4fv((GLint) location, (GLsizei) 1, (GLboolean) 0, (GLfloat *) m);
|
||||
}
|
||||
|
||||
void JNI(setValueAt)(JNIEnv* env, jclass* clazz, jlong ptr, jint pos,
|
||||
jfloat value) {
|
||||
float* m = CAST(ptr);
|
||||
if (pos > -1 && pos < 16)
|
||||
m[pos] = value;
|
||||
void JNI(setValueAt)(JNIEnv* env, jclass* clazz, jlong ptr, jint pos, jfloat value)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
if (pos > -1 && pos < 16)
|
||||
m[pos] = value;
|
||||
}
|
||||
|
||||
void JNI(identity)(JNIEnv* env, jclass* clazz, jlong ptr) {
|
||||
float* m = CAST(ptr);
|
||||
memcpy(m, identity, MAT_SIZE);
|
||||
void JNI(identity)(JNIEnv* env, jclass* clazz, jlong ptr)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
memcpy(m, identity, MAT_SIZE);
|
||||
}
|
||||
|
||||
void JNI(setScale)(JNIEnv* env, jclass* clazz, jlong ptr, jfloat sx, jfloat sy,
|
||||
jfloat sz) {
|
||||
float* m = CAST(ptr);
|
||||
memcpy(m, identity, MAT_SIZE);
|
||||
m[0] = sx;
|
||||
m[5] = sy;
|
||||
m[10] = sz;
|
||||
void JNI(setScale)(JNIEnv* env, jclass* clazz, jlong ptr, jfloat sx, jfloat sy, jfloat sz)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
memcpy(m, identity, MAT_SIZE);
|
||||
m[0] = sx;
|
||||
m[5] = sy;
|
||||
m[10] = sz;
|
||||
}
|
||||
|
||||
void JNI(setRotate)(JNIEnv* env, jclass* clazz, jlong ptr, jfloat a, jfloat x,
|
||||
jfloat y, jfloat z) {
|
||||
float* m = CAST(ptr);
|
||||
setRotateM(m, 0, a, x, y, z);
|
||||
void JNI(setTranslation)(JNIEnv* env, jclass* clazz, jlong ptr, jfloat x, jfloat y, jfloat z)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
memcpy(m, identity, MAT_SIZE);
|
||||
m[12] = x;
|
||||
m[13] = y;
|
||||
m[14] = z;
|
||||
}
|
||||
|
||||
void JNI(setTransScale)(JNIEnv* env, jclass* clazz, jlong ptr, jfloat tx,
|
||||
jfloat ty, jfloat scale) {
|
||||
float* m = CAST(ptr);
|
||||
memcpy(m, identity, MAT_SIZE);
|
||||
m[0] = scale;
|
||||
m[5] = scale;
|
||||
m[12] = tx;
|
||||
m[13] = ty;
|
||||
void JNI(setRotation)(JNIEnv* env, jclass* clazz, jlong ptr, jfloat a, jfloat x, jfloat y, jfloat z)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
setRotateM(m, 0, a, x, y, z);
|
||||
}
|
||||
|
||||
void JNI(set)(JNIEnv* env, jclass* clazz, jlong ptr, jfloatArray obj_mat) {
|
||||
float* m = CAST(ptr);
|
||||
float* mat = (float*) (*env)->GetPrimitiveArrayCritical(env, obj_mat, 0);
|
||||
|
||||
memcpy(m, mat, MAT_SIZE);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, obj_mat, mat, 0);
|
||||
void JNI(setTransScale)(JNIEnv* env, jclass* clazz, jlong ptr, jfloat tx, jfloat ty, jfloat scale)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
memcpy(m, identity, MAT_SIZE);
|
||||
m[0] = scale;
|
||||
m[5] = scale;
|
||||
m[12] = tx;
|
||||
m[13] = ty;
|
||||
}
|
||||
|
||||
void JNI(get)(JNIEnv* env, jclass* clazz, jlong ptr, jfloatArray obj_mat) {
|
||||
float* m = CAST(ptr);
|
||||
float* mat = (float*) (*env)->GetPrimitiveArrayCritical(env, obj_mat, 0);
|
||||
void JNI(set)(JNIEnv* env, jclass* clazz, jlong ptr, jfloatArray obj_mat)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
float* mat = (float*) (*env)->GetPrimitiveArrayCritical(env, obj_mat, 0);
|
||||
|
||||
memcpy(mat, m, MAT_SIZE);
|
||||
memcpy(m, mat, MAT_SIZE);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, obj_mat, mat, 0);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, obj_mat, mat, 0);
|
||||
}
|
||||
|
||||
void JNI(mul)(JNIEnv* env, jclass* clazz, jlong ptr_a, jlong ptr_b) {
|
||||
float* mata = CAST(ptr_a);
|
||||
float* matb = CAST(ptr_b);
|
||||
void JNI(get)(JNIEnv* env, jclass* clazz, jlong ptr, jfloatArray obj_mat)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
float* mat = (float*) (*env)->GetPrimitiveArrayCritical(env, obj_mat, 0);
|
||||
|
||||
multiplyMM(mata, mata, matb);
|
||||
memcpy(mat, m, MAT_SIZE);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, obj_mat, mat, 0);
|
||||
}
|
||||
|
||||
void JNI(copy)(JNIEnv* env, jclass* clazz, jlong ptr_dst, jlong ptr_src) {
|
||||
float* dst = CAST(ptr_dst);
|
||||
float* src = CAST(ptr_src);
|
||||
void JNI(mul)(JNIEnv* env, jclass* clazz, jlong ptr_a, jlong ptr_b)
|
||||
{
|
||||
float* mata = CAST(ptr_a);
|
||||
float* matb = CAST(ptr_b);
|
||||
|
||||
memcpy(dst, src, MAT_SIZE);
|
||||
multiplyMM(mata, mata, matb);
|
||||
}
|
||||
|
||||
void JNI(smul)(JNIEnv* env, jclass* clazz, jlong ptr_r, jlong ptr_a,
|
||||
jlong ptr_b) {
|
||||
float* matr = CAST(ptr_r);
|
||||
float* mata = CAST(ptr_a);
|
||||
float* matb = CAST(ptr_b);
|
||||
void JNI(copy)(JNIEnv* env, jclass* clazz, jlong ptr_dst, jlong ptr_src)
|
||||
{
|
||||
float* dst = CAST(ptr_dst);
|
||||
float* src = CAST(ptr_src);
|
||||
|
||||
multiplyMM(matr, mata, matb);
|
||||
memcpy(dst, src, MAT_SIZE);
|
||||
}
|
||||
|
||||
void JNI(strans)(JNIEnv* env, jclass* clazz, jlong ptr_r, jlong ptr_a) {
|
||||
float* matr = CAST(ptr_r);
|
||||
float* mata = CAST(ptr_a);
|
||||
void JNI(smul)(JNIEnv* env, jclass* clazz, jlong ptr_r, jlong ptr_a, jlong ptr_b)
|
||||
{
|
||||
float* matr = CAST(ptr_r);
|
||||
float* mata = CAST(ptr_a);
|
||||
float* matb = CAST(ptr_b);
|
||||
|
||||
transposeM(matr, 0, mata, 0);
|
||||
multiplyMM(matr, mata, matb);
|
||||
}
|
||||
|
||||
void JNI(prj)(JNIEnv* env, jclass* clazz, jlong ptr, jfloatArray obj_vec) {
|
||||
float* m = CAST(ptr);
|
||||
float* vec = (float*) (*env)->GetPrimitiveArrayCritical(env, obj_vec, 0);
|
||||
void JNI(strans)(JNIEnv* env, jclass* clazz, jlong ptr_r, jlong ptr_a)
|
||||
{
|
||||
float* matr = CAST(ptr_r);
|
||||
float* mata = CAST(ptr_a);
|
||||
|
||||
matrix4_proj(m, vec);
|
||||
transposeM(matr, 0, mata, 0);
|
||||
}
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, obj_vec, vec, 0);
|
||||
void JNI(prj)(JNIEnv* env, jclass* clazz, jlong ptr, jfloatArray obj_vec)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
float* vec = (float*) (*env)->GetPrimitiveArrayCritical(env, obj_vec, 0);
|
||||
|
||||
matrix4_proj(m, vec);
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, obj_vec, vec, 0);
|
||||
}
|
||||
|
||||
static float someRandomEpsilon = 1.0f / (1 << 11);
|
||||
|
||||
void JNI(addDepthOffset)(JNIEnv* env, jclass* clazz, jlong ptr, jint delta) {
|
||||
float* m = CAST(ptr);
|
||||
void JNI(addDepthOffset)(JNIEnv* env, jclass* clazz, jlong ptr, jint delta)
|
||||
{
|
||||
float* m = CAST(ptr);
|
||||
|
||||
// from http://www.mathfor3dgameprogramming.com/code/Listing9.1.cpp
|
||||
// float n = MapViewPosition.VIEW_NEAR;
|
||||
// float f = MapViewPosition.VIEW_FAR;
|
||||
// float pz = 1;
|
||||
// float epsilon = -2.0f * f * n * delta / ((f + n) * pz * (pz + delta));
|
||||
// from http://www.mathfor3dgameprogramming.com/code/Listing9.1.cpp
|
||||
// float n = MapViewPosition.VIEW_NEAR;
|
||||
// float f = MapViewPosition.VIEW_FAR;
|
||||
// float pz = 1;
|
||||
// float epsilon = -2.0f * f * n * delta / ((f + n) * pz * (pz + delta));
|
||||
|
||||
m[10] *= 1.0f + someRandomEpsilon * delta;
|
||||
m[10] *= 1.0f + someRandomEpsilon * delta;
|
||||
}
|
||||
|
||||
/**
|
||||
** Copyright 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.
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
// from android/platform_frameworks_base/blob/master/core/jni/android/opengl/util.cpp
|
||||
#define I(_i, _j) ((_j)+ 4*(_i))
|
||||
|
||||
static
|
||||
void multiplyMM(float* r, const float* lhs, const float* rhs) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
register const float rhs_i0 = rhs[I(i,0)];
|
||||
register float ri0 = lhs[I(0,0)] * rhs_i0;
|
||||
register float ri1 = lhs[I(0,1)] * rhs_i0;
|
||||
register float ri2 = lhs[I(0,2)] * rhs_i0;
|
||||
register float ri3 = lhs[I(0,3)] * rhs_i0;
|
||||
for (int j = 1; j < 4; j++) {
|
||||
register const float rhs_ij = rhs[I(i,j)];
|
||||
ri0 += lhs[I(j,0)] * rhs_ij;
|
||||
ri1 += lhs[I(j,1)] * rhs_ij;
|
||||
ri2 += lhs[I(j,2)] * rhs_ij;
|
||||
ri3 += lhs[I(j,3)] * rhs_ij;
|
||||
}
|
||||
r[I(i,0)] = ri0;
|
||||
r[I(i,1)] = ri1;
|
||||
r[I(i,2)] = ri2;
|
||||
r[I(i,3)] = ri3;
|
||||
}
|
||||
static inline void
|
||||
multiplyMM(float* r, const float* lhs, const float* rhs)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
register const float rhs_i0 = rhs[I(i,0)];
|
||||
register float ri0 = lhs[I(0,0)] * rhs_i0;
|
||||
register float ri1 = lhs[I(0,1)] * rhs_i0;
|
||||
register float ri2 = lhs[I(0,2)] * rhs_i0;
|
||||
register float ri3 = lhs[I(0,3)] * rhs_i0;
|
||||
for (int j = 1; j < 4; j++)
|
||||
{
|
||||
register const float rhs_ij = rhs[I(i,j)];
|
||||
ri0 += lhs[I(j,0)] * rhs_ij;
|
||||
ri1 += lhs[I(j,1)] * rhs_ij;
|
||||
ri2 += lhs[I(j,2)] * rhs_ij;
|
||||
ri3 += lhs[I(j,3)] * rhs_ij;
|
||||
}
|
||||
r[I(i,0)] = ri0;
|
||||
r[I(i,1)] = ri1;
|
||||
r[I(i,2)] = ri2;
|
||||
r[I(i,3)] = ri3;
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
void mx4transform(float x, float y, float z, float w, const float* pM,
|
||||
float* pDest) {
|
||||
pDest[0] = pM[0 + 4 * 0] * x + pM[0 + 4 * 1] * y + pM[0 + 4 * 2] * z
|
||||
+ pM[0 + 4 * 3] * w;
|
||||
pDest[1] = pM[1 + 4 * 0] * x + pM[1 + 4 * 1] * y + pM[1 + 4 * 2] * z
|
||||
+ pM[1 + 4 * 3] * w;
|
||||
pDest[2] = pM[2 + 4 * 0] * x + pM[2 + 4 * 1] * y + pM[2 + 4 * 2] * z
|
||||
+ pM[2 + 4 * 3] * w;
|
||||
|
||||
pDest[3] = pM[3 + 4 * 0] * x + pM[3 + 4 * 1] * y + pM[3 + 4 * 2] * z
|
||||
+ pM[3 + 4 * 3] * w;
|
||||
}
|
||||
//static inline
|
||||
//void
|
||||
//mx4transform(float x, float y, float z, float w, const float* pM, float* pDest)
|
||||
//{
|
||||
// pDest[0] = pM[0 + 4 * 0] * x + pM[0 + 4 * 1] * y + pM[0 + 4 * 2] * z + pM[0 + 4 * 3] * w;
|
||||
// pDest[1] = pM[1 + 4 * 0] * x + pM[1 + 4 * 1] * y + pM[1 + 4 * 2] * z + pM[1 + 4 * 3] * w;
|
||||
// pDest[2] = pM[2 + 4 * 0] * x + pM[2 + 4 * 1] * y + pM[2 + 4 * 2] * z + pM[2 + 4 * 3] * w;
|
||||
//
|
||||
// pDest[3] = pM[3 + 4 * 0] * x + pM[3 + 4 * 1] * y + pM[3 + 4 * 2] * z + pM[3 + 4 * 3] * w;
|
||||
//}
|
||||
|
||||
/**
|
||||
* Computes the length of a vector
|
||||
@ -224,8 +248,10 @@ void mx4transform(float x, float y, float z, float w, const float* pM,
|
||||
* @param z z coordinate of a vector
|
||||
* @return the length of a vector
|
||||
*/
|
||||
static float length(float x, float y, float z) {
|
||||
return (float) sqrt(x * x + y * y + z * z);
|
||||
static inline float
|
||||
length(float x, float y, float z)
|
||||
{
|
||||
return (float) sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
/**
|
||||
* Rotates matrix m by angle a (in degrees) around the axis (x, y, z)
|
||||
@ -237,73 +263,82 @@ static float length(float x, float y, float z) {
|
||||
* @param z scale factor z
|
||||
*/
|
||||
|
||||
static void setRotateM(float* rm, int rmOffset, float a, float x, float y,
|
||||
float z) {
|
||||
rm[rmOffset + 3] = 0;
|
||||
rm[rmOffset + 7] = 0;
|
||||
rm[rmOffset + 11] = 0;
|
||||
rm[rmOffset + 12] = 0;
|
||||
rm[rmOffset + 13] = 0;
|
||||
rm[rmOffset + 14] = 0;
|
||||
rm[rmOffset + 15] = 1;
|
||||
a *= (float) (M_PI / 180.0f);
|
||||
float s = (float) sin(a);
|
||||
float c = (float) cos(a);
|
||||
if (1.0f == x && 0.0f == y && 0.0f == z) {
|
||||
rm[rmOffset + 5] = c;
|
||||
rm[rmOffset + 10] = c;
|
||||
rm[rmOffset + 6] = s;
|
||||
rm[rmOffset + 9] = -s;
|
||||
rm[rmOffset + 1] = 0;
|
||||
rm[rmOffset + 2] = 0;
|
||||
rm[rmOffset + 4] = 0;
|
||||
rm[rmOffset + 8] = 0;
|
||||
rm[rmOffset + 0] = 1;
|
||||
} else if (0.0f == x && 1.0f == y && 0.0f == z) {
|
||||
rm[rmOffset + 0] = c;
|
||||
rm[rmOffset + 10] = c;
|
||||
rm[rmOffset + 8] = s;
|
||||
rm[rmOffset + 2] = -s;
|
||||
rm[rmOffset + 1] = 0;
|
||||
rm[rmOffset + 4] = 0;
|
||||
rm[rmOffset + 6] = 0;
|
||||
rm[rmOffset + 9] = 0;
|
||||
rm[rmOffset + 5] = 1;
|
||||
} else if (0.0f == x && 0.0f == y && 1.0f == z) {
|
||||
rm[rmOffset + 0] = c;
|
||||
rm[rmOffset + 5] = c;
|
||||
rm[rmOffset + 1] = s;
|
||||
rm[rmOffset + 4] = -s;
|
||||
rm[rmOffset + 2] = 0;
|
||||
rm[rmOffset + 6] = 0;
|
||||
rm[rmOffset + 8] = 0;
|
||||
rm[rmOffset + 9] = 0;
|
||||
rm[rmOffset + 10] = 1;
|
||||
} else {
|
||||
float len = length(x, y, z);
|
||||
if (1.0f != len) {
|
||||
float recipLen = 1.0f / len;
|
||||
x *= recipLen;
|
||||
y *= recipLen;
|
||||
z *= recipLen;
|
||||
}
|
||||
float nc = 1.0f - c;
|
||||
float xy = x * y;
|
||||
float yz = y * z;
|
||||
float zx = z * x;
|
||||
float xs = x * s;
|
||||
float ys = y * s;
|
||||
float zs = z * s;
|
||||
rm[rmOffset + 0] = x * x * nc + c;
|
||||
rm[rmOffset + 4] = xy * nc - zs;
|
||||
rm[rmOffset + 8] = zx * nc + ys;
|
||||
rm[rmOffset + 1] = xy * nc + zs;
|
||||
rm[rmOffset + 5] = y * y * nc + c;
|
||||
rm[rmOffset + 9] = yz * nc - xs;
|
||||
rm[rmOffset + 2] = zx * nc - ys;
|
||||
rm[rmOffset + 6] = yz * nc + xs;
|
||||
rm[rmOffset + 10] = z * z * nc + c;
|
||||
}
|
||||
static inline void
|
||||
setRotateM(float* rm, int rmOffset, float a, float x, float y, float z)
|
||||
{
|
||||
rm[rmOffset + 3] = 0;
|
||||
rm[rmOffset + 7] = 0;
|
||||
rm[rmOffset + 11] = 0;
|
||||
rm[rmOffset + 12] = 0;
|
||||
rm[rmOffset + 13] = 0;
|
||||
rm[rmOffset + 14] = 0;
|
||||
rm[rmOffset + 15] = 1;
|
||||
a *= (float) (M_PI / 180.0f);
|
||||
float s = (float) sin(a);
|
||||
float c = (float) cos(a);
|
||||
if (1.0f == x && 0.0f == y && 0.0f == z)
|
||||
{
|
||||
rm[rmOffset + 5] = c;
|
||||
rm[rmOffset + 10] = c;
|
||||
rm[rmOffset + 6] = s;
|
||||
rm[rmOffset + 9] = -s;
|
||||
rm[rmOffset + 1] = 0;
|
||||
rm[rmOffset + 2] = 0;
|
||||
rm[rmOffset + 4] = 0;
|
||||
rm[rmOffset + 8] = 0;
|
||||
rm[rmOffset + 0] = 1;
|
||||
}
|
||||
else if (0.0f == x && 1.0f == y && 0.0f == z)
|
||||
{
|
||||
rm[rmOffset + 0] = c;
|
||||
rm[rmOffset + 10] = c;
|
||||
rm[rmOffset + 8] = s;
|
||||
rm[rmOffset + 2] = -s;
|
||||
rm[rmOffset + 1] = 0;
|
||||
rm[rmOffset + 4] = 0;
|
||||
rm[rmOffset + 6] = 0;
|
||||
rm[rmOffset + 9] = 0;
|
||||
rm[rmOffset + 5] = 1;
|
||||
}
|
||||
else if (0.0f == x && 0.0f == y && 1.0f == z)
|
||||
{
|
||||
rm[rmOffset + 0] = c;
|
||||
rm[rmOffset + 5] = c;
|
||||
rm[rmOffset + 1] = s;
|
||||
rm[rmOffset + 4] = -s;
|
||||
rm[rmOffset + 2] = 0;
|
||||
rm[rmOffset + 6] = 0;
|
||||
rm[rmOffset + 8] = 0;
|
||||
rm[rmOffset + 9] = 0;
|
||||
rm[rmOffset + 10] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
float len = length(x, y, z);
|
||||
if (1.0f != len)
|
||||
{
|
||||
float recipLen = 1.0f / len;
|
||||
x *= recipLen;
|
||||
y *= recipLen;
|
||||
z *= recipLen;
|
||||
}
|
||||
float nc = 1.0f - c;
|
||||
float xy = x * y;
|
||||
float yz = y * z;
|
||||
float zx = z * x;
|
||||
float xs = x * s;
|
||||
float ys = y * s;
|
||||
float zs = z * s;
|
||||
rm[rmOffset + 0] = x * x * nc + c;
|
||||
rm[rmOffset + 4] = xy * nc - zs;
|
||||
rm[rmOffset + 8] = zx * nc + ys;
|
||||
rm[rmOffset + 1] = xy * nc + zs;
|
||||
rm[rmOffset + 5] = y * y * nc + c;
|
||||
rm[rmOffset + 9] = yz * nc - xs;
|
||||
rm[rmOffset + 2] = zx * nc - ys;
|
||||
rm[rmOffset + 6] = yz * nc + xs;
|
||||
rm[rmOffset + 10] = z * z * nc + c;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -315,14 +350,17 @@ static void setRotateM(float* rm, int rmOffset, float a, float x, float y,
|
||||
* @param m the input array
|
||||
* @param mOffset an offset into m where the matrix is stored.
|
||||
*/
|
||||
static void transposeM(float* mTrans, int mTransOffset, float* m, int mOffset) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int mBase = i * 4 + mOffset;
|
||||
mTrans[i + mTransOffset] = m[mBase];
|
||||
mTrans[i + 4 + mTransOffset] = m[mBase + 1];
|
||||
mTrans[i + 8 + mTransOffset] = m[mBase + 2];
|
||||
mTrans[i + 12 + mTransOffset] = m[mBase + 3];
|
||||
}
|
||||
static inline void
|
||||
transposeM(float* mTrans, int mTransOffset, float* m, int mOffset)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int mBase = i * 4 + mOffset;
|
||||
mTrans[i + mTransOffset] = m[mBase];
|
||||
mTrans[i + 4 + mTransOffset] = m[mBase + 1];
|
||||
mTrans[i + 8 + mTransOffset] = m[mBase + 2];
|
||||
mTrans[i + 12 + mTransOffset] = m[mBase + 3];
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Copyright 2011 See libgdx AUTHORS file.
|
||||
@ -357,17 +395,14 @@ static void transposeM(float* mTrans, int mTransOffset, float* m, int mOffset) {
|
||||
#define M32 11
|
||||
#define M33 15
|
||||
|
||||
static inline void matrix4_proj(float* mat, float* vec) {
|
||||
float inv_w = 1.0f
|
||||
/ (vec[0] * mat[M30] + vec[1] * mat[M31] + vec[2] * mat[M32]
|
||||
+ mat[M33]);
|
||||
float x = (vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02]
|
||||
+ mat[M03]) * inv_w;
|
||||
float y = (vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12]
|
||||
+ mat[M13]) * inv_w;
|
||||
float z = (vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22]
|
||||
+ mat[M23]) * inv_w;
|
||||
vec[0] = x;
|
||||
vec[1] = y;
|
||||
vec[2] = z;
|
||||
static inline void
|
||||
matrix4_proj(float* mat, float* vec)
|
||||
{
|
||||
float inv_w = 1.0f / (vec[0] * mat[M30] + vec[1] * mat[M31] + vec[2] * mat[M32] + mat[M33]);
|
||||
float x = (vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02] + mat[M03]) * inv_w;
|
||||
float y = (vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12] + mat[M13]) * inv_w;
|
||||
float z = (vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22] + mat[M23]) * inv_w;
|
||||
vec[0] = x;
|
||||
vec[1] = y;
|
||||
vec[2] = z;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import org.oscim.core.GeoPoint;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.MercatorProjection;
|
||||
import org.oscim.overlay.OverlayItem.HotspotPlace;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.SymbolLayer;
|
||||
import org.oscim.renderer.overlays.BasicOverlay;
|
||||
import org.oscim.view.MapView;
|
||||
@ -32,7 +33,6 @@ import org.oscim.view.MapView;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.opengl.Matrix;
|
||||
|
||||
/* @author Marc Kurtz
|
||||
* @author Nicolas Gramlich
|
||||
@ -77,8 +77,7 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
||||
class ItemOverlay extends BasicOverlay {
|
||||
|
||||
private final SymbolLayer mSymbolLayer;
|
||||
private final float[] mMvp = new float[16];
|
||||
private final float[] mVec = new float[4];
|
||||
private final float[] mVec = new float[3];
|
||||
|
||||
public ItemOverlay(MapView mapView) {
|
||||
super(mapView);
|
||||
@ -89,7 +88,7 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
||||
@Override
|
||||
public synchronized void update(MapPosition curPos,
|
||||
boolean positionChanged,
|
||||
boolean tilesChanged) {
|
||||
boolean tilesChanged, Matrices matrices) {
|
||||
|
||||
if (!positionChanged && !mUpdate)
|
||||
return;
|
||||
@ -100,12 +99,6 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
||||
int mx = (int) curPos.x;
|
||||
int my = (int) curPos.y;
|
||||
|
||||
// TODO could pass mvp as param
|
||||
mMapView.getMapViewPosition().getMatrix(null, null, mMvp);
|
||||
|
||||
float[] matrix = mMvp;
|
||||
float[] vec = mVec;
|
||||
|
||||
// limit could be 1 if we update on every position change
|
||||
float limit = 1.5f;
|
||||
|
||||
@ -139,13 +132,13 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
||||
}
|
||||
|
||||
// map points to screen
|
||||
vec[0] = it.x;
|
||||
vec[1] = it.y;
|
||||
vec[2] = 0;
|
||||
vec[3] = 1;
|
||||
Matrix.multiplyMV(vec, 0, matrix, 0, vec, 0);
|
||||
float sx = vec[0] / vec[3];
|
||||
float sy = vec[1] / vec[3];
|
||||
mVec[0] = it.x;
|
||||
mVec[1] = it.y;
|
||||
mVec[2] = 0;
|
||||
matrices.viewproj.prj(mVec);
|
||||
|
||||
float sx = mVec[0];
|
||||
float sy = mVec[1];
|
||||
|
||||
// check if it is visible
|
||||
if (sx < -limit || sx > limit || sy < -limit || sy > limit) {
|
||||
|
@ -22,6 +22,7 @@ import java.util.List;
|
||||
import org.oscim.core.GeoPoint;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.MercatorProjection;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.Layer;
|
||||
import org.oscim.renderer.layer.LineLayer;
|
||||
import org.oscim.renderer.overlays.BasicOverlay;
|
||||
@ -73,7 +74,7 @@ public class PathOverlay extends Overlay {
|
||||
@Override
|
||||
public synchronized void update(MapPosition curPos,
|
||||
boolean positionChanged,
|
||||
boolean tilesChanged) {
|
||||
boolean tilesChanged, Matrices matrices) {
|
||||
|
||||
if (!tilesChanged && !mUpdatePoints)
|
||||
return;
|
||||
|
@ -22,10 +22,9 @@ import org.oscim.core.MapPosition;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.Layer;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.GlUtils;
|
||||
import org.oscim.utils.Matrix4;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.Matrix;
|
||||
|
||||
/**
|
||||
* This class is for rendering the Line- and PolygonLayers of visible MapTiles.
|
||||
@ -38,9 +37,9 @@ import android.opengl.Matrix;
|
||||
public class BaseMap {
|
||||
private final static String TAG = BaseMap.class.getName();
|
||||
|
||||
private static float[] mMVPMatrix = new float[16];
|
||||
private static float[] mVPMatrix = new float[16];
|
||||
private static float[] mfProjMatrix = new float[16];
|
||||
//private static Matrix4 mMVPMatrix = new Matrix4();
|
||||
private static Matrix4 mVPMatrix = new Matrix4();
|
||||
private static Matrix4 mfProjMatrix = new Matrix4();
|
||||
|
||||
// used to increase polygon-offset for each tile drawn.
|
||||
private static int mDrawCnt;
|
||||
@ -48,17 +47,26 @@ public class BaseMap {
|
||||
// used to not draw a tile twice per frame.
|
||||
private static int mDrawSerial = 0;
|
||||
|
||||
static void setProjection(float[] projMatrix) {
|
||||
System.arraycopy(projMatrix, 0, mfProjMatrix, 0, 16);
|
||||
static void setProjection(Matrix4 projMatrix) {
|
||||
float[] tmp = new float[16];
|
||||
projMatrix.get(tmp);
|
||||
//System.arraycopy(projMatrix, 0, mfProjMatrix, 0, 16);
|
||||
// set to zero: we modify the z value with polygon-offset for clipping
|
||||
mfProjMatrix[10] = 0;
|
||||
mfProjMatrix[14] = 0;
|
||||
tmp[10] = 0;
|
||||
tmp[14] = 0;
|
||||
mfProjMatrix.set(tmp);
|
||||
}
|
||||
|
||||
private static Matrices mMatrices;
|
||||
|
||||
static void draw(MapTile[] tiles, int tileCnt, MapPosition pos, Matrices m) {
|
||||
mDrawCnt = 0;
|
||||
mMatrices = m;
|
||||
|
||||
Matrix.multiplyMM(mVPMatrix, 0, mfProjMatrix, 0, m.view, 0);
|
||||
// use our 'flat' projection matrix
|
||||
mVPMatrix.multiplyMM(mfProjMatrix, m.view);
|
||||
|
||||
//Matrix.multiplyMM(mVPMatrix, 0, mfProjMatrix, 0, m.view, 0);
|
||||
|
||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||
|
||||
@ -95,8 +103,12 @@ public class BaseMap {
|
||||
LineRenderer.endLines();
|
||||
|
||||
mDrawSerial++;
|
||||
|
||||
// dont keep the ref...
|
||||
mMatrices = null;
|
||||
}
|
||||
|
||||
|
||||
private static void drawTile(MapTile tile, MapPosition pos) {
|
||||
// draw parents only once
|
||||
if (tile.lastDraw == mDrawSerial)
|
||||
@ -121,11 +133,11 @@ public class BaseMap {
|
||||
float y = (float) (tile.pixelY - pos.y * div);
|
||||
float scale = pos.scale / div;
|
||||
|
||||
float[] mvp = mMVPMatrix;
|
||||
GlUtils.setTileMatrix(mvp, x, y, scale);
|
||||
Matrices m = mMatrices;
|
||||
m.mvp.setTransScale(x * scale, y * scale, scale / GLRenderer.COORD_SCALE);
|
||||
|
||||
// add view-projection matrix
|
||||
Matrix.multiplyMM(mvp, 0, mVPMatrix, 0, mvp, 0);
|
||||
m.mvp.multiplyMM(mVPMatrix, m.mvp);
|
||||
|
||||
// set depth offset (used for clipping to tile boundaries)
|
||||
GLES20.glPolygonOffset(1, mDrawCnt++);
|
||||
@ -140,26 +152,26 @@ public class BaseMap {
|
||||
for (Layer l = t.layers.baseLayers; l != null;) {
|
||||
switch (l.type) {
|
||||
case Layer.POLYGON:
|
||||
l = PolygonRenderer.draw(pos, l, mvp, !clipped, true);
|
||||
l = PolygonRenderer.draw(pos, l, m, !clipped, true);
|
||||
clipped = true;
|
||||
break;
|
||||
|
||||
case Layer.LINE:
|
||||
if (!clipped) {
|
||||
// draw stencil buffer clip region
|
||||
PolygonRenderer.draw(pos, null, mvp, true, true);
|
||||
PolygonRenderer.draw(pos, null, m, true, true);
|
||||
clipped = true;
|
||||
}
|
||||
l = LineRenderer.draw(t.layers, l, pos, mvp, div, simpleShader);
|
||||
l = LineRenderer.draw(t.layers, l, pos, m, div, simpleShader);
|
||||
break;
|
||||
|
||||
case Layer.TEXLINE:
|
||||
if (!clipped) {
|
||||
// draw stencil buffer clip region
|
||||
PolygonRenderer.draw(pos, null, mvp, true, true);
|
||||
PolygonRenderer.draw(pos, null, m, true, true);
|
||||
clipped = true;
|
||||
}
|
||||
l = LineTexRenderer.draw(t.layers, l, pos, mvp, div);
|
||||
l = LineTexRenderer.draw(t.layers, l, pos, m, div);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -169,7 +181,7 @@ public class BaseMap {
|
||||
}
|
||||
|
||||
// clear clip-region and could also draw 'fade-effect'
|
||||
PolygonRenderer.drawOver(mvp);
|
||||
PolygonRenderer.drawOver(m);
|
||||
}
|
||||
|
||||
private static int drawProxyChild(MapTile tile, MapPosition pos) {
|
||||
|
@ -37,12 +37,12 @@ import org.oscim.renderer.overlays.RenderOverlay;
|
||||
import org.oscim.theme.RenderTheme;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.GlUtils;
|
||||
import org.oscim.utils.Matrix4;
|
||||
import org.oscim.view.MapView;
|
||||
import org.oscim.view.MapViewPosition;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.opengl.Matrix;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
@ -75,15 +75,15 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
private static int mBufferMemoryUsage;
|
||||
|
||||
private static float[] mTileCoords = new float[8];
|
||||
private static float[] mDebugCoords = new float[8];
|
||||
//private static float[] mDebugCoords = new float[8];
|
||||
|
||||
public class Matrices {
|
||||
public final float[] viewproj = new float[16];
|
||||
public final float[] proj = new float[16];
|
||||
public final float[] view = new float[16];
|
||||
public final Matrix4 viewproj = new Matrix4();
|
||||
public final Matrix4 proj = new Matrix4();
|
||||
public final Matrix4 view = new Matrix4();
|
||||
|
||||
// for temporary use by callee
|
||||
public final float[] mvp = new float[16];
|
||||
public final Matrix4 mvp = new Matrix4();
|
||||
}
|
||||
|
||||
private static Matrices mMatrices;
|
||||
@ -476,7 +476,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
List<RenderOverlay> overlays = mMapView.getOverlayManager().getRenderLayers();
|
||||
|
||||
for (int i = 0, n = overlays.size(); i < n; i++)
|
||||
overlays.get(i).update(mMapPosition, positionChanged, tilesChanged);
|
||||
overlays.get(i).update(mMapPosition, positionChanged, tilesChanged, mMatrices);
|
||||
|
||||
/* draw base layer */
|
||||
BaseMap.draw(tiles, tileCnt, pos, mMatrices);
|
||||
@ -498,30 +498,30 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start));
|
||||
}
|
||||
|
||||
if (debugView) {
|
||||
GLState.test(false, false);
|
||||
|
||||
float mm = 0.5f;
|
||||
float min = -mm;
|
||||
float max = mm;
|
||||
float ymax = mm * mHeight / mWidth;
|
||||
mDebugCoords[0] = min;
|
||||
mDebugCoords[1] = ymax;
|
||||
mDebugCoords[2] = max;
|
||||
mDebugCoords[3] = ymax;
|
||||
mDebugCoords[4] = min;
|
||||
mDebugCoords[5] = -ymax;
|
||||
mDebugCoords[6] = max;
|
||||
mDebugCoords[7] = -ymax;
|
||||
|
||||
PolygonRenderer.debugDraw(mMatrices.proj, mDebugCoords, 0);
|
||||
|
||||
pos.zoomLevel = -1;
|
||||
mMapViewPosition.getMapViewProjection(mDebugCoords);
|
||||
|
||||
PolygonRenderer.debugDraw(mMatrices.viewproj, mDebugCoords, 1);
|
||||
|
||||
}
|
||||
//if (debugView) {
|
||||
// GLState.test(false, false);
|
||||
//
|
||||
// float mm = 0.5f;
|
||||
// float min = -mm;
|
||||
// float max = mm;
|
||||
// float ymax = mm * mHeight / mWidth;
|
||||
// mDebugCoords[0] = min;
|
||||
// mDebugCoords[1] = ymax;
|
||||
// mDebugCoords[2] = max;
|
||||
// mDebugCoords[3] = ymax;
|
||||
// mDebugCoords[4] = min;
|
||||
// mDebugCoords[5] = -ymax;
|
||||
// mDebugCoords[6] = max;
|
||||
// mDebugCoords[7] = -ymax;
|
||||
//
|
||||
// PolygonRenderer.debugDraw(mMatrices.proj, mDebugCoords, 0);
|
||||
//
|
||||
// pos.zoomLevel = -1;
|
||||
// mMapViewPosition.getMapViewProjection(mDebugCoords);
|
||||
//
|
||||
// PolygonRenderer.debugDraw(mMatrices.viewproj, mDebugCoords, 1);
|
||||
//
|
||||
//}
|
||||
|
||||
if (GlUtils.checkGlOutOfMemory("finish")) {
|
||||
checkBufferUsage(true);
|
||||
@ -583,13 +583,13 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
|
||||
mMapViewPosition.getMatrix(null, mMatrices.proj, null);
|
||||
|
||||
if (debugView) {
|
||||
// modify this to scale only the view, to see better which tiles are
|
||||
// rendered
|
||||
Matrix.setIdentityM(mMatrices.mvp, 0);
|
||||
Matrix.scaleM(mMatrices.mvp, 0, 0.5f, 0.5f, 1);
|
||||
Matrix.multiplyMM(mMatrices.proj, 0, mMatrices.mvp, 0, mMatrices.proj, 0);
|
||||
}
|
||||
//if (debugView) {
|
||||
// // modify this to scale only the view, to see better which tiles are
|
||||
// // rendered
|
||||
// Matrix.setIdentityM(mMatrices.mvp, 0);
|
||||
// Matrix.scaleM(mMatrices.mvp, 0, 0.5f, 0.5f, 1);
|
||||
// Matrix.multiplyMM(mMatrices.proj, 0, mMatrices.mvp, 0, mMatrices.proj, 0);
|
||||
//}
|
||||
|
||||
BaseMap.setProjection(mMatrices.proj);
|
||||
|
||||
|
@ -20,12 +20,11 @@ import static android.opengl.GLES20.glDrawArrays;
|
||||
import static android.opengl.GLES20.glGetAttribLocation;
|
||||
import static android.opengl.GLES20.glGetUniformLocation;
|
||||
import static android.opengl.GLES20.glUniform1f;
|
||||
import static android.opengl.GLES20.glUniform4fv;
|
||||
import static android.opengl.GLES20.glUniformMatrix4fv;
|
||||
import static android.opengl.GLES20.glVertexAttribPointer;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.generator.TileGenerator;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.Layer;
|
||||
import org.oscim.renderer.layer.Layers;
|
||||
import org.oscim.renderer.layer.LineLayer;
|
||||
@ -109,7 +108,7 @@ public final class LineRenderer {
|
||||
}
|
||||
|
||||
public static Layer draw(Layers layers, Layer curLayer, MapPosition pos,
|
||||
float[] matrix, float div, int mode) {
|
||||
Matrices m, float div, int mode) {
|
||||
|
||||
if (curLayer == null)
|
||||
return null;
|
||||
@ -128,7 +127,8 @@ public final class LineRenderer {
|
||||
glVertexAttribPointer(hLineVertexPosition[mode], 4, GL_SHORT,
|
||||
false, 0, layers.lineOffset + LINE_VERTICES_DATA_POS_OFFSET);
|
||||
|
||||
glUniformMatrix4fv(hLineMatrix[mode], 1, false, matrix, 0);
|
||||
//glUniformMatrix4fv(hLineMatrix[mode], 1, false, matrix, 0);
|
||||
m.mvp.setAsUniform(hLineMatrix[mode]);
|
||||
|
||||
int zoom = pos.zoomLevel;
|
||||
float scale = pos.scale;
|
||||
@ -163,7 +163,7 @@ public final class LineRenderer {
|
||||
float width;
|
||||
|
||||
if (line.fade < zoom) {
|
||||
glUniform4fv(uLineColor, 1, line.color, 0);
|
||||
GlUtils.setColor(uLineColor, line.color, 1);
|
||||
} else if (line.fade > zoom) {
|
||||
continue;
|
||||
} else {
|
||||
|
@ -19,6 +19,7 @@ import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.Layer;
|
||||
import org.oscim.renderer.layer.Layers;
|
||||
import org.oscim.renderer.layer.LineLayer;
|
||||
@ -57,7 +58,7 @@ public class LineTexRenderer {
|
||||
// batch up up to 64 quads in one draw call
|
||||
private static int maxQuads = 64;
|
||||
private static int maxIndices = maxQuads * 6;
|
||||
private static int[] mTexID;
|
||||
//private static int[] mTexID;
|
||||
|
||||
public static void init() {
|
||||
shader = GlUtils.createProgram(vertexShader, fragmentShader);
|
||||
@ -132,7 +133,7 @@ public class LineTexRenderer {
|
||||
private final static int LEN_OFFSET = 8;
|
||||
|
||||
public static Layer draw(Layers layers, Layer curLayer,
|
||||
MapPosition pos, float[] matrix, float div) {
|
||||
MapPosition pos, Matrices m, float div) {
|
||||
|
||||
GLState.blend(true);
|
||||
GLState.useProgram(shader);
|
||||
@ -145,7 +146,8 @@ public class LineTexRenderer {
|
||||
GLES20.glEnableVertexAttribArray(hVertexLength1);
|
||||
GLES20.glEnableVertexAttribArray(hVertexFlip);
|
||||
|
||||
GLES20.glUniformMatrix4fv(hMatrix, 1, false, matrix, 0);
|
||||
//GLES20.glUniformMatrix4fv(hMatrix, 1, false, matrix, 0);
|
||||
m.mvp.setAsUniform(hMatrix);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER,
|
||||
mIndicesBufferID);
|
||||
@ -180,8 +182,6 @@ public class LineTexRenderer {
|
||||
// keep line width fixed
|
||||
GLES20.glUniform1f(hWidth, ll.width / s * COORD_SCALE_BY_DIR_SCALE);
|
||||
|
||||
GlUtils.checkGlError("0");
|
||||
|
||||
// add offset vertex
|
||||
int vOffset = -STRIDE;
|
||||
|
||||
@ -246,7 +246,7 @@ public class LineTexRenderer {
|
||||
|
||||
l = l.next;
|
||||
|
||||
GlUtils.checkGlError(TAG);
|
||||
//GlUtils.checkGlError(TAG);
|
||||
}
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
@ -37,6 +37,7 @@ import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.Layer;
|
||||
import org.oscim.renderer.layer.PolygonLayer;
|
||||
import org.oscim.theme.renderinstruction.Area;
|
||||
@ -105,12 +106,8 @@ public final class PolygonRenderer {
|
||||
}
|
||||
GLState.blend(true);
|
||||
|
||||
if (f < 1) {
|
||||
GlUtils.setColor(hPolygonColor, a.color,
|
||||
f * a.color[3]);
|
||||
} else {
|
||||
glUniform4fv(hPolygonColor, 1, a.color, 0);
|
||||
}
|
||||
GlUtils.setColor(hPolygonColor, a.color, f);
|
||||
|
||||
} else if (a.blend > 0 && a.blend <= zoom) {
|
||||
/* blend colors (not alpha) */
|
||||
GLState.blend(false);
|
||||
@ -119,7 +116,7 @@ public final class PolygonRenderer {
|
||||
GlUtils.setBlendColors(hPolygonColor,
|
||||
a.color, a.blendColor, scale - 1.0f);
|
||||
else
|
||||
glUniform4fv(hPolygonColor, 1, a.blendColor, 0);
|
||||
GlUtils.setColor(hPolygonColor, a.blendColor, 1);
|
||||
|
||||
} else {
|
||||
if (a.color[3] != 1)
|
||||
@ -127,7 +124,7 @@ public final class PolygonRenderer {
|
||||
else
|
||||
GLState.blend(false);
|
||||
|
||||
glUniform4fv(hPolygonColor, 1, a.color, 0);
|
||||
GlUtils.setColor(hPolygonColor, a.color, 1);
|
||||
}
|
||||
|
||||
// set stencil buffer mask used to draw this layer
|
||||
@ -152,8 +149,8 @@ public final class PolygonRenderer {
|
||||
* in layer.area.
|
||||
* @param layer
|
||||
* layer to draw (referencing vertices in current vbo)
|
||||
* @param matrix
|
||||
* mvp matrix
|
||||
* @param m
|
||||
* current Matrices
|
||||
* @param first
|
||||
* pass true to clear stencil buffer region
|
||||
* @param clip
|
||||
@ -162,7 +159,7 @@ public final class PolygonRenderer {
|
||||
* next layer
|
||||
*/
|
||||
public static Layer draw(MapPosition pos, Layer layer,
|
||||
float[] matrix, boolean first, boolean clip) {
|
||||
Matrices m, boolean first, boolean clip) {
|
||||
|
||||
GLState.test(false, true);
|
||||
|
||||
@ -170,7 +167,8 @@ public final class PolygonRenderer {
|
||||
GLState.enableVertexArrays(hPolygonVertexPosition, -1);
|
||||
glVertexAttribPointer(hPolygonVertexPosition, 2, GL_SHORT,
|
||||
false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
glUniformMatrix4fv(hPolygonMatrix, 1, false, matrix, 0);
|
||||
|
||||
m.mvp.setAsUniform(hPolygonMatrix);
|
||||
|
||||
int zoom = pos.zoomLevel;
|
||||
int cur = mCount;
|
||||
@ -296,7 +294,7 @@ public final class PolygonRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
static void drawOver(float[] matrix) {
|
||||
static void drawOver(Matrices m) {
|
||||
if (GLState.useProgram(polygonProgram)) {
|
||||
|
||||
GLState.enableVertexArrays(hPolygonVertexPosition, -1);
|
||||
@ -304,7 +302,7 @@ public final class PolygonRenderer {
|
||||
glVertexAttribPointer(hPolygonVertexPosition, 2, GL_SHORT,
|
||||
false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
|
||||
glUniformMatrix4fv(hPolygonMatrix, 1, false, matrix, 0);
|
||||
m.mvp.setAsUniform(hPolygonMatrix);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -19,6 +19,7 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.Layer;
|
||||
import org.oscim.renderer.layer.TextureLayer;
|
||||
import org.oscim.utils.GlUtils;
|
||||
@ -92,7 +93,7 @@ public final class TextureRenderer {
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
public static Layer draw(Layer layer, float scale, float[] projection, float matrix[]) {
|
||||
public static Layer draw(Layer layer, float scale, Matrices m) {
|
||||
GLState.test(false, false);
|
||||
GLState.blend(true);
|
||||
|
||||
@ -109,8 +110,8 @@ public final class TextureRenderer {
|
||||
|
||||
GLES20.glUniform1f(hTextureScreenScale, 1f / GLRenderer.mWidth);
|
||||
|
||||
GLES20.glUniformMatrix4fv(hTextureProjMatrix, 1, false, projection, 0);
|
||||
GLES20.glUniformMatrix4fv(hTextureMVMatrix, 1, false, matrix, 0);
|
||||
m.proj.setAsUniform(hTextureProjMatrix);
|
||||
m.mvp.setAsUniform(hTextureMVMatrix);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesVBO);
|
||||
|
||||
@ -143,8 +144,6 @@ public final class TextureRenderer {
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
// GlUtils.checkGlError("< draw texture");
|
||||
|
||||
return layer.next;
|
||||
}
|
||||
|
||||
|
@ -59,13 +59,13 @@ public abstract class BasicOverlay extends RenderOverlay {
|
||||
for (Layer l = layers.baseLayers; l != null;) {
|
||||
switch (l.type) {
|
||||
case Layer.POLYGON:
|
||||
l = PolygonRenderer.draw(pos, l, m.mvp, true, false);
|
||||
l = PolygonRenderer.draw(pos, l, m, true, false);
|
||||
break;
|
||||
case Layer.LINE:
|
||||
l = LineRenderer.draw(layers, l, pos, m.mvp, div, 0);
|
||||
l = LineRenderer.draw(layers, l, pos, m, div, 0);
|
||||
break;
|
||||
case Layer.TEXLINE:
|
||||
l = LineTexRenderer.draw(layers, l, pos, m.mvp, div);
|
||||
l = LineTexRenderer.draw(layers, l, pos, m, div);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -77,7 +77,7 @@ public abstract class BasicOverlay extends RenderOverlay {
|
||||
float scale = (mMapPosition.scale / pos.scale) * div;
|
||||
|
||||
for (Layer l = layers.textureLayers; l != null;) {
|
||||
l = TextureRenderer.draw(l, scale, m.proj, m.mvp);
|
||||
l = TextureRenderer.draw(l, scale, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,534 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.overlays;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLRenderer;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.GLState;
|
||||
import org.oscim.renderer.layer.VertexPool;
|
||||
import org.oscim.renderer.layer.VertexPoolItem;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.GlUtils;
|
||||
import org.oscim.view.MapView;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.Matrix;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @author Hannes Janetzek
|
||||
*/
|
||||
public class BuildingOverlay extends RenderOverlay {
|
||||
|
||||
public BuildingOverlay(MapView mapView) {
|
||||
super(mapView);
|
||||
}
|
||||
|
||||
private static int buildingProgram;
|
||||
private static int hBuildingVertexPosition;
|
||||
private static int hBuildingLightPosition;
|
||||
private static int hBuildingMatrix;
|
||||
private static int hBuildingColor;
|
||||
private static int hBuildingMode;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
private int mIndicesBufferID;
|
||||
private int mVertexBufferID;
|
||||
|
||||
private int mNumIndices = 0;
|
||||
private int mNumVertices = 0;
|
||||
private VertexPoolItem mVertices, mCurVertices;
|
||||
private VertexPoolItem mIndices[], mCurIndices[];
|
||||
|
||||
private final int mIndiceCnt[] = { 0, 0, 0 };
|
||||
|
||||
private void addOutline(float[] points, float height) {
|
||||
int len = points.length;
|
||||
boolean oddFace = (len % 4 != 0);
|
||||
int verticesCnt = len + (oddFace ? 2 : 0);
|
||||
int indicesCnt = len / 2 * 6;
|
||||
|
||||
short h = (short) height;
|
||||
|
||||
float cx = points[len - 2];
|
||||
float cy = points[len - 1];
|
||||
float nx = points[0];
|
||||
float ny = points[1];
|
||||
|
||||
float vx = nx - cx;
|
||||
float vy = ny - cy;
|
||||
float a = vx / (float) Math.sqrt(vx * vx + vy * vy);
|
||||
|
||||
short color1 = (short) (200 + (40 * (a > 0 ? a : -a)));
|
||||
short fcolor = color1;
|
||||
short color2 = 0;
|
||||
|
||||
boolean even = true;
|
||||
|
||||
short[] vertices = mCurVertices.vertices;
|
||||
int v = mCurVertices.used;
|
||||
|
||||
for (int i = 0; i < len; i += 2, v += 8) {
|
||||
cx = nx;
|
||||
cy = ny;
|
||||
|
||||
if (v == VertexPoolItem.SIZE) {
|
||||
mCurVertices.used = VertexPoolItem.SIZE;
|
||||
mCurVertices.next = VertexPool.get();
|
||||
mCurVertices = mCurVertices.next;
|
||||
vertices = mCurVertices.vertices;
|
||||
v = 0;
|
||||
}
|
||||
|
||||
vertices[v + 0] = vertices[v + 4] = (short) cx;
|
||||
vertices[v + 1] = vertices[v + 5] = (short) cy;
|
||||
|
||||
vertices[v + 2] = 0;
|
||||
vertices[v + 6] = h;
|
||||
|
||||
if (i < len - 2) {
|
||||
nx = points[i + 2];
|
||||
ny = points[i + 3];
|
||||
|
||||
vx = nx - cx;
|
||||
vy = ny - cy;
|
||||
a = vx / (float) Math.sqrt(vx * vx + vy * vy);
|
||||
|
||||
color2 = (short) (200 + (40 * (a > 0 ? a : -a)));
|
||||
} else {
|
||||
color2 = fcolor;
|
||||
}
|
||||
|
||||
short c;
|
||||
if (even)
|
||||
c = (short) (color1 | color2 << 8);
|
||||
else
|
||||
c = (short) (color2 | color1 << 8);
|
||||
|
||||
vertices[v + 3] = vertices[v + 7] = c;
|
||||
|
||||
color1 = color2;
|
||||
even = !even;
|
||||
}
|
||||
|
||||
if (oddFace) {
|
||||
//int v = len * 4;
|
||||
if (v == VertexPoolItem.SIZE) {
|
||||
mCurVertices.used = VertexPoolItem.SIZE;
|
||||
mCurVertices.next = VertexPool.get();
|
||||
mCurVertices = mCurVertices.next;
|
||||
vertices = mCurVertices.vertices;
|
||||
v = 0;
|
||||
}
|
||||
|
||||
cx = points[0];
|
||||
cy = points[1];
|
||||
|
||||
vertices[v + 0] = vertices[v + 4] = (short) cx;
|
||||
vertices[v + 1] = vertices[v + 5] = (short) cy;
|
||||
|
||||
vertices[v + 2] = 0;
|
||||
vertices[v + 6] = h;
|
||||
|
||||
short c = (short) (color1 | fcolor << 8);
|
||||
vertices[v + 3] = vertices[v + 7] = c;
|
||||
|
||||
v += 8;
|
||||
}
|
||||
|
||||
mCurVertices.used = v;
|
||||
|
||||
// fill ZigZagQuadIndices(tm)
|
||||
for (int j = 0; j < 2; j++) {
|
||||
short[] indices = mCurIndices[j].vertices;
|
||||
int cnt = mCurIndices[j].used;
|
||||
|
||||
for (int k = j * 2; k < len; k += 4) {
|
||||
int i = mNumVertices + k;
|
||||
|
||||
short s0 = (short) (i + 0);
|
||||
short s1 = (short) (i + 1);
|
||||
short s2 = (short) (i + 2);
|
||||
short s3 = (short) (i + 3);
|
||||
|
||||
if (cnt == VertexPoolItem.SIZE) {
|
||||
mCurIndices[j].used = VertexPoolItem.SIZE;
|
||||
mCurIndices[j].next = VertexPool.get();
|
||||
mCurIndices[j] = mCurIndices[j].next;
|
||||
vertices = mCurIndices[j].vertices;
|
||||
cnt = 0;
|
||||
}
|
||||
|
||||
// connect last to first (when number of faces is even)
|
||||
if (k + 3 > verticesCnt) {
|
||||
s2 -= verticesCnt;
|
||||
s3 -= verticesCnt;
|
||||
}
|
||||
|
||||
indices[cnt++] = s0;
|
||||
indices[cnt++] = s1;
|
||||
indices[cnt++] = s2;
|
||||
|
||||
indices[cnt++] = s1;
|
||||
indices[cnt++] = s3;
|
||||
indices[cnt++] = s2;
|
||||
//System.out.println("indice:" + k + "\t" + s0 + "," + s1 + "," + s2);
|
||||
//System.out.println("indice:" + k + "\t" + s1 + "," + s3 + "," + s2);
|
||||
}
|
||||
mCurIndices[j].used = cnt;
|
||||
}
|
||||
|
||||
// roof indices for convex shapes
|
||||
int cnt = mCurIndices[2].used;
|
||||
short[] indices = mCurIndices[2].vertices;
|
||||
short first = (short) (mNumVertices + 1);
|
||||
|
||||
for (int k = 0; k < len - 4; k += 2) {
|
||||
|
||||
if (cnt == VertexPoolItem.SIZE) {
|
||||
mCurIndices[2].used = VertexPoolItem.SIZE;
|
||||
mCurIndices[2].next = VertexPool.get();
|
||||
mCurIndices[2] = mCurIndices[2].next;
|
||||
vertices = mCurIndices[2].vertices;
|
||||
cnt = 0;
|
||||
}
|
||||
indices[cnt++] = first;
|
||||
indices[cnt++] = (short) (first + k + 4);
|
||||
indices[cnt++] = (short) (first + k + 2);
|
||||
|
||||
System.out.println("indice:" + k + "\t" + indices[cnt - 3] + "," + indices[cnt - 2]
|
||||
+ "," + indices[cnt - 1]);
|
||||
|
||||
indicesCnt += 3;
|
||||
}
|
||||
mCurIndices[2].used = cnt;
|
||||
|
||||
mNumVertices += verticesCnt;
|
||||
mNumIndices += indicesCnt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
||||
boolean tilesChanged) {
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
initialized = true;
|
||||
|
||||
// Set up the program for rendering buildings
|
||||
buildingProgram = GlUtils.createProgram(buildingVertexShader,
|
||||
buildingFragmentShader);
|
||||
if (buildingProgram == 0) {
|
||||
Log.e("blah", "Could not create building program.");
|
||||
return;
|
||||
}
|
||||
hBuildingMatrix = GLES20.glGetUniformLocation(buildingProgram, "u_mvp");
|
||||
hBuildingColor = GLES20.glGetUniformLocation(buildingProgram, "u_color");
|
||||
hBuildingMode = GLES20.glGetUniformLocation(buildingProgram, "u_mode");
|
||||
hBuildingVertexPosition = GLES20.glGetAttribLocation(buildingProgram, "a_position");
|
||||
hBuildingLightPosition = GLES20.glGetAttribLocation(buildingProgram, "a_light");
|
||||
|
||||
mVertices = mCurVertices = VertexPool.get();
|
||||
mIndices = new VertexPoolItem[3];
|
||||
mCurIndices = new VertexPoolItem[3];
|
||||
mIndices[0] = mCurIndices[0] = VertexPool.get();
|
||||
mIndices[1] = mCurIndices[1] = VertexPool.get();
|
||||
mIndices[2] = mCurIndices[2] = VertexPool.get();
|
||||
|
||||
float height = 450;
|
||||
|
||||
float[] points = {
|
||||
-200, -200,
|
||||
200, -200,
|
||||
200, 200,
|
||||
-200, 200,
|
||||
-300, 0
|
||||
};
|
||||
addOutline(points, height);
|
||||
|
||||
float[] points2 = {
|
||||
300, -300,
|
||||
500, -300,
|
||||
600, 100,
|
||||
300, 100,
|
||||
// 350, 0
|
||||
};
|
||||
|
||||
addOutline(points2, height);
|
||||
|
||||
height = 650;
|
||||
|
||||
float[] points4 = new float[80];
|
||||
for (int i = 0; i < 80; i += 2) {
|
||||
points4[i + 0] = (float) (Math.sin(i / -40f * Math.PI) * 200);
|
||||
points4[i + 1] = (float) (Math.cos(i / -40f * Math.PI) * 200) - 600;
|
||||
}
|
||||
|
||||
addOutline(points4, height);
|
||||
|
||||
height = 950;
|
||||
|
||||
points4 = new float[40];
|
||||
for (int i = 0; i < 40; i += 2) {
|
||||
points4[i + 0] = (float) (Math.sin(i / -20f * Math.PI) * 100);
|
||||
points4[i + 1] = (float) (Math.cos(i / -20f * Math.PI) * 100) - 550;
|
||||
}
|
||||
|
||||
addOutline(points4, height);
|
||||
|
||||
float[] points3 = new float[24];
|
||||
for (int i = 0; i < 24; i += 2) {
|
||||
points3[i + 0] = (float) (Math.sin(i / -12f * Math.PI) * 200) - 600;
|
||||
points3[i + 1] = (float) (Math.cos(i / -12f * Math.PI) * 200) - 600;
|
||||
}
|
||||
|
||||
addOutline(points3, height);
|
||||
|
||||
int bufferSize = Math.max(mNumVertices * 4 * 2, mNumIndices * 2);
|
||||
ByteBuffer buf = ByteBuffer.allocateDirect(bufferSize)
|
||||
.order(ByteOrder.nativeOrder());
|
||||
|
||||
ShortBuffer sbuf = buf.asShortBuffer();
|
||||
|
||||
int[] mVboIds = new int[2];
|
||||
GLES20.glGenBuffers(2, mVboIds, 0);
|
||||
mIndicesBufferID = mVboIds[0];
|
||||
mVertexBufferID = mVboIds[1];
|
||||
|
||||
// upload indices
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (VertexPoolItem vi = mIndices[i]; vi != null; vi = vi.next) {
|
||||
System.out.println("put indices: " + vi.used + " " + mNumIndices);
|
||||
sbuf.put(vi.vertices, 0, vi.used);
|
||||
mIndiceCnt[i] += vi.used;
|
||||
}
|
||||
}
|
||||
sbuf.flip();
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
||||
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER,
|
||||
mNumIndices * 2, sbuf, GLES20.GL_STATIC_DRAW);
|
||||
sbuf.clear();
|
||||
|
||||
// upload vertices
|
||||
for (VertexPoolItem vi = mVertices; vi != null; vi = vi.next) {
|
||||
System.out.println("put vertices: " + vi.used + " " + mNumVertices);
|
||||
sbuf.put(vi.vertices, 0, vi.used);
|
||||
}
|
||||
sbuf.flip();
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,
|
||||
mNumVertices * 4 * 2, sbuf, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
mMapView.getMapViewPosition().getMapPosition(mMapPosition);
|
||||
|
||||
// tell GLRenderer to call 'render'
|
||||
isReady = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void render(MapPosition pos, Matrices m) {
|
||||
setMatrix(pos, m);
|
||||
|
||||
GLState.useProgram(buildingProgram);
|
||||
|
||||
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, m.mvp, 0);
|
||||
GLES20.glUniform4f(hBuildingColor, 0.5f, 0.5f, 0.5f, 0.7f);
|
||||
|
||||
GLState.enableVertexArrays(hBuildingVertexPosition, hBuildingLightPosition);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||
|
||||
GLES20.glVertexAttribPointer(hBuildingVertexPosition, 3,
|
||||
GLES20.GL_SHORT, false, 8, 0);
|
||||
|
||||
GLES20.glVertexAttribPointer(hBuildingLightPosition, 2,
|
||||
GLES20.GL_UNSIGNED_BYTE, false, 8, 6);
|
||||
|
||||
// GLES20.glDrawElements(GLES20.GL_TRIANGLES, mNumIndices,
|
||||
// GLES20.GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
// draw to depth buffer
|
||||
GLES20.glUniform1i(hBuildingMode, 0);
|
||||
GLES20.glColorMask(false, false, false, false);
|
||||
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
|
||||
GLState.test(true, false);
|
||||
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
||||
|
||||
GLES20.glDepthMask(true);
|
||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mNumIndices,
|
||||
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
// enable color buffer, use depth mask
|
||||
GLES20.glColorMask(true, true, true, true);
|
||||
GLES20.glDepthMask(false);
|
||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||
|
||||
// draw roof
|
||||
GLES20.glUniform4f(hBuildingColor, 0.75f, 0.7f, 0.7f, 0.9f);
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mIndiceCnt[0],
|
||||
GLES20.GL_UNSIGNED_SHORT, (mIndiceCnt[0] + mIndiceCnt[1]) * 2);
|
||||
|
||||
// draw sides 1
|
||||
//GLES20.glUniform4f(hBuildingColor, 0.8f, 0.8f, 0.8f, 1.0f);
|
||||
GLES20.glUniform4f(hBuildingColor, 0.9f, 0.905f, 0.9f, 1.0f);
|
||||
GLES20.glUniform1i(hBuildingMode, 1);
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mIndiceCnt[0],
|
||||
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
// draw sides 2
|
||||
GLES20.glUniform4f(hBuildingColor, 0.9f, 0.9f, 0.905f, 1.0f);
|
||||
GLES20.glUniform1i(hBuildingMode, 2);
|
||||
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mIndiceCnt[1],
|
||||
GLES20.GL_UNSIGNED_SHORT, mIndiceCnt[0] * 2);
|
||||
|
||||
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
GlUtils.checkGlError("...");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setMatrix(MapPosition curPos, Matrices m) {
|
||||
|
||||
MapPosition oPos = mMapPosition;
|
||||
|
||||
byte z = oPos.zoomLevel;
|
||||
|
||||
float div = FastMath.pow(z - curPos.zoomLevel);
|
||||
float x = (float) (oPos.x - curPos.x * div);
|
||||
float y = (float) (oPos.y - curPos.y * div);
|
||||
|
||||
// flip around date-line
|
||||
float max = (Tile.TILE_SIZE << z);
|
||||
if (x < -max / 2)
|
||||
x = max + x;
|
||||
else if (x > max / 2)
|
||||
x = x - max;
|
||||
|
||||
float scale = curPos.scale / div;
|
||||
|
||||
Matrix.setIdentityM(m.mvp, 0);
|
||||
|
||||
// translate relative to map center
|
||||
m.mvp[12] = x * scale;
|
||||
m.mvp[13] = y * scale;
|
||||
// scale to current tile world coordinates
|
||||
scale = (curPos.scale / oPos.scale) / div;
|
||||
scale /= GLRenderer.COORD_SCALE;
|
||||
m.mvp[0] = scale;
|
||||
m.mvp[5] = scale;
|
||||
m.mvp[10] = scale / 1000f;
|
||||
|
||||
Matrix.multiplyMM(m.mvp, 0, m.viewproj, 0, m.mvp, 0);
|
||||
}
|
||||
|
||||
final static String buildingVertexShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "uniform int u_mode;"
|
||||
+ "uniform float u_scale;"
|
||||
+ "attribute vec4 a_position;"
|
||||
+ "attribute vec2 a_light;"
|
||||
+ "varying vec4 color;"
|
||||
+ "const float ff = 255.0;"
|
||||
+ "void main() {"
|
||||
+ " gl_Position = u_mvp * a_position;"
|
||||
+ " if (u_mode == 0)"
|
||||
// roof / depth pass
|
||||
+ " color = u_color;"
|
||||
+ " else if (u_mode == 1)"
|
||||
// sides 1 - use 0xff00
|
||||
+ " color = vec4(u_color.rgb * (a_light.y / ff), 0.95);"
|
||||
+ " else"
|
||||
// sides 2 - use 0x00ff
|
||||
+ " color = vec4(u_color.rgb * (a_light.x / ff), 0.95);"
|
||||
+ "}";
|
||||
|
||||
final static String buildingFragmentShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "varying vec4 color;"
|
||||
+ "void main() {"
|
||||
+ " gl_FragColor = color;"
|
||||
+ "}";
|
||||
|
||||
@Override
|
||||
public void compile() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
// private short[] mVertices = {
|
||||
// // 0 - north
|
||||
// -200, -200, 0,
|
||||
// (short) (220 | (200 << 8)),
|
||||
// // 1
|
||||
// -200, -200, 950,
|
||||
// (short) (220 | (200 << 8)),
|
||||
// // 2
|
||||
// 200, -200, 0,
|
||||
// (short) (170 | (200 << 8)),
|
||||
// // 3
|
||||
// 200, -200, 950,
|
||||
// (short) (170 | (200 << 8)),
|
||||
//
|
||||
// // 4 - south
|
||||
// 200, 200, 0,
|
||||
// (short) (170 | (180 << 8)),
|
||||
// // 5
|
||||
// 200, 200, 950,
|
||||
// (short) (170 | (180 << 8)),
|
||||
// // 6
|
||||
// -200, 200, 0,
|
||||
// (short) (220 | (180 << 8)),
|
||||
// // 7
|
||||
// -200, 200, 950,
|
||||
// (short) (220 | (180 << 8)),
|
||||
//};
|
||||
//
|
||||
//private short[] mIndices = {
|
||||
// // north
|
||||
// 0, 1, 2,
|
||||
// 1, 3, 2,
|
||||
// // south
|
||||
// 4, 5, 6,
|
||||
// 5, 7, 6,
|
||||
// // east
|
||||
// 2, 3, 4,
|
||||
// 3, 5, 4,
|
||||
// // west
|
||||
// 6, 7, 0,
|
||||
// 7, 1, 0,
|
||||
// // top
|
||||
// 1, 5, 3,
|
||||
// 7, 5, 1
|
||||
//};
|
||||
//
|
||||
//
|
||||
//private int mNumIndices = mIndices.length;
|
||||
//private int mNumVertices = mVertices.length / 4;
|
||||
}
|
@ -54,7 +54,7 @@ public class CustomOverlay extends RenderOverlay {
|
||||
|
||||
// ---------- everything below runs in GLRender Thread ----------
|
||||
@Override
|
||||
public void update(MapPosition curPos, boolean positionChanged, boolean tilesChanged) {
|
||||
public void update(MapPosition curPos, boolean positionChanged, boolean tilesChanged, Matrices matrices) {
|
||||
if (!mInitialized) {
|
||||
if (!init())
|
||||
return;
|
||||
@ -107,13 +107,7 @@ public class CustomOverlay extends RenderOverlay {
|
||||
// set mvp (tmp) matrix relative to mMapPosition
|
||||
// i.e. fixed on the map
|
||||
setMatrix(pos, m);
|
||||
|
||||
//Matrix.multiplyMM(tmp, 0, proj, 0, tmp, 0);
|
||||
|
||||
// or set mvp matrix fixed on screen center
|
||||
// Matrix.multiplyMM(tmp, 0, proj, 0, pos.viewMatrix, 0);
|
||||
|
||||
GLES20.glUniformMatrix4fv(hMatrixPosition, 1, false, m.mvp, 0);
|
||||
m.mvp.setAsUniform(hMatrixPosition);
|
||||
|
||||
// Draw the triangle
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
@ -31,7 +31,6 @@ import org.oscim.utils.GlUtils;
|
||||
import org.oscim.view.MapView;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.Matrix;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
@ -63,7 +62,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
|
||||
@Override
|
||||
public void update(MapPosition curPos, boolean positionChanged,
|
||||
boolean tilesChanged) {
|
||||
boolean tilesChanged, Matrices matrices) {
|
||||
|
||||
mMapView.getMapViewPosition().getMapPosition(mMapPosition);
|
||||
|
||||
@ -172,9 +171,6 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
// TODO one could render in one pass to texture and then draw the texture
|
||||
// with alpha... might be faster.
|
||||
|
||||
//Matrix.multiplyMM(mVPMatrix, 0, proj, 0, pos.viewMatrix, 0);
|
||||
//proj = mVPMatrix;
|
||||
|
||||
MapTile[] tiles = mTiles;
|
||||
|
||||
float div = FastMath.pow(tiles[0].zoomLevel - pos.zoomLevel);
|
||||
@ -200,7 +196,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
||||
|
||||
setMatrix(pos, m, tiles[i], div, 0);
|
||||
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, m.mvp, 0);
|
||||
m.mvp.setAsUniform(uExtMatrix);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
||||
@ -252,7 +248,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
|
||||
int d = GLRenderer.depthOffset(t) * 10;
|
||||
setMatrix(pos, m, t, div, d);
|
||||
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, m.mvp, 0);
|
||||
m.mvp.setAsUniform(uExtMatrix);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
||||
@ -278,7 +274,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||
int d = GLRenderer.depthOffset(t) * 10;
|
||||
setMatrix(pos, m, t, div, d);
|
||||
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, m.mvp, 0);
|
||||
m.mvp.setAsUniform(uExtMatrix);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
||||
@ -307,8 +303,9 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
// drawing gl_lines with the same coordinates does not result in
|
||||
// same depth values as polygons, so add offset and draw gl_lequal:
|
||||
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
|
||||
GlUtils.addOffsetM(m.mvp, 100);
|
||||
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, m.mvp, 0);
|
||||
|
||||
m.mvp.addDepthOffset(100);
|
||||
m.mvp.setAsUniform(uExtMatrix);
|
||||
|
||||
GLES20.glUniform1i(uExtMode, 3);
|
||||
GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3],
|
||||
@ -331,13 +328,15 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
float y = (float) (tile.pixelY - mapPosition.y * div);
|
||||
float scale = mapPosition.scale / div;
|
||||
|
||||
GlUtils.setTileMatrix(m.mvp, x, y, scale);
|
||||
m.mvp.setTransScale(x * scale, y * scale,
|
||||
scale / GLRenderer.COORD_SCALE);
|
||||
|
||||
// scale height
|
||||
m.mvp[10] = scale / (1000f * GLRenderer.COORD_SCALE);
|
||||
m.mvp.setValue(10, scale / (1000f * GLRenderer.COORD_SCALE));
|
||||
|
||||
Matrix.multiplyMM(m.mvp, 0, m.viewproj, 0, m.mvp, 0);
|
||||
m.mvp.multiplyMM(m.viewproj, m.mvp);
|
||||
|
||||
GlUtils.addOffsetM(m.mvp, delta);
|
||||
m.mvp.addDepthOffset(delta);
|
||||
}
|
||||
|
||||
private final float _a = 0.86f;
|
||||
|
@ -16,6 +16,7 @@ package org.oscim.renderer.overlays;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.Layer;
|
||||
import org.oscim.renderer.layer.LineLayer;
|
||||
import org.oscim.renderer.layer.TextItem;
|
||||
@ -105,7 +106,7 @@ public class GridOverlay extends BasicOverlay {
|
||||
|
||||
@Override
|
||||
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
||||
boolean tilesChanged) {
|
||||
boolean tilesChanged, Matrices matrices) {
|
||||
|
||||
updateMapPosition();
|
||||
|
||||
|
@ -1,255 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.overlays;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLRenderer;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.GLState;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.GlUtils;
|
||||
import org.oscim.view.MapView;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.Matrix;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @author Hannes Janetzek
|
||||
*/
|
||||
public class ModelOverlay extends RenderOverlay {
|
||||
|
||||
public ModelOverlay(MapView mapView) {
|
||||
super(mapView);
|
||||
}
|
||||
|
||||
private final float[] box = {
|
||||
// north
|
||||
-200f, -200f, 0, 0.9f,
|
||||
200f, -200f, 0, 0.9f,
|
||||
-200f, -200f, 0.15f, 0.9f,
|
||||
200f, -200f, 0.15f, 0.9f,
|
||||
|
||||
// west
|
||||
-200f, -200f, 0, 0.8f,
|
||||
-200f, 200f, 0, 0.8f,
|
||||
-200f, -200f, 0.15f, 0.8f,
|
||||
-200f, 200f, 0.15f, 0.8f,
|
||||
|
||||
// south
|
||||
200f, 200f, 0, 0.7f,
|
||||
-200f, 200f, 0, 0.7f,
|
||||
200f, 200f, 0.15f, 0.7f,
|
||||
-200f, 200f, 0.15f, 0.7f,
|
||||
|
||||
// east
|
||||
200f, -200f, 0, 1.0f,
|
||||
200f, 200f, 0, 1.0f,
|
||||
200f, -200f, 0.15f, 1.0f,
|
||||
200f, 200f, 0.15f, 1.0f,
|
||||
};
|
||||
|
||||
private final short[] indices = {
|
||||
// north
|
||||
0, 1, 2,
|
||||
2, 1, 3,
|
||||
// west
|
||||
4, 5, 6,
|
||||
6, 5, 7,
|
||||
// south
|
||||
8, 9, 10,
|
||||
10, 9, 11,
|
||||
// east
|
||||
12, 13, 14,
|
||||
14, 13, 15,
|
||||
// top
|
||||
2, 3, 10,
|
||||
10, 11, 2
|
||||
};
|
||||
|
||||
private static int polygonProgram;
|
||||
private static int hPolygonVertexPosition;
|
||||
private static int hPolygonLightPosition;
|
||||
private static int hPolygonMatrix;
|
||||
private static int hPolygonColor;
|
||||
//private static int hPolygonScale;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
final static String polygonVertexShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "attribute vec4 a_position;"
|
||||
+ "attribute float a_light;"
|
||||
+ "varying vec4 color;"
|
||||
+ "void main() {"
|
||||
+ " gl_Position = u_mvp * a_position;"
|
||||
+ " if (u_color.a == 0.0)"
|
||||
+ " color = vec4(u_color.rgb * a_light, 0.8);"
|
||||
+ " else"
|
||||
+ " color = u_color;"
|
||||
+ "}";
|
||||
|
||||
final static String polygonFragmentShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "varying vec4 color;"
|
||||
+ "void main() {"
|
||||
+ " gl_FragColor = color;"
|
||||
+ "}";
|
||||
|
||||
private int mIndicesBufferID;
|
||||
private int mVertexBufferID;
|
||||
|
||||
@Override
|
||||
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
||||
boolean tilesChanged) {
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
initialized = true;
|
||||
|
||||
// Set up the program for rendering polygons
|
||||
polygonProgram = GlUtils.createProgram(polygonVertexShader,
|
||||
polygonFragmentShader);
|
||||
if (polygonProgram == 0) {
|
||||
Log.e("blah", "Could not create polygon program.");
|
||||
return;
|
||||
}
|
||||
hPolygonMatrix = GLES20.glGetUniformLocation(polygonProgram, "u_mvp");
|
||||
hPolygonColor = GLES20.glGetUniformLocation(polygonProgram, "u_color");
|
||||
hPolygonVertexPosition = GLES20.glGetAttribLocation(polygonProgram, "a_position");
|
||||
hPolygonLightPosition = GLES20.glGetAttribLocation(polygonProgram, "a_light");
|
||||
|
||||
int[] mVboIds = new int[2];
|
||||
GLES20.glGenBuffers(2, mVboIds, 0);
|
||||
mIndicesBufferID = mVboIds[0];
|
||||
mVertexBufferID = mVboIds[1];
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocateDirect(64 * 4)
|
||||
.order(ByteOrder.nativeOrder());
|
||||
|
||||
ShortBuffer sbuf = buf.asShortBuffer();
|
||||
sbuf.put(indices);
|
||||
sbuf.flip();
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
||||
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, 30 * 2, sbuf, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
FloatBuffer fbuf = buf.asFloatBuffer();
|
||||
fbuf.put(box);
|
||||
fbuf.flip();
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 64 * 4, fbuf, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
mMapView.getMapViewPosition().getMapPosition(mMapPosition);
|
||||
|
||||
// tell GLRenderer to call 'render'
|
||||
isReady = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void render(MapPosition pos, Matrices m) {
|
||||
|
||||
setMatrix(pos, m);
|
||||
|
||||
GLState.useProgram(polygonProgram);
|
||||
|
||||
GLState.enableVertexArrays(hPolygonVertexPosition, hPolygonLightPosition);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||
|
||||
GLES20.glVertexAttribPointer(hPolygonVertexPosition, 3, GLES20.GL_FLOAT, false, 16, 0);
|
||||
GLES20.glVertexAttribPointer(hPolygonLightPosition, 1, GLES20.GL_FLOAT, false, 16, 12);
|
||||
|
||||
GLES20.glUniformMatrix4fv(hPolygonMatrix, 1, false, m.mvp, 0);
|
||||
GLES20.glUniform4f(hPolygonColor, 0.5f, 0.5f, 0.5f, 0.7f);
|
||||
|
||||
// draw to depth buffer
|
||||
GLES20.glColorMask(false, false, false, false);
|
||||
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
|
||||
GLState.test(true, false);
|
||||
GLES20.glDepthMask(true);
|
||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 30, GLES20.GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
GLES20.glColorMask(true, true, true, true);
|
||||
GLES20.glDepthMask(false);
|
||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||
|
||||
// draw sides
|
||||
GLES20.glUniform4f(hPolygonColor, 0.7f, 0.7f, 0.7f, 0.0f);
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 24, GLES20.GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
// draw roof
|
||||
GLES20.glUniform4f(hPolygonColor, 0.7f, 0.5f, 0.5f, 0.7f);
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, 24 * 2);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
GlUtils.checkGlError("...");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setMatrix(MapPosition curPos, Matrices m) {
|
||||
// TODO if oPos == curPos this could be simplified
|
||||
|
||||
MapPosition oPos = mMapPosition;
|
||||
|
||||
byte z = oPos.zoomLevel;
|
||||
|
||||
float div = FastMath.pow(z - curPos.zoomLevel);
|
||||
float x = (float) (oPos.x - curPos.x * div);
|
||||
float y = (float) (oPos.y - curPos.y * div);
|
||||
|
||||
// flip around date-line
|
||||
float max = (Tile.TILE_SIZE << z);
|
||||
if (x < -max / 2)
|
||||
x = max + x;
|
||||
else if (x > max / 2)
|
||||
x = x - max;
|
||||
|
||||
float scale = curPos.scale / div;
|
||||
|
||||
Matrix.setIdentityM(m.mvp, 0);
|
||||
|
||||
// translate relative to map center
|
||||
m.mvp[12] = x * scale;
|
||||
m.mvp[13] = y * scale;
|
||||
// scale to current tile world coordinates
|
||||
scale = (curPos.scale / oPos.scale) / div;
|
||||
scale /= GLRenderer.COORD_SCALE;
|
||||
m.mvp[0] = scale;
|
||||
m.mvp[5] = scale;
|
||||
m.mvp[10] = scale; // 1000f;
|
||||
|
||||
Matrix.multiplyMM(m.mvp, 0, m.viewproj, 0, m.mvp, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compile() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -19,11 +19,8 @@ import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLRenderer;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.GlUtils;
|
||||
import org.oscim.view.MapView;
|
||||
|
||||
import android.opengl.Matrix;
|
||||
|
||||
public abstract class RenderOverlay {
|
||||
|
||||
protected final MapView mMapView;
|
||||
@ -52,8 +49,9 @@ public abstract class RenderOverlay {
|
||||
* true when MapPosition has changed
|
||||
* @param tilesChanged
|
||||
* true when current tiles changed
|
||||
* @param matrices TODO
|
||||
*/
|
||||
public abstract void update(MapPosition curPos, boolean positionChanged, boolean tilesChanged);
|
||||
public abstract void update(MapPosition curPos, boolean positionChanged, boolean tilesChanged, Matrices matrices);
|
||||
|
||||
/**
|
||||
* called 2. compile everything for drawing
|
||||
@ -102,13 +100,10 @@ public abstract class RenderOverlay {
|
||||
// set scale to be relative to current scale
|
||||
float s = (curPos.scale / oPos.scale) / div;
|
||||
|
||||
GlUtils.setMatrix(m.mvp, x * scale, y * scale,
|
||||
m.mvp.setTransScale(x * scale, y * scale,
|
||||
s / GLRenderer.COORD_SCALE);
|
||||
|
||||
if (project)
|
||||
Matrix.multiplyMM(m.mvp, 0, m.viewproj, 0, m.mvp, 0);
|
||||
else
|
||||
Matrix.multiplyMM(m.mvp, 0, m.view, 0, m.mvp, 0);
|
||||
m.mvp.multiplyMM(project ? m.viewproj : m.view, m.mvp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,440 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.overlays;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLRenderer;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.GLState;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.GlUtils;
|
||||
import org.oscim.view.MapView;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.Matrix;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @author Hannes Janetzek
|
||||
*/
|
||||
public class TestLineOverlay extends RenderOverlay {
|
||||
|
||||
public TestLineOverlay(MapView mapView) {
|
||||
super(mapView);
|
||||
}
|
||||
|
||||
// Interleave two segment quads in one block to be able to use
|
||||
// vertices twice. pos0 and pos1 use the same vertex array where
|
||||
// pos1 is off-setted by one vertex. The vertex shader will use
|
||||
// pos0 when the vertexId is even, pos1 when the Id is odd.
|
||||
//
|
||||
// As there is no gl_VertexId in gles 2.0 an additional 'flip'
|
||||
// array is used. Depending on 'flip' extrusion is inverted.
|
||||
//
|
||||
// Indices and flip buffers can be static.
|
||||
//
|
||||
// First pass: using even vertex array positions
|
||||
// (used vertices are in braces)
|
||||
// vertex id 0 1 2 3 4 5 6 7
|
||||
// pos0 - (0) 1 (2) 3 (4) 5 (6) 7 -
|
||||
// pos1 - (0) 1 (2) 3 (4) 5 (6) 7 -
|
||||
// flip 0 1 0 1 0 1 0 1
|
||||
//
|
||||
// Second pass: using odd vertex array positions
|
||||
// vertex id 0 1 2 3 4 5 6 7
|
||||
// pos0 - 0 (1) 2 (3) 4 (5) 6 (7) -
|
||||
// pos1 - 0 (1) 2 (3) 4 (5) 6 (7) -
|
||||
// flip 0 1 0 1 0 1 0 1
|
||||
//
|
||||
// Vertex layout:
|
||||
// [2 short] position,
|
||||
// [2 short] extrusion,
|
||||
// [1 short] line length
|
||||
// [1 short] unused
|
||||
//
|
||||
// indices: (two indice blocks)
|
||||
// 0, 1, 2,
|
||||
// 2, 1, 3,
|
||||
// 4, 5, 6,
|
||||
// 6, 5, 7,
|
||||
|
||||
private static int testProgram;
|
||||
private static int htestVertexPosition0;
|
||||
private static int htestVertexPosition1;
|
||||
private static int htestVertexLength0;
|
||||
private static int htestVertexLength1;
|
||||
private static int htestVertexFlip;
|
||||
private static int htestMatrix;
|
||||
private static int htestTexColor;
|
||||
private static int htestBgColor;
|
||||
private static int htestScale;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
final static String testVertexShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "uniform float u_scale;"
|
||||
+ "attribute vec4 a_pos0;"
|
||||
+ "attribute vec4 a_pos1;"
|
||||
+ "attribute vec2 a_len0;"
|
||||
+ "attribute vec2 a_len1;"
|
||||
+ "attribute float a_flip;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
+ " float div = (8.0 * 16.0) / max(ceil(log(u_scale)),1.0);"
|
||||
+ " if (a_flip == 0.0){"
|
||||
+ " vec2 dir = a_pos0.zw/16.0;"
|
||||
+ " gl_Position = u_mvp * vec4(a_pos0.xy + dir / u_scale, 0.0, 1.0);"
|
||||
+ " v_st = vec2(a_len0.x/div, 1.0);"
|
||||
+ " }else {"
|
||||
+ " vec2 dir = a_pos1.zw/16.0;"
|
||||
+ " gl_Position = u_mvp * vec4(a_pos1.xy - dir / u_scale, 0.0, 1.0);"
|
||||
+ " v_st = vec2(a_len1.x/div, -1.0);"
|
||||
+ " }"
|
||||
+ "}";
|
||||
|
||||
final static String testFragmentShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform sampler2D tex;"
|
||||
+ " uniform vec4 u_color;"
|
||||
+ " uniform vec4 u_bgcolor;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
+ " float len = texture2D(tex, v_st).a;"
|
||||
+ " float tex_w = abs(v_st.t);"
|
||||
+ " float line_w = (1.0 - smoothstep(0.7, 1.0, tex_w));"
|
||||
+ " float stipple_w = (1.0 - smoothstep(0.1, 0.6, tex_w));"
|
||||
+ " float stipple_p = smoothstep(0.495, 0.505, len);"
|
||||
+ " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
|
||||
|
||||
//+ " gl_FragColor = u_color * min(abs(1.0 - mod(v_len, 20.0)/10.0), (1.0 - abs(v_st.x)));"
|
||||
+ "}";
|
||||
|
||||
private int mIndicesBufferID;
|
||||
private int mVertexBufferID;
|
||||
private int mVertexFlipID;
|
||||
|
||||
//private int mNumVertices;
|
||||
private int mNumIndices;
|
||||
|
||||
private int mTexID;
|
||||
|
||||
@Override
|
||||
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
||||
boolean tilesChanged) {
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
initialized = true;
|
||||
|
||||
// Set up the program for rendering tests
|
||||
testProgram = GlUtils.createProgram(testVertexShader,
|
||||
testFragmentShader);
|
||||
if (testProgram == 0) {
|
||||
Log.e("...", "Could not create test program.");
|
||||
return;
|
||||
}
|
||||
htestMatrix = GLES20.glGetUniformLocation(testProgram, "u_mvp");
|
||||
htestTexColor = GLES20.glGetUniformLocation(testProgram, "u_color");
|
||||
htestBgColor = GLES20.glGetUniformLocation(testProgram, "u_bgcolor");
|
||||
htestScale = GLES20.glGetUniformLocation(testProgram, "u_scale");
|
||||
|
||||
htestVertexPosition0 = GLES20.glGetAttribLocation(testProgram, "a_pos0");
|
||||
htestVertexPosition1 = GLES20.glGetAttribLocation(testProgram, "a_pos1");
|
||||
htestVertexLength0 = GLES20.glGetAttribLocation(testProgram, "a_len0");
|
||||
htestVertexLength1 = GLES20.glGetAttribLocation(testProgram, "a_len1");
|
||||
htestVertexFlip = GLES20.glGetAttribLocation(testProgram, "a_flip");
|
||||
|
||||
int[] mVboIds = new int[3];
|
||||
GLES20.glGenBuffers(3, mVboIds, 0);
|
||||
mIndicesBufferID = mVboIds[0];
|
||||
mVertexBufferID = mVboIds[1];
|
||||
mVertexFlipID = mVboIds[2];
|
||||
|
||||
float points[] = {
|
||||
-800, -800,
|
||||
800, -800,
|
||||
800, 800,
|
||||
-800, 800,
|
||||
-800, -800,
|
||||
};
|
||||
|
||||
// float[] points = new float[12 * 2];
|
||||
// for (int i = 0; i < 24; i += 2) {
|
||||
// points[i + 0] = (float) Math.sin(-i / 11f * Math.PI) * 8*400;
|
||||
// points[i + 1] = (float) Math.cos(-i / 11f * Math.PI) * 8*400;
|
||||
// }
|
||||
|
||||
boolean oddSegments = points.length % 4 == 0;
|
||||
|
||||
int numVertices = points.length + (oddSegments ? 2 : 0);
|
||||
|
||||
short[] vertices = new short[numVertices * 6];
|
||||
|
||||
int opos = 6;
|
||||
|
||||
float x = points[0];
|
||||
float y = points[1];
|
||||
|
||||
float scale = 255;
|
||||
boolean even = true;
|
||||
float len = 0;
|
||||
|
||||
for (int i = 2; i < points.length; i += 2) {
|
||||
float nx = points[i + 0];
|
||||
float ny = points[i + 1];
|
||||
|
||||
// Calculate triangle corners for the given width
|
||||
float vx = nx - x;
|
||||
float vy = ny - y;
|
||||
|
||||
float a = (float) Math.sqrt(vx * vx + vy * vy);
|
||||
|
||||
// normal vector
|
||||
vx /= a;
|
||||
vy /= a;
|
||||
|
||||
// perpendicular to line segment
|
||||
float ux = -vy;
|
||||
float uy = vx;
|
||||
|
||||
short dx = (short) (ux * scale);
|
||||
short dy = (short) (uy * scale);
|
||||
|
||||
vertices[opos + 0] = (short) x;
|
||||
vertices[opos + 1] = (short) y;
|
||||
vertices[opos + 2] = dx;
|
||||
vertices[opos + 3] = dy;
|
||||
vertices[opos + 4] = (short) len;
|
||||
vertices[opos + 5] = 0;
|
||||
|
||||
len += a;
|
||||
vertices[opos + 12] = (short) nx;
|
||||
vertices[opos + 13] = (short) ny;
|
||||
vertices[opos + 14] = dx;
|
||||
vertices[opos + 15] = dy;
|
||||
vertices[opos + 16] = (short) len;
|
||||
vertices[opos + 17] = 0;
|
||||
|
||||
x = nx;
|
||||
y = ny;
|
||||
|
||||
if (even) {
|
||||
// go to second segment
|
||||
opos += 6;
|
||||
even = false;
|
||||
} else {
|
||||
// go to next block
|
||||
even = true;
|
||||
opos += 18;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 0, 1, 0, 1
|
||||
byte[] flip = new byte[points.length];
|
||||
for (int i = 0; i < flip.length; i++)
|
||||
flip[i] = (byte) (i % 2);
|
||||
|
||||
short j = 0;
|
||||
mNumIndices = ((points.length) >> 2) * 6;
|
||||
|
||||
short[] indices = new short[mNumIndices];
|
||||
for (int i = 0; i < mNumIndices; i += 6, j += 4) {
|
||||
indices[i + 0] = (short) (j + 0);
|
||||
indices[i + 1] = (short) (j + 1);
|
||||
indices[i + 2] = (short) (j + 2);
|
||||
|
||||
indices[i + 3] = (short) (j + 2);
|
||||
indices[i + 4] = (short) (j + 1);
|
||||
indices[i + 5] = (short) (j + 3);
|
||||
}
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocateDirect(numVertices * 6 * 2)
|
||||
.order(ByteOrder.nativeOrder());
|
||||
|
||||
ShortBuffer sbuf = buf.asShortBuffer();
|
||||
sbuf.put(indices);
|
||||
sbuf.flip();
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
||||
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, indices.length * 2, sbuf,
|
||||
GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
sbuf.clear();
|
||||
sbuf.put(vertices);
|
||||
sbuf.flip();
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertices.length * 2, sbuf,
|
||||
GLES20.GL_STATIC_DRAW);
|
||||
|
||||
buf.clear();
|
||||
buf.put(flip);
|
||||
buf.flip();
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexFlipID);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, flip.length, buf,
|
||||
GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
byte[] stipple = new byte[2];
|
||||
stipple[0] = 8;
|
||||
stipple[1] = 8;
|
||||
//stipple[2] = 16;
|
||||
//stipple[3] = 48;
|
||||
|
||||
mTexID = GlUtils.loadStippleTexture(stipple);
|
||||
|
||||
mMapView.getMapViewPosition().getMapPosition(mMapPosition);
|
||||
|
||||
// tell GLRenderer to call 'render'
|
||||
isReady = true;
|
||||
}
|
||||
|
||||
private final static int STRIDE = 12;
|
||||
private final static int LEN_OFFSET = 8;
|
||||
|
||||
@Override
|
||||
public synchronized void render(MapPosition pos, Matrices m) {
|
||||
|
||||
setMatrix(pos, m);
|
||||
//Matrix.multiplyMM(mv, 0, proj, 0, mv, 0);
|
||||
|
||||
GLState.useProgram(testProgram);
|
||||
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
||||
GLState.test(false, false);
|
||||
GLState.enableVertexArrays(-1, -1);
|
||||
GLES20.glEnableVertexAttribArray(htestVertexPosition0);
|
||||
GLES20.glEnableVertexAttribArray(htestVertexPosition1);
|
||||
GlUtils.checkGlError("-4");
|
||||
GLES20.glEnableVertexAttribArray(htestVertexLength0);
|
||||
GlUtils.checkGlError("-3");
|
||||
GLES20.glEnableVertexAttribArray(htestVertexLength1);
|
||||
GlUtils.checkGlError("-2");
|
||||
GLES20.glEnableVertexAttribArray(htestVertexFlip);
|
||||
|
||||
GLES20.glUniformMatrix4fv(htestMatrix, 1, false, m.mvp, 0);
|
||||
float div = FastMath.pow(pos.zoomLevel - mMapPosition.zoomLevel);
|
||||
GLES20.glUniform1f(htestScale, pos.scale / mMapPosition.scale * div);
|
||||
|
||||
GLES20.glUniform4f(htestTexColor, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
GLES20.glUniform4f(htestBgColor, 0.3f, 0.3f, 0.3f, 1.0f);
|
||||
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexID);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER,
|
||||
mIndicesBufferID);
|
||||
GlUtils.checkGlError("-1");
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexFlipID);
|
||||
GLES20.glVertexAttribPointer(htestVertexFlip, 1,
|
||||
GLES20.GL_BYTE, false, 0, 0);
|
||||
GlUtils.checkGlError("0");
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||
GlUtils.checkGlError("1");
|
||||
|
||||
// first pass
|
||||
GLES20.glVertexAttribPointer(htestVertexPosition0,
|
||||
4, GLES20.GL_SHORT, false, STRIDE, STRIDE);
|
||||
GlUtils.checkGlError("2");
|
||||
|
||||
GLES20.glVertexAttribPointer(htestVertexLength0,
|
||||
2, GLES20.GL_SHORT, false, STRIDE, STRIDE + LEN_OFFSET);
|
||||
GlUtils.checkGlError("3");
|
||||
|
||||
GLES20.glVertexAttribPointer(htestVertexPosition1,
|
||||
4, GLES20.GL_SHORT, false, STRIDE, 0);
|
||||
GlUtils.checkGlError("4");
|
||||
|
||||
GLES20.glVertexAttribPointer(htestVertexLength1,
|
||||
2, GLES20.GL_SHORT, false, STRIDE, LEN_OFFSET);
|
||||
GlUtils.checkGlError("5");
|
||||
|
||||
//GLES20.glUniform4f(htestColor, 0.5f, 0.5f, 1.0f, 1.0f);
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mNumIndices,
|
||||
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
// second pass
|
||||
GLES20.glVertexAttribPointer(htestVertexPosition0,
|
||||
4, GLES20.GL_SHORT, false, STRIDE, 2 * STRIDE);
|
||||
|
||||
GLES20.glVertexAttribPointer(htestVertexLength0,
|
||||
2, GLES20.GL_SHORT, false, STRIDE, 2 * STRIDE + LEN_OFFSET);
|
||||
|
||||
GLES20.glVertexAttribPointer(htestVertexPosition1,
|
||||
4, GLES20.GL_SHORT, false, STRIDE, STRIDE);
|
||||
|
||||
GLES20.glVertexAttribPointer(htestVertexLength1,
|
||||
2, GLES20.GL_SHORT, false, STRIDE, STRIDE + LEN_OFFSET);
|
||||
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mNumIndices,
|
||||
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
GLES20.glDisableVertexAttribArray(htestVertexPosition0);
|
||||
GLES20.glDisableVertexAttribArray(htestVertexPosition1);
|
||||
GLES20.glDisableVertexAttribArray(htestVertexLength0);
|
||||
GLES20.glDisableVertexAttribArray(htestVertexLength1);
|
||||
GLES20.glDisableVertexAttribArray(htestVertexFlip);
|
||||
GlUtils.checkGlError("...");
|
||||
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setMatrix(MapPosition curPos, Matrices m) {
|
||||
MapPosition oPos = mMapPosition;
|
||||
|
||||
byte z = oPos.zoomLevel;
|
||||
|
||||
float div = FastMath.pow(z - curPos.zoomLevel);
|
||||
float x = (float) (oPos.x - curPos.x * div);
|
||||
float y = (float) (oPos.y - curPos.y * div);
|
||||
|
||||
// flip around date-line
|
||||
float max = (Tile.TILE_SIZE << z);
|
||||
if (x < -max / 2)
|
||||
x = max + x;
|
||||
else if (x > max / 2)
|
||||
x = x - max;
|
||||
|
||||
float scale = curPos.scale / div;
|
||||
|
||||
Matrix.setIdentityM(m.mvp, 0);
|
||||
|
||||
// translate relative to map center
|
||||
m.mvp[12] = x * scale;
|
||||
m.mvp[13] = y * scale;
|
||||
// scale to current tile world coordinates
|
||||
scale = (curPos.scale / oPos.scale) / div;
|
||||
scale /= GLRenderer.COORD_SCALE;
|
||||
m.mvp[0] = scale;
|
||||
m.mvp[5] = scale;
|
||||
m.mvp[10] = 1; //scale; // 1000f;
|
||||
|
||||
Matrix.multiplyMM(m.mvp, 0, m.viewproj, 0, m.mvp, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compile() {
|
||||
}
|
||||
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
package org.oscim.renderer.overlays;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.Layer;
|
||||
import org.oscim.renderer.layer.LineTexLayer;
|
||||
import org.oscim.renderer.layer.TextItem;
|
||||
@ -122,7 +123,7 @@ public class TestOverlay extends BasicOverlay {
|
||||
|
||||
@Override
|
||||
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
||||
boolean tilesChanged) {
|
||||
boolean tilesChanged, Matrices matrices) {
|
||||
// keep position constant (or update layer relative to new position)
|
||||
//mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);
|
||||
|
||||
|
@ -44,7 +44,6 @@ import org.oscim.renderer.layer.TextItem;
|
||||
import org.oscim.renderer.layer.TextLayer;
|
||||
import org.oscim.theme.renderinstruction.Line;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.GlUtils;
|
||||
import org.oscim.utils.OBB2D;
|
||||
import org.oscim.utils.PausableThread;
|
||||
import org.oscim.view.MapView;
|
||||
@ -53,7 +52,6 @@ import org.oscim.view.MapViewPosition;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint.Cap;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.Matrix;
|
||||
import android.os.SystemClock;
|
||||
|
||||
public class TextOverlay extends BasicOverlay {
|
||||
@ -247,7 +245,7 @@ public class TextOverlay extends BasicOverlay {
|
||||
|
||||
private Layers mDebugLayer;
|
||||
private final static float[] mDebugPoints = new float[4];
|
||||
private final float[] mMVP = new float[16];
|
||||
//private final Matrix4 mMVP = new Matrix4();
|
||||
|
||||
void addTile(MapTile t) {
|
||||
|
||||
@ -305,7 +303,7 @@ public class TextOverlay extends BasicOverlay {
|
||||
synchronized (mMapViewPosition) {
|
||||
mMapViewPosition.getMapPosition(pos);
|
||||
mMapViewPosition.getMapViewProjection(coords);
|
||||
mMapViewPosition.getMatrix(null, null, mMVP);
|
||||
//mMapViewPosition.getMatrix(null, null, mMVP);
|
||||
}
|
||||
int mw = (mMapView.getWidth() + Tile.TILE_SIZE) / 2;
|
||||
int mh = (mMapView.getHeight() + Tile.TILE_SIZE) / 2;
|
||||
@ -617,7 +615,7 @@ public class TextOverlay extends BasicOverlay {
|
||||
|
||||
@Override
|
||||
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
||||
boolean tilesChanged) {
|
||||
boolean tilesChanged, Matrices matrices) {
|
||||
|
||||
if (mNextLayer != null) {
|
||||
// keep text layer, not recrating its canvas each time
|
||||
@ -687,10 +685,10 @@ public class TextOverlay extends BasicOverlay {
|
||||
|
||||
for (Layer l = layers.baseLayers; l != null;) {
|
||||
if (l.type == Layer.POLYGON) {
|
||||
l = PolygonRenderer.draw(pos, l, m.mvp, true, false);
|
||||
l = PolygonRenderer.draw(pos, l, m, true, false);
|
||||
} else {
|
||||
float scale = pos.scale * div;
|
||||
l = LineRenderer.draw(layers, l, pos, m.mvp, scale, 0);
|
||||
l = LineRenderer.draw(layers, l, pos, m, scale, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -699,7 +697,7 @@ public class TextOverlay extends BasicOverlay {
|
||||
for (Layer l = layers.textureLayers; l != null;) {
|
||||
float scale = (mMapPosition.scale / pos.scale) * div;
|
||||
|
||||
l = TextureRenderer.draw(l, scale, m.proj, m.mvp);
|
||||
l = TextureRenderer.draw(l, scale, m);
|
||||
}
|
||||
|
||||
}
|
||||
@ -714,10 +712,10 @@ public class TextOverlay extends BasicOverlay {
|
||||
|
||||
float scale = (curPos.scale / mMapPosition.scale) / div;
|
||||
float s = curPos.scale / div;
|
||||
GlUtils.setMatrix(m.mvp, x * s, y * s,
|
||||
m.mvp.setTransScale(x * s, y * s,
|
||||
scale / GLRenderer.COORD_SCALE);
|
||||
|
||||
Matrix.multiplyMM(m.mvp, 0, m.view, 0, m.mvp, 0);
|
||||
m.mvp.multiplyMM(m.view, m.mvp);
|
||||
}
|
||||
|
||||
private boolean mHolding;
|
||||
|
@ -17,8 +17,6 @@ package org.oscim.utils;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import org.oscim.renderer.GLRenderer;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLUtils;
|
||||
@ -204,37 +202,33 @@ public class GlUtils {
|
||||
return oom;
|
||||
}
|
||||
|
||||
// this is save as it can only be called from glThread
|
||||
private static float[] tmpColor = new float[4];
|
||||
|
||||
public static void setBlendColors(int handle, float[] c1, float[] c2, float mix) {
|
||||
if (mix <= 0f)
|
||||
GLES20.glUniform4fv(handle, 1, c1, 0);
|
||||
else if (mix >= 1f)
|
||||
GLES20.glUniform4fv(handle, 1, c2, 0);
|
||||
else {
|
||||
tmpColor[0] = c1[0] * (1 - mix) + c2[0] * mix;
|
||||
tmpColor[1] = c1[1] * (1 - mix) + c2[1] * mix;
|
||||
tmpColor[2] = c1[2] * (1 - mix) + c2[2] * mix;
|
||||
tmpColor[3] = c1[3] * (1 - mix) + c2[3] * mix;
|
||||
GLES20.glUniform4fv(handle, 1, tmpColor, 0);
|
||||
GLES20.glUniform4f(handle,
|
||||
c1[0] * (1 - mix) + c2[0] * mix,
|
||||
c1[1] * (1 - mix) + c2[1] * mix,
|
||||
c1[2] * (1 - mix) + c2[2] * mix,
|
||||
c1[3] * (1 - mix) + c2[3] * mix);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setColor(int handle, float[] c, float alpha) {
|
||||
if (alpha >= 1) {
|
||||
GLES20.glUniform4fv(handle, 1, c, 0);
|
||||
GLES20.glUniform4f(handle, c[0], c[1], c[2], c[3]);
|
||||
} else {
|
||||
if (alpha < 0) {
|
||||
Log.d(TAG, "setColor: " + alpha);
|
||||
alpha = 0;
|
||||
GLES20.glUniform4f(handle, 0, 0, 0, 0);
|
||||
}
|
||||
tmpColor[0] = c[0] * alpha;
|
||||
tmpColor[1] = c[1] * alpha;
|
||||
tmpColor[2] = c[2] * alpha;
|
||||
tmpColor[3] = c[3] * alpha;
|
||||
|
||||
GLES20.glUniform4fv(handle, 1, tmpColor, 0);
|
||||
GLES20.glUniform4f(handle,
|
||||
c[0] * alpha, c[1] * alpha,
|
||||
c[2] * alpha, c[3] * alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,56 +274,56 @@ public class GlUtils {
|
||||
color[2] = FastMath.clampN((float) (p + (b - p) * change));
|
||||
}
|
||||
|
||||
private final static float[] mIdentity = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1 };
|
||||
|
||||
public static void setTileMatrix(float[] matrix, float tx, float ty, float s) {
|
||||
System.arraycopy(mIdentity, 0, matrix, 0, 16);
|
||||
// scale tile relative to map scale
|
||||
matrix[0] = matrix[5] = s / GLRenderer.COORD_SCALE;
|
||||
// translate relative to map center
|
||||
matrix[12] = tx * s;
|
||||
matrix[13] = ty * s;
|
||||
}
|
||||
|
||||
public static void setTranslation(float[] matrix, float x, float y, float z) {
|
||||
System.arraycopy(mIdentity, 0, matrix, 0, 16);
|
||||
matrix[12] = x;
|
||||
matrix[13] = y;
|
||||
matrix[14] = z;
|
||||
}
|
||||
|
||||
public static void setMatrix(float[] matrix, float tx, float ty, float scale) {
|
||||
System.arraycopy(mIdentity, 0, matrix, 0, 16);
|
||||
matrix[12] = tx;
|
||||
matrix[13] = ty;
|
||||
matrix[0] = scale;
|
||||
matrix[5] = scale;
|
||||
//matrix[10] = scale;
|
||||
}
|
||||
|
||||
public static void setIdentity(float[] matrix) {
|
||||
System.arraycopy(mIdentity, 0, matrix, 0, 16);
|
||||
}
|
||||
|
||||
public static void setScaleM(float[] matrix, float sx, float sy, float sz) {
|
||||
System.arraycopy(mIdentity, 0, matrix, 0, 16);
|
||||
matrix[0] = sx;
|
||||
matrix[5] = sy;
|
||||
matrix[10] = sz;
|
||||
}
|
||||
|
||||
public static void addOffsetM(float[] matrix, int delta) {
|
||||
// from http://www.mathfor3dgameprogramming.com/code/Listing9.1.cpp
|
||||
// float n = MapViewPosition.VIEW_NEAR;
|
||||
// float f = MapViewPosition.VIEW_FAR;
|
||||
// float pz = 1;
|
||||
// float epsilon = -2.0f * f * n * delta / ((f + n) * pz * (pz + delta));
|
||||
float epsilon = 1.0f / (1 << 11);
|
||||
|
||||
matrix[10] *= 1.0f + epsilon * delta;
|
||||
}
|
||||
// private final static float[] mIdentity = {
|
||||
// 1, 0, 0, 0,
|
||||
// 0, 1, 0, 0,
|
||||
// 0, 0, 1, 0,
|
||||
// 0, 0, 0, 1 };
|
||||
//
|
||||
// public static void setTileMatrix(float[] matrix, float tx, float ty, float s) {
|
||||
// System.arraycopy(mIdentity, 0, matrix, 0, 16);
|
||||
// // scale tile relative to map scale
|
||||
// matrix[0] = matrix[5] = s / GLRenderer.COORD_SCALE;
|
||||
// // translate relative to map center
|
||||
// matrix[12] = tx * s;
|
||||
// matrix[13] = ty * s;
|
||||
// }
|
||||
//
|
||||
// public static void setTranslation(float[] matrix, float x, float y, float z) {
|
||||
// System.arraycopy(mIdentity, 0, matrix, 0, 16);
|
||||
// matrix[12] = x;
|
||||
// matrix[13] = y;
|
||||
// matrix[14] = z;
|
||||
// }
|
||||
//
|
||||
// public static void setMatrix(float[] matrix, float tx, float ty, float scale) {
|
||||
// System.arraycopy(mIdentity, 0, matrix, 0, 16);
|
||||
// matrix[12] = tx;
|
||||
// matrix[13] = ty;
|
||||
// matrix[0] = scale;
|
||||
// matrix[5] = scale;
|
||||
// //matrix[10] = scale;
|
||||
// }
|
||||
//
|
||||
// public static void setIdentity(float[] matrix) {
|
||||
// System.arraycopy(mIdentity, 0, matrix, 0, 16);
|
||||
// }
|
||||
//
|
||||
// public static void setScaleM(float[] matrix, float sx, float sy, float sz) {
|
||||
// System.arraycopy(mIdentity, 0, matrix, 0, 16);
|
||||
// matrix[0] = sx;
|
||||
// matrix[5] = sy;
|
||||
// matrix[10] = sz;
|
||||
// }
|
||||
//
|
||||
// public static void addOffsetM(float[] matrix, int delta) {
|
||||
// // from http://www.mathfor3dgameprogramming.com/code/Listing9.1.cpp
|
||||
// // float n = MapViewPosition.VIEW_NEAR;
|
||||
// // float f = MapViewPosition.VIEW_FAR;
|
||||
// // float pz = 1;
|
||||
// // float epsilon = -2.0f * f * n * delta / ((f + n) * pz * (pz + delta));
|
||||
// float epsilon = 1.0f / (1 << 11);
|
||||
//
|
||||
// matrix[10] *= 1.0f + epsilon * delta;
|
||||
// }
|
||||
}
|
||||
|
226
src/org/oscim/utils/Matrix4.java
Normal file
226
src/org/oscim/utils/Matrix4.java
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.utils;
|
||||
|
||||
public class Matrix4 {
|
||||
|
||||
static {
|
||||
System.loadLibrary("glutils");
|
||||
}
|
||||
|
||||
private final static String TAG = Matrix4.class.getName();
|
||||
private final static boolean dbg = false;
|
||||
|
||||
private native static long alloc();
|
||||
|
||||
private native static void delete(long self);
|
||||
|
||||
private native static void set(long self, float[] m);
|
||||
|
||||
private native static void copy(long self, long other);
|
||||
|
||||
private native static void identity(long self);
|
||||
|
||||
private native static void get(long self, float[] m);
|
||||
|
||||
private native static void mul(long self, long lhs_ptr);
|
||||
|
||||
private native static void smul(long self, long rhs_ptr, long lhs_ptr);
|
||||
|
||||
private native static void strans(long self, long rhs_ptr);
|
||||
|
||||
private native static void prj(long self, float[] vec3);
|
||||
|
||||
private native static void setRotation(long self, float a, float x, float y, float z);
|
||||
|
||||
private native static void setScale(long self, float x, float y, float z);
|
||||
|
||||
private native static void setTranslation(long self, float x, float y, float z);
|
||||
|
||||
private native static void setTransScale(long self, float tx, float ty, float scale);
|
||||
|
||||
private native static void setAsUniform(long self, int handle);
|
||||
|
||||
private native void setValueAt(long self, int pos, float value);
|
||||
|
||||
private native void addDepthOffset(long self, int delta);
|
||||
|
||||
private final long pointer;
|
||||
|
||||
private final static String INVALID_INPUT = "Bad Array!";
|
||||
|
||||
public Matrix4() {
|
||||
pointer = alloc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Matrix from float array
|
||||
*
|
||||
* @param m float array to copy
|
||||
*/
|
||||
public void set(float[] m) {
|
||||
if (m == null || m.length != 16)
|
||||
throw new IllegalArgumentException(INVALID_INPUT);
|
||||
|
||||
set(pointer, m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Matrix as float array
|
||||
*
|
||||
* @param m float array to store Matrix
|
||||
*/
|
||||
public void get(float[] m) {
|
||||
if (m == null || m.length != 16)
|
||||
throw new IllegalArgumentException(INVALID_INPUT);
|
||||
|
||||
get(pointer, m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy values from mat
|
||||
*
|
||||
* @param mat Matrix to copy
|
||||
*/
|
||||
public void copy(Matrix4 mat) {
|
||||
copy(pointer, mat.pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Project Vector with Matrix
|
||||
*
|
||||
* @param vec3 Vector to project
|
||||
*/
|
||||
public void prj(float[] vec3) {
|
||||
if (vec3 == null || vec3.length < 3)
|
||||
throw new IllegalArgumentException(INVALID_INPUT);
|
||||
|
||||
prj(pointer, vec3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply rhs onto Matrix
|
||||
*
|
||||
* @param rhs right hand side
|
||||
*/
|
||||
public void multiplyMM(Matrix4 rhs) {
|
||||
smul(pointer, pointer, rhs.pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply rhs onto lhs and store result in Matrix
|
||||
*
|
||||
* @param lhs left hand side
|
||||
* @param rhs right hand side
|
||||
*/
|
||||
public void multiplyMM(Matrix4 lhs, Matrix4 rhs) {
|
||||
smul(pointer, lhs.pointer, rhs.pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transpose mat and store result in Matrix
|
||||
*
|
||||
* @param mat to transpose
|
||||
*/
|
||||
public void transposeM(Matrix4 mat) {
|
||||
strans(pointer, mat.pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rotation
|
||||
*
|
||||
* @param a angle in degree
|
||||
* @param x around x-axis
|
||||
* @param y around y-axis
|
||||
* @param z around z-axis
|
||||
*/
|
||||
public void setRotation(float a, float x, float y, float z) {
|
||||
setRotation(pointer, a, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set translation
|
||||
*
|
||||
* @param x along x-axis
|
||||
* @param y along y-axis
|
||||
* @param z along z-axis
|
||||
*/
|
||||
public void setTranslation(float x, float y, float z) {
|
||||
setTranslation(pointer, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set scale factor
|
||||
*
|
||||
* @param x axis
|
||||
* @param y axis
|
||||
* @param z axis
|
||||
*/
|
||||
public void setScale(float x, float y, float z) {
|
||||
setScale(pointer, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set translation and x,y scale
|
||||
*
|
||||
* @param tx translate x
|
||||
* @param ty translate y
|
||||
* @param scale factor x,y
|
||||
*/
|
||||
public void setTransScale(float tx, float ty, float scale) {
|
||||
setTransScale(pointer, tx, ty, scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Matrix with glUniformMatrix
|
||||
*
|
||||
* @param location GL location id
|
||||
*/
|
||||
public void setAsUniform(int location) {
|
||||
setAsUniform(pointer, location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set single value
|
||||
*
|
||||
* @param pos at position
|
||||
* @param value value to set
|
||||
*/
|
||||
public void setValue(int pos, float value) {
|
||||
setValueAt(pointer, pos, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* add some offset (similar to glDepthOffset)
|
||||
*
|
||||
* @param delta offset
|
||||
*/
|
||||
public void addDepthOffset(int delta) {
|
||||
addDepthOffset(pointer, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set identity matrix
|
||||
*/
|
||||
public void setIdentity() {
|
||||
identity(pointer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
if (pointer != 0)
|
||||
delete(pointer);
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ import org.oscim.core.PointD;
|
||||
import org.oscim.core.PointF;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.GlUtils;
|
||||
import org.oscim.utils.Matrix4;
|
||||
|
||||
import android.opengl.Matrix;
|
||||
import android.os.Handler;
|
||||
@ -98,13 +98,13 @@ public class MapViewPosition {
|
||||
});
|
||||
}
|
||||
|
||||
private final float[] mProjMatrix = new float[16];
|
||||
private final float[] mProjMatrixI = new float[16];
|
||||
private final float[] mUnprojMatrix = new float[16];
|
||||
private final float[] mViewMatrix = new float[16];
|
||||
private final float[] mVPMatrix = new float[16];
|
||||
private final float[] mRotMatrix = new float[16];
|
||||
private final float[] mTmpMatrix = new float[16];
|
||||
private final Matrix4 mProjMatrix = new Matrix4();
|
||||
private final Matrix4 mProjMatrixI = new Matrix4();
|
||||
private final Matrix4 mRotMatrix = new Matrix4();
|
||||
private final Matrix4 mViewMatrix = new Matrix4();
|
||||
private final Matrix4 mVPMatrix = new Matrix4();
|
||||
private final Matrix4 mUnprojMatrix = new Matrix4();
|
||||
private final Matrix4 mTmpMatrix = new Matrix4();
|
||||
|
||||
// temporary vars: only use in synchronized functions!
|
||||
private final PointD mMovePoint = new PointD();
|
||||
@ -123,14 +123,18 @@ public class MapViewPosition {
|
||||
void setViewport(int width, int height) {
|
||||
float s = VIEW_SCALE;
|
||||
float aspect = height / (float) width;
|
||||
float[] tmp = new float[16];
|
||||
|
||||
Matrix.frustumM(mProjMatrix, 0, -s, s,
|
||||
Matrix.frustumM(tmp, 0, -s, s,
|
||||
aspect * s, -aspect * s, VIEW_NEAR, VIEW_FAR);
|
||||
|
||||
GlUtils.setTranslation(mTmpMatrix, 0, 0, -VIEW_DISTANCE);
|
||||
Matrix.multiplyMM(mProjMatrix, 0, mProjMatrix, 0, mTmpMatrix, 0);
|
||||
mProjMatrix.set(tmp);
|
||||
mTmpMatrix.setTranslation(0, 0, -VIEW_DISTANCE);
|
||||
mProjMatrix.multiplyMM(mTmpMatrix);
|
||||
mProjMatrix.get(tmp);
|
||||
|
||||
Matrix.invertM(mProjMatrixI, 0, mProjMatrix, 0);
|
||||
Matrix.invertM(tmp, 0, tmp, 0);
|
||||
mProjMatrixI.set(tmp);
|
||||
|
||||
mHeight = height;
|
||||
mWidth = width;
|
||||
@ -180,15 +184,15 @@ public class MapViewPosition {
|
||||
* @param proj projection Matrix
|
||||
* @param vp view and projection
|
||||
*/
|
||||
public synchronized void getMatrix(float[] view, float[] proj, float[] vp) {
|
||||
public synchronized void getMatrix(Matrix4 view, Matrix4 proj, Matrix4 vp) {
|
||||
if (view != null)
|
||||
System.arraycopy(mViewMatrix, 0, view, 0, 16);
|
||||
view.copy(mViewMatrix);
|
||||
|
||||
if (proj != null)
|
||||
System.arraycopy(mProjMatrix, 0, proj, 0, 16);
|
||||
proj.copy(mProjMatrix);
|
||||
|
||||
if (vp != null)
|
||||
System.arraycopy(mVPMatrix, 0, vp, 0, 16);
|
||||
vp.copy(mVPMatrix);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -233,23 +237,21 @@ public class MapViewPosition {
|
||||
mv[0] = 0;
|
||||
mv[1] = (float) (ry / ua);
|
||||
mv[2] = (float) (cx - cx / ua);
|
||||
mv[3] = 1;
|
||||
|
||||
Matrix.multiplyMV(mv, 0, mProjMatrix, 0, mv, 0);
|
||||
mProjMatrix.prj(mv);
|
||||
|
||||
return mv[2] / mv[3];
|
||||
return mv[2];
|
||||
}
|
||||
|
||||
private void unproject(float x, float y, float z, float[] coords, int position) {
|
||||
mv[0] = x;
|
||||
mv[1] = y;
|
||||
mv[2] = z;
|
||||
mv[3] = 1;
|
||||
|
||||
Matrix.multiplyMV(mv, 0, mUnprojMatrix, 0, mv, 0);
|
||||
mUnprojMatrix.prj(mv);
|
||||
|
||||
coords[position + 0] = mv[0] / mv[3];
|
||||
coords[position + 1] = mv[1] / mv[3];
|
||||
coords[position + 0] = mv[0];
|
||||
coords[position + 1] = mv[1];
|
||||
}
|
||||
|
||||
/** @return the current center point of the MapView. */
|
||||
@ -400,11 +402,9 @@ public class MapViewPosition {
|
||||
mv[2] = 0;
|
||||
mv[3] = 1;
|
||||
|
||||
Matrix.multiplyMV(mv, 0, mVPMatrix, 0, mv, 0);
|
||||
|
||||
// positive direction is down and right;
|
||||
out.x = (int) ((mv[0] / mv[3]) * (mWidth / 2));
|
||||
out.y = (int) -((mv[1] / mv[3]) * (mHeight / 2));
|
||||
mVPMatrix.prj(mv);
|
||||
out.x = (int) (mv[0] * (mWidth / 2));
|
||||
out.y = (int) -(mv[1] * (mHeight / 2));
|
||||
}
|
||||
|
||||
private void updateMatrix() {
|
||||
@ -417,37 +417,34 @@ public class MapViewPosition {
|
||||
// 4. translate to VIEW_DISTANCE
|
||||
// 5. apply projection
|
||||
|
||||
Matrix.setRotateM(mRotMatrix, 0, mRotation, 0, 0, 1);
|
||||
mRotMatrix.setRotation(mRotation, 0, 0, 1);
|
||||
|
||||
// tilt map
|
||||
float tilt = mTilt;
|
||||
Matrix.setRotateM(mTmpMatrix, 0, tilt, 1, 0, 0);
|
||||
mTmpMatrix.setRotation(mTilt, 1, 0, 0);
|
||||
|
||||
// apply first rotation, then tilt
|
||||
Matrix.multiplyMM(mRotMatrix, 0, mTmpMatrix, 0, mRotMatrix, 0);
|
||||
mRotMatrix.multiplyMM(mTmpMatrix, mRotMatrix);
|
||||
|
||||
// scale to window coordinates
|
||||
GlUtils.setScaleM(mTmpMatrix, 1 / mWidth, 1 / mWidth, 1);
|
||||
mTmpMatrix.setScale(1 / mWidth, 1 / mWidth, 1);
|
||||
|
||||
Matrix.multiplyMM(mViewMatrix, 0, mRotMatrix, 0, mTmpMatrix, 0);
|
||||
mViewMatrix.multiplyMM(mRotMatrix, mTmpMatrix);
|
||||
|
||||
Matrix.multiplyMM(mVPMatrix, 0, mProjMatrix, 0, mViewMatrix, 0);
|
||||
mVPMatrix.multiplyMM(mProjMatrix, mViewMatrix);
|
||||
|
||||
//--- unproject matrix:
|
||||
// Matrix.multiplyMM(mTmpMatrix, 0, mProjMatrix, 0, mViewMatrix, 0);
|
||||
// Matrix.invertM(mUnprojMatrix, 0, mTmpMatrix, 0);
|
||||
|
||||
// inverse scale
|
||||
GlUtils.setScaleM(mUnprojMatrix, mWidth, mWidth, 1);
|
||||
mUnprojMatrix.setScale(mWidth, mWidth, 1);
|
||||
|
||||
// inverse rotation and tilt
|
||||
Matrix.transposeM(mTmpMatrix, 0, mRotMatrix, 0);
|
||||
mTmpMatrix.transposeM(mRotMatrix);
|
||||
|
||||
// (AB)^-1 = B^-1*A^-1, unapply scale, tilt and rotation
|
||||
Matrix.multiplyMM(mTmpMatrix, 0, mUnprojMatrix, 0, mTmpMatrix, 0);
|
||||
mTmpMatrix.multiplyMM(mUnprojMatrix, mTmpMatrix);
|
||||
|
||||
// (AB)^-1 = B^-1*A^-1, unapply projection
|
||||
Matrix.multiplyMM(mUnprojMatrix, 0, mTmpMatrix, 0, mProjMatrixI, 0);
|
||||
mUnprojMatrix.multiplyMM(mTmpMatrix, mProjMatrixI);
|
||||
}
|
||||
|
||||
/** @return true if this MapViewPosition is valid, false otherwise. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user