简体   繁体   中英

glm::ortho() streches when using glm::ortho(-width / 2, width / 2, -height/2, height, 0.1f, 10.0f);

I have been experimenting with 3d projection for a while,

but I've always used vertexes in -1 1 range I want to use units that are 1pixel big, so I use glm::ortho(-width / 2, width / 2, -height/2, height, 0.1f, 10.0f);

but that doesn't work

heres the code with glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, 0.1f,1.0f):

#include "Engine.h"
#include "vendor/stb/stb_image.h"

float width = 1200;
float height = 750;

// edits in imgui files have farouk comment before them


int main(void)
{
    initGLFW();

GLFWimage icon;
icon.pixels = stbi_load("data/Images/Icon.png", &icon.width, &icon.height, nullptr, 4);

GLFWimage image;
image.pixels = stbi_load("data/Images/Cursor.png", &image.width, &image.height, nullptr, 4);
GLFWcursor * cursor = glfwCreateCursor(&image, image.width / 2, image.height / 2);

glfwWindowHint(GLFW_SAMPLES, 6);
glEnable(GL_MULTISAMPLE);

Window window("OGL", width, height, MVP());
Renderer renderer;

renderer.GenerateFonts({"data/fonts/arial.ttf", "data/fonts/Pixelboy.ttf"}, {"arial", "roboto"}, {64, 64});

// set perspective projection & set xyz ranges from -1, 1 to respective ranges
window.mvp.projection = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, 0.1f, 10.0f);

window.createWindow("data/Images/Cursor.png", "data/Images/Icon.png");

glfwSetWindowIcon(window.window, 1, &icon);
glfwSetCursor(window.window, cursor);

stbi_image_free(image.pixels);
stbi_image_free(icon.pixels);

glfwMakeContextCurrent(window.window);
initGLEW(true);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

renderer.loadFonts({"arial", "roboto"});
initImGUI(window.window, "data/fonts/arial.ttf");

Shader shader("data/shaders/base.shader");


// TODO: Add Multiple Window Support (Window Manager)
// Addd .txt file for text with Characters map insteadt loaf Fonts
// texture in 3d space & 3d textures
// map -1, 1 to -width/2 , width/2


std::vector <Obj> cubes = {
{
        {
            { {-0.5, -0.5, -1.1}, {1,1,1,1} },
            { {-0.5, 0.5, -1.1}, {1,1,1,1} },
            { {0.5, 0.5, -1.1}, {1,1,1,1} },
            { {0.5, -0.5, -1.1}, {1,1,1,1} },

            { {-0.5, -0.5, -2.1}, {0,1,1,1} },
            { {-0.5, 0.5, -2.1}, {0,1,1,1} },
            { {0.5, 0.5, -2.1}, {0,1,1,1} },
            { {0.5, -0.5, -2.1}, {0,1,1,1} },

        },
        {
            0,1,2, 2,3,0, 4,5,6, 6,7,4, 0,4,5, 1,5,0
        },
        true
    }
};

float tx = 0;
float ty = 0;
float tz = 0;

while (!glfwWindowShouldClose(window.window) )
{
    glfwMakeContextCurrent(window.window);
    renderer.Clear({0.0, 0.0, 0.0, 1});


    // feed inputs to dear imgui, start new frame
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    renderer.Draw(shader, window.mvp, cubes);
    window.mvp.view = glm::translate(glm::mat4(1), glm::vec3(0, 0, -1.6)) * glm::rotate(glm::mat4(1), glm::radians(tx), glm::vec3(1,0,0)) * glm::rotate(glm::mat4(1), glm::radians(ty), glm::vec3(0,1,0)) * glm::rotate(glm::mat4(1), glm::radians(tz), glm::vec3(0,0,1));
    window.mvp.view = glm::translate(window.mvp.view, glm::vec3(0, 0, 1.6));
    renderer.Text(shader, MVP(glm::mat4(1.0), glm::mat4(1.0),glm::ortho(0.0, (double)width, 0.0, (double)height)), {(TextObj){"roboto", "FPS:" + std::to_string((int)ImGui::GetIO().Framerate), 0.01424501424f * height, 0.01424501424f * height, 0, 0.02849002849f * height, 0, {1,1,1,1}}});

    // render your GUI
    ImGui::Begin("Demo window");
    ImGui::Button("Hello!");
    ImGui::SliderFloat("x", &tx, 0, 360, "%.0f", 1.0f);
    ImGui::SliderFloat("y", &ty, 0, 360, "%.0f", 1.0f);
    ImGui::SliderFloat("z", &tz, 0, 360, "%.0f", 1.0f);
    ImGui::End();

    // Render dear imgui into screen
    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());


    int display_w, display_h;
    glfwGetFramebufferSize(window.window, &display_w, &display_h);
    glViewport(0, 0, display_w, display_h);
    glfwSwapBuffers(window.window);
    glfwSwapInterval(1);
    glfwPollEvents();
}

ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();

return 0;
}

and the output:

在此处输入图像描述

and heres the code with glm::ortho(-width / 2, width / 2, -height/2, height, 0.1f, 10.0f):

#include "Engine.h"
#include "vendor/stb/stb_image.h"

float width = 1200;
float height = 750;

// edits in imgui files have farouk comment before them


