OpenGL- GLSL texture()调用:1282无效操作

时间:2015-10-27 23:23:58

标签: java opengl glsl textures lwjgl

我正在制作游戏引擎,在那里我有一个加载OBJ模型的类。这个类本身运行得很完美,但是,我得到的问题是,当我使用纹理渲染任何模型时,我将始终得到错误(1282)无效操作。我在代码中尝试了不同的东西,我发现它特别是片段着色器中的texture()调用导致了这个问题。我有一个自定义类,根据打开的单位将纹理移动到纹理单元,这是类:

public class GLTextureHandler{
    private static ConcurrentHashMap<Integer,Integer> texRef=new ConcurrentHashMap<Integer,Integer>();
    public static final int texUnits=GL11.glGetInteger(GL20.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
    private static Integer[] inUse=new Integer[texUnits];
    static{
        for(int i=0;i<inUse.length;i++){
            inUse[i]=0;
        }
        inUse[0]=1;
    }
    public static void registerTex(int tex){
        texRef.put(tex,-1);
    }
    public static int useTex(int tex){
        if(!texRef.containsKey(tex))
            registerTex(tex);
        int slot=texRef.get(tex);
        if(slot!=-1)
            return slot;
        int cnt=0;
        for(int u:inUse){
            System.out.println("Checking CNT ("+cnt+"), u is "+u);
            if(u==0){
                glActiveTexture(GL_TEXTURE0+cnt);
                glBindTexture(GL_TEXTURE_2D,tex);
                inUse[u]=1;
                texRef.put(tex,cnt);
                System.out.println("putting in slot "+cnt);
                return cnt;
            }
            cnt++;
        }
        glActiveTexture(GL_TEXTURE0+texUnits-1);
        glBindTexture(GL_TEXTURE_2D,tex);
        inUse[texUnits-1]=1;
        texRef.put(tex,texUnits-1);
        return texUnits-1;
    }
    public static void openSlot(int tex){
        if(!texRef.containsKey(tex))
            return;
        int slot=texRef.get(tex);
        if(slot!=-1)
            inUse[slot]=0;
    }
    public static boolean hasTex(int tex){
        return texRef.containsKey(tex);
    }
}

当调用useTex()时,类将纹理放入一个槽中,并返回它放入的槽。我在我的DetailedVAO类中调用它,它只是在更新材料的制服后呈现VAO(模型视图矩阵是在模型类中处理)。它还告诉着色器纹理所在的纹理单元,据我所知,它可以直接绑定纹理。详细的VAO类是这样的:

class DetailedVAO{
    private Material mtl;
    private int vao,ksloc,kaloc,kdloc,texLoc,shinyLoc;
    private int texRef;

