Après une session Google assez longue, j'en ai assez!Est-il possible d'utiliser gluLookAt avec un Vertex Shader?
J'ai eu une application python/opengl avec quelques simples Quad où j'ai utilisé gluLookAt pour se déplacer sur la scène. Ensuite, j'avais juste besoin d'une texture sur l'un de ces quads, alors j'utilise évidemment un programme de shaders pour ce seul Quad maintenant. Maintenant, quand j'utilise gluLookAt, le Quad avec la Texture ne bouge pas, ce que je peux aussi comprendre.
Maintenant, y a-t-il un moyen d'utiliser la fonction gluLookAt pour travailler avec le programme shader, obtenir la pile de matrice actuelle pour pouvoir alimenter le programme shader ou dois-je réécrire l'application trou et réinventer la fonction glulookup like he did (dans le shader ou sur le CPU)?
EDIT1: j'utilise:
python 3,5
PyOpenGL 3.1.0
GLSL 1,4 (According to this list)
EDIT2 (Ma Solution):
Depuis j'ai ouvert ce fil, certaines choses ont changé, mais avec l'guideance de vous, je réussi à obtenir une solution stable & moderne.
Il y a 3 composants principaux que je dois dessiner. Un champ statique, quelques lignes (pour une meilleure visualisation) et quelques Quads mobiles.
Le champ est maintenant écrit une fois à un VBO dans un tableau. (amélioration majeure par rapport aux commandes de dessin uniques)
Les carrés et les lignes mobiles fonctionnent sur le même principe, mais ils sont dynamiques et doivent être déplacés à chaque image.
Type d'objet Foreach J'ai un programme vertex + fragment shader. Je suis conscient que je ne pourrais en utiliser qu'un seul, mais ce n'est pas comme ça. Chaque matrice (modèle, vue, projection) est affectée à un uniforme qui est ensuite multiplié avec les sommets du VBO dans le vertex shader.
Champ Vertex Shader (Exemple):
#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);
}
Ce que j'ai demandé était pas la bonne façon de le faire.(Combinaison anciens et nouveaux OpenGL) Unfortunatly Je ne peux pas partager le code de trou comme il est, mais je vous trouverez ici tous les codes clés opengl:
Vertex/Fragment Shader Programme Loader:
Initialize Vertex/Fragment shader (dans ce cas pour le champ)
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
écran Dessin Cycle
Ceci est maintenant juste psydo code:
OpenGLEnv.Clear()
OpenGLEnv.SetCamera()
OpenGLEnv.DrawField()
OpenGLEnv.FlipBuffer()
Alors SetCamera est le ViewMat mis et 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)
Dessiner routine sur le terrain
Avec cette fonction je tirerai les sommets du 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)
occasion Librarys:
- GLM (je pense qu'il était celui https://github.com/Zuzu-Typ/PyGLM)
- OpenGL (PyOpenGL 3.1.0)
- Numpy
- Math
Je suggère d'utiliser une bibliothèque de maths au lieu d'essayer de bidouiller avec la pile de matrice. [glm] (https://glm.g-truc.net/0.9.8/index.html) pourrait être un bon choix et fournit également une fonction lookat. Pour le reste de votre question: Cela dépend de la version et du profil que vous utilisez. – BDL
Désolé de ne pas le mentionner, je travaille avec Python ^^ Ok vous iriez avec un calcul manuel des Matrices ... Merci pour vos conseils. – noscript
Il existe aussi une version python de glm. S'il vous plaît voir le lien suivant https://github.com/mackst/glm. Il n'est pas aussi complet que GLM mais a les fonctions dont vous avez besoin. –