1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
| Méthode initializeGL() :
// Création des vertices et des couleurs, contenus dans un object QVector<QVector3D>
// ...
// Création et linkage des shaders
m_program_depth.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertex_depth.glsl");
m_program_depth.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fragment_depth.glsl");
m_program_depth.link();
m_program_rendu.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertex_rendu.glsl");
m_program_rendu.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fragment_rendu.glsl");
m_program_rendu.link();
// Création des VBO
VBO_vertex.create();
VBO_vertex.bind();
VBO_vertex.setUsagePattern(QOpenGLBuffer::StaticDraw);
VBO_vertex.allocate(static_cast<GLvoid*>(m_vertices.data()), sizeof(QVector3D) * m_vertices.size());
VBO_vertex.release();
VBO_couleur.create();
VBO_couleur.bind();
VBO_couleur.setUsagePattern(QOpenGLBuffer::StaticDraw);
VBO_couleur.allocate(static_cast<GLvoid*>(m_couleur.data()), sizeof(QVector3D) * m_couleur.size());
VBO_couleur.release();
// Création des textures (code repiqué sur le net, je n'ai pas bien compris pourquoi toutes ces textures...)
renderTexture = createTexture(640,480);
depthTexture = createTexture(640,480,true);
shadowMap = createTexture(shadowMapWidth, shadowMapHeight, true); // 640*8 pixels et 480*8 pixels
// Création du FBO (code repiqué également...)
glGenFramebuffers(1, &shadowFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D, depthTexture , 0);
int i=glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(i!=GL_FRAMEBUFFER_COMPLETE)
{
qDebug() << "Framebuffer is not OK, status=" << i;
}
glBindFramebuffer(GL_FRAMEBUFFER,0);
Méthode paintGL() :
// Création des matrices
QMatrix4x4 vueProjMatrix;
vueProjMatrix.perspective(60.0f, width() / height(), 1.0f, 1000.0f);
QMatrix4x4 vueLookAtMatrix;
vueLookAtMatrix.lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D(0.0f, 0.0f, -100.0f), QVector3D(0.0f, 1.0f, 0.0f));
QVector3D light_position(10.0f, 30.0f, 10.0f);
QVector3D light_direction(-3.5f, -3.5f, -10.0f);
QMatrix4x4 lightLookAtMatrix;
lightLookAtMatrix.lookAt(light_position, light_direction, QVector3D(0.0f, 1.0f, 0.0f));
QMatrix4x4 lightProjMatrix;
lightProjMatrix = vueProjMatrix;
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_COLOR_BUFFER_BIT);
glDepthFunc(GL_LESS);
// 1ère passe :
glViewport(0, 0, shadowMapWidth, shadowMapHeight);
glClearColor(0.4f, 0.4f, 0.4f,1.0f);
glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT );
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glEnable(GL_DEPTH_TEST);
m_program_depth.bind();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shadowFramebuffer);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D, shadowMap, 0);
VBO_vertex.bind();
m_program_depth.enableAttributeArray("pos_vertex_depth");
m_program_depth.setAttributeBuffer("pos_vertex_depth", GL_FLOAT, 0, 3);
VBO_vertex.release();
m_program_depth.setUniformValue("modelViewProjectionMatrix_depth", lightProjMatrix * lightLookAtMatrix);
m_program_depth.setUniformValue("modelMatrix_depth", QMatrix4x4());
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
m_program_depth.disableAttributeArray("pos_vertex_depth");
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
m_program_depth.release();
glDisable(GL_CULL_FACE);
// 2ème passe :
glViewport(0, 0, width(), height());
glClearColor(0.4f, 0.4f, 0.4f,1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT );
m_program_rendu.bind();
VBO_vertex.bind();
m_program_rendu.enableAttributeArray("pos_vertex_rendu");
m_program_rendu.setAttributeBuffer("pos_vertex_rendu", GL_FLOAT, 0, 3);
VBO_vertex.release();
VBO_couleur.bind();
m_program_rendu.enableAttributeArray("color_vertex_rendu");
m_program_rendu.setAttributeBuffer("color_vertex_rendu", GL_FLOAT, 0, 3);
VBO_couleur.release();
QMatrix4x4 scaleBiasMatrix;
scaleBiasMatrix.scale(QVector3D(0.5f, 0.5f, 0.5f));
scaleBiasMatrix.translate(QVector3D(0.5f, 0.5f, 0.5f));
m_program_rendu.setUniformValue("modelViewProjectionMatrix_rendu", vueProjMatrix * vueLookAtMatrix);
m_program_rendu.setUniformValue("lightModelViewProjectionMatrix_rendu", scaleBiasMatrix * lightProjMatrix * lightLookAtMatrix);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, shadowMap);
m_program_rendu.setUniformValue("shadowMap", 0);
m_program_rendu.setUniformValue("modelMatrix_rendu", QMatrix4x4());
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
glBindTexture(GL_TEXTURE_2D, 0);
m_program_rendu.disableAttributeArray("pos_vertex_rendu");
m_program_rendu.disableAttributeArray("color_vertex_rendu");
m_program_rendu.release();
// Méthode createTexture(int w, int h, bool isDepth = false) // Code repiqué sur le net...
{
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D,0,(!isDepth ? GL_RGBA8 : GL_DEPTH_COMPONENT),w,h,0,isDepth ? GL_DEPTH_COMPONENT : GL_RGBA,GL_FLOAT,NULL);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER);
int i;
i=glGetError();
if(i!=0)
{
qDebug() << "Error happened while loading the texture: " << i;
}
glBindTexture(GL_TEXTURE_2D, 0);
return textureId;
}
// Vertex Shader du programme 1 (génère la texture de profondeur) :
#version 330 core
attribute vec3 pos_vertex_depth;
uniform mat4 modelViewProjectionMatrix_depth;
uniform mat4 modelMatrix_depth;
void main()
{
gl_Position = modelViewProjectionMatrix_depth * modelMatrix_depth * vec4(pos_vertex_depth, 1.0);
}
// Fragment Shader du programme 1 (génère la texture de profondeur) :
#version 330 core
void main()
{
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
// Vertex Shader du programme 2 (génère l'image finale) :
#version 330 core
attribute vec3 pos_vertex_rendu;
attribute vec3 color_vertex_rendu;
uniform mat4 modelMatrix_rendu;
uniform mat4 modelViewProjectionMatrix_rendu;
uniform mat4 lightModelViewProjectionMatrix_rendu;
out vec4 lightVertexPosition_rendu;
out vec3 color_rendu;
void main()
{
gl_Position = modelViewProjectionMatrix_rendu * modelMatrix_rendu * vec4(pos_vertex_rendu, 1.0);
lightVertexPosition_rendu = lightModelViewProjectionMatrix_rendu * modelMatrix_rendu * vec4(pos_vertex_rendu, 1.0);
color_rendu = color_vertex_rendu;
}
// Fragment Shader du programme 2 (génère l'image finale) :
#version 330 core
uniform sampler2D shadowMap;
in vec4 lightVertexPosition_rendu;
in vec3 color_rendu;
out vec4 outColor_rendu;
void main() // POUR LE MOMENT JE NE RENVOIE QUE LA COULEUR DU FRAGMENT (TEST)
{
#if 0
float shadowValue = 0.0;
vec4 lightVertexPosition2 = lightVertexPosition_rendu;
lightVertexPosition2 /= lightVertexPosition2.w;
for(float x=-0.001;x<=0.001;x+=0.0005)
{
for(float y=-0.001;y<=0.001;y+=0.0005)
{
if(texture2D(shadowMap, lightVertexPosition2.xy + vec2(x,y)).r >= lightVertexPosition2.z)
shadowValue+=1.0;
}
}
shadowValue /= 16.0;
//gl_FragColor = vec4(outColor * (shadowValue+0.05), 1.0);
//gl_FragColor = vec4(outColor, 1.0);
#endif
outColor_rendu = vec4(color_rendu, 1.0);
} |
Partager