3

I'm not able to draw an object, that has the same height and width. I'm originally trying to do something a bit more complex, but I've broken it down as much as I could:

I have a window with a resolution of 600x600px and the following vertex and fragment shader:

Vertex Shader

#version 330 core

layout (location = 0) in vec3 aPos;
void main()
{
    gl_Position =  vec4(aPos, 1.0f);
}

Fragment Shader

#version 330 core
out vec4 FragColor;
void main()
    {
        FragColor = vec4(1.0f,1.0f,1.0f,1.0f);
    }

The Output I receive looks like this:

not a square

Here is the code I use to draw the square:

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "shader.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Object.h"

int width = 600;
int height = 600;

int main()
{
//window creation -----------------------------------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_SAMPLES, 16);
    GLFWwindow* window = glfwCreateWindow(width, height, "Mumel", NULL, NULL);

    glfwMakeContextCurrent(window);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Error during GLAD initialization" << std::endl;
        glfwTerminate();
        return -1;
    }

    glViewport(0, 0, width, height);
//----------------------------------------------------------------------
    Shader sh("./shader/vShader.vSh", "./shader/fShader.fSh");

    Circle * circle = new Circle(0.5); //is explained later in the post

    while (!glfwWindowShouldClose(window))
    {
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        sh.use();
        circle->draw();

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}

And last but not least, my "Circle" (it is supposed to be one, but a square was easier to debug) is created by the following code:

#ifndef OBJECT_H
#define OBJECT_H

#include <glad/glad.h>
#include <iostream>
#include "shader.h"
#include <vector>


class Circle
{
public:
    static const int size = 6; 

    Circle()
    {
        std::vector<float> vertexData(3 * size); 
        // center 
        vertexData.at(0) = 0.0f;
        vertexData.at(1) = 0.0f;
        vertexData.at(2) = 0.0f;

        vertexData.at(3) = 0.5f;
        vertexData.at(5) = 0.0f;
        vertexData.at(4) = -0.5f;

        vertexData.at(6) = -0.5f;
        vertexData.at(8) = 0.0f;
        vertexData.at(7) = -0.5f;

        vertexData.at(9) = -0.5f;
        vertexData.at(11) = 0.0f;
        vertexData.at(10) = 0.5f;

        vertexData.at(12) = 0.5f;
        vertexData.at(14) = 0.0f;
        vertexData.at(13) = 0.5f;

        vertexData.at(15) = 0.5f;
        vertexData.at(17) = 0.0f;
        vertexData.at(16) = -0.5f;


        glGenBuffers(1, &VBO);
        glGenVertexArrays(1, &VAO);
        glBindVertexArray(VAO);

        float * dataArr = vertexData.data(); //The GLSL shader needs a C Array, this returns the pointer to the first array object used by std::vector
        int dataSize = vertexData.size();

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, dataSize * sizeof(float), dataArr, GL_STATIC_DRAW);

        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);

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

    void draw()
    {
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLE_FAN, 0, 3 * (size - 2));
        glBindVertexArray(0);
    }
private:
    unsigned int VBO, VAO;

};

#endif
genpfault
  • 51,148
  • 11
  • 85
  • 139
adm0n
  • 53
  • 5
  • Anything change if you use values from `glfwGetFramebufferSize()` to populate `glViewport()` every frame? – genpfault May 21 '19 at 15:41
  • Nope, sadly not. – adm0n May 21 '19 at 15:44
  • Likely your monitor doesn't have square pixels (in its current resolution setting), so drawing a true square involves filling in a rectangle of pixels. See https://community.khronos.org/t/aspect-ratio/20656 and https://stackoverflow.com/questions/9071814/opengl-stretched-shapes-aspect-ratio – L. Scott Johnson May 21 '19 at 15:45
  • @L.ScottJohnson I'm having problems thinking in non square pixels, but from what I've read, it'd be very unlikely for me to draw non square pixels and the images looks visibly squished on my screen as well. Do you have any idea how I could find out what "pixel ration" I do have? – adm0n May 21 '19 at 16:04
  • @adm0n If you can't find it in the specs, you can get a good idea by using a ruler: set the screen to all white, measure the white rectangle and compare to the pixel resolution setting. – L. Scott Johnson May 21 '19 at 16:12
  • Where's the `double`-taking `Circle` constructor (as called by `main()`)? You've only provided a zero-argument `Circle` constructor. – genpfault May 21 '19 at 16:18
  • I do not see any aspect ratio correction... If I see it right your square is `+/-0.5` and you do not use any matrices so in vertex shader you should do `gl_Position = vec4(aPos.x, aPos.y*xs/ys, aPos.z, 1.0f);` where `xs,ys` is the resolution of your client area of Window where GL is rendered ... the same resolution goes to the `glViewport`. You know windows have border caption and menu and stuff so Client area is smaller than the actual window size ... – Spektre May 21 '19 at 18:08
  • @genpfault Sorry, I forgot to update the code. The double doesn't affect the circle and it deleted it in the actually constructed of the code I ran. – adm0n May 23 '19 at 08:10
  • @Spektre The problem lies somewhere outside of my control. The Viewport is actually 600x600px and the square is also a square. That is until I let my GPU render it. So if I use glReadPixels and reconstruct the image after the fact, it looks correct. Since I'm only interested in that data, I don't really have a problem anymore ... – adm0n May 23 '19 at 08:14

