PDA

View Full Version : Help with shader error



paul_g_griffiths
01-07-2017, 05:07 AM
I'm receiving a shader errors:
0(15) : error C1321: structure type 'lightType' may not be defined in a uniform or buffer block

Heres what the part is:

layout(std140, binding = 1) uniform lightArray {
struct lightType {
vec4 position;
vec4 color;
} light[100];
} LightArray;

This part I'm receiving error: 0(8) : error C0000: syntax error, unexpected type identifier, expecting '{' at token "vec4"
0(10) : error C0000: syntax error, unexpected '}' at token "}"
It looks allright to me, what's wrong?

gl_Position = LightTransform.VPMatrix[gl_InvocationID] * vec4(outVertexPosition[i], 1.f);

Heres the whole shader:

#version 420 core

layout(std140, binding = 2) uniform lightTransform {
mat4 VPMatrix[600];
} LightTransform;

layout(std140, binding = 1) uniform lightArray {
struct lightType {
vec4 position;
vec4 color;
} light[100];
} LightArray;

layout(triangles, invocations = 10) in;
layout(triangle_strip, max_vertices = 3) out;

layout(location = 0) in vec3 outVertexPosition[];

out gl_PerVertex {
vec4 gl_Position;
};

void main() {

vec3 normal = cross(outVertexPosition[2]-outVertexPosition[0], outVertexPosition[0]-outVertexPosition[1]);
vec3 light = vec3(LightArray.light[gl_InvocationID].position) - outVertexPosition[0];

if (dot(normal, light) > 0.f) {

for (int i=0; i<3; ++i) {
gl_Position = LightTransform.VPMatrix[gl_InvocationID] * vec4(outVertexPosition[i], 1.f);
gl_Layer = gl_InvocationID;
EmitVertex();
}
EndPrimitive();

}
}

It comes from a book "opengl insights"

Thank you.

paul_g_griffiths
01-07-2017, 06:12 AM
I moved the struct outside to this and it compiles the application runs.

struct lightType {
vec4 position;
vec4 color;
};

layout(std140, binding = 1) uniform lightArray {
lightType light[100];
} LightArray;

This is what I get, supposed to be multiple shadows:
https://s23.postimg.org/70tyguknv/pic.jpg

Any idea what the problem is?

paul_g_griffiths
01-07-2017, 07:36 AM
I have changed the shader code and updated the application code too:


layout(std140, binding = 1) uniform lightPosArray {
vec4 lightPos[100];
} LightPosArray;

layout(std140, binding = 1) uniform lightColorArray {
vec4 lightColor[100];
} LightColorArray;

The result is similar to the picture in previous post, any ideas?

paul_g_griffiths
01-07-2017, 09:04 AM
I know it's a lot but I'm posting the scene code, can you tell anything wrong?


/*
* dragon.cpp
*
* Created on: Sep 24, 2011
* Author: aqnuep
*/

#include <iostream>
#include <fstream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <glm/glm.hpp>
#include <glm/gtx/matrix_operation.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "wavefront.h"
#include "tga.h"
#include "dragon.h"
#define M_PI 3.14
#define CHECK_GL_ERROR() \
{ \
GLenum glError; \
if ((glError = glGetError()) != GL_NO_ERROR) { \
cerr << "OpenGL error code in '" << __FILE__ << "' at line " << __LINE__ << ": " << gluErrorString(glError) << endl; \
} \
}

#define CHECK_FRAMEBUFFER_STATUS() \
{ \
GLenum status; \
status = glCheckFramebufferStatus(GL_FRAMEBUFFER); \
switch(status) { \
case GL_FRAMEBUFFER_COMPLETE: \
break; \
case GL_FRAMEBUFFER_UNSUPPORTED: \
/* choose different formats */ \
cerr << "Unsupported framebuffer format!" << endl; \
break; \
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: \
cerr << "Incomplete framebuffer attachment!" << endl; \
break; \
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: \
cerr << "Missing framebuffer attachment!" << endl; \
break; \
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: \
cerr << "Incomplete layer target!" << endl; \
break; \
default: \
/* programming error; will fail on all hardware */ \
cerr << "Invalid framebuffer format!" << endl; \
exit(0); \
} \
}

using namespace glm;
using namespace demo;

namespace dragon {

DragonDemo::DragonDemo() {

cerr << "> Initializing scene data..." << endl;

// initialize camera data
float aspectRatio = SCREEN_WIDTH / SCREEN_HEIGHT;
float fieldOfView = 45.f;
camera.position = vec3(-7.5f, 5.5f, 7.5f);
camera.rotation = vec3(40.0f, 45.0f, 0.0f);
transform.zNear = 0.1f;
transform.zFar = 40.f;
transform.nearTop = transform.zNear * tan(0.5f * fieldOfView);
transform.nearRight = transform.nearTop * aspectRatio;
transform.Viewport = vec4(0.f, 0.f, SCREEN_WIDTH, SCREEN_HEIGHT);
transform.ProjectionMatrix = perspective(fieldOfView, aspectRatio, transform.zNear, transform.zFar);

// create uniform buffer and store camera data
glGenBuffers(1, &transformUB);
glBindBuffer(GL_UNIFORM_BUFFER, transformUB);
glBufferData(GL_UNIFORM_BUFFER, sizeof(transform), &transform, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, transformUB);

loadShaders();
loadModels();
setupGBuffer();
createLights();

glEnable(GL_FRAMEBUFFER_SRGB);

cerr << "> Configuring rendering environment..." << endl;

glEnable(GL_CULL_FACE);

cerr << "> Done!" << endl;

CHECK_GL_ERROR();
}

DragonDemo::~DragonDemo() {

cerr << "> Freeing graphics resources... ";

// delete shader programs
glDeleteProgram(GBufferVSP);
glDeleteProgram(GBufferFSP);
glDeleteProgram(shadowMultiVSP);
glDeleteProgram(shadowMultiGSP);
glDeleteProgram(shadowSingleVSP);
glDeleteProgram(lightVSP);
glDeleteProgram(lightGSP);
glDeleteProgram(lightFSP);

// delete program pipelines
glDeleteProgramPipelines(1, &GBufferPPL);
glDeleteProgramPipelines(1, &shadowMultiPPL);
glDeleteProgramPipelines(1, &shadowSinglePPL);
glDeleteProgramPipelines(1, &lightPPL);

// delete uniform buffers
glDeleteBuffers(1, &transformUB);
glDeleteBuffers(1, &lightTransformUB);
glDeleteBuffers(1, &lightPosUB);
glDeleteBuffers(1, &lightColorUB);

// delete vertex buffer
glDeleteBuffers(1, &vertexBuffer);

// delete index buffer
glDeleteBuffers(1, &indexBuffer);

// delete vertex arrays
glDeleteVertexArrays(1, &vertexArray);

// delete G-buffer textures
glDeleteTextures(1, &positionGBT);
glDeleteTextures(1, &normalGBT);
glDeleteTextures(1, &depthGBT);

// delete shadow map
glDeleteTextures(1, &shadowArrayTex);

// delete framebuffers
glDeleteFramebuffers(1, &shadowFB);

cerr << "Done!" << endl;

}

void DragonDemo::loadModels() {

cerr << "> Loading models..." << endl;

WaveFrontObj dragonObj("models/dragon.obj");

cerr << "> Uploading mesh data to GPU..." << endl;

// create empty index buffer
int indexBufferSize = dragonObj.index.size() * sizeof(uint);
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSize, NULL, GL_STATIC_DRAW);

// map index buffer and fill with data
uint *index = (uint*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, indexBufferSize,
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);

for (uint i = 0; i < dragonObj.index.size(); ++i)
index[i] = dragonObj.index[i];

glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);

// create empty vertex buffer
int vertexBufferSize = dragonObj.vertex.size() * sizeof(Vertex);
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertexBufferSize, NULL, GL_STATIC_DRAW);

