为什么这个简单的OpenGL ES 2.0 / SDL 2程序不能让我改变我的点精灵大小?

问题描述 投票:0回答:2

我正在研究一个简单的OpenGL ES 2.0程序(与SDL 2一起使事情变得更容易),并决定尝试点精灵。我能够让它们成功绘制,但我无法通过从顶点着色器输出gl_PointSize来改变它们的大小。从理论上讲,这应该是我必须做的一切。

以下代码片段是我的几乎没有C ++代码的简化版本(根本没有错误检查,但这是因为它没有任何问题)它演示了我如何尝试更改我的点精灵的大小。它已经在具有类似结果的两台相当不同的计算机上进行了测试(Linux,但是32位/软件渲染与64位/离散GPU),并且可以使用g ++与g++ main.cpp -lSDL2 -Wall -D_REENTRANT -lGLESv2进行编译。

#include <GLES2/gl2.h>
#include <SDL2/SDL.h>

struct myData {
    SDL_Window *window;
    SDL_GLContext context;
};

const GLchar vertex[] =
    "#version 100\n"
    "precision mediump float;\n"
    "void main()\n"
    "{\n"
    "   gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
    "   gl_PointSize = 128.0;\n"
    "}\0";

const GLchar fragment[] =
    "#version 100\n"
    "precision mediump float;\n"
    "void main()\n"
    "{\n"
    "   gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
    "}\0";

GLuint loadShader(GLuint program, GLenum type, const GLchar *shaderSrc) {
    GLuint shader;
    shader = glCreateShader(type);
    glShaderSource(shader, 1, &shaderSrc, NULL);
    glCompileShader(shader);
    glAttachShader(program, shader);
    return 0;
}

int sdlInit(myData *data) {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    data->window = SDL_CreateWindow("Demo", 0, 0, 512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
    data->context = SDL_GL_CreateContext(data->window);

    return 0;
}

int glInit(myData *data) {
    GLuint programObject;
    programObject = glCreateProgram();
    loadShader(programObject, GL_VERTEX_SHADER, vertex);
    loadShader(programObject, GL_FRAGMENT_SHADER, fragment);
    glLinkProgram(programObject);
    glUseProgram(programObject);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glViewport(0, 0, 512, 512);

    return 0;
}

int loopFunc(myData *data) {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        if (event.type == SDL_QUIT) {
            return 1;
        }
    }

    glClear(GL_COLOR_BUFFER_BIT);
    glDrawArrays(GL_POINTS, 0, 1);
    SDL_GL_SwapWindow(data->window);

    return 0;
}

void sdlQuit(myData *data) {
    SDL_GL_DeleteContext(data->context);
    SDL_DestroyWindow(data->window);
    SDL_Quit();
    return;
}

int main() {
    myData data;

    sdlInit(&data);

    glInit(&data);

    while (!loopFunc(&data));

    sdlQuit(&data);

    return 0;
}

运行时,程序应该按照我在顶点着色器中设置的值生成一个大小为128像素的点精灵。然而,当实际执行时,窗口中心的点精灵的大小恰好是一个像素。我究竟做错了什么?

c++ opengl-es opengl-es-2.0 sdl-2 point-sprites
2个回答
1
投票

我想你忘了初始化opengles2上下文。

SDL_Init(SDL_INIT_VIDEO);

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);

SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

0
投票

几件事:

  • 正如jumapico指出的那样,请确保您确实从SDL请求ES 2.0上下文,否则您可能会获得支持OpenGL ES的#version 100 GLSL代码的常规桌面OpenGL上下文;桌面OpenGL要求您通过gl_PointSize打开glEnable(GL_PROGRAM_POINT_SIZE)
  • 通过检查gl_PointSize,确保你的GL实现实际上支持128.0GL_ALIASED_POINT_SIZE_RANGE;规范只要求实现支持1.0到1.0的范围,任何高于该范围的都是可选的。

在这个Debian Buster盒子上工作得很好:

screenshot of large GL_POINT

SDL / OpenGL ES信息:

SDL compiled version: 2.0.9
SDL linked version  : 2.0.9
GL_VENDOR   : X.Org
GL_RENDERER : AMD Radeon (TM) R9 Fury Series (FIJI, DRM 3.27.0, 4.19.0-2-amd64, LLVM 7.0.1)
GL_VERSION  : OpenGL ES 3.2 Mesa 18.3.4
GLSL version: OpenGL ES GLSL ES 3.20
gl_PointSize min: 1
gl_PointSize max: 2048

码:

// g++ `pkg-config --cflags sdl2 glesv2` main.cpp `pkg-config --libs sdl2 glesv2`
#include <SDL.h>
#include <SDL_opengles2.h>
#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 100
precision mediump float;
void main()
{
    gl_Position = vec4( 0.0, 0.0, 0.0, 1.0 );
    gl_PointSize = 128.0;
}
)GLSL";

const char* const frag = 1 + R"GLSL(
#version 100
precision mediump float;
void main()
{
    gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
}
)GLSL";

int main( int argc, char** argv )
{
    SDL_Init( SDL_INIT_VIDEO );
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES );
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 0 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 );
    SDL_Window *window = SDL_CreateWindow( "SDL2", 0, 0, 640, 480, SDL_WINDOW_OPENGL );
    SDL_GLContext context = SDL_GL_CreateContext( window );

    // SDL info
    SDL_version compiled;
    SDL_version linked;
    SDL_VERSION( &compiled );
    SDL_GetVersion( &linked );
    std::cout << "SDL compiled version: " << (int)compiled.major << "." << (int)compiled.minor << "." << (int)compiled.patch << "\n";
    std::cout << "SDL linked version  : " << (int)linked.major << "." << (int)linked.minor << "." << (int)linked.patch << "\n";

    // GL info
    std::cout << "GL_VENDOR   : " << glGetString( GL_VENDOR ) << "\n";
    std::cout << "GL_RENDERER : " << glGetString( GL_RENDERER ) << "\n";
    std::cout << "GL_VERSION  : " << glGetString( GL_VERSION ) << "\n";
    std::cout << "GLSL version: " << glGetString( GL_SHADING_LANGUAGE_VERSION ) << "\n";
    float pointSizeRange[2] = { -1.0, -1.0 };
    glGetFloatv( GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange );
    std::cout << "gl_PointSize min: " << pointSizeRange[0] << "\n";
    std::cout << "gl_PointSize max: " << pointSizeRange[1] << "\n";

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

    bool running = true;
    while( running )
    {
        SDL_Event ev;
        while( SDL_PollEvent( &ev ) )
        {
            if( ev.type == SDL_QUIT )
            {
                running = false;
            }
        }

        glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
        glClear( GL_COLOR_BUFFER_BIT );
        glDrawArrays( GL_POINTS, 0, 1 );
        SDL_GL_SwapWindow( window );
    }

    SDL_GL_DeleteContext( context ); 
    SDL_DestroyWindow( window );
    SDL_Quit();
    return EXIT_SUCCESS;
}
© www.soinside.com 2019 - 2024. All rights reserved.