即使很难,OpenGL、SDL 和 GLSL 都不会抛出错误,没有绘制多边形

Posted

技术标签:

【中文标题】即使很难,OpenGL、SDL 和 GLSL 都不会抛出错误,没有绘制多边形【英文标题】:Even tough neither OpenGL nor SDL nor GLSL throws an error, there is no polygon that is drawn 【发布时间】:2017-10-22 08:39:23 【问题描述】:

我正在学习使用 SDL2 的 OpenGL,并关注 this tutorial,我已经来到了绘图多边形 -> 着色器部分。然而,虽然我已经完成了教程所指示的一切,但我无法从代码中获得任何输出,

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>

//Glew
#define GLEW_STATIC
#include <GL/glew.h>

//SDL headers
#include "SDL.h"
#include "SDL_opengl.h"

//OpenGL headers
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>

//Constants
#define SCREEN_H 800
#define SCREEN_W 600
#define SCREEN_POS_X 0
#define SCREEN_POS_Y 0
#define SCREEN_FLAGS SDL_WINDOW_SHOWN|SDL_WINDOW_INPUT_FOCUS|SDL_WINDOW_MOUSE_FOCUS|SDL_WINDOW_OPENGL
//SDL_WINDOWPOS_CENTERED
bool done = false;

SDL_Window * pWindow = NULL;
SDL_GLContext pGLContext = NULL;

//Methods
int Init(void );
void GameLoop();
void Render();
void EventTick();
void Quit(void );

    // Shader sources
const GLchar* vertexSource = R"glsl(
    #version 150 core
    in vec2 position;
    void main()
    
        gl_Position = vec4(position, 0.0, 1.0);
    
)glsl";

const GLchar* fragmentSource = R"glsl(
    #version 150 core
    out vec4 outColor;
    void main()
    
        outColor = vec4(1.0, 1.0, 1.0, 1.0);
    
)glsl";


int main(int argc, char const *argv[])

    Init();
    GameLoop();
    Quit();
    return 0;


int Init()

    if(SDL_Init(SDL_INIT_VIDEO) < 0)
    
        fprintf(stderr, "SDL_Error: %s\n", SDL_GetError());
        return -1;
    

    //Compatibility
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

    pWindow = SDL_CreateWindow("Main", SCREEN_POS_X, SCREEN_POS_Y, SCREEN_W, SCREEN_H, SCREEN_FLAGS);
    if (pWindow == NULL)
    
        fprintf(stderr, "SDL_Error: %s\n", SDL_GetError());
        return -1;
    

    pGLContext = SDL_GL_CreateContext(pWindow);

    glewExperimental = GL_TRUE;
    glewInit();


    return 0;


void GameLoop()

    printf("%s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
    printf("%s\n", glGetString(GL_VERSION));
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    float Vertices[] = 
        0.0f, 20.0f,
        20.0f, 0.0f,
        20.0f, 20.0f
    ;

    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexSource, NULL);
    glCompileShader(vertexShader);

    //Check the vertex shader compilation
    GLint status_vertex;
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status_vertex);
    if (status_vertex != GL_TRUE)
    
        char buffer[512];
        glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
        fprintf(stdout, "Vertex Shader: %s\n", buffer);
    

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
    glCompileShader(fragmentShader);

    //Check the fragment shader compilation
    GLint status_fragment;
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status_fragment);
    if (status_fragment != GL_TRUE)
    
        char buffer[512];
        glGetShaderInfoLog(fragmentShader, 512, NULL, buffer);
        fprintf(stdout, "Fragment Shader: %s\n", buffer);
    

    GLuint shaderProgram = glCreateProgram();
    if (shaderProgram == 0)
    
        fprintf(stderr, "glGetError: %u\n", glGetError());
    
    glBindAttribLocation(shaderProgram, 0, "position");
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glBindFragDataLocation(shaderProgram, 0, "outColor");
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);

    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posAttrib);

    GLint program_linked;
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &program_linked);
    if (program_linked != GL_TRUE)
    
        GLsizei log_length = 0;
        GLchar message[1024];
        glGetProgramInfoLog(shaderProgram, 1024, &log_length, message);
        fprintf(stdout, "%s\n", message);
    
    fprintf(stderr, "glGetError (End): %u\n", glGetError());
    fprintf(stderr, "SDL Error: %s\n", SDL_GetError());
    while(!done)
    
        EventTick();
        Render();
    
    fprintf(stderr, "glGetError (End): %u\n", glGetError());
    fprintf(stderr, "SDL Error: %s\n", SDL_GetError());

    glDeleteProgram(shaderProgram);
    glDeleteShader(fragmentShader);
    glDeleteShader(vertexShader);
    glDeleteBuffers(1, &vbo);
    glDeleteVertexArrays(1, &vao);