// map vertex buffer and fill with data
Vertex *vertex = (Vertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, vertexBufferSize,
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);

for (uint i = 0; i < dragonObj.vertex.size(); ++i) {
vertex[i].position[0] = dragonObj.vertex[i].x;
vertex[i].position[1] = dragonObj.vertex[i].y;
vertex[i].position[2] = dragonObj.vertex[i].z;
vertex[i].normal[0] = dragonObj.normal[i].x;
vertex[i].normal[1] = dragonObj.normal[i].y;
vertex[i].normal[2] = dragonObj.normal[i].z;
}

glUnmapBuffer(GL_ARRAY_BUFFER);

// setup vertex array
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal));
glBindVertexArray(0);

// setup draw command
drawCommand.prim_type = GL_TRIANGLES;
drawCommand.indexOffset = 0;
drawCommand.indexCount = dragonObj.index.size();

CHECK_GL_ERROR();

}

void DragonDemo::updateLights() {

// update light positions and view-projection matrices
mat4 ProjMat = perspective(90.f, (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.01f, 40.f);
for (int i = 0; i < NUMBER_OF_LIGHTS; ++i) {
float angle = (float)i / NUMBER_OF_LIGHTS + lightRotationFactor;
lightPos[i] = vec4(sin(angle * M_PI * 2.f) * 4.f, -2.5f,
cos(angle * M_PI * 2.f) * 4.f, 1.f);
lightTransform[i].VPMatrix = ProjMat * translate(rotate(rotate(mat4(1.f), +30.f, vec3(1.f, 0.f, 0.f)), angle * -360.f, vec3(0.f, 1.f, 0.f)), -vec3(lightPos[i]));
}

// update light uniform buffer
glBindBuffer(GL_UNIFORM_BUFFER, lightPosUB);
glBufferSubData(GL_UNIFORM_BUFFER, 0, NUMBER_OF_LIGHTS * sizeof(vec4), lightPos);

glBindBuffer(GL_UNIFORM_BUFFER, lightColorUB);
glBufferSubData(GL_UNIFORM_BUFFER, 0, NUMBER_OF_LIGHTS * sizeof(vec4), lightColor);


// update shadow rendering VP matrix uniform buffer
glBindBuffer(GL_UNIFORM_BUFFER, lightTransformUB);
glBufferSubData(GL_UNIFORM_BUFFER, 0, NUMBER_OF_LIGHTS * sizeof(LightTransform), lightTransform);

}

void DragonDemo::createLights() {

cerr << "> Creating lights..." << endl;

// generate lights
for (int i = 0; i < NUMBER_OF_LIGHTS; ++i) {
lightColor[i] = vec4((rand() * 0.2f) / RAND_MAX + 0.1f,
(rand() * 0.2f) / RAND_MAX + 0.1f,
(rand() * 0.2f) / RAND_MAX + 0.1f, 1.f);

lightPos[i] = vec4(0.0f, 0.0f, 0.0f, 1.f);
}

// create light uniform buffer
glGenBuffers(1, &lightPosUB);
glBindBuffer(GL_UNIFORM_BUFFER, lightPosUB);
glBufferData(GL_UNIFORM_BUFFER, NUMBER_OF_LIGHTS * sizeof(vec4), lightPos, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 1, lightPosUB);

glGenBuffers(1, &lightColorUB);
glBindBuffer(GL_UNIFORM_BUFFER, lightColorUB);
glBufferData(GL_UNIFORM_BUFFER, NUMBER_OF_LIGHTS * sizeof(vec4), lightColor, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 1, lightColorUB);

// create shadow rendering VP matrix uniform buffer
glGenBuffers(1, &lightTransformUB);
glBindBuffer(GL_UNIFORM_BUFFER, lightTransformUB);
glBufferData(GL_UNIFORM_BUFFER, NUMBER_OF_LIGHTS * sizeof(LightTransform), lightTransform, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 2, lightTransformUB);

// update light information
lightRotationFactor = 0.f;
updateLights();

// create shadow map texture cube array
glGenTextures(1, &shadowArrayTex);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowArrayTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT16,
SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, NUMBER_OF_LIGHTS,
0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);

// create shadow rendering framebuffer
glGenFramebuffers(1, &shadowFB);
glBindFramebuffer(GL_FRAMEBUFFER, shadowFB);
glDrawBuffer(GL_NONE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowArrayTex, 0);
CHECK_FRAMEBUFFER_STATUS();
glBindFramebuffer(GL_FRAMEBUFFER, 0);

CHECK_GL_ERROR();

}

