154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/* libs/opengles/primitives.cpp
254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project**
354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project** Copyright 2006, The Android Open Source Project
454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project**
554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project** you may not use this file except in compliance with the License.
754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project** You may obtain a copy of the License at
854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project**
954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
1054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project**
1154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
1254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
1354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project** See the License for the specific language governing permissions and
1554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project** limitations under the License.
1654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project*/
1754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <stdio.h>
1954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <stdlib.h>
2054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <math.h>
2154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
2254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "context.h"
2354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "primitives.h"
2454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "light.h"
2554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "matrix.h"
2654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "vertex.h"
2754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "fp.h"
2854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "TextureObjectManager.h"
2954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectextern "C" void iterators0032(const void* that,
3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t* it, int32_t c0, int32_t c1, int32_t c2);
3254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectnamespace android {
3454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// ----------------------------------------------------------------------------
3654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void primitive_point(ogles_context_t* c, vertex_t* v);
3854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void primitive_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1);
3954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void primitive_clip_triangle(ogles_context_t* c,
4054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
4154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void primitive_nop_point(ogles_context_t* c, vertex_t* v);
4354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void primitive_nop_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1);
4454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void primitive_nop_triangle(ogles_context_t* c,
4554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
4654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic inline bool cull_triangle(ogles_context_t* c,
4854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
4954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lerp_triangle(ogles_context_t* c,
5154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lerp_texcoords(ogles_context_t* c,
5454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
5554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lerp_texcoords_w(ogles_context_t* c,
5754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
5854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void triangle(ogles_context_t* c,
6054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void clip_triangle(ogles_context_t* c,
6354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic unsigned int clip_line(ogles_context_t* c,
6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* s, vertex_t* p);
6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// ----------------------------------------------------------------------------
6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#if 0
7054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#pragma mark -
7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#endif
7254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lightTriangleDarkSmooth(ogles_context_t* c,
7454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
7554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
7654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!(v0->flags & vertex_t::LIT)) {
7754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        v0->flags |= vertex_t::LIT;
7854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const GLvoid* cp = c->arrays.color.element(
7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                v0->index & vertex_cache_t::INDEX_MASK);
8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->arrays.color.fetch(c, v0->color.v, cp);
8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!(v1->flags & vertex_t::LIT)) {
8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        v1->flags |= vertex_t::LIT;
8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const GLvoid* cp = c->arrays.color.element(
8554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                v1->index & vertex_cache_t::INDEX_MASK);
8654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->arrays.color.fetch(c, v1->color.v, cp);
8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
8854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if(!(v2->flags & vertex_t::LIT)) {
8954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        v2->flags |= vertex_t::LIT;
9054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const GLvoid* cp = c->arrays.color.element(
9154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                v2->index & vertex_cache_t::INDEX_MASK);
9254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->arrays.color.fetch(c, v2->color.v, cp);
9354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
9454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
9654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lightTriangleDarkFlat(ogles_context_t* c,
9754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
9854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!(v2->flags & vertex_t::LIT)) {
10054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        v2->flags |= vertex_t::LIT;
10154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const GLvoid* cp = c->arrays.color.element(
10254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                v2->index & vertex_cache_t::INDEX_MASK);
10354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->arrays.color.fetch(c, v2->color.v, cp);
10454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // configure the rasterizer here, before we clip
10654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->rasterizer.procs.color4xv(c, v2->color.v);
10754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
10854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
10954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lightTriangleSmooth(ogles_context_t* c,
11054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
11154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
11254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!(v0->flags & vertex_t::LIT))
11354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->lighting.lightVertex(c, v0);
11454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!(v1->flags & vertex_t::LIT))
11554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->lighting.lightVertex(c, v1);
11654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if(!(v2->flags & vertex_t::LIT))
11754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->lighting.lightVertex(c, v2);
11854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
11954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lightTriangleFlat(ogles_context_t* c,
12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
12254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
12354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!(v2->flags & vertex_t::LIT))
12454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->lighting.lightVertex(c, v2);
12554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // configure the rasterizer here, before we clip
12654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->rasterizer.procs.color4xv(c, v2->color.v);
12754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
12854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
12954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// The fog versions...
13054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
13154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic inline
13254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid lightVertexDarkSmoothFog(ogles_context_t* c, vertex_t* v)
13354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
13454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!(v->flags & vertex_t::LIT)) {
13554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        v->flags |= vertex_t::LIT;
136f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        v->fog = c->fog.fog(c, v->eye.z);
13754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const GLvoid* cp = c->arrays.color.element(
13854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                v->index & vertex_cache_t::INDEX_MASK);
13954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->arrays.color.fetch(c, v->color.v, cp);
14054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
14154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
14254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic inline
14354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid lightVertexDarkFlatFog(ogles_context_t* c, vertex_t* v)
14454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
14554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!(v->flags & vertex_t::LIT)) {
14654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        v->flags |= vertex_t::LIT;
147f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        v->fog = c->fog.fog(c, v->eye.z);
14854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
14954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
15054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic inline
15154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid lightVertexSmoothFog(ogles_context_t* c, vertex_t* v)
15254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
15354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!(v->flags & vertex_t::LIT)) {
154f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        v->fog = c->fog.fog(c, v->eye.z);
15554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->lighting.lightVertex(c, v);
15654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
15754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
15854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
15954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lightTriangleDarkSmoothFog(ogles_context_t* c,
16054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
16154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
16254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexDarkSmoothFog(c, v0);
16354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexDarkSmoothFog(c, v1);
16454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexDarkSmoothFog(c, v2);
16554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
16654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
16754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lightTriangleDarkFlatFog(ogles_context_t* c,
16854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
16954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
17054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexDarkFlatFog(c, v0);
17154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexDarkFlatFog(c, v1);
17254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexDarkSmoothFog(c, v2);
17354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // configure the rasterizer here, before we clip
17454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->rasterizer.procs.color4xv(c, v2->color.v);
17554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
17654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
17754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lightTriangleSmoothFog(ogles_context_t* c,
17854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
17954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
18054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexSmoothFog(c, v0);
18154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexSmoothFog(c, v1);
18254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexSmoothFog(c, v2);
18354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
18454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void lightTriangleFlatFog(ogles_context_t* c,
18654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
18754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
18854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexDarkFlatFog(c, v0);
18954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexDarkFlatFog(c, v1);
19054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightVertexSmoothFog(c, v2);
19154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // configure the rasterizer here, before we clip
19254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->rasterizer.procs.color4xv(c, v2->color.v);
19354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
19454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
19554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
19654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
19754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projecttypedef void (*light_primitive_t)(ogles_context_t*,
19854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t*, vertex_t*, vertex_t*);
19954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
20054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// fog 0x4, light 0x2, smooth 0x1
20154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic const light_primitive_t lightPrimitive[8] = {
20254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightTriangleDarkFlat,          // no fog | dark  | flat
20354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightTriangleDarkSmooth,        // no fog | dark  | smooth
20454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightTriangleFlat,              // no fog | light | flat
20554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightTriangleSmooth,            // no fog | light | smooth
20654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightTriangleDarkFlatFog,       // fog    | dark  | flat
20754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightTriangleDarkSmoothFog,     // fog    | dark  | smooth
20854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightTriangleFlatFog,           // fog    | light | flat
20954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lightTriangleSmoothFog          // fog    | light | smooth
21054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project};
21154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
21254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid ogles_validate_primitives(ogles_context_t* c)
21354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
21454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
21554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // set up the lighting/shading/smoothing/fogging function
21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int index = enables & GGL_ENABLE_SMOOTH ? 0x1 : 0;
21854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    index |= c->lighting.enable ? 0x2 : 0;
21954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    index |= enables & GGL_ENABLE_FOG ? 0x4 : 0;
22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->lighting.lightTriangle = lightPrimitive[index];
22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
22254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // set up the primitive renderers
22354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_likely(c->arrays.vertex.enable)) {
22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->prims.renderPoint    = primitive_point;
22554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->prims.renderLine     = primitive_line;
22654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->prims.renderTriangle = primitive_clip_triangle;
22754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
22854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->prims.renderPoint    = primitive_nop_point;
22954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->prims.renderLine     = primitive_nop_line;
23054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->prims.renderTriangle = primitive_nop_triangle;
23154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// ----------------------------------------------------------------------------
23554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid compute_iterators_t::initTriangle(
23754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t const* v0, vertex_t const* v1, vertex_t const* v2)
23854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
23954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_dx01 = v1->window.x - v0->window.x;
24054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_dy10 = v0->window.y - v1->window.y;
24154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_dx20 = v0->window.x - v2->window.x;
24254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_dy02 = v2->window.y - v0->window.y;
24354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_area = m_dx01*m_dy02 + (-m_dy10)*m_dx20;
24454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
24554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
246f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Projectvoid compute_iterators_t::initLine(
247f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        vertex_t const* v0, vertex_t const* v1)
248f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project{
249f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    m_dx01 = m_dy02 = v1->window.x - v0->window.x;
250f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    m_dy10 = m_dx20 = v0->window.y - v1->window.y;
251f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    m_area = m_dx01*m_dy02 + (-m_dy10)*m_dx20;
252f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project}
253f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project
25454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid compute_iterators_t::initLerp(vertex_t const* v0, uint32_t enables)
25554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
25654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_x0 = v0->window.x;
25754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_y0 = v0->window.y;
25854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const GGLcoord area = (m_area + TRI_HALF) >> TRI_FRACTION_BITS;
259f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    const GGLcoord minArea = 2; // cannot be inverted
26054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // triangles with an area smaller than 1.0 are not smooth-shaded
26154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
26254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int q=0, s=0, d=0;
26354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (abs(area) >= minArea) {
26454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // Here we do some voodoo magic, to compute a suitable scale
26554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // factor for deltas/area:
26654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
26754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // First compute the 1/area with full 32-bits precision,
26854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // gglRecipQNormalized returns a number [-0.5, 0.5[ and an exponent.
26954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        d = gglRecipQNormalized(area, &q);
27054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
27154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // Then compute the minimum left-shift to not overflow the muls
27254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // below.
27354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        s = 32 - gglClz(abs(m_dy02)|abs(m_dy10)|abs(m_dx01)|abs(m_dx20));
27454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
27554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // We'll keep 16-bits of precision for deltas/area. So we need
27654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // to shift everything left an extra 15 bits.
27754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        s += 15;
27854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
27954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // make sure all final shifts are not > 32, because gglMulx
28054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // can't handle it.
28154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (s < q) s = q;
28254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (s > 32) {
28354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            d >>= 32-s;
28454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s = 32;
28554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
28654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
28754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
28854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_dx01 = gglMulx(m_dx01, d, s);
28954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_dy10 = gglMulx(m_dy10, d, s);
29054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_dx20 = gglMulx(m_dx20, d, s);
29154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_dy02 = gglMulx(m_dy02, d, s);
29254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_area_scale = 32 + q - s;
29354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_scale = 0;
29454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
29554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (enables & GGL_ENABLE_TMUS) {
29654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const int A = gglClz(abs(m_dy02)|abs(m_dy10)|abs(m_dx01)|abs(m_dx20));
29754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const int B = gglClz(abs(m_x0)|abs(m_y0));
29854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        m_scale = max(0, 32 - (A + 16)) +
29954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                  max(0, 32 - (B + TRI_FRACTION_BITS)) + 1;
30054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
30154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
30254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
30354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint compute_iterators_t::iteratorsScale(GGLfixed* it,
30454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t c0, int32_t c1, int32_t c2) const
30554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
30654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t dc01 = c1 - c0;
30754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t dc02 = c2 - c0;
30854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int A = gglClz(abs(c0));
30954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int B = gglClz(abs(dc01)|abs(dc02));
31054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int scale = min(A, B - m_scale) - 2;
31154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (scale >= 0) {
31254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c0   <<= scale;
31354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        dc01 <<= scale;
31454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        dc02 <<= scale;
31554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
31654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c0   >>= -scale;
31754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        dc01 >>= -scale;
31854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        dc02 >>= -scale;
31954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
32054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int s = m_area_scale;
32154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t dcdx = gglMulAddx(dc01, m_dy02, gglMulx(dc02, m_dy10, s), s);
32254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t dcdy = gglMulAddx(dc02, m_dx01, gglMulx(dc01, m_dx20, s), s);
32354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t c = c0 - (gglMulAddx(dcdx, m_x0,
32454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            gglMulx(dcdy, m_y0, TRI_FRACTION_BITS), TRI_FRACTION_BITS));
32554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    it[0] = c;
32654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    it[1] = dcdx;
32754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    it[2] = dcdy;
32854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return scale;
32954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
33054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
33154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid compute_iterators_t::iterators1616(GGLfixed* it,
33254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        GGLfixed c0, GGLfixed c1, GGLfixed c2) const
33354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
33454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const GGLfixed dc01 = c1 - c0;
33554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const GGLfixed dc02 = c2 - c0;
33654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // 16.16 x 16.16 == 32.32 --> 16.16
33754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int s = m_area_scale;
33854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t dcdx = gglMulAddx(dc01, m_dy02, gglMulx(dc02, m_dy10, s), s);
33954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t dcdy = gglMulAddx(dc02, m_dx01, gglMulx(dc01, m_dx20, s), s);
34054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t c = c0 - (gglMulAddx(dcdx, m_x0,
34154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            gglMulx(dcdy, m_y0, TRI_FRACTION_BITS), TRI_FRACTION_BITS));
34254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    it[0] = c;
34354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    it[1] = dcdx;
34454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    it[2] = dcdy;
34554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
34654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
347f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Projectvoid compute_iterators_t::iterators0032(int64_t* it,
34854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t c0, int32_t c1, int32_t c2) const
34954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
35054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int s = m_area_scale - 16;
35154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t dc01 = (c1 - c0)>>s;
35254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t dc02 = (c2 - c0)>>s;
35354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // 16.16 x 16.16 == 32.32
35454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int64_t dcdx = gglMulii(dc01, m_dy02) + gglMulii(dc02, m_dy10);
35554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int64_t dcdy = gglMulii(dc02, m_dx01) + gglMulii(dc01, m_dx20);
356f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    it[ 0] = (c0<<16) - ((dcdx*m_x0 + dcdy*m_y0)>>4);
35754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    it[ 1] = dcdx;
35854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    it[ 2] = dcdy;
35954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
360f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project
361f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project#if defined(__arm__) && !defined(__thumb__)
362f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Projectinline void compute_iterators_t::iterators0032(int32_t* it,
363f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        int32_t c0, int32_t c1, int32_t c2) const
364f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project{
365f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    ::iterators0032(this, it, c0, c1, c2);
366f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project}
367f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project#else
368f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Projectvoid compute_iterators_t::iterators0032(int32_t* it,
369f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        int32_t c0, int32_t c1, int32_t c2) const
370f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project{
371f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    int64_t it64[3];
37226f6a823ca32b4c8e42bc02efb0ce74c3f281f55Shin-ichiro KAWASAKI    iterators0032(it64, c0, c1, c2);
373f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    it[0] = it64[0];
374f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    it[1] = it64[1];
375f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    it[2] = it64[2];
376f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project}
37754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#endif
37854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
37954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// ----------------------------------------------------------------------------
38054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
38154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic inline int32_t clampZ(GLfixed z) CONST;
38254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint32_t clampZ(GLfixed z) {
38354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    z = (z & ~(z>>31));
38454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (z >= 0x10000)
38554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        z = 0xFFFF;
38654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return z;
38754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
38854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
38954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic __attribute__((noinline))
39054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid fetch_texcoord_impl(ogles_context_t* c,
39154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
39254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
39354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    vertex_t* const vtx[3] = { v0, v1, v2 };
39454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    array_t const * const texcoordArray = c->arrays.texture;
39554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
39654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
39754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!(c->rasterizer.state.texture[i].enable))
39854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            continue;
39954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
40054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        for (int j=0 ; j<3 ; j++) {
40154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            vertex_t* const v = vtx[j];
40254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (v->flags & vertex_t::TT)
40354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                continue;
40454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
40554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // NOTE: here we could compute automatic texgen
40654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // such as sphere/cube maps, instead of fetching them
40754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // from the textcoord array.
40854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
40954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            vec4_t& coords = v->texture[i];
41054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const GLubyte* tp = texcoordArray[i].element(
41154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    v->index & vertex_cache_t::INDEX_MASK);
41254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            texcoordArray[i].fetch(c, coords.v, tp);
41354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
41454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // transform texture coordinates...
41554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            coords.Q = 0x10000;
41654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const transform_t& tr = c->transforms.texture[i].transform;
41754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (ggl_unlikely(tr.ops)) {
41854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                c->arrays.tex_transform[i](&tr, &coords, &coords);
41954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
42054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
42154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // divide by Q
42254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const GGLfixed q = coords.Q;
42354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (ggl_unlikely(q != 0x10000)) {
42454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                const int32_t qinv = gglRecip28(q);
42554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                coords.S = gglMulx(coords.S, qinv, 28);
42654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                coords.T = gglMulx(coords.T, qinv, 28);
42754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
42854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
42954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
43054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    v0->flags |= vertex_t::TT;
43154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    v1->flags |= vertex_t::TT;
43254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    v2->flags |= vertex_t::TT;
43354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
43454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
43554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectinline void fetch_texcoord(ogles_context_t* c,
43654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
43754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
43854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
43954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!(enables & GGL_ENABLE_TMUS))
44054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return;
44154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
44254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // Fetch & transform texture coordinates...
44354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_likely(v0->flags & v1->flags & v2->flags & vertex_t::TT)) {
44454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // already done for all three vertices, bail...
44554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return;
44654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
44754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    fetch_texcoord_impl(c, v0, v1, v2);
44854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
44954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
45054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// ----------------------------------------------------------------------------
45154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#if 0
45254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#pragma mark -
45354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#pragma mark Point
45454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#endif
45554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
45654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid primitive_nop_point(ogles_context_t*, vertex_t*) {
45754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
45854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
45954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid primitive_point(ogles_context_t* c, vertex_t* v)
46054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
46154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // lighting & clamping...
46254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
46354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
46454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_unlikely(!(v->flags & vertex_t::LIT))) {
46554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (c->lighting.enable) {
46654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            c->lighting.lightVertex(c, v);
46754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else {
46854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            v->flags |= vertex_t::LIT;
46954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const GLvoid* cp = c->arrays.color.element(
47054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    v->index & vertex_cache_t::INDEX_MASK);
47154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            c->arrays.color.fetch(c, v->color.v, cp);
47254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
47354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (enables & GGL_ENABLE_FOG) {
474f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project            v->fog = c->fog.fog(c, v->eye.z);
47554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
47654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
47754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
47854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // XXX: we don't need to do that each-time
47954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // if color array and lighting not enabled
48054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->rasterizer.procs.color4xv(c, v->color.v);
48154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
48254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // XXX: look into ES point-sprite extension
48354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (enables & GGL_ENABLE_TMUS) {
48454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        fetch_texcoord(c, v,v,v);
48554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
48654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (!c->rasterizer.state.texture[i].enable)
48754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                continue;
48854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int32_t itt[8];
48954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            itt[1] = itt[2] = itt[4] = itt[5] = 0;
49054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            itt[6] = itt[7] = 16; // XXX: check that
49154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (c->rasterizer.state.texture[i].s_wrap == GGL_CLAMP) {
49254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                int width = c->textures.tmu[i].texture->surface.width;
49354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                itt[0] = v->texture[i].S * width;
49454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                itt[6] = 0;
49554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
49654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (c->rasterizer.state.texture[i].t_wrap == GGL_CLAMP) {
49754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                int height = c->textures.tmu[i].texture->surface.height;
49854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                itt[3] = v->texture[i].T * height;
49954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                itt[7] = 0;
50054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
50154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
50254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
50354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
50454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
50554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (enables & GGL_ENABLE_DEPTH_TEST) {
50654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t itz[3];
50754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        itz[0] = clampZ(v->window.z) * 0x00010001;
50854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        itz[1] = itz[2] = 0;
50954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->rasterizer.procs.zGrad3xv(c, itz);
51054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
51154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
51254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (enables & GGL_ENABLE_FOG) {
51354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        GLfixed itf[3];
51454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        itf[0] = v->fog;
51554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        itf[1] = itf[2] = 0;
51654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->rasterizer.procs.fogGrad3xv(c, itf);
51754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
51854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
51954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // Render our point...
52054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->rasterizer.procs.pointx(c, v->window.v, c->point.size);
52154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
52254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
52354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// ----------------------------------------------------------------------------
52454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#if 0
52554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#pragma mark -
52654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#pragma mark Line
52754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#endif
52854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
52954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid primitive_nop_line(ogles_context_t*, vertex_t*, vertex_t*) {
53054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
53154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
53254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid primitive_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1)
53354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
53454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // get texture coordinates
53554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    fetch_texcoord(c, v0, v1, v1);
53654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
53754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // light/shade the vertices first (they're copied below)
53854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->lighting.lightTriangle(c, v0, v1, v1);
53954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
54054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // clip the line if needed
54154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_unlikely((v0->flags | v1->flags) & vertex_t::CLIP_ALL)) {
54254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        unsigned int count = clip_line(c, v0, v1);
54354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (ggl_unlikely(count == 0))
54454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
54554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
54654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
54754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // compute iterators...
54854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
54954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const uint32_t mask =   GGL_ENABLE_TMUS |
55054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            GGL_ENABLE_SMOOTH |
55154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            GGL_ENABLE_W |
55254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            GGL_ENABLE_FOG |
55354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            GGL_ENABLE_DEPTH_TEST;
55454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
55554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_unlikely(enables & mask)) {
556f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        c->lerp.initLine(v0, v1);
557f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        lerp_triangle(c, v0, v1, v0);
55854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
55954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
56054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // render our line
56154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->rasterizer.procs.linex(c, v0->window.v, v1->window.v, c->line.width);
56254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
56354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
56454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// ----------------------------------------------------------------------------
56554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#if 0
56654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#pragma mark -
56754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#pragma mark Triangle
56854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#endif
56954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
57054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid primitive_nop_triangle(ogles_context_t* c,
57154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2) {
57254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
57354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
57454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid primitive_clip_triangle(ogles_context_t* c,
57554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
57654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
57754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    uint32_t cc = (v0->flags | v1->flags | v2->flags) & vertex_t::CLIP_ALL;
57854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_likely(!cc)) {
57954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // code below must be as optimized as possible, this is the
58054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // common code path.
58154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // This triangle is not clipped, test if it's culled
58354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // unclipped triangle...
58454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->lerp.initTriangle(v0, v1, v2);
58554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (cull_triangle(c, v0, v1, v2))
58654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return; // culled!
58754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // Fetch all texture coordinates if needed
58954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        fetch_texcoord(c, v0, v1, v2);
59054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
59154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // light (or shade) our triangle!
59254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->lighting.lightTriangle(c, v0, v1, v2);
59354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
59454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        triangle(c, v0, v1, v2);
59554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return;
59654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
59754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
59854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // The assumption here is that we're not going to clip very often,
59954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // and even more rarely will we clip a triangle that ends up
60054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // being culled out. So it's okay to light the vertices here, even though
60154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // in a few cases we won't render the triangle (if culled).
60254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
60354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // Fetch texture coordinates...
60454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    fetch_texcoord(c, v0, v1, v2);
60554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
60654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // light (or shade) our triangle!
60754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->lighting.lightTriangle(c, v0, v1, v2);
60854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
60954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    clip_triangle(c, v0, v1, v2);
61054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
61154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
61254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// -----------------------------------------------------------------------
61354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
61454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid triangle(ogles_context_t* c,
61554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
61654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
61754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // compute iterators...
61854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
61954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const uint32_t mask =   GGL_ENABLE_TMUS |
62054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            GGL_ENABLE_SMOOTH |
62154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            GGL_ENABLE_W |
62254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            GGL_ENABLE_FOG |
62354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            GGL_ENABLE_DEPTH_TEST;
62454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
62554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_likely(enables & mask))
62654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        lerp_triangle(c, v0, v1, v2);
62754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
62854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->rasterizer.procs.trianglex(c, v0->window.v, v1->window.v, v2->window.v);
62954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
63054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
63154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid lerp_triangle(ogles_context_t* c,
63254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
63354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
63454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
63554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->lerp.initLerp(v0, enables);
63654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
63754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // set up texture iterators
63854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (enables & GGL_ENABLE_TMUS) {
63954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (enables & GGL_ENABLE_W) {
64054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            lerp_texcoords_w(c, v0, v1, v2);
64154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else {
64254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            lerp_texcoords(c, v0, v1, v2);
64354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
64454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
64554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
64654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // set up the color iterators
64754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const compute_iterators_t& lerp = c->lerp;
64854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (enables & GGL_ENABLE_SMOOTH) {
64954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        GLfixed itc[12];
65054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        for (int i=0 ; i<4 ; i++) {
65154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const GGLcolor c0 = v0->color.v[i] * 255;
65254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const GGLcolor c1 = v1->color.v[i] * 255;
65354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const GGLcolor c2 = v2->color.v[i] * 255;
65454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            lerp.iterators1616(&itc[i*3], c0, c1, c2);
65554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
65654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->rasterizer.procs.colorGrad12xv(c, itc);
65754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
65854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
65954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (enables & GGL_ENABLE_DEPTH_TEST) {
66054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t itz[3];
66154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const int32_t v0z = clampZ(v0->window.z);
66254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const int32_t v1z = clampZ(v1->window.z);
66354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const int32_t v2z = clampZ(v2->window.z);
66454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (ggl_unlikely(c->polygonOffset.enable)) {
665f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project            const int32_t units = (c->polygonOffset.units << 16);
66654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const GLfixed factor = c->polygonOffset.factor;
667f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project            if (factor) {
668f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                int64_t itz64[3];
669f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                lerp.iterators0032(itz64, v0z, v1z, v2z);
670f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                int64_t maxDepthSlope = max(itz64[1], itz64[2]);
671f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                itz[0] = uint32_t(itz64[0])
672f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                        + uint32_t((maxDepthSlope*factor)>>16) + units;
673f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                itz[1] = uint32_t(itz64[1]);
674f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                itz[2] = uint32_t(itz64[2]);
675f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project            } else {
676f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                lerp.iterators0032(itz, v0z, v1z, v2z);
677f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                itz[0] += units;
678f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project            }
679f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        } else {
680f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project            lerp.iterators0032(itz, v0z, v1z, v2z);
68154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
68254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->rasterizer.procs.zGrad3xv(c, itz);
683f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    }
68454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
68554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_unlikely(enables & GGL_ENABLE_FOG)) {
68654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        GLfixed itf[3];
68754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        lerp.iterators1616(itf, v0->fog, v1->fog, v2->fog);
68854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->rasterizer.procs.fogGrad3xv(c, itf);
68954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
69054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
69154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
69254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
69354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic inline
69454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint compute_lod(ogles_context_t* c, int i,
69554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t s0, int32_t t0, int32_t s1, int32_t t1, int32_t s2, int32_t t2)
69654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
69754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // Compute mipmap level / primitive
69854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // rho = sqrt( texelArea / area )
69954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // lod = log2( rho )
70054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // lod = log2( texelArea / area ) / 2
70154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // lod = (log2( texelArea ) - log2( area )) / 2
70254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const compute_iterators_t& lerp = c->lerp;
70354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const GGLcoord area = abs(lerp.area());
70454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int w = c->textures.tmu[i].texture->surface.width;
70554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int h = c->textures.tmu[i].texture->surface.height;
70654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int shift = 16 + (16 - TRI_FRACTION_BITS);
70754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t texelArea = abs( gglMulx(s1-s0, t2-t0, shift) -
70854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            gglMulx(s2-s0, t1-t0, shift) )*w*h;
70954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int log2TArea = (32-TRI_FRACTION_BITS  -1) - gglClz(texelArea);
71054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int log2Area  = (32-TRI_FRACTION_BITS*2-1) - gglClz(area);
71154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int lod = (log2TArea - log2Area + 1) >> 1;
71254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return lod;
71354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
71454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
71554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid lerp_texcoords(ogles_context_t* c,
71654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
71754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
71854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const compute_iterators_t& lerp = c->lerp;
71954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t itt[8] __attribute__((aligned(16)));
72054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
72154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const texture_t& tmu = c->rasterizer.state.texture[i];
72254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!tmu.enable)
72354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            continue;
72454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
72554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // compute the jacobians using block floating-point
72654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t s0 = v0->texture[i].S;
72754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t t0 = v0->texture[i].T;
72854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t s1 = v1->texture[i].S;
72954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t t1 = v1->texture[i].T;
73054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t s2 = v2->texture[i].S;
73154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t t2 = v2->texture[i].T;
73254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
73354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const GLenum min_filter = c->textures.tmu[i].texture->min_filter;
73454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (ggl_unlikely(min_filter >= GL_NEAREST_MIPMAP_NEAREST)) {
73554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int lod = compute_lod(c, i, s0, t0, s1, t1, s2, t2);
73654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            c->rasterizer.procs.bindTextureLod(c, i,
73754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    &c->textures.tmu[i].texture->mip(lod));
73854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
73954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
74054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // premultiply (s,t) when clampling
74154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (tmu.s_wrap == GGL_CLAMP) {
74254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const int width = tmu.surface.width;
74354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s0 *= width;
74454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s1 *= width;
74554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s2 *= width;
74654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
74754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (tmu.t_wrap == GGL_CLAMP) {
74854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const int height = tmu.surface.height;
74954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            t0 *= height;
75054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            t1 *= height;
75154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            t2 *= height;
75254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
75354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        itt[6] = -lerp.iteratorsScale(itt+0, s0, s1, s2);
75454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        itt[7] = -lerp.iteratorsScale(itt+3, t0, t1, t2);
75554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
75654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
75754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
75854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
75954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid lerp_texcoords_w(ogles_context_t* c,
76054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
76154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
76254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const compute_iterators_t& lerp = c->lerp;
76354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t itt[8] __attribute__((aligned(16)));
76454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t itw[3];
76554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
76654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // compute W's scale to 2.30
76754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t w0 = v0->window.w;
76854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t w1 = v1->window.w;
76954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t w2 = v2->window.w;
77054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int wscale = 32 - gglClz(w0|w1|w2);
77154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
77254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // compute the jacobian using block floating-point
77354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int sc = lerp.iteratorsScale(itw, w0, w1, w2);
77454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    sc +=  wscale - 16;
77554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->rasterizer.procs.wGrad3xv(c, itw);
77654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
77754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
77854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const texture_t& tmu = c->rasterizer.state.texture[i];
77954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!tmu.enable)
78054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            continue;
78154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
78254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // compute the jacobians using block floating-point
78354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t s0 = v0->texture[i].S;
78454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t t0 = v0->texture[i].T;
78554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t s1 = v1->texture[i].S;
78654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t t1 = v1->texture[i].T;
78754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t s2 = v2->texture[i].S;
78854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int32_t t2 = v2->texture[i].T;
78954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
79054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const GLenum min_filter = c->textures.tmu[i].texture->min_filter;
79154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (ggl_unlikely(min_filter >= GL_NEAREST_MIPMAP_NEAREST)) {
79254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int lod = compute_lod(c, i, s0, t0, s1, t1, s2, t2);
79354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            c->rasterizer.procs.bindTextureLod(c, i,
79454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    &c->textures.tmu[i].texture->mip(lod));
79554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
79654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
79754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // premultiply (s,t) when clampling
79854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (tmu.s_wrap == GGL_CLAMP) {
79954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const int width = tmu.surface.width;
80054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s0 *= width;
80154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s1 *= width;
80254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s2 *= width;
80354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
80454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (tmu.t_wrap == GGL_CLAMP) {
80554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const int height = tmu.surface.height;
80654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            t0 *= height;
80754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            t1 *= height;
80854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            t2 *= height;
80954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
81054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
81154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        s0 = gglMulx(s0, w0, wscale);
81254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        t0 = gglMulx(t0, w0, wscale);
81354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        s1 = gglMulx(s1, w1, wscale);
81454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        t1 = gglMulx(t1, w1, wscale);
81554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        s2 = gglMulx(s2, w2, wscale);
81654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        t2 = gglMulx(t2, w2, wscale);
81754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
81854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        itt[6] = sc - lerp.iteratorsScale(itt+0, s0, s1, s2);
81954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        itt[7] = sc - lerp.iteratorsScale(itt+3, t0, t1, t2);
82054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
82154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
82254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
82354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
82454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
82554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic inline
82654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectbool cull_triangle(ogles_context_t* c, vertex_t* v0, vertex_t* v1, vertex_t* v2)
82754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
82854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_likely(c->cull.enable)) {
82954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const GLenum winding = (c->lerp.area() > 0) ? GL_CW : GL_CCW;
83054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const GLenum face = (winding == c->cull.frontFace) ? GL_FRONT : GL_BACK;
83154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (face == c->cull.cullFace)
83254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return true; // culled!
83354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
83454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return false;
83554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
83654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
83754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic inline
83854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectGLfixed frustumPlaneDist(int plane, const vec4_t& s)
83954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
84054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const GLfixed d = s.v[ plane >> 1 ];
84154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return  ((plane & 1) ? (s.w - d) : (s.w + d));
84254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
84354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
84454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic inline
84554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint32_t clipDivide(GLfixed a, GLfixed b) {
84654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // returns a 4.28 fixed-point
84754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return gglMulDivi(1LU<<28, a, b);
84854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
84954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
85054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid clip_triangle(ogles_context_t* c,
85154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
85254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
85354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    uint32_t all_cc = (v0->flags | v1->flags | v2->flags) & vertex_t::CLIP_ALL;
85454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
85554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    vertex_t *p0, *p1, *p2;
85654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int MAX_CLIPPING_PLANES = 6 + OGLES_MAX_CLIP_PLANES;
85754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const int MAX_VERTICES = 3;
85854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
85954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // Temporary buffer to hold the new vertices. Each plane can add up to
86054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // two new vertices (because the polygon is convex).
86154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // We need one extra element, to handle an overflow case when
86254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the polygon degenerates into something non convex.
86354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    vertex_t buffer[MAX_CLIPPING_PLANES * 2 + 1];   // ~3KB
86454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    vertex_t* buf = buffer;
86554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
86654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // original list of vertices (polygon to clip, in fact this
86754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // function works with an arbitrary polygon).
86854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    vertex_t* in[3] = { v0, v1, v2 };
86954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
87054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // output lists (we need 2, which we use back and forth)
87154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // (maximum outpout list's size is MAX_CLIPPING_PLANES + MAX_VERTICES)
87254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // 2 more elements for overflow when non convex polygons.
87354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    vertex_t* out[2][MAX_CLIPPING_PLANES + MAX_VERTICES + 2];
87454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    unsigned int outi = 0;
87554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
87654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // current input list
87754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    vertex_t** ivl = in;
87854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
87954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // 3 input vertices, 0 in the output list, first plane
88054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    unsigned int ic = 3;
88154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
88254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // User clip-planes first, the clipping is always done in eye-coordinate
88354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // this is basically the same algorithm than for the view-volume
88454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // clipping, except for the computation of the distance (vertex, plane)
88554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // and the fact that we need to compute the eye-coordinates of each
88654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // new vertex we create.
88754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
88854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_unlikely(all_cc & vertex_t::USER_CLIP_ALL))
88954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    {
89054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        unsigned int plane = 0;
89154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        uint32_t cc = (all_cc & vertex_t::USER_CLIP_ALL) >> 8;
89254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        do {
89354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (cc & 1) {
89454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // pointers to our output list (head and current)
89554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                vertex_t** const ovl = &out[outi][0];
89654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                vertex_t** output = ovl;
89754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                unsigned int oc = 0;
89854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                unsigned int sentinel = 0;
899f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                // previous vertex, compute distance to the plane
90054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                vertex_t* s = ivl[ic-1];
90154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                const vec4_t& equation = c->clipPlanes.plane[plane].equation;
90254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                GLfixed sd = dot4(equation.v, s->eye.v);
903f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                // clip each vertex against this plane...
90454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                for (unsigned int i=0 ; i<ic ; i++) {
90554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    vertex_t* p = ivl[i];
90654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    const GLfixed pd = dot4(equation.v, p->eye.v);
90754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    if (sd >= 0) {
90854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (pd >= 0) {
90954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            // both inside
91054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            *output++ = p;
91154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            oc++;
91254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        } else {
91354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            // s inside, p outside (exiting)
91454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            const GLfixed t = clipDivide(sd, sd-pd);
91554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            c->arrays.clipEye(c, buf, t, p, s);
91654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            *output++ = buf++;
91754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            oc++;
91854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            if (++sentinel >= 3)
91954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                return; // non-convex polygon!
92054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
92154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    } else {
92254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (pd >= 0) {
92354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            // s outside (entering)
92454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            if (pd) {
92554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                const GLfixed t = clipDivide(pd, pd-sd);
92654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                c->arrays.clipEye(c, buf, t, s, p);
92754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                *output++ = buf++;
92854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                oc++;
92954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                if (++sentinel >= 3)
93054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                    return; // non-convex polygon!
93154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            }
93254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            *output++ = p;
93354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            oc++;
93454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        } else {
93554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                           // both outside
93654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
93754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
93854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    s = p;
93954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    sd = pd;
94054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
94154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // output list become the new input list
94254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (oc<3)
94354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    return; // less than 3 vertices left? we're done!
94454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                ivl = ovl;
94554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                ic = oc;
94654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                outi = 1-outi;
94754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
94854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            cc >>= 1;
94954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            plane++;
95054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } while (cc);
95154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
95254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
95354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // frustum clip-planes
95454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (all_cc & vertex_t::FRUSTUM_CLIP_ALL)
95554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    {
95654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        unsigned int plane = 0;
95754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        uint32_t cc = all_cc & vertex_t::FRUSTUM_CLIP_ALL;
95854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        do {
95954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (cc & 1) {
96054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // pointers to our output list (head and current)
96154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                vertex_t** const ovl = &out[outi][0];
96254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                vertex_t** output = ovl;
96354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                unsigned int oc = 0;
96454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                unsigned int sentinel = 0;
965f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                // previous vertex, compute distance to the plane
96654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                vertex_t* s = ivl[ic-1];
96754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                GLfixed sd = frustumPlaneDist(plane, s->clip);
968f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                // clip each vertex against this plane...
96954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                for (unsigned int i=0 ; i<ic ; i++) {
97054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    vertex_t* p = ivl[i];
97154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    const GLfixed pd = frustumPlaneDist(plane, p->clip);
97254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    if (sd >= 0) {
97354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (pd >= 0) {
97454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            // both inside
97554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            *output++ = p;
97654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            oc++;
97754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        } else {
97854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            // s inside, p outside (exiting)
97954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            const GLfixed t = clipDivide(sd, sd-pd);
98054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            c->arrays.clipVertex(c, buf, t, p, s);
98154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            *output++ = buf++;
98254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            oc++;
98354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            if (++sentinel >= 3)
98454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                return; // non-convex polygon!
98554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
98654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    } else {
98754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (pd >= 0) {
98854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            // s outside (entering)
98954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            if (pd) {
99054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                const GLfixed t = clipDivide(pd, pd-sd);
99154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                c->arrays.clipVertex(c, buf, t, s, p);
99254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                *output++ = buf++;
99354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                oc++;
99454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                if (++sentinel >= 3)
99554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                    return; // non-convex polygon!
99654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            }
99754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            *output++ = p;
99854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            oc++;
99954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        } else {
100054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                           // both outside
100154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
100254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
100354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    s = p;
100454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    sd = pd;
100554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
100654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // output list become the new input list
100754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (oc<3)
100854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    return; // less than 3 vertices left? we're done!
100954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                ivl = ovl;
101054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                ic = oc;
101154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                outi = 1-outi;
101254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
101354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            cc >>= 1;
101454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            plane++;
101554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } while (cc);
101654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
101754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
101854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // finally we can render our triangles...
101954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    p0 = ivl[0];
102054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    p1 = ivl[1];
102154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    for (unsigned int i=2 ; i<ic ; i++) {
102254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        p2 = ivl[i];
102354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->lerp.initTriangle(p0, p1, p2);
102454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (cull_triangle(c, p0, p1, p2)) {
102554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            p1 = p2;
102654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            continue; // culled!
102754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
102854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        triangle(c, p0, p1, p2);
102954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        p1 = p2;
103054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
103154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
103254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
103354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectunsigned int clip_line(ogles_context_t* c, vertex_t* s, vertex_t* p)
103454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
103554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const uint32_t all_cc = (s->flags | p->flags) & vertex_t::CLIP_ALL;
103654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
103754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (ggl_unlikely(all_cc & vertex_t::USER_CLIP_ALL))
103854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    {
103954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        unsigned int plane = 0;
104054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        uint32_t cc = (all_cc & vertex_t::USER_CLIP_ALL) >> 8;
104154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        do {
104254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (cc & 1) {
104354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                const vec4_t& equation = c->clipPlanes.plane[plane].equation;
104454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                const GLfixed sd = dot4(equation.v, s->eye.v);
104554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                const GLfixed pd = dot4(equation.v, p->eye.v);
104654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (sd >= 0) {
104754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    if (pd >= 0) {
104854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        // both inside
104954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    } else {
105054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        // s inside, p outside (exiting)
105154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        const GLfixed t = clipDivide(sd, sd-pd);
105254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        c->arrays.clipEye(c, p, t, p, s);
105354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
105454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } else {
105554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    if (pd >= 0) {
105654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        // s outside (entering)
105754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (pd) {
105854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            const GLfixed t = clipDivide(pd, pd-sd);
105954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            c->arrays.clipEye(c, s, t, s, p);
106054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
106154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    } else {
106254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                       // both outside
106354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                       return 0;
106454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
106554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
106654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
106754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            cc >>= 1;
106854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            plane++;
106954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } while (cc);
107054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
107154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
107254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // frustum clip-planes
107354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (all_cc & vertex_t::FRUSTUM_CLIP_ALL)
107454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    {
107554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        unsigned int plane = 0;
107654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        uint32_t cc = all_cc & vertex_t::FRUSTUM_CLIP_ALL;
107754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        do {
107854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (cc & 1) {
107954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                const GLfixed sd = frustumPlaneDist(plane, s->clip);
108054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                const GLfixed pd = frustumPlaneDist(plane, p->clip);
108154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (sd >= 0) {
108254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    if (pd >= 0) {
108354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        // both inside
108454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    } else {
108554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        // s inside, p outside (exiting)
108654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        const GLfixed t = clipDivide(sd, sd-pd);
108754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        c->arrays.clipVertex(c, p, t, p, s);
108854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
108954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } else {
109054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    if (pd >= 0) {
109154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        // s outside (entering)
109254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (pd) {
109354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            const GLfixed t = clipDivide(pd, pd-sd);
109454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            c->arrays.clipVertex(c, s, t, s, p);
109554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
109654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    } else {
109754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                       // both outside
109854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                       return 0;
109954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
110054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
110154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
110254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            cc >>= 1;
110354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            plane++;
110454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } while (cc);
110554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
110654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
110754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return 2;
110854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
110954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
111054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
111154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}; // namespace android
1112