由于 gl_Position,opengl 纹理坐标未正确插值
opengl texture coordinates not interpolated correctly due to gl_Position
我正在使用 LWJGL 制作 opengl 联合动画 java。我所有的关节和顶点都按预期正确转换,但是当我使用纹理
渲染我的模型时,奇怪的事情开始发生
顶点着色器代码
# 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);
}
我没有在我的模型中使用光照,因为它已经过测试并且工作正常,但我的纹理坐标不正确,所以我在我的着色器中将它们作为红色、绿色组合输出以进行调试
我的每个着色器中有两行代码需要注意
VertexShader: gl_Position
FragmentShader: pixelColor
当
gl_Position=projection*view*modelRotate*vec4(vertex,1.0);
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*vec4(vertex,1.0);
TO
gl_Position=projection*view*modelRotate*finalVertex;
它改变了我的生活
致此:(
任何来自任何地方的建议,无论是重塑我的角色或我的纹理,还是创建一个新的渲染引擎,我们都将不胜感激。
编写加载模型的代码以及联合变换和层次结构花了我 4 天的时间
2 周过去了,我仍然无法弄清楚我的着色器有什么问题。
谢谢
我这里有一个简单的静态着色器,可以加载统一矩阵
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 class
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();
}
}
接下来我们有一个几何渲染器,它从二进制文件加载模型并将其渲染到屏幕上。
public class MeshRender
{
private final int vao;
private final ArrayList<Integer> vbos=new ArrayList<Integer>();
private final ArrayList<Integer> indexLocations=new ArrayList<Integer>();
private final int vertexCount;
public MeshRender(int vertices)
{
vao=GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
vertexCount=vertices;
}
public void createAttribute(int index,int vectype,FloatBuffer buffer)
{
int vbo=GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,buffer,GL15.GL_DYNAMIC_DRAW);
GL20.glVertexAttribPointer(index,vectype,GL11.GL_FLOAT,false,0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
indexLocations.add(index);
vbos.add(vbo);
}
public void createAttribute(int index,int vectype,IntBuffer buffer)
{
int vbo=GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,buffer,GL15.GL_DYNAMIC_DRAW);
GL20.glVertexAttribPointer(index,vectype,GL11.GL_INT,false,0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
indexLocations.add(index);
vbos.add(vbo);
}
public void unBind(){GL30.glBindVertexArray(0);}
public void render()
{
GL30.glBindVertexArray(vao);
for(int index: indexLocations){GL20.glEnableVertexAttribArray(index);}
GL11.glDrawArrays(GL11.GL_TRIANGLES,0,vertexCount);
for(int index: indexLocations){GL20.glDisableVertexAttribArray(index);}
GL30.glBindVertexArray(0);
}
public void release()
{
for(int vbo: vbos){GL15.glDeleteBuffers(vbo);}
GL30.glDeleteVertexArrays(vao);
}
public static MeshRender createMesh()
{
MeshRender mesh=null;
try
{
Model model=Model.readFromFile("/main/Model.data");
FloatBuffer fBuffer;
IntBuffer iBuffer;
fBuffer=model.toFBuffer(0);
mesh=new MeshRender(fBuffer.capacity()/3);
mesh.createAttribute(0,3,fBuffer);/*VERTICES' INDEX=0 FLOAT'S=3*/
fBuffer=model.toFBuffer(1);
mesh.createAttribute(1,3,fBuffer);/*NORMAL'S INDEX=1 FLOAT'S=3*/
fBuffer=model.toFBuffer(2);
mesh.createAttribute(2,2,fBuffer);/*TEX COORD'S INDEX=2 FLOAT'S=2*/
iBuffer=model.toIBuffer(3);
mesh.createAttribute(3,4,iBuffer);/*JOINT INDICES INDEX=3 INT'S=4*/
fBuffer=model.toFBuffer(4);
mesh.createAttribute(4,4,fBuffer);/*WEIGHT'S INDEX=4 FLOAT'S=4*/
mesh.unBind();
}
catch(Exception ex){ex.printStackTrace();}
return mesh;
}
}
Class 模型是从工作文件加载的实际数据 fine.But 你可以在这里加载你想要的任何信息。
最后我的着色器和几何体一起用于我的主要 class
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();}
}
我的悬架正在将一个矩阵加载到一组制服中,但我不确定。谢谢你
好吧,我发现问题不在于我的着色器或我的模型,而是在 linking 数据时我的 MeshRenderer。
如果你必须 link 整数数据到你的着色器[linking jointId's] 你必须使用
GL30.glVertexAttribIPointer(index,vecType,GL11.GL_INT,0,0)
And not
GL20.glVertexAttribPointer(index,vectype,GL11.GL_INT,false,0,0);
不知道为什么他们为 linking 整数制作了一个单独的方法,但这使我的纹理完美工作。结案
我正在使用 LWJGL 制作 opengl 联合动画 java。我所有的关节和顶点都按预期正确转换,但是当我使用纹理
渲染我的模型时,奇怪的事情开始发生顶点着色器代码
# 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);
}
我没有在我的模型中使用光照,因为它已经过测试并且工作正常,但我的纹理坐标不正确,所以我在我的着色器中将它们作为红色、绿色组合输出以进行调试
我的每个着色器中有两行代码需要注意
VertexShader: gl_Position
FragmentShader: pixelColor
当
gl_Position=projection*view*modelRotate*vec4(vertex,1.0);
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*vec4(vertex,1.0);
TO
gl_Position=projection*view*modelRotate*finalVertex;
它改变了我的生活
致此:(
任何来自任何地方的建议,无论是重塑我的角色或我的纹理,还是创建一个新的渲染引擎,我们都将不胜感激。
编写加载模型的代码以及联合变换和层次结构花了我 4 天的时间
2 周过去了,我仍然无法弄清楚我的着色器有什么问题。 谢谢
我这里有一个简单的静态着色器,可以加载统一矩阵
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 class
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();
}
}
接下来我们有一个几何渲染器,它从二进制文件加载模型并将其渲染到屏幕上。
public class MeshRender
{
private final int vao;
private final ArrayList<Integer> vbos=new ArrayList<Integer>();
private final ArrayList<Integer> indexLocations=new ArrayList<Integer>();
private final int vertexCount;
public MeshRender(int vertices)
{
vao=GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
vertexCount=vertices;
}
public void createAttribute(int index,int vectype,FloatBuffer buffer)
{
int vbo=GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,buffer,GL15.GL_DYNAMIC_DRAW);
GL20.glVertexAttribPointer(index,vectype,GL11.GL_FLOAT,false,0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
indexLocations.add(index);
vbos.add(vbo);
}
public void createAttribute(int index,int vectype,IntBuffer buffer)
{
int vbo=GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,buffer,GL15.GL_DYNAMIC_DRAW);
GL20.glVertexAttribPointer(index,vectype,GL11.GL_INT,false,0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
indexLocations.add(index);
vbos.add(vbo);
}
public void unBind(){GL30.glBindVertexArray(0);}
public void render()
{
GL30.glBindVertexArray(vao);
for(int index: indexLocations){GL20.glEnableVertexAttribArray(index);}
GL11.glDrawArrays(GL11.GL_TRIANGLES,0,vertexCount);
for(int index: indexLocations){GL20.glDisableVertexAttribArray(index);}
GL30.glBindVertexArray(0);
}
public void release()
{
for(int vbo: vbos){GL15.glDeleteBuffers(vbo);}
GL30.glDeleteVertexArrays(vao);
}
public static MeshRender createMesh()
{
MeshRender mesh=null;
try
{
Model model=Model.readFromFile("/main/Model.data");
FloatBuffer fBuffer;
IntBuffer iBuffer;
fBuffer=model.toFBuffer(0);
mesh=new MeshRender(fBuffer.capacity()/3);
mesh.createAttribute(0,3,fBuffer);/*VERTICES' INDEX=0 FLOAT'S=3*/
fBuffer=model.toFBuffer(1);
mesh.createAttribute(1,3,fBuffer);/*NORMAL'S INDEX=1 FLOAT'S=3*/
fBuffer=model.toFBuffer(2);
mesh.createAttribute(2,2,fBuffer);/*TEX COORD'S INDEX=2 FLOAT'S=2*/
iBuffer=model.toIBuffer(3);
mesh.createAttribute(3,4,iBuffer);/*JOINT INDICES INDEX=3 INT'S=4*/
fBuffer=model.toFBuffer(4);
mesh.createAttribute(4,4,fBuffer);/*WEIGHT'S INDEX=4 FLOAT'S=4*/
mesh.unBind();
}
catch(Exception ex){ex.printStackTrace();}
return mesh;
}
}
Class 模型是从工作文件加载的实际数据 fine.But 你可以在这里加载你想要的任何信息。
最后我的着色器和几何体一起用于我的主要 class
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();}
}
我的悬架正在将一个矩阵加载到一组制服中,但我不确定。谢谢你
好吧,我发现问题不在于我的着色器或我的模型,而是在 linking 数据时我的 MeshRenderer。
如果你必须 link 整数数据到你的着色器[linking jointId's] 你必须使用
GL30.glVertexAttribIPointer(index,vecType,GL11.GL_INT,0,0)
And not
GL20.glVertexAttribPointer(index,vectype,GL11.GL_INT,false,0,0);
不知道为什么他们为 linking 整数制作了一个单独的方法,但这使我的纹理完美工作。结案