GLuint DragonDemo::loadShaderProgramFromFile(const char* filename, GLenum shaderType) {

ifstream file(filename);
if (!file) {
cerr << "Unable to open file: " << filename << endl;
return 0;
}

char line[256];
string source;

while (file) {
file.getline(line, 256);
source += line;
source += '\n';
}

if (!file.eof()) {
cerr << "Error reading the file: " << filename << endl;
return 0;
}
const GLchar *pText = static_cast<const GLchar *>(source.c_str());
GLuint program = glCreateShaderProgramv(shaderType, 1, &pText);

GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
cerr << "Failed to compile/link shader program:" << endl;
GLchar log[10000];
glGetProgramInfoLog(program, 10000, NULL, log);
cerr << log << endl;
exit(1);
}

return program;

}

GLuint DragonDemo::createProgramPipeline(GLuint vertexShader, GLuint geometryShader, GLuint fragmentShader) {

GLuint pipeline;
glGenProgramPipelines(1, &pipeline);

if (vertexShader != 0) glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vertexShader);
if (geometryShader != 0) glUseProgramStages(pipeline, GL_GEOMETRY_SHADER_BIT, geometryShader);
if (fragmentShader != 0) glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, fragmentShader);

glValidateProgramPipeline(pipeline);

GLint status;
glGetProgramPipelineiv(pipeline, GL_VALIDATE_STATUS, &status);
if (status != GL_TRUE) {
cerr << "Failed to validate program pipeline:" << endl;
GLchar log[10000];
glGetProgramPipelineInfoLog(pipeline, 10000, NULL, log);
cerr << log << endl;
exit(1);
}

