[OpenGL] Don't understand why my mesh can't display in the screen.

I only wrote this piece of code following one rule:

No jumping around. (That means no function calling at the minimum).

This rule enables me to learn about the orders of execution, and doesn’t put focus on programming design paradigms. Why did I focus on orders of execution? By programming with a very linear path down, I can be able to learn a bit more about OpenGL function executions and things like loading textures to the screen, and etc.

However, I have stumbled across a dead end: I can’t find the reason why my mesh isn’t showing up. And I’m exhausted (after a long session) from finding the error myself. I request for help; I need someone who can tell me what I did wrong and what I must do to change. Please be welcomed, thank you.


Below are the only 2 class objects I had created in my project. Because they are large, I used the pastebin to keep things small and nonintrusive. Why it’s huge? Codes don’t branch off to someplace else, so they are easy to read in a linear fashion. However, my “No jumping around” rule makes them very anesthetic after reading the code many times over. Hence my exhaustion.

Something class: It holds the mesh data and texture data.
http://pastebin.java-gaming.org/5303c53937b

Game class: It acts like a container for setting up the OpenGL context to a thread.
http://pastebin.java-gaming.org/303c3639b79

For practicing OpenGL. That’s my main focus and main concern for enforcing such rule.

It was never intended to be something that I will release to the public in the future.

You’re not doing any error checking yourself. glGetError()!

Been there, done that. All glFunctions() report GL_NO_ERROR. :smiley:

In that case, start stripping out things.

  • Remove the texture sampling from your fragment shader to see if the texture is the problem.
  • Double check the math to ensure that what you’re rendering is actually in the view frustum.
  • Remove the matrix transformations from your vertex shader and if necessary simplify the vertex data.

Note that I haven’t actually looked that much in your code. I’d rather teach you how to fix problems like these yourself than to just find the solution for you. .___.

I’m going to refactor the code, and rewrite most of the codes.

I will report back to see what’s the actual problem in my code.

Right now, it’s 4:43AM in the morning. After 6 hours past my bedtime, I couldn’t find any problems. Updated code even contains all glGetError() functions everywhere, and they are not returning a single “ERROR” value in the console.

I have removed the texture sampler in the fragment shader. Still nothing. The texture itself loads just fine.

As for the math, I couldn’t see where I did the math wrong. Frustum’s near and far are reasonable, FOV angle is 45f, therefore the view area isn’t too wide or shallow. Translation and rotation seems fine, as I have ported the working Android source code into this Java project. I am absolutely clueless.

The vertex shader doesn’t contain any complicated calculations. If you mean removing the matrix transformation in the vertex shader, I did that and have set the vertices to be coordinates in the world space. No results.

Here’s the code in its entirely:


uniform mat4 u_matrix;

attribute vec4 a_position;
attribute vec2 a_texPos;

varying vec2 v_texPos;

void main(){
	v_texPos=a_texPos;
	//gl_Position=u_matrix*a_position;
	gl_Position=a_position;
}


So is the fragment shader, nothing’s very complicated.

uniform sampler2D u_texUnit;

varying vec2 v_texPos;

void main(){
	//gl_FragColor=texture2D(u_texUnit,v_texPos);
	gl_FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}

I have both of them simplified as much as possible, and nothing is showing up. I’m going to leave it like this, in order to check up on the rest.


Below is the updated “Something” class, in which I have refactored the code up a bit, just to see what is going on. I still can’t find the problem, even when I rewrote a large portion of the code.


public class Something {
	private Shader shader;
	private Sample textureSample;
	private int texture;
	
	//private FloatBuffer viewMatrix;
	private FloatBuffer modelProjectionMatrix;
	

	public Something() {
		glClearColor(0.4f, 0.6f, 0.9f, 1f);
		glViewport(0, 0, Game.WIDTH, Game.HEIGHT);
		
		Matrix4f pMatrix = new Matrix4f();
		FloatBuffer projectionMatrix;
		float[] p = new float[16];
		perspectiveM(p, 45f, (float) Game.WIDTH / (float) Game.HEIGHT, 1f, 10f);
		projectionMatrix = BufferUtils.createFloatBuffer(16).put(p);
		projectionMatrix.flip();
		pMatrix.load(projectionMatrix);
		
		Matrix4f mMatrix = new Matrix4f();
		Vector3f tempVector = new Vector3f();
		tempVector.set(0f, 0f, -2.5f);
		mMatrix.setIdentity();
		mMatrix.translate(tempVector);
		tempVector.set(1f, 0f, 0f);
		mMatrix.rotate(-60f, tempVector);
		modelProjectionMatrix = BufferUtils.createFloatBuffer(16);
		Matrix4f mpMatrix = new Matrix4f();
		Matrix4f.mul(mMatrix, pMatrix, mpMatrix);
		mpMatrix.store(modelProjectionMatrix);
		modelProjectionMatrix.flip();
		this.init();
	}
	
	public void init() {
		
		shader = new Shader();
		textureSample = new Sample();
		
		this.textureInit();
	}
	
	public void update() {
		
	}
	
	public void render() {
		glClear(GL_COLOR_BUFFER_BIT);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}

		glEnable(GL_TEXTURE_2D);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glEnable(GL_BLEND);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		
		glUseProgram(shader.program);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glUniformMatrix4(shader.uMatrixLocation, false, this.modelProjectionMatrix);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		
		GL13.glActiveTexture(GL13.GL_TEXTURE0);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glBindTexture(GL_TEXTURE_2D, this.texture);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		//The second parameter refers to the texture unit.
		glUniform1i(shader.uTextureUnitLocation, 0);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		
		//TODO: Where is the glUniform() for uTextureUnitLocation?
		
		//???  This is correct?   ???
		this.textureSample.vertexBuffer.position(0);
		glVertexAttribPointer(0, 2, false, 0, textureSample.vertexBuffer);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glEnableVertexAttribArray(0);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		this.textureSample.vertexBuffer.position(0);
		
		this.textureSample.texBuffer.position(0);
		glVertexAttribPointer(1, 2, false, 0, textureSample.texBuffer);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glEnableVertexAttribArray(1);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		this.textureSample.texBuffer.position(0);
		
		glDrawArrays(GL_TRIANGLES, 0, 4);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		
		glDisableVertexAttribArray(0);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glDisableVertexAttribArray(1);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
	}
	
	private void textureInit() {
		this.texture = glGenTextures();
		BufferedImage img = null;
		String filename = "/icon.png";
		try {
			img = ImageIO.read(Something.class.getResource(filename));
		}
		catch (IOException e) {
			e.printStackTrace();
			System.err.println("Unable to load image: " + filename);
			throw new RuntimeException(e);
		}
		int[] pixels = new int[img.getWidth() * img.getHeight() * 4];
		img.getRGB(0, 0, img.getWidth(), img.getHeight(), pixels, 0, img.getWidth());
		
		ByteBuffer pixelBuffer = BufferUtils.createByteBuffer(pixels.length);
		pixelBuffer.position(0);
		for (int y = 0; y < img.getHeight(); y++) {
			for (int x = 0; x < img.getWidth(); x++) {
				int pixel = pixels[y * img.getWidth() + x];
				pixelBuffer.put((byte) ((pixel >> 16) & 0xFF));
				pixelBuffer.put((byte) ((pixel >> 8) & 0xFF));
				pixelBuffer.put((byte) ((pixel) & 0xFF));
				pixelBuffer.put((byte) ((pixel >> 24) & 0xFF));
			}
		}
		pixelBuffer.flip();

		glBindTexture(GL_TEXTURE_2D, texture);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, img.getWidth(), img.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer);
		
		glBindTexture(GL_TEXTURE_2D, 0);
	}
	
	public static void perspectiveM(float[] m, float yFovInDegrees, float aspect, float n, float f) {
        final float angleInRadians = (float) (yFovInDegrees * Math.PI / 180.0);
        final float a = (float) (1.0 / Math.tan(angleInRadians / 2.0));

        m[0] = a / aspect;
        m[1] = 0f;
        m[2] = 0f;
        m[3] = 0f;

        m[4] = 0f;
        m[5] = a;
        m[6] = 0f;
        m[7] = 0f;

        m[8] = 0f;
        m[9] = 0f;
        m[10] = -((f + n) / (f - n));
        m[11] = -1f;

        m[12] = 0f;
        m[13] = 0f;
        m[14] = -((2f * f * n) / (f - n));
        m[15] = 0f;        
    }
}

Shader code and the texture object are working normally. The problem must be in this “Something” class.

I would be pissed if I didn’t see an error you guys pointed out, if you guys found it. Unless the bug itself has to do with something very basic, I don’t see it with my own eyes, and I’m getting dang sleepy because of it.

I don’t like the fact that in your vertex shader you set gl_Poisition to something you pass in. Where do you actually set that attribute?

In the shader loading class.

