Skip to content

Commit 1e4f116

Browse files
committed
lesson2.1
1 parent 11c855d commit 1e4f116

File tree

15 files changed

+753
-14
lines changed

15 files changed

+753
-14
lines changed

lesson1.2/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
cache/
2+
nimblecache/
3+
htmldocs/
4+
*.exe

lesson1.2/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Lesson 1.1

lesson1.2/core/camera.nim

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import os, strutils
2+
import nimgl/opengl
3+
import glm
4+
5+
6+
type
7+
Camera* = object
8+
position*: Vec3[GLfloat]
9+
front*: Vec3[GLfloat]
10+
up*: Vec3[GLfloat]
11+
right*: Vec3[GLfloat]
12+
worldUp*: Vec3[GLfloat]
13+
# Eular Angles
14+
yaw*: GLfloat
15+
pitch*: GLfloat
16+
# roll*: GLfloat # чекать
17+
# Camera options
18+
# movementSpeed*: GLfloat
19+
# mouseSensitivity*: GLfloat
20+
zoom*: GLfloat
21+
proc updateCameraVectors(self: var Camera): void;
22+
23+
24+
25+
proc newCamera*(
26+
position: Vec3[GLfloat] = vec3(0.0f, 0.0f, 0.0f),
27+
up: Vec3[GLfloat] = vec3(0.0f, 1.0f, 0.0f),
28+
yaw: GLfloat = -90.0f,
29+
pitch: GLfloat = 0.0f,
30+
zoom: GLfloat = radians(45.0f)
31+
): Camera =
32+
## Constructor with vectors
33+
result.position = position
34+
result.position = position
35+
result.worldUp = up
36+
result.yaw = yaw
37+
result.pitch = pitch
38+
result.zoom = zoom
39+
result.updateCameraVectors()
40+
41+
proc newCamera*(
42+
posX, posY, posZ, upX, upY, upZ, yaw, pitch: GLfloat, zoom: GLfloat = radians(45.0f)
43+
): Camera =
44+
## Constructor with scalars
45+
result.position = vec3(posX, posY, posZ)
46+
result.worldUp = vec3(upX, upY, upZ)
47+
result.yaw = yaw
48+
result.pitch = pitch
49+
result.zoom = zoom
50+
result.updateCameraVectors()
51+
52+
#proc setDirection(self: var Camera): void =
53+
54+
55+
proc getViewMatrix*(self: var Camera): Mat4[GLfloat] =
56+
self.updateCameraVectors()
57+
return lookAt(self.position, self.position + self.front, self.up)
58+
59+
proc updateCameraVectors(self: var Camera): void =
60+
var front: Vec3[GLfloat]
61+
front.x = cos(radians(self.yaw)) * cos(radians(self.pitch))
62+
front.y = sin(radians(self.pitch))
63+
front.z = sin(radians(self.yaw)) * cos(radians(self.pitch))
64+
self.front = normalize(front);
65+
#Also re-calculate the Right and Up vector
66+
self.right = normalize(cross(self.front, self.worldUp)) # Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
67+
self.up = normalize(cross(self.right, self.front))
68+