1 Answers1

1

Workin' fine for me:

screenshot of paint.net showing square dimensions

System/build info:

  • Windows 10
  • GLFW 3.3
  • Monitor set to 1920x1200
  • 100% GUI scaling

Code:

#include <glad/glad.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <vector>
#include <iostream>

void CheckStatus( GLuint obj, bool isShader )
{
    GLint status = GL_FALSE, log[ 1 << 11 ] = { 0 };
    ( isShader ? glGetShaderiv : glGetProgramiv )( obj, isShader ? GL_COMPILE_STATUS : GL_LINK_STATUS, &status );
    if( status == GL_TRUE ) return;
    ( isShader ? glGetShaderInfoLog : glGetProgramInfoLog )( obj, sizeof( log ), NULL, (GLchar*)log );
    std::cerr << (GLchar*)log << "\n";
    std::exit( EXIT_FAILURE );
}

void AttachShader( GLuint program, GLenum type, const char* src )
{
    GLuint shader = glCreateShader( type );
    glShaderSource( shader, 1, &src, NULL );
    glCompileShader( shader );
    CheckStatus( shader, true );
    glAttachShader( program, shader );
    glDeleteShader( shader );
}

const char* const vert = 1 + R"GLSL(
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
    gl_Position =  vec4(aPos, 1.0f);
}
)GLSL";

const char* const frag = 1 + R"GLSL(
#version 330 core
out vec4 FragColor;
void main()
{
    FragColor = vec4(1.0f,1.0f,1.0f,1.0f);
}
)GLSL";

class Circle
{
public:
    static const int size = 6; 

    Circle()
    {
        std::vector<float> vertexData(3 * size); 
        // center 
        vertexData.at(0) = 0.0f;
        vertexData.at(1) = 0.0f;
        vertexData.at(2) = 0.0f;

        vertexData.at(3) = 0.5f;
        vertexData.at(5) = 0.0f;
        vertexData.at(4) = -0.5f;

        vertexData.at(6) = -0.5f;
        vertexData.at(8) = 0.0f;
        vertexData.at(7) = -0.5f;

        vertexData.at(9) = -0.5f;
        vertexData.at(11) = 0.0f;
        vertexData.at(10) = 0.5f;

        vertexData.at(12) = 0.5f;
        vertexData.at(14) = 0.0f;
        vertexData.at(13) = 0.5f;

        vertexData.at(15) = 0.5f;
        vertexData.at(17) = 0.0f;
        vertexData.at(16) = -0.5f;

        glGenBuffers(1, &VBO);
        glGenVertexArrays(1, &VAO);
        glBindVertexArray(VAO);

        float * dataArr = vertexData.data(); //The GLSL shader needs a C Array, this returns the pointer to the first array object used by std::vector
        int dataSize = vertexData.size();

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, dataSize * sizeof(float), dataArr, GL_STATIC_DRAW);

        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);

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

    void draw()
    {
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLE_FAN, 0, 3 * (size - 2));
        glBindVertexArray(0);
    }

private:
    unsigned int VBO, VAO;
};

int main( int, char** )
{
    glfwSetErrorCallback( []( int, const char* desc ) { std::cerr << desc << "\n"; std::exit( EXIT_FAILURE ); } );
    glfwInit();
    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
    glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE );
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
    GLFWwindow* window = glfwCreateWindow( 600, 600, "GLFW", NULL, NULL );
    glfwMakeContextCurrent( window );
    gladLoadGLLoader( (GLADloadproc)glfwGetProcAddress );

    Circle * circle = new Circle();

    GLuint prog = glCreateProgram();
    AttachShader( prog, GL_VERTEX_SHADER, vert );
    AttachShader( prog, GL_FRAGMENT_SHADER, frag );
    glLinkProgram( prog );
    CheckStatus( prog, false );
    glUseProgram( prog );

    while( !glfwWindowShouldClose( window ) )
    {
        glfwPollEvents();

        int w, h;
        glfwGetFramebufferSize( window, &w, &h );
        glViewport( 0, 0, w, h );

        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

        circle->draw();

        glfwSwapBuffers( window );
    }

    glfwTerminate();
}
genpfault
  • 51,148
  • 11
  • 85
  • 139