package core;

import static org.lwjgl.opengl.GL11.GL_NO_ERROR;
import static org.lwjgl.opengl.GL11.glGetError;
import static org.lwjgl.opengl.GL20.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Shader {
	private String vertexShaderSource = loadCode("/tex_vert.glsl");
	private String fragmentShaderSource = loadCode("/tex_frag.glsl");
	
	private final String U_MATRIX = "u_matrix";
	private final String U_TEXTUREUNIT = "u_texUnit";
	private final String A_POSITION = "a_position";
	private final String A_TEXTURE_COORDINATES = "a_texPos";
	
	public int uMatrixLocation;
	public int uTextureUnitLocation;
	public int aPositionLocation;
	public int aTextureCoordinatesLocation;
	public int program;
	
	public static String loadCode(String filename) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(Shader.class.getResourceAsStream(filename)));
		StringBuilder builder = new StringBuilder();
		String line;
		try {
			while ((line = reader.readLine()) != null) {
				builder.append(line);
				builder.append('\n');
			}
		}
		catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		return builder.toString();
	}
	
	public Shader() {
		int vertexShaderHandle = glCreateShader(GL_VERTEX_SHADER);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glShaderSource(vertexShaderHandle, vertexShaderSource);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glCompileShader(vertexShaderHandle);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		if (glGetShaderi(vertexShaderHandle, GL_COMPILE_STATUS) == 0) {
			System.out.printf("Vertex Shader Error. Log info: %s", glGetShaderInfoLog(vertexShaderHandle, GL_INFO_LOG_LENGTH));
			glDeleteShader(vertexShaderHandle);
			return;
		}
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		int fragmentShaderHandle = glCreateShader(GL_FRAGMENT_SHADER);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glShaderSource(fragmentShaderHandle, fragmentShaderSource);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glCompileShader(fragmentShaderHandle);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		if (glGetShaderi(fragmentShaderHandle, GL_COMPILE_STATUS) == 0) {
			System.out.printf("Fragment Shader Error. Log info: %s", glGetShaderInfoLog(fragmentShaderHandle, GL_INFO_LOG_LENGTH));
			glDeleteShader(fragmentShaderHandle);
			return;
		}
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}

		this.program = glCreateProgram();
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		if (this.program == 0) {
			System.out.printf("Program not created. Error info: %s", glGetProgramInfoLog(program, GL_INFO_LOG_LENGTH));
			return;
		}
		glAttachShader(this.program, vertexShaderHandle);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glAttachShader(this.program, fragmentShaderHandle);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glLinkProgram(this.program);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		if (glGetProgrami(program, GL_LINK_STATUS) == 0) {
			System.out.println("Program unable to link.");
			glDeleteProgram(this.program);
			return;
		}
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		glValidateProgram(this.program);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		if (glGetProgrami(program, GL_VALIDATE_STATUS) == 0) {
			System.out.println("Program validation failed.");
			glDeleteProgram(this.program);
			return;
		}
		
		uMatrixLocation = glGetUniformLocation(program, U_MATRIX);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		uTextureUnitLocation = glGetUniformLocation(program, U_TEXTUREUNIT);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		aPositionLocation = glGetAttribLocation(program, A_POSITION);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		aTextureCoordinatesLocation = glGetAttribLocation(program, A_TEXTURE_COORDINATES);
		if (glGetError() != GL_NO_ERROR) {
			System.out.println("ERROR");
			return;
		}
		
		//		glBindAttribLocation(program, 0, A_POSITION);
		//		glBindAttribLocation(program, 1, A_TEXTURE_COORDINATES);
		//		glBindAttribLocation(program, 2, U_MATRIX);
		//		glBindAttribLocation(program, 3, U_TEXTUREUNIT);

	}
}

And if you want to know the vertices, it’s hardcoded in my “Sample” class.

package core;

import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;

public class Sample {
	public FloatBuffer vertexBuffer;
	public FloatBuffer texBuffer;
	
	private final float[] vertexData = {
			10f, 10f,
			40f, 10f,
			40f, 40f,
			10f, 40f
	};

	private final float[] texData = {
			0f, 1f,
			1f, 1f,
			1f, 0f,
			0f, 0f
	};
	
	public Sample() {
		vertexBuffer = BufferUtils.createFloatBuffer(vertexData.length).put(vertexData);
		vertexBuffer.flip();
		texBuffer = BufferUtils.createFloatBuffer(texData.length).put(texData);
		texBuffer.flip();
	}
}