int main(void)
{
    initGLFW();
GLFWimage icon;
icon.pixels = stbi_load("data/Images/Icon.png", &icon.width, &icon.height, nullptr, 4);

GLFWimage image;
image.pixels = stbi_load("data/Images/Cursor.png", &image.width, &image.height, nullptr, 4);
GLFWcursor * cursor = glfwCreateCursor(&image, image.width / 2, image.height / 2);

glfwWindowHint(GLFW_SAMPLES, 6);
glEnable(GL_MULTISAMPLE);

Window window("OGL", width, height, MVP());
Renderer renderer;

renderer.GenerateFonts({"data/fonts/arial.ttf", "data/fonts/Pixelboy.ttf"}, {"arial", "roboto"}, {64, 64});

// set perspective projection & set xyz ranges from -1, 1 to respective ranges
window.mvp.projection = glm::ortho(-width / 2, width / 2, -height/2, height, 0.1f, 10.0f);

window.createWindow("data/Images/Cursor.png", "data/Images/Icon.png");

glfwSetWindowIcon(window.window, 1, &icon);
glfwSetCursor(window.window, cursor);

stbi_image_free(image.pixels);
stbi_image_free(icon.pixels);

glfwMakeContextCurrent(window.window);
initGLEW(true);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

renderer.loadFonts({"arial", "roboto"});
initImGUI(window.window, "data/fonts/arial.ttf");

Shader shader("data/shaders/base.shader");


// TODO: Add Multiple Window Support (Window Manager)
// Addd .txt file for text with Characters map insteadt loaf Fonts
// texture in 3d space & 3d textures
// map -1, 1 to -width/2 , width/2


std::vector <Obj> cubes = {
{
        {
            { {-300, -300, -1.1}, {1,1,1,1} },
            { {-300, 300, -1.1}, {1,1,1,1} },
            { {300, 300, -1.1}, {1,1,1,1} },
            { {300, -300, -1.1}, {1,1,1,1} },

            { {-300, -300, -2.1}, {0,1,1,1} },
            { {-300, 300, -2.1}, {0,1,1,1} },
            { {300, 300, -2.1}, {0,1,1,1} },
            { {300, -300, -2.1}, {0,1,1,1} },

        },
        {
            0,1,2, 2,3,0, 4,5,6, 6,7,4, 0,4,5, 1,5,0
        },
        true
    }
};

float tx = 0;
float ty = 0;
float tz = 0;

while (!glfwWindowShouldClose(window.window) )
{
    glfwMakeContextCurrent(window.window);
    renderer.Clear({0.0, 0.0, 0.0, 1});


    // feed inputs to dear imgui, start new frame
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    renderer.Draw(shader, window.mvp, cubes);
    window.mvp.view = glm::translate(glm::mat4(1), glm::vec3(0, 0, -1.6)) * glm::rotate(glm::mat4(1), glm::radians(tx), glm::vec3(1,0,0)) * glm::rotate(glm::mat4(1), glm::radians(ty), glm::vec3(0,1,0)) * glm::rotate(glm::mat4(1), glm::radians(tz), glm::vec3(0,0,1));
    window.mvp.view = glm::translate(window.mvp.view, glm::vec3(0, 0, 1.6));
    renderer.Text(shader, MVP(glm::mat4(1.0), glm::mat4(1.0),glm::ortho(0.0, (double)width, 0.0, (double)height)), {(TextObj){"roboto", "FPS:" + std::to_string((int)ImGui::GetIO().Framerate), 0.01424501424f * height, 0.01424501424f * height, 0, 0.02849002849f * height, 0, {1,1,1,1}}});

    // render your GUI
    ImGui::Begin("Demo window");
    ImGui::Button("Hello!");
    ImGui::SliderFloat("x", &tx, 0, 360, "%.0f", 1.0f);
    ImGui::SliderFloat("y", &ty, 0, 360, "%.0f", 1.0f);
    ImGui::SliderFloat("z", &tz, 0, 360, "%.0f", 1.0f);
    ImGui::End();

    // Render dear imgui into screen
    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());


    int display_w, display_h;
    glfwGetFramebufferSize(window.window, &display_w, &display_h);
    glViewport(0, 0, display_w, display_h);
    glfwSwapBuffers(window.window);
    glfwSwapInterval(1);
    glfwPollEvents();
}

ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();

return 0;
}

and the output: 在此处输入图像描述

notice that i chane the vertexes from 0.5 to 300 so thats not a problem

explanation of obj struct

{

// vertexes -> vbo

{ {-0.5, -0.5, -1.1}, {1,1,1,1} }, glm::vec3 pos, glm::vec4 col

{ {-0.5, 0.5, -1.1}, {1,1,1,1} },

{ {0.5, 0.5, -1.1}, {1,1,1,1} },

{ {0.5, -0.5, -1.1}, {1,1,1,1} },

{ {-0.5, -0.5, -2.1}, {0,1,1,1} },

{ {-0.5, 0.5, -2.1}, {0,1,1,1} },

{ {0.5, 0.5, -2.1}, {0,1,1,1} },

{ {0.5, -0.5, -2.1}, {0,1,1,1} },

},

{ // indexex -> ibo

0,1,2, 2,3,0, 4,5,6, 6,7,4, 0,4,5, 1,5,0

},

true // fill -> GL_TRIANGLES or GL_LINES

}

Thanks to @derhass for the clarification the cuboid that I was drawing was too thin and my Z far value was too short I've adjusted it to 1000.0f and now everything works great

here is his comment:

"The problem is that the cube becomes a line". There are no cubes in your vertex data, there is a cuboid sized 600x600x1, so if you look at it at certain angles, it will look very thin of course. And furthermore, you will run into clipping issues as your z range is only 10 units.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM