使用 OpenGL 时,我尝试渲染的正方形没有显示 [重复]

Posted

技术标签:

【中文标题】使用 OpenGL 时,我尝试渲染的正方形没有显示 [重复]【英文标题】:My square I'm trying to render isn't showing up when using OpenGL [duplicate] 【发布时间】:2020-11-22 01:00:05 【问题描述】:

我正在尝试使用两个三角形渲染一个正方形,然后应用一些变换,但无论出于何种原因,它都没有显示出来。代码如下:

#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>



#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace std;

#define WINDOW_TITLE "Modern OpenGL 3D Cube"


#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version "\n" #Source
#endif


GLint shaderProgram, windowWidth = 800, windowHeight = 600;
GLuint VBO, VAO, EBO, texture;


void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);




const GLchar* vertexShaderSource = GLSL(330,
    layout(location = 0) in vec3 position; 
layout(location = 1) in vec3 color;

out vec3 mobileColor; 

uniform mat4 shaderTransform;

void main() 
    gl_Position = shaderTransform * vec4(position, 1.0f); 
    mobileColor = color;
);


const GLchar* fragmentShaderSource = GLSL(330,
    in vec3 mobileColor; 
out vec4 gpuColor; 

void main() 
    gpuColor = vec4(mobileColor, 1.0);
);



//main program
int main(int argc, char** argv) 
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(windowWidth, windowHeight);
    glutCreateWindow(WINDOW_TITLE);
    glutReshapeFunc(UResizeWindow);

    glewExperimental = GL_TRUE;
    
    if (glewInit() != GLEW_OK) 
        cout << "Failed to initialize GLEW" << endl;
        return -1;
    

    UCreateShader();
    UCreateBuffers();

    
    glUseProgram(shaderProgram);

    glClearColor(0, 0, 0, 1);
    glutDisplayFunc(URenderGraphics);
    glutMainLoop();

    
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);

    return 0;



void UResizeWindow(int w, int h) 
    windowWidth = w;
    windowHeight = h;
    glViewport(0, 0, windowWidth, windowHeight);



void URenderGraphics(void) 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glBindVertexArray(VAO);

    glm::mat4 currentTransform; 

    
    currentTransform = glm::translate(currentTransform, glm::vec3(0.0f, 0.5f, 0.0f));

    
    currentTransform = glm::rotate(currentTransform, 45.0f, glm::vec3(0.0f, 0.0f, 1.0f));

    
    currentTransform = glm::scale(currentTransform, glm::vec3(0.5f, 0.5f, 0.5f));

    
    GLuint transformLocation = glGetUniformLocation(shaderProgram, "shaderTransform");
    glUniformMatrix4fv(transformLocation, 1, GL_FALSE, glm::value_ptr(currentTransform));

    
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0); 
    glutSwapBuffers(); 



void UCreateShader() 
    
    GLint vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader); 

    
    GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader); 
    glAttachShader(shaderProgram, fragmentShader); 
    glLinkProgram(shaderProgram); 

    
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);



void UCreateBuffers() 
    
    GLfloat vertices[] = 
        0.5f, 0.5f, 0.0f,   1, 0, 0, //top right vertex 0
        0.5f, -0.5f, 0.0f,    0, 1, 0, //bottom right vertex 1
        -0.5f, -0.5f, 0.0f,   0, 0, 1, //bottom left vertex 2
        -0.5f, 0.5f, 0.0f,    1, 0, 1 //top left vertex 3
    ;

    GLuint indices[] = 
        0, 1, 3, //triangle 1
        1, 2, 3 //triangle 2
    ;

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

    
    glBindVertexArray(VAO);

    
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1); 

    glBindVertexArray(0);

它编译和运行得很好,但它只打开一个空白窗口。该窗口上没有像通常那样显示图形。输出应该看起来像一个稍微旋转的正方形,围绕它的 z 轴旋转,但什么都没有出现。感谢所有帮助。

【问题讨论】:

没有人的广场第一次出现。 ;) 你的程序最后一个正常工作的版本是什么?换句话说,花一些时间尝试识别导致意外行为的最小代码更改。从头开始。你能得到 glClearColor、glClear 和 glutSwapBuffers 来输出清晰的颜色吗?从那里逐步添加功能。 问题解决了吗? 不.. 我完全删除了以前的项目,开始了一个新项目,为字母输入了相同的源代码字母,现在它呈现了一个没有以任何方式转换的白色方块。代码一点都没变.. 【参考方案1】:

当我得到臭名昭著的空白屏幕时,我检查了一些常见的事情:

在开始传递制服之前忘记致电 glUseProgram(shaderID)(完成) 将模型矩阵作为单位矩阵传递。 仔细检查 VBO/EBO 是否在内存中正确布局(此外,在此步骤中简化它们,即删除颜色属性,只传递位置,并在片段着色器中硬编码颜色) 做一些错误检查,看看使用glGetShaderInfoLogglGetProgramInfoLog的着色器编译是否有问题。

【讨论】:

我在 main() 中指定 glutDisplayFunc 之前调用了 glUseProgram(shaderProgram),这不是你说我忘了做的吗? 是的,应该没问题。【参考方案2】:

模型矩阵变量glm::mat4 currentTransform必须由Identity matrix初始化。

OpenGL Mathematics (GLM) API documentation 基于 OpenGL 着色语言 (GLSL) 并引用 The OpenGL Shading Language specification。

5.4.2 向量和矩阵构造函数

[...] 如果矩阵构造函数只有一个标量参数,则用于初始化矩阵对角线上的所有分量,其余分量初始化为 0.0。

一个Identity matrix可以通过单个参数1.0来初始化:

glm::mat4 currentTransform;

glm::mat4 currentTransform(1.0f);

【讨论】:

以上是关于使用 OpenGL 时,我尝试渲染的正方形没有显示 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL仅渲染黑色正方形

将纹理添加到 QT OpenGL 场景图

OpenGL 不渲染正方形

OpenGL ES在android上画一个正方形

Opengl渲染到纹理,但纹理为空

当我尝试从 vbo 获取颜色时,glDrawElements 没有输出