Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
由于gl_位置,opengl纹理坐标插值不正确_Opengl_Lwjgl_Vertex Shader - Fatal编程技术网

由于gl_位置,opengl纹理坐标插值不正确

由于gl_位置,opengl纹理坐标插值不正确,opengl,lwjgl,vertex-shader,Opengl,Lwjgl,Vertex Shader,我正在使用LWJGL java制作opengl关节动画。我所有的关节和顶点都按预期正确变换,但当我使用纹理渲染模型时,奇怪的事情开始发生 顶点着色器代码 # version 430 core uniform mat4 projection, view, model; in vec3 vertex; uniform mat4 rotate; in vec2 texCoord; out vec2 vertexTexCoord; uniform mat4 joints[16]; in ivec4

我正在使用LWJGL java制作opengl关节动画。我所有的关节和顶点都按预期正确变换,但当我使用纹理渲染模型时,奇怪的事情开始发生

顶点着色器代码

# version 430 core

uniform mat4
projection,
view,
model;
in vec3 vertex;
uniform mat4 rotate;

in vec2 texCoord;
out vec2 vertexTexCoord;

uniform mat4 joints[16];
in ivec4 jointIndices;
in vec4  weights;

in vec3 normal;
const vec3 directions[3]={vec3(0,-1,0),vec3(0,1,0),vec3(0,0,-1)};
out vec3 vertexNormal;
out vec3 lighting[3];


void main()
{
 mat4 modelRotate=(model*rotate);
 vec4 finalVertex=vec4(0.0);
 vec4 finalNormal=vec4(0.0);

 for(int i=0;i<4;i++)
 {
   mat4 jointTransform=joints[jointIndices[i]];  

   vec4 modelVertex=vec4(vertex,1.0);
   vec4 posVertex=jointTransform*modelVertex;
   finalVertex+=posVertex*weights[i];

   vec4 modelNormal=vec4(normal,0.0);
   vec4 poseNormal=jointTransform*modelNormal;
   finalNormal+=poseNormal*weights[i];
 }
 gl_Position=projection*view*modelRotate*vec4(vertex,1.0);

 vertexNormal=(modelRotate*finalNormal).xyz;
 for(int i=0;i<3;i++){lighting[i]=directions[i]*-1;}

 vertexTexCoord=texCoord;
}
#version 430 core

in vec3 vertexNormal;
in vec3 lighting[3];

in vec2 vertexTexCoord;
uniform sampler2D tex;

out vec4 pixelColor;

void main()
{
 vec3 nNormal=normalize(vertexNormal); 

 vec3 lightColor=vec3(0.0);
 for(int i=0;i<3;i++)
 {
  vec3 nLight=normalize(lighting[i]);  
  float nDot=max(0.0,dot(nNormal,nLight));
  lightColor+=vec3(1,1,1)*nDot;
 }

 pixelColor=vec4(vertexTexCoord.x,vertexTexCoord.y,0,0);
}
什么时候

也就是说,我的模型使用原始输入顶点,而不是转换的finalVertex

输出

正如您所看到的,每个曲面上的纹理坐标都应该是不同的,这是正确的

因此,当我使用这些纹理坐标的正确纹理渲染我的模型时,通过将我的pixelColor更改为

pixelColor=texture(tex,vertexTexCoord);
输出

我的模型在正确的位置使用纹理正确渲染

现在事情从这一点上变得很奇怪 将我的着色器代码更改为

gl_Position=projection*view*modelRotate*finalVertex;
pixelColor=vec4(vertexTexCoord.x,vertexTexCoord.y,0,0);
pixelColor=texture(tex,vertexTexCoord);
现在,我的模型使用来自每个关节的最终变换顶点,我的片段着色器输出纹理坐标。
输出应该与上面的文字相同,没有任何变化,但是我得到了这个

输出

现在,整个模型中的纹理坐标完全相同,根本不进行插值。他们都是统一的

现在,当我通过将片段着色器代码更改为

gl_Position=projection*view*modelRotate*finalVertex;
pixelColor=vec4(vertexTexCoord.x,vertexTexCoord.y,0,0);
pixelColor=texture(tex,vertexTexCoord);
输出如预期的,而不是我预期的:

输出:

如果有帮助,这里是我的模型纹理。我从教程下载的

似乎纹理坐标被粘在了图像的左上角,这可能解释了为什么我的模型是全黑色的,因为在左上角有很多黑色区域

因此,通过将顶点着色器中的一行代码从

gl_Position=projection*view*modelRotate*vec4(vertex,1.0);
                    TO
gl_Position=projection*view*modelRotate*finalVertex;
它改变了我的生活

