After a fairly long Google Session I have enough from it!
I had a python/opengl application with some simple Quad's where I used gluLookAt to move around on the scene. Then I needed just 1 Texture on one of those Quad's, so I obviously use a shader progam for this single Quad now.
Now when I use gluLookAt, the Quad with the Texture doesn't move, what I also can understand.
Now is there any way to somehow get the gluLookAt function to working with the shader program, get the Current Matrix Stack so I can feed the shader programm with it or do I have to rewrite the hole application and reinvent the glulookup function like he did(either in the shader or on the CPU)?
EDIT1: I use:
python 3.5
PyOpenGL 3.1.0
GLSL 1.4 (According to this list)
EDIT2 (My Solution):
Since I opened this thread, some things have changed but with the guideance of you I managed to get a modern & stable solution.
There are 3 Main components which I have to draw. A static Field, some Lines (for better visualisation) and some Movable Quads.
The Field is now written once to a VBO in an Array. (major improvement compared to single drawing commands)
The moveable squares and lines work on the same principle, but they are dynamic and must be reuploaded with each frame.
Foreach type of object I have a vertex + fragment shader program. I'am aware that I could use just one big one but that's not like it's supposed to be.
Each Matrix (Model,View,Projection) Is assigned to a uniform which then are multiplied with the Vertices from the VBO in the vertex shader.
Field Vertex Shader (Example):
#version 330
uniform mat4 uniform_Model;
uniform mat4 uniform_View;
uniform mat4 uniform_Projection;
in vec3 Quad_Color_Attrib;
in vec3 Quad_Size_Attrib;
out vec3 frag_ColorId;
void main()
{
// Pass the tex coord straight through to the fragment shader
frag_ColorId = Quad_Color_Attrib;
// Remember : inverted !
gl_Position = uniform_Projection * uniform_View * uniform_Model * vec4(Quad_Size_Attrib,1);
}
What I asked for wasn't the right way to do it. (Combining old and new OpenGL) Unfortunatly I can't share the hole code as it is but I here you can find all opengl key codes:
Vertex/Fragment Shader Program Loader:
Initialize Vertex/Fragment Shader (in this case for the field)
def init_field(self, p_VertexShaderPath, p_FragmentShaderPath, p_FieldList, p_FieldCount):
# ############### Field Shader ###############
# Shader Program
self.m_FieldShader = LoadShaders(p_VertexShaderPath, p_FragmentShaderPath)
glUseProgram(self.m_FieldShader)
# VAO
self.m_FieldVAO = glGenVertexArrays(1)
glBindVertexArray(self.m_FieldVAO)
# Field Definition
self.m_FieldCount = p_FieldCount
t_Vertices = []
for t_FieldNr in p_FieldList:
x = p_FieldList[t_FieldNr].m_XPos
y = p_FieldList[t_FieldNr].m_YPos
cr = p_FieldList[t_FieldNr].m_Color[0]/255
cg = p_FieldList[t_FieldNr].m_Color[1]/255
cb = p_FieldList[t_FieldNr].m_Color[2]/255
t_Vertices.extend([
x - 0.5, y + 0.5, 0.0, cr, cg, cb, # 0----1
x + 0.5, y + 0.5, 0.0, cr, cg, cb, # | |
x + 0.5, y - 0.5, 0.0, cr, cg, cb, # | |
x - 0.5, y - 0.5, 0.0, 0, 0, 0 # 3----2
])
t_FieldVerticesBuffer = numpy.array(t_Vertices, dtype = numpy.float32)
# VBO
self.m_FieldVBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.m_FieldVBO)
glBufferData(GL_ARRAY_BUFFER, t_FieldVerticesBuffer.nbytes, t_FieldVerticesBuffer, GL_STATIC_DRAW)
# VBO Size Attrib
self.m_FieldVerticesAttrib = glGetAttribLocation(self.m_FieldShader, "Quad_Size_Attrib")
glEnableVertexAttribArray(self.m_FieldVerticesAttrib)
glVertexAttribPointer(self.m_FieldVerticesAttrib,
3,
GL_FLOAT,
GL_FALSE,
ctypes.sizeof(6*GLfloat),
ctypes.c_void_p(0))
# VBO Color Attrib
self.m_FieldColorAttrib = glGetAttribLocation(self.m_FieldShader, "Quad_Color_Attrib")
glEnableVertexAttribArray(self.m_FieldColorAttrib)
glVertexAttribPointer(self.m_FieldColorAttrib,
3,
GL_FLOAT,
GL_FALSE,
ctypes.sizeof(6*GLfloat),
ctypes.c_void_p(12))
# Uniform Locations
self.m_Field_ModelMat_Uniform = glGetUniformLocation(self.m_FieldShader, 'uniform_Model')
self.m_Field_ViewMat_Uniform = glGetUniformLocation(self.m_FieldShader, 'uniform_View')
self.m_Field_ProjectionMat_Uniform = glGetUniformLocation(self.m_FieldShader, 'uniform_Projection')
# Detach Shader & VAO
glBindVertexArray(0) # unbind the VAO
glUseProgram(0) # Disable shader
Screen Draw Cycle
This now is just psydo code:
OpenGLEnv.Clear()
OpenGLEnv.SetCamera()
OpenGLEnv.DrawField()
OpenGLEnv.FlipBuffer()
So SetCamera set's the ViewMat and ProjectionMat.
def SetCamera(self, camera, zoom_distance):
self.m_ViewMat = lookAt(glm.vec3(-camera[0], -camera[1], zoom_distance), # Camera is at (x,x,x), in World Space
glm.vec3(-camera[0], -camera[1], -100), # and looks at the origin
glm.vec3(0, 1, 0)) # Head is up (set to 0,-1,0 to look upside-down)
self.m_ProjectionMat = perspective(45, self.m_AspectRatio, 1, 1000.0)
Draw Field Routine
With this Function I will draw the Vertices from the VBO.
def DrawField(self):
glUseProgram(self.m_FieldShader) # Use shader
self.m_ModelMat = glm.mat4(1) # Reset ModelMat
# ############################
# 1. Scale self.ModelMat = scale(self.ModelMat,glm.vec3(10,10,10))
# 2. Rotation self.ModelMat = rotate(self.ModelMat, self.test, glm.vec3(0,1,0))
# 3. Translate self.ModelMat = translate(self.ModelMat,glm.vec3(0,0,0))
####################################
glUniformMatrix4fv(self.m_Field_ModelMat_Uniform, 1, GL_FALSE, numpy.squeeze(numpy.asarray(self.m_ModelMat.value)))
glUniformMatrix4fv(self.m_Field_ViewMat_Uniform, 1, GL_FALSE, numpy.squeeze(numpy.asarray(self.m_ViewMat.value)))
glUniformMatrix4fv(self.m_Field_ProjectionMat_Uniform, 1, GL_FALSE, numpy.squeeze(numpy.asarray(self.m_ProjectionMat.value)))
glBindVertexArray(self.m_FieldVAO)
glBindBuffer(GL_ARRAY_BUFFER, self.m_FieldVBO)
# Draw Field
glDrawArrays(GL_QUADS, 0, 4*self.m_FieldCount)
# Disable shader and unbind VAO
glBindVertexArray(0)
glUseProgram(0)
Used Librarys:
- GLM (I think it was this one https://github.com/Zuzu-Typ/PyGLM)
- OpenGL (PyOpenGL 3.1.0)
- Numpy
- Math