Compare commits
16 Commits
assignment
...
assignment
| Author | SHA1 | Date | |
|---|---|---|---|
| c34d3f803f | |||
| 3b96b5008e | |||
| 9f0f8667ec | |||
| 58c761cb99 | |||
| 2d5f145c34 | |||
| 0931f3ce91 | |||
| 97606d398c | |||
| c30419899d | |||
| c1a5be6d90 | |||
| cf725c4c69 | |||
| d084ce8799 | |||
| 95275f9183 | |||
| 9124618ab6 | |||
| 1089861aa3 | |||
| 49219fc597 | |||
| db6e548476 |
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.
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
varying vec3 fcolor;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_FragColor = vec4(fcolor, 1);
|
|
||||||
}
|
|
||||||
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.
12
data/shaders/fragment.glsl
Normal file
12
data/shaders/fragment.glsl
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
uniform int useTexture;
|
||||||
|
uniform sampler2D texSampler;
|
||||||
|
varying vec3 fcolor;
|
||||||
|
varying vec2 ftexcoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
if (useTexture == 1) {
|
||||||
|
gl_FragColor = texture2D(texSampler, ftexcoord);
|
||||||
|
} else {
|
||||||
|
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
uniform mat4 mvp;
|
uniform mat4 mvp;
|
||||||
attribute vec3 vpos;
|
attribute vec3 vpos;
|
||||||
attribute vec3 vcolor;
|
attribute vec3 vcolor;
|
||||||
|
attribute vec2 vtexcoord;
|
||||||
varying vec3 fcolor;
|
varying vec3 fcolor;
|
||||||
|
varying vec2 ftexcoord;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = mvp * vec4(vpos, 1);
|
gl_Position = mvp * vec4(vpos, 1);
|
||||||
fcolor = vcolor;
|
fcolor = vcolor;
|
||||||
|
ftexcoord = vtexcoord;
|
||||||
}
|
}
|
||||||
BIN
data/textures/front.png
(Stored with Git LFS)
Normal file
BIN
data/textures/front.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
data/textures/top.png
(Stored with Git LFS)
Normal file
BIN
data/textures/top.png
(Stored with Git LFS)
Normal file
Binary file not shown.
7187
lib/stb_image.h
Normal file
7187
lib/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
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"));
|
||||||
|
|||||||
100
src/engine.cpp
100
src/engine.cpp
@@ -10,10 +10,12 @@
|
|||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
#include "material.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
|
#include "texture.h"
|
||||||
#include "vertex.h"
|
#include "vertex.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
|
|
||||||
@@ -83,8 +85,8 @@ void Engine::initialize()
|
|||||||
|
|
||||||
// Initialize default shader
|
// Initialize default shader
|
||||||
Logger::info("Loading default shaders...");
|
Logger::info("Loading default shaders...");
|
||||||
state::default_shader =
|
state::default_shader = std::make_shared<Shader>(
|
||||||
std::make_shared<Shader>("data/vertex.glsl", "data/fragment.glsl");
|
"data/shaders/vertex.glsl", "data/shaders/fragment.glsl");
|
||||||
if (std::strlen(state::default_shader->error()) > 0) {
|
if (std::strlen(state::default_shader->error()) > 0) {
|
||||||
Logger::error(sstr("Failed to initialize shaders: ",
|
Logger::error(sstr("Failed to initialize shaders: ",
|
||||||
state::default_shader->error()));
|
state::default_shader->error()));
|
||||||
@@ -109,7 +111,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) {
|
||||||
@@ -142,7 +144,8 @@ void Engine::setup()
|
|||||||
|
|
||||||
// Create camera
|
// Create camera
|
||||||
camera_ = std::make_shared<Camera>();
|
camera_ = std::make_shared<Camera>();
|
||||||
camera_->set_position(glm::vec3(0.0f, 0.0f, 6.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_projection(
|
camera_->set_projection(
|
||||||
glm::perspective(glm::radians(45.0f),
|
glm::perspective(glm::radians(45.0f),
|
||||||
static_cast<float>(screen_width_)
|
static_cast<float>(screen_width_)
|
||||||
@@ -153,31 +156,30 @@ 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");
|
||||||
|
|
||||||
// Create triangle mesh
|
// Load the box_stack model
|
||||||
std::vector<Vertex> vertices = {
|
auto box_stack_mesh = Mesh::load("data/models/box_stack.obj");
|
||||||
{{0.0f, 0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}},
|
if (box_stack_mesh) {
|
||||||
{{-0.5f, -0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}},
|
auto box_stack_model = std::make_shared<Model>(box_stack_mesh);
|
||||||
{{0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}}};
|
box_stack_model->set_position(glm::vec3(-2.0f, -1.25f, 0.0f));
|
||||||
std::vector<uint16_t> indices = {0, 1, 2};
|
models_.push_back(box_stack_model);
|
||||||
|
world_->add_entity(box_stack_model);
|
||||||
auto buffer = std::make_shared<Buffer>(vertices, indices);
|
Logger::info("Box stack model loaded and added to world");
|
||||||
mesh_ = std::make_shared<Mesh>();
|
|
||||||
mesh_->add_buffer(buffer);
|
|
||||||
Logger::info(sstr("Mesh created with ", vertices.size(),
|
|
||||||
" vertices and ", indices.size(), " indices"));
|
|
||||||
|
|
||||||
// Create 9 models in a 3x3 grid
|
|
||||||
for (int row = 0; row < 3; ++row) {
|
|
||||||
for (int col = 0; col < 3; ++col) {
|
|
||||||
auto model = std::make_shared<Model>(mesh_);
|
|
||||||
model->set_position(
|
|
||||||
glm::vec3(-3.0f + static_cast<float>(col) * 3.0f,
|
|
||||||
0.0f, static_cast<float>(-row) * 3.0f));
|
|
||||||
models_.push_back(model);
|
|
||||||
world_->add_entity(model);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Logger::info(sstr("Created ", models_.size(), " models in scene"));
|
|
||||||
|
// Load the gunslinger model
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
Logger::info("Scene setup complete");
|
Logger::info("Scene setup complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,22 +189,44 @@ 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
|
|
||||||
angle_ += 32.0 * delta_time;
|
|
||||||
|
|
||||||
// Update rotation for all models
|
|
||||||
for (auto& model : models_) {
|
|
||||||
model->set_rotation(glm::vec3(
|
|
||||||
0.0f, glm::radians(static_cast<float>(angle_)), 0.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update world
|
// Update world
|
||||||
world_->update(static_cast<float>(delta_time));
|
world_->update(static_cast<float>(delta_time));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
16
src/main.cpp
16
src/main.cpp
@@ -1,6 +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
|
||||||
|
#include "../lib/stb_image.h"
|
||||||
|
|
||||||
|
#define TINYOBJLOADER_IMPLEMENTATION
|
||||||
|
#include "../lib/tiny_obj_loader.h"
|
||||||
|
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
|
||||||
@@ -12,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;
|
||||||
}
|
}
|
||||||
|
|||||||
61
src/material.cpp
Normal file
61
src/material.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#include "material.h"
|
||||||
|
|
||||||
|
#include "../lib/glm/glm.hpp"
|
||||||
|
|
||||||
|
#include "shader.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
|
Material::Material(const std::shared_ptr<Texture>& tex,
|
||||||
|
const std::shared_ptr<Shader>& shader)
|
||||||
|
: shader_(shader), texture_(tex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<Shader>& Material::shader() const
|
||||||
|
{
|
||||||
|
return shader_ ? shader_ : state::default_shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Shader>& Material::shader()
|
||||||
|
{
|
||||||
|
return shader_ ? shader_ : state::default_shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::set_shader(const std::shared_ptr<Shader>& shader)
|
||||||
|
{
|
||||||
|
shader_ = shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::prepare()
|
||||||
|
{
|
||||||
|
// Activate shader
|
||||||
|
std::shared_ptr<Shader> active_shader = shader();
|
||||||
|
if (!active_shader)
|
||||||
|
return;
|
||||||
|
|
||||||
|
active_shader->use();
|
||||||
|
|
||||||
|
// Set uniform variables
|
||||||
|
const glm::mat4 mvp =
|
||||||
|
state::projection_matrix * state::view_matrix * state::model_matrix;
|
||||||
|
const int mvp_loc = active_shader->uniform_location("mvp");
|
||||||
|
Shader::set_mat4(mvp_loc, mvp);
|
||||||
|
|
||||||
|
// Set texture-related uniforms
|
||||||
|
const int use_texture_loc =
|
||||||
|
active_shader->uniform_location("useTexture");
|
||||||
|
if (texture_) {
|
||||||
|
Shader::set_int(use_texture_loc, 1);
|
||||||
|
const int sampler_loc =
|
||||||
|
active_shader->uniform_location("texSampler");
|
||||||
|
Shader::set_int(sampler_loc, 0); // Texture unit 0
|
||||||
|
} else {
|
||||||
|
Shader::set_int(use_texture_loc, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind texture if available
|
||||||
|
if (texture_) {
|
||||||
|
texture_->bind();
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/material.h
Normal file
35
src/material.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef MATERIAL_H_
|
||||||
|
#define MATERIAL_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class Shader;
|
||||||
|
class Texture;
|
||||||
|
|
||||||
|
class Material {
|
||||||
|
public:
|
||||||
|
Material(const std::shared_ptr<Texture>& tex = nullptr,
|
||||||
|
const std::shared_ptr<Shader>& shader = nullptr);
|
||||||
|
~Material() = default;
|
||||||
|
|
||||||
|
[[nodiscard]] const std::shared_ptr<Shader>& shader() const;
|
||||||
|
[[nodiscard]] std::shared_ptr<Shader>& shader();
|
||||||
|
void set_shader(const std::shared_ptr<Shader>& shader);
|
||||||
|
|
||||||
|
[[nodiscard]] const std::shared_ptr<Texture>& texture() const
|
||||||
|
{
|
||||||
|
return texture_;
|
||||||
|
}
|
||||||
|
void set_texture(const std::shared_ptr<Texture>& tex)
|
||||||
|
{
|
||||||
|
texture_ = tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepare();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<Shader> shader_;
|
||||||
|
std::shared_ptr<Texture> texture_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MATERIAL_H_
|
||||||
197
src/mesh.cpp
197
src/mesh.cpp
@@ -1,33 +1,194 @@
|
|||||||
#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 "shader.h"
|
#include "shader.h"
|
||||||
#include "state.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];
|
||||||
|
}
|
||||||
|
|
||||||
|
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 std::shared_ptr<Shader>& shader)
|
const Material& material)
|
||||||
{
|
{
|
||||||
buffers_.push_back(buffer);
|
buffers_.push_back(buffer);
|
||||||
shaders_.push_back(shader);
|
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()
|
||||||
{
|
{
|
||||||
// Calculate MVP matrix
|
// Draw each buffer with its material
|
||||||
glm::mat4 mvp = state::projection_matrix * state::view_matrix
|
|
||||||
* state::model_matrix;
|
|
||||||
|
|
||||||
// Draw each buffer with its shader
|
|
||||||
for (size_t i = 0; i < buffers_.size(); ++i) {
|
for (size_t i = 0; i < buffers_.size(); ++i) {
|
||||||
// Use buffer's shader if available, otherwise use default
|
materials_[i].prepare();
|
||||||
// shader
|
buffers_[i]->draw(*materials_[i].shader());
|
||||||
std::shared_ptr<Shader> shader =
|
|
||||||
shaders_[i] ? shaders_[i] : state::default_shader;
|
|
||||||
|
|
||||||
if (shader) {
|
|
||||||
shader->use();
|
|
||||||
int mvpLoc = shader->uniform_location("mvp");
|
|
||||||
Shader::set_mat4(mvpLoc, mvp);
|
|
||||||
buffers_[i]->draw(*shader);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/mesh.h
19
src/mesh.h
@@ -4,6 +4,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "material.h"
|
||||||
|
|
||||||
class Buffer;
|
class Buffer;
|
||||||
class Shader;
|
class Shader;
|
||||||
|
|
||||||
@@ -12,8 +14,12 @@ 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 std::shared_ptr<Shader>& shader = nullptr);
|
const Material& material);
|
||||||
|
|
||||||
[[nodiscard]] size_t num_buffers() const
|
[[nodiscard]] size_t num_buffers() const
|
||||||
{
|
{
|
||||||
@@ -28,11 +34,20 @@ public:
|
|||||||
return buffers_[index];
|
return buffers_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const Material& material(size_t index) const
|
||||||
|
{
|
||||||
|
return materials_[index];
|
||||||
|
}
|
||||||
|
[[nodiscard]] Material& material(size_t index)
|
||||||
|
{
|
||||||
|
return materials_[index];
|
||||||
|
}
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::shared_ptr<Buffer>> buffers_;
|
std::vector<std::shared_ptr<Buffer>> buffers_;
|
||||||
std::vector<std::shared_ptr<Shader>> shaders_;
|
std::vector<Material> materials_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MESH_H_
|
#endif // MESH_H_
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "vertex.h"
|
#include "vertex.h"
|
||||||
|
|
||||||
Shader::Shader(const std::string& vertexPath, const std::string& fragmentPath)
|
Shader::Shader(const std::string& vertex_path, const std::string& fragment_path)
|
||||||
{
|
{
|
||||||
const uint32_t vshader = compile_shader(GL_VERTEX_SHADER, vertexPath);
|
const uint32_t vshader = compile_shader(GL_VERTEX_SHADER, vertex_path);
|
||||||
const uint32_t fshader =
|
const uint32_t fshader =
|
||||||
compile_shader(GL_FRAGMENT_SHADER, fragmentPath);
|
compile_shader(GL_FRAGMENT_SHADER, fragment_path);
|
||||||
|
|
||||||
if (vshader == 0 || fshader == 0) {
|
if (vshader == 0 || fshader == 0) {
|
||||||
program_id_ = 0;
|
program_id_ = 0;
|
||||||
@@ -65,6 +65,14 @@ void Shader::setup_attribs() const
|
|||||||
loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||||
reinterpret_cast<const void*>(offsetof(Vertex, color)));
|
reinterpret_cast<const void*>(offsetof(Vertex, color)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loc = glGetAttribLocation(program_id_, "vtexcoord");
|
||||||
|
if (loc != -1) {
|
||||||
|
glEnableVertexAttribArray(loc);
|
||||||
|
glVertexAttribPointer(
|
||||||
|
loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||||
|
reinterpret_cast<const void*>(offsetof(Vertex, tex_coord)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Shader::uniform_location(const char* key) const
|
int Shader::uniform_location(const char* key) const
|
||||||
@@ -141,9 +149,8 @@ uint32_t Shader::compile_shader(uint32_t type, const std::string& source_path)
|
|||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
glGetShaderInfoLog(shader, sizeof(buffer), nullptr, buffer);
|
glGetShaderInfoLog(shader, sizeof(buffer), nullptr, buffer);
|
||||||
error_ = buffer;
|
error_ = buffer;
|
||||||
Logger::error(
|
Logger::error(sstr("Shader compilation failed (",
|
||||||
sstr("Shader compilation failed (", shader_type_name, "): ",
|
shader_type_name, "): ", buffer));
|
||||||
buffer));
|
|
||||||
glDeleteShader(shader);
|
glDeleteShader(shader);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
81
src/texture.cpp
Normal file
81
src/texture.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#include "texture.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "../lib/glew/GL/glew.h"
|
||||||
|
#include "../lib/glfw/glfw3.h"
|
||||||
|
#include "../lib/stb_image.h"
|
||||||
|
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
Texture::Texture(uint32_t id, const glm::ivec2& size)
|
||||||
|
: id_(id), size_(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture::~Texture()
|
||||||
|
{
|
||||||
|
if (id_ != 0) {
|
||||||
|
glDeleteTextures(1, &id_);
|
||||||
|
Logger::info(sstr("Texture ", id_, " destroyed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Texture> Texture::load(const char* filename)
|
||||||
|
{
|
||||||
|
Logger::info(sstr("Loading texture: ", filename));
|
||||||
|
|
||||||
|
// Load image
|
||||||
|
int width, height, channels;
|
||||||
|
stbi_uc* pixels =
|
||||||
|
stbi_load(filename, &width, &height, &channels, STBI_rgb_alpha);
|
||||||
|
|
||||||
|
if (!pixels) {
|
||||||
|
Logger::error(sstr("Failed to load texture: ", filename, " - ",
|
||||||
|
stbi_failure_reason()));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flip image vertically (OpenGL expects bottom row first)
|
||||||
|
const int row_size = width * 4; // 4 channels (RGBA)
|
||||||
|
auto* row_buffer = new stbi_uc[row_size];
|
||||||
|
for (int y = 0; y < height / 2; ++y) {
|
||||||
|
stbi_uc* row1 = pixels + y * row_size;
|
||||||
|
stbi_uc* row2 = pixels + (height - 1 - y) * row_size;
|
||||||
|
std::copy(row1, row1 + row_size, row_buffer);
|
||||||
|
std::copy(row2, row2 + row_size, row1);
|
||||||
|
std::copy(row_buffer, row_buffer + row_size, row2);
|
||||||
|
}
|
||||||
|
delete[] row_buffer;
|
||||||
|
|
||||||
|
// Generate OpenGL texture
|
||||||
|
GLuint texture_id;
|
||||||
|
glGenTextures(1, &texture_id);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||||
|
|
||||||
|
// Upload texture data
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
|
||||||
|
GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
|
// Set trilinear filtering
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||||
|
GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
// Generate mipmaps
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
// Free image data
|
||||||
|
stbi_image_free(pixels);
|
||||||
|
|
||||||
|
Logger::info(sstr("Texture loaded successfully: ", filename, " (",
|
||||||
|
width, "x", height, ", ", channels, " channels)"));
|
||||||
|
|
||||||
|
return std::shared_ptr<Texture>(
|
||||||
|
new Texture(texture_id, glm::ivec2(width, height)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::bind() const
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, id_);
|
||||||
|
}
|
||||||
35
src/texture.h
Normal file
35
src/texture.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef TEXTURE_H_
|
||||||
|
#define TEXTURE_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "../lib/glm/glm.hpp"
|
||||||
|
|
||||||
|
class Texture {
|
||||||
|
public:
|
||||||
|
Texture() = delete;
|
||||||
|
~Texture();
|
||||||
|
|
||||||
|
static std::shared_ptr<Texture> load(const char* filename);
|
||||||
|
|
||||||
|
[[nodiscard]] uint32_t id() const
|
||||||
|
{
|
||||||
|
return id_;
|
||||||
|
}
|
||||||
|
[[nodiscard]] const glm::ivec2& size() const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Texture(uint32_t id, const glm::ivec2& size);
|
||||||
|
|
||||||
|
uint32_t id_;
|
||||||
|
glm::ivec2 size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TEXTURE_H_
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
struct Vertex {
|
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};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VERTEX_H_
|
#endif // VERTEX_H_
|
||||||
|
|||||||
@@ -159,15 +159,18 @@
|
|||||||
<ClInclude Include="lib\glew\GL\glew.h" />
|
<ClInclude Include="lib\glew\GL\glew.h" />
|
||||||
<ClInclude Include="lib\glfw\glfw3.h" />
|
<ClInclude Include="lib\glfw\glfw3.h" />
|
||||||
<ClInclude Include="lib\glfw\glfw3native.h" />
|
<ClInclude Include="lib\glfw\glfw3native.h" />
|
||||||
|
<ClInclude Include="lib\stb\stb_image.h" />
|
||||||
<ClInclude Include="src\buffer.h" />
|
<ClInclude Include="src\buffer.h" />
|
||||||
<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\logger.h" />
|
<ClInclude Include="src\logger.h" />
|
||||||
|
<ClInclude Include="src\material.h" />
|
||||||
<ClInclude Include="src\mesh.h" />
|
<ClInclude Include="src\mesh.h" />
|
||||||
<ClInclude Include="src\model.h" />
|
<ClInclude Include="src\model.h" />
|
||||||
<ClInclude Include="src\shader.h" />
|
<ClInclude Include="src\shader.h" />
|
||||||
<ClInclude Include="src\state.h" />
|
<ClInclude Include="src\state.h" />
|
||||||
|
<ClInclude Include="src\texture.h" />
|
||||||
<ClInclude Include="src\vertex.h" />
|
<ClInclude Include="src\vertex.h" />
|
||||||
<ClInclude Include="src\world.h" />
|
<ClInclude Include="src\world.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -179,15 +182,17 @@
|
|||||||
<ClCompile Include="src\entity.cpp" />
|
<ClCompile Include="src\entity.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\mesh.cpp" />
|
<ClCompile Include="src\mesh.cpp" />
|
||||||
<ClCompile Include="src\model.cpp" />
|
<ClCompile Include="src\model.cpp" />
|
||||||
<ClCompile Include="src\shader.cpp" />
|
<ClCompile Include="src\shader.cpp" />
|
||||||
|
<ClCompile Include="src\texture.cpp" />
|
||||||
<ClCompile Include="src\vertex.cpp" />
|
<ClCompile Include="src\vertex.cpp" />
|
||||||
<ClCompile Include="src\world.cpp" />
|
<ClCompile Include="src\world.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="data\fragment.glsl" />
|
<None Include="data\shaders\fragment.glsl" />
|
||||||
<None Include="data\vertex.glsl" />
|
<None Include="data\shaders\vertex.glsl" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
<Filter Include="glew">
|
<Filter Include="glew">
|
||||||
<UniqueIdentifier>{296e1ba9-28bc-4e0b-8d4e-413551edca96}</UniqueIdentifier>
|
<UniqueIdentifier>{296e1ba9-28bc-4e0b-8d4e-413551edca96}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="stb">
|
||||||
|
<UniqueIdentifier>{e3c5a7f2-1d4b-4a9c-8f2e-9b5c8d7a6e4f}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
<Filter Include="Shaders">
|
<Filter Include="Shaders">
|
||||||
<UniqueIdentifier>{0628083b-a31c-4825-822c-11b6f933e7bd}</UniqueIdentifier>
|
<UniqueIdentifier>{0628083b-a31c-4825-822c-11b6f933e7bd}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
@@ -33,6 +36,9 @@
|
|||||||
<ClInclude Include="lib\glew\GL\glew.h">
|
<ClInclude Include="lib\glew\GL\glew.h">
|
||||||
<Filter>glew</Filter>
|
<Filter>glew</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="lib\stb\stb_image.h">
|
||||||
|
<Filter>stb</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="src\vertex.h">
|
<ClInclude Include="src\vertex.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -66,6 +72,12 @@
|
|||||||
<ClInclude Include="src\logger.h">
|
<ClInclude Include="src\logger.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\material.h">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\texture.h">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\main.cpp">
|
<ClCompile Include="src\main.cpp">
|
||||||
@@ -104,12 +116,18 @@
|
|||||||
<ClCompile Include="src\logger.cpp">
|
<ClCompile Include="src\logger.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\material.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\texture.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="data\fragment.glsl">
|
<None Include="data\shaders\fragment.glsl">
|
||||||
<Filter>Shaders</Filter>
|
<Filter>Shaders</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\vertex.glsl">
|
<None Include="data\shaders\vertex.glsl">
|
||||||
<Filter>Shaders</Filter>
|
<Filter>Shaders</Filter>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user