为此:

任何来自任何地方的建议,无论是重塑我的角色或纹理,还是创建新的渲染引擎,我们都将不胜感激

编写加载模型和联合变换以及层次结构的代码花了我4天的时间

两周后,我仍然无法找出我的着色器出了什么问题。 多谢各位

我这里有一个简单的静态着色器,可以加载一个统一的矩阵

public abstract class StaticShader
{
 private int
 programID=0,
 vertexShaderID=0,
 fragmentShaderID=0,
 infoLogSize=0;

 private final FloatBuffer mat4fBuffer=BufferUtils.createFloatBuffer(16);

 protected StaticShader(Object vertexShader,Object fragmentShader)
 {
   programID=GL20.glCreateProgram();  
   vertexShaderID=loadShader(vertexShader,GL20.GL_VERTEX_SHADER);
   fragmentShaderID=loadShader(fragmentShader,GL20.GL_FRAGMENT_SHADER);

   GL20.glAttachShader(programID,vertexShaderID);
   GL20.glAttachShader(programID,fragmentShaderID);
   bindAttributes();   



   GL20.glLinkProgram(programID);
   if(GL20.glGetProgrami(programID,GL20.GL_LINK_STATUS)==GL11.GL_FALSE)
   {  
    infoLogSize=GL20.glGetProgrami(programID,GL20.GL_INFO_LOG_LENGTH);
    System.err.println(GL20.glGetProgramInfoLog(programID,infoLogSize));
    System.err.println("COULD NOT LINK SHADER");
    System.exit(-1);
   } 

   GL20.glValidateProgram(programID); 
   if(GL20.glGetProgrami(programID,GL20.GL_VALIDATE_STATUS)==GL11.GL_FALSE)
   {
    infoLogSize=GL20.glGetProgrami(programID,GL20.GL_INFO_LOG_LENGTH);  
    System.err.println(GL20.glGetProgramInfoLog(programID,infoLogSize));
    System.err.println("COULD NOT VALIDATE SHADER");
    System.exit(-1);
   } 
 }

 protected void bindAttribute(int attribno,String variable){GL20.glBindAttribLocation(programID,attribno,variable);}
 abstract void bindAttributes();

 private int loadShader(Object src,int shaderType)
 {
     StringBuilder source=Utils.loadSource(src);

     int shaderID=GL20.glCreateShader(shaderType);
     GL20.glShaderSource(shaderID,source);
     GL20.glCompileShader(shaderID);

     if(GL20.glGetShaderi(shaderID,GL20.GL_COMPILE_STATUS)==GL11.GL_FALSE)
     {
       infoLogSize=GL20.glGetShaderi(shaderID,GL20.GL_INFO_LOG_LENGTH);
       System.err.println(GL20.glGetShaderInfoLog(shaderID,infoLogSize));
       System.err.println("COULD NOT COMPILE SHADER");
       System.exit(-1);
     }    

     return shaderID;
 }

 public void start(){GL20.glUseProgram(programID);}
 public void stop(){GL20.glUseProgram(0);}
 public void release()
 {
   GL20.glUseProgram(0);

   GL20.glDetachShader(programID,vertexShaderID);
   GL20.glDetachShader(programID,fragmentShaderID);

   GL20.glDeleteShader(vertexShaderID);
   GL20.glDeleteShader(fragmentShaderID);  
 }

 public void loadMatrix(String name,Matrix4f mat)
 {
  start(); 
  mat.store(mat4fBuffer);
  mat4fBuffer.flip();
  GL20.glUniformMatrix4(GL20.glGetUniformLocation(programID,name),false,mat4fBuffer);
  stop();
 }
}
从这个着色器中,我继承了MyShader类

public class MyShader extends StaticShader
{
  private static final String
  VERTEX_SHADER="/main/animate.VS",
  FRAGMENT_SHADER="/main/animate.FS";

  private Texture tex;

