GLSLシェーダとVBOを使用してメッシュをレンダリングしていますが、VBOには4つの属性が格納されています。 positionXYZ、normalXYZ、textureUV、colourRGBA。 UVを除いてすべてが機能します(おそらく法線もありますが、まだそれらをテストする方法はありません)。テクスチャUVがシェーダに正しく送信されない
何が起こっているのですか、配列のテクスチャUV位置は、配列の通常のxおよびy位置にオフセットされています。配列は途中でVVVNNNTTCCCC
(頂点位置、通常、テクスチャ、カラー)として構造化されています。問題がシェーダにVBOを送信するどこかにあることは確かです。私はVBOのデータが正しい順序であることを確かに知っています。
これは私のレンダリングコードです:ジオメトリがあり
#version 400 core
in vec3 ppVertPosition;
in vec3 ppVertNormal;
in vec2 ppVertTexture;
in vec4 ppVertColour;
uniform sampler2D texture;
void main()
{
gl_FragColor = texture2D(texture, ppVertTexture);
}
:バーテックスシェーダ
VBOクラス
public final class Mesh
{
public static final int FLOAT_SIZE_BYTES = 4;
public static final int FLOATS_PER_POSITION = 3;
public static final int FLOATS_PER_NORMAL = 3;
public static final int FLOATS_PER_TEXTURE = 2;
public static final int FLOATS_PER_COLOUR = 4;
public static final int VERTEX_SIZE_FLOATS = FLOATS_PER_POSITION + FLOATS_PER_NORMAL + FLOATS_PER_TEXTURE + FLOATS_PER_COLOUR;
public static final int VERTEX_SIZE_BYTES = VERTEX_SIZE_FLOATS * FLOAT_SIZE_BYTES;
public static final int POSITION_OFFSET_FLOATS = 0;
public static final int NORMAL_OFFSET_FLOATS = POSITION_OFFSET_FLOATS + FLOATS_PER_POSITION;
public static final int TEXTURE_OFFSET_FLOATS = NORMAL_OFFSET_FLOATS + FLOATS_PER_NORMAL;
public static final int COLOUR_OFFSET_FLOATS = TEXTURE_OFFSET_FLOATS + FLOATS_PER_TEXTURE;
public static final int POSITION_OFFSET_BYTES = POSITION_OFFSET_FLOATS * FLOAT_SIZE_BYTES;
public static final int NORMAL_OFFSET_BYTES = NORMAL_OFFSET_FLOATS * FLOAT_SIZE_BYTES;
public static final int TEXTURE_OFFSET_BYTES = TEXTURE_OFFSET_FLOATS * FLOAT_SIZE_BYTES;
public static final int COLOUR_OFFSET_BYTES = COLOUR_OFFSET_FLOATS * FLOAT_SIZE_BYTES;
public static final int POSITION_STRIDE_BYTES = VERTEX_SIZE_BYTES;
public static final int NORMAL_STRIDE_BYTES = VERTEX_SIZE_BYTES;
public static final int TEXTURE_STRIDE_BYTES = VERTEX_SIZE_BYTES;
public static final int COLOUR_STRIDE_BYTES = VERTEX_SIZE_BYTES;
public final static int VERTICES_PER_FACE = 3;
public static final int ATTRIBUTE_LOCATION_POSITION = 0;
public static final int ATTRIBUTE_LOCATION_NORMAL = 1;
public static final int ATTRIBUTE_LOCATION_TEXTURE = 2;
public static final int ATTRIBUTE_LOCATION_COLOUR = 3;
private int vaoID;
private int iboID;
private int indexCount;
private Mesh(int vaoID, int iboID, int indexCount)
{
this.vaoID = vaoID;
this.iboID = iboID;
this.indexCount = indexCount;
}
public void draw(AbstractShaderProgram shader, Texture texture)
{
glEnable(GL_TEXTURE_2D);
if (texture != null) texture.bind(shader);
else Texture.MISSING_TEXTURE.bind(shader);
glBindVertexArray(vaoID);
glEnableVertexAttribArray(ATTRIBUTE_LOCATION_POSITION);
// glEnableVertexAttribArray(ATTRIBUTE_LOCATION_NORMAL);
// glEnableVertexAttribArray(ATTRIBUTE_LOCATION_TEXTURE);
// glEnableVertexAttribArray(ATTRIBUTE_LOCATION_COLOUR);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID);
glDrawElements(GL_TRIANGLES, indexCount, GL_FLOAT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(ATTRIBUTE_LOCATION_POSITION);
// glDisableVertexAttribArray(ATTRIBUTE_LOCATION_NORMAL);
// glDisableVertexAttribArray(ATTRIBUTE_LOCATION_TEXTURE);
// glDisableVertexAttribArray(ATTRIBUTE_LOCATION_COLOUR);
glBindVertexArray(0);
glDisable(GL_TEXTURE_2D);
}
public static Mesh compile(List<Face> faces)
{
if (faces.size() <= 0)
throw new RuntimeException("Failed to compile mesh. No faces were provided.");
HashMap<Vertex, Integer> indexMap = new HashMap<>();
ArrayList<Vertex> vertices = new ArrayList<>();
int vertexCount = 0;
for (Face face : faces)
{
for (Vertex vertex : face.getVertices())
{
if (!indexMap.containsKey(vertex))
{
indexMap.put(vertex, vertexCount++);
vertices.add(vertex);
}
}
}
int indicesCount = faces.size() * VERTICES_PER_FACE;
int dataSize = vertexCount * VERTEX_SIZE_FLOATS;
FloatBuffer vertexData = BufferUtils.createFloatBuffer(dataSize);
if (vertexData == null)
System.err.println("Failed to allocate FloatBuffer with size " + dataSize);
for (Vertex vertex : vertices)
{
vertexData.put(vertex.getPosition().x);
vertexData.put(vertex.getPosition().y);
vertexData.put(vertex.getPosition().z);
// vertexData.put(vertex.getNormal() == null ? 1.0F : vertex.getNormal().x);
// vertexData.put(vertex.getNormal() == null ? 1.0F : vertex.getNormal().y);
// vertexData.put(vertex.getNormal() == null ? 1.0F : vertex.getNormal().z);
// vertexData.put(vertex.getTexture() == null ? 0.0F : vertex.getTexture().x);
// vertexData.put(vertex.getTexture() == null ? 0.0F : vertex.getTexture().y);
// vertexData.put(vertex.getColour() == null ? 1.0F : vertex.getColour().getRGBA().x);
// vertexData.put(vertex.getColour() == null ? 1.0F : vertex.getColour().getRGBA().y);
// vertexData.put(vertex.getColour() == null ? 1.0F : vertex.getColour().getRGBA().z);
// vertexData.put(vertex.getColour() == null ? 1.0F : vertex.getColour().getRGBA().w);
}
vertexData.flip();
IntBuffer indices = BufferUtils.createIntBuffer(indicesCount);
for (Face face : faces)
{
for (Vertex vertex : face.getVertices())
{
int index = indexMap.get(vertex);
indices.put(index);
}
}
indices.flip();
int vaoID = glGenVertexArrays();
glBindVertexArray(vaoID);
int vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
glVertexAttribPointer(ATTRIBUTE_LOCATION_POSITION, FLOATS_PER_POSITION, GL_FLOAT, false, 0, 0);
// glVertexAttribPointer(ATTRIBUTE_LOCATION_NORMAL, FLOATS_PER_NORMAL, GL_FLOAT, false, NORMAL_STRIDE_BYTES, NORMAL_OFFSET_BYTES);
// glVertexAttribPointer(ATTRIBUTE_LOCATION_TEXTURE, FLOATS_PER_TEXTURE, GL_FLOAT, false, TEXTURE_STRIDE_BYTES, TEXTURE_OFFSET_BYTES);
// glVertexAttribPointer(ATTRIBUTE_LOCATION_COLOUR, FLOATS_PER_COLOUR, GL_FLOAT, false, COLOUR_STRIDE_BYTES, COLOUR_OFFSET_BYTES);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
int iboID = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return new Mesh(vaoID, iboID, indicesCount);
}
}
:
#version 400 core
in vec3 vertPosition;
in vec3 vertNormal;
in vec2 vertTexture;
in vec4 vertColour;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
out vec3 pVertPosition;
out vec3 pVertNormal;
out vec2 pVertTexture;
out vec4 pVertColour;
void main()
{
pVertPosition = vertPosition;
pVertNormal = vertNormal;
pVertTexture = vertTexture;
pVertColour = vertColour;
gl_Position = vec4(vec3(vertPosition.xy + vertTexture, vertPosition.z), 1.0);
}
フラグメントシェーダシェイダーのこれらの間には存在しますが、現在は冗長で、情報をフラグメントシェーダにまっすぐに伝えます(outとinの変数が一致しない理由です)。また、フラグメントシェーダの頂点位置にtextureUVが追加された理由は実際に渡されているテクスチャのUV値をデバッグします。これは、UVが通常のxyにオフセットされていることを私が知る方法です。私がテクスチャUVを通常のxyに入れると、それらは完全にうまく動作します。
追加したいコードがある場合は、それを追加します。あまりにも多くのコードがあるので、私はVBOクラス全体など、すべてを追加していません。私は、私が関連していると思われるものと、問題がどこにあるのかを含めただけです。
編集#1: vertPosition
やvertNormal
のようなシェーダ内の可変ロケーションがバインドされています。これは、CT同じ結果\ EXをもたらしそうのように、レイアウトを使用して、頂点シェーダを変更し、それらを
glBindAttribLocation(program, Mesh.ATTRIBUTE_LOCATION_POSITION, "vertPosition");
glBindAttribLocation(program, Mesh.ATTRIBUTE_LOCATION_NORMAL, "vertNormal");
glBindAttribLocation(program, Mesh.ATTRIBUTE_LOCATION_TEXTURE, "vertTexture");
glBindAttribLocation(program, Mesh.ATTRIBUTE_LOCATION_COLOUR, "vertColour");
をバインドするために私のコードです。
layout(location = 0) in vec3 vertPosition;
layout(location = 1) in vec3 vertNormal;
layout(location = 2) in vec2 vertTexture;
layout(location = 3) in vec4 vertColour;
編集#2 は、私はそれの部分だけではなく、メッシュ全体のクラスを投稿することを決めました。 VBOではなくVAOを実装しようとしましたが、動作しません。
うーん、されている必要がありますが、それが動作する桁違いの運ではありません。私は 'vertPosition'、' vertNormal'などをバインドしましたが、私はそのコードをその質問に投稿しませんでした。ごめんなさい。私のコードは次のようになります: 'glBindAttribLocation(program、Mesh.ATTRIBUTE_LOCATION_POSITION、" vertPosition ");' – Kelan
ハハ、大丈夫、残念です。クライアントステートを削除し、代わりに 'glEnableVertexAttribArray(Mesh.ATTRIBUTE_LOCATION_POSITION)'を使用することをお勧めします。それでも問題が発生する可能性があります。そしてあなたが指定したインデックスで 'glVertexAttribPointer'を使います。だから、glVertexAttribPointer(Mesh.ATTRIBUTE_LOCATION_POSITION .... ' – TWT
glVertexAttribPointerは、glVertexPointerとそれ以外のものを置き換える必要があります。 – TWT