return pipeline;

}

void DragonDemo::loadShaders() {

cerr << "> Loading shaders..." << endl;

// load G-buffer shaders
GBufferVSP = loadShaderProgramFromFile("shaders/gbuffer.vs", GL_VERTEX_SHADER);
GBufferFSP = loadShaderProgramFromFile("shaders/gbuffer.fs", GL_FRAGMENT_SHADER);
GBufferPPL = createProgramPipeline(GBufferVSP, 0, GBufferFSP);

// load light shaders
lightVSP = loadShaderProgramFromFile("shaders/light.vs", GL_VERTEX_SHADER);
lightGSP = loadShaderProgramFromFile("shaders/light.gs", GL_GEOMETRY_SHADER);
lightFSP = loadShaderProgramFromFile("shaders/light.fs", GL_FRAGMENT_SHADER);
lightPPL = createProgramPipeline(lightVSP, lightGSP, lightFSP);

// load shadow shaders
shadowMultiVSP = loadShaderProgramFromFile("shaders/shadow_multi.vs", GL_VERTEX_SHADER);
shadowMultiGSP = loadShaderProgramFromFile("shaders/shadow_multi.gs", GL_GEOMETRY_SHADER);
shadowMultiPPL = createProgramPipeline(shadowMultiVSP, shadowMultiGSP, 0);

shadowSingleVSP = loadShaderProgramFromFile("shaders/shadow_single.vs", GL_VERTEX_SHADER);
shadowSinglePPL = createProgramPipeline(shadowSingleVSP, 0, 0);
lightIDUniformLoc = glGetUniformLocation(shadowSingleVSP, "lightID");
}