  public MyShader()
  {
    super(VERTEX_SHADER,FRAGMENT_SHADER);
    Matrix4f mat=new Matrix4f();

     try
     {
      InputStream is=MyShader.class.getResourceAsStream("Character Texture.png");
      tex=TextureLoader.getTexture(".png",is,true);
      is.close();
     }
     catch(Exception ex){ex.printStackTrace();}


     float aspectRatio=(float)Display.getWidth()/(float)Display.getHeight();
     Utils.perspective(50,0.1f,1000,aspectRatio,mat);
     super.loadMatrix("projection",mat);/*PERSPECTIVE MATRIX*/

     Vector3f location=new Vector3f(0,4,12);
     Vector3f lookAt=new Vector3f(0,4,0);
     Vector3f up=new Vector3f(0,1,0);
     Utils.lookAt(location,lookAt,up,mat);
     super.loadMatrix("view",mat);        /*VIEW MATRIX*/

     mat.setIdentity();
     mat.scale(new Vector3f(1.2f,1,1));
     super.loadMatrix("model",mat);       /*MODEL MATRIX*/

     mat.setIdentity();
     mat.rotate((float)Math.toRadians(90),new Vector3f(-1,0,0));
     super.loadMatrix("rotate",mat);     /*FLIP MODEL BY 90 DEGRESS*/

     for(int i=0;i<16;i++)
     {
      mat.setIdentity();/*LOAD ALL JOINT TRANSFORM'S AS IDENTITY*/ 
      super.loadMatrix("joints["+String.valueOf(i)+"]",mat);
     }
  }

  public void bindAttributes()
  {
   super.bindAttribute(0,"vertex");
   super.bindAttribute(1,"normal");
   super.bindAttribute(2,"texCoord");
   super.bindAttribute(3,"jointIndices");
   super.bindAttribute(4,"weights");   
  }

  public void start()
  {
   super.start();
   GL13.glActiveTexture(GL13.GL_TEXTURE0);
   GL11.glBindTexture(GL11.GL_TEXTURE_2D,tex.getTextureID());
  }

  public void release()
  {
   tex.release();
   super.release();
  }
}

我的暂停正在将矩阵加载到制服数组中,但我不确定。谢谢你,我发现链接数据时问题不在于着色器或模型,而在于网格渲染器

如果必须将整数数据链接到着色器[linking jointId],则必须使用

GL30.glVertexAttribIPointer(index,vecType,GL11.GL_INT,0,0)
                      And not
GL20.glVertexAttribPointer(index,vectype,GL11.GL_INT,false,0,0);

我不知道为什么他们会用一个单独的方法来链接integer,但这让我的纹理工作得非常完美。大小写结束

输出应与上述文字相同。没有任何变化,没有任何变化?实际上有很多变化,包括潜在的所有统一位置以及属性位置。好吧,您根本没有发布相关代码,因此没有人可以给出任何具体建议。我的第一个怀疑是您没有正确地处理或指定属性和/或统一位置。不,我们不会整理您的代码库的相关位。您必须提供一个。好的,您可以通过查询着色器正在使用的实际属性位置,并检查它正在使用/假定的VAO设置代码来缩小范围。问题中的代码不完整,同时,它也远远不是最小的。这不是stackoverflow上的定义方式。您需要将代码添加到问题本身。而且你的东西也不是最小的。例如,不需要复杂的模型文件来演示问题。一个三角形就足够了,这个三角形可以直接在源代码中定义。纹理文件是完全不相关的。这不是把你的东西上传到什么地方。它是关于迭代地剥离代码和数据,直到达到演示问题所需的绝对最小值。
public class Main
{
 /*DISPLAY ATTRIBUTES*/   
private static ContextAttribs createDisplayAttributes()
 {
   ContextAttribs attribs=new ContextAttribs(4,2)
   .withForwardCompatible(true)
   .withProfileCore(true);

   return attribs;
 }

 private static void initDisplay(String title)
 {
  try
  {
   Display.create(new PixelFormat(),createDisplayAttributes());

   Display.setTitle(title);

   Display.setDisplayMode(new DisplayMode(1500,705));

   Display.setLocation(0,-2);

   Display.setResizable(false);
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }    
 }
 /*DISPLAY ATTRIBUTES*/

 private static void startFrame()
 {
  GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
  GL11.glEnable(GL11.GL_DEPTH_TEST);
  GL11.glClearColor(0,0,1,0);
 }

 public static void main(String args[])
 {
  initDisplay("ANIMATION TEST");

  MeshRender mesh=MeshRender.createMesh();
  MyShader myShader=new MyShader();

  while(!Display.isCloseRequested())
  {
   startFrame();

   myShader.start();
   mesh.render();
   myShader.stop();

   updateDisplay();
  }

  mesh.release();
  myShader.release();

  mesh.release();
  releaseOpenGL();
 }

 private static void updateDisplay()
 {
  Display.update();
  Display.sync(60);
 }

 private static void releaseOpenGL()
 {
   try
   {    
    Mouse.destroy();
    Keyboard.destroy();
    Display.releaseContext();
    Display.destroy();
   }
   catch(Exception ex){ex.printStackTrace();}
 }
GL30.glVertexAttribIPointer(index,vecType,GL11.GL_INT,0,0)
                      And not
GL20.glVertexAttribPointer(index,vectype,GL11.GL_INT,false,0,0);