Skip to content

Commit 46acc05

Browse files
committed
added basic rendering
0 parents  commit 46acc05

22 files changed

+37539
-0
lines changed

.gitignore

Whitespace-only changes.

FullScreenQuad.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import numpy as np
2+
from OpenGL.GL import *
3+
from Shader import *
4+
from MaterialData import*
5+
import pyrr
6+
7+
'''
8+
objects of this class can draw a fullscreen 2d plane covering whole screen .
9+
'''
10+
11+
class FullScreenQuad:
12+
13+
def __init__(self , fname):
14+
self.shader = Shader(fname)
15+
self.mat = MaterialData()
16+
self.identityMat = pyrr.matrix44.create_identity()
17+
vertices = [-1 , 1 , -1 , -1 , 1 , 1 , 1 , -1]
18+
vertices = np.array(vertices, dtype='float32')
19+
self.vao = glGenVertexArrays(1)
20+
glBindVertexArray(self.vao)
21+
self.vbo = glGenBuffers(1)
22+
glBindBuffer(GL_ARRAY_BUFFER, self.vbo);
23+
glBufferData(GL_ARRAY_BUFFER,8*4 , vertices, GL_STATIC_DRAW)
24+
glEnableVertexAttribArray(0);
25+
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, None);
26+
27+
glBindVertexArray(0);
28+
29+
def renderFullScreenQuad(self):
30+
self.shader.bind()
31+
self.shader.updateUniforms(self.identityMat , self.identityMat ,self.identityMat , self.mat)
32+
glBindVertexArray(self.vao)
33+
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
34+
glBindVertexArray(0);

MaterialData.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import numpy as np
2+
3+
'''
4+
just a placeholder for storing material values
5+
'''
6+
class MaterialData:
7+
def __init__(self):
8+
self.diffuse = "None"
9+
self.specularIntensity = 0.0
10+
self.specularPower = 0.0
11+
12+
self.reflectAmt = 0.0
13+
self.reflectColor = [0.0 , 0.0 , 0.0]
14+
self.refractAmt = 0.0
15+
self.refractColor = [0.0 , 0.0 , 0.0]

