マルチライト用のシェーダーと、ライトの作成を処理する関数を設計していました。ライトは struct uniform 配列内に保存され、ライトの量は「light_quantity」と呼ばれる int ユニフォームに保存されます。
これは、ライトを作成する関数です。
int Game::AllocLight(LIGHT_TYPE mylight,float radius,glm::vec3 position,glm::vec3 direction,glm::vec4 ambient,glm::vec4 specular,glm::vec4 diffuse,bool status,int in_pos){
if(number_lights + 1 > MAX_LIGHTS || in_pos > MAX_LIGHTS){
return -1;
}
int newindex;
if(in_pos==-1){
newindex = number_lights++;
}else{
newindex=in_pos;
}
std::string as = std::to_string((unsigned long long)newindex);
// LightBase name
string light_base_name = "lights_a[" + as + "]";
GLint renderit_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".renderit")).c_str());
GLint ambient_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".ambient_light")).c_str());
GLint diffuse_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".diffuse_light")).c_str());
GLint specular_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".specular_light")).c_str());
GLint radius_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".radius")).c_str());
GLint position_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".light_position")).c_str());
GLint direction_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".light_direction")).c_str());
GLint type_uniform = glGetUniformLocation(main_program.GetId(),string(light_base_name + string(".light_type")).c_str());
int light_type;
switch(mylight){
case POINT_TYPE:
light_type=1;
break;
case DIRECTIONAL_TYPE:
light_type=2;
break;
case AREA_TYPE:
light_type=3;
break;
case SUN_TYPE:
light_type=4;
break;
}
glUniform1i(renderit_uniform,status);
glUniform4f(ambient_uniform,ambient.w,ambient.x,ambient.y,ambient.z);
glUniform4f(diffuse_uniform,diffuse.w,diffuse.x,diffuse.y,diffuse.z);
glUniform4f(specular_uniform,specular.w,specular.x,specular.y,specular.z);
glUniform1f(radius_uniform,radius);
glUniform3f(position_uniform,position.x,position.y,position.z);
glUniform3f(direction_uniform,direction.x,direction.y,direction.z);
glUniform1i(type_uniform,light_type);
glUniform1i(glGetUniformLocation(main_program.GetId(),"light_quantity"),number_lights);
return newindex;
}
MAX_LIGHTS: #defined で定義されたマクロ、それは int です...
問題は、制服が想定どおりに定義されていないことです。
これが私のフラグメント シェーダーです (頂点シェーダーはこの問題では重要ではないと思います...)
#version 330 core
struct LightBase{
int renderit;
vec4 ambient_light;
vec4 specular_light;
vec4 diffuse_light;
float radius;
vec3 light_position;
vec3 light_direction;
int light_type;
};
struct MaterialBase{
vec4 ambient_affect;
vec4 specular_affect;
vec4 diffuse_affect;
float shining;
float mirror;
int light_affect;
};
in vec3 VertexPos;
in vec3 Normal;
uniform int light_quantity;
uniform LightBase lights_a[50];
uniform MaterialBase material;
uniform float usingTex;
uniform sampler2D texturemap;
in vec2 UVs;
in vec4 Colors;
out vec4 color;
void main(){
vec4 texture_u = texture(texturemap,UVs).rgba * usingTex;
vec4 color_u = Colors * (1.0f-usingTex);
vec4 final_color = color_u+texture_u;
for(int i=0;i<light_quantity;i++){
//if(lights_a[i].renderit==1){ // This is commented for test if the "light_quantity" is getting defined.
//if(lights_a[i].light_type==1){ // This is commented for test if the "light_quantity" is getting defined.
// Point Type
float attenuation = max(0.0,1.0-dot(lights_a[i].light_direction,lights_a[i].light_direction));
vec3 L = normalize(lights_a[i].light_direction);
vec3 N = normalize(Normal);
vec3 V = normalize(-VertexPos);
vec3 R = normalize(-reflect(L,N));
float nDotL = max(0.0,dot(N,L));
float rDotV = max(0.0,dot(R,V));
vec4 ambient_result = lights_a[i].ambient_light * material.ambient_affect * attenuation;
vec4 diffuse_result = lights_a[i].diffuse_light * material.diffuse_affect * nDotL * attenuation;
vec4 specular_result = lights_a[i].specular_light * material.specular_affect * pow(rDotV,material.shining) * attenuation;
vec4 this_colour = (ambient_result + diffuse_result + specular_result) * final_color;
final_color = vec4(0,0,0,0); // this_colour; // vec4(0,0,0,0) for test if the "light_quantity" is getting defined.
//} // This is commented for test if the "light_quantity" is getting defined.
//} // This is commented for test if the "light_quantity" is getting defined.
}
color = final_color;
}
なぜこれが起こっているのかについてのアイデアはありますか? すでに何度もテストしましたが、問題はユニフォームにあるという結論に達しました。何が起こっているのでしょうか? 機能していない制服ですか?