teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

5

コメントの修正しました。

2019/11/04 22:34

投稿

littlestream
littlestream

スコア37

answer CHANGED
@@ -176,7 +176,7 @@
176
176
  {
177
177
  j=0;
178
178
  //以下の内容が通用しないのでテキストエディタ(最悪Windowsのメモ帳でも可)
179
- //で空白を,(カンマ)に換する必要がある、
179
+ //で空白を,(カンマ)に換する必要がある、
180
180
 
181
181
  //while(FileStr[i][j])
182
182
  {

4

ソースの問題点を変更したのと画像を変えました。

2019/11/04 22:34

投稿

littlestream
littlestream

スコア37

answer CHANGED
@@ -1,7 +1,6 @@
1
1
  ~~自己解決しました。一応、WndProc関数を貼っておきます。~~
2
+ ![イメージ説明](6f4536cc4b8dc5e6c0a034227abc817a.png)
2
3
 
3
- ![イメージ説明](6e7251752cca68668f9fa9b0d5af57da.png)
4
-
5
4
  ```c/c++
6
5
  int min_[HEIGHT];
7
6
  int max_[HEIGHT];
@@ -399,14 +398,10 @@
399
398
 
400
399
  for(int i=0;i<MAXVTX;i++)
401
400
  {
402
- //全ての頂点毎に、全ての面の頂点座標と比較して、
403
- if(vvv[i].count>0)
404
- {
405
- Normalize(&vvv[i]);
401
+ Normalize(&vvv[i]);
406
- //vvv[i].x/=vvv[i].count ;
402
+ //vvv[i].x/=vvv[i].count ;
407
- //vvv[i].y/=vvv[i].count ;
403
+ //vvv[i].y/=vvv[i].count ;
408
- //vvv[i].z/=vvv[i].count ;
404
+ //vvv[i].z/=vvv[i].count ;
409
- }
410
405
  }
411
406
  //頂点ベクトルは求まった(はず...)から、頂点カラーを面にある全ての頂点で求める
412
407
 

3

ソースを大幅に増やしました。

2019/11/04 20:27

投稿

littlestream
littlestream

スコア37

answer CHANGED
@@ -3,7 +3,69 @@
3
3
  ![イメージ説明](6e7251752cca68668f9fa9b0d5af57da.png)
4
4
 
5
5
  ```c/c++
6
+ int min_[HEIGHT];
7
+ int max_[HEIGHT];
8
+ typedef struct VTX{
9
+ double x,y,z;
10
+ int count;
11
+ int R,G,B;
12
+ }VTX;
6
13
 
14
+ typedef struct XYZ{
15
+ double x;
16
+ double y;
17
+ double z;
18
+ int count;
19
+ }XYZ;
20
+ typedef struct XY{
21
+ double x;
22
+ double y;
23
+ }XY;
24
+
25
+ #define RAD (3.14159265/180)
26
+ #define MAX_XYZ 1000
27
+
28
+ XYZ Pnt[MAX_XYZ];
29
+ XY Pnt2[MAX_XYZ];
30
+ int Poly[1000][4];
31
+ double vpx=1.0f,vpy=1.0f,vpz=-800.0f;
32
+ double D=624;
33
+
34
+ void Projection2DAxisFrom3DAxis(HWND hwnd)
35
+ {
36
+ HDC hdc = GetDC(hwnd);
37
+
38
+ for(int i=0;i<MAXVTX;i++)
39
+ {
40
+ Pnt2[i].x=(Pnt[i].x*D)/(Pnt[i].z-vpz)+160.0f;
41
+ Pnt2[i].y=-(Pnt[i].y*D)/(Pnt[i].z-vpz)+120.0f;
42
+ //PSET(Pnt2[i].x,Pnt2[i].y,0x00ff0000);
43
+ //char str[100];
44
+ //sprintf(str,"%d",i);
45
+ //TextOut(hdc,Pnt2[i].x,Pnt2[i].y,str,strlen(str));
46
+ }
47
+ }
48
+ void SetPoly(int num,int n1,int n2,int n3)
49
+ {
50
+ Poly[num][0]=n1;//頂点番号を指定
51
+ Poly[num][1]=n2;
52
+ Poly[num][2]=n3;
53
+ }
54
+ void SetXYZ(int num,double x,double y,double z)
55
+ {
56
+ if(num<0 || num>=MAX_XYZ) return;
57
+ Pnt[num].x=x;//頂点座標を指定
58
+ Pnt[num].y=y;
59
+ Pnt[num].z=z;
60
+ }
61
+ void PSET(int x,int y,int col)
62
+ {
63
+ //点を打つ
64
+ if(x<0 || x>=WIDTH-2) return;
65
+ if(y<0 || y>=HEIGHT-2) return;
66
+
67
+ lpPixel[x+(y*WIDTH)]=col;
68
+ }
7
69
  inline void LINE2COL(int x1,int y1,int x2,int y2,int COL,int COL2)
8
70
  {
9
71
  //線を描くのと左か右かを判断する関数

2

ソースを更新しましたがこれ以上入るのでしょうか?

2019/11/04 20:03

投稿

littlestream
littlestream

スコア37

answer CHANGED
@@ -1,8 +1,215 @@
1
- 自己解決しました。一応、WndProc関数を貼っておきます。
1
+ ~~自己解決しました。一応、WndProc関数を貼っておきます。~~
2
2
 
3
3
  ![イメージ説明](6e7251752cca68668f9fa9b0d5af57da.png)
4
4
 
5
5
  ```c/c++
6
+
7
+ inline void LINE2COL(int x1,int y1,int x2,int y2,int COL,int COL2)
8
+ {
9
+ //線を描くのと左か右かを判断する関数
10
+ int NewX,NewY;
11
+
12
+ for(int j=0;j<1024;j++)
13
+ {
14
+ NewX=x1*(1024-j)+x2*j>>10;
15
+ NewY=y1*(1024-j)+y2*j>>10;
16
+
17
+ int R1,R2,G1,G2,B1,B2;
18
+
19
+ R1=(COL>>16) & 0xFF;
20
+ G1=(COL>>8) & 0xFF;
21
+ B1=(COL) & 0xFF;
22
+
23
+ R2=(COL2>>16) & 0xFF;
24
+ G2=(COL2>>8) & 0xFF;
25
+ B2=(COL2) & 0xFF;
26
+
27
+
28
+ int R=R1*(1024-j)+R2*j>>10;
29
+ int G=G1*(1024-j)+G2*j>>10;
30
+ int B=B1*(1024-j)+B2*j>>10;
31
+
32
+ PSET(NewX,NewY,RGB(R,G,B));
33
+
34
+ if(min_[(int)NewY]>NewX){
35
+ min_[(int)NewY]=NewX;
36
+ cmin[(int)NewY]=RGB(R,G,B);
37
+ }
38
+ if(max_[(int)NewY]<NewX){
39
+ max_[(int)NewY]=NewX;
40
+ cmax[(int)NewY]=RGB(R,G,B);
41
+ }
42
+
43
+ }
44
+ }
45
+
46
+ int min_Y(int y1,int y2,int y3)
47
+ {
48
+ if(y1<y2 && y1<y3) return y1;
49
+ if(y2<y1 && y2<y3) return y2;
50
+ if(y3<y1 && y3<y2) return y3;
51
+ }
52
+
53
+ int max_Y(int y1,int y2,int y3)
54
+ {
55
+ if(y1>y2 && y1>y3) return y1;
56
+ if(y2>y1 && y2>y3) return y2;
57
+ if(y3>y1 && y3>y2) return y3;
58
+ }
59
+
60
+ inline void GouraudShade(int x1,int y1,int x2,int y2,int x3,int y3,int C1,int C2,int C3)
61
+ {
62
+
63
+ //入れ忘れ(笑)
64
+ for(int i=0;i<SCREENHEIGHT;i++)
65
+ {
66
+ min_[i]=65816;
67
+ max_[i]=-65816;
68
+ cmin[i]=RGB(0,0,0);
69
+ cmax[i]=RGB(0,0,0);
70
+ }
71
+
72
+ LINE2COL(x1,y1,x2,y2,C1,C2);
73
+ LINE2COL(x2,y2,x3,y3,C2,C3);
74
+ LINE2COL(x1,y1,x3,y3,C1,C3);
75
+
76
+ for(int Y=min_Y(y1,y2,y3);Y<max_Y(y1,y2,y3);Y++)
77
+ {
78
+ int R1=(cmin[Y]>>16) & 0xFF;
79
+ int G1=(cmin[Y]>>8) & 0xFF;
80
+ int B1=(cmin[Y]) & 0xFF;
81
+
82
+ int R2=(cmax[Y]>>16) & 0xFF;
83
+ int G2=(cmax[Y]>>8) & 0xFF;
84
+ int B2=(cmax[Y]) & 0xFF;
85
+
86
+ LINE2COL(min_[Y],Y,max_[Y],Y,RGB(R1,G1,B1),RGB(R2,G2,B2));
87
+
88
+ }
89
+
90
+ }
91
+
92
+ void LoadOBJFile(char filename[10000],HWND hwnd)
93
+ {
94
+
95
+ static int flag=0;
96
+ FILE *fp;
97
+ fp=fopen(filename,"r");
98
+ if(fp==NULL)
99
+ {
100
+ MessageBox(NULL,"ファイルがありません。","OK?",MB_OK);
101
+ SelectObject(hdcBMP, hBMPOLD);
102
+
103
+ DeleteObject(hdcBMP);
104
+ DeleteObject(hBMP);
105
+
106
+ PostQuitMessage(0);
107
+
108
+ return;
109
+ }
110
+
111
+ int i=0;
112
+ int j=0;
113
+
114
+ while(fgets(FileStr[i],50,fp)!=NULL)
115
+ {
116
+ j=0;
117
+ //以下の内容が通用しないのでテキストエディタ(最悪Windowsのメモ帳でも可)
118
+ //で空白を,(カンマ)に変換する必要がある、
119
+
120
+ //while(FileStr[i][j])
121
+ {
122
+ // if(FileStr[i][j]==' ') FileStr[i][j]=',';
123
+ // ++j;
124
+ }
125
+ ++i;
126
+ }
127
+
128
+ LastLine=i;//最後の行数を保存する
129
+ char opecode[10000]={0};
130
+ double XF,YF,ZF;
131
+ int TriNum1,TriNum2,TriNum3;
132
+ int k=0;
133
+
134
+ for(int i=0;i<LastLine;i++)
135
+ {
136
+
137
+ opecode[0]=FileStr[i][0];
138
+ //CameraPos.D=535.0f;
139
+ //CameraPos.Z=-810.0f;
140
+
141
+ //PSET(400,300,GetColor(0,0,255));
142
+ if(opecode[0]=='v')
143
+ {
144
+ sscanf(FileStr[i],"%c,%lf,%lf,%lf",
145
+ opecode,&XF,&YF,&ZF);
146
+ SetXYZ(k,XF*SCALE,YF*SCALE,ZF*SCALE);
147
+ Projection2DAxisFrom3DAxis(hwnd);
148
+ //i=0;
149
+
150
+ ++k;
151
+ MAXVTX=k;
152
+ }
153
+
154
+
155
+ if(opecode[0]=='f')
156
+ {
157
+ sscanf(FileStr[i],"%c,%d,%d,%d",
158
+ opecode,&TriNum1,&TriNum2,&TriNum3);
159
+ if(flag==0)
160
+ {
161
+ j=0;
162
+ flag=1;
163
+ }
164
+
165
+ SetPoly(j,(int)TriNum1-1,(int)TriNum2-1,(int)TriNum3-1);
166
+
167
+ Projection2DAxisFrom3DAxis(hwnd);
168
+
169
+ ++j;
170
+ MAXPOL=j;
171
+
172
+ }
173
+
174
+
175
+ }
176
+
177
+ }
178
+
179
+ XYZ CalcCross(XYZ a,XYZ b,XYZ c)
180
+ {
181
+ XYZ d={0.0f};
182
+ XYZ a2,b2;
183
+
184
+ a2.x=a.x-b.x;
185
+ a2.y=a.y-b.y;
186
+ a2.z=a.z-b.z;
187
+
188
+ b2.x=a.x-c.x;
189
+ b2.y=a.y-c.y;
190
+ b2.z=a.z-c.z;
191
+
192
+ double len=sqrt(a2.x*a2.x+a2.y*a2.y+a2.z*a2.z);
193
+ a2.x/=len;
194
+ a2.y/=len;
195
+ a2.z/=len;
196
+
197
+ double len2=sqrt(b2.x*b2.x+b2.y*b2.y+b2.z*b2.z);
198
+ b2.x/=len2;
199
+ b2.y/=len2;
200
+ b2.z/=len2;
201
+
202
+
203
+ //23-32 31-13 12-21
204
+ //aY*bZ-aZ*bY aZ*bX-aX*bZ aX*bY-aY*bX
205
+ d.x=a2.y*b2.z-a2.z*b2.y;
206
+ d.y=a2.z*b2.x-a2.x*b2.z;
207
+ d.z=a2.x*b2.y-a2.y*b2.x;
208
+
209
+ return d;
210
+ }
211
+
212
+
6
213
  LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
7
214
 
8
215
 
@@ -107,7 +314,12 @@
107
314
  int i2=Poly[i][1];
108
315
  int i3=Poly[i][2];
109
316
 
110
- XYZ n=CalcNormal2(Pnt[i1],Pnt[i2],Pnt[i3]);
317
+ XYZ n=CalcCross(Pnt[i1],Pnt[i2],Pnt[i3]);
318
+ //外積を行った
319
+
320
+ Normalize(&n);
321
+ //正規化を行った
322
+
111
323
  vvv[i1].x+=n.x;
112
324
  vvv[i1].y+=n.y;
113
325
  vvv[i1].z+=n.z;
@@ -120,7 +332,12 @@
120
332
  vvv[i3].y+=n.y;
121
333
  vvv[i3].z+=n.z;
122
334
 
335
+
336
+ }
337
+
338
+ for(int i=0;i<MAXVTX;i++)
339
+ {
123
- //全ての頂点毎に、全ての面の頂点座標と比較して、
340
+ //全ての頂点毎に、全ての面の頂点座標と比較して、
124
341
  if(vvv[i].count>0)
125
342
  {
126
343
  Normalize(&vvv[i]);
@@ -129,7 +346,6 @@
129
346
  //vvv[i].z/=vvv[i].count ;
130
347
  }
131
348
  }
132
-
133
349
  //頂点ベクトルは求まった(はず...)から、頂点カラーを面にある全ての頂点で求める
134
350
 
135
351
  //XYZ vpx=200,vpy=-120,vpz=100;
@@ -142,7 +358,7 @@
142
358
  int i2=Poly[i][1];
143
359
  int i3=Poly[i][2];
144
360
 
145
- XYZ n=CalcNormal2(Pnt[i1],Pnt[i2],Pnt[i3]);
361
+ XYZ n=CalcCross(Pnt[i1],Pnt[i2],Pnt[i3]);
146
362
 
147
363
  XYZ light={100,-120,200};
148
364
  double lenlight=sqrt((double)light.x*light.x+light.y*light.y+light.z*light.z);
@@ -162,8 +378,10 @@
162
378
  double v3=vpz/(vv+0.01f);//
163
379
  double ViewCos;
164
380
 
381
+
165
382
  ViewCos=(v1*n.x+v2*n.y+v3*n.z);
166
383
  //視線ベクトルと面ごとの法線ベクトルの内積
384
+
167
385
  if(ViewCos<0)
168
386
  GouraudShade(Pnt2[Poly[i][0]].x,Pnt2[Poly[i][0]].y,
169
387
  Pnt2[Poly[i][1]].x,Pnt2[Poly[i][1]].y,
@@ -211,4 +429,5 @@
211
429
  return DefWindowProc(hwnd, iMsg, wParam, lParam);
212
430
 
213
431
  }
432
+
214
433
  ```

1

画像を貼りました。

2019/11/04 19:45

投稿

littlestream
littlestream

スコア37

answer CHANGED
@@ -1,5 +1,7 @@
1
1
  自己解決しました。一応、WndProc関数を貼っておきます。
2
2
 
3
+ ![イメージ説明](6e7251752cca68668f9fa9b0d5af57da.png)
4
+
3
5
  ```c/c++
4
6
  LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
5
7