Mesh.py

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import numpy as np
2+
import MeshData
3+
import MaterialData
4+
import Texture
5+
from Shader import *
6+
from OpenGL.GL import *
7+
8+
'''
9+
this class loads .obj and .mat files from harddrive and render it on screen
10+
11+
'''
12+
13+
class Mesh:
14+
def __init__(self , OBJname , MATname): #loads .obj and .mat files
15+
self.meshData = []
16+
self.materialData = []
17+
self.count = 0
18+
self.VBOs = []
19+
self.VAOs = []
20+
self.shader = Shader("./shaders/diffuseSpec") #loads the master shader
21+
self.textures = []
22+
self.loadMesh(OBJname)
23+
self.loadMaterial(MATname)
24+
self.loadDataInGPU()
25+
26+
def loadMaterial(self , fname):
27+
for line in open(fname, 'r'):
28+
if line.startswith('#'): continue
29+
values = line.split()
30+
if not values: continue
31+
if values[0] == 'o':
32+
data = []
33+
data = MaterialData.MaterialData()
34+
self.materialData.append(data)
35+
if values[0] == 'diffuse':
36+
data.diffuse = values[2]
37+
self.textures.append(Texture.Texture("./res/" + data.diffuse))
38+
if values[0] == 'specularIntensity':
39+
data.specularIntensity = np.float32(float(values[2]))
40+
if values[0] == 'specularPower':
41+
data.specularPower = np.float32(float(values[2]))
42+
if values[0] == 'reflectAmt':
43+
data.reflectAmt = np.float32(float(values[2]))
44+
if values[0] == 'reflectColor':
45+
data.reflectColor[0] = np.float32(float(values[1]))
46+
data.reflectColor[1] = np.float32(float(values[2]))
47+
data.reflectColor[2] = np.float32(float(values[3]))
48+
49+
if values[0] == 'refractAmt':
50+
data.refractAmt = np.float32(float(values[2]))
51+
if values[0] == 'refractColor':
52+
data.refractColor[0]= np.float32(float(values[1]))
53+
data.refractColor[1]= np.float32(float(values[2]))
54+
data.refractColor[2]= np.float32(float(values[3]))
55+
56+
57+
58+
def loadMesh(self, fname):
59+
data = []
60+
for line in open(fname, 'r'):
61+
if line.startswith('#'): continue
62+
values = line.split()
63+
if not values: continue
64+
65+
if values[0] == 'o':
66+
data = []
67+
data = MeshData.MeshData()
68+
self.meshData.append(data)
69+
self.count = self.count + 1
70+
for c in values[1:]:
71+
data.name += c
72+
73+
if values[0] == 'v':
74+
data.vert_coords.append(values[1:4])
75+
if values[0] == 'vt':
76+
data.text_coords.append(values[1:3])
77+
if values[0] == 'vn':
78+
data.norm_coords.append(values[1:4])
79+
80+
if values[0] == 'f':
81+
face_i = []
82+
text_i = []
83+
norm_i = []
84+
for v in values[1:4]:
85+
w = v.split('/')
86+
vOffset = 0
87+
tOffset = 0
88+
nOffset = 0
89+
if (self.count >= 2):
90+
for g in range(self.count - 1):
91+
vOffset += len(self.meshData[g].vert_coords)
92+
tOffset += len(self.meshData[g].text_coords)
93+
nOffset += len(self.meshData[g].norm_coords)
94+
face_i.append(int(w[0]) - 1 - vOffset)
95+
text_i.append(int(w[1]) - 1 - tOffset)
96+
norm_i.append(int(w[2]) - 1 - nOffset)
97+
data.vertex_index.append(face_i)
98+
data.texture_index.append(text_i)
99+
data.normal_index.append(norm_i)
100+
101+
for k in range(self.count):
102+
self.meshData[k].vertex_index = [y for x in self.meshData[k].vertex_index for y in x]
103+
self.meshData[k].texture_index = [y for x in self.meshData[k].texture_index for y in x]
104+
self.meshData[k].normal_index = [y for x in self.meshData[k].normal_index for y in x]
105+
106+
for i in self.meshData[k].vertex_index:
107+
self.meshData[k].model.extend(self.meshData[k].vert_coords[i])
108+
109+
for i in self.meshData[k].texture_index:
110+
self.meshData[k].model.extend(self.meshData[k].text_coords[i])
111+
112+
for i in self.meshData[k].normal_index:
113+
self.meshData[k].model.extend(self.meshData[k].norm_coords[i])
114+
115+
self.meshData[k].model = np.array(self.meshData[k].model, dtype='float32')
116+
117+
118+
def loadDataInGPU(self):
119+
for i in range(self.count):
120+
texture_offset = len(self.meshData[i].vertex_index) * 12
121+
normal_offset = (texture_offset + len(self.meshData[i].texture_index) * 8)
122+
self.VAOs.append(glGenVertexArrays(1))
123+
glBindVertexArray(self.VAOs[i])
124+
self.VBOs.append(glGenBuffers(1))
125+
126+
glBindBuffer(GL_ARRAY_BUFFER, self.VBOs[i])
127+
glBufferData(GL_ARRAY_BUFFER, self.meshData[i].model.itemsize * len(self.meshData[i].model),
128+
self.meshData[i].model, GL_STATIC_DRAW)
129+
130+
# position
131+
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, self.meshData[i].model.itemsize * 3,
132+
ctypes.c_void_p(0))
133+
glEnableVertexAttribArray(0)
134+
# texture
135+
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, self.meshData[i].model.itemsize * 2,
136+
ctypes.c_void_p(texture_offset))
137+
glEnableVertexAttribArray(1)
138+
#normal
139+
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, self.meshData[i].model.itemsize * 3,
140+
ctypes.c_void_p(normal_offset))
141+
glEnableVertexAttribArray(2)
142+
143+
glBindVertexArray(0)
144+
145+
def renderALL(self , view, projection, model):
146+
self.shader.bind()
147+
148+
for i in range(self.count):
149+
self.textures[i].bind(GL_TEXTURE0)
150+
self.shader.updateUniforms(view , projection , model ,self.materialData[i] )
151+
glBindVertexArray(self.VAOs[i])
152+
glDrawArrays(GL_TRIANGLES, 0, len(self.meshData[i].vertex_index))
153+
glBindVertexArray(0)
154+
155+
156+
157+
158+
159+
160+
161+
162+
163+
164+
165+
166+

MeshData.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
'''
3+
placeholder for different attributes of mesh
4+
'''
5+
class MeshData:
6+
def __init__(self):
7+
self.vert_coords = []
8+
self.text_coords = []
9+
self.norm_coords = []
10+
11+
self.vertex_index = []
12+
self.texture_index = []
13+
self.normal_index = []
14+
self.name = ""
15+
16+
self.model = []

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# OpenGLRenderingEngine
2+
3D real time rendering engine in python
3+
![ScreenShot](/res/sample.png)
4+
5+
# Build Instructions
6+
7+
Just run setup.py to install all dependencies<br/>
8+

