Ginger3D/src/main/java/com/github/hydos/ginger/engine/opengl/shadow/ShadowMapEntityRenderer.java

87 lines
3.1 KiB
Java

package com.github.hydos.ginger.engine.opengl.shadow;
import java.util.*;
import org.joml.Matrix4f;
import org.lwjgl.opengl.*;
import com.github.hydos.ginger.engine.common.elements.objects.GLRenderObject;
import com.github.hydos.ginger.engine.common.math.Maths;
import com.github.hydos.ginger.engine.opengl.render.GLRenderManager;
import com.github.hydos.ginger.engine.opengl.render.models.*;
public class ShadowMapEntityRenderer
{
private Matrix4f projectionViewMatrix;
private ShadowShader shader;
/** @param shader
* - the simple shader program being used for the shadow render
* pass.
* @param projectionViewMatrix
* - the orthographic projection matrix multiplied by the light's
* "view" matrix. */
protected ShadowMapEntityRenderer(ShadowShader shader, Matrix4f projectionViewMatrix)
{
this.shader = shader;
this.projectionViewMatrix = projectionViewMatrix;
}
/** Binds a raw model before rendering. Only the attribute 0 is enabled here
* because that is where the positions are stored in the VAO, and only the
* positions are required in the vertex shader.
*
* @param rawModel
* - the model to be bound. */
private void bindModel(RawModel rawModel)
{
GL30.glBindVertexArray(rawModel.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
}
/** Prepares an entity to be rendered. The model matrix is created in the
* usual way and then multiplied with the projection and view matrix (often
* in the past we've done this in the vertex shader) to create the
* mvp-matrix. This is then loaded to the vertex shader as a uniform.
*
* @param entity
* - the entity to be prepared for rendering. */
private void prepareInstance(GLRenderObject entity)
{
Matrix4f modelMatrix = Maths.createTransformationMatrix(entity.getPosition(),
entity.getRotX(), entity.getRotY(), entity.getRotZ(), entity.getScale());
Matrix4f mvpMatrix = projectionViewMatrix.mul(modelMatrix);
shader.loadMvpMatrix(mvpMatrix);
}
/** Renders entieis to the shadow map. Each model is first bound and then all
* of the entities using that model are rendered to the shadow map.
*
* @param entities
* - the entities to be rendered to the shadow map. */
protected void render(Map<GLTexturedModel, List<GLRenderObject>> entities)
{
for (GLTexturedModel model : entities.keySet())
{
RawModel rawModel = model.getRawModel();
bindModel(rawModel);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexture().getTextureID());
if (model.getTexture().isTransparent())
{ GLRenderManager.disableCulling(); }
for (GLRenderObject entity : entities.get(model))
{
prepareInstance(entity);
GL11.glDrawElements(GL11.GL_TRIANGLES, rawModel.getVertexCount(),
GL11.GL_UNSIGNED_INT, 0);
}
if (model.getTexture().isTransparent())
{ GLRenderManager.enableCulling(); }
}
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL30.glBindVertexArray(0);
}
}