    public DetailedVAO(int vao,Material mtl,int ksloc,int kaloc,int kdloc,int texLoc,int shinyLoc){
        this.vao=vao;
        this.mtl=mtl;
        this.kaloc=kaloc;
        this.kdloc=kdloc;
        this.ksloc=ksloc;
        this.texLoc=texLoc;this.shinyLoc=shinyLoc;
        texRef=(mtl.tex()==null?-1:mtl.tex().getTextureID());
        GLTextureHandler.registerTex(texRef);
    }
    public void render(){
        Vec3 Ks=(mtl.getKs()==null?new Vec3(1):mtl.getKs());
        Vec3 Ka=(mtl.getKa()==null?new Vec3(.5f):mtl.getKa());
        Vec3 Kd=(mtl.getKd()==null?new Vec3(1):mtl.getKd());

        GL20.glUniform3f(ksloc,Ks.x,Ks.y,Ks.z);
        GL20.glUniform3f(kaloc,Ka.x,Ka.y,Ka.z);
        GL20.glUniform3f(kdloc,Kd.x,Kd.y,Kd.z);
        GL20.glUniform1f(shinyLoc,mtl.getShiny());

        int aSlot=GLTextureHandler.useTex(texRef);
        GL20.glUniform1f(texLoc,aSlot);

        glBindVertexArray(vao);
        glDrawArrays(GL_TRIANGLES, 0, Model.fvaoSize/4);
    }
}

顶点着色器:

#version 330

in vec4 position;
in vec3 normals;
in vec2 texCoords;

uniform mat4 view;
uniform mat4 projection;
uniform mat4 model;
uniform mat4 normal;

uniform vec3 u_lightPosition;
uniform vec3 u_cameraPosition;

uniform vec3 Ks;
uniform vec3 Ka;
uniform vec3 Kd;

out vec3 o_normal;
out vec3 o_toLight;
out vec3 o_toCamera;
out vec2 o_texcoords;

void main()
{
    vec4 worldPosition=model*position;

    o_normal = normalize(mat3(normal) * normals);

   // direction to light
   o_toLight = normalize(u_lightPosition - worldPosition.xyz);

   // direction to camera
   o_toCamera = normalize(u_cameraPosition - worldPosition.xyz);

   // texture coordinates to fragment shader
   o_texcoords = texCoords;

    gl_Position=projection*view*worldPosition;
}

如果我只使用Blinn-Phong值,片段着色器可以工作:

#version 330
out vec4 outputColor;

uniform vec4 color;

uniform mat4 view;
uniform mat4 projection;
uniform mat4 model;

uniform vec3 u_lightAmbientIntensitys; // = vec3(0.6, 0.3, 0);
uniform vec3 u_lightDiffuseIntensitys; // = vec3(1, 0.5, 0);
uniform vec3 u_lightSpecularIntensitys; // = vec3(0, 1, 0);

// parameters of the material and possible values
uniform vec3 u_matAmbientReflectances; // = vec3(1, 1, 1);
uniform vec3 u_matDiffuseReflectances; // = vec3(1, 1, 1);
uniform vec3 u_matSpecularReflectances; // = vec3(1, 1, 1);
uniform float u_matShininess;

uniform sampler2D u_diffuseTexture;

uniform vec3 Ks;
uniform vec3 Ka;
uniform vec3 Kd;

in vec3 o_normal;
in vec3 o_toLight;
in vec3 o_toCamera;
in vec2 o_texcoords;

vec3 ambientLighting()
{
   return Ka * u_lightAmbientIntensitys;
}

// returns intensity of diffuse reflection
vec3 diffuseLighting(in vec3 N, in vec3 L)
{
   // calculation as for Lambertian reflection
   float diffuseTerm = clamp(dot(N, L), 0, 1) ;
   return Kd * u_lightDiffuseIntensitys * diffuseTerm;
}

// returns intensity of specular reflection
vec3 specularLighting(in vec3 N, in vec3 L, in vec3 V)
{
   float specularTerm = 0;

   // calculate specular reflection only if
   // the surface is oriented to the light source
   if(dot(N, L) > 0)
   {
      // half vector
      vec3 H = normalize(L + V);
      specularTerm = pow(dot(N, H), u_matShininess);
   }
   return Ks * u_lightSpecularIntensitys * specularTerm;
}

void main(void)
{
   // normalize vectors after interpolation
   vec3 L = normalize(o_toLight);
  vec3 V = normalize(o_toCamera);
  vec3 N = normalize(o_normal);

   // get Blinn-Phong reflectance components
   vec3 Iamb = ambientLighting();
   vec3 Idif = diffuseLighting(N, L);
   vec3 Ispe = specularLighting(N, L, V);

   // diffuse color of the object from texture
   vec3 diffuseColor = vec3(texture(u_diffuseTexture, o_texcoords.xy));
   // combination of all components and diffuse color of the object
   outputColor.xyz = diffuseColor*(Iamb+Ispe+Idif);
   outputColor.a = 1;
}

1 个答案:

答案 0 :(得分:1)

  • 这可能是您遇到问题的根源:

    GL20.glUniform1f(texLoc,aSlot);
    

    应该是

    GL20.glUniform1i(texLoc,aSlot); // i not f
    
  • 编辑:我没有仔细阅读有关设置glActiveTexture的代码。我的评论是错误的。

  • 您没有解开您的VAO:

    glBindVertexArray(vao);
    glDrawArrays(GL_TRIANGLES, 0, Model.fvaoSize/4);
    glBindVertexArray( 0 ); // <- Probably want this