From c744cdd099b6f93ed019e69a4751a74f3113c062 Mon Sep 17 00:00:00 2001 From: Thomas FORGIONE Date: Fri, 25 Nov 2016 11:27:05 +0100 Subject: [PATCH] Using shaders --- controls/Controls.py | 50 +++++++++++++++++++++++++++++++ controls/__init__.py | 0 conv3d/__init__.py | 0 {examples => models}/cube.obj | 0 {examples => models}/link.obj | 0 modelviewer.py | 55 ++++++++++------------------------- shaders/shader.frag | 14 +++++++++ shaders/shader.vert | 6 ++++ 8 files changed, 85 insertions(+), 40 deletions(-) create mode 100644 controls/Controls.py create mode 100644 controls/__init__.py create mode 100644 conv3d/__init__.py rename {examples => models}/cube.obj (100%) rename {examples => models}/link.obj (100%) create mode 100644 shaders/shader.frag create mode 100644 shaders/shader.vert diff --git a/controls/Controls.py b/controls/Controls.py new file mode 100644 index 0000000..92242c9 --- /dev/null +++ b/controls/Controls.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 + +class Controls: + def __init__(self): + pass + + def apply(self): + pass + + def update(self, time = 10): + pass + +class TrackBallControls(Controls): + def __init__(self): + super().__init__(self) + self.vertex = Vertex() + self.theta = 0 + + def apply(self): + glRotatef(self.theta * 180 / math.pi, self.vertex.x, self.vertex.y, self.vertex.z) + + def update(self, time = 10): + + if not pygame.mouse.get_pressed()[0]: + return + + coeff = 0.001 + move = pygame.mouse.get_rel() + + dV = Vertex(move[1] * time * coeff, move[0] * time * coeff, 0) + dTheta = dV.norm2() + + if abs(dTheta) < 0.00001: + return + + dV.normalize() + + cosT2 = math.cos(self.theta / 2) + sinT2 = math.sin(self.theta / 2) + cosDT2 = math.cos(dTheta / 2) + sinDT2 = math.sin(dTheta / 2) + + A = cosT2 * sinDT2 * dV + cosDT2 * sinT2 * self.vertex + sinDT2 * sinT2 * Vertex.cross_product(dV, self.vertex) + + self.theta = 2 * math.acos(cosT2 * cosDT2 - sinT2 * sinDT2 * Vertex.dot(dV, self.vertex)) + + self.vertex = A + self.vertex.normalize() + + diff --git a/controls/__init__.py b/controls/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/conv3d/__init__.py b/conv3d/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/cube.obj b/models/cube.obj similarity index 100% rename from examples/cube.obj rename to models/cube.obj diff --git a/examples/link.obj b/models/link.obj similarity index 100% rename from examples/link.obj rename to models/link.obj diff --git a/modelviewer.py b/modelviewer.py index 9830dc0..0781046 100755 --- a/modelviewer.py +++ b/modelviewer.py @@ -9,12 +9,14 @@ import math from pygame.locals import * from OpenGL.GL import * +from OpenGL.GL.shaders import * from OpenGL.GLU import * from OpenGL.GLUT import * from conv3d.loadmodel import load_model from conv3d.model import Vertex +from controls import TrackBallControls WINDOW_WIDTH = 1024 WINDOW_HEIGHT = 768 @@ -24,42 +26,6 @@ y = 0.5 width = 1 height = 1 -class TrackBallControls: - def __init__(self): - self.vertex = Vertex() - self.theta = 0 - - def apply(self): - glRotatef(self.theta * 180 / math.pi, self.vertex.x, self.vertex.y, self.vertex.z) - - def update(self, time = 10): - - if not pygame.mouse.get_pressed()[0]: - return - - coeff = 0.001 - move = pygame.mouse.get_rel() - - dV = Vertex(move[1] * time * coeff, move[0] * time * coeff, 0) - dTheta = dV.norm2() - - if abs(dTheta) < 0.00001: - return - - dV.normalize() - - cosT2 = math.cos(self.theta / 2) - sinT2 = math.sin(self.theta / 2) - cosDT2 = math.cos(dTheta / 2) - sinDT2 = math.sin(dTheta / 2) - - A = cosT2 * sinDT2 * dV + cosDT2 * sinT2 * self.vertex + sinDT2 * sinT2 * Vertex.cross_product(dV, self.vertex) - - self.theta = 2 * math.acos(cosT2 * cosDT2 - sinT2 * sinDT2 * Vertex.dot(dV, self.vertex)) - - self.vertex = A - self.vertex.normalize() - def init_frame(): @@ -88,15 +54,22 @@ def main(args): glEnable(GL_BLEND) glClearColor(0, 0, 0, 0) - glLightfv(GL_LIGHT0, GL_POSITION, [10,5,7]) - glEnable(GL_LIGHTING) - glEnable(GL_LIGHT0) - running = True model = load_model(args.input) model.generate_vbos() + + VERTEX_SHADER = None + FRAGMENT_SHADER = None + with open('shaders/shader.vert') as f: + VERTEX_SHADER = compileShader(f.read(), GL_VERTEX_SHADER) + with open('shaders/shader.frag') as f: + FRAGMENT_SHADER = compileShader(f.read(), GL_FRAGMENT_SHADER) + + print(VERTEX_SHADER, FRAGMENT_SHADER) + SHADER = compileProgram(VERTEX_SHADER, FRAGMENT_SHADER) + while running: for event in pygame.event.get(): if event.type == pygame.QUIT: @@ -118,7 +91,9 @@ def main(args): glPushMatrix() controls.apply() + glUseProgram(SHADER) model.gl_draw() + glUseProgram(0) glPopMatrix() glFlush() diff --git a/shaders/shader.frag b/shaders/shader.frag new file mode 100644 index 0000000..d1fe7ef --- /dev/null +++ b/shaders/shader.frag @@ -0,0 +1,14 @@ +varying vec3 fNormal; + +vec3 ambientLight = vec3(0.2,0.2,0.2); +vec3 directionnalLight = normalize(vec3(10,5,7)); +vec3 directionnalLightFactor = vec3(0.5,0.5,0.5); + + +void main() { + + vec3 ambientFactor = ambientLight; + vec3 lambertFactor = max(vec3(0.0,0.0,0.0), dot(directionnalLight, fNormal) * directionnalLightFactor); + + gl_FragColor = vec4(ambientFactor + lambertFactor, 1.0); +} diff --git a/shaders/shader.vert b/shaders/shader.vert new file mode 100644 index 0000000..7cfea69 --- /dev/null +++ b/shaders/shader.vert @@ -0,0 +1,6 @@ +varying vec3 fNormal; + +void main() { + fNormal = gl_Normal; + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +}