forked from Kolyah35/minecraft-pe-0.6.1
(MAJOR)Added Java Beta/Normal Shading, toggleble in settings Fixed and restored the unused Item Switching Animation, toggleble in tweaks too Added Dynamic Texture for Lava Added option to use Block Outline Selection which was unused normally Added Split Touch Controls into Options Mobs will now drop cooked variants of their meat if they died by fire Fixed Untranslated Strings in Settings (MAJOR) Ravines and Lava/Water pools have been fixed and renabled Tweaked BasicTree to hopefully speed up generation a bit, might disable them temporarily if they keep being slow You can now grow Fancy Oak Trees using saplings.
438 lines
9.5 KiB
C++
Executable File
438 lines
9.5 KiB
C++
Executable File
#include "Tesselator.h"
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <algorithm>
|
|
|
|
Tesselator Tesselator::instance(sizeof(GLfloat) * MAX_FLOATS); // max size in bytes
|
|
|
|
const int VertexSizeBytes = sizeof(VERTEX);
|
|
|
|
Tesselator::Tesselator( int size )
|
|
: size(size),
|
|
vertices(0),
|
|
u(0), v(0),
|
|
_color(0),
|
|
hasColor(false),
|
|
hasTexture(false),
|
|
hasNormal(false),
|
|
p(0),
|
|
count(0),
|
|
_noColor(false),
|
|
mode(0),
|
|
xo(0), yo(0), zo(0),
|
|
_normal(0),
|
|
_sx(1), _sy(1),
|
|
|
|
tesselating(false),
|
|
vboId(-1),
|
|
vboCounts(128),
|
|
totalSize(0),
|
|
accessMode(ACCESS_STATIC),
|
|
maxVertices(size / sizeof(VERTEX)),
|
|
_voidBeginEnd(false)
|
|
{
|
|
vboIds = new GLuint[vboCounts];
|
|
|
|
_varray = new VERTEX[maxVertices];
|
|
|
|
char* a = (char*)&_varray[0];
|
|
char* b = (char*)&_varray[1];
|
|
LOGI("Vsize: %lu, %d\n", sizeof(VERTEX), (b-a));
|
|
}
|
|
|
|
Tesselator::~Tesselator()
|
|
{
|
|
delete[] vboIds;
|
|
delete[] _varray;
|
|
}
|
|
|
|
void Tesselator::init()
|
|
{
|
|
#ifndef STANDALONE_SERVER
|
|
glGenBuffers2(vboCounts, vboIds);
|
|
#endif
|
|
}
|
|
|
|
void Tesselator::clear()
|
|
{
|
|
accessMode = ACCESS_STATIC;
|
|
vertices = 0;
|
|
count = 0;
|
|
p = 0;
|
|
_voidBeginEnd = false;
|
|
}
|
|
|
|
int Tesselator::getVboCount() {
|
|
return vboCounts;
|
|
}
|
|
|
|
RenderChunk Tesselator::end( bool useMine, int bufferId )
|
|
{
|
|
#ifndef STANDALONE_SERVER
|
|
//if (!tesselating) throw /*new*/ IllegalStateException("Not tesselating!");
|
|
if (!tesselating)
|
|
LOGI("not tesselating!\n");
|
|
|
|
if (!tesselating || _voidBeginEnd) return RenderChunk();
|
|
|
|
tesselating = false;
|
|
const int o_vertices = vertices;
|
|
|
|
if (vertices > 0) {
|
|
if (p <= 0 || p > maxVertices) { clear(); return RenderChunk(); }
|
|
int bytes = p * sizeof(VERTEX);
|
|
if (bytes <= 0) return RenderChunk();
|
|
if (++vboId >= vboCounts)
|
|
vboId = 0;
|
|
|
|
#ifdef USE_VBO
|
|
// Using VBO, use default buffer id only if we don't send in any
|
|
if (!useMine) {
|
|
bufferId = vboIds[vboId];
|
|
}
|
|
#else
|
|
// Not using VBO - always use the next buffer object
|
|
bufferId = vboIds[vboId];
|
|
#endif
|
|
int access = GL_STATIC_DRAW;//(accessMode==ACCESS_DYNAMIC) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
|
|
glBindBuffer2(GL_ARRAY_BUFFER, bufferId);
|
|
glBufferData2(GL_ARRAY_BUFFER, bytes, _varray, access); // GL_STREAM_DRAW
|
|
|
|
totalSize += bytes;
|
|
|
|
#ifndef USE_VBO
|
|
// 0 1 2 3 4 5 6 7
|
|
// x y z u v c
|
|
if (hasTexture) {
|
|
glTexCoordPointer2(2, GL_FLOAT, VertexSizeBytes, (GLvoid*) (3 * 4));
|
|
glEnableClientState2(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
if (hasColor) {
|
|
glColorPointer2(4, GL_UNSIGNED_BYTE, VertexSizeBytes, (GLvoid*) (5 * 4));
|
|
glEnableClientState2(GL_COLOR_ARRAY);
|
|
}
|
|
if (hasNormal) {
|
|
glNormalPointer(GL_BYTE, VertexSizeBytes, (GLvoid*) (6 * 4));
|
|
glEnableClientState2(GL_NORMAL_ARRAY);
|
|
}
|
|
glVertexPointer2(3, GL_FLOAT, VertexSizeBytes, 0);
|
|
glEnableClientState2(GL_VERTEX_ARRAY);
|
|
|
|
if (mode == GL_QUADS) {
|
|
glDrawArrays2(GL_TRIANGLES, 0, vertices);
|
|
} else {
|
|
glDrawArrays2(mode, 0, vertices);
|
|
}
|
|
//printf("drawing %d tris, size %d (%d,%d,%d)\n", vertices, p, hasTexture, hasColor, hasNormal);
|
|
glDisableClientState2(GL_VERTEX_ARRAY);
|
|
if (hasTexture) glDisableClientState2(GL_TEXTURE_COORD_ARRAY);
|
|
if (hasColor) glDisableClientState2(GL_COLOR_ARRAY);
|
|
if (hasNormal) glDisableClientState2(GL_NORMAL_ARRAY);
|
|
#endif /*!USE_VBO*/
|
|
}
|
|
|
|
clear();
|
|
RenderChunk out(bufferId, o_vertices);
|
|
//map.insert( std::make_pair(bufferId, out.id) );
|
|
return out;
|
|
#else
|
|
return RenderChunk();
|
|
#endif
|
|
|
|
}
|
|
|
|
void Tesselator::begin( int mode )
|
|
{
|
|
if (tesselating || _voidBeginEnd) {
|
|
if (tesselating && !_voidBeginEnd)
|
|
LOGI("already tesselating!\n");
|
|
return;
|
|
}
|
|
//if (tesselating) {
|
|
// throw /*new*/ IllegalStateException("Already tesselating!");
|
|
//}
|
|
tesselating = true;
|
|
|
|
clear();
|
|
this->mode = mode;
|
|
hasNormal = false;
|
|
hasColor = false;
|
|
hasTexture = false;
|
|
_noColor = false;
|
|
}
|
|
|
|
void Tesselator::begin()
|
|
{
|
|
begin(GL_QUADS);
|
|
}
|
|
|
|
void Tesselator::tex( float u, float v )
|
|
{
|
|
hasTexture = true;
|
|
this->u = u;
|
|
this->v = v;
|
|
}
|
|
|
|
int Tesselator::getColor() {
|
|
return _color;
|
|
}
|
|
|
|
void Tesselator::color( float r, float g, float b )
|
|
{
|
|
color((int) (r * 255), (int) (g * 255), (int) (b * 255));
|
|
}
|
|
|
|
void Tesselator::color( float r, float g, float b, float a )
|
|
{
|
|
color((int) (r * 255), (int) (g * 255), (int) (b * 255), (int) (a * 255));
|
|
}
|
|
|
|
void Tesselator::color( int r, int g, int b )
|
|
{
|
|
color(r, g, b, 255);
|
|
}
|
|
|
|
void Tesselator::color( int r, int g, int b, int a )
|
|
{
|
|
if (_noColor) return;
|
|
|
|
if (r > 255) r = 255;
|
|
if (g > 255) g = 255;
|
|
if (b > 255) b = 255;
|
|
if (a > 255) a = 255;
|
|
if (r < 0) r = 0;
|
|
if (g < 0) g = 0;
|
|
if (b < 0) b = 0;
|
|
if (a < 0) a = 0;
|
|
|
|
hasColor = true;
|
|
//if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
|
|
if (true) {
|
|
_color = (a << 24) | (b << 16) | (g << 8) | (r);
|
|
} else {
|
|
_color = (r << 24) | (g << 16) | (b << 8) | (a);
|
|
}
|
|
}
|
|
|
|
void Tesselator::color( char r, char g, char b )
|
|
{
|
|
color(r & 0xff, g & 0xff, b & 0xff);
|
|
}
|
|
|
|
void Tesselator::color( int c )
|
|
{
|
|
int r = ((c >> 16) & 255);
|
|
int g = ((c >> 8) & 255);
|
|
int b = ((c) & 255);
|
|
color(r, g, b);
|
|
}
|
|
|
|
//@note: doesn't care about endianess
|
|
void Tesselator::colorABGR( int c )
|
|
{
|
|
if (_noColor) return;
|
|
hasColor = true;
|
|
_color = c;
|
|
}
|
|
|
|
void Tesselator::color( int c, int alpha )
|
|
{
|
|
int r = ((c >> 16) & 255);
|
|
int g = ((c >> 8) & 255);
|
|
int b = ((c) & 255);
|
|
color(r, g, b, alpha);
|
|
}
|
|
|
|
void Tesselator::vertexUV( float x, float y, float z, float u, float v )
|
|
{
|
|
tex(u, v);
|
|
vertex(x, y, z);
|
|
}
|
|
|
|
void Tesselator::scale2d(float sx, float sy) {
|
|
_sx *= sx;
|
|
_sy *= sy;
|
|
}
|
|
|
|
void Tesselator::resetScale() {
|
|
_sx = _sy = 1;
|
|
}
|
|
|
|
void Tesselator::vertex( float x, float y, float z )
|
|
{
|
|
#ifndef STANDALONE_SERVER
|
|
count++;
|
|
|
|
if (mode == GL_QUADS && (count & 3) == 0) {
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
const int offs = 3 - i;
|
|
if (p - offs < 0 || p >= maxVertices) { clear(); return; }
|
|
VERTEX& src = _varray[p - offs];
|
|
VERTEX& dst = _varray[p];
|
|
|
|
if (hasTexture) {
|
|
dst.u = src.u;
|
|
dst.v = src.v;
|
|
}
|
|
if (hasColor) {
|
|
dst.color = src.color;
|
|
}
|
|
if (hasNormal) {
|
|
dst.normal = src.normal;
|
|
}
|
|
|
|
dst.x = src.x;
|
|
dst.y = src.y;
|
|
dst.z = src.z;
|
|
|
|
++vertices;
|
|
++p;
|
|
}
|
|
}
|
|
|
|
if (p < 0 || p >= maxVertices) { clear(); return; }
|
|
VERTEX& vertex = _varray[p];
|
|
|
|
if (hasTexture) {
|
|
vertex.u = u;
|
|
vertex.v = v;
|
|
}
|
|
if (hasColor) {
|
|
vertex.color = _color;
|
|
}
|
|
if (hasNormal) {
|
|
vertex.normal = _normal;
|
|
}
|
|
|
|
vertex.x = _sx * (x + xo);
|
|
vertex.y = _sy * (y + yo);
|
|
vertex.z = z + zo;
|
|
|
|
++p;
|
|
++vertices;
|
|
|
|
if ((vertices & 3) == 0 && p >= maxVertices-1) {
|
|
for (int i = 0; i < 3; ++i)
|
|
printf("Overwriting the vertex buffer! This chunk/entity won't show up\n");
|
|
clear();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void Tesselator::noColor()
|
|
{
|
|
_noColor = true;
|
|
}
|
|
|
|
void Tesselator::setAccessMode(int mode)
|
|
{
|
|
accessMode = mode;
|
|
}
|
|
|
|
void Tesselator::normal( float x, float y, float z )
|
|
{
|
|
//static int _warn_t = 0;
|
|
//if ((++_warn_t & 32767) == 1)
|
|
// LOGI("WARNING: Can't use normals (Tesselator::normal)\n");
|
|
//return;
|
|
|
|
if (!tesselating) printf("But..");
|
|
hasNormal = true;
|
|
char xx = (char) (x * 128);
|
|
char yy = (char) (y * 127);
|
|
char zz = (char) (z * 127);
|
|
|
|
_normal = xx | (yy << 8) | (zz << 16);
|
|
}
|
|
|
|
void Tesselator::offset( float xo, float yo, float zo ) {
|
|
this->xo = xo;
|
|
this->yo = yo;
|
|
this->zo = zo;
|
|
}
|
|
|
|
void Tesselator::addOffset( float x, float y, float z ) {
|
|
xo += x;
|
|
yo += y;
|
|
zo += z;
|
|
}
|
|
|
|
void Tesselator::offset( const Vec3& v ) {
|
|
xo = v.x;
|
|
yo = v.y;
|
|
zo = v.z;
|
|
}
|
|
|
|
void Tesselator::addOffset( const Vec3& v ) {
|
|
xo += v.x;
|
|
yo += v.y;
|
|
zo += v.z;
|
|
}
|
|
|
|
void Tesselator::draw()
|
|
{
|
|
#ifndef STANDALONE_SERVER
|
|
if (!tesselating)
|
|
LOGI("not (draw) tesselating!\n");
|
|
|
|
if (!tesselating || _voidBeginEnd)
|
|
return;
|
|
|
|
tesselating = false;
|
|
|
|
if (vertices > 0) {
|
|
if (p <= 0 || p > maxVertices) { clear(); return; }
|
|
int bytes = p * sizeof(VERTEX);
|
|
if (bytes <= 0) { clear(); return; }
|
|
if (++vboId >= vboCounts)
|
|
vboId = 0;
|
|
|
|
int bufferId = vboIds[vboId];
|
|
|
|
int access = GL_DYNAMIC_DRAW;//(accessMode==ACCESS_DYNAMIC) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
|
|
glBindBuffer2(GL_ARRAY_BUFFER, bufferId);
|
|
glBufferData2(GL_ARRAY_BUFFER, bytes, _varray, access); // GL_STREAM_DRAW
|
|
|
|
if (hasTexture) {
|
|
glTexCoordPointer2(2, GL_FLOAT, VertexSizeBytes, (GLvoid*) (3 * 4));
|
|
//glTexCoordPointer2(2, GL_FLOAT, VertexSizeBytes, (GLvoid*) &_varray->u);
|
|
glEnableClientState2(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
if (hasColor) {
|
|
glColorPointer2(4, GL_UNSIGNED_BYTE, VertexSizeBytes, (GLvoid*) (5 * 4));
|
|
//glColorPointer2(4, GL_UNSIGNED_BYTE, VertexSizeBytes, (GLvoid*) &_varray->color);
|
|
glEnableClientState2(GL_COLOR_ARRAY);
|
|
}
|
|
if (hasNormal) {
|
|
glNormalPointer(GL_BYTE, VertexSizeBytes, (GLvoid*) (6 * 4));
|
|
glEnableClientState2(GL_NORMAL_ARRAY);
|
|
}
|
|
//glVertexPointer2(3, GL_FLOAT, VertexSizeBytes, (GLvoid*)&_varray);
|
|
glVertexPointer2(3, GL_FLOAT, VertexSizeBytes, 0);
|
|
glEnableClientState2(GL_VERTEX_ARRAY);
|
|
|
|
if (mode == GL_QUADS) {
|
|
glDrawArrays2(GL_TRIANGLES, 0, vertices);
|
|
} else {
|
|
glDrawArrays2(mode, 0, vertices);
|
|
}
|
|
|
|
glDisableClientState2(GL_VERTEX_ARRAY);
|
|
if (hasTexture) glDisableClientState2(GL_TEXTURE_COORD_ARRAY);
|
|
if (hasColor) glDisableClientState2(GL_COLOR_ARRAY);
|
|
if (hasNormal) glDisableClientState2(GL_NORMAL_ARRAY);
|
|
}
|
|
|
|
clear();
|
|
#endif
|
|
}
|
|
|
|
void Tesselator::voidBeginAndEndCalls(bool doVoid) {
|
|
_voidBeginEnd = doVoid;
|
|
}
|
|
|
|
void Tesselator::enableColor() {
|
|
_noColor = false;
|
|
}
|