Weird issue with GLSL Radial Blur - c++

Shader used: http://www.gamerendering.com/2008/12/20/radial-blur-filter/
My issue is this: The whole scene only takes up a quarter of the screen space (which is a rectangle of these coordinates: width/2,0 width,height/2), and it seems to have been literally clipped (not scaled). It also rendered it with Y inverted (but I was able to fix this by removing the - sign from line 9's gl_Position.y).
I used this tutorial to do the post-processing, with the exception of using basic glBegin(GL_QUADS) instead of vertex arrays.
EDIT 2: I have tried using another shader (http://www.geeks3d.com/20110428/shader-library-swirl-post-processing-filter-in-glsl/), and it worked perfectly fine. No clipping.
EDIT: Here is the source of the shaders (I did some minor edits):
Fragment shader:
#version 140
// This texture should hold the image to blur.
// This can perhaps be a previous rendered scene.
uniform sampler2D tex;
// texture coordinates passed from the vertex shader
varying vec2 uv;
// some const, tweak for best look
const float sampleDist = 1.0;
const float sampleStrength = 20.2;
void main(void)
{
// some sample positions
float samples[10] =
float[](-0.08,-0.05,-0.03,-0.02,-0.01,0.01,0.02,0.03,0.05,0.08);
// 0.5,0.5 is the center of the screen
// so substracting uv from it will result in
// a vector pointing to the middle of the screen
vec2 dir = 0.5 - uv;
// calculate the distance to the center of the screen
float dist = sqrt(dir.x*dir.x + dir.y*dir.y);
// normalize the direction (reuse the distance)
//dir = dir/dist;
dir /= dist;
// this is the original colour of this fragment
// using only this would result in a nonblurred version
vec4 color = texture2D(tex,uv);
vec4 sum = color;
// take 10 additional blur samples in the direction towards
// the center of the screen
for (int i = 0; i < 10; i++)
{
sum += texture2D( tex, uv + dir * samples[i] * sampleDist );
}
// we have taken eleven samples
sum *= 1.0/11.0;
// weighten the blur effect with the distance to the
// center of the screen ( further out is blurred more)
float t = dist * sampleStrength;
t = clamp( t ,0.0,1.0); //0 <= t <= 1
//Blend the original color with the averaged pixels
gl_FragColor = mix( color, sum, t );
}
Vertex shader:
#version 140
varying vec2 uv;
// this vertex shader is from AMD RenderMonkey
void main(void)
{
gl_Position = vec4( gl_Vertex.xy, 0.0, 1.0 );
gl_Position = sign( gl_Position );
// Texture coordinate for screen aligned (in correct range):
uv = (vec2( gl_Position.x, gl_Position.y ) + vec2(1.0 )) / vec2( 2.0 );
}
Post-processor:
#include "std/opengl.h"
#include "postprocess.h"
Post::Post(Pos2D res) {
this->res = res;
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &this->texture);
glBindTexture(GL_TEXTURE_2D, this->texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res.x, res.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glGenRenderbuffers(1, &this->rbo);
glBindRenderbuffer(GL_RENDERBUFFER, this->rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, res.x, res.y);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glGenFramebuffers(1, &this->fbo);
glBindFramebuffer(GL_FRAMEBUFFER, this->fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->texture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, this->rbo);
GLenum status;
if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
fprintf(stderr, "Framebuffer error! %i", status);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Post::~Post() {
glDeleteRenderbuffers(1, &this->rbo);
glDeleteTextures(1, &this->texture);
glDeleteFramebuffers(1, &this->fbo);
}
void Post::update(Pos2D res) {
this->res = res;
glBindTexture(GL_TEXTURE_2D, this->texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res.x, res.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glBindRenderbuffer(GL_RENDERBUFFER, this->rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, res.x, res.y);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
void Post::bind() {
glBindFramebuffer(GL_FRAMEBUFFER, this->fbo);
}
void Post::unbind() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Post::render(Shader* shader) {
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 1.0);
shader->run();
auto tex = glGetUniformLocation(shader->program_handle, "tex");
glBindTexture(GL_TEXTURE_2D, this->texture);
glUniform1i(tex, 0);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(0, 0);
glTexCoord2f(0.0, 1.0);
glVertex2f(0, this->res.y);
glTexCoord2f(1.0, 1.0);
glVertex2f(this->res.x, this->res.y);
glTexCoord2f(1.0, 0.0);
glVertex2f(this->res.x, 0);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glUseProgram(0);
}
Screenshot of the issue (as you can see, it's cut off):
Screenshot when I disable the shader (as you can see, it can render to the whole window, it is not clipped):

the problem comes from the way you define your vertex coordinates:
glTexCoord2f(0.0, 0.0);
glVertex2f(0, 0);
glTexCoord2f(0.0, 1.0);
glVertex2f(0, this->res.y);
glTexCoord2f(1.0, 1.0);
glVertex2f(this->res.x, this->res.y);
glTexCoord2f(1.0, 0.0);
glVertex2f(this->res.x, 0);
instead of using the window resolution as vertex coordinates, try drawing a quad with the following vertices: ( -1, -1 ), ( -1, 1 ), ( 1, 1 ) and ( 1, -1 ) - that would result in a full-screen quad in opengl's native coordinate system. in your vertex shader, it looks to me like your're trying to use the sign function to transform the vertex coords into this coordinate system:
gl_Position = vec4( gl_Vertex.xy, 0.0, 1.0 );
gl_Position = sign( gl_Position );
but of course then you'll get a quad with the corner points ( 0, 0 ), ( 0, 1 ), ( 1, 1 ) and ( 1, 0 ) instead, which explains why it only fills part of the screen.
And as a result, the texture coordinates that you calculate in your shader with this line:
uv = (vec2( gl_Position.x, gl_Position.y ) + vec2(1.0 )) / vec2( 2.0 );
are also wrong, resulting in the 'clipped' look you're experiencing - your texcoords range from 0.5 to 1, instead of 0 to 1. By the way, you explicitly define texcoords with glTexCoord2f anyway, and those are correct - so there's no need to calculate them again in the shader, just use the built-in gl_MultiTexcoord.

Related

opengl - Only one texture displaying

I have been trying draw a hut (as a cylinder with a cone on top) and add a brick txture to the wall and a roof-tile texture to the roof. However, I am only getting the first texture that I load (the bricks).
Here is my code (Please note that I have tried to switch between textures using glActiveTexture):
void drawCylinder()
{
int width, height;
unsigned char * data_for_wall = SOIL_load_image("./bricks.jpg", &width, &height, NULL, 0);
glDisable(GL_LIGHTING);
glGenTextures( 2, textures );
glActiveTexture(GL_TEXTURE0);
glEnable( GL_TEXTURE_2D );
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Generate mipmaps, by the way.
glGenerateMipmap(GL_TEXTURE_2D);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, data_for_wall);
for(float theta = 0.0; theta <= 360.0; theta += 10.0 )
{
//colors[k] = color4(0.69, 0.35, 0.0, 1.0); //This color is brown.
tex_coords[global_index]=vec2(theta*DegreesToRadians, 0.0);
float x = 0.15*sin(theta*DegreesToRadians);
float y = 0.15*cos(theta*DegreesToRadians);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(x, 0.0, y, 1.0);
// This is the
// bottom of the cylinder. The points are plotted in a full circle. The first three numbers are the x,y and z values
// respectively. The last number (ie. 1.0) is not important - it just converts to homogeneous coordinates.
++global_index;
tex_coords[global_index] = vec2(theta*DegreesToRadians, 0.25);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(x, 0.25, y, 1.0);
// This is the
// top of the cylinder
++global_index;
}
}
//The roof of the hut
void drawCone()
{
int width, height;
unsigned char * data_for_roof = SOIL_load_image("./roof_tiles.jpg", &width, &height, NULL, 0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture( GL_TEXTURE_2D, textures[1] );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Generate mipmaps, by the way.
glGenerateMipmap(GL_TEXTURE_2D);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, data_for_roof);
int index = 0;
int l = 0;
for(float theta = 0.0; theta <= 360.0; theta += 10.0)
{
tex_coords[global_index]=vec2(theta*DegreesToRadians, 0.25);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(0.0, 0.5, 0.0, 1.0); // This is the top of the cone.
++global_index;
tex_coords[global_index] = vec2(theta*DegreesToRadians, 0.5);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(0.25*sin(theta*DegreesToRadians), 0.25, 0.25*cos(theta*DegreesToRadians), 1.0);
// This is the
// bottom of the cone.
++global_index;
}
}
And here is the display function:
void
display( void )
{
mat4 mv = Translate(0.0, -0.065, -rad)*RotateX(Theta[0])*RotateY(Theta[1])*RotateZ(Theta[2]);
mat4 p = Perspective(10.0, aspectRatio, zNear, zFar);
glUniformMatrix4fv( matrix_loc, 1, GL_TRUE, mv );
glUniformMatrix4fv( projection_loc, 1, GL_TRUE, p );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glUniform3fv( theta, 1, Theta );
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glDrawArrays( GL_TRIANGLE_STRIP, 0, 74 );
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glDrawArrays( GL_TRIANGLE_STRIP, 74, 74);
glutSwapBuffers();
}
I am not sure if it is important to include the fragment shader but I will do it anyways:
#version 150
in vec2 texCoord;
out vec4 fColor;
uniform sampler2D texture;
void main()
{
fColor = texture2D( texture, texCoord );
}
I have been struggling for hours to get this right. Does anyone know what I have done wrong?
glActiveTexture() is used to set the texture slot that you are binding a texture to when multi-texturing (rendering more than one texture in a single pass). For example, you might have one texture for a texture map, another for normal map and so on.
However, you are not multi-texturing, because you render the walls and the cone in separate passes (i.e. two separate calls to glDrawArrays()), and your shader only uses a single texture per pass. So within each pass you are only rendering a single texture, which will be in slot 0.
If you set the active texture to GL_TEXTURE1 and then call glBindTexture() then the texture will be bound to slot 1, and slot 0 will remain unchanged.
So, set the active texture slot to 0 both times. Remove this line from your display() function:
glActiveTexture(GL_TEXTURE1);

Shadow Mapping in OpenGL

I can't get shadow mapping to work in my application. I try to render a quad bike and view its shadow on a floor beneath it.
Here's some of my code.
Texture creation:
// Create a depth texture
glGenTextures(1, &depth_texture);
glBindTexture(GL_TEXTURE_2D, depth_texture);
// Allocate storage for the texture data
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32 ,1600, 900, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
// Set the default filtering modes
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Set up wrapping modes
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
// Create FBO to render depth into
glGenFramebuffers(1, &depth_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo);
// Attach the depth texture to it
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
depth_texture, 0);
// Disable color rendering as there are no color attachments
glDrawBuffer(GL_NONE);
//check fbo status
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(result != GL_FRAMEBUFFER_COMPLETE)
throw std::runtime_error("shadow mapping framebuffer error");
//bind default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
render to depth texture:
progShadow.Use();
glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo);
glClear(GL_DEPTH_BUFFER_BIT);
glm::mat4 shadowProjection = glm::frustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 100.0f);
glm::mat4 shadowView = glm::lookAt(light.position, glm::vec3(0,0,0), glm::vec3(0,1,0));
glm::mat4 shadowModel(1);
if(g_rotate)
shadowModel = glm::rotate((float)clock() / (float)CLOCKS_PER_SEC, glm::vec3(0,1,0));
glm::mat4 shadowMVP = shadowProjection * shadowView * shadowModel;
progShadow.SetUniform("MVPMatrix", shadowMVP);
quadBike.Draw();
I also use a "test" shader program that renders my depth texture. Here's what it looks like.
So I guess I'm good until now.
Now I render the scene normally.
glBindTexture(GL_TEXTURE_2D, depth_texture);
prog.Use();//main program
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 shadowBias = glm::mat4(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
glm::mat4 ShadowBiasMVP = shadowBias * shadowMVP;
prog.SetUniform("ShadowBiasMVP", ShadowBiasMVP);
//draw quadBike and floor
...
Relevant parts of my vertex shader:
#version 430
...
out vec4 shadowCoord;
void main()
{
gl_Position = ProjectionMatrix * CameraMatrix * ModelMatrix * vec4(vertex, 1.0);
shadowCoord = ShadowBiasMVP * vec4(vertex, 1.0);
...
}
Relevant parts of my fragment shader:
#version 430
...
uniform sampler2D shadowMap;
in vec4 shadowCoord;
void main()
{
...
float visibility = 1.0;
if ( texture(shadowMap, shadowCoord.xy).z < shadowCoord.z)
visibility = 0.0;
...
}
Now the problem is that I get a scene that is fully dark as if it was all covered by shadow. Only when the light is really close to the quad bike, it renders it normally. (the depth texture is visible on the right side because it's rendered with a different program. I use it for testing)
What am I doing wrong?
You should read a grayscale depthtexture at the first component.
texture(shadowMap, shadowCoord.xy).r or
texture(shadowMap, shadowCoord.xy).x
The Shadow Coordinates should be dehomogenized (divided by w) after interpolation.
-> in fragment shader: shadowPos = shadowPos/shadowPos.w;
If no other techniques like polygon offset is used you need to substract a bias from the shadow depth value to prevent self shadowing.
Here is an example function to calculate shadows in fragment shader. Note: It is part of a deferred renderer, that is why matrix multiplication is done in the fragment shader.
float calculateShadow(vec3 position){
vec4 shadowPos = depthBiasMV * vec4(position,1);
shadowPos = shadowPos/shadowPos.w;
float bias = 0.0012;
float visibility = 1.0f;
if ((shadowPos.x < 0 || shadowPos.x > 1 || shadowPos.y < 0 || shadowPos.y > 1 || shadowPos.z < 0 || shadowPos.z > 1)){
visibility = 1.0f;
}else{
float shadowDepth = texture(depthTex, shadowPos.xy).r;
if(shadowDepth<shadowPos.z-bias)
visibility = 0.0f;
}
return visibility;
}

texture(...) function always returns 0

I have been trying to get shadow mapping to work for quite some time now and I am still no closer than I was a month ago. I am beginning to think it may be an issue with my GL drivers because I haven't been able to see any side effects such as "light acne."
I was told to start using a sampler2DShadow instead of a sampler2D and this is what I did. However, whenever I sample the map using texture(...) the result is always 0. Why would this be happening?
I have tried entering manual depthCoord values and I still get 0. Could this be a result of the shadowMap itself (i.e the way it has been setup?) or is it a driver issue?
Framebuffer Setup
FramebufferName = 0;
glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glGenTextures(1, &depthTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
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_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT, 512, 512, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Fragment Shader
uniform sampler2DShadow shadowMap;
in vec4 depthCoord;
void main(){
//The final color after lighting is stored as 'FinalColor'
float visibility = 1.0;
if (texture(shadowMap, depthCoord.xyz) == 0.0){
visibility = 0.1;
}
color = vec4(finalColor.rgb * visibility, 1.0);
}
Rendering Code
glm::vec3 lightInvDir = glm::vec3(0,-10,-10);
glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20);
glm::mat4 depthViewMatrix = glm::lookAt(lightInvDir, glm::vec3(0,0,0), glm::vec3(0,1,0));
glm::mat4 depthModelMatrix = glm::mat4(1.0);
glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix;
glm::mat4 biasMatrix(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0
);
glm::mat4 depthBiasMVP = biasMatrix*depthMVP;
/* Shadow */
subShader->useShader();
glViewport(0,0,512,512);
glUniformMatrix4fv(glGetUniformLocation(subShader->getShader(),"depthMVP"), 1, GL_FALSE, &depthMVP[0][0]);
glBindFramebuffer(GL_FRAMEBUFFER, Shadows::framebuffer());
renderBuffer(objBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
/* Clear */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Shader */
objShader->useShader();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Shadows::shadowmap());
glUniform1f(glGetUniformLocation(objShader->getShader(),"shadowMap"),0);
/* Render Scene */
glUniformMatrix4fv(glGetUniformLocation(objShader->getShader(),"depthBiasMVP"), 1, GL_FALSE, &depthBiasMVP[0][0]);
glViewport(0,0,640,480);
glUniform1f(glGetUniformLocation(objShader->getShader(),"renderingPass"),1.0);
renderBuffer(objBuffer);
The majority of this code has been learned from sites such as (http://www.opengl-tutorial.org/) with modifications based on (http://www.fabiensanglard.net/shadowmapping/index.php) and the red book.

OpenGL Shadow Mapping with FBO - multiple trailing draw

I am trying to implement shadow mapping in our game project. I am using render to texture technique with two pass rendering. I have created a FBO first and bound a texture for depth component only. In the first pass, I enable this FBO, disable texture and render my scene from light POV. In the second pass, I pass the depth texture to the shader and render the scene normally. I perform the shadow related calculation in the shader.
But, my code is not working correctly. I am not able to see any shadow. Also, when I render both pass, I see a multiple drawing of the whole world trailing one after another if my camera is looking above a certain angle : 45. If I look below that angle, the rendering looks ok. What may be the source of this problem?
. If I disable the first pass, the world looks darker but the trailing scene is gone. I have also attached my codes below.
I have also another confusion. I have disabled texture for the first shadowmap pass. But I send the texture coordinates with my vertex coordinates to the VBO. Will that cause any problem?
FBO Initialization
LightPosition = glm::vec3(50.0f, 40.0f, 50.0f);
upVector = glm::vec3(0.0f, 1.0f, 0.0f);
glGenTextures(1, &m_shadowMap);
glBindTexture(GL_TEXTURE_2D, m_shadowMap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,
WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
glDrawBuffers(0, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowMap, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (Status != GL_FRAMEBUFFER_COMPLETE) {
printf("FB error, status: 0x%x\n", Status);
return false;
}
return true;
Shadow Map Pass:
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glViewport(0, 0, windowWidth, windowHeight);
glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO.m_fbo);
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glm::mat4 lightProjection = glm::perspective(45.0f,
1.0f * windowWidth / windowHeight, 0.125f, 1000.0f);
glGetFloatv(GL_PROJECTION_MATRIX, shadowMapFBO.LightProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glm::mat4 lightModelView = glm::lookAt(shadowMapFBO.LightPosition,
glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glGetFloatv(GL_MODELVIEW_MATRIX, shadowMapFBO.LightModelViewMatrix);
glm::mat4 lmvp = lightProjection * lightModelView;
glCullFace(GL_FRONT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glUniform1i(Shader::id_uniform_layer, 0);
world->render(lmvp);
printGLError();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Render Pass:
static glm::vec3 cCameraPosition = glm::vec3(0.0f, 5.0f, 10.0f);
static glm::vec3 cLightPosition = glm::vec3(50.0f, 40.0f, 50.0f);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, windowWidth, windowHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glm::mat4 modelView = player->getView();
float viewAngle = 45.0f;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glm::mat4 projection = glm::perspective(viewAngle,
1.0f * windowWidth / windowHeight, 0.01f, 1000.0f);
glm::mat4 mvp = projection * modelView;
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shadowMapFBO.m_shadowMap);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5f, 0.5f, 0.5f);
glScalef(0.5f, 0.5f, 0.5f);
glMultMatrixf(shadowMapFBO.LightProjectionMatrix);
glMultMatrixf(shadowMapFBO.LightModelViewMatrix);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, id_texture_blocks);
glUseProgram(Shader::id_program);
glUniform3fv(Shader::id_uniform_lightPosition, 1,
glm::value_ptr(cLightPosition));
glUniform3fv(Shader::id_uniform_CameraPosition, 1,
glm::value_ptr(*(player->getCoordinates())));
//Enabling color write (previously disabled for light POV z-buffer rendering)
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glUniform1i(Shader::id_shader_shadow, 1);
glUniformMatrix4fv(Shader::id_uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));
glEnable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glUniform1i(Shader::id_uniform_layer, 0);
world->render(mvp);
printGLError();
Vertex Shader:
attribute vec4 coordinates;
uniform mat4 mvp;
//Fragment shader forward variables.
varying vec4 voxel;
//shadow map
// Used for shadow lookup
varying vec4 ShadowCoord;
uniform vec3 LightPosition, CameraPosition;
varying vec3 LightDirection, LightDirectionReflected, CameraDirection, Normal;
void main(void) {
//shadow map
LightDirection = LightPosition - gl_Vertex.xyz;
LightDirectionReflected = reflect(-LightDirection, gl_Normal);
CameraDirection = CameraPosition - gl_Vertex.xyz;
Normal = gl_Normal;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_Vertex;
voxel = coordinates;
//Calculates projection on xyz.
gl_Position = mvp * vec4(coordinates.xyz, 1);
}
Fragment Shader:
#extension GL_EXT_gpu_shader4 : enable
//Rendering layer.
uniform int layer;
//Colors.
uniform float colorRed;
uniform float colorGreen;
uniform float colorBlue;
uniform float colorAlpha;
//Fog density.
uniform float fogDensity;
varying vec4 voxel;
uniform sampler2D texture;
const float N_TEXTURES = 32.0;
//////////////////////shadow map
uniform sampler2DShadow ShadowMap;
varying vec4 ShadowCoord;
varying vec3 LightDirection, LightDirectionReflected, CameraDirection, Normal;
void main(void) {
vec2 coord2d;
float intensity;
vec4 color = texture2D(texture, coord2d);
float z = gl_FragCoord.z / gl_FragCoord.w;
float fog = clamp(exp(-fogDensity * z * z), 0.2, 1.0);
color.xyz = color.xyz * intensity;
//shadow map
float Shadow = shadow2DProj(ShadowMap, gl_TexCoord[1]).r;
float NdotLD = max(dot(normalize(LightDirection), Normal), 0.0) * Shadow;
float Spec = pow(max(dot(normalize(LightDirectionReflected), normalize(CameraDirection)), 0.0), 32.0) * Shadow;
color.xyz = color.xyz * (0.25 + NdotLD * 0.75 + Spec);
//Final color.
vec4 fogColor = vec4(colorRed, colorGreen, colorBlue, colorAlpha);
gl_FragColor = mix(fogColor, color, fog);
}
At a glance it looks like you're not using glClear so the sky is whatever was in the last frame, or at least its not working. What's the alpha value of the glClearColor?

How to get texture coordinate to GLSL in version 150?

In GLSL version 110 i can get coordinate in gl_TexCoord[] but it's deprecated in 150.
OpenGL code:
shader.setupShaderFromFile(GL_VERTEX_SHADER, "t.vert");
shader.setupShaderFromFile(GL_FRAGMENT_SHADER, "t.frag");
shader.linkProgram();
glGetFloatv(GL_MODELVIEW_MATRIX, modelview_mat_);
glGetFloatv(GL_PROJECTION_MATRIX, projectionview_mat_);
shader.begin();
glUniformMatrix4fv( glGetUniformLocation(shader.getProgram(), "MVMatrix"), 1, GL_FALSE, modelview_mat_);
glUniformMatrix4fv( glGetUniformLocation(shader.getProgram(), "MPMatrix"), 1, GL_FALSE, projectionview_mat_);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);glVertex2f(0, 0);
glTexCoord2f(1, 0);glVertex2f(100, 0);
glTexCoord2f(1, 1);glVertex2f(100, 100);
glTexCoord2f(0, 1);glVertex2f(0, 100);
glEnd();
shader.end();
Shader Code:
VERTEX-
#version 150
in vec3 in_vertex;
in vec2 in_coord;
uniform mat4 MVMatrix;
uniform mat4 MPMatrix;
out vec2 tex_coord;
void main()
{
vec4 v = vec4( in_vertex, 1.0 );
tex_coord = in_coord;
gl_Position = MPMatrix * MVMatrix * v;
}
FRAGMENT:
#version 150
in vec2 tex_coord;
out vec4 frgcolor;
void main()
{
frgcolor = vec4( tex_coord, 0.0, 1.0);
}
final screen is a red quad.
How to pass texture coordinate to shader? or my code is wrong?
If you don't want to use the deprecated methods, you'll have to stop using glTexCoord2f, and use a custom attribute.
If you want to stay with immediate mode, you'll use glVertexAttrib2f.
You pair this up with your new variable 'in_coord' by quering the index after shader linking:
int program = glCreateProgram();
//create shader as normal
int texcoord_index = glGetAttribLocation(program, "in_coord");
glBegin(GL_QUADS);
glVertexAttrib2f(texcoord_index, 0, 0); ...
If you want to use VA/VBO instead, the functions you use instead is glEnableVertexAttribArray/glVertexAttribPointer
in your case just look into gl_TexCoord[0] in your vertex shader. Definitely works with shader model 1.5
in C++:
glActiveTexture(GL_TEXTURE0 );
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2f(0, 0);glVertex2f(0, 0);
glTexCoord2f(1, 0);glVertex2f(100, 0);
glTexCoord2f(1, 1);glVertex2f(100, 100);
glTexCoord2f(0, 1);glVertex2f(0, 100);
glEnd();
in vertex shader:
gl_TexCoord[0]=gl_MultiTexCoord0;
in fragment shader:
vec4 c = texture2D(texSampler, gl_TexCoord[0].st );