void DragonDemo::setupGBuffer() {

cerr << "> Setting up G-buffer..." << endl;

// create normal buffer
glGenTextures(1, &positionGBT);
glBindTexture(GL_TEXTURE_2D, positionGBT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

// create normal buffer
glGenTextures(1, &normalGBT);
glBindTexture(GL_TEXTURE_2D, normalGBT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

// create depth buffer
glGenTextures(1, &depthGBT);
glBindTexture(GL_TEXTURE_2D, depthGBT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, SCREEN_WIDTH, SCREEN_HEIGHT, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

// create framebuffer and setup attachments
glGenFramebuffers(1, &GBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, GBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, positionGBT, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normalGBT, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthGBT, 0);

const GLenum buffers[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, buffers);

CHECK_FRAMEBUFFER_STATUS();
glBindFramebuffer(GL_FRAMEBUFFER, 0);

CHECK_GL_ERROR();

}

void DragonDemo::moveCamera(float dx, float dy, float dz, float dtime) {
mat4 rotation = mat4(1.0f);
rotation = rotate(rotation, camera.rotation.x, vec3(1.0f, 0.0f, 0.0f));
rotation = rotate(rotation, camera.rotation.y, vec3(0.0f, 1.0f, 0.0f));
rotation = rotate(rotation, camera.rotation.z, vec3(0.0f, 0.0f, 1.0f));
camera.position += vec3(vec4(dtime*dx, dtime*dy, dtime*dz, 1.0f) * rotation);
camera.position = clamp(camera.position, vec3(-7.5f, -5.5f, -7.5f), vec3(+7.5f, +5.5f, +7.5f));
}

void DragonDemo::rotateCamera(float dx, float dy, float dz, float dtime) {
camera.rotation += vec3(dtime*dx, dtime*dy, dtime*dz);
camera.rotation.x = clamp(camera.rotation.x, -90.0f, 90.0f);
}

void DragonDemo::renderScene(float dtime, bool useMultiShadow) {

// update camera data to uniform buffer
transform.ModelViewMatrix = mat4(1.0f);
transform.ModelViewMatrix = rotate(transform.ModelViewMatrix, camera.rotation.x, vec3(1.0f, 0.0f, 0.0f));
transform.ModelViewMatrix = rotate(transform.ModelViewMatrix, camera.rotation.y, vec3(0.0f, 1.0f, 0.0f));
transform.ModelViewMatrix = rotate(transform.ModelViewMatrix, camera.rotation.z, vec3(0.0f, 0.0f, 1.0f));
transform.ModelViewMatrix = translate(transform.ModelViewMatrix, -camera.position);
transform.MVPMatrix = transform.ProjectionMatrix * transform.ModelViewMatrix;
glBindBuffer(GL_UNIFORM_BUFFER, transformUB);
glBufferData(GL_UNIFORM_BUFFER, sizeof(transform), &transform, GL_STATIC_DRAW);

// update light information
lightRotationFactor = fmodf(lightRotationFactor + dtime * 0.05, 1.f);
updateLights();

// render G-buffer
glBindFramebuffer(GL_FRAMEBUFFER, GBuffer);
glBindProgramPipeline(GBufferPPL);
glBindVertexArray(vertexArray);

glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glClear(GL_DEPTH_BUFFER_BIT);

glDrawElements(drawCommand.prim_type, drawCommand.indexCount, GL_UNSIGNED_INT, (GLvoid*)drawCommand.indexOffset);

// render shadows
if (useMultiShadow) {

glBindFramebuffer(GL_FRAMEBUFFER, shadowFB);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowArrayTex, 0);
glBindProgramPipeline(shadowMultiPPL);
glViewport(0, 0, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
glClear(GL_DEPTH_BUFFER_BIT);
glDrawElements(drawCommand.prim_type, drawCommand.indexCount, GL_UNSIGNED_INT, (GLvoid*)drawCommand.indexOffset);

}
else {

glBindFramebuffer(GL_FRAMEBUFFER, shadowFB);
glBindProgramPipeline(shadowSinglePPL);
glViewport(0, 0, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
for (int i = 0; i < NUMBER_OF_LIGHTS; ++i) {
glProgramUniform1i(shadowSingleVSP, lightIDUniformLoc, i);
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowArrayTex, 0, i);
glClear(GL_DEPTH_BUFFER_BIT);
glDrawElementsInstanced(drawCommand.prim_type, drawCommand.indexCount, GL_UNSIGNED_INT, (GLvoid*)drawCommand.indexOffset, 4);
}

}

// render lights
glBindProgramPipeline(lightPPL);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
glClear(GL_COLOR_BUFFER_BIT);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, positionGBT);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, normalGBT);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, depthGBT);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowArrayTex);

glDrawArraysInstanced(GL_POINTS, 0, 1, NUMBER_OF_LIGHTS);

CHECK_GL_ERROR();

}

} /* namespace dragon */

paul_g_griffiths
01-07-2017, 09:55 AM
Things don't maker sense in the light shaders:

Geometry shader:

#version 420 core

layout(std140, binding = 0) uniform transform {
mat4 ModelViewMatrix;
mat4 ProjectionMatrix;
mat4 MVPMatrix;
vec4 Viewport;
float zNear;
float zFar;
float nearTop;
float nearRight;
} Transform;

layout(std140, binding = 1) uniform lightPosArray {
vec4 lightPos[100];
} LightPosArray;

layout(std140, binding = 1) uniform lightColorArray {
vec4 lightColor[100];
} LightColorArray;


layout(points) in;
layout(triangle_strip, max_vertices = 4) out;

layout(location = 0) flat in int instanceID[];

layout(location = 0) out vec2 interpTexCoord;
layout(location = 1) out vec3 lightPosition;
layout(location = 2) out vec4 lightColor;
layout(location = 3) flat out int lightID;

out gl_PerVertex {
vec4 gl_Position;
};

