Я пишу современный загрузчик модели openGL и сталкиваюсь с некоторыми проблемами, используя расположение атрибутов шейдера, отличных от 0. Я могу получить атрибут position в шейдере, но не значения, необходимые для Blinn- Фонг-затенение (привязано в программе к местоположениям: Ks-3, Ka-4, Kd-5). Вот код, я использую для загрузки и визуализации модели OBJ:Проблема с привязкой OpenGL VAO к множественным VBO
public class Model{
private List<Vector3f> vertices=new ArrayList<>();
private List<Vector3f> normals=new ArrayList<>();
private ArrayList<Integer> vaos=new ArrayList<>();
private float[] faces=new float[fvaoSize];
private float[] ks=new float[kvaoSize];
private float[] ka=new float[kvaoSize];
private float[] kd=new float[kvaoSize];
private int currentPlace=0,kcurrentPlace=0;
private static final int fvaoSize=glGetInteger(GL12.GL_MAX_ELEMENTS_VERTICES)-(glGetInteger(GL12.GL_MAX_ELEMENTS_VERTICES)%12);
private static final int kvaoSize=(fvaoSize/4)*3;
private int facesd=0;
private HashMap<String,Material> materials=new HashMap<>();
@SuppressWarnings("unused")
private int plainFaceVAO=0,texFaceVAO=0,normalsFaceVAO=0,normalsTexVAO=0;
@SuppressWarnings("unused")
private int faceOffset=0,
texOffset=0,texTexture=0,texCoords=0,
normalOffset=0,normalCoords=0,
normalTexOffset=0,normalTexNormalCoords,normalTexTexCoords,normalTexTexture=0;
@SuppressWarnings("unused")
private Shader faceShader=null,texShader=null,normalsShader=null,normalTexShader=null;
private Material currMtl=null;
public Model(File f,Shader faceShader,Shader texShader,Shader normalsShader,Shader normalTexShader){
loadModelData(f);
this.faceShader=faceShader;
this.texShader=texShader;
this.normalsShader=normalsShader;
this.normalTexShader=normalTexShader;
faceOffset=glGetUniformLocation(faceShader.getID(),"trans");
texOffset=glGetUniformLocation(texShader.getID(),"trans");
texTexture=glGetAttribLocation(texShader.getID(),"tex");
texCoords=glGetAttribLocation(texShader.getID(),"texCoords");
normalOffset=glGetUniformLocation(normalsShader.getID(),"trans");
normalCoords=glGetAttribLocation(normalsShader.getID(),"normalsCoords");
}
@SuppressWarnings("null")
private void loadModelData(File f){
try(BufferedReader br=new BufferedReader(new FileReader(f))){
String line="";
while((line=br.readLine())!=null){
String[] words=line.split(" ");
//System.out.println(line);
if(line.startsWith("#"))
continue;
switch(words[0]){
case OBJ_VERTEX:
vertices.add(new Vector3f(parseFloat(words[1]),parseFloat(words[2]),-parseFloat(words[3])));
break;
case OBJ_VERTEX_NORMAL:
normals.add(new Vector3f(parseFloat(words[1]),parseFloat(words[2]),-parseFloat(words[3])));
break;
case OBJ_FACE:
facesd++;
FaceType cft=null;
int slashCount=0;
for(char c:words[1].toCharArray()){
if(c=='/')
slashCount++;
}
if(slashCount==0){
cft=FaceType.COORDSONLY;
}else if(slashCount==1){
cft=FaceType.TEXTURE;
}else if(slashCount==2){
if(words[0].contains("//")){
cft=FaceType.NORMALS;
}else{
cft=FaceType.NORMALS_AND_TEXTURE;
}
}
switch(cft){
case COORDSONLY:
Vector3f pos1=vertices.get(Integer.parseInt(words[1])-1);
Vector3f pos2=vertices.get(Integer.parseInt(words[2])-1);
Vector3f pos3=vertices.get(Integer.parseInt(words[3])-1);
Vec3 Ks=(currMtl.getKs()!=null?currMtl.getKs():new Vec3(1));
Vec3 Ka=(currMtl.getKa()!=null?currMtl.getKa():new Vec3(1));
Vec3 Kd=(currMtl.getKd()!=null?currMtl.getKd():new Vec3(1));
float[] temp=new float[]
{
pos1.x,pos1.y,pos1.z,1.0f,
pos2.x,pos2.y,pos2.z,1.0f,
pos3.x,pos3.y,pos3.z,1.0f
};
for(int i=0;i<12;i++){
faces[currentPlace+i]=temp[i];
}
float[] ktemp=new float[]
{
Ks.x,Ks.y,Ks.z,
Ks.x,Ks.y,Ks.z,
Ks.x,Ks.y,Ks.z
};
for(int i=0;i<9;i++){
ks[kcurrentPlace+i]=ktemp[i];
}
ktemp=new float[]
{
Ka.x,Ka.y,Ka.z,
Ka.x,Ka.y,Ka.z,
Ka.x,Ka.y,Ka.z
};
for(int i=0;i<9;i++){
ka[kcurrentPlace+i]=ktemp[i];
}
ktemp=new float[]
{
Kd.x,Kd.y,Kd.z,
Kd.x,Kd.y,Kd.z,
Kd.x,Kd.y,Kd.z
};
for(int i=0;i<9;i++){
kd[kcurrentPlace+i]=ktemp[i];
}
kcurrentPlace+=9;
currentPlace+=12;
if(currentPlace==fvaoSize){
int fvbo=glGenBuffers();
FloatBuffer vertexPositionsBuffer=BufferUtils.createFloatBuffer(fvaoSize);
vertexPositionsBuffer.put(faces);
vertexPositionsBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, fvbo);
glBufferData(GL_ARRAY_BUFFER, vertexPositionsBuffer, GL_STATIC_DRAW);
int ksvbo=glGenBuffers();
FloatBuffer ksBuffer=BufferUtils.createFloatBuffer(kvaoSize);
ksBuffer.put(ks);
ksBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, ksvbo);
glBufferData(GL_ARRAY_BUFFER, ksBuffer, GL_STATIC_DRAW);
int kavbo=glGenBuffers();
FloatBuffer kaBuffer=BufferUtils.createFloatBuffer(kvaoSize);
kaBuffer.put(ka);
kaBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, kavbo);
glBufferData(GL_ARRAY_BUFFER, kaBuffer, GL_STATIC_DRAW);
int kdvbo=glGenBuffers();
FloatBuffer kdBuffer=BufferUtils.createFloatBuffer(kvaoSize);
kdBuffer.put(kd);
kdBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, kdvbo);
glBufferData(GL_ARRAY_BUFFER, kdBuffer, GL_STATIC_DRAW);
int vao = glGenVertexArrays();
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, fvbo);
glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, ksvbo);
glVertexAttribPointer(3, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, kavbo);
glVertexAttribPointer(4, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, kdvbo);
glVertexAttribPointer(5, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glBindVertexArray(0);
glDeleteBuffers(fvbo);
glDeleteBuffers(ksvbo);
glDeleteBuffers(kavbo);
glDeleteBuffers(kdvbo);
ksBuffer=null;
kaBuffer=null;
kdBuffer=null;
vertexPositionsBuffer=null;
vaos.add(vao);
glBindBuffer(GL_ARRAY_BUFFER, 0);
currentPlace=0;
kcurrentPlace=0;
faces=new float[fvaoSize];
ks=new float[kvaoSize];
ka=new float[kvaoSize];
kd=new float[kvaoSize];
}
break;
case NORMALS:
throw new RuntimeException("File is unsupported.");
case NORMALS_AND_TEXTURE:
throw new RuntimeException("File is unsupported.");
case TEXTURE:
throw new RuntimeException("File is unsupported.");
default:
throw new RuntimeException("File is unsupported.");
}
break;
case OBJ_MTLLIB:
materials=MTLLibLoader.loadMTLLib(f.toPath().getParent()+"/"+words[1]);
break;
case OBJ_USEMTL:
System.out.println("Using Material "+words[1]+": Exists in hmap: "+materials.containsKey(words[1]));
currMtl=materials.get(words[1]);
break;
default:
break;
}
}
int fvbo=glGenBuffers();
FloatBuffer vertexPositionsBuffer=BufferUtils.createFloatBuffer(fvaoSize);
vertexPositionsBuffer.put(faces);
vertexPositionsBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, fvbo);
glBufferData(GL_ARRAY_BUFFER, vertexPositionsBuffer, GL_STATIC_DRAW);
int ksvbo=glGenBuffers();
FloatBuffer ksBuffer=BufferUtils.createFloatBuffer(kvaoSize);
ksBuffer.put(ks);
ksBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, ksvbo);
glBufferData(GL_ARRAY_BUFFER, ksBuffer, GL_STATIC_DRAW);
int kavbo=glGenBuffers();
FloatBuffer kaBuffer=BufferUtils.createFloatBuffer(kvaoSize);
kaBuffer.put(ka);
kaBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, kavbo);
glBufferData(GL_ARRAY_BUFFER, kaBuffer, GL_STATIC_DRAW);
int kdvbo=glGenBuffers();
FloatBuffer kdBuffer=BufferUtils.createFloatBuffer(kvaoSize);
kdBuffer.put(kd);
kdBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, kdvbo);
glBufferData(GL_ARRAY_BUFFER, kdBuffer, GL_STATIC_DRAW);
int vao = glGenVertexArrays();
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, fvbo);
glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, ksvbo);
glVertexAttribPointer(3, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, kavbo);
glVertexAttribPointer(4, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, kdvbo);
glVertexAttribPointer(5, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glBindVertexArray(0);
glDeleteBuffers(fvbo);
glDeleteBuffers(ksvbo);
glDeleteBuffers(kavbo);
glDeleteBuffers(kdvbo);
ksBuffer=null;
kaBuffer=null;
kdBuffer=null;
vertexPositionsBuffer=null;
vaos.add(vao);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}catch(FileNotFoundException e){
// TODO Auto-generated catch block
e.printStackTrace();
}catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Object \""+f.getName().substring(0,f.getName().lastIndexOf("."))+"\" loaded, has "+facesd+" faces");
}
public void drawModel(Camera c,Vec3 offset){
//System.err.format("rendering model, %d vaos\n",vaos.size());
//Matrix4f modelMat=RenderMatrixHelper.getModelMatrix(offset,new Vec3(0));
faceShader.useShader();
c.useCameraView();
glUniform4f(faceOffset,offset.x,offset.y,offset.z,0f);
for(Integer i:vaos){
glBindVertexArray(i);
glDrawArrays(GL_TRIANGLES, 0, fvaoSize/4);
}
Shader.stopShader();
glBindVertexArray(0);
}
public int getNumFaces(){
return facesd;
}
private enum FaceType{
COORDSONLY,
TEXTURE,
NORMALS,
NORMALS_AND_TEXTURE,
}
}
Я думаю, что я правильно объять K-ВБО, чтобы в нужном месте, но затенение делает их черным , Вот код вершинного шейдера:
#version 330
in vec4 position;
in vec3 normals;
in vec2 texCoords;
uniform vec4 trans;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 model;
void main()
{
gl_Position = projection*view* (position+trans);//-camera_position;
}
пиксельный шейдер выводит черный цвет, если Кд имеет значение (0,0,0), в противном случае белый. В моем коде, я проверил и знаю, что Kd является (0,64, 0,64, 0,64) И пиксельный шейдер:
#version 330
out vec4 outputColor;
in vec3 Ks;
in vec3 Ka;
in vec3 Kd;
uniform mat4 view;
uniform mat4 projection;
void main()
{
if(Kd==vec3(0f)){
outputColor=vec4(0f);
}else{
outputColor=vec4(1f);
}
}
Я не могу найти проблему, но если кто-то может было бы большая помощь. Благодаря!
Несмотря на то, что проблема на самом деле была **, компилятор оптимизировал их **, я все еще чему-то научился, и я считаю, что другие с этой проблемой могут принести пользу. +1 и спасибо! – johnnic431