J'ai essayé de suivre le code comme spécifié dans this tutorial on OpenGL3+ textures, mais mon résultat finit par noir au lieu de la texture.Texture rendue en noir quad
J'utilise stbimage pour charger l'image de la texture utilise dans une ByteBuffer directe et peut garantir les données RVB dans la mémoire tampon est, au moins, pas uniforme - il ne peut pas être ça.
Je n'aime pas du tout vider le code, mais je ne vois pas grand-chose d'autre à ce stade. Voici mon code et shaders java:
GL
est une interface pointant vers toutes les fonctionnalités GL ## dans LWJGL3 .
ShaderProgram
enveloppe tout le contenu spécifique du shader dans une belle boîte noire qui génère un shaderprogram à partir des shaders attachés sur le premier appel de use(GL)
et réutilise ensuite ce programme. Cela fonctionne très bien pour le rendu d'un triangle coloré, donc j'élimine toutes les erreurs qui s'y trouvent.
Util.checkError(GL, boolean);
vérifie les erreurs OpenGL qui se sont accumulées depuis sa dernière exécution et génère une exception d'exécution si le booléen n'est pas défini (écrit en silence à la place, si défini).
Le code de rendu, mise à jour (GL, long) est exécutée une fois toutes les images
private static final ResourceAPI res = API.get(ResourceAPI.class);
Image lwjgl32;
ShaderProgram prog = new ShaderProgram();
int vbo, vao, ebo;
int texture;
@Override
public void init(GL gl) {
try {
prog.attach(res.get("shaders/texDemo.vert", ShaderSource.class));
prog.attach(res.get("shaders/texDemo.frag", ShaderSource.class));
lwjgl32 = res.get("textures/lwjgl32.png", Image.class);
} catch(ResourceException e) {
throw new RuntimeException(e);
}
float[] vertices = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
int[] indices = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
vao = gl.glGenVertexArrays();
vbo = gl.glGenBuffers();
ebo = gl.glGenBuffers();
gl.glBindVertexArray(vao);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo);
gl.glBufferData(GL.GL_ARRAY_BUFFER, vertices, GL.GL_STATIC_DRAW);
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, ebo);
gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices, GL.GL_STATIC_DRAW);
gl.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, 8 * Float.BYTES, 0);
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(1, 3, GL.GL_FLOAT, false, 8 * Float.BYTES, 3 * Float.BYTES);
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(2, 2, GL.GL_FLOAT, false, 8 * Float.BYTES, 6 * Float.BYTES);
gl.glEnableVertexAttribArray(0);
texture = gl.glGenTextures();
gl.glBindTexture(GL.GL_TEXTURE_2D, texture);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, lwjgl32.getWidth(), lwjgl32.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, lwjgl32.getImageData());
gl.glGenerateMipmap(GL.GL_TEXTURE_2D);
prog.use(gl);
gl.glUniform1i(gl.glGetUniformLocation(prog.getId(gl), "texture"), 0);
Util.checkError(gl, false);
}
@Override
protected void update(GL gl, long deltaFrame) {
gl.glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glActiveTexture(GL.GL_TEXTURE0);
gl.glBindTexture(GL.GL_TEXTURE_2D, texture);
prog.use(gl);
gl.glBindVertexArray(vao);
gl.glDrawElements(GL.GL_TRIANGLES, 6, GL.GL_UNSIGNED_INT, 0);
}
@Override
public void clean(GL gl) {
gl.glDeleteVertexArrays(vao);
gl.glDeleteBuffers(vbo);
gl.glDeleteBuffers(ebo);
ShaderProgram.clearUse(gl);
prog.dispose(gl);
}
Vertex shaders
#version 330 core
layout (location = 0) in vec3 in_position;
layout (location = 1) in vec3 in_color;
layout (location = 2) in vec2 in_texCoord;
out vec3 color;
out vec2 texCoord;
void main() {
gl_Position = vec4(in_position, 1.0);
color = in_color;
texCoord = vec2(in_texCoord.x, in_texCoord.y);
}
Fragment shaders
#version 330 core
out vec4 frag_colour;
in vec3 color;
in vec2 texCoord;
uniform sampler2D texture;
void main() {
frag_colour = texture(texture, texCoord) * vec4(color, 1.0);
}
J'enveloppé de GL de LWJGL3 ## classes statiques en une seule interface et la mise en œuvre afin que je puisse avoir un tas de méthodes stateful qui font des choses telles que l'identification du contexte qui est rendu à, etc. J'ai aussi fait de mon mieux pour supprimer les fonctionnalités non essentielles de l'interface, je ne suis même pas tenté d'utiliser des choses obsolètes
par scott vous avez raison. J'ai été tellement obsédé par la validation de l'entrée de texture .... –