OpenGL绘制全屏

Posted

技术标签:

【中文标题】OpenGL绘制全屏【英文标题】:OpenGL draw full of screen 【发布时间】:2017-10-22 01:18:20 【问题描述】:

我正在尝试在完整窗口中绘制 2D 足球场。但是,它的左右两侧会出现黑条:

这是我的代码:

#include <OpenGL/gl.h> // include GLEW and new version of GL on Windows
#include <GLFW/glfw3.h> // GLFW helper library
#include <stdio.h>
#include <math.h>

void Soccer_Field();

int main() 
    // start GL context and O/S window using the GLFW helper library
    if (!glfwInit()) 
        fprintf(stderr, "ERROR: could not start GLFW3\n");
        return 1;
    

    // uncomment these lines if on Apple OS X
    /*glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);*/

    GLFWwindow* window = glfwCreateWindow(640, 480, "Soccer field", NULL, NULL);
    if (!window) 
        fprintf(stderr, "ERROR: could not open window with GLFW3\n");
        glfwTerminate();
        return 1;
    
    glfwMakeContextCurrent(window);

    // get version info
    const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
    const GLubyte* version = glGetString(GL_VERSION); // version as a string
    printf("Renderer: %s\n", renderer);
    printf("OpenGL version supported %s\n", version);

    /* OTHER STUFF GOES HERE NEXT */
    while(!glfwWindowShouldClose(window)) 
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glLoadIdentity();
        glOrtho(0.0, 1, 0.0, 1, -1.0, 1.0);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();

       Soccer_Field();

        // update other events like input handling
        glfwPollEvents();
        // put the stuff we've been drawing onto the display
        glfwSwapBuffers(window);
    

    // close GL context and any other GLFW resources
    glfwTerminate();
    return 0;


void Soccer_Field (void)

    float x, y, ang, radius = 0.05;     // Not sure what the radius of the center circle should be?

    static float RAD_DEG = 57.296;

    glBegin (GL_QUADS);
    glColor3f  (0.20, 0.60, 0.20);                           // GreenYard
    glVertex2f (0.10, 0.10); glVertex2f (0.90, 0.10);
    glVertex2f (0.90, 0.90); glVertex2f (0.10, 0.90);
    glColor3f  (1.0, 1.0, 1.0);
    glVertex2f (0.90, 0.35); glVertex2f (0.83, 0.35);        // Inner White Quad - Right
    glVertex2f (0.83, 0.65); glVertex2f (0.90, 0.65);
    glVertex2f (0.10, 0.35); glVertex2f (0.17, 0.35);        // Inner White Quad - Left
    glVertex2f (0.17, 0.65); glVertex2f (0.10, 0.65);
    glEnd ();

    glColor3f (0.0, 0.0, 0.0);                                  // Change color to black

    glBegin (GL_LINES);
    glVertex2f (0.50, 0.10); glVertex2f (0.50, 0.90);        // Mid Line

    // Left side of the Ground
    glVertex2f (0.25, 0.25); glVertex2f (0.25, 0.75);        // Goal keeper front line
    glVertex2f (0.10, 0.75); glVertex2f (0.25, 0.75);        // Goal keeper left line
    glVertex2f (0.10, 0.25); glVertex2f (0.25, 0.25);        // Goal keeper right line

    // Right Side of the Ground
    glVertex2f (0.75, 0.25); glVertex2f (0.75, 0.75);        // Goal keeper front line
    glVertex2f (0.75, 0.25); glVertex2f (0.90, 0.25);        // Goal keeper left  Line
    glVertex2f (0.75, 0.75); glVertex2f (0.90, 0.75);        // Goal keeper right line
    glEnd ();

    glBegin (GL_LINE_LOOP);                                     // Circle at center of field
    for (ang = 0.0; ang < 360.0; ang += 10.0)  
        x = radius * cos(ang/RAD_DEG) + 1.0;
        y = radius * sin(ang/RAD_DEG) + 0.5;
        glVertex2f (x/2.0, y);
    
    glEnd ();

我该如何解决这个问题?我已尝试设置视口和其他内容,但无法正常工作。

希望有人能直截了当。

谢谢

【问题讨论】:

修改视图转换并放大 请注意...您对 OpenGL 的使用是前现代的,即 OpenGL 1.1 ...我建议您专注于学习使用顶点缓冲区对象和着色器的当前 OpenGL 方法,这实际上更容易,更灵活,更好地利用现代 GPU 硬件 使用现代 OpenGL 3.2+ 方法的一个免费副作用是,c++ 图形代码很容易移植到 WebGL,并且您在使用 c++ 或其他语言学习现代 OpenGL 的技能将允许您编写使用相同的现代 OpenGL 调用的 WebGL 中的新项目 由于人们在推动你学习现代 opengl,这里有一个很好的资源:@​​987654322@ 【参考方案1】:

投影矩阵描述了从场景的 3D 点到视口的 2D 点的映射。投影矩阵从视图空间变换到剪辑空间,剪辑空间中的坐标变换为 (-1, -1, -1) 到 (1, 1, 1) 范围内的归一化设备坐标 (NDC)通过与剪辑坐标的w 分量相除。 在正交投影中,眼睛空间中的坐标被线性映射到标准化的设备坐标。

正交投影矩阵由glOrtho 定义。使用此函数,您可以定义场景的视野。

由于所有几何图形都在 (0.1, 0.1) 到 (0.9, 0.9) 的范围内,因此您必须将其更改为:

GLdouble left   = 0.1;
GLdouble right  = 0.9; 
GLdouble bottom = 0.1;
GLdouble top    = 0.9; 
glOrtho(left, right, bottom, top, -1.0, 1.0);

第二种可能性是通过模型视图矩阵来缩放几何。您必须将几何从 [(0.1, 0.1), (0.9, 0.9)] 缩放 (glScale) 到由正交投影设置的范围 [(0.0, 0.0), (1.0, 1.0)] .请注意,在这种情况下,您必须“重新居中”几何图形 (glTranslate):

glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

GLdouble scaleX = (1.0 - 0.0) / (0.9 - 0.1);
GLdouble scaleY = (1.0 - 0.0) / (0.9 - 0.1); 
glScaled( scaleX, scaleY, 1.0 );
glTranslated( -0.1, -0.1, 0.0 );

【讨论】:

以上是关于OpenGL绘制全屏的主要内容,如果未能解决你的问题,请参考以下文章

如何优化多个全屏透明 iPhone OpenGL ES 图层的绘制?

我可以在 iPhone 上同时显示多个全屏 OpenGL 视图 (EAGLView) 吗?

在 OpenGL 的全屏四边形中将 QGraphicsScene 显示为纹理

绘制分层 OpenGL ES 内容的最佳方式是啥?

将 CIFilter 应用于 OpenGL 渲染到纹理

OpenGL独占模式全屏