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