При попытке сделать 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;
}