I have a script that renders a 2D hexagon-shaped grid of hexagon tiles. The grid loads fine, but my textures are missing huge bits of color. What is wrong with my code? Have I mapped the coordinates incorrectly?
This is the texture image that I am loading:
This is how the texture appears in my game:
Here is my code:
public class LWJGLHelloWorld {
public static int SCREEN_WIDTH;
public static int SCREEN_HEIGHT;
public static int WINDOW_WIDTH;
public static int WINDOW_HEIGHT;
public double WIDTH;
public double HEIGHT;
public ArrayList<Hexagon> hexagons = new ArrayList<Hexagon>();
public ArrayList<String> resources = new ArrayList<String>();
public Texture brick;
public Texture stone;
public Texture lumber;
public Texture wool;
public Texture wheat;
public Texture wasteland;
public int textureID;
private float[][] textureCoords = {
{0.5f, 0.5f},
{0.5f, 0.0f},
{0.0f, 0.25f},
{0.0f, 0.75f},
{0.5f, 0.0f},
{1.0f, 0.75f},
{1.0f, 0.25f}
};
private static enum State {
INTRO, MAIN_MENU, GAME;
}
private State state = State.INTRO;
public LWJGLHelloWorld(){
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double SCREEN_WIDTH = screenSize.getWidth();
double SCREEN_HEIGHT = screenSize.getHeight();
double WIDTH = SCREEN_WIDTH * .85;
double HEIGHT = SCREEN_HEIGHT * .85;
try {
Display.setDisplayMode(new DisplayMode((int)WIDTH, (int)HEIGHT));
Display.setTitle("Hello, LWJGL!");;
Display.create();
} catch (LWJGLException e){
e.printStackTrace();
}
resetResources();
brick = loadTexture("brick");
stone = loadTexture("stone");
lumber = loadTexture("lumber");
//Texture wheat = loadTexture("wheat");
wool = loadTexture("wool");
wasteland = loadTexture("wasteland");
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
int originX = (int)(Display.getDisplayMode().getWidth() / 2);
int originY = (int)(Display.getDisplayMode().getHeight() / 2);
int radius = (int)(HEIGHT * .1);
int padding = (int)(HEIGHT * .005);
findHexCoords(originX, originY, 5, radius, padding);
while(!Display.isCloseRequested()){
checkInput();
glClear(GL_COLOR_BUFFER_BIT);
for(int h = 0; h < hexagons.size(); h++){
String rsrc = resources.get(h);
switch(rsrc){
case "brick":
brick.bind();
break;
case "stone":
stone.bind();
break;
case "lumber":
lumber.bind();
break;
case "wheat":
//wheat.bind();
break;
case "wool":
wool.bind();
break;
case "wasteland":
wasteland.bind();
break;
}
glBegin(GL_POLYGON);
Hexagon hex = hexagons.get(h);
for(int p = 0; p < hex.points.length; p++){
Point point = hex.points[p];
glVertex2f(point.x, point.y);
glTexCoord2f(textureCoords[p][0], textureCoords[p][0]);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
}
glEnd();
}
Display.update();
Display.sync(60);
}
Display.destroy();
}
private void bindTexture(String rsrc){
}
private void findHexCoords(int x, int y, int size, int radius, int padding) {
Point origin = new Point(x, y);
double ang30 = Math.toRadians(30);
double xOff = Math.cos(ang30) * (radius + padding);
double yOff = Math.sin(ang30) * (radius + padding);
int half = size / 2;
int i = 0;
for (int row = 0; row < size; row++) {
int cols = size - Math.abs(row - half);
for (int col = 0; col < cols; col++) {
int xLbl = row < half ? col - row : col - half;
int yLbl = row - half;
int centerX = (int) (origin.x + xOff * (col * 2 + 1 - cols));
int centerY = (int) (origin.y + yOff * (row - half) * 3);
Hexagon hex = new Hexagon(centerX, centerY, radius);
System.out.println(centerX+","+centerY);
hexagons.add(hex);
i++;
}
}
}
public void checkInput(){
switch(state){
case INTRO:
if(Keyboard.isKeyDown(Keyboard.KEY_S)){
state = State.MAIN_MENU;
}
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
Display.destroy();
System.exit(0);;
}
break;
case GAME:
if(Keyboard.isKeyDown(Keyboard.KEY_BACK)){
state = State.MAIN_MENU;
}
break;
case MAIN_MENU:
if(Keyboard.isKeyDown(Keyboard.KEY_RETURN)){
state = State.GAME;
}
if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)){
state = State.INTRO;
}
break;
}
}
private Texture loadTexture(String key){
try {
return TextureLoader.getTexture("PNG", new FileInputStream(new File("img/" + key + ".png")));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
new LWJGLHelloWorld();
}
public void resetResources(){
resources.clear();
resources.add("Brick");
resources.add("Brick");
resources.add("Brick");
resources.add("Wool");
resources.add("Wool");
resources.add("Wool");
resources.add("Wool");
resources.add("Lumber");
resources.add("Lumber");
resources.add("Lumber");
resources.add("Lumber");
resources.add("Stone");
resources.add("Stone");
resources.add("Stone");
resources.add("Wheat");
resources.add("Wheat");
resources.add("Wheat");
resources.add("Wheat");
long seed = System.nanoTime();
Collections.shuffle(resources, new Random(seed));
int randomIndex = ThreadLocalRandom.current().nextInt(0, 19);
resources.add(randomIndex, "Wasteland");
for(int r = 0; r < resources.size(); r++){
System.out.println(resources.get(r));
}
}
}
I assume this is happening because my texture coordinates are not correct because whenever I change them, the area of black in the textures changes.
Your texture coordinates are indeed wrong. Since you're drawing a polygon as a whole, there isn't any vertex with texture coordinate [0.5, 0.5], which is center of a texture.
Try to use image bellow to determinate your texture coordinates properly. :)
Write down a texture coordinate for each vertex and put 'em in same order as you're drawing your vertices.
EDIT:
To be fair, you would be much better to draw those tiles as rectangles/quads and make 'em overlap a little bit. Your texture coordinates then would be {[0, 0], [0, 1], [1, 1], [1, 0]} assuming youre starting at bottom left corner and drawing clockwise. See image bellow.