Quad Is Rendered As Completely White

Started by TLHPoE, March 12, 2018, 18:42:42

Previous topic - Next topic

TLHPoE

My current goal is to render a quad with colors, but currently my quad is drawn as completely white. I am using the "modern method," with each vertex's position and color being interleaved into one VBO. The quad is being drawn correctly, but the entire quad is white. I have tried enabling blending and alpha.

My code is based around the tutorials found on the LWJGL wiki, with a few minor adjustments:

  • My loop is found in my main class; the majority of my rendering code has been isolated to my QuadRendering class
  • I load the element buffer in the very beginning and reuse it for every draw
  • My vertex class is condensed with the order x, y, z, r, g, b, a
  • Removed the magic numbers that the tutorial used to identify attributes; I defined them at the top of my QuadRendering class

I am relatively new to OpenGL, so any comments on how I structure things or my interpretation of the functions are appreciated.

Here is my code,

Main Render Method:
private void render(double dT) {
		try(MemoryStack stack = stackPush()) {
			IntBuffer pWidth = stack.mallocInt(1);
			IntBuffer pHeight = stack.mallocInt(1);

			glfwGetWindowSize(window, pWidth, pHeight);

			glViewport(0, 0, pWidth.get(0), pHeight.get(0));
		}

		shader.bind();

		QuadRendering.render(dT);

		shader.unbind();
	}


QuadRendering:
package com.kain.gp1;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;

import java.nio.*;

import org.lwjgl.*;
import org.lwjgl.opengl.*;

import com.kain.gp1.render.*;

public class QuadRendering {
	public static final int POSITION = 0, COLOR = 1;

	public static int quadIndicesVBOID, quadIndexCount;

	public static void preloadData() {
		byte[] indices = {
				0, 1, 2,
				2, 3, 0
		};

		quadIndexCount = indices.length;

		ByteBuffer indicesBuffer = BufferUtils.createByteBuffer(quadIndexCount);
		indicesBuffer.put(indices);
		indicesBuffer.flip();

		quadIndicesVBOID = glGenBuffers();

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadIndicesVBOID);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW);

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	}

	public static void render(double dT) {
		int vaoID = GL30.glGenVertexArrays();
		int vboID = GL15.glGenBuffers();

		FloatBuffer verticesBuffer = Vertex.combineVertices(
				new Vertex(-0.5F, 0.5F, 0F, 1F, 0F, 0F, 1F),
				new Vertex(-0.5F, -0.5F, 0F, 0F, 1F, 0F, 1F),
				new Vertex(0.5F, -0.5F, 0F, 0F, 0F, 1F, 1F),
				new Vertex(0.5F, 0.5F, 0F, 1F, 1F, 1F, 1F));

		//Data variables created
		//Now to send the data to the GPU

		glBindVertexArray(vaoID);

		glBindBuffer(GL_ARRAY_BUFFER, vboID);
		glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);

		glVertexAttribPointer(POSITION, Vertex.XYZ_SIZE, GL_FLOAT, false, Vertex.TOTAL_BYTE_SIZE, 0);
		glVertexAttribPointer(COLOR, Vertex.COLOR_SIZE, GL_FLOAT, false, Vertex.TOTAL_BYTE_SIZE, Vertex.XYZ_BYTE_SIZE);

		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindVertexArray(0);

		//Data sent to the GPU
		//Now to draw

		glEnable(GL_BLEND); //These 2 methods are my attempts to get any color to appear
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		
		glBindVertexArray(vaoID);
		
		glEnableVertexAttribArray(POSITION);
		glEnableVertexAttribArray(COLOR);
		
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadIndicesVBOID);

		glDrawElements(GL_TRIANGLES, quadIndexCount, GL_UNSIGNED_BYTE, 0);

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		
		glDisableVertexAttribArray(POSITION);
		glDisableVertexAttribArray(COLOR);
		
		glBindVertexArray(0);

		//After drawing, we have to dispose of the variables

		glDeleteBuffers(vboID);
		glDeleteVertexArrays(vaoID);
	}

	public static void dispose() {
		glDeleteBuffers(quadIndicesVBOID);
	}
}


Vertex:
package com.kain.gp1.render;

import java.nio.*;

import org.lwjgl.system.*;

public class Vertex {
	public static int XYZ_SIZE = 3, COLOR_SIZE = 4, TOTAL_SIZE = XYZ_SIZE + COLOR_SIZE;
	public static int FLOAT_BYTE_SIZE = 4;
	public static int XYZ_BYTE_SIZE = XYZ_SIZE * FLOAT_BYTE_SIZE, COLOR_BYTE_SIZE = COLOR_SIZE * FLOAT_BYTE_SIZE, TOTAL_BYTE_SIZE = TOTAL_SIZE * FLOAT_BYTE_SIZE;

