1+ #include " freertos/FreeRTOS.h"
2+ #include " freertos/task.h"
13#include " vector2.hpp"
24#include " vector3.hpp"
35#include " vector4.hpp"
@@ -28,7 +30,7 @@ extern "C"{
2830#define POINTNUM int (sizeof (pointvec)/sizeof(pointvec[0 ]))
2931#define WIRENUM int (sizeof (wireframe)/sizeof(wireframe[0 ]))
3032
31- #define MAXPROC_POLYNUM (POLYNUM* 3 / 5 )
33+ #define MAXPROC_POLYNUM (800 )
3234
3335vector3 pv[12 ][3 ];
3436
@@ -56,6 +58,22 @@ static __inline__ uint32_t xos_get_ccount(void)
5658#endif
5759}
5860
61+
62+ volatile enum vtaskstate{
63+ VTASK_WAIT,
64+ VTASK_VERTEX_CALCULATION,
65+ VTASK_POLY_GENERATE,
66+ VTASK_POLY_DRAW,
67+ } vtaskstate;
68+
69+ fvector4 obj_transed[POINTNUM];
70+ fvector4 poly_transed[POINTNUM];
71+ Matrix4 m;
72+
73+ extern " C" {
74+ void vTask (void *);
75+ };
76+
5977float loadPower (const fvector3 &light_pos,const fvector3 &light_n,const fvector4 obj[3 ]){
6078 fvector3 light_obj;
6179 fvector3 n;
@@ -75,9 +93,6 @@ float loadPower(const fvector3 &light_pos,const fvector3 &light_n,const fvector4
7593
7694const int SIZE_TEX = 256 ;
7795
78- fvector4 obj_transed[POINTNUM];
79- fvector4 poly_transed[POINTNUM];
80-
8196
8297#if ZSORT
8398// ソート用のデータの作成
@@ -93,29 +108,120 @@ uint16_t *drawbuff[2];
93108float *zlinebuf;
94109
95110
111+ uint8_t drawidx[POLYNUM];
112+ static
113+ texturetriangle *t[MAXPROC_POLYNUM];
114+
115+ int draw_y;
116+ fvector3 veye;
117+ int lastbuff = 0 ;
118+
119+ void vTask (void * prm){
120+ fvector4 vo[3 ];
121+ fvector4 v[3 ];
122+ fvector3 n;
123+
124+ while (1 ){
125+ switch (vtaskstate){
126+ case VTASK_WAIT:
127+ break ;
128+ case VTASK_VERTEX_CALCULATION:
129+ for (int j=POINTNUM/2 ;j<POINTNUM;j++){
130+ obj_transed[j] = fvector4 (pointvec[j].x ,pointvec[j].y ,pointvec[j].z );
131+ poly_transed[j] = m.applyit_v4 (fvector3 (pointvec[j]));
132+ poly_transed[j].x =poly_transed[j].x *window_width+window_width/2 ;poly_transed[j].y =poly_transed[j].y *window_height+window_height/2 ;
133+ }
134+ vtaskstate = VTASK_WAIT;
135+ break ;
136+ case VTASK_POLY_GENERATE:
137+ {
138+ int searchidx = MAXPROC_POLYNUM/2 ;
139+ for (int i=1 ;i<POLYNUM;i+=2 ){
140+ if (drawidx[i])continue ;
141+ for (int j=0 ;j<3 ;j++){
142+ v[j] = poly_transed[polyvec[i][j]];
143+ vo[j] = obj_transed[polyvec[i][j]];
144+ }
145+ if ((draw_y*DRAW_NLINES+DRAW_NLINES < v[0 ].y &&draw_y*DRAW_NLINES+DRAW_NLINES < v[1 ].y &&draw_y*DRAW_NLINES+DRAW_NLINES < v[2 ].y ))continue ;
146+ drawidx[i] = 1 ;
147+ if ((0 > v[0 ].x &&0 >v[1 ].x &&0 > v[2 ].x )||(window_width <= v[0 ].x &&window_width<=v[1 ].x &&window_width <= v[2 ].x ))continue ;
148+ // 簡易1次クリッピング
149+ if (v[0 ].w < 0 )continue ;
150+ if (v[2 ].w < 0 )continue ;
151+ if (v[1 ].w < 0 )continue ;
152+ // クリップ座標系からディスプレイ座標系の変換
153+ // v[0].x=v[0].x*window_width+window_width/2;v[0].y=v[0].y*window_height+window_height/2;
154+ // v[1].x=v[1].x*window_width+window_width/2;v[1].y=v[1].y*window_height+window_height/2;
155+ // v[2].x=v[2].x*window_width+window_width/2;v[2].y=v[2].y*window_height+window_height/2;
156+
157+ // 光量の計算
158+ float light = loadPower (fvector3 (),veye,vo);
159+ if (light>0 ){
160+ // テクスチャのデータ
161+ const texture_t tex={
162+ stonetex,vector2 (4 ,4 )
163+ };
164+ fvector2 puv[3 ];
165+ for (int j=0 ;j<3 ;j++){
166+ puv[j].x = (1 .f -point_uv[polyvec[i][j]].x )*SIZE_TEX;
167+ puv[j].y = (point_uv[polyvec[i][j]].y )*SIZE_TEX;
168+ }
169+ while (searchidx < MAXPROC_POLYNUM&&t[searchidx]->isexisting )searchidx++;
170+ if (searchidx == MAXPROC_POLYNUM){
171+ printf (" over flowed\n " );
172+ continue ;
173+ }
174+ if (t[searchidx]->triangle_set (v,light,&tex,puv)==-1 )t[searchidx]->isexisting = 0 ;
175+ }
176+ }
177+ vtaskstate = VTASK_WAIT;
178+ break ;
179+ }
180+
181+ case VTASK_POLY_DRAW:
182+ // case VTASK_DRAW:
183+ for (int i=1 ;i<MAXPROC_POLYNUM;i+=2 ){
184+ // #if ZSORT
185+ // if(t[draworder[i].draworder]->ymin < &&t[draworder[i].draworder]->ymax >= y){
186+ // t[draworder[i].draworder]->draw(zlinebuf,drawbuff[lastbuff],y*DRAW_NLINES);
187+ // }
188+ // #else
189+
190+ if (t[i]->isexisting // ymin < (y*DRAW_NLINES)+DRAW_NLINES&&t[i]->ymax >= y*DRAW_NLINES
191+ ){
192+ if (t[i]->draw (zlinebuf,drawbuff[lastbuff],draw_y*DRAW_NLINES)){
193+ t[i]->isexisting = 0 ;
194+ }
195+ }
196+ // #endif
197+ }
198+ vtaskstate = VTASK_WAIT;
199+ break ;
200+ }
201+ }
202+ }
203+
96204int main3d (void ){
97- Matrix4 m;
98205 Matrix4 projection;
99206 Matrix4 obj;
100- int lastbuff = 0 ;
207+
101208
102209 drawbuff[0 ] = new uint16_t [window_width*DRAW_NLINES];
103210 drawbuff[1 ] = new uint16_t [window_width*DRAW_NLINES];
104211 zlinebuf = new float [window_width*DRAW_NLINES];
105212
106- texturetriangle *t[MAXPROC_POLYNUM];
107213
108214 for (int i=0 ;i<MAXPROC_POLYNUM;i++){
109215 printf (" %d\n " ,i);
110216 fflush (stdout);
111217 t[i] = new texturetriangle;
218+ t[i]->isexisting = 0 ;
112219 }
113220
114221 // 透視投影行列
115222 projection=loadPerspective (0 .25f ,float (window_height)/window_width,0 .0001f ,3 .f ,0 ,0 )*projection;
116223
117224 fvector3 viewdir;
118- fvector3 veye;
119225 float dist = 3 .f ;
120226 vector2 mouse;
121227 vector2 pmouse;
@@ -136,7 +242,7 @@ int main3d(void){
136242 obj = obj*magnify (0.995 );
137243 while (1 ){
138244 {
139- esp_task_wdt_feed (); // if(hogec!=0)
245+ // esp_task_wdt_feed(); // if(hogec!=0)
140246 // send_aline_finish();
141247 if (1 ){
142248 if (prev){
@@ -166,76 +272,98 @@ int main3d(void){
166272#else
167273 m=projection*lookat (fvector3 (0 ,0 ,0 ),veye*dist)*obj*translation (fvector3 (0 ,0.3 ,-0.7 ));
168274#endif
275+
169276 // 頂点データを変換
170- for (int j=0 ;j<POINTNUM;j++){
277+ vtaskstate = VTASK_VERTEX_CALCULATION;
278+ for (int j=0 ;j<POINTNUM/2 ;j++){
171279 obj_transed[j] = fvector4 (pointvec[j].x ,pointvec[j].y ,pointvec[j].z );
172280 poly_transed[j] = m.applyit_v4 (fvector3 (pointvec[j]));
281+ poly_transed[j].x =poly_transed[j].x *window_width+window_width/2 ;poly_transed[j].y =poly_transed[j].y *window_height+window_height/2 ;
173282 // std::cout<<"poly"<<poly_transed[j].x<<","<<poly_transed[j].y<<","<<poly_transed[j].z<<std::endl;
174283 }
284+ while (vtaskstate == VTASK_VERTEX_CALCULATION);
175285 // ポリゴンデータの生成
176- for (int i=0 ;i<POLYNUM;i++){
177- for (int j=0 ;j<3 ;j++){
178- v[j] = poly_transed[polyvec[i][j]];
179- vo[j] = obj_transed[polyvec[i][j]];
180- }
181-
182- // 簡易1次クリッピング
183- if (v[0 ].w < 0 )continue ;
184- if (v[2 ].w < 0 )continue ;
185- if (v[1 ].w < 0 )continue ;
186- if (!(
187- !((abs (v[0 ].x ) > 1 .f )||(abs (v[0 ].y ) > 1 .f )||(abs (v[0 ].z ) < 0 .f ))||
188- !((abs (v[1 ].x ) > 1 .f )||(abs (v[1 ].y ) > 1 .f )||(abs (v[1 ].z ) < 0 .f ))||
189- !((abs (v[2 ].x ) > 1 .f )||(abs (v[2 ].y ) > 1 .f )||(abs (v[2 ].z ) < 0 .f ))))
190- continue ;
191- // クリップ座標系からディスプレイ座標系の変換
192- v[0 ].x =v[0 ].x *window_width+window_width/2 ;v[0 ].y =v[0 ].y *window_height+window_height/2 ;
193- v[1 ].x =v[1 ].x *window_width+window_width/2 ;v[1 ].y =v[1 ].y *window_height+window_height/2 ;
194- v[2 ].x =v[2 ].x *window_width+window_width/2 ;v[2 ].y =v[2 ].y *window_height+window_height/2 ;
195-
196- // テクスチャのデータ
197- const texture_t tex={
198- stonetex,vector2 (4 ,4 )
199- };
200- fvector2 puv[3 ];
201- for (int j=0 ;j<3 ;j++){
202- puv[j].x = (1 .f -point_uv[polyvec[i][j]].x )*SIZE_TEX;
203- puv[j].y = (point_uv[polyvec[i][j]].y )*SIZE_TEX;
204- }
205- // 光量の計算
206- float light = loadPower (fvector3 (),veye,vo);
207- if (light>0 ){
208- if (t[tnum++]->triangle_set (v,light,&tex,puv)==-1 )tnum--;
209- }
210- }
211286
212- #if ZSORT
213- for (int i=0 ;i<tnum;i++){
214- draworder[i].draworder = i;
215- draworder[i].zdata = t[i]->pdz [0 ]*65536 .;
216- }
217- std::sort (draworder,draworder+tnum, [](draworder_t & x, draworder_t & y){return x.zdata < y.zdata ;});
287+ // #if ZSORT
288+ // for(int i=0;i<tnum;i++){
289+ // draworder[i].draworder = i;
290+ // draworder[i].zdata = t[i]->pdz[0]*65536.;
291+ // }
292+ // std::sort(draworder,draworder+tnum, [](draworder_t& x, draworder_t& y){return x.zdata < y.zdata ;});
218293
219- #endif
294+ // #endif
295+ for (int i=0 ;i<MAXPROC_POLYNUM;i++){
296+ t[i]->isexisting = 0 ;
297+ }
298+ for (int i=0 ;i<POLYNUM;i++){
299+ drawidx[i] = 0 ;
300+ }
220301 // ラインごとに描画しLCDに転送
221- for (int y=0 ;y<window_height/DRAW_NLINES;y++){
302+ for (draw_y=0 ;draw_y<window_height/DRAW_NLINES;draw_y++){
303+ int searchidx = 0 ;
222304 for (int i=0 ;i<window_width*DRAW_NLINES;i++){
223305 zlinebuf[i]=1 .f ;
224306 drawbuff[lastbuff][i]=0x0020 ;/* RGB*/
225307 }
226- for (int i=0 ;i<tnum;i++){
227- #if ZSORT
228- if (t[draworder[i].draworder ]->ymin < y&&t[draworder[i].draworder ]->ymax >= y){
229- t[draworder[i].draworder ]->draw (zlinebuf,drawbuff[lastbuff],y*DRAW_NLINES);
230- }
231- #else
232308
233- if (t[i]->ymin < (y*DRAW_NLINES)+DRAW_NLINES&&t[i]->ymax >= y*DRAW_NLINES){
234- t[i]->draw (zlinebuf,drawbuff[lastbuff],y*DRAW_NLINES);
309+ vtaskstate = VTASK_POLY_GENERATE;
310+ for (int i=0 ;i<POLYNUM;i+=2 ){
311+ if (drawidx[i])continue ;
312+ for (int j=0 ;j<3 ;j++){
313+ v[j] = poly_transed[polyvec[i][j]];
314+ vo[j] = obj_transed[polyvec[i][j]];
235315 }
236- #endif
316+ if ((draw_y*DRAW_NLINES+DRAW_NLINES < v[0 ].y &&draw_y*DRAW_NLINES+DRAW_NLINES < v[1 ].y &&draw_y*DRAW_NLINES+DRAW_NLINES < v[2 ].y ))continue ;
317+ drawidx[i] = 1 ;
318+ if ((0 > v[0 ].x &&0 >v[1 ].x &&0 > v[2 ].x )||(window_width <= v[0 ].x &&window_width<=v[1 ].x &&window_width <= v[2 ].x ))continue ;
319+ // 簡易1次クリッピング
320+ if (v[0 ].w < 0 )continue ;
321+ if (v[2 ].w < 0 )continue ;
322+ if (v[1 ].w < 0 )continue ;
323+ // クリップ座標系からディスプレイ座標系の変換
324+ // v[0].x=v[0].x*window_width+window_width/2;v[0].y=v[0].y*window_height+window_height/2;
325+ // v[1].x=v[1].x*window_width+window_width/2;v[1].y=v[1].y*window_height+window_height/2;
326+ // v[2].x=v[2].x*window_width+window_width/2;v[2].y=v[2].y*window_height+window_height/2;
327+
328+ // 光量の計算
329+ float light = loadPower (fvector3 (),veye,vo);
330+ if (light>0 ){
331+ // テクスチャのデータ
332+ const texture_t tex={
333+ stonetex,vector2 (4 ,4 )
334+ };
335+ fvector2 puv[3 ];
336+ for (int j=0 ;j<3 ;j++){
337+ puv[j].x = (1 .f -point_uv[polyvec[i][j]].x )*SIZE_TEX;
338+ puv[j].y = (point_uv[polyvec[i][j]].y )*SIZE_TEX;
339+ }
340+ while (searchidx < MAXPROC_POLYNUM&&t[searchidx]->isexisting )searchidx++;
341+ if (searchidx == MAXPROC_POLYNUM){
342+ printf (" over flowed\n " );
343+ continue ;
344+ }
345+ if (t[searchidx]->triangle_set (v,light,&tex,puv)==-1 )t[searchidx]->isexisting = 0 ;
346+ }
347+ }
348+ while (vtaskstate == VTASK_POLY_GENERATE);
349+ vtaskstate = VTASK_POLY_DRAW;
350+ for (int i=0 ;i<MAXPROC_POLYNUM;i+=2 ){
351+ // #if ZSORT
352+ // if(t[draworder[i].draworder]->ymin < &&t[draworder[i].draworder]->ymax >= y){
353+ // t[draworder[i].draworder]->draw(zlinebuf,drawbuff[lastbuff],y*DRAW_NLINES);
354+ // }
355+ // #else
356+
357+ if (t[i]->isexisting // ymin < (y*DRAW_NLINES)+DRAW_NLINES&&t[i]->ymax >= y*DRAW_NLINES
358+ ){
359+ if (t[i]->draw (zlinebuf,drawbuff[lastbuff],draw_y*DRAW_NLINES)){
360+ t[i]->isexisting = 0 ;
361+ }
362+ }
363+ // #endif
237364 }
238- send_line (y*DRAW_NLINES,drawbuff[lastbuff]);
365+ while (vtaskstate == VTASK_POLY_DRAW);
366+ send_line (draw_y*DRAW_NLINES,drawbuff[lastbuff]);
239367 lastbuff = 1 -lastbuff;
240368 }
241369 }
0 commit comments