Hello everyone, I'm struggling doing a simple action as rotating a shader.
This is what I currently have:
public static void drawImageRegion(Image image, float x1, float y1, float x2, float y2, float s1, float t1, float s2, float t2, Color3f color, int angle){
glPushMatrix();
long window = GLFW.glfwGetCurrentContext();
IntBuffer widthBuffer = BufferUtils.createIntBuffer(1);
IntBuffer heightBuffer = BufferUtils.createIntBuffer(1);
GLFW.glfwGetFramebufferSize(window, widthBuffer, heightBuffer);
int w = widthBuffer.get();
int h = heightBuffer.get();
glBindTexture(GL_TEXTURE_2D, image.getID());
int vao = glGenVertexArrays();
glBindVertexArray(vao);
float r = color.r;
float g = color.g;
float b = color.b;
FloatBuffer vertices = BufferUtils.createFloatBuffer(4 * 7);
vertices.put(x1).put(y1).put(r).put(g).put(b).put(s1).put(t1);
vertices.put(x2).put(y1).put(r).put(g).put(b).put(s2).put(s1);
vertices.put(x2).put(y2).put(r).put(g).put(b).put(s2).put(t2);
vertices.put(x1).put(y2).put(r).put(g).put(b).put(s1).put(t2);
vertices.flip();
int vbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
int ebo = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
IntBuffer elements = BufferUtils.createIntBuffer(2 * 3);
elements.put(0).put(1).put(2);
elements.put(2).put(3).put(0);
elements.flip();
glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements, GL_STATIC_DRAW);
ShaderProgram program = new ShaderProgram();
Shader v = Shader.loadShader(GL_VERTEX_SHADER, "shaders/texVertex.glsl");
program.attachShader(v);
Shader f = Shader.loadShader(GL_FRAGMENT_SHADER, "shaders/texFrag.glsl");
program.attachShader(f);
program.bindFragmentDataLocation(0, "fragColor");
program.link();
program.use();
program = specifyVertexAttributes(program);
// Set texture uniform
int uniTex = program.getUniformLocation("texImage");
program.setUniform(uniTex, 0);
// Set model matrix to identity matrix
Matrix4f model = Matrix4f.rotate(angle, 0, 0, 1);
int uniModel = program.getUniformLocation("model");
program.setUniform(uniModel, model);
// Set view matrix to identity matrix
Matrix4f view = new Matrix4f();
int uniView = program.getUniformLocation("view");
program.setUniform(uniView, view);
// Set projection matrix to an orthographic projection
Matrix4f projection = Matrix4f.orthographic(0f, w, h, 0f, -1f, 1f);
int uniProjection = program.getUniformLocation("projection");
program.setUniform(uniProjection, projection);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glDeleteTextures(image.getID());
v.delete();
f.delete();
program.delete();
glUseProgram(0);
glPopMatrix();
}
/**
* Specifies the vertex pointers.
*/
private static ShaderProgram specifyVertexAttributes(ShaderProgram program) {
/* Specify Vertex Pointer */
int posAttrib = program.getAttributeLocation("position");
program.enableVertexAttribute(posAttrib);
program.pointVertexAttribute(posAttrib, 2, 7 * Float.BYTES, 0);
/* Specify Color3f Pointer */
int colAttrib = program.getAttributeLocation("color");
program.enableVertexAttribute(colAttrib);
program.pointVertexAttribute(colAttrib, 3, 7 * Float.BYTES, 2 * Float.BYTES);
/* Specify Texture Pointer */
int texAttrib = program.getAttributeLocation("texcoord");
program.enableVertexAttribute(texAttrib);
program.pointVertexAttribute(texAttrib, 2, 7 * Float.BYTES, 5 * Float.BYTES);
return program;
}
And these are my shaders:
Vertex:
#version 150 core
in vec2 position;
in vec3 color;
in vec2 texcoord;
out vec3 vertexColor;
out vec2 textureCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
vertexColor = color;
textureCoord = texcoord;
mat4 mvp = projection * view * model;
gl_Position = mvp * vec4(position, 0.0, 1.0);
}
Fragment:
#version 150 core
in vec3 vertexColor;
in vec2 textureCoord;
out vec4 fragColor;
uniform sampler2D texImage;
void main() {
vec4 textureColor = texture(texImage, textureCoord);
fragColor = vec4(vertexColor, 1.0) * textureColor;
}
Doing some research I have found that I should use the model matrix to perform rotation with shaders. In fact line 56 works but not how intended. I have a small 32x32 image at coordinates (500; 500) and I rotate it using the method shown. Here's the relevant code:
image = Image.loadImage("textures/lwjgl32.png");
Renderer.drawImageRegion(image, 500, 500, 0, 0, 32, 32, Colors.WHITE.color, angle++);
The problem is that the texture rotates with center (0; 0) (top-left corner) instead of rotating around itself. I have tried translating the model matrix to the X and Y coordinate of the texture but seems to just move the origin down to (500; 500) which is the location of the texture.
I might be missing something obvious but it has been a while and I still not have found a way around this. Please excuse me for my noobiness and if you can explain in detail how and why the solution works.
Thanks a bunch.