Part of the Khronos Group

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Drawing a cube and a triangle in different positions

  1. #1
    Newbie Newbie
    Join Date
    Feb 2014

    Question Drawing a cube and a triangle in different positions


    I'm learning OpenGL and I have a (potentially stupid) question. My main objective is to draw a cube and a triangle in different locations by using two separated arrays, two MVP (Model, View and Projection) matrices and one vertex shader. If I draw my cube alone it works, and the same with my triangle, but when I try to draw both of them at the same time I don't get the desired result

    This is my C++ code:
    Code :
    #define GLEW_STATIC
    #include <GL\glew.h>
    #include <GLFW\glfw3.h>
    #include <glm\glm.hpp>
    #include <glm\gtx\transform.hpp>
    #include <glm\gtc\matrix_transform.hpp>
    #include <vector>
    #include <iostream>
    #include "ShaderFile.hpp" //My own shader wrapper
    //Using the OpenGL 4.1 version
    #define OPENGL_MAJOR 4
    #define OPENGL_MINOR 1
    //#define FULLSCREEN
    #define WINDOW_TITLE "Color Cube and The Lone Triangle"
    #ifdef FULLSCREEN
    #define SCREEN_WIDTH 1366
    #define SCREEN_HEIGHT 768
    #define SCREEN_WIDTH 800
    #define SCREEN_HEIGHT 600
    ///My cube
    static const GLfloat vertex_buffer_array[] = {
    	-1.0f, -1.0f, -1.0f,
    	-1.0f, -1.0f, 1.0f,
    	-1.0f, 1.0f, 1.0f,
    	1.0f, 1.0f, -1.0f,
    	-1.0f, -1.0f, -1.0f,
    	-1.0f, 1.0f, -1.0f,
    	1.0f, -1.0f, 1.0f,
    	-1.0f, -1.0f, -1.0f,
    	1.0f, -1.0f, -1.0f,
    	1.0f, 1.0f, -1.0f,
    	1.0f, -1.0f, -1.0f,
    	-1.0f, -1.0f, -1.0f,
    	-1.0f, -1.0f, -1.0f,
    	-1.0f, 1.0f, 1.0f,
    	-1.0f, 1.0f, -1.0f,
    	1.0f, -1.0f, 1.0f,
    	-1.0f, -1.0f, 1.0f,
    	-1.0f, -1.0f, -1.0f,
    	-1.0f, 1.0f, 1.0f,
    	-1.0f, -1.0f, 1.0f,
    	1.0f, -1.0f, 1.0f,
    	1.0f, 1.0f, 1.0f,
    	1.0f, -1.0f, -1.0f,
    	1.0f, 1.0f, -1.0f,
    	1.0f, -1.0f, -1.0f,
    	1.0f, 1.0f, 1.0f,
    	1.0f, -1.0f, 1.0f,
    	1.0f, 1.0f, 1.0f,
    	1.0f, 1.0f, -1.0f,
    	-1.0f, 1.0f, -1.0f,
    	1.0f, 1.0f, 1.0f,
    	-1.0f, 1.0f, -1.0f,
    	-1.0f, 1.0f, 1.0f,
    	1.0f, 1.0f, 1.0f,
    	-1.0f, 1.0f, 1.0f,
    	1.0f, -1.0f, 1.0f
    //Colors for my cube
    static const GLfloat color_buffer_data[] = {
    	0.583f,  0.771f,  0.014f,
    	0.609f,  0.115f,  0.436f,
    	0.327f,  0.483f,  0.844f,
    	0.822f,  0.569f,  0.201f,
    	0.435f,  0.602f,  0.223f,
    	0.310f,  0.747f,  0.185f,
    	0.597f,  0.770f,  0.761f,
    	0.559f,  0.436f,  0.730f,
    	0.359f,  0.583f,  0.152f,
    	0.483f,  0.596f,  0.789f,
    	0.559f,  0.861f,  0.639f,
    	0.195f,  0.548f,  0.859f,
    	0.014f,  0.184f,  0.576f,
    	0.771f,  0.328f,  0.970f,
    	0.406f,  0.615f,  0.116f,
    	0.676f,  0.977f,  0.133f,
    	0.971f,  0.572f,  0.833f,
    	0.140f,  0.616f,  0.489f,
    	0.997f,  0.513f,  0.064f,
    	0.945f,  0.719f,  0.592f,
    	0.543f,  0.021f,  0.978f,
    	0.279f,  0.317f,  0.505f,
    	0.167f,  0.620f,  0.077f,
    	0.347f,  0.857f,  0.137f,
    	0.055f,  0.953f,  0.042f,
    	0.714f,  0.505f,  0.345f,
    	0.783f,  0.290f,  0.734f,
    	0.722f,  0.645f,  0.174f,
    	0.302f,  0.455f,  0.848f,
    	0.225f,  0.587f,  0.040f,
    	0.517f,  0.713f,  0.338f,
    	0.053f,  0.959f,  0.120f,
    	0.393f,  0.621f,  0.362f,
    	0.673f,  0.211f,  0.457f,
    	0.820f,  0.883f,  0.371f,
    	0.982f,  0.099f,  0.879f
    //The triangle
    static const GLfloat triangle_data_array[] = {
    	-1.0F, -1.0F, 0.0F,
    	1.0F, -1.0F, 0.0F,
    	0.0F, 1.0F, 0.0F
    // Functions prototypes
    //It creates the main UI window
    GLFWwindow* createContext(void);
    //It configures OpenGL and the context
    void configureGLFWWindow(void);
    //Vertex Array Object: It stores all of the links between the attributes
    //and your Vertex Buffer Objects with raw vertex data
    GLuint inline createVAO(void);
    //It draws the vertex data
    void inline draw(GLuint&, GLuint&);
    void inline drawTriangle(GLuint&);
    //It creates the shader program
    GLuint createProgram(void);
    //This function compile the referenced shader ID with the shader file string.
    void compileShader(GLuint&, const GLchar* const);
    //It shows information about the render and the OpenGL version
    void showInfo(void);
    //It computes and returns the Model, View and Projection matrix
    glm::mat4 createMVPMatrix(bool is_triangle = false);
    glm::mat4 createModelMatrix(void);
    glm::mat4 createModelMatrixForTriangle(void);
    int main()
    	auto window = createContext();
    	if (window == nullptr) return EXIT_FAILURE;
    	showInfo(); //Show info about the rendered and the OpenGL version
    	GLuint programID = createProgram(); //Create the shader program
    	//Get a handle for our "MVP" uniform.
    	GLuint MVPmatrixID = glGetUniformLocation(programID, "MVP");
    	glm::mat4 MVPmatrix = createMVPMatrix();
    	//The MVP for the triangle
    	GLuint MPVtriangleID = glGetUniformLocation(programID, "MVP_triangle");
    	glm::mat4 MVPmatrix_triangle = createMVPMatrix(true); //true for the triangle!
    	//The color of the background when you clear the screen
    	glClearColor(0.2f, 0.1f, 0.3f, 0.0f);
    	//The Z-Buffer
    	glEnable(GL_DEPTH_TEST); //Enable depth test
    	glDepthFunc(GL_LESS); //Accept fragment if it closer to the camera than the former one
    	//Create the Vertex Array Object
    	auto VAO_id = createVAO();
    	//Create the buffers: vertices
    	GLuint vertexBuffer;
    	glGenBuffers(1, &vertexBuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_buffer_array),
    	             vertex_buffer_array, GL_STATIC_DRAW);
    	//Create the buffers: colors
    	GLuint colorBuffer;
    	glGenBuffers(1, &colorBuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(color_buffer_data),
    	             color_buffer_data, GL_STATIC_DRAW);
    	//The Lone Triangle
    	GLuint triangleBuffer;
    	glGenBuffers(1, &triangleBuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_data_array),
    	             triangle_data_array, GL_STATIC_DRAW);
    	//The main loop!
    	while (!glfwWindowShouldClose(window)) {
    		//Tell GLFW to retrieve window events...
    		//Clear the screen
    		//Use the shader program!
    		//Send our transformation to the currently bound shader
    		glUniformMatrix4fv(MVPmatrixID, 1, GL_FALSE, &MVPmatrix[0][0]);
    		draw(vertexBuffer, colorBuffer);
    		//Draw the triangle!
    		glUniformMatrix4fv(MPVtriangleID, 1, GL_FALSE, &MVPmatrix_triangle[0][0]);
    		//If you press escape key, break the loop and finish execution
    		if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    			glfwSetWindowShouldClose(window, GL_TRUE);
    	// Cleanup VBO and shader
    	glDeleteBuffers(1, &vertexBuffer);
    	glDeleteBuffers(1, &colorBuffer);
    	glDeleteBuffers(1, &triangleBuffer);
    	glDeleteVertexArrays(1, &VAO_id);
    	return 0;
    // Prototypes implementation
    GLFWwindow* createContext(void)
    	if (!glfwInit()) {
    		std::cerr << "Failed to initialize GLFW =(" << std::endl;
    		return nullptr;
    	GLFWwindow* window;
    #ifdef FULLSCREEN
    	window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, WINDOW_TITLE,
    	                          glfwGetPrimaryMonitor(), nullptr);
    	window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, WINDOW_TITLE,
    	                          nullptr, nullptr);
    	//Prepare GLEW
    	glewExperimental = GL_TRUE;
    	if (glewInit() != GLEW_OK) {
    		std::cerr << "Failed to initialize GLEW =(" << std::endl;
    		return nullptr;
    	return window;
    void configureGLFWWindow(void)
    	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    GLuint inline createVAO(void)
    	GLuint VertexArrayID;
    	glGenVertexArrays(1, &VertexArrayID);
    	return VertexArrayID;
    void inline draw(GLuint& vertex, GLuint& colors)
    	glBindBuffer(GL_ARRAY_BUFFER, vertex);
    	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    	//Second buffer attributes: the colors
    	glBindBuffer(GL_ARRAY_BUFFER, colors);
    	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    	//Draw: 12 * 3 indices starting at 0 -> 12 triangles -> 6 squares
    	glDrawArrays(GL_TRIANGLES, 0, 12 * 3);
    void inline drawTriangle(GLuint& buffer)
    	glBindBuffer(GL_ARRAY_BUFFER, buffer);
    	glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    	glDrawArrays(GL_TRIANGLES, 0, 3);
    GLuint createProgram(void)
    	//Create and compile the shaders
    	GLuint vertexID = glCreateShader(GL_VERTEX_SHADER);
    	compileShader(vertexID, "shader.vert");
    	GLuint fragmentID = glCreateShader(GL_FRAGMENT_SHADER);
    	compileShader(fragmentID, "shader.frag");
    	//Link the program with the shaders
    	std::cout << "--> Linking the program..." << std::endl;
    	GLuint programID = glCreateProgram();
    	glAttachShader(programID, vertexID);
    	glAttachShader(programID, fragmentID);
    	//Check the program for any error
    	GLint result = GL_FALSE;
    	GLint infoLogLength;
    	glGetProgramiv(programID, GL_LINK_STATUS, &result);
    	if (result == GL_TRUE)
    		std::cout << "\tProgram #" << programID << " OK!" << std::endl;
    	else {
    		glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength);
    		std::vector<char> programInfoMsg(infoLogLength);
    		glGetProgramInfoLog(programID, infoLogLength, nullptr,
    		std::cout << "\tProgram #" << programID << " info log:\n"
    		          << &programInfoMsg[0] << std::endl;
    	return programID;
    void compileShader(GLuint& shaderID, const GLchar* const shaderFile)
    	Utils::ShaderFile shader(shaderFile);
    	//Get the vertex shader source and compile it
    	std::string shaderString = shader.getShaderStringSource();
    	const GLchar* vertSrc = const_cast<GLchar*>(shaderString.c_str());
    	std::cout << "--> Compiling Shader #"
    	          << shaderID << "... " << std::endl;
    	glShaderSource(shaderID, 1, &vertSrc, nullptr);
    	//Check the vertex shader compilation
    	GLint result = GL_FALSE;
    	int infoLogLength;
    	glGetShaderiv(shaderID, GL_COMPILE_STATUS, &result);
    	if (result == GL_TRUE)
    		std::cout << "\tShader #" << shaderID << " OK!" << std::endl;
    	else {
    		glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
    		std::vector<GLchar> vertexShaderInfoMsg(infoLogLength);
    		glGetShaderInfoLog(shaderID, infoLogLength, nullptr,
    		std::cout << "\tShader #" << shaderID << " info log:\n"
    		          << &vertexShaderInfoMsg[0] << std::endl;
    void showInfo(void)
    	std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;
    	std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;
    glm::mat4 createMVPMatrix(bool is_triangle)
    	//Projection matrix: 45 Field of View, 4:3 ratio
    	glm::mat4 projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
    	//View matrix
    	glm::mat4 view = glm::lookAt(glm::vec3(4, 3, -3), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
    	//Model matrix
    	glm::mat4 model = is_triangle ? createModelMatrixForTriangle() : createModelMatrix();
    	//Return the Model-View-Projection matrix
    	return projection * view * model;
    //The cube is in the upper right corner
    glm::mat4 createModelMatrix(void)
    	glm::mat4 translation = glm::translate(glm::vec3(-3.3F, 0.0F, 0.0F));
    	glm::mat4 scaling = glm::mat4(1.0F);
    	glm::mat4 rotation = glm::mat4(1.0F);
    	return translation * rotation * scaling;
    //The triangle is in the lower left corner
    glm::mat4 createModelMatrixForTriangle(void)
    	glm::mat4 translation = glm::translate(glm::vec3(1.3F, 0.0F, 0.0F));
    	glm::mat4 scaling = glm::mat4(1.0F);
    	glm::mat4 rotation = glm::mat4(1.0F);
    	return translation * rotation * scaling;

    And my vertex shader code where (I think) I have the problem:
    Code :
    #version 410 core
    layout(location = 0) in vec3 cube_position;
    layout(location = 1) in vec3 vertexColor;
    layout(location = 3) in vec3 triangle_position;
    out vec3 fragmentColor;
    uniform mat4 MVP; //Model-View-Projection
    uniform mat4 MVP_triangle;
    void main() {
    	vec4 cube_pos = (MVP * vec4(cube_position, 1));
    	vec4 triangle_pos = (MVP_triangle * vec4(triangle_position, 1));
    	gl_Position = triangle_pos;// * cube_pos; ????
    	// The color of each vertex will be interpolated to produce the color of each fragment
    	fragmentColor = vertexColor;

    I don't know if this is the right way... Can someone give me a hand?

    Thank you =)

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    You seem very confused about how a vertex shader works. It takes 1 vertex and applies the transformation to it. Therefore you should have only 1 input vertex and 1 MVP in the shader.
    your sequence is basically

    1) load the shader porgram
    2) bind the cube vertex buffer
    3) set the MVP in the shader to the cube matrix
    4) do draw of cube
    5) bind the triangle buffer
    6) set the MVP in the shader to the triangle matrix
    7) do draw triangle

  3. #3
    Newbie Newbie
    Join Date
    Feb 2014
    Thank you very much for your reply, I got it!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts