Help with render to texture

Started by clownvin, January 11, 2018, 10:19:57

Previous topic - Next topic

clownvin

I've got some code that's supposed to render text to a texture so that I don't have to render each character each draw step, and can instead use the rendered texture. However, my code does not as it's supposed to, and the texture is left blank. After a few hours of trying different things, I cannot figure it out, and so I bring the question to you.

I'm fairly certain the problem is somewhere in this code chunk below, but if you think it's not, I'll gladly post whatever other samples of code you would like. I just really want to get this done already. The exact problem is that the created texture is blank, and never is rendered to (it seems like). I've tried just drawing one massive quad on it, and that didn't seem to work either.
Edit: After flipping the buffer, I can get some color to be rendered to the texture, but it's all just one color (which makes me think it's only sampling one pixel), and I can't figure out how to get the actual image I want to render to show on it.

public Text(String text, int x, int y, Font font, float size, GUIComponent parent, Binding binding) {
		super(null, x, y, font.getStringWidth(size, text), font.getStringHeight(size), parent, binding, false);
		this.text = text;
		this.font = font;
		this.width = font.getStringWidth(size, text);
		this.height = font.getStringHeight(size);
		int fbo = glGenFramebuffers();
		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
		int tex = glGenTextures();
		glBindTexture(GL_TEXTURE_2D, tex);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);
		IntBuffer intBuffer = BufferUtils.createIntBuffer(1);
		intBuffer.put(GL_COLOR_ATTACHMENT0);
		intBuffer.flip();
		glDrawBuffers(intBuffer);
		if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
			throw new RuntimeException("Something really bad happened");
		}
		//RENDER
		RenderUtil.recalibrate(width, height, 1.0f); //Does glViewport(width, height), and some matrix stuff
		Camera.updateShader("textshader", "projection", false); //Update projection matrix
		glEnableVertexAttribArray(0);
		glEnableVertexAttribArray(1);
		int width = 0;
		float f = this.width / 1.0f;
		int charWidth = 0;
		for (char c : text.toCharArray()) {
			font.bind(0, c % 256); // calls glBindTexture, this works, have tested
			//ResourceManager.getTexture("grassroadedger1").bind(0, 0);
			charWidth = font.getCharWidth(size, c);
			//float[] verts = new float[] { -1f, 1f, 1f, 1f, 1f, -1f, -1f, -1f };
			float[] verts = new float[] { -1.0f + (width / f), 1.0f, 1.0f + ((width + charWidth) / f), 1.0f, 1.0f + ((width + charWidth) / f), -1.0f, -1.0f + (width / f), -1.0f };
			width += charWidth;
			glBindBuffer(GL_ARRAY_BUFFER, vertexPointer);
			glBufferSubData(GL_ARRAY_BUFFER, 0, RenderUtil.createBuffer(verts));
			glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);

			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, RenderUtil.getIndicesPointer());
			glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

			glBindBuffer(GL_ARRAY_BUFFER, 0);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		}
		glDisableVertexAttribArray(0);
		glDisableVertexAttribArray(1);
		//END
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glBindTexture(GL_TEXTURE_2D, 0);
		RenderUtil.recalibrate(Window.getWidth(), Window.getHeight(), LuminaEngine.getGlobalImageScale());
		this.setTexture(new Texture(tex, "text_"+size+"_"+text));
	}


Fragment Shader
#version 330 core

in vec2 uv;

layout(location = 0) out vec4 color;

uniform sampler2D sampler;

void main(){

    color = texture2D( sampler, uv );
}


VertexShader

#version 330 core

layout(location = 0) in vec3 vertices;
layout(location = 1) in vec2 textures;

out vec2 uv;

uniform mat4 projection;

void main(){

    gl_Position =  projection * vec4(vertices,1);

    uv = textures;
}


Update: found out I need to flip the intBuffer, but that's not the only problem apparently, since I can only get a giant blue square to appear. Still trying things.

quew8

I notice that when you render the quads, you only setup a pointer for vertex attrib 0 which looks like position but you enable and expect vertex attrib 1 as well which looks like tex coords.

...
glBindBuffer(GL_ARRAY_BUFFER, vertexPointer);
glBufferSubData(GL_ARRAY_BUFFER, 0, RenderUtil.createBuffer(verts));
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
//MISSING CALL to glVertexAttribPointer(1, 2, GL_FLOAT, ?, ?);
 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, RenderUtil.getIndicesPointer());
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
...


Now I don't know for sure what happens if you enable a vertex attribute but don't setup a pointer for it. Probably depends on whatever state you left it in but, it evaluating to a constant value (like 0) seems plausible. Which in this case would mean only sampling a single pixel of the bitmap texture. Which is what you recon is going on.

Might not be the case but probably worth a look.