void main() {

vec4 lightPos = LightPosArray.lightPos[instanceID[0]];
lightColor = LightColorArray.lightColor[instanceID[0]];

gl_Position = vec4( 1.0, 1.0, 0.5, 1.0 );
interpTexCoord = vec2( 1.0, 1.0 );
lightPosition = lightPos.xyz;
lightID = instanceID[0];
EmitVertex();

gl_Position = vec4(-1.0, 1.0, 0.5, 1.0 );
interpTexCoord = vec2( 0.0, 1.0 );
lightPosition = lightPos.xyz;
lightID = instanceID[0];
EmitVertex();

gl_Position = vec4( 1.0,-1.0, 0.5, 1.0 );
interpTexCoord = vec2( 1.0, 0.0 );
lightPosition = lightPos.xyz;
lightID = instanceID[0];
EmitVertex();

gl_Position = vec4(-1.0,-1.0, 0.5, 1.0 );
interpTexCoord = vec2( 0.0, 0.0 );
lightPosition = lightPos.xyz;
lightID = instanceID[0];
EmitVertex();

EndPrimitive();

}

Vertex shader:

#version 420 core

layout(location = 0) flat out int instanceID;

void main(void) {

/* pass through instance ID */
instanceID = gl_InstanceID;

}



Framgent shader:

#version 420 core

layout(std140, binding = 0) uniform transform {
mat4 ModelViewMatrix;
mat4 ProjectionMatrix;
mat4 MVPMatrix;
vec4 Viewport;
float zNear;
float zFar;
float nearTop;
float nearRight;
} Transform;

layout(std140, binding = 2) uniform lightTransform {
mat4 VPMatrix[600];
} LightTransform;

layout(binding = 0) uniform sampler2D smpPositionBuffer;
layout(binding = 1) uniform sampler2D smpNormalBuffer;
layout(binding = 2) uniform sampler2D smpDepthBuffer;
layout(binding = 3) uniform sampler2DArrayShadow smpShadowMapArray;

layout(location = 0) in vec2 interpTexCoord;
layout(location = 1) in vec3 lightPosition;
layout(location = 2) in vec4 lightColor;
layout(location = 3) flat in int lightID;

layout(location = 0) out vec4 outFragmentColor;

void main(void) {

/* reconstruct normal from X and Y component (not 100% accurate though
as Z can be sometimes negative due to perspective projection) */
vec3 normal = texture(smpNormalBuffer, interpTexCoord).xyz;

/* get position */
vec4 position = texture(smpPositionBuffer, interpTexCoord);

/* calculate attenuation */
vec3 lightVec = lightPosition - position.xyz;
float sqrDist = dot(lightVec, lightVec);
float att = 1.f / (1.f + 0.01f * sqrDist);

/* calculate diffuse */
float diffuse = clamp(dot(normal, normalize(lightVec)), 0.f, 1.f);

/* calculate projected shadow map coordinates */
vec4 shadowCoordHom = LightTransform.VPMatrix[lightID] * position;

/* we manually have to do the perspective divide as there is no
version of textureProj that can take a sampler2DArrayShadow */
shadowCoordHom.xyz /= shadowCoordHom.w;
shadowCoordHom.xyz = shadowCoordHom.xyz * 0.5 + 0.5;
shadowCoordHom.z *= 0.9999;
vec4 shadowCoord = vec4(shadowCoordHom.x, shadowCoordHom.y, lightID, shadowCoordHom.z);

/* calculate shadow factor */
float shadow = texture(smpShadowMapArray, shadowCoord);

/* apply counter shadow eliminator factor */
float counterShadow = min(floor(shadowCoord.w), 1.0f);
shadow = mix(shadow, 1.f, counterShadow);

outFragmentColor = lightColor * att * diffuse * shadow;

}


In the geometry shader lightID = instanceID[0] always.
interpTexCoord = vec2( 0.0, 1.0 ); I'ts a buffer the size of the screen so why is it something like 0.0, 1.0?

interpTexCoord is used for buffers in the fragment shader but as I said the buffers are the size of the screen.

And in the vertex shader check this out:

vec4 shadowCoord = vec4(shadowCoordHom.x, shadowCoordHom.y, lightID, shadowCoordHom.z);
Why would lightID be in a coord?

Is this unfinished code or something?
The code is given away for free, but what if I purchased the book :(

All I'm looking for is multiple lighting and shadows, not head pain. :(
Another day wasted...

Just sent them an email saying I'm not happy and have they working code? I doubt Ill get a reply.

paul_g_griffiths
01-07-2017, 11:52 AM
Found an amasing demo: http://hd-prg.com/tileBasedShadows.html

Edit: It's in ogl and well developed, have to keep looking elsewhere.

Gpu Pro 6 book has code, think the demo above is based on it.
https://www.amazon.co.uk/GPU-Pro-Advanced-Rendering-Techniques/dp/1482264617

Man is it getting complicated! Am used to GLFW and GLM.

Anyone got any advice?