I am making a 2d tile renderer. I have gotten it to be very efficient, but I cannot figure out how to smack textures on to the tiles.
Here my code
package gfx;
import org.lwjgl.system.MemoryUtil;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.opengl.GL31.glDrawElementsInstanced;
import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BUFFER;
import static org.lwjgl.system.MemoryUtil.*;
public class TileMap {
private final int mapWidth, mapHeight;
private float tileSize = 0.1f;
private final int vaoId;
private final int iboId;
public float camX = 0.0f, camY = 0.0f;
public float scale = 1.0f;
private int usboId;
Texture tt;
ShaderProgram shaderProgram;
private final float[] vertices;
private final int[] indices = new int[]{
0, 1, 3, 3, 1, 2,
};
private final FloatBuffer offsetBuffer;
private final FloatBuffer tpBuffer;
public TileMap(int mapSize, float tileSize) {
this.mapWidth = mapSize;
this.mapHeight = mapSize;
this.tileSize = tileSize;
tt = Texture.loadTexture("sexyminion.jpg");
float[] offsets = new float[mapWidth * mapHeight * 2];
float[] texPos = new float[mapWidth * mapHeight * 8];
vertices = new float[]{
-tileSize, tileSize, 0.0f,
-tileSize, -tileSize, 0.0f,
tileSize, -tileSize, 0.0f,
tileSize, tileSize, 0.0f,
};
float[] test = new float[]{
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f
};
int index = 0;
for (int x = 0; x < mapWidth; x++) {
for (int y = 0; y < mapHeight; y++) {
float xPos = (float) x * tileSize;
float yPos = (float) y * tileSize;
offsets[index++] = xPos;
offsets[index++] = yPos;
}
}
index = 0;
for(int i = 0; i < mapWidth * mapHeight * 8; i++) {
texPos[i] = test[index];
index++;
if(index >= 8) {
index = 0;
}
}
offsetBuffer = MemoryUtil.memAllocFloat(offsets.length);
offsetBuffer.put(offsets).flip();
tpBuffer = MemoryUtil.memAllocFloat(texPos.length);
tpBuffer.put(texPos).flip();
shaderProgram = ShaderProgram.getShaderProgram("test_program");
ShaderProgram.useProgram("test_program");
vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
// Store vertex data off-heap
FloatBuffer vertexData = MemoryUtil.memAllocFloat(vertices.length);
vertexData.put(vertices).flip();
// Create and bind VBO for vertices
int vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);
memFree(vertexData);
// Store index data off-heap
IntBuffer indexData = MemoryUtil.memAllocInt(indices.length);
indexData.put(indices).flip();
// Create and bind IBO for indices
iboId = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexData, GL_STATIC_DRAW);
memFree(indexData);
// Create and bind the SSBO for offsets
int ssboId = glGenBuffers();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssboId);
glBufferData(GL_SHADER_STORAGE_BUFFER, offsetBuffer, GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssboId);
// Create and bind the SSBO for texture coordinates
usboId = glGenBuffers();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, usboId);
glBufferData(GL_SHADER_STORAGE_BUFFER, tpBuffer, GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, usboId);
// Unbind VAO
glBindVertexArray(0);
}
float tick = 0;
public void render1() {
tick += 0.01f;
ShaderProgram.useProgram("test_program");
glBindVertexArray(vaoId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboId);
shaderProgram.setUniform("delta", tick);
shaderProgram.setUniform("projectionMatrix", Render.projectionMatrix);
shaderProgram.setUniform("texture_sampler", 0); // Ensure correct texture unit
shaderProgram.setUniform("scale", scale);
shaderProgram.setUniform("camPos", camX, camY);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tt.getId());
glDrawElementsInstanced(GL_TRIANGLES, indices.length, GL_UNSIGNED_INT, 0, mapWidth * mapHeight);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
ShaderProgram.unbindProgram();
}
}
Texture class ????????????????????
package gfx;
import org.lwjgl.system.MemoryStack;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.stb.STBImage.*;
public class Texture {
private int id;
private static final HashMap<String, Texture> loadedTextures = new HashMap<>();
private int width, height;
public static Texture loadTexture(String path) {
if (loadedTextures.containsKey(path)) {
System.out.println("FART");
return loadedTextures.get(path);
}
int width;
int height;
ByteBuffer buffer;
new Texture(0, 0, 0);
try (MemoryStack stack = MemoryStack.stackPush()) {
IntBuffer w = stack.mallocInt(1);
IntBuffer h = stack.mallocInt(1);
IntBuffer channels = stack.mallocInt(1);
URL url = Texture.class.getClassLoader().getResource(path);
assert url != null;
File file = new File(url.getPath()); // Get file from URL
String filePath = file.getAbsolutePath();
buffer = stbi_load(filePath, w, h, channels, 4);
if (buffer == null) {
throw new IOException("Failed to load texture file: " + path + ", Reason: " + stbi_failure_reason());
}
width = w.get(0);
height = h.get(0);
int textureId = glGenTextures();
glEnable(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
// Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Upload texture data
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// Generate mipmaps
glGenerateMipmap(GL_TEXTURE_2D);
// Free image data
stbi_image_free(buffer);
Texture t = new Texture(textureId, width, height);
// Store the texture ID in the map
loadedTextures.put(path, t);
return t;
} catch (Exception e) {
e.printStackTrace();
return new Texture(0, 0, 0); // Return a default texture ID on failure
}
}
public Texture(int id, int width, int height) {
this.id = id;
this.width = width;
this.height = height;
}
public int getId() {
return id;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
Vertex Shader
#version 460
layout(location = 0) in vec3 position;
layout(std430, binding = 0) buffer OffsetPositions {
vec2 offsets[];
};
layout(std430, binding = 1) buffer TexturePositions {
vec2 textCoords[];
};
uniform float delta;
uniform mat4 projectionMatrix;
uniform vec2 camPos;
uniform float scale;
out vec2 outTP;
void main() {
int index = gl_InstanceID;
vec2 offset = offsets[index];
outTP = textCoords[index];
gl_Position = projectionMatrix * vec4(
position.xy * scale + offset * scale + camPos * scale,
position.z,
1.0
);
}
fragment shader
#version 330 core
out vec4 fragColor;
uniform sampler2D texture_sampler;
in vec2 outTP;
void main() {
fragColor = texture(texture_sampler, outTP);
}
I don’t really know what to say, I just don’t know what to do.
Don’t be annoying I’m sorry if I made a stupid mistake. I’m 15 I’m trying pleaaase pleeeasseeee I just hit my like eighth hour I don’t have time for pretty please pretttyyy please with a cherry on top. HELP HELLLP MEEEEEEEEEEE
Thanks