Compare commits
	
		
			14 Commits
		
	
	
		
			assignment
			...
			assignment
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 50a4f56e75 | |||
| c34d3f803f | |||
| 3b96b5008e | |||
| 9f0f8667ec | |||
| 58c761cb99 | |||
| 2d5f145c34 | |||
| 0931f3ce91 | |||
| 97606d398c | |||
| c30419899d | |||
| c1a5be6d90 | |||
| cf725c4c69 | |||
| d084ce8799 | |||
| 95275f9183 | |||
| 9124618ab6 | 
							
								
								
									
										176
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										176
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							| @@ -43,7 +43,7 @@ | |||||||
| *.udk lock | *.udk lock | ||||||
| *.upk lock | *.upk lock | ||||||
| # Anything in `/RawContent` dir | # Anything in `/RawContent` dir | ||||||
| /RowContent/**/* lfs | /RawContent/**/* lfs | ||||||
| # Common files | # Common files | ||||||
| *.3ds lock | *.3ds lock | ||||||
| *.3DS lock | *.3DS lock | ||||||
| @@ -167,6 +167,8 @@ | |||||||
| *.TAR lfs | *.TAR lfs | ||||||
| *.tar.gz lfs | *.tar.gz lfs | ||||||
| *.TAR.GZ lfs | *.TAR.GZ lfs | ||||||
|  | *.tga lfs | ||||||
|  | *.TGA lfs | ||||||
| *.tif lfs | *.tif lfs | ||||||
| *.TIF lfs | *.TIF lfs | ||||||
| *.tiff lfs | *.tiff lfs | ||||||
| @@ -210,175 +212,3 @@ | |||||||
| *.DYLIB lfs | *.DYLIB lfs | ||||||
| *.pdb lfs | *.pdb lfs | ||||||
| *.PDB lfs | *.PDB lfs | ||||||
| *.locres filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.locmeta filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.ico filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.uasset filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.umap filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.udk filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.upk filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.3DS filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.ABC filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.AEP filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.AFDESIGN filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.AFPHOTO filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.AI filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.AIF filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.AVI filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.BANK filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.BGEO filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.BIN filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.BLEND filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.BMP filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.BPOLY filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.C4D filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.DOC filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.DOCX filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.DWG filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.DXF filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.EXR filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.FBX filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.GEO filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.GI filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.GI2 filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.GIF filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.GLB filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.GLTF filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.HDR filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.HIP filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.HIPLC filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.HIPNC filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.JPEG filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.JPG filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.MA filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.MAX filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.MB filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.MOV filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.MP3 filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.MP4 filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.MPEG filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.MPG filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.OBJ filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PDF filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PFM filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PIC filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PMB filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PNG filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.POLY filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PPT filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PPTX filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PROFRAW filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PRPROJ filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PSB filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PSD filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.RAR filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.RAT filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.RIB filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.SKETCH filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.STL filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.TAR filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.TAR.GZ filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.TIF filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.TIFF filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.TMP filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.UEXP filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.USD filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.USDC filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.USDZ filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.VDB filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.VOX filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.WAV filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.XCF filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.XLS filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.XLSX filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.ZIP filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.3ds filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.abc filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.aep filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.afdesign filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.afphoto filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.ai filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.aif filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.avi filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.bank filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.bgeo filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.bin filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.blend filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.bmp filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.bpoly filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.c4d filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.doc filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.docx filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.dwg filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.dxf filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.exr filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.fbx filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.geo filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.gi filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.gi2 filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.gif filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.glb filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.gltf filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.hdr filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.hip filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.hiplc filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.hipnc filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.jpeg filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.jpg filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.ma filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.max filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.mb filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.mov filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.mp3 filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.mp4 filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.mpeg filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.mpg filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.obj filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.pdf filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.pfm filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.pic filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.pmb filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.png filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.poly filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.ppt filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.pptx filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.profraw filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.prproj filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.psb filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.psd filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.rar filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.rat filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.rib filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.sketch filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.stl filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.tar filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.tar.gz filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.tif filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.tiff filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.tmp filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.uexp filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.usd filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.usdc filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.usdz filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.vdb filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.vox filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.wav filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.xcf filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.xls filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.xlsx filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.zip filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.a filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.A filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.lib filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.LIB filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.exe filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.EXE filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.dll filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.DLL filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.so filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.SO filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.dylib filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.DYLIB filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.pdb filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.PDB filter=lfs diff=lfs merge=lfs -text |  | ||||||
| *.tga filter=lfs diff=lfs merge=lfs -text |  | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -90,5 +90,9 @@ Mkfile.old | |||||||
| dkms.conf | dkms.conf | ||||||
|  |  | ||||||
| # Build directory | # Build directory | ||||||
| Build/ | build/ | ||||||
| **/Build/ | **/build/ | ||||||
|  |  | ||||||
|  | # Asset directory | ||||||
|  | !data/ | ||||||
|  | !data/** | ||||||
|   | |||||||
| @@ -1,3 +1,3 @@ | |||||||
| # U-Tad: 3D Programming | # U-Tad - 3D Programming | ||||||
|  |  | ||||||
| "3D Programming" subject assignments from the U-Tad's Master Degree in Video Game Programming. | "3D Programming" subject assignments from the U-Tad's Master Degree in Video Game Programming. | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								data/models/box_stack.mtl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								data/models/box_stack.mtl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | # Blender MTL File: 'box_stack.blend' | ||||||
|  | # Material Count: 3 | ||||||
|  |  | ||||||
|  | newmtl mat_bot | ||||||
|  | Ns 96.078431 | ||||||
|  | Ka 0.000000 1.000000 1.000000 | ||||||
|  | Kd 0.640000 0.640000 0.640000 | ||||||
|  | Ks 0.500000 0.500000 0.500000 | ||||||
|  | Ke 0.000000 0.000000 0.000000 | ||||||
|  | Ni 1.000000 | ||||||
|  | d 1.000000 | ||||||
|  | illum 2 | ||||||
|  | map_Ka top.png | ||||||
|  |  | ||||||
|  | newmtl mat_mid | ||||||
|  | Ns 96.078431 | ||||||
|  | Ka 0.600000 0.600000 0.000000 | ||||||
|  | Kd 0.640000 0.640000 0.000000 | ||||||
|  | Ks 0.500000 0.500000 0.500000 | ||||||
|  | Ke 0.000000 0.000000 0.000000 | ||||||
|  | Ni 1.000000 | ||||||
|  | d 1.000000 | ||||||
|  | illum 2 | ||||||
|  | map_Ka front.png | ||||||
|  |  | ||||||
|  | newmtl mat_top | ||||||
|  | Ns 96.078431 | ||||||
|  | Ka 1.000000 0.000000 1.000000 | ||||||
|  | Kd 0.640000 0.640000 0.640000 | ||||||
|  | Ks 0.500000 0.500000 0.500000 | ||||||
|  | Ke 0.000000 0.000000 0.000000 | ||||||
|  | Ni 1.000000 | ||||||
|  | d 1.000000 | ||||||
|  | illum 2 | ||||||
|  | map_Ka top.png | ||||||
							
								
								
									
										
											BIN
										
									
								
								data/models/box_stack.obj
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/box_stack.obj
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/models/front.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/front.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										32
									
								
								data/models/gunslinger.mtl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								data/models/gunslinger.mtl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | # 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware | ||||||
|  | # File Created: 21.07.2015 23:00:44 | ||||||
|  |  | ||||||
|  | newmtl revolver | ||||||
|  | 	Ns 30.0000 | ||||||
|  | 	Ni 1.5000 | ||||||
|  | 	d 1.0000 | ||||||
|  | 	Tr 0.0000 | ||||||
|  | 	Tf 1.0000 1.0000 1.0000  | ||||||
|  | 	illum 2 | ||||||
|  | 	Ka 0.5500 0.5500 0.5500 | ||||||
|  | 	Kd 0.5500 0.5500 0.5500 | ||||||
|  | 	Ks 0.0000 0.0000 0.0000 | ||||||
|  | 	Ke 0.0000 0.0000 0.0000 | ||||||
|  | 	map_Ka revolver_dfs.tga | ||||||
|  | 	map_Kd revolver_dfs.tga | ||||||
|  | 	map_bump revolver_nrm.tga | ||||||
|  | 	bump revolver_nrm.tga | ||||||
|  |  | ||||||
|  | newmtl gunslinger | ||||||
|  | 	Ns 30.0000 | ||||||
|  | 	Ni 1.5000 | ||||||
|  | 	d 1.0000 | ||||||
|  | 	Tr 0.0000 | ||||||
|  | 	Tf 1.0000 1.0000 1.0000  | ||||||
|  | 	illum 2 | ||||||
|  | 	Ka 0.5500 0.5500 0.5500 | ||||||
|  | 	Kd 0.5500 0.5500 0.5500 | ||||||
|  | 	Ks 0.0000 0.0000 0.0000 | ||||||
|  | 	Ke 0.0000 0.0000 0.0000 | ||||||
|  | 	map_Ka gunslinger_dfs.tga | ||||||
|  | 	map_Kd gunslinger_dfs.tga | ||||||
							
								
								
									
										
											BIN
										
									
								
								data/models/gunslinger.obj
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/gunslinger.obj
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/models/gunslinger_dfs.bmp
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/gunslinger_dfs.bmp
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/models/gunslinger_dfs.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/gunslinger_dfs.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/models/gunslinger_nrm.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/gunslinger_nrm.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/models/gunslinger_spc.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/gunslinger_spc.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/models/revolver_dfs.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/revolver_dfs.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/models/revolver_nrm.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/revolver_nrm.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/models/revolver_spc.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/revolver_spc.tga
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/models/top.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/models/top.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,12 +1,68 @@ | |||||||
| uniform int useTexture; | uniform int useTexture; | ||||||
| uniform sampler2D texSampler; | uniform sampler2D texSampler; | ||||||
|  | uniform int numLights; | ||||||
|  | uniform vec4 materialColor; | ||||||
|  | uniform float shininess; | ||||||
|  | uniform vec3 ambientLight; | ||||||
|  |  | ||||||
|  | struct Light { | ||||||
|  | 	vec4 vector; | ||||||
|  | 	vec3 color; | ||||||
|  | 	float intensity; | ||||||
|  | 	float linear_att; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | uniform Light lights[10]; | ||||||
|  |  | ||||||
| varying vec3 fcolor; | varying vec3 fcolor; | ||||||
| varying vec2 ftexcoord; | varying vec2 ftexcoord; | ||||||
|  | varying vec3 fnormal; | ||||||
|  | varying vec4 fposition; | ||||||
|  |  | ||||||
| void main() { | void main() { | ||||||
|  | 	vec3 diffuseAccum = vec3(0.0, 0.0, 0.0); | ||||||
|  | 	vec3 specularAccum = vec3(0.0, 0.0, 0.0); | ||||||
|  |  | ||||||
|  | 	if (numLights > 0) { | ||||||
|  | 		diffuseAccum = ambientLight; | ||||||
|  |  | ||||||
|  | 		for (int i = 0; i < 10; i++) { | ||||||
|  | 			if (i >= numLights) break; | ||||||
|  |  | ||||||
|  | 			vec3 N = normalize(fnormal); | ||||||
|  | 			vec3 L = lights[i].vector.xyz; | ||||||
|  | 			float attenuation = 1.0; | ||||||
|  |  | ||||||
|  | 			if (lights[i].vector.w == 1.0) { | ||||||
|  | 				L = L - fposition.xyz; | ||||||
|  | 				float distance = length(L); | ||||||
|  | 				attenuation = 1.0 / (1.0 + lights[i].linear_att * distance); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			L = normalize(L); | ||||||
|  | 			float NdotL = max(dot(N, L), 0.0); | ||||||
|  |  | ||||||
|  | 			diffuseAccum += NdotL * lights[i].color * lights[i].intensity * attenuation; | ||||||
|  |  | ||||||
|  | 			if (shininess > 0.0 && NdotL > 0.0) { | ||||||
|  | 				vec3 V = normalize(-fposition.xyz); | ||||||
|  | 				vec3 H = normalize(L + V); | ||||||
|  | 				float NdotH = max(dot(N, H), 0.0); | ||||||
|  | 				specularAccum += pow(NdotH, shininess) * attenuation * lights[i].color * lights[i].intensity; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	vec4 fragmentColor; | ||||||
| 	if (useTexture == 1) { | 	if (useTexture == 1) { | ||||||
| 		gl_FragColor = texture2D(texSampler, ftexcoord); | 		fragmentColor = texture2D(texSampler, ftexcoord); | ||||||
| 	} else { | 	} else { | ||||||
| 		gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); | 		fragmentColor = materialColor; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (numLights > 0) { | ||||||
|  | 		gl_FragColor = vec4(fragmentColor.rgb * diffuseAccum + specularAccum, fragmentColor.a); | ||||||
|  | 	} else { | ||||||
|  | 		gl_FragColor = fragmentColor; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,12 +1,19 @@ | |||||||
| uniform mat4 mvp; | uniform mat4 mvp; | ||||||
|  | uniform mat4 modelView; | ||||||
|  | uniform mat4 normalMatrix; | ||||||
| attribute vec3 vpos; | attribute vec3 vpos; | ||||||
| attribute vec3 vcolor; | attribute vec3 vcolor; | ||||||
| attribute vec2 vtexcoord; | attribute vec2 vtexcoord; | ||||||
|  | attribute vec3 vnormal; | ||||||
| varying vec3 fcolor; | varying vec3 fcolor; | ||||||
| varying vec2 ftexcoord; | varying vec2 ftexcoord; | ||||||
|  | varying vec3 fnormal; | ||||||
|  | varying vec4 fposition; | ||||||
|  |  | ||||||
| void main() { | void main() { | ||||||
| 	gl_Position = mvp * vec4(vpos, 1); | 	gl_Position = mvp * vec4(vpos, 1); | ||||||
| 	fcolor = vcolor; | 	fcolor = vcolor; | ||||||
| 	ftexcoord = vtexcoord; | 	ftexcoord = vtexcoord; | ||||||
|  | 	fnormal = vec3(normalMatrix * vec4(vnormal, 0.0)); | ||||||
|  | 	fposition = modelView * vec4(vpos, 1); | ||||||
| } | } | ||||||
							
								
								
									
										2029
									
								
								lib/tiny_obj_loader.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2029
									
								
								lib/tiny_obj_loader.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -27,9 +27,8 @@ Buffer::Buffer(const std::vector<Vertex>&   vertices, | |||||||
| 	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), | 	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), | ||||||
| 		     indices.data(), GL_STATIC_DRAW); | 		     indices.data(), GL_STATIC_DRAW); | ||||||
|  |  | ||||||
| 	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), | 	// Note: Vertex attributes are set up by Shader::setup_attribs() during rendering | ||||||
| 			      nullptr); | 	// This allows the shader to dynamically query and set the correct attribute locations | ||||||
| 	glEnableVertexAttribArray(0); |  | ||||||
|  |  | ||||||
| 	Logger::info(sstr("Buffer created with ", vertices.size(), | 	Logger::info(sstr("Buffer created with ", vertices.size(), | ||||||
| 			  " vertices and ", indices.size(), " indices")); | 			  " vertices and ", indices.size(), " indices")); | ||||||
|   | |||||||
							
								
								
									
										167
									
								
								src/engine.cpp
									
									
									
									
									
								
							
							
						
						
									
										167
									
								
								src/engine.cpp
									
									
									
									
									
								
							| @@ -9,6 +9,7 @@ | |||||||
|  |  | ||||||
| #include "buffer.h" | #include "buffer.h" | ||||||
| #include "camera.h" | #include "camera.h" | ||||||
|  | #include "light.h" | ||||||
| #include "logger.h" | #include "logger.h" | ||||||
| #include "material.h" | #include "material.h" | ||||||
| #include "mesh.h" | #include "mesh.h" | ||||||
| @@ -19,6 +20,10 @@ | |||||||
| #include "vertex.h" | #include "vertex.h" | ||||||
| #include "world.h" | #include "world.h" | ||||||
|  |  | ||||||
|  | // Instance variables | ||||||
|  | std::shared_ptr<Light> point_light; | ||||||
|  |  | ||||||
|  | // Constants | ||||||
| constexpr int	 screen_width  = 800; | constexpr int	 screen_width  = 800; | ||||||
| constexpr int	 screen_height = 600; | constexpr int	 screen_height = 600; | ||||||
| constexpr double fps_limit     = 1.0 / 60.0; | constexpr double fps_limit     = 1.0 / 60.0; | ||||||
| @@ -111,7 +116,7 @@ void Engine::run() | |||||||
| 		const double now	= glfwGetTime(); | 		const double now	= glfwGetTime(); | ||||||
| 		const double delta_time = now - last_update_time_; | 		const double delta_time = now - last_update_time_; | ||||||
|  |  | ||||||
| 		process_input(); | 		process_input(delta_time); | ||||||
| 		update(delta_time); | 		update(delta_time); | ||||||
|  |  | ||||||
| 		if (now - last_frame_time_ >= fps_limit) { | 		if (now - last_frame_time_ >= fps_limit) { | ||||||
| @@ -140,11 +145,12 @@ void Engine::setup() | |||||||
|  |  | ||||||
| 	// Create world | 	// Create world | ||||||
| 	world_ = std::make_unique<World>(); | 	world_ = std::make_unique<World>(); | ||||||
|  | 	world_->set_ambient(glm::vec3(0.2f, 0.2f, 0.2f)); | ||||||
| 	Logger::info("World created"); | 	Logger::info("World created"); | ||||||
|  |  | ||||||
| 	// Create camera at position (0, 1, 3) with -20 degrees X rotation | 	// Create camera | ||||||
| 	camera_ = std::make_shared<Camera>(); | 	camera_ = std::make_shared<Camera>(); | ||||||
| 	camera_->set_position(glm::vec3(0.0f, 1.0f, 3.0f)); | 	camera_->set_position(glm::vec3(0.0f, 4.0f, 12.0f)); | ||||||
| 	camera_->set_rotation(glm::vec3(glm::radians(-20.0f), 0.0f, 0.0f)); | 	camera_->set_rotation(glm::vec3(glm::radians(-20.0f), 0.0f, 0.0f)); | ||||||
| 	camera_->set_projection( | 	camera_->set_projection( | ||||||
| 	    glm::perspective(glm::radians(45.0f), | 	    glm::perspective(glm::radians(45.0f), | ||||||
| @@ -156,78 +162,49 @@ void Engine::setup() | |||||||
| 	world_->add_entity(camera_); | 	world_->add_entity(camera_); | ||||||
| 	Logger::info("Camera created and added to world"); | 	Logger::info("Camera created and added to world"); | ||||||
|  |  | ||||||
| 	// Load textures | 	// Load the box_stack model | ||||||
| 	auto top_texture   = Texture::load("data/textures/top.png"); | 	auto box_stack_mesh = Mesh::load("data/models/box_stack.obj"); | ||||||
| 	auto front_texture = Texture::load("data/textures/front.png"); | 	if (box_stack_mesh) { | ||||||
|  | 		auto box_stack_model = std::make_shared<Model>(box_stack_mesh); | ||||||
|  | 		box_stack_model->set_position(glm::vec3(-2.0f, -1.25f, 0.0f)); | ||||||
|  | 		models_.push_back(box_stack_model); | ||||||
|  | 		world_->add_entity(box_stack_model); | ||||||
|  | 		Logger::info("Box stack model loaded and added to world"); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Create cube mesh with two buffers | 	// Load the gunslinger model | ||||||
| 	mesh_ = std::make_shared<Mesh>(); | 	auto gunslinger_mesh = Mesh::load("data/models/gunslinger.obj"); | ||||||
|  | 	if (gunslinger_mesh) { | ||||||
|  | 		auto gunslinger_model = | ||||||
|  | 		    std::make_shared<Model>(gunslinger_mesh); | ||||||
|  | 		gunslinger_model->set_position(glm::vec3(2.0f, 0.0f, 0.0f)); | ||||||
|  | 		gunslinger_model->set_rotation( | ||||||
|  | 		    glm::vec3(0.0f, glm::radians(-30.0f), 0.0f)); | ||||||
|  | 		gunslinger_model->set_scale(glm::vec3(0.1f, 0.1f, 0.1f)); | ||||||
|  | 		models_.push_back(gunslinger_model); | ||||||
|  | 		world_->add_entity(gunslinger_model); | ||||||
|  | 		Logger::info("Gunslinger model loaded and added to world"); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Buffer 1: Top and bottom faces | 	// Create directional light | ||||||
| 	std::vector<Vertex> top_bottom_vertices = { | 	auto directional_light = std::make_shared<Light>(); | ||||||
| 	    // Top face (y = 0.5) | 	directional_light->set_type(Light::Type::DIRECTIONAL); | ||||||
| 	    {{-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}, | 	directional_light->set_color(glm::vec3(1.0f, 1.0f, 1.0f)); | ||||||
| 	    {{0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f}}, | 	directional_light->set_intensity(1.0f); | ||||||
| 	    {{0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}, | 	directional_light->set_position(glm::normalize( | ||||||
| 	    {{-0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}, | 	    glm::vec3(1.0f, 1.0f, 1.0f))); // Use position as direction | ||||||
| 	    // Bottom face (y = -0.5) | 	world_->add_entity(directional_light); | ||||||
| 	    {{-0.5f, -0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}, | 	Logger::info("Directional light created and added to world"); | ||||||
| 	    {{0.5f, -0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f}}, |  | ||||||
| 	    {{0.5f, -0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}, |  | ||||||
| 	    {{-0.5f, -0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}}; |  | ||||||
| 	std::vector<uint16_t> top_bottom_indices = {// Top face |  | ||||||
| 						    0, 1, 2, 0, 2, 3, |  | ||||||
| 						    // Bottom face |  | ||||||
| 						    4, 6, 5, 4, 7, 6}; |  | ||||||
|  |  | ||||||
| 	auto top_bottom_buffer = | 	// Create point light | ||||||
| 	    std::make_shared<Buffer>(top_bottom_vertices, top_bottom_indices); | 	point_light = std::make_shared<Light>(); | ||||||
| 	Material top_material(top_texture); | 	point_light->set_type(Light::Type::POINT); | ||||||
| 	mesh_->add_buffer(top_bottom_buffer, top_material); | 	point_light->set_color(glm::vec3(1.0f, 0.0f, 0.0f)); | ||||||
|  | 	point_light->set_intensity(2.0f); | ||||||
| 	// Buffer 2: Front, back, left, right faces | 	point_light->set_linear_attenuation(0.2f); | ||||||
| 	std::vector<Vertex> side_vertices = { | 	point_light->set_position(glm::vec3(5.0f, 0.0f, 0.0f)); | ||||||
| 	    // Front face (z = 0.5) | 	world_->add_entity(point_light); | ||||||
| 	    {{-0.5f, -0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}, | 	Logger::info("Point light created and added to world"); | ||||||
| 	    {{0.5f, -0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f}}, |  | ||||||
| 	    {{0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}, |  | ||||||
| 	    {{-0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}, |  | ||||||
| 	    // Back face (z = -0.5) |  | ||||||
| 	    {{-0.5f, -0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f}}, |  | ||||||
| 	    {{-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}, |  | ||||||
| 	    {{0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}, |  | ||||||
| 	    {{0.5f, -0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}, |  | ||||||
| 	    // Left face (x = -0.5) |  | ||||||
| 	    {{-0.5f, -0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}, |  | ||||||
| 	    {{-0.5f, -0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f}}, |  | ||||||
| 	    {{-0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}, |  | ||||||
| 	    {{-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}, |  | ||||||
| 	    // Right face (x = 0.5) |  | ||||||
| 	    {{0.5f, -0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f}}, |  | ||||||
| 	    {{0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}, |  | ||||||
| 	    {{0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}, |  | ||||||
| 	    {{0.5f, -0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}}; |  | ||||||
| 	std::vector<uint16_t> side_indices = {// Front face |  | ||||||
| 					      0, 1, 2, 0, 2, 3, |  | ||||||
| 					      // Back face |  | ||||||
| 					      4, 5, 6, 4, 6, 7, |  | ||||||
| 					      // Left face |  | ||||||
| 					      8, 9, 10, 8, 10, 11, |  | ||||||
| 					      // Right face |  | ||||||
| 					      12, 13, 14, 12, 14, 15}; |  | ||||||
|  |  | ||||||
| 	auto side_buffer = |  | ||||||
| 	    std::make_shared<Buffer>(side_vertices, side_indices); |  | ||||||
| 	Material side_material(front_texture); |  | ||||||
| 	mesh_->add_buffer(side_buffer, side_material); |  | ||||||
|  |  | ||||||
| 	Logger::info("Cube mesh created with two buffers"); |  | ||||||
|  |  | ||||||
| 	// Create model at origin |  | ||||||
| 	auto model = std::make_shared<Model>(mesh_); |  | ||||||
| 	model->set_position(glm::vec3(0.0f, 0.0f, 0.0f)); |  | ||||||
| 	models_.push_back(model); |  | ||||||
| 	world_->add_entity(model); |  | ||||||
|  |  | ||||||
| 	Logger::info("Scene setup complete"); | 	Logger::info("Scene setup complete"); | ||||||
| } | } | ||||||
| @@ -238,20 +215,52 @@ void Engine::start() | |||||||
| 	// Can be used for initialization that needs the scene to be ready | 	// Can be used for initialization that needs the scene to be ready | ||||||
| } | } | ||||||
|  |  | ||||||
| void Engine::process_input() | void Engine::process_input(const double delta_time) | ||||||
| { | { | ||||||
| 	glfwPollEvents(); | 	glfwPollEvents(); | ||||||
|  |  | ||||||
|  | 	if (!camera_) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	constexpr float camera_speed = 7.5f; | ||||||
|  |  | ||||||
|  | 	glm::vec3 forward = glm::vec3(0.0f, 0.0f, -1.0f); | ||||||
|  | 	glm::vec3 right	  = glm::vec3(1.0f, 0.0f, 0.0f); | ||||||
|  |  | ||||||
|  | 	glm::mat4 rotation = glm::mat4(1.0f); | ||||||
|  | 	rotation	   = glm::rotate(rotation, camera_->rotation().y, | ||||||
|  | 					 glm::vec3(0.0f, 1.0f, 0.0f)); | ||||||
|  | 	rotation	   = glm::rotate(rotation, camera_->rotation().x, | ||||||
|  | 					 glm::vec3(1.0f, 0.0f, 0.0f)); | ||||||
|  | 	forward		   = glm::vec3(rotation * glm::vec4(forward, 0.0f)); | ||||||
|  | 	right		   = glm::vec3(rotation * glm::vec4(right, 0.0f)); | ||||||
|  |  | ||||||
|  | 	const float movement = camera_speed * static_cast<float>(delta_time); | ||||||
|  | 	if (glfwGetKey(window_, GLFW_KEY_UP) == GLFW_PRESS) { | ||||||
|  | 		camera_->set_position(camera_->position() + forward * movement); | ||||||
|  | 	} | ||||||
|  | 	if (glfwGetKey(window_, GLFW_KEY_DOWN) == GLFW_PRESS) { | ||||||
|  | 		camera_->set_position(camera_->position() - forward * movement); | ||||||
|  | 	} | ||||||
|  | 	if (glfwGetKey(window_, GLFW_KEY_LEFT) == GLFW_PRESS) { | ||||||
|  | 		camera_->set_position(camera_->position() - right * movement); | ||||||
|  | 	} | ||||||
|  | 	if (glfwGetKey(window_, GLFW_KEY_RIGHT) == GLFW_PRESS) { | ||||||
|  | 		camera_->set_position(camera_->position() + right * movement); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void Engine::update(const double delta_time) | void Engine::update(const double delta_time) | ||||||
| { | { | ||||||
| 	// Update angle for rotation | 	// Update angle for orbiting light | ||||||
| 	angle_ += 32.0 * delta_time; | 	angle_ += delta_time; | ||||||
|  |  | ||||||
| 	// Update rotation for all models | 	// Make point light orbit around the model | ||||||
| 	for (auto& model : models_) { | 	if (point_light) { | ||||||
| 		model->set_rotation(glm::vec3( | 		constexpr float radius = 7.5f; | ||||||
| 		    0.0f, glm::radians(static_cast<float>(angle_)), 0.0f)); | 		point_light->set_position(glm::vec3(radius * cos(angle_), 2.0f, | ||||||
|  | 						    radius * sin(angle_))); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Update world | 	// Update world | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ private: | |||||||
| 	// Lifecycle methods | 	// Lifecycle methods | ||||||
| 	void setup(); | 	void setup(); | ||||||
| 	void start(); | 	void start(); | ||||||
| 	void process_input(); | 	void process_input(const double delta_time); | ||||||
| 	void update(const double delta_time); | 	void update(const double delta_time); | ||||||
| 	void render(); | 	void render(); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										56
									
								
								src/light.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/light.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | #include "light.h" | ||||||
|  |  | ||||||
|  | #include "../lib/glm/gtc/matrix_transform.hpp" | ||||||
|  |  | ||||||
|  | #include "shader.h" | ||||||
|  | #include "state.h" | ||||||
|  |  | ||||||
|  | Light::Light() | ||||||
|  |     : Entity() | ||||||
|  |     , type_(Type::DIRECTIONAL) | ||||||
|  |     , color_(1.0f, 1.0f, 1.0f) | ||||||
|  |     , intensity_(1.0f) | ||||||
|  |     , linear_attenuation_(0.0f) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Light::prepare(int index, std::shared_ptr<Shader>& shader) const | ||||||
|  | { | ||||||
|  | 	if (!shader) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	// Build uniform names for this light index | ||||||
|  | 	std::string light_vector = | ||||||
|  | 	    "lights[" + std::to_string(index) + "].vector"; | ||||||
|  | 	std::string light_color = "lights[" + std::to_string(index) + "].color"; | ||||||
|  | 	std::string light_intensity = | ||||||
|  | 	    "lights[" + std::to_string(index) + "].intensity"; | ||||||
|  | 	std::string light_linear_att = | ||||||
|  | 	    "lights[" + std::to_string(index) + "].linear_att"; | ||||||
|  |  | ||||||
|  | 	// Get uniform locations | ||||||
|  | 	int vector_loc	   = shader->uniform_location(light_vector.c_str()); | ||||||
|  | 	int color_loc	   = shader->uniform_location(light_color.c_str()); | ||||||
|  | 	int intensity_loc  = shader->uniform_location(light_intensity.c_str()); | ||||||
|  | 	int linear_att_loc = shader->uniform_location(light_linear_att.c_str()); | ||||||
|  |  | ||||||
|  | 	// Calculate light vector in view space | ||||||
|  | 	glm::vec4 light_vector_view; | ||||||
|  | 	if (type_ == Type::DIRECTIONAL) { | ||||||
|  | 		// For directional lights, w = 0 | ||||||
|  | 		glm::vec3 direction = | ||||||
|  | 		    glm::normalize(position_); // Use position as direction | ||||||
|  | 		light_vector_view = | ||||||
|  | 		    state::view_matrix * glm::vec4(direction, 0.0f); | ||||||
|  | 	} else { | ||||||
|  | 		// For point lights, w = 1 | ||||||
|  | 		light_vector_view = | ||||||
|  | 		    state::view_matrix * glm::vec4(position_, 1.0f); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Set uniforms | ||||||
|  | 	Shader::set_vec4(vector_loc, light_vector_view); | ||||||
|  | 	Shader::set_vec3(color_loc, color_); | ||||||
|  | 	Shader::set_float(intensity_loc, intensity_); | ||||||
|  | 	Shader::set_float(linear_att_loc, linear_attenuation_); | ||||||
|  | } | ||||||
							
								
								
									
										67
									
								
								src/light.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/light.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | #ifndef LIGHT_H_ | ||||||
|  | #define LIGHT_H_ | ||||||
|  |  | ||||||
|  | #include <memory> | ||||||
|  |  | ||||||
|  | #include "../lib/glm/glm.hpp" | ||||||
|  |  | ||||||
|  | #include "entity.h" | ||||||
|  |  | ||||||
|  | class Shader; | ||||||
|  |  | ||||||
|  | class Light : public Entity { | ||||||
|  | public: | ||||||
|  | 	enum class Type { | ||||||
|  | 		DIRECTIONAL, | ||||||
|  | 		POINT | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	Light(); | ||||||
|  | 	~Light() override = default; | ||||||
|  |  | ||||||
|  | 	[[nodiscard]] Type type() const | ||||||
|  | 	{ | ||||||
|  | 		return type_; | ||||||
|  | 	} | ||||||
|  | 	void set_type(Type type) | ||||||
|  | 	{ | ||||||
|  | 		type_ = type; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	[[nodiscard]] const glm::vec3& color() const | ||||||
|  | 	{ | ||||||
|  | 		return color_; | ||||||
|  | 	} | ||||||
|  | 	void set_color(const glm::vec3& color) | ||||||
|  | 	{ | ||||||
|  | 		color_ = color; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	[[nodiscard]] float intensity() const | ||||||
|  | 	{ | ||||||
|  | 		return intensity_; | ||||||
|  | 	} | ||||||
|  | 	void set_intensity(float intensity) | ||||||
|  | 	{ | ||||||
|  | 		intensity_ = intensity; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	[[nodiscard]] float linear_attenuation() const | ||||||
|  | 	{ | ||||||
|  | 		return linear_attenuation_; | ||||||
|  | 	} | ||||||
|  | 	void set_linear_attenuation(float att) | ||||||
|  | 	{ | ||||||
|  | 		linear_attenuation_ = att; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void prepare(int index, std::shared_ptr<Shader>& shader) const; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	Type	  type_; | ||||||
|  | 	glm::vec3 color_; | ||||||
|  | 	float	  intensity_; | ||||||
|  | 	float	  linear_attenuation_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // LIGHT_H_ | ||||||
							
								
								
									
										15
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/main.cpp
									
									
									
									
									
								
							| @@ -1,9 +1,12 @@ | |||||||
| /*#ifdef _MSC_VER | // #ifdef _MSC_VER | ||||||
| #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") | // #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") | ||||||
| #endif*/ | // #endif | ||||||
|  |  | ||||||
| #define STB_IMAGE_IMPLEMENTATION | #define STB_IMAGE_IMPLEMENTATION | ||||||
| #include "../lib/stb/stb_image.h" | #include "../lib/stb_image.h" | ||||||
|  |  | ||||||
|  | #define TINYOBJLOADER_IMPLEMENTATION | ||||||
|  | #include "../lib/tiny_obj_loader.h" | ||||||
|  |  | ||||||
| #include "engine.h" | #include "engine.h" | ||||||
|  |  | ||||||
| @@ -15,5 +18,9 @@ int main() | |||||||
| 	engine.run(); | 	engine.run(); | ||||||
| 	engine.destroy(); | 	engine.destroy(); | ||||||
|  |  | ||||||
|  | 	// _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); | ||||||
|  | 	// _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); | ||||||
|  | 	// _CrtDumpMemoryLeaks(); | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,14 +1,19 @@ | |||||||
| #include "material.h" | #include "material.h" | ||||||
|  |  | ||||||
| #include "../lib/glm/glm.hpp" | #include "../lib/glm/glm.hpp" | ||||||
|  | #include "../lib/glm/gtc/matrix_transform.hpp" | ||||||
|  |  | ||||||
|  | #include "light.h" | ||||||
| #include "shader.h" | #include "shader.h" | ||||||
| #include "state.h" | #include "state.h" | ||||||
| #include "texture.h" | #include "texture.h" | ||||||
|  |  | ||||||
| Material::Material(const std::shared_ptr<Texture>& tex, | Material::Material(const std::shared_ptr<Texture>& tex, | ||||||
| 		   const std::shared_ptr<Shader>&  shader) | 		   const std::shared_ptr<Shader>&  shader) | ||||||
|     : shader_(shader), texture_(tex) |     : shader_(shader) | ||||||
|  |     , texture_(tex) | ||||||
|  |     , color_(1.0f, 1.0f, 1.0f, 1.0f) | ||||||
|  |     , shininess_(0) | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -42,6 +47,39 @@ void Material::prepare() | |||||||
| 	const int mvp_loc = active_shader->uniform_location("mvp"); | 	const int mvp_loc = active_shader->uniform_location("mvp"); | ||||||
| 	Shader::set_mat4(mvp_loc, mvp); | 	Shader::set_mat4(mvp_loc, mvp); | ||||||
|  |  | ||||||
|  | 	// Set ModelView matrix | ||||||
|  | 	const glm::mat4 model_view = state::view_matrix * state::model_matrix; | ||||||
|  | 	const int model_view_loc = active_shader->uniform_location("modelView"); | ||||||
|  | 	Shader::set_mat4(model_view_loc, model_view); | ||||||
|  |  | ||||||
|  | 	// Set Normal matrix (transpose of inverse of ModelView) | ||||||
|  | 	const glm::mat4 normal_matrix = | ||||||
|  | 	    glm::transpose(glm::inverse(model_view)); | ||||||
|  | 	const int normal_matrix_loc = | ||||||
|  | 	    active_shader->uniform_location("normalMatrix"); | ||||||
|  | 	Shader::set_mat4(normal_matrix_loc, normal_matrix); | ||||||
|  |  | ||||||
|  | 	// Set material properties | ||||||
|  | 	const int material_color_loc = | ||||||
|  | 	    active_shader->uniform_location("materialColor"); | ||||||
|  | 	Shader::set_vec4(material_color_loc, color_); | ||||||
|  |  | ||||||
|  | 	const int shininess_loc = active_shader->uniform_location("shininess"); | ||||||
|  | 	Shader::set_float(shininess_loc, static_cast<float>(shininess_)); | ||||||
|  |  | ||||||
|  | 	// Set ambient light | ||||||
|  | 	const int ambient_loc = active_shader->uniform_location("ambientLight"); | ||||||
|  | 	Shader::set_vec3(ambient_loc, state::ambient); | ||||||
|  |  | ||||||
|  | 	// Set number of lights | ||||||
|  | 	const int num_lights_loc = active_shader->uniform_location("numLights"); | ||||||
|  | 	Shader::set_int(num_lights_loc, static_cast<int>(state::lights.size())); | ||||||
|  |  | ||||||
|  | 	// Prepare each light | ||||||
|  | 	for (size_t i = 0; i < state::lights.size(); ++i) { | ||||||
|  | 		state::lights[i]->prepare(static_cast<int>(i), active_shader); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Set texture-related uniforms | 	// Set texture-related uniforms | ||||||
| 	const int use_texture_loc = | 	const int use_texture_loc = | ||||||
| 	    active_shader->uniform_location("useTexture"); | 	    active_shader->uniform_location("useTexture"); | ||||||
|   | |||||||
| @@ -3,6 +3,8 @@ | |||||||
|  |  | ||||||
| #include <memory> | #include <memory> | ||||||
|  |  | ||||||
|  | #include "../lib/glm/glm.hpp" | ||||||
|  |  | ||||||
| class Shader; | class Shader; | ||||||
| class Texture; | class Texture; | ||||||
|  |  | ||||||
| @@ -25,11 +27,31 @@ public: | |||||||
| 		texture_ = tex; | 		texture_ = tex; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	[[nodiscard]] const glm::vec4& color() const | ||||||
|  | 	{ | ||||||
|  | 		return color_; | ||||||
|  | 	} | ||||||
|  | 	void set_color(const glm::vec4& color) | ||||||
|  | 	{ | ||||||
|  | 		color_ = color; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	[[nodiscard]] uint8_t shininess() const | ||||||
|  | 	{ | ||||||
|  | 		return shininess_; | ||||||
|  | 	} | ||||||
|  | 	void set_shininess(uint8_t shininess) | ||||||
|  | 	{ | ||||||
|  | 		shininess_ = shininess; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	void prepare(); | 	void prepare(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	std::shared_ptr<Shader>	 shader_; | 	std::shared_ptr<Shader>	 shader_; | ||||||
| 	std::shared_ptr<Texture> texture_; | 	std::shared_ptr<Texture> texture_; | ||||||
|  | 	glm::vec4		 color_; | ||||||
|  | 	uint8_t			 shininess_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif // MATERIAL_H_ | #endif // MATERIAL_H_ | ||||||
|   | |||||||
							
								
								
									
										184
									
								
								src/mesh.cpp
									
									
									
									
									
								
							
							
						
						
									
										184
									
								
								src/mesh.cpp
									
									
									
									
									
								
							| @@ -1,15 +1,197 @@ | |||||||
| #include "mesh.h" | #include "mesh.h" | ||||||
|  |  | ||||||
|  | #include <filesystem> | ||||||
|  | #include <string> | ||||||
|  | #include <unordered_map> | ||||||
|  |  | ||||||
|  | #include "../lib/tiny_obj_loader.h" | ||||||
|  |  | ||||||
| #include "buffer.h" | #include "buffer.h" | ||||||
|  | #include "logger.h" | ||||||
| #include "material.h" | #include "material.h" | ||||||
|  | #include "shader.h" | ||||||
|  | #include "state.h" | ||||||
|  | #include "texture.h" | ||||||
|  | #include "vertex.h" | ||||||
|  |  | ||||||
|  | // Helper structures and functions for OBJ loading | ||||||
|  | namespace { | ||||||
|  |  | ||||||
|  | struct LoadContext { | ||||||
|  | 	std::string						  base_dir; | ||||||
|  | 	std::unordered_map<std::string, std::shared_ptr<Texture>> texture_cache; | ||||||
|  | 	const std::vector<tinyobj::material_t>*			  materials; | ||||||
|  | 	const std::shared_ptr<Shader>&				  shader; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | Vertex create_vertex(const tinyobj::attrib_t& attrib, | ||||||
|  | 		     const tinyobj::index_t&  idx) | ||||||
|  | { | ||||||
|  | 	Vertex vertex; | ||||||
|  |  | ||||||
|  | 	// Position | ||||||
|  | 	if (idx.vertex_index >= 0) { | ||||||
|  | 		vertex.position.x = attrib.vertices[3 * idx.vertex_index + 0]; | ||||||
|  | 		vertex.position.y = attrib.vertices[3 * idx.vertex_index + 1]; | ||||||
|  | 		vertex.position.z = attrib.vertices[3 * idx.vertex_index + 2]; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Color (default to white) | ||||||
|  | 	vertex.color = glm::vec3(1.0f, 1.0f, 1.0f); | ||||||
|  |  | ||||||
|  | 	// Texture coordinates | ||||||
|  | 	vertex.tex_coord = glm::vec2(0.0f, 0.0f); | ||||||
|  | 	if (idx.texcoord_index >= 0) { | ||||||
|  | 		vertex.tex_coord.x = attrib.texcoords[2 * idx.texcoord_index + 0]; | ||||||
|  | 		vertex.tex_coord.y = attrib.texcoords[2 * idx.texcoord_index + 1]; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Normal | ||||||
|  | 	vertex.normal = glm::vec3(0.0f, 0.0f, 1.0f); | ||||||
|  | 	if (idx.normal_index >= 0) { | ||||||
|  | 		vertex.normal.x = attrib.normals[3 * idx.normal_index + 0]; | ||||||
|  | 		vertex.normal.y = attrib.normals[3 * idx.normal_index + 1]; | ||||||
|  | 		vertex.normal.z = attrib.normals[3 * idx.normal_index + 2]; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return vertex; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void process_shape(const tinyobj::shape_t&   shape, | ||||||
|  | 		   const tinyobj::attrib_t& attrib, | ||||||
|  | 		   std::vector<Vertex>&	    out_vertices, | ||||||
|  | 		   std::vector<uint16_t>&   out_indices) | ||||||
|  | { | ||||||
|  | 	// Process all indices - create one vertex per index | ||||||
|  | 	for (size_t i = 0; i < shape.mesh.indices.size(); ++i) { | ||||||
|  | 		const tinyobj::index_t& idx = shape.mesh.indices[i]; | ||||||
|  | 		Vertex			vertex	= create_vertex(attrib, idx); | ||||||
|  |  | ||||||
|  | 		out_vertices.push_back(vertex); | ||||||
|  | 		out_indices.push_back( | ||||||
|  | 		    static_cast<uint16_t>(out_vertices.size() - 1)); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::shared_ptr<Texture> load_material_texture(int	    material_id, | ||||||
|  | 					       LoadContext& context) | ||||||
|  | { | ||||||
|  | 	if (material_id < 0 | ||||||
|  | 	    || material_id >= static_cast<int>(context.materials->size())) { | ||||||
|  | 		return nullptr; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	const auto& mat		 = (*context.materials)[material_id]; | ||||||
|  | 	std::string texture_name = mat.diffuse_texname; | ||||||
|  |  | ||||||
|  | 	// Try ambient texture if diffuse is not available | ||||||
|  | 	if (texture_name.empty()) { | ||||||
|  | 		texture_name = mat.ambient_texname; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (texture_name.empty()) { | ||||||
|  | 		return nullptr; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Check cache first | ||||||
|  | 	auto it = context.texture_cache.find(texture_name); | ||||||
|  | 	if (it != context.texture_cache.end()) { | ||||||
|  | 		return it->second; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Load texture | ||||||
|  | 	std::string texture_path = context.base_dir + texture_name; | ||||||
|  | 	auto	    texture	 = Texture::load(texture_path.c_str()); | ||||||
|  |  | ||||||
|  | 	if (texture) { | ||||||
|  | 		context.texture_cache[texture_name] = texture; | ||||||
|  | 		Logger::info(sstr("Loaded texture: ", texture_path)); | ||||||
|  | 	} else { | ||||||
|  | 		Logger::warn(sstr("Failed to load texture: ", texture_path)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return texture; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void create_buffer_for_shape(const tinyobj::shape_t&   shape, | ||||||
|  | 			     const std::vector<Vertex>&	   vertices, | ||||||
|  | 			     const std::vector<uint16_t>& indices, | ||||||
|  | 			     LoadContext&		   context, | ||||||
|  | 			     std::shared_ptr<Mesh>&	   mesh) | ||||||
|  | { | ||||||
|  | 	auto buffer = std::make_shared<Buffer>(vertices, indices); | ||||||
|  |  | ||||||
|  | 	// Use first material ID from the shape | ||||||
|  | 	int material_id = -1; | ||||||
|  | 	if (!shape.mesh.material_ids.empty() && shape.mesh.material_ids[0] >= 0) { | ||||||
|  | 		material_id = shape.mesh.material_ids[0]; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	auto texture = load_material_texture(material_id, context); | ||||||
|  | 	auto material_shader = | ||||||
|  | 	    context.shader ? context.shader : state::default_shader; | ||||||
|  |  | ||||||
|  | 	Material mat(texture, material_shader); | ||||||
|  | 	mesh->add_buffer(buffer, mat); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace | ||||||
|  |  | ||||||
| void Mesh::add_buffer(const std::shared_ptr<Buffer>& buffer, | void Mesh::add_buffer(const std::shared_ptr<Buffer>& buffer, | ||||||
| 		      const Material& material) | 		      const Material&		     material) | ||||||
| { | { | ||||||
| 	buffers_.push_back(buffer); | 	buffers_.push_back(buffer); | ||||||
| 	materials_.push_back(material); | 	materials_.push_back(material); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::shared_ptr<Mesh> Mesh::load(const char*			filename, | ||||||
|  | 				 const std::shared_ptr<Shader>& shader) | ||||||
|  | { | ||||||
|  | 	Logger::info(sstr("Loading mesh from: ", filename)); | ||||||
|  |  | ||||||
|  | 	// Load OBJ file | ||||||
|  | 	tinyobj::attrib_t		 attrib; | ||||||
|  | 	std::vector<tinyobj::shape_t>	 shapes; | ||||||
|  | 	std::vector<tinyobj::material_t> materials; | ||||||
|  | 	std::string			 err; | ||||||
|  |  | ||||||
|  | 	std::filesystem::path obj_path(filename); | ||||||
|  | 	std::string	      base_dir = obj_path.parent_path().string(); | ||||||
|  | 	if (!base_dir.empty()) { | ||||||
|  | 		base_dir += "/"; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename, | ||||||
|  | 			      base_dir.c_str())) { | ||||||
|  | 		Logger::error( | ||||||
|  | 		    sstr("Failed to load OBJ file: ", filename, " - ", err)); | ||||||
|  | 		return nullptr; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (!err.empty()) { | ||||||
|  | 		Logger::warn(sstr("TinyObjLoader warning: ", err)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Setup load context | ||||||
|  | 	LoadContext context{base_dir, {}, &materials, shader}; | ||||||
|  |  | ||||||
|  | 	// Process each shape | ||||||
|  | 	auto mesh = std::make_shared<Mesh>(); | ||||||
|  | 	for (const auto& shape : shapes) { | ||||||
|  | 		Logger::info(sstr("Processing shape: ", shape.name)); | ||||||
|  |  | ||||||
|  | 		std::vector<Vertex>   vertices; | ||||||
|  | 		std::vector<uint16_t> indices; | ||||||
|  |  | ||||||
|  | 		process_shape(shape, attrib, vertices, indices); | ||||||
|  | 		create_buffer_for_shape(shape, vertices, indices, context, mesh); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Logger::info(sstr("Mesh loaded successfully with ", mesh->num_buffers(), | ||||||
|  | 			  " buffers")); | ||||||
|  | 	return mesh; | ||||||
|  | } | ||||||
|  |  | ||||||
| void Mesh::draw() | void Mesh::draw() | ||||||
| { | { | ||||||
| 	// Draw each buffer with its material | 	// Draw each buffer with its material | ||||||
|   | |||||||
| @@ -7,12 +7,17 @@ | |||||||
| #include "material.h" | #include "material.h" | ||||||
|  |  | ||||||
| class Buffer; | class Buffer; | ||||||
|  | class Shader; | ||||||
|  |  | ||||||
| class Mesh { | class Mesh { | ||||||
| public: | public: | ||||||
| 	Mesh()	= default; | 	Mesh()	= default; | ||||||
| 	~Mesh() = default; | 	~Mesh() = default; | ||||||
|  |  | ||||||
|  | 	static std::shared_ptr<Mesh> | ||||||
|  | 	load(const char*		    filename, | ||||||
|  | 	     const std::shared_ptr<Shader>& shader = nullptr); | ||||||
|  |  | ||||||
| 	void add_buffer(const std::shared_ptr<Buffer>& buffer, | 	void add_buffer(const std::shared_ptr<Buffer>& buffer, | ||||||
| 			const Material&		       material); | 			const Material&		       material); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -73,6 +73,14 @@ void Shader::setup_attribs() const | |||||||
| 		    loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), | 		    loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), | ||||||
| 		    reinterpret_cast<const void*>(offsetof(Vertex, tex_coord))); | 		    reinterpret_cast<const void*>(offsetof(Vertex, tex_coord))); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	loc = glGetAttribLocation(program_id_, "vnormal"); | ||||||
|  | 	if (loc != -1) { | ||||||
|  | 		glEnableVertexAttribArray(loc); | ||||||
|  | 		glVertexAttribPointer( | ||||||
|  | 		    loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), | ||||||
|  | 		    reinterpret_cast<const void*>(offsetof(Vertex, normal))); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| int Shader::uniform_location(const char* key) const | int Shader::uniform_location(const char* key) const | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								src/state.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/state.h
									
									
									
									
									
								
							| @@ -2,16 +2,20 @@ | |||||||
| #define STATE_H_ | #define STATE_H_ | ||||||
|  |  | ||||||
| #include <memory> | #include <memory> | ||||||
|  | #include <vector> | ||||||
| #include "../lib/glm/glm.hpp" | #include "../lib/glm/glm.hpp" | ||||||
|  |  | ||||||
| class Shader; | class Shader; | ||||||
|  | class Light; | ||||||
|  |  | ||||||
| namespace state { | namespace state { | ||||||
|  |  | ||||||
| inline std::shared_ptr<Shader> default_shader	 = nullptr; | inline std::shared_ptr<Shader>		   default_shader    = nullptr; | ||||||
| inline glm::mat4	       projection_matrix = glm::mat4(1.0f); | inline glm::mat4			   projection_matrix = glm::mat4(1.0f); | ||||||
| inline glm::mat4	       view_matrix	 = glm::mat4(1.0f); | inline glm::mat4			   view_matrix	     = glm::mat4(1.0f); | ||||||
| inline glm::mat4	       model_matrix	 = glm::mat4(1.0f); | inline glm::mat4			   model_matrix	     = glm::mat4(1.0f); | ||||||
|  | inline std::vector<std::shared_ptr<Light>> lights; | ||||||
|  | inline glm::vec3 ambient = glm::vec3(0.0f, 0.0f, 0.0f); | ||||||
|  |  | ||||||
| } // namespace state | } // namespace state | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
|  |  | ||||||
| #include "../lib/glew/GL/glew.h" | #include "../lib/glew/GL/glew.h" | ||||||
| #include "../lib/glfw/glfw3.h" | #include "../lib/glfw/glfw3.h" | ||||||
| #include "../lib/stb/stb_image.h" | #include "../lib/stb_image.h" | ||||||
|  |  | ||||||
| #include "logger.h" | #include "logger.h" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ struct Vertex { | |||||||
| 	glm::vec3 position{0.0f, 0.0f, 0.0f}; | 	glm::vec3 position{0.0f, 0.0f, 0.0f}; | ||||||
| 	glm::vec3 color{0.0f, 0.0f, 0.0f}; | 	glm::vec3 color{0.0f, 0.0f, 0.0f}; | ||||||
| 	glm::vec2 tex_coord{0.0f, 0.0f}; | 	glm::vec2 tex_coord{0.0f, 0.0f}; | ||||||
|  | 	glm::vec3 normal{0.0f, 0.0f, 0.0f}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif // VERTEX_H_ | #endif // VERTEX_H_ | ||||||
|   | |||||||
| @@ -4,7 +4,9 @@ | |||||||
|  |  | ||||||
| #include "camera.h" | #include "camera.h" | ||||||
| #include "entity.h" | #include "entity.h" | ||||||
|  | #include "light.h" | ||||||
| #include "logger.h" | #include "logger.h" | ||||||
|  | #include "state.h" | ||||||
|  |  | ||||||
| void World::add_entity(const std::shared_ptr<Entity>& entity) | void World::add_entity(const std::shared_ptr<Entity>& entity) | ||||||
| { | { | ||||||
| @@ -17,10 +19,20 @@ void World::add_entity(const std::shared_ptr<Entity>& entity) | |||||||
| 		cameras_.push_back(camera); | 		cameras_.push_back(camera); | ||||||
| 		Logger::info(sstr("Camera added to world (total cameras: ", | 		Logger::info(sstr("Camera added to world (total cameras: ", | ||||||
| 				  cameras_.size(), ")")); | 				  cameras_.size(), ")")); | ||||||
| 	} else { | 		return; | ||||||
| 		Logger::info(sstr("Entity added to world (total entities: ", |  | ||||||
| 				  entities_.size(), ")")); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// Check if entity is a light | ||||||
|  | 	std::shared_ptr<Light> light = std::dynamic_pointer_cast<Light>(entity); | ||||||
|  | 	if (light) { | ||||||
|  | 		lights_.push_back(light); | ||||||
|  | 		Logger::info(sstr("Light added to world (total lights: ", | ||||||
|  | 				  lights_.size(), ")")); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Logger::info(sstr( | ||||||
|  | 	    "Entity added to world (total entities: ", entities_.size(), ")")); | ||||||
| } | } | ||||||
|  |  | ||||||
| void World::remove_entity(const std::shared_ptr<Entity>& entity) | void World::remove_entity(const std::shared_ptr<Entity>& entity) | ||||||
| @@ -43,6 +55,16 @@ void World::remove_entity(const std::shared_ptr<Entity>& entity) | |||||||
| 			Logger::info("Camera removed from world"); | 			Logger::info("Camera removed from world"); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// Check if entity is a light and remove from lights list | ||||||
|  | 	std::shared_ptr<Light> light = std::dynamic_pointer_cast<Light>(entity); | ||||||
|  | 	if (light) { | ||||||
|  | 		auto lightIt = std::find(lights_.begin(), lights_.end(), light); | ||||||
|  | 		if (lightIt != lights_.end()) { | ||||||
|  | 			lights_.erase(lightIt); | ||||||
|  | 			Logger::info("Light removed from world"); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void World::update(float delta_time) | void World::update(float delta_time) | ||||||
| @@ -54,6 +76,10 @@ void World::update(float delta_time) | |||||||
|  |  | ||||||
| void World::draw() | void World::draw() | ||||||
| { | { | ||||||
|  | 	// Update state with world lighting information | ||||||
|  | 	state::ambient = ambient_; | ||||||
|  | 	state::lights  = lights_; | ||||||
|  |  | ||||||
| 	// Draw for each camera | 	// Draw for each camera | ||||||
| 	for (auto& camera : cameras_) { | 	for (auto& camera : cameras_) { | ||||||
| 		// Prepare the camera (sets viewport, projection, view, clears | 		// Prepare the camera (sets viewport, projection, view, clears | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								src/world.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/world.h
									
									
									
									
									
								
							| @@ -4,8 +4,11 @@ | |||||||
| #include <memory> | #include <memory> | ||||||
| #include <vector> | #include <vector> | ||||||
|  |  | ||||||
|  | #include "../lib/glm/glm.hpp" | ||||||
|  |  | ||||||
| class Entity; | class Entity; | ||||||
| class Camera; | class Camera; | ||||||
|  | class Light; | ||||||
|  |  | ||||||
| class World { | class World { | ||||||
| public: | public: | ||||||
| @@ -27,12 +30,23 @@ public: | |||||||
| 		return entities_[index]; | 		return entities_[index]; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	[[nodiscard]] const glm::vec3& ambient() const | ||||||
|  | 	{ | ||||||
|  | 		return ambient_; | ||||||
|  | 	} | ||||||
|  | 	void set_ambient(const glm::vec3& ambient) | ||||||
|  | 	{ | ||||||
|  | 		ambient_ = ambient; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	void update(float delta_time); | 	void update(float delta_time); | ||||||
| 	void draw(); | 	void draw(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	std::vector<std::shared_ptr<Entity>> entities_; | 	std::vector<std::shared_ptr<Entity>> entities_; | ||||||
| 	std::vector<std::shared_ptr<Camera>> cameras_; | 	std::vector<std::shared_ptr<Camera>> cameras_; | ||||||
|  | 	std::vector<std::shared_ptr<Light>>  lights_; | ||||||
|  | 	glm::vec3			     ambient_{0.0f, 0.0f, 0.0f}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif // WORLD_H_ | #endif // WORLD_H_ | ||||||
|   | |||||||
| @@ -164,6 +164,7 @@ | |||||||
|     <ClInclude Include="src\camera.h" /> |     <ClInclude Include="src\camera.h" /> | ||||||
|     <ClInclude Include="src\engine.h" /> |     <ClInclude Include="src\engine.h" /> | ||||||
|     <ClInclude Include="src\entity.h" /> |     <ClInclude Include="src\entity.h" /> | ||||||
|  |     <ClInclude Include="src\light.h" /> | ||||||
|     <ClInclude Include="src\logger.h" /> |     <ClInclude Include="src\logger.h" /> | ||||||
|     <ClInclude Include="src\material.h" /> |     <ClInclude Include="src\material.h" /> | ||||||
|     <ClInclude Include="src\mesh.h" /> |     <ClInclude Include="src\mesh.h" /> | ||||||
| @@ -180,6 +181,7 @@ | |||||||
|     <ClCompile Include="src\camera.cpp" /> |     <ClCompile Include="src\camera.cpp" /> | ||||||
|     <ClCompile Include="src\engine.cpp" /> |     <ClCompile Include="src\engine.cpp" /> | ||||||
|     <ClCompile Include="src\entity.cpp" /> |     <ClCompile Include="src\entity.cpp" /> | ||||||
|  |     <ClCompile Include="src\light.cpp" /> | ||||||
|     <ClCompile Include="src\logger.cpp" /> |     <ClCompile Include="src\logger.cpp" /> | ||||||
|     <ClCompile Include="src\main.cpp" /> |     <ClCompile Include="src\main.cpp" /> | ||||||
|     <ClCompile Include="src\material.cpp" /> |     <ClCompile Include="src\material.cpp" /> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user