OpenGL ->Rotate / Scale in GLSL vertex shader question
Posted: Mon Feb 08, 2021 7:38 pm
Why, oh why is the aspect ratio of the image not kept after rotate / scale?
I must be misunderstanding something...
If I change the screen resolution to a square (#W=#H) then it's ok, but I do not understand why since the vertexes are in world coords.
I must be misunderstanding something...
If I change the screen resolution to a square (#W=#H) then it's ok, but I do not understand why since the vertexes are in world coords.
Code: Select all
#W=1200
#H=800
#GL_COLOR_BUFFER_BIT = $00004000
#GL_DEPTH_BUFFER_BIT = $00000100
#GL_ARRAY_BUFFER = $8892
#GL_ELEMENT_ARRAY_BUFFER = $8893
#GL_MODELVIEW = $1700
#GL_PROJECTION = $1701
#GL_SMOOTH = $1D01
#GL_DEPTH_TEST = $0B71
#GL_CULL_FACE = $0B44
#GL_STATIC_DRAW = $88E4
#GL_VERTEX_ARRAY = $8074
#GL_FLOAT = $1406
#GL_TRIANGLES = $0004
#GL_UNSIGNED_BYTE = $1401
#GL_UNSIGNED_SHORT = $1403
#GL_UNSIGNED_INT = $1405
#GL_ARRAY_BUFFER = $8892
#GL_STATIC_DRAW = $88E4
#GL_VERTEX_SHADER = $8B31
#GL_FRAGMENT_SHADER = $8B30
#GL_TEXTURE0 = $84C0
#GL_TEXTURE1 = $84C1
#GL_BGR = $80E0
#GL_BGRA = $80E1
#GL_RGB= $1907
#GL_RGBA= $1908
Prototype glGenBuffers( n.i, *buffers)
Prototype glBindBuffer( target.l, buffer.i)
Prototype glBufferData ( target.l, size.i, *Data_, usage.l)
Prototype glBufferSubData ( target.l, offset.i, size.i, *Data_)
Prototype glGenVertexArrays (n.i, *arrays)
Prototype glBindVertexArray(n.i)
Prototype glEnableVertexAttribArray ( index.i )
Prototype glVertexAttribPointer ( index.i, size.i, type.l, normalized.b, stride.i, *pointer )
Prototype glDrawArrays ( mode.l, first.i, count.i )
Prototype glIndexPointer ( enum.i, stride.i, *length )
Prototype glDeleteBuffers ( n.i, *buffers)
Prototype glDeleteVertexArrays ( n.i, *buffers)
Prototype glDisableVertexAttribArray(index.i)
Prototype glMapBuffer(Target.i, Access.i)
Prototype glUnmapBuffer(Target.i)
Prototype glActiveTexture(Texture.l)
Prototype glUniformMatrix4fv(location.i, count.i, transpose.b, *value)
Prototype glCreateShader(type.l)
Prototype glCreateProgram()
Prototype glCompileShader(shader.l)
Prototype glDeleteShader(ShaderObj.i)
Prototype glLinkProgram(shader.l)
Prototype glUseProgram(shader.l)
Prototype glAttachShader(Program.l, shader.l)
Prototype glShaderSource(shader.l, numOfStrings.l, *strings, *lenOfStrings) :
Prototype glGetUniformLocation(Program.i, name.p-ascii)
Prototype glUniform1i(location.i, v0.i)
Prototype glUniform2i(location.i, v0.i, v1.i)
Prototype glUniform1f(location.i, v0.f)
Prototype glUniform2f(location.i, v0.f, v1.f)
Prototype glGetShaderInfoLog(shader.i, bufSize.l, *length_l, *infoLog)
Structure GLSL
glGenBuffers.glGenBuffers
glBindBuffer.glBindBuffer
glBufferData.glBufferData
glBufferSubData.glBufferSubData
glGenVertexArrays.glGenVertexArrays
glBindVertexArray.glBindVertexArray
glEnableVertexAttribArray.glEnableVertexAttribArray
glVertexAttribPointer.glVertexAttribPointer
glDrawArrays.glDrawArrays
glIndexPointer.glIndexPointer
glDeleteBuffers.glDeleteBuffers
glDeleteVertexArrays.glDeleteVertexArrays
glDisableVertexAttribArray.glDisableVertexAttribArray
glMapBuffer.glMapBuffer
glUnmapBuffer.glUnmapBuffer
glActiveTexture.glActiveTexture
glUniformMatrix4fv.glUniformMatrix4fv
glCreateShader.glCreateShader
glCreateProgram.glCreateProgram
glCompileShader.glCompileShader
glDeleteShader.glDeleteShader
glLinkProgram.glLinkProgram
glUseProgram.glUseProgram
glAttachShader.glAttachShader
glShaderSource.glShaderSource
glGetUniformLocation.glGetUniformLocation
glUniform1i.glUniform1i
glUniform2i.glUniform2i
glUniform1f.glUniform1f
glUniform2f.glUniform2f
glGetShaderInfoLog.glGetShaderInfoLog
EndStructure
Procedure GLGetFunctions(*GLSL.GLSL)
*GLSL\glGenBuffers = wglGetProcAddress_("glGenBuffers")
*GLSL\glBindBuffer = wglGetProcAddress_("glBindBuffer")
*GLSL\glBufferData = wglGetProcAddress_("glBufferData")
*GLSL\glBufferSubData = wglGetProcAddress_("glBufferSubData")
*GLSL\glGenVertexArrays = wglGetProcAddress_("glGenVertexArrays")
*GLSL\glBindVertexArray = wglGetProcAddress_("glBindVertexArray")
*GLSL\glEnableVertexAttribArray = wglGetProcAddress_("glEnableVertexAttribArray")
*GLSL\glVertexAttribPointer = wglGetProcAddress_("glVertexAttribPointer")
*GLSL\glDrawArrays = wglGetProcAddress_("glDrawArrays")
*GLSL\glIndexPointer = wglGetProcAddress_("glIndexPointer")
*GLSL\glDeleteBuffers = wglGetProcAddress_("glDeleteBuffers")
*GLSL\glDeleteVertexArrays = wglGetProcAddress_("glDeleteVertexArrays")
*GLSL\glDisableVertexAttribArray = wglGetProcAddress_("glDisableVertexAttribArray")
*GLSL\glMapBuffer = wglGetProcAddress_("glMapBuffer")
*GLSL\glUnmapBuffer = wglGetProcAddress_("glUnmapBuffer")
*GLSL\glActiveTexture = wglGetProcAddress_("glActiveTexture")
*GLSL\glUniformMatrix4fv=wglGetProcAddress_("glUniformMatrix4fv")
*GLSL\glCreateShader = wglGetProcAddress_("glCreateShader")
*GLSL\glCreateProgram = wglGetProcAddress_("glCreateProgram")
*GLSL\glCompileShader = wglGetProcAddress_("glCompileShader")
*GLSL\glDeleteShader = wglGetProcAddress_("glDeleteShader")
*GLSL\glLinkProgram = wglGetProcAddress_("glLinkProgram")
*GLSL\glUseProgram = wglGetProcAddress_("glUseProgram")
*GLSL\glAttachShader = wglGetProcAddress_("glAttachShader")
*GLSL\glShaderSource = wglGetProcAddress_("glShaderSource")
*GLSL\glGetUniformLocation = wglGetProcAddress_("glGetUniformLocation")
*GLSL\glUniform1i = wglGetProcAddress_("glUniform1i")
*GLSL\glUniform2i = wglGetProcAddress_("glUniform2i")
*GLSL\glUniform1f = wglGetProcAddress_("glUniform1f")
*GLSL\glUniform2f = wglGetProcAddress_("glUniform2f")
*GLSL\glGetShaderInfoLog = wglGetProcAddress_("glGetShaderInfoLog")
EndProcedure
Global points_vbo.i, colors_vbo.i, vao.i, ebo.i, texture.i, transparenz.f
Structure _2DPoint
x.f
y.f
EndStructure
Structure _2DTex
x.f
y.f
EndStructure
Structure myTexVertex
Pos._2DPoint
Tex._2DTex
EndStructure
Structure Tindex
a.l
b.l
c.l
d.l
EndStructure
UseJPEGImageDecoder()
UsePNGImageDecoder()
#ImagePath = #PB_Compiler_Home + "examples/3d/Data/Textures/"
LoadImage(1, #ImagePath + "ValetCoeur.jpg")
ImgDepth=ImageDepth(1)
If ImgDepth<>32
CreateImage(2,ImageWidth(1), ImageHeight(1),32)
StartDrawing(ImageOutput(2))
DrawImage(ImageID(1),0,0)
StopDrawing()
FreeImage(1)
CopyImage(2,1)
FreeImage(2)
EndIf
Sprite_W=ImageWidth(1)
Sprite_H=ImageHeight(1)
StartDrawing(ImageOutput(1))
Debug DrawingBufferPixelFormat()
mem=DrawingBuffer()
size=DrawingBufferPitch()* ImageHeight(1)
*Buffer1=AllocateMemory(size)
CopyMemory(mem, *Buffer1, size)
StopDrawing()
Dim Vertex.myTexVertex(3)
Sprite_X=0
Sprite_Y=0
; Vertexes in WorldSpace
; // top left
Vertex(0)\Pos\x = -1 : Vertex(0)\Pos\y = 1
Vertex(0)\Tex\x = 0.0 : Vertex(0)\Tex\y = 1.0
;// top right
Vertex(1)\Pos\x = 1 : Vertex(1)\Pos\y = 1
Vertex(1)\Tex\x = 1.0 : Vertex(1)\Tex\y = 1.0
; // bottom left
Vertex(2)\Pos\x = -1 : Vertex(2)\Pos\y = -1
Vertex(2)\Tex\x = 0.0 : Vertex(2)\Tex\y = 0.0
; // bottom right
Vertex(3)\Pos\x = 1 : Vertex(3)\Pos\y = -1
Vertex(3)\Tex\x = 1.0 : Vertex(3)\Tex\y = 0.0
;Another way to transform, but that's not the question...
;fLeft.f=((Sprite_X/#W)-0.5)*2
;fTop.f=(0.5-(Sprite_Y/#H))*2
;fRight.f=(((Sprite_X+Sprite_W)/#W)-0.5)*2
;fBottom.f=(0.5-((Sprite_Y+Sprite_H)/#H))*2
Dim uRotate.f(3,3)
Dim uScale.f(3,3)
Dim uTranslate.f(3,3)
Dim Index.Tindex(0)
Index(0)\a = 2 : Index(0)\b = 3 : Index(0)\c = 1 : Index(0)\d = 0
Global GLSL.GLSL
;**************************************************************************************
OpenWindow(0, 0, 0, #W, #H, "GLSL sprites in WindowedScreen")
InitSprite()
OpenWindowedScreen(WindowID(0),0,0,#W,#H)
;**************************************************************************************
GLGetFunctions(GLSL.GLSL)
;**************************************************************************************
glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
glEnable_(#GL_DEPTH_TEST); // enable depth-testing
glEnable_(#GL_BLEND)
glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE_MINUS_SRC_ALPHA)
GLSL\glGenVertexArrays(1, @vao)
GLSL\glGenBuffers(1, @points_vbo )
GLSL\glGenBuffers(1, @ebo)
GLSL\glBindVertexArray(vao)
GLSL\glBindBuffer(#GL_ARRAY_BUFFER, points_vbo)
GLSL\glBufferData(#GL_ARRAY_BUFFER,SizeOf(myTexVertex) * (ArraySize(Vertex())+1),@Vertex(0), #GL_STATIC_DRAW)
GLSL\glBindBuffer(#GL_ELEMENT_ARRAY_BUFFER, ebo)
GLSL\glBufferData(#GL_ELEMENT_ARRAY_BUFFER, 16*(ArraySize(Index())+1), @Index(0), #GL_STATIC_DRAW)
GLSL\glVertexAttribPointer(0, SizeOf(_2DPoint)/SizeOf(float), #GL_FLOAT, #GL_FALSE, SizeOf(myTexVertex), 0)
GLSL\glEnableVertexAttribArray(0)
GLSL\glVertexAttribPointer(1, SizeOf(_2DTex)/SizeOf(float), #GL_FLOAT, #GL_FALSE, SizeOf(myTexVertex), OffsetOf(myTexVertex\Tex))
GLSL\glEnableVertexAttribArray(1);
glGenTextures_(1, @texture1)
glBindTexture_(#GL_TEXTURE_2D, texture1)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_WRAP_S, #GL_CLAMP_TO_EDGE)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_WRAP_T, #GL_CLAMP_TO_EDGE)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 4, ImageWidth(1), ImageHeight(1), 0, #GL_BGRA_EXT, #GL_UNSIGNED_BYTE, *Buffer1)
;glGenerateMipmap_(#GL_TEXTURE_2D)
FreeMemory(*Buffer1)
Define vertex_shader.s
Define fragment_shader.s
Define *fbuff
Define *vbuff
vertex_shader = "#version 330 core"+#CRLF$
vertex_shader + "layout(location = 0) in vec2 aPos;"+#CRLF$ ; the position variable has attribute position 0
vertex_shader + "layout(location = 1) in vec2 aTexCoord;"+#CRLF$ ; the color variable has attribute position 1
vertex_shader + "out vec2 TexCoord;"+#CRLF$
vertex_shader + "uniform mat4 uScale;"+#CRLF$
vertex_shader + "uniform mat4 uRotate;"+#CRLF$
vertex_shader + "uniform mat4 uTranslate;"+#CRLF$
vertex_shader + "void main() {"+#CRLF$
vertex_shader + "vec4 Position = vec4(aPos, 1.0, 1.0);"+#CRLF$
;I DO NOT UNDERSTAND WHY ROTATE/SCALE acts like this
vertex_shader + "Position = uRotate*Position;"+#CRLF$
vertex_shader + "Position = uScale*Position;"+#CRLF$
vertex_shader + "Position = uTranslate*Position;"+#CRLF$
vertex_shader + "gl_Position = Position;"+#CRLF$
vertex_shader + "TexCoord = aTexCoord;"+#CRLF$
vertex_shader + "}"
fragment_shader = "#version 330 core"+#CRLF$
fragment_shader + "out vec4 FragColor;"+#CRLF$
fragment_shader + "in vec2 TexCoord;"+#CRLF$
fragment_shader + "uniform sampler2D texture1;"+#CRLF$
fragment_shader + "void main()"+#CRLF$
fragment_shader + "{"+#CRLF$
fragment_shader + " FragColor = texture(texture1, TexCoord)*vec4(1.,1.,1.,1);"+#CRLF$
fragment_shader + "}"+#CRLF$
*vbuff = Ascii(vertex_shader)
*fbuff = Ascii(fragment_shader)
Global vs = GLSL\glCreateShader(#GL_VERTEX_SHADER);
GLSL\glShaderSource(vs, 1, @*vbuff, #Null) ;
GLSL\glCompileShader(vs)
buffer = AllocateMemory(512)
GLSL\glGetShaderInfoLog(vs,512,#Null,buffer)
Log$=PeekS(buffer,512,#PB_Ascii)
If Log$:Debug Log$:EndIf
FreeMemory(buffer)
Global fs = GLSL\glCreateShader(#GL_FRAGMENT_SHADER);
GLSL\glShaderSource(fs, 1, @*fbuff, #Null);
GLSL\glCompileShader(fs)
Global Shader = GLSL\glCreateProgram();
GLSL\glAttachShader(Shader, vs)
GLSL\glAttachShader(Shader, fs)
GLSL\glLinkProgram(Shader)
GLSL\glDeleteShader(vs)
GLSL\glDeleteShader(fs)
GLSL\glUseProgram(Shader) ; // don't forget to activate/use the shader before setting uniforms!
GLSL\glUniform1i(GLSL\glGetUniformLocation(Shader, "texture1"), 0) ; muss nur einmal festgelegt werden
GLSL\glActiveTexture(#GL_TEXTURE0);
glBindTexture_(#GL_TEXTURE_2D, texture1)
Repeat
Event = WindowEvent()
;glClearColor_(0.2, 0.5, 0.3, 1)
;glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
;glViewport_(0, 0, #W, #H)
GLSL\glUseProgram(Shader)
GLSL\glBindVertexArray(vao)
Scale_X.f=(Sprite_W/#W)
Scale_Y.f=Sprite_H/#H
Sprite_X=0
Sprite_Y=0
fLeft.f=Sprite_X/(#W/2)
fTop.f=Sprite_Y/#H
myCos.f=Cos(Radian(Angle))
mySin.f=Sin(Radian(Angle))
Angle+1
Angle%360
;Trying to understand matrices.....???
;Why is the aspect ratio of the image not correct after rotate / scale ?????
uScale(0,0)=Scale_X : uScale(1,0)=0 : uScale(2,0)=0 : uScale(3,0)=0
uScale(0,1)=0 : uScale(1,1)=Scale_Y : uScale(2,1)=0 : uScale(3,1)=0
uScale(0,2)=0 : uScale(1,2)=0 : uScale(2,2)=1 : uScale(3,2)=0
uScale(0,3)=0 : uScale(1,3)=0 : uScale(2,3)=0 : uScale(3,3)=1
uRotate(0,0)=myCos : uRotate(1,0)=-mySin : uRotate(2,0)=0 : uRotate(3,0)=0
uRotate(0,1)=mySin : uRotate(1,1)=myCos : uRotate(2,1)=0 : uRotate(3,1)=0
uRotate(0,2)=0 : uRotate(1,2)=0 : uRotate(2,2)=1 : uRotate(3,2)=0
uRotate(0,3)=0 : uRotate(1,3)=0 : uRotate(2,3)=0 : uRotate(3,3)=1
uTranslate(0,0)=1 : uTranslate(1,0)=0 : uTranslate(2,0)=0 : uTranslate(3,0)=fLeft
uTranslate(0,1)=0 : uTranslate(1,1)=1 : uTranslate(2,1)=0 : uTranslate(3,1)=fTop
uTranslate(0,2)=0 : uTranslate(1,2)=0 : uTranslate(2,2)=1 : uTranslate(3,2)=0
uTranslate(0,3)=0 : uTranslate(1,3)=0 : uTranslate(2,3)=0 : uTranslate(3,3)=1
GLSL\glUniformMatrix4fv(GLSL\glGetUniformLocation(Shader, "uScale"), 1, #GL_FALSE, @uScale(0,0));
GLSL\glUniformMatrix4fv(GLSL\glGetUniformLocation(Shader, "uRotate"), 1, #GL_FALSE, @uRotate(0,0));
GLSL\glUniformMatrix4fv(GLSL\glGetUniformLocation(Shader, "uTranslate"), 1, #GL_FALSE, @uTranslate(0,0));
glDrawElements_(#GL_QUADS, 4, #GL_UNSIGNED_INT, 0 )
GLSL\glBindVertexArray(0)
GLSL\glUseProgram(0)
FlipBuffers()
Until Event = #PB_Event_CloseWindow Or quit = 1