Shader.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
from OpenGL.GL import *
2+
import OpenGL.GL.shaders
3+
4+
'''
5+
loads shader from file into memory
6+
'''
7+
8+
class Shader:
9+
10+
def __init__(self , fname):
11+
self.uniformMap = {}
12+
self.shaderProgram = self.compile_shader(fname)
13+
view_loc = glGetUniformLocation(self.shaderProgram, "view")
14+
proj_loc = glGetUniformLocation(self.shaderProgram, "projection")
15+
model_loc = glGetUniformLocation(self.shaderProgram, "model")
16+
17+
specularIntensity_loc = glGetUniformLocation(self.shaderProgram, "specularIntensity")
18+
specularPower_loc = glGetUniformLocation(self.shaderProgram, "specularPower")
19+
20+
reflectAmt_loc = glGetUniformLocation(self.shaderProgram, "reflectAmt")
21+
refractAmt_loc = glGetUniformLocation(self.shaderProgram, "refractAmt")
22+
reflectColor_loc = glGetUniformLocation(self.shaderProgram, "reflectColor")
23+
refractColor_loc = glGetUniformLocation(self.shaderProgram, "refractColor")
24+
diffuse_loc = glGetUniformLocation(self.shaderProgram, "diffuse")
25+
skybox_loc = glGetUniformLocation(self.shaderProgram, "skybox")
26+
mask_loc = glGetUniformLocation(self.shaderProgram, "mask")
27+
self.uniformMap["view"] = view_loc
28+
self.uniformMap["projection"] = proj_loc
29+
self.uniformMap["model"] = model_loc
30+
self.uniformMap["specularIntensity"] = specularIntensity_loc
31+
self.uniformMap["specularPower"] = specularPower_loc
32+
self.uniformMap["reflectAmt"] = reflectAmt_loc
33+
self.uniformMap["refractAmt"] = refractAmt_loc
34+
self.uniformMap["reflectColor"] = reflectColor_loc
35+
self.uniformMap["refractColor"] = refractColor_loc
36+
self.uniformMap["diffuse"] = diffuse_loc
37+
self.uniformMap["skybox"] = skybox_loc
38+
self.uniformMap["mask"] = mask_loc
39+
40+
def updateUniforms(self , view , proj , model , mat):
41+
self.setUniformMat4("view" , view)
42+
self.setUniformMat4("projection" , proj)
43+
self.setUniformMat4("model" , model)
44+
self.setUniformFloat("specularIntensity" , mat.specularIntensity)
45+
self.setUniformFloat("specularPower" , mat.specularPower)
46+
self.setUniformFloat("reflectAmt" , mat.reflectAmt)
47+
self.setUniformFloat("refractAmt" , mat.refractAmt)
48+
self.setUniformVec3("reflectColor" , mat.reflectColor[0] , mat.reflectColor[1] , mat.reflectColor[2])
49+
self.setUniformVec3("refractColor" , mat.refractColor[0] , mat.refractColor[1] , mat.refractColor[2])
50+
self.setUniformSampler("diffuse" , 0);
51+
self.setUniformSampler("skybox" , 1);
52+
self.setUniformSampler("mask" , 2);
53+
54+
def setUniformMat4(self , uName , value):
55+
glUniformMatrix4fv(self.uniformMap[uName], 1, GL_FALSE, value)
56+
def setUniformMat3(self , uName , value):
57+
glUniformMatrix4fv(self.uniformMap[uName], 1, GL_FALSE, value)
58+
def setUnifromVec4(self , uName , x , y , z ,w ):
59+
glUniform4f(self.uniformMap[uName], x, y, z, w)
60+
def setUniformVec3(self , uName , x , y , z ):
61+
glUniform3f(self.uniformMap[uName], x, y, z)
62+
def setUniformFloat(self , uName , x):
63+
glUniform1f(self.uniformMap[uName], x)
64+
def setUniformSampler(self , uName , x):
65+
glUniform1i(self.uniformMap[uName], x);
66+
67+
def bind(self):
68+
glUseProgram(self.shaderProgram)
69+
70+
def load_shader(self , shader_file):
71+
shader_source = ""
72+
with open(shader_file) as f:
73+
shader_source = f.read()
74+
f.close()
75+
return str.encode(shader_source)
76+
77+
def compile_shader(self ,fname):
78+
vert_shader = self.load_shader(fname + ".vs")
79+
frag_shader = self.load_shader(fname + ".fs")
80+
81+
shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vert_shader, GL_VERTEX_SHADER),
82+
OpenGL.GL.shaders.compileShader(frag_shader, GL_FRAGMENT_SHADER))
83+
return shader
84+
85+
86+
87+
88+

Texture.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from PIL import Image
2+
from OpenGL.GL import *
3+
import numpy
4+
5+
'''
6+
loads a 2d texture from file into memory
7+
'''
8+
class Texture:
9+
def __init__(self , fname):
10+
self.texture_id = 0
11+
self.width= 0
12+
self.height= 0
13+
self.loadTexture(fname)
14+
def loadTexture(self , fname):
15+
self.texture_id = glGenTextures(1)
16+
glBindTexture(GL_TEXTURE_2D, self.texture_id)
17+
# Set the texture wrapping parameters
18+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
19+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
20+
# Set texture filtering parameters
21+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
22+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
23+
glGenerateMipmap(GL_TEXTURE_2D)
24+
# load image
25+
image = Image.open(fname)
26+
self.width = image.size[0]
27+
self.height = image.size[1]
28+
29+
flipped_image = image.transpose(Image.FLIP_TOP_BOTTOM)
30+
31+
img_data = numpy.array(list(flipped_image.getdata()), numpy.uint8)
32+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, self.width, self.height, 0, GL_RGB,
33+
GL_UNSIGNED_BYTE, img_data)
34+
glEnable(GL_TEXTURE_2D)
35+
def bind(self , id):
36+
glActiveTexture(id)
37+
glBindTexture(GL_TEXTURE_2D , self.texture_id)

0 commit comments

Comments
 (0)