e.g.
#version 330
layout(location = 0) in vec4 position;
vec2 offset = vec2(0.5, -0.5);
void main()
{
gl_Position = position;
gl_Position.xy += offset;
}
Don't worry about understanding the actual geometry behind this, explaining that is beyond the scope of this guide. What matters is that you have a solid idea of how a rotation is described by a rotation axis and an angle and that you've at least seen what a rotation matrix looks like.
git diff glVersionIndependent glmRotate main.cpp
diff --git a/main.cpp b/main.cpp
index 12a8548..92c684e 100644
--- a/main.cpp
+++ b/main.cpp
@@ -5,6 +5,13 @@
#include <GL/glew.h>
#include <SDL.h>
+#define GLM_FORCE_RADIANS //force glm to use radians //must do **before** including GLM headers
+//NOTE: GLSL uses radians, so will do the same, for consistency
+
+#include <glm/glm.hpp> //include the main glm header
+#include <glm/gtc/matrix_transform.hpp> //include functions to ease the calculation of the view and projection matrices
+#include <glm/gtc/type_ptr.hpp> //include functionality for converting a matrix object into a float array for usage in OpenGL
+
using namespace std;
/////////////////////
@@ -23,11 +30,10 @@ const std::string strVertexShader(
"#version 140\n"
#endif
"in vec4 position;\n"
- "uniform vec2 offset;\n"
+ "uniform mat4 rotateMatrix;\n"
"void main()\n"
"{\n"
- " gl_Position = position;\n"
- " gl_Position.xy += offset;\n"
+ " gl_Position = rotateMatrix * position;\n" //multiple the position by the transformation matrix (rotate)
"}\n"
);
@@ -56,17 +62,16 @@ const float vertexPositions[] = {
0.4330127f, -0.25f, 0.0f, 1.0f,
};
-//the offset we'll pass to the GLSL
-double offsetX = -0.5; //using different values from CPU and static GLSL examples, to make it clear this is working
-double offsetY = -0.5; //NOTE: we could use an array and pass the pointer, to be simpler & more efficent
-double offsetXSpeed = 0.2; //rate of change of offsetX in units per second
-double offsetYSpeed = 0.2; //rate of change of offsetY in units per second
+//the rotate we'll pass to the GLSL
+glm::mat4 rotateMatrix; // the transformation matrix for our object - which is the identity matrix by default
+float rotateSpeed = 1.0f; //rate of change of the rotate - in radians per second
+
//our GL and GLSL variables
GLuint theProgram; //GLuint that we'll fill in to refer to the GLSL program (only have 1 at this point)
-GLint positionLocation; //GLuint that we'll fill in with the location of the `offset` variable in the GLSL
-GLint offsetLocation; //GLuint that we'll fill in with the location of the `offset` variable in the GLSL
+GLint positionLocation; //GLuint that we'll fill in with the location of the `rotate` variable in the GLSL
+GLint rotateMatrixLocation; //GLuint that we'll fill in with the location of the `rotate` variable in the GLSL
GLuint positionBufferObject;
GLuint vao;
@@ -233,7 +238,7 @@ void initializeProgram()
}
positionLocation = glGetAttribLocation(theProgram, "position");
- offsetLocation = glGetUniformLocation(theProgram, "offset");
+ rotateMatrixLocation = glGetUniformLocation(theProgram, "rotateMatrix");
//clean up shaders (we don't need them anymore as they are no in theProgram
for_each(shaderList.begin(), shaderList.end(), glDeleteShader);
}
@@ -263,8 +268,13 @@ void loadAssets()
void updateSimulation(double simLength) //update simulation with an amount of time to simulate for (in seconds)
{
- offsetX += offsetXSpeed * simLength;
- offsetY += offsetYSpeed * simLength;
+
+ //calculate the amount of rotate for this timestep
+ float rotate = (float)simLength * rotateSpeed; //simlength is a double for precision, but rotateSpeedVector in a vector of float, alternatively use glm::dvec3
+
+ //modify the rotateMatrix with the rotate, as a rotate, around the z-axis
+ const glm::vec3 unitZ = glm::vec3(0, 0, 1);
+ rotateMatrix = glm::rotate(rotateMatrix, rotate, unitZ);
}
void render()
@@ -272,8 +282,8 @@ void render()
glUseProgram(theProgram); //installs the program object specified by program as part of current rendering state
//load data to GLSL that **may** have changed
- glUniform2f(offsetLocation, offsetX, offsetY);
-
+ glUniformMatrix4fv(rotateMatrixLocation, 1, GL_FALSE, glm::value_ptr(rotateMatrix)); //uploaed the rotateMatrix to the appropriate uniform location
+ // upload only one matrix, and don't transpose it
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); //bind positionBufferObject