Repository navigation
Expand file tree
/
Copy pathbasic.tjs
More file actions
162 lines (143 loc) · 6.23 KB
/
Copy pathbasic.tjs
File metadata and controls
162 lines (143 loc) · 6.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/**
* threepp 基本描画スモークテスト (VRM 抜き)
*
* 目的: GLES 描画パイプライン(GLRenderer→adaptor.capture→dest レイヤ)が
* 実際にピクセルを出せるかを、最小構成の回転キューブで確認する。
* まず MeshBasicMaterial(unlit=ライト非依存) の赤いキューブで「何か映るか」を見る。
*
* -shot=out … 60 フレーム後に out.png を保存して終了 (自動確認用)
* -lit … MeshStandardMaterial + ライトに切り替える (ライティング確認用)
*/
Plugins.link("krkrgles.dll");
Plugins.link("../build/x64-windows/Release/krkrthreepp.dll");
var SCREEN_W = 800;
var SCREEN_H = 800;
class BasicViewer extends Window
{
var adaptor, renderer, scene, camera, mesh;
var back, dest, timer, shotName, frameCount = 0;
function BasicViewer()
{
super.Window();
caption = "threepp basic smoke";
setInnerSize(SCREEN_W, SCREEN_H);
// 背景 (暗い単色。3D が乗れば分かる)
back = new Layer(this, null);
back.setImageSize(SCREEN_W, SCREEN_H);
back.setSize(SCREEN_W, SCREEN_H);
back.fillRect(0, 0, SCREEN_W, SCREEN_H, 0xff102030);
back.visible = true;
add(back);
// 3D 描画結果 (α 非保持のため加算合成)
dest = new Layer(this, back);
dest.setImageSize(SCREEN_W, SCREEN_H);
dest.setSize(SCREEN_W, SCREEN_H);
dest.type = ltAlpha; // 3D結果(α込み)を背景へ通常アルファ合成
dest.visible = true;
add(dest);
// GLES コンテキスト
adaptor = new GLESAdaptor(this);
adaptor.setScreenSize(SCREEN_W, SCREEN_H);
adaptor.unpremultiply = true; // MSAA の premultiplied 縁を straight-alpha へ戻す
adaptor.makeCurrent();
renderer = new Threepp.GLRenderer(adaptor, SCREEN_W, SCREEN_H);
// -clear: クリアカラーを不透明の明色にして「読み戻し自体が効くか」を切り分ける。
// (画面全体が水色になれば clear+readback は動作 → 問題は geometry 描画側)
if (System.getArgument("-clear") !== void)
renderer.setClearColor(0x0060c0, 1.0);
else
renderer.setClearColor(0x000000, 0.0);
Debug.message("GLRenderer constructed OK");
scene = new Threepp.Scene();
camera = new Threepp.PerspectiveCamera(50, SCREEN_W / SCREEN_H, 0.1, 100);
camera.setPosition(0, 0, 3); // +Z 側からキューブを見る
camera.lookAt(0, 0, 0);
// キューブ
var geom = new Threepp.BoxGeometry(1, 1, 1);
var mat;
if (System.getArgument("-tex") !== void) {
// テクスチャ確認: Layer にチェッカーボードを描いて threepp テクスチャ化。
// (プライマリレイヤ(parent=null)は LayerManager を作り invalidate 時に
// 競合するため、既存レイヤの子として作る)
var texLayer = new Layer(this, back);
texLayer.setImageSize(64, 64);
texLayer.setSize(64, 64);
texLayer.visible = false;
for (var ty = 0; ty < 8; ty++)
for (var tx = 0; tx < 8; tx++) {
var c = (((tx + ty) & 1) != 0) ? 0xffff8020 : 0xff2050ff;
texLayer.fillRect(tx * 8, ty * 8, 8, 8, c);
}
var tex = textureFromLayer(texLayer);
mat = new Threepp.MeshBasicMaterial();
mat.color = 0xffffff; // 白 = テクスチャ色をそのまま出す
mat.setMap(tex);
invalidate texLayer; // 画素はテクスチャへコピー済み
Debug.message("tex mode: textured cube tex=" + (tex !== void));
} else if (System.getArgument("-lit") !== void) {
mat = new Threepp.MeshStandardMaterial();
mat.color = 0xff3030;
// ライト
var dir = new Threepp.DirectionalLight(0xffffff, 1.0);
dir.setPosition(2, 3, 4);
scene.add(dir);
var amb = new Threepp.AmbientLight(0xffffff, 0.4);
scene.add(amb);
Debug.message("lit mode: MeshStandardMaterial + lights");
} else {
mat = new Threepp.MeshBasicMaterial();
mat.color = 0xff3030; // 赤 (unlit なので常に見えるはず)
Debug.message("unlit mode: MeshBasicMaterial");
}
mesh = new Threepp.Mesh(geom, mat);
scene.add(mesh);
Debug.message("cube added: geom=" + (geom !== void) + " mat=" + (mat !== void) + " mesh=" + (mesh !== void));
shotName = System.getArgument("-shot");
if (shotName !== void) shotName += ".png";
timer = new Timer(this, "onFrame");
timer.interval = 16;
timer.enabled = true;
add(timer);
}
function onFrame()
{
if (mesh !== void) { mesh.rotateY(0.02); mesh.rotateX(0.01); }
adaptor.capture(dest, onRender, this, 0x00000000);
dest.update();
frameCount++;
if (shotName !== void && frameCount >= 60) {
timer.enabled = false;
saveShot(shotName);
System.exit(0);
}
}
function onRender(w, h, self)
{
if (self.frameCount <= 2) Debug.message("onRender called: w=" + w + " h=" + h);
self.renderer.onBeginScene(w, h);
self.renderer.render(self.scene, self.camera);
self.renderer.onEndScene();
}
function saveShot(name)
{
var shot = new Layer(this, back);
shot.visible = false;
shot.setImageSize(SCREEN_W, SCREEN_H);
shot.setSize(SCREEN_W, SCREEN_H);
shot.copyRect(0, 0, back, 0, 0, SCREEN_W, SCREEN_H);
shot.operateRect(0, 0, dest, 0, 0, SCREEN_W, SCREEN_H, omAdditive);
shot.saveLayerImage(name, "png24");
invalidate shot;
Debug.message("saved: " + name);
}
function finalize()
{
if (timer !== void) timer.enabled = false;
invalidate mesh if mesh !== void;
invalidate renderer if renderer !== void;
invalidate adaptor if adaptor !== void;
super.finalize(...);
}
}
var win = new BasicViewer();
win.visible = true;