[solved] OpenGL GLSL shader tutorial example translated, but not working

Started by
0 comments, last by gamedev199191 12 years, 2 months ago
Hi,

I've been converting the "OpenGL Tutorials for the modern graphics programmer" (see here) from the C it is written in, to Python using the gletools module. Up to this point, each direct Python conversion works exactly as the original C version did. And if it doesn't, it has been due to something not being converted across correctly.

However, having converted the Lesson 6 / Translation example (see here) over to Python, it just won't work. I've gone over the original code side by side with the Python conversion several times and found all the differences, but with no discernable differences remaining (besides the implementation language).. I'm at a loss for why it won't work.

The code executes without error, but does not display anything. Whereas the C version displays three rainbow coloured shapes that move around. I've debugged the Python and C version to ensure that all values are the same.

Can anyone see anything incorrect?

The code is also attached to this post, but pyglet (1.2dev or later) and gletools (from pypi is fine) both need to be installed if it is to be run.

import ctypes
import time
import math
import pyglet
from pyglet.gl import *
from gletools import ShaderProgram, FragmentShader, VertexShader
window = pyglet.window.Window(width=500, height=500)
modelToCameraMatrixUnif = None
cameraToClipMatrixUnif = None
cameraToClipMatrix = (GLfloat * 16)(*([ 0.0 ] * 16))
def CalcFrustumScale(fFovDeg):
degToRad = 3.14159 * 2.0 / 360.0
fFovRad = fFovDeg * degToRad
return 1.0 / math.tan(fFovRad / 2.0)
fFrustrumScale = CalcFrustumScale(45.0)
def InitializeProgram():
global cameraToClipMatrix
global modelToCameraMatrixUnif
global cameraToClipMatrixUnif
modelToCameraMatrixUnif = program.uniform_location("modelToCameraMatrix")
cameraToClipMatrixUnif = program.uniform_location("cameraToClipMatrix")
fzNear = 1.0
fzFar = 45.0
cameraToClipMatrix[0] = fFrustrumScale # Column 0.x
cameraToClipMatrix[5] = fFrustrumScale # Column 1.y
cameraToClipMatrix[10] = (fzFar + fzNear) / (fzNear - fzFar) # Column 2.z
cameraToClipMatrix[11] = -1.0 # Column3.z
cameraToClipMatrix[14] = (2 * fzFar * fzNear) / (fzNear - fzFar) # Column 3.w
with program:
glUniformMatrix4fv(cameraToClipMatrixUnif, 1, GL_FALSE, cameraToClipMatrix)

GREEN_COLOR = 0.0, 1.0, 0.0, 1.0
BLUE_COLOR = 0.0, 0.0, 1.0, 1.0
RED_COLOR = 1.0, 0.0, 0.0, 1.0
GREY_COLOR = 0.8, 0.8, 0.8, 1.0
BROWN_COLOR = 0.5, 0.5, 0.0, 1.0
vertexData = [
+1.0, +1.0, +1.0,
-1.0, -1.0, +1.0,
-1.0, +1.0, -1.0,
+1.0, -1.0, -1.0,
-1.0, -1.0, -1.0,
+1.0, +1.0, -1.0,
+1.0, -1.0, +1.0,
-1.0, +1.0, +1.0,
]
numberOfVertices = len(vertexData) / 3
colours = [
GREEN_COLOR,
BLUE_COLOR,
RED_COLOR,
BROWN_COLOR,
GREEN_COLOR,
BLUE_COLOR,
RED_COLOR,
BROWN_COLOR,
]
for colour in colours:
vertexData.extend(colour)
vertexDataGl = (GLfloat * len(vertexData))(*vertexData)
sizeof_GLfloat = ctypes.sizeof(GLfloat)
indexData = [
0, 1, 2,
1, 0, 3,
2, 3, 0,
3, 2, 1,
5, 4, 6,
4, 5, 7,
7, 6, 4,
6, 7, 5,
]
indexDataGl = (GLushort * len(indexData))(*indexData)
sizeof_GLushort = ctypes.sizeof(GLushort)

