Why isn't it drawing RGB triangle?

Why isn’t it drawing RGB triangle? The triangle color is like red. Can anyone please see code below?

Full code:

#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <fstream>

GLuint LoadShader(GLenum type, const char *shaderSrc)
{
	GLuint shader;
	GLint compiled;
	
	// Create the shader object
	shader = glCreateShader(type);
	if(shader == 0)
	{
		return 0;
	}
	// Load the shader source
	glShaderSource(shader, 1, &shaderSrc, NULL);
	
	glCompileShader(shader);
	// Check the compile status
	glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
	if(!compiled) 
	{
		GLint infoLen = 0;
		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
		
		if(infoLen > 1)
		{
			char* infoLog = (char*) malloc(sizeof(char) * infoLen);
			glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
			printf("Error compiling shader:\n%s\n", infoLog);
			free(infoLog);
		}
		glDeleteShader(shader);
		return 0;
	}
	return shader;
}


GLuint programObject_;
GLuint vertexBuffer_;
GLuint indexBuffer_;
GLuint vertexArray_;
GLuint colors_;

/*
 *	Initialize the shader and program object.
 *	Initialize the triangle data buffers.
 */
bool Init(int width, int height)
{
	// Set the viewport
	glViewport(0, 0, width, height);
	/*
	GLchar *vShaderStr =
		"#version 460\n"
		"in vec3 vPosition;\n"
		"out vec3 vertexColor;\n"
		"void main()\n"
		"{\n"
		"	vertexColor = vPosition + vec3(0.5, 0.5, 0.5) / 2;\n"
		"	gl_Position = vec4(vPosition, 1.0);\n"
		"}\n";
	
	GLchar *fShaderStr =
		"#version 460\n"
		"in vec3 vertexColor;\n"
		"out vec4 finalColor;\n"
		""
		"void main()\n"
		"{\n"
		"  finalColor = vec4(vertexColor, 1.0);\n"
		"}\n";
	*/
	std::string VertexShaderCode;
	std::ifstream VertexShaderStream("vertex.vs", std::ios::in);
	if(VertexShaderStream.is_open())
	{
		std::string Line = "";
		while(getline(VertexShaderStream, Line))
			VertexShaderCode +="\n" + Line;
		VertexShaderStream.close();
	}
	const GLchar *vShaderStr = VertexShaderCode.c_str();

	std::string FragmentShaderCode;
	std::ifstream FragmentShaderStream("fragment.fs", std::ios::in);
	if(FragmentShaderStream.is_open())
	{
		std::string Line = "";
		while(getline(FragmentShaderStream, Line))
			FragmentShaderCode +="\n" + Line;
		FragmentShaderStream.close();
	}
	const GLchar *fShaderStr = FragmentShaderCode.c_str();
	
	GLuint vertexShader;
	GLuint fragmentShader;
	GLuint programObject;
	GLint linked;
	// Load the vertex/fragment shaders
	vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr);
	fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr);
	if (vertexShader == 0 || fragmentShader == 0)
	{
		return false;
	}
	programObject = glCreateProgram();

	glAttachShader(programObject, vertexShader);
	glAttachShader(programObject, fragmentShader);
	// Bind vPosition to attribute 0	
	glBindAttribLocation(programObject, 0, "vPosition");

	glLinkProgram(programObject);

	// Check the link status
	glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
	if(!linked) 
	{
		GLint infoLen = 0;
		glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
		
		if(infoLen > 1)
		{
			char* infoLog = (char*) malloc(sizeof(char) * infoLen);
			glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
			printf("Error linking program:\n%s\n", infoLog);
			
			free(infoLog);
		}
		glDeleteProgram(programObject);
		return false;
	}
	programObject_ = programObject;

	// set the background color when clear
	glClearColor(0.0f, 0.4f, 0.6f, 1.0f);

	GLfloat vVertices[] = {
		0.0f, 0.5f, 0.0f, 
		-0.5f, -0.5f, 0.0f,
		0.5f, -0.5f,  0.0f,
		
		1.0f, 0.0f, 0.0f, 
		0.0f, 1.0f, 0.0f,
		0.0f, 0.0f, 1.0f
	};
	GLshort vIndices[] = {0, 1, 2, 3, 4, 5};

	GLuint vertexBuffer;
	GLuint indexBuffer;
	glGenBuffers(1, &vertexBuffer);
	glGenBuffers(1, &indexBuffer);

	GLuint vertexArray;
	glGenVertexArrays(1, &vertexArray);

	// store the vertices of the triangle
	glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), vVertices, GL_STATIC_DRAW);
	
	// store the vertex indices of the triangle
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vIndices), vIndices, GL_STATIC_DRAW);

	glBindVertexArray(vertexArray);
	// start to store vertex binding information into VertexArray

	glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
	// Specify the data format of attribute channel 0
	
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GL_FLOAT), (void *)0);

	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GL_FLOAT), (void *)(3*sizeof(GL_FLOAT)));
	
	// end of storing vertex binding information into VertexArray
	glBindVertexArray(0);

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);
	
	vertexBuffer_ = vertexBuffer;
	indexBuffer_ = indexBuffer;
	vertexArray_ = vertexArray;

	return true;
}

/*
 *	Draw a triangle using the shader pair created in Init()
 */
void Draw()
{
	// Clear the color buffer
	glClear(GL_COLOR_BUFFER_BIT);
	// Use the program object
	glUseProgram(programObject_);
	
	// use the vertex bind information we bind previously
	glBindVertexArray(vertexArray_);
	// draw the triangle by index
	glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
	// unbind the vertex array to avoid it modified somewhere else
	glBindVertexArray(0);
	
	// CODE OMITTED: here are the code to swap buffers
}

int main() {
	GLFWwindow* window;
    if (!glfwInit())
        return -1;
    window = glfwCreateWindow(800, 600, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glewExperimental = GL_TRUE;
	glewInit();
	int width = 600;
	int height = 500;
	if (!Init(width, height))
	{
		return 0;
	}
    while (!glfwWindowShouldClose(window))
    {
    	Draw();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwTerminate();

	return 0;
}

vertex shader:

#version 460
in vec3 vPosition;
in vec3 vColor;
out vec3 vertexColor;
void main()
{
	vertexColor = vColor;
	gl_Position = vec4(vPosition, 1.0);
}

fragment shader:

#version 460
in vec3 vertexColor;
out vec4 finalColor;
void main()
{
  finalColor = vec4(vertexColor, 1.0);
}

The last argument should be 9*sizeof(GLfloat).

Also: sizeof(GL_FLOAT) is incorrect in all cases; it just happens to work because GLfloat is the same size as int. The type is GLfloat; GL_FLOAT is a manifest constant (whose type is int).

It looks, this solved the problem. Thanks GClements. But in the output, why is green color has more area than red or blue?

It doesn’t.

If you change the fragment shader to:

  finalColor = vec4(round(vertexColor), 1.0);

you’ll get three identical-size segments, corresponding to which of the three components has the largest value. The boundaries between segments are the points where the two largest components are equal.

If you feel that green appears larger, it’s because you’re considering yellow and/or cyan as being “green”, when they’re equally close to green and red/blue.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.