lesson1.2/core/mesh.nim

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import nimgl/opengl
2+
import glm
3+
import ../core/shader
4+
5+
type
6+
TextureType* = enum
7+
texture_diffuse,
8+
texture_specular,
9+
texture_normal,
10+
texture_height
11+
Texture* = object
12+
id*: GLuint
13+
texType*: TextureType
14+
Vertex* = object
15+
position*: Vec3[GLfloat]
16+
normal*: Vec3[GLfloat]
17+
texCoords*: Vec2[GLfloat]
18+
Mesh* = object
19+
vertices*: seq[Vertex]
20+
indices*: seq[GLuint]
21+
textures*: seq[Texture]
22+
VAO, VBO, EBO: GLuint
23+
24+
proc setupMesh*(mesh: var Mesh): void =
25+
glGenVertexArrays(1, addr mesh.VAO)
26+
glGenBuffers(1, addr mesh.VBO)
27+
glGenBuffers(1, addr mesh.EBO)
28+
29+
glBindVertexArray(mesh.VAO)
30+
glBindBuffer(GL_ARRAY_BUFFER, mesh.VBO)
31+
32+
glBufferData(GL_ARRAY_BUFFER, mesh.vertices.sizeof(), addr mesh.vertices[0], GL_STATIC_DRAW)
33+
34+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.EBO);
35+
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.sizeof(), addr mesh.indices[0], GL_STATIC_DRAW)
36+
# vertex positions
37+
glEnableVertexAttribArray(0.GLuint)
38+
glVertexAttribPointer(0.GLuint, 3.GLint, EGL_FLOAT, false, sizeof(Vertex).GLsizei, cast[pointer](0))
39+
# vertex normals
40+
glEnableVertexAttribArray(1.GLuint)
41+
glVertexAttribPointer(1.GLuint, 3.GLint, EGL_FLOAT, false, sizeof(Vertex).GLsizei, cast[pointer](offsetof(Vertex, normal)))
42+
# vertex texture coords
43+
glEnableVertexAttribArray(2.GLuint)
44+
glVertexAttribPointer(2.GLuint, 2.GLint, EGL_FLOAT, false, sizeof(Vertex).GLsizei, cast[pointer](offsetof(Vertex, texCoords)))
45+
glBindVertexArray(0)
46+
47+
# , shader: var Shader
48+
proc draw*(mesh: var Mesh): void =
49+
50+
if mesh.textures.len > 0:
51+
for textureN in 0..mesh.textures.len-1:
52+
glActiveTexture((GL_TEXTURE0.GLuint + textureN.GLuint).GLEnum) #activate proper texture unit before binding
53+
case (mesh.textures[textureN].texType):
54+
of texture_diffuse:
55+
break
56+
of texture_specular:
57+
break
58+
of texture_normal:
59+
break
60+
of texture_height:
61+
break
62+
else:
63+
errorMessageWriter("Unknown TextureType." & $mesh.textures[textureN].texType)
64+
65+
# now set the sampler to the correct texture unit
66+
#glUniform1i(glGetUniformLocation(shader.ID, (name + number).c_str()), i)
67+
glBindTexture(GL_TEXTURE_2D, mesh.textures[textureN].id)
68+
69+
glActiveTexture(GL_TEXTURE0);
70+
71+
# draw mesh
72+
glBindVertexArray(mesh.VAO);
73+
glDrawElements(GL_TRIANGLES, mesh.indices.len.GLsizei, GL_UNSIGNED_INT, cast[pointer](0));
74+
glBindVertexArray(0);
75+

lesson1.2/core/shader.nim

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import os, strutils
2+
import nimgl/opengl
3+
import glm
4+
5+
6+
type
7+
Shader* = object
8+
id*: GLuint
9+
10+
11+
proc readShader*(filepath: string): cstring =
12+
## Read shader from file with dependencies
13+
try:
14+
var source = splitLines(readFile(filepath))
15+
let path = splitFile(filepath)
16+
17+
for line in 0..source.len-1:
18+
if source[line].find("#include ") != -1:
19+
let file = source[line].splitWhitespace()
20+
source[line] = $readShader(path.dir & "/" & file[1])
21+
return join(source, "\n\r").cstring
22+
except IOError:
23+
echo("ERROR LOAD SHADER " & filepath)
24+
25+
proc statusShader(shader: GLuint) =
26+
## (ECHO ERROR)
27+
var status: int32
28+
glGetShaderiv(shader, GL_COMPILE_STATUS, status.addr);
29+
if status != GL_TRUE.ord:
30+
var
31+
log_length: int32
32+
message = newSeq[char](1024)
33+
res: string
34+
glGetShaderInfoLog(shader, 1024, log_length.addr, message[0].addr);
35+
for i in message:
36+
res &= i
37+
echo res
38+
39+
proc statusProgram(program: GLuint) =
40+
## (ECHO ERROR)
41+
var
42+
log_length: int32
43+
message = newSeq[char](1024)
44+
pLinked: int32
45+
res: string
46+
glGetProgramiv(program, GL_LINK_STATUS, pLinked.addr);
47+
if pLinked != GL_TRUE.ord:
48+
glGetProgramInfoLog(program, 1024, log_length.addr, message[0].addr);
49+
for i in message:
50+
res &= i
51+
echo res
52+
53+
54+
proc newShader*(vertexPath, fragmentPath: string): Shader =
55+
try:
56+
var
57+
vertexCode = readShader(vertexPath)
58+
fragmentCode = readShader(fragmentPath)
59+
60+
let vertex = glCreateShader(GL_VERTEX_SHADER)
61+
glShaderSource(vertex, 1'i32, vertexCode.addr, nil)
62+
glCompileShader(vertex)
63+
statusShader(vertex)
64+
65+
let fragment = glCreateShader(GL_FRAGMENT_SHADER)
66+
glShaderSource(fragment, 1, fragmentCode.addr, nil)
67+
glCompileShader(fragment)
68+
statusShader(fragment)
69+
70+
let program = glCreateProgram()
71+
glAttachShader(program, vertex)
72+
glAttachShader(program, fragment)
73+
glLinkProgram(program)
74+
statusProgram(program)
75+
76+
result.id = program
77+
78+
glDeleteShader(vertex)
79+
glDeleteShader(fragment)
80+
except:
81+
echo("Shader was not loaded!!!")
82+
83+
proc use*(shader: Shader): void =
84+
glUseProgram(shader.id)
85+
86+
proc setBool*(shader: Shader, name: string, value: GLboolean): void =
87+
glUniform1i(glGetUniformLocation(shader.id, name), value.GLint)
88+
89+
proc setInt*(shader: Shader, name: string, value: GLint): void =
90+
glUniform1i(glGetUniformLocation(shader.id, name), value)
91+
92+
proc setFloat*(shader: Shader, name: string, value: GLfloat): void =
93+
glUniform1f(glGetUniformLocation(shader.id, name), value)

lesson1.2/core/texture.nim

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import nimgl/opengl
2+
import ../vendor/stb_image/read as stbi
3+
import os
4+
5+
type
6+
Texture* = ref object
7+
rendererId*: uint32
8+
filepath*: string
9+
localBuffer*: seq[byte]
10+
width*: int
11+
height*: int
12+
bpp*: int
13+
14+
15+
proc newTexture*(filepath: string): Texture =
16+
result = Texture(filepath: filepath)
17+
stbi.setFlipVerticallyOnLoad(false)
18+
result.localBuffer = stbi.load(filepath, result.width, result.height, result.bpp, 4)
19+
glGenTextures(1, result.rendererId.addr)
20+
glBindTexture(GL_TEXTURE_2D, result.rendererId)
21+
22+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR.int32)
23+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR.int32)
24+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE.int32)
25+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE.int32)
26+
27+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8.int32, result.width.int32, result.height.int32, 0,
28+
GL_RGBA, GL_UNSIGNED_BYTE, result.localBuffer[0].addr)
29+
glGenerateMipmap(GL_TEXTURE_2D)
30+
31+
result.localBuffer = @[]
32+
33+
# разобраться в номерах текстур
34+
35+
proc `bind`*(texture: Texture, offset: uint32 = 0) =
36+
if texture.rendererId + offset < 16:
37+
glActiveTexture(GLenum(GL_TEXTURE0.ord + texture.rendererId))
38+
glBindTexture(GL_TEXTURE_2D, texture.rendererId)
39+
40+
# proc `bind`*(texture: Texture, offset: uint32 = 0) =
41+
# if texture.rendererId + offset < 16:
42+
# glActiveTexture(GLenum(GL_TEXTURE0.ord + offset + texture.rendererId))
43+
# glBindTexture(GL_TEXTURE_2D, texture.rendererId)
44+
45+
proc unbind*(texture: Texture) =
46+
glBindTexture(GL_TEXTURE_2D, 0)

0 commit comments

Comments
 (0)