program = ShaderProgram(
FragmentShader('''
#version 330
smooth in vec4 theColor;
out vec4 outputColor;
void main()
{
outputColor = theColor;
}
'''),
VertexShader('''
#version 330
layout (location = 0) in vec4 position;
layout (location = 1) in vec4 color;
smooth out vec4 theColor;
uniform mat4 cameraToClipMatrix;
uniform mat4 modelToCameraMatrix;
void main()
{
vec4 cameraPos = modelToCameraMatrix * position;
gl_Position = cameraToClipMatrix * cameraPos;
theColor = color;
}
''')
)

vertexBufferObject = GLuint()
indexBufferObject = GLuint()
vao = GLuint()

def InitializeVertexBuffer():
global vertexBufferObject, indexBufferObject
glGenBuffers(1, vertexBufferObject)
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject)
glBufferData(GL_ARRAY_BUFFER, len(vertexDataGl)*sizeof_GLfloat, vertexDataGl, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glGenBuffers(1, indexBufferObject)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, len(indexDataGl)*sizeof_GLushort, indexDataGl, GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

def _StationaryOffset(fElapsedTime):
return [ 0.0, 0.0, -20.0 ]
def _OvalOffset(fElapsedTime):
fLoopDuration = 3.0
fScale = 3.14159 * 2.0 / fLoopDuration
fCurrTimeThroughLoop = math.fmod(fElapsedTime, fLoopDuration)
return [ math.cos(fCurrTimeThroughLoop * fScale) * 4.0, math.sin(fCurrTimeThroughLoop * fScale) * 6.0, -20.0 ]
def _BottomCircleOffset(fElapsedTime):
fLoopDuration = 12.0
fScale = 3.14159 * 2.0 / fLoopDuration
fCurrTimeThroughLoop = math.fmod(fElapsedTime, fLoopDuration)
return [ math.cos(fCurrTimeThroughLoop * fScale) * 5.0, -3.5, math.sin(fCurrTimeThroughLoop * fScale) * 5.0 - 20.0 ]
def ConstructMatrix(f, fElapsedTime):
theMat = (GLfloat * 16)(*([ 0.0 ] * 16))
theMat[0] = 1.0 # column 0, row 0 / x
theMat[5] = 1.0 # column 1, row 1 / y
theMat[10] = 1.0 # column 2, row 2 / z
theMat[15] = 1.0 # column 3, row 3 / w
wVec3 = f(fElapsedTime)
theMat[3] = wVec3[0] # column 3, row 0 / x
theMat[7] = wVec3[1] # column 3, row 1 / y
theMat[11] = wVec3[2] # column 3, row 2 / z
return theMat
objects = [
_StationaryOffset,
_OvalOffset,
_BottomCircleOffset,
]
def init():
global vao
InitializeProgram()
InitializeVertexBuffer()
glGenVertexArrays(1, vao)
glBindVertexArray(vao)
colorDataOffset = sizeof_GLfloat * 3 * numberOfVertices
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject)
glEnableVertexAttribArray(0)
glEnableVertexAttribArray(1)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, colorDataOffset)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject)
glBindVertexArray(0)
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
glFrontFace(GL_CW)
glEnable(GL_DEPTH_TEST)
glDepthMask(GL_TRUE)
glDepthFunc(GL_LEQUAL)
glDepthRange(0.0, 1.0)
@window.event
def on_draw():
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
with program:
glBindVertexArray(vao)
elapsedTime = time.clock()
for f in objects:
transformMatrix = ConstructMatrix(f, elapsedTime)
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, transformMatrix)
glDrawElements(GL_TRIANGLES, len(indexData), GL_UNSIGNED_SHORT, 0)
glBindVertexArray(0)
@window.event
def on_resize(width, height):
cameraToClipMatrix[0] = fFrustrumScale / (height / float(width))
cameraToClipMatrix[5] = fFrustrumScale
with program:
glUniformMatrix4fv(cameraToClipMatrixUnif, 1, GL_FALSE, cameraToClipMatrix)
glViewport(0, 0, width, height)
return pyglet.event.EVENT_HANDLED
init()

def update(dt):
pass
pyglet.clock.schedule_interval(update, 1/60.0)
pyglet.app.run()
Advertisement
Aha, got it. I assumed the float ordering in the matrices was row after row, rather than column after column. Changing that fixes it :-)

This topic is closed to new replies.

Advertisement