	public float[] xyz, color, uv;

	public Vertex(float x, float y, float z, float r, float g, float b, float a) {
		setXYZ(x, y, z);
		setColor(r, g, b, a);
	}

	public Vertex setXYZ(float x, float y, float z) {
		xyz = new float[] { x, y, z };

		return this;
	}

	public Vertex setColor(float r, float g, float b, float a) {
		color = new float[] { r, g, b, a };

		return this;
	}

	public FloatBuffer toFloatBuffer() {
		FloatBuffer buf = MemoryUtil.memCallocFloat(TOTAL_SIZE);

		buf.put(xyz);
		buf.put(color);
		buf.flip();

		return buf;
	}

	public static FloatBuffer combineVertices(Vertex... vertices) {
		FloatBuffer verticesBuf = MemoryUtil.memAllocFloat(TOTAL_SIZE * vertices.length);

		for(Vertex vertex : vertices) {
			verticesBuf.put(vertex.toFloatBuffer());
		}

		verticesBuf.flip();

		return verticesBuf;
	}
}


ShaderProgram:
package com.kain.gp1.shader;

import static org.lwjgl.opengl.GL20.*;

import java.io.*;
import java.nio.charset.*;
import java.nio.file.*;

import com.kain.gp1.*;

public class ShaderProgram {
	public final int programID, vsID, fsID;

	public ShaderProgram() throws Exception {
		programID = glCreateProgram();

		if(programID == 0) {
			throw new Exception("Could not create Shader");
		}

		vsID = createShader(getFileText("./res/vertex.vs"), GL_VERTEX_SHADER);
		fsID = createShader(getFileText("./res/fragment.fs"), GL_FRAGMENT_SHADER);
	}

	public void link() throws Exception {
		glLinkProgram(programID);

		if(glGetProgrami(programID, GL_LINK_STATUS) == 0) {
			throw new Exception("Error linking shader program: " + glGetProgramInfoLog(programID, 1024));
		}

		if(vsID != 0) {
			glDetachShader(programID, vsID);
		}

		if(fsID != 0) {
			glDetachShader(programID, fsID);

			glValidateProgram(programID);

			if(glGetProgrami(programID, GL_VALIDATE_STATUS) == 0) {
				System.err.println("Warning validating shader code: " + glGetProgramInfoLog(programID, 1024));
			}
		}
	}
	
	public void bind() {
		glUseProgram(programID);
	}
	
	public void unbind() {
		glUseProgram(0);
	}
	
	public void dispose() {
		unbind();
		
		if(programID != 0) {
			glDeleteProgram(programID);
		}
	}

	private int createShader(String shaderCode, int shaderType) throws Exception {
		int shaderID = glCreateShader(shaderType);

		if(shaderID == 0) {
			throw new Exception("Error creating shader. Type: " + shaderType);
		}

		glShaderSource(shaderID, shaderCode);
		glCompileShader(shaderID);

		if(glGetShaderi(shaderID, GL_COMPILE_STATUS) == 0) {
			throw new Exception("Error compiling shader code: " + glGetShaderInfoLog(shaderID, 1024));
		}

		glBindAttribLocation(programID, QuadRendering.POSITION, "in_Position");
		glBindAttribLocation(programID, QuadRendering.COLOR, "in_Color");

		glAttachShader(programID, shaderID);

		return shaderID;
	}

	private String getFileText(String file) throws IOException {
		byte[] encoded = Files.readAllBytes(Paths.get(file));

		return new String(encoded, StandardCharsets.UTF_8);
	}
}


Vertex Shader:
#version 150 core

in vec4 in_Position;
in vec4 in_Color;
in vec2 in_UV;

out vec4 pass_Color;
out vec2 pass_UV;

void main() {
	gl_Position = in_Position;
	
	pass_Color = in_Color;
	
	pass_UV = in_UV;
}


Fragment Shader:
#version 150 core

uniform sampler2D texture_diffuse;

in vec4 pass_Color;
in vec2 pass_UV;

out vec4 out_Color;
out vec2 out_UV;

void main() {
	out_Color = pass_Color;
	
	out_Color = texture(texture_diffuse, pass_UV);
}

Andrew Alfazy

I'm new too but may be the problem in fragment shader
out_Color = pass_Color;
out_Color = texture(texture_diffuse, pass_UV);

first you set the out color to be  pass_Color than set it again to be texture(texture_diffuse, pass_UV).
You must add values.
out_Color = pass_Color + texture(texture_diffuse, pass_UV);

the final code
#version 150 core
 
uniform sampler2D texture_diffuse;
 
in vec4 pass_Color;
in vec2 pass_UV;
 
out vec4 out_Color;
out vec2 out_UV;
 
void main() {
    out_Color = pass_Color + texture(texture_diffuse, pass_UV);
}