Mercurial > hg > Game > Cerium
view Renderer/Engine/task/CreatePolygonFromSceneGraph.cc @ 2041:363b7c401c79 draft
Make Rendefing Engine
author | Shin,ichi Uehara |
---|---|
date | Mon, 23 Mar 2015 17:47:12 +0900 |
parents | 8587ee89ef79 |
children |
line wrap: on
line source
/** * SceneGraphを読み込んでpolygonの座標に変換行列を掛けて * 実座標のpolygonを生成する。 * * SceneGraph が増えてくると動かなくなるかもしれない。 * 一応 mainMem とかで動くようになるとは思うけど。 * だめだったら、そこら辺が怪しいと思うべき */ #include "CreatePolygonFromSceneGraph.h" #include "polygon_pack.h" #include "texture.h" #include "matrix_calc.h" #include "Func.h" #define STATUS_NUM 3 SchedDefineTask1(CreatePolygonFromSceneGraph,createPolygon); /** * ベクトルに行列を乗算する * @param[out] v vector (float[4]) * @param[in] m matrix (float[16]) */ /* static void ApplyMatrix(float *v, float *m) { float t[4]; t[0] = v[0]; t[1] = v[1]; t[2] = v[2]; t[3] = v[3]; for (int i = 0; i < 4; i++) { v[i] = t[0]*m[i] + t[1]*m[i+4] + t[2]*m[i+8] + t[3]*m[i+12]; } } */ static int compare_value(float *val, int num) { float max = 0; float min = 0; max = val[0]; min = val[0]; for (int i = 1; i < num; i++) { if (max < val[i]) { max = val[i]; } else if (min > val[i]) { min = val[i]; } } return (max - min); } /** * 輝度の計算 * @param[in] vertexs polygon vertex position * @param[in] normal normal vector * @param[in] light light object position * @return diffuse */ // test static float lighting(const float *vertex, const float *normal, const float *light) { float light_vector[4]; float normal_vector[4]; light_vector[0] = vertex[0] - light[0]; light_vector[1] = vertex[1] - light[1]; light_vector[2] = vertex[2] - light[2]; light_vector[3] = 0; normal_vector[0] = normal[0]; normal_vector[1] = normal[1]; normal_vector[2] = normal[2]; normal_vector[3] = 0; normalize(light_vector, light_vector); normalize(normal_vector, normal_vector); float diffuse = innerProduct(light_vector, normal_vector); if ( diffuse < 0 ) { diffuse = 0; } return diffuse; } static int createPolygon(SchedTask *smanager, void *rbuf, void *wbuf) { float xyz1[4], xyz2[4], xyz3[4]; float normal1[4],normal2[4],normal3[4]; //pp, matrix, を受け取る PolygonPackPtr in_pp = (PolygonPackPtr)smanager->get_input(rbuf, 0); // w = world, v = view, p = perspective float *wvp_matrix = (float*)smanager->get_input(rbuf, 1); float *m_screen = (float*)smanager->get_input(rbuf, 2); float normal_matrix[16]; for (int i = 0; i<16; i++) normal_matrix[i] = wvp_matrix[i]; normal_matrix[4*0+3] = normal_matrix[4*1+3] = normal_matrix[4*2+3] = 0; normal_matrix[4*3] = normal_matrix[4*3+1] = normal_matrix[4*3+2] = 0; normal_matrix[4*3+3] = 1; float matrix[16]; // wvps matrix matrix4x4(matrix, wvp_matrix, m_screen); texture_list *tritexinfo = (texture_list*)smanager->get_input(rbuf, 3); PolygonPackPtr next = (PolygonPackPtr)smanager->get_param(0); PolygonPackPtr out_pp = (PolygonPackPtr)smanager->get_output(wbuf, 0); out_pp->info.size = in_pp->info.size; out_pp->next = next; if (in_pp->info.size == 0) { printf("in_pp->info.size = 0\n"); } float *light_xyz = (float*)smanager->global_get(LightData); int *light_switch = (int*)smanager->global_get(LightSwitch); int light_num = 4; // test for (int i = 0; i < in_pp->info.size; i++) { float diffuse1 = 0; float diffuse2 = 0; float diffuse3 = 0; TrianglePack tri = in_pp->tri[i]; xyz1[0] = tri.ver1.x; xyz1[1] = tri.ver1.y; xyz1[2] = tri.ver1.z * -1.0f; xyz1[3] = 1.0f; xyz2[0] = tri.ver2.x; xyz2[1] = tri.ver2.y; xyz2[2] = tri.ver2.z * -1.0f; xyz2[3] = 1.0f; xyz3[0] = tri.ver3.x; xyz3[1] = tri.ver3.y; xyz3[2] = tri.ver3.z * -1.0f; xyz3[3] = 1.0f; normal1[0] = tri.normal1.x; normal1[1] = tri.normal1.y; normal1[2] = tri.normal1.z * -1.0f; //normal1[3] = 1.0f; normal1[3] = 0.0f; normal2[0] = tri.normal2.x; normal2[1] = tri.normal2.y; normal2[2] = tri.normal2.z * -1.0f; //normal2[3] = 1.0f; normal2[3] = 0.0f; normal3[0] = tri.normal3.x; normal3[1] = tri.normal3.y; normal3[2] = tri.normal3.z * -1.0f; //normal3[3] = 1.0f; normal3[3] = 0.0f; // matrix = ビュー座標変換行列*射影変換行列 ApplyMatrix(xyz1, matrix); ApplyMatrix(xyz2, matrix); ApplyMatrix(xyz3, matrix); ApplyMatrix(normal1, normal_matrix); ApplyMatrix(normal2, normal_matrix); ApplyMatrix(normal3, normal_matrix); // test for (int j = 0; j < light_num; j++) { // 光源のスイッチが入ってたら if (light_switch[j] == 1) { // 複数の光源の計算, 全部足し合わせてみる.. // rdb値は255を超えた値は、255にされるからここではいくら足してもいい diffuse1 += lighting(xyz1, normal1, &light_xyz[j*4]); diffuse2 += lighting(xyz2, normal2, &light_xyz[j*4]); diffuse3 += lighting(xyz3, normal3, &light_xyz[j*4]); } } // このif文は、視錐台カリングに変えられる. 違うやり方があるはず if (xyz1[2] > 100 && xyz2[2] > 100 && xyz3[2] > 100) { /* * 同次座標で除算、同次クリップ空間に変換する * */ xyz1[0] /= xyz1[3]; xyz1[1] /= xyz1[3]; xyz1[2] /= xyz1[3]; xyz2[0] /= xyz2[3]; xyz2[1] /= xyz2[3]; xyz2[2] /= xyz2[3]; xyz3[0] /= xyz3[3]; xyz3[1] /= xyz3[3]; xyz3[2] /= xyz3[3]; } else { // ここは0じゃなくて、ppに登録しなければいい。pp->info.size をデクリメントすればいいはず xyz1[0] = 0; xyz1[1] = 0; xyz1[2] = 0; xyz2[0] = 0; xyz2[1] = 0; xyz2[2] = 0; xyz3[0] = 0; xyz3[1] = 0; xyz3[2] = 0; } TrianglePackPtr triangle = &out_pp->tri[i]; triangle->ver1.x = xyz1[0]; triangle->ver1.y = xyz1[1]; triangle->ver1.z = xyz1[2]; triangle->ver1.tex_x = tri.ver1.tex_x; triangle->ver1.tex_y = tri.ver1.tex_y; // test triangle->ver1.diffuse = diffuse1; triangle->ver2.x = xyz2[0]; triangle->ver2.y = xyz2[1]; triangle->ver2.z = xyz2[2]; triangle->ver2.tex_x = tri.ver2.tex_x; triangle->ver2.tex_y = tri.ver2.tex_y; // test triangle->ver2.diffuse = diffuse2; triangle->ver3.x = xyz3[0]; triangle->ver3.y = xyz3[1]; triangle->ver3.z = xyz3[2]; triangle->ver3.tex_x = tri.ver3.tex_x; triangle->ver3.tex_y = tri.ver3.tex_y; // test triangle->ver3.diffuse = diffuse3; triangle->normal1.x = normal1[0]; triangle->normal1.y = normal1[1]; triangle->normal1.z = normal1[2]; triangle->normal2.x = normal2[0]; triangle->normal2.y = normal2[1]; triangle->normal2.z = normal2[2]; triangle->normal3.x = normal3[0]; triangle->normal3.y = normal3[1]; triangle->normal3.z = normal3[2]; triangle->tex_info.addr = tritexinfo->pixels; triangle->tex_info.width = tritexinfo->t_w; triangle->tex_info.height = tritexinfo->t_h; triangle->tex_info.scale_max = tritexinfo->scale_max; //spanの数を先に計算しておくと、CreateSpanの時に静的にoutputが割り振れる(Taskの内の dma load がなくせるよ) //polygonの高さが、spanの数と一緒になるはず。 float y[STATUS_NUM] = { xyz1[1], xyz2[1], xyz3[1] }; int span_num = 0; span_num = compare_value(y, STATUS_NUM); out_pp->info.span_num += span_num; } return 0; }