LINUX.ORG.RU

SDL, openGL - криво вертится


0

1

При попытке сделать rotate как через glm, так и внутри шейдера, првязываясь к времени, всё хорошо и плавно. Когда привязываю к нажатию клавиши, сначала реагирует только на её отпускание, потом и вовсе начинает тормозить. Причем это именно с вращением, с масштабированием и переносом всё хорошо. Теряюсь в догадках, с чем такое м.б. связано?

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <fstream>
#define GL3_PROTOTYPES 1
#include <GL3/gl3w.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <SDL/SDL.h>

SDL_Window *mainwindow;
SDL_GLContext maincontext;
GLuint translateLoc,shader,VBO,sinLoc;
float tm=0;
glm::mat4 translation;
void sdldie(const char *msg)
{
    printf("%s: %s\n", msg, SDL_GetError());
    SDL_Quit();
    exit(1);
}
void quit()
{
    glDeleteProgram(shader);
    SDL_GL_DeleteContext(maincontext);
    SDL_DestroyWindow(mainwindow);
    SDL_Quit();
}


void draw_scene()
{
  //  tm+=0.1;
    glClear ( GL_COLOR_BUFFER_BIT);
//    translation = glm::rotate(translation,glm::sin(tm),glm::vec3(0.0f,1.0f,0.0f));
    glUniformMatrix4fv(translateLoc,1,GL_FALSE,glm::value_ptr(translation));
    glUniform1f(sinLoc,tm);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);
    glDrawArrays(GL_TRIANGLES,0,3);
    glDisableVertexAttribArray(0);
    SDL_GL_SwapWindow(mainwindow);
    SDL_GL_SwapBuffers();
    SDL_Delay(20);
}
GLuint load_and_compile_shader(char *filename, GLenum shaderType)
{
    std::string line,total;
    std::ifstream shaderFile(filename);
    if(shaderFile.is_open())
    {
        while(shaderFile.good())
        {
            getline(shaderFile,line);
            total+=line+"\n";
        }
        shader = glCreateShader(shaderType);
        GLint Lengths[1];
        const GLchar *text = total.c_str();
        Lengths[0]= strlen(text);
        glShaderSource(shader,1,&text,Lengths);
        glCompileShader(shader);
        GLint result;
        glGetShaderiv(shader,GL_COMPILE_STATUS,&result);
        if(!result)
        {
            GLchar infoLog[1024];
            glGetShaderInfoLog(shader,sizeof(infoLog),NULL,infoLog);
            printf("Error while compiling shader: %s\n",infoLog);
            exit(-1);
        }
        else
            return shader;
    }
}

void prepare()
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
        sdldie("Unable to initialize SDL");
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    const SDL_VideoInfo *vi = SDL_GetVideoInfo();
    mainwindow = SDL_CreateWindow("stop", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        vi->current_w, vi->current_h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN);
    if (!mainwindow)
        sdldie("Unable to create window");
    maincontext = SDL_GL_CreateContext(mainwindow);
    SDL_GL_SetSwapInterval(1);
    gl3wInit();
    glClear ( GL_COLOR_BUFFER_BIT || GL_DEPTH_BUFFER_BIT);
    glGenBuffers(1,&VBO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    glm::vec3 modelData[3];
    float size = 0.2f;
    modelData[0] = glm::vec3(-size,-size,0.0f);
    modelData[1] = glm::vec3(size,-size,0.0f);
    modelData[2] = glm::vec3(size,size,0.0f);
    glBufferData(GL_ARRAY_BUFFER,sizeof(modelData),modelData,GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    GLuint myshader = glCreateProgram();
    GLuint vert = load_and_compile_shader("train.vert",GL_VERTEX_SHADER);
    GLuint frag = load_and_compile_shader("train.frag",GL_FRAGMENT_SHADER);
    glAttachShader(myshader,vert);
    glAttachShader(myshader,frag);
    glLinkProgram(myshader);
    translateLoc = glGetUniformLocation(myshader,"mTranslate");
    translation = glm::mat4(1.0f);
    GLint status;
    glGetProgramiv(myshader,GL_LINK_STATUS,&status);
    if(!status)
    {
        GLchar infoLog[1024];
        glGetProgramInfoLog(myshader,sizeof(infoLog),NULL,infoLog);
        printf("Error while linking shader: %s\n",infoLog);
    }
    glValidateProgram(myshader);
    glUseProgram(myshader);
}

void handle_keys(SDL_Event ev)
{
    switch(ev.key.keysym.sym)
    {
    case SDLK_ESCAPE:
        SDL_Quit();
        quit();
        exit(0);
        break;
    case SDLK_w:
        translation = glm::translate(translation,glm::vec3(0.0f,0.05f,0.0f));
        break;
    case SDLK_s:
        translation = glm::translate(translation,glm::vec3(0.0f,-0.05f,0.0f));
        break;
    case SDLK_a:
        translation = glm::translate(translation,glm::vec3(-0.05f,0.0f,0.0f));
        break;
    case SDLK_d:
        translation = glm::translate(translation,glm::vec3(0.05f,0.0f,0.0f));
        break;
    case SDLK_UP:
        translation = glm::rotate(translation,0.01f,glm::vec3(1.0f,0.0f,0.0f));
        break;
    case SDLK_DOWN:
        translation = glm::rotate(translation,-0.01f,glm::vec3(1.0f,0.0f,0.0f));
        break;
    case SDLK_RIGHT:
        translation = glm::rotate(translation,0.01f,glm::vec3(0.0f,1.0f,0.0f));
        break;
    case SDLK_LEFT:
        translation = glm::rotate(translation,-0.01f,glm::vec3(0.0f,1.0f,0.0f));
        break;
    case SDLK_q:
        translation = glm::scale(translation,glm::vec3(0.9f,0.9f,0.0f));
        break;
    case SDLK_e:
        translation = glm::scale(translation,glm::vec3(1.1f,1.1f,0.0f));
        break;
    }
}

int main(int argc, char *argv[])
{
    prepare();
    SDL_Event event;
    while( true ) {
        SDL_PollEvent( &event );
            switch( event.type ) {
            case SDL_KEYDOWN:
                handle_keys(event);
                break;
            default:
                draw_scene();
            }
        }
    return 0;
}

Шейдеры:

#version 330
in layout (location = 0) vec3 Position;
uniform mat4 mTranslate;
out vec4 FragColor;
void main(void)
{
    gl_Position = mTranslate * vec4(Position,1.0);
    FragColor = vec4(1.0,0.0,0.0,1.0);
}

in vec4 FragColor;

void main(void)
{
    gl_FragColor = FragColor;
}
★★★★

Уверен, что не теряешь нажатия клавиш? Рекомендую воспользоваться SDL_GetKeyState вместо событий

unC0Rr ★★★★★ ()
Ответ на: комментарий от unC0Rr

Спасибо, поправил, теперь нормально. Правда, не getKeyState, а keyboardState

wingear ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.