void Render()

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0f, 1.0f, 0.0f);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    SDL_GL_SwapWindow(pWindow);



void EventTick()

    SDL_Event s_GameEngEvent;
    while(SDL_PollEvent(&s_GameEngEvent))
    
        switch(s_GameEngEvent.type)
        
            case SDL_QUIT:
            
                fprintf(stdout, "SQL is quitting...\n");
                done = true;
            break;

            case SDL_KEYDOWN:
            
                switch(s_GameEngEvent.key.keysym.scancode)
                
                    case SDL_SCANCODE_ESCAPE:
                        
                        fprintf(stdout, "SQL is quitting...\n");
                        done = true;
                        break;
                    default:
                    break;
                
            break;
        
    



void Quit(void )

    //Destructions...
    SDL_GL_DeleteContext(pGLContext);
    SDL_DestroyWindow(pWindow);
    SDL_Quit();

我把几部分的代码一一拿来,和原来的code对比了一下,却一无所获。

如果有人可以检查有问题的部分在哪里,我将不胜感激。我的意思是我知道我没有尝试在上面编写好的代码,我试图专注于 OpenGL 的工作原理,但目前我的目标是找出我正在犯的错误。

注意: 我不确定这里是否可以接受这样的问题,如果可以,请关闭它。

编辑: 我正在使用 g++ 和 c++11 编译代码。

【问题讨论】:

如果您使用 C++ 编程,请不要添加 C 语言标签。 @Someprogrammerdude 我不确定,函数“fprintf, printf, ...”属于 C 语言,我一般都使用它们,所以这就是我添加 C 语言的动机。我的意思是我最初是一名 C 程序员,而且我经常这样做。 您正在使用 C++ 编程,您使用仅 C++ 的头文件,您使用仅 C++ 的表达式和文字。即使您使用来自 C 的旧函数,您仍然使用 C++ 进行编程。所以这是你应该使用的唯一标签。 @Someprogrammerdude 我明白了,谢谢指出。 【参考方案1】:

您尝试绘制的三角形超出了可见区域。默认情况下(这意味着没有应用任何投影/变换),可见区域在所有三个轴上从 -1 变为 1。代码中使用的三角形不与该区域相交,因此不会渲染任何内容。

除此之外:您正在调用核心配置文件中已弃用的 glColor3f 函数。这应该报告一个GL_INVALID_OPERATION,您很可能没有看到,因为错误检查仅在渲染循环结束时发生。您真的应该检查渲染循环中某处的错误。

【讨论】:

其实我也想过,但我不知道可见范围在所有轴上都在-1和1之间变化。非常感谢。

以上是关于即使很难,OpenGL、SDL 和 GLSL 都不会抛出错误,没有绘制多边形的主要内容,如果未能解决你的问题,请参考以下文章

可以将 GLSL 着色器应用于 SDL_Textures 吗?

不支持 GLSL 330 内核

Qt 4.6 OpenGL GLSL

OpenGL + SDL2 +计算着色器=黑屏

在 Ubuntu 上设置 OpenGL

GLSL 灯光/高光随相机移动