framerate

This commit is contained in:
Frank DeMarco 2018-11-28 03:58:33 -05:00
parent 57ddb3dca0
commit 0686d226b3
3 changed files with 144 additions and 41 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@ main
glm/
sdl2-gfx/
screen.png
frames*/
local/

15
flat.vert Normal file
View File

@ -0,0 +1,15 @@
#version 130
in vec3 in_Position;
in vec2 vertexUV;
in vec3 in_Color;
out vec2 UV;
out vec4 ex_Color;
void main(void)
{
gl_Position = vec4(in_Position, 1);
UV = vertexUV;
ex_Color = vec4(in_Color, 1);
}

168
main.cpp
View File

@ -2,8 +2,11 @@
#include <math.h>
#include <vector>
#include <array>
#include <list>
#include <cstdlib>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#if defined(__LINUX__) || defined(__MINGW32__)
#define GL_GLEXT_PROTOTYPES
@ -79,26 +82,59 @@ int link_shader(GLuint program)
return 0;
}
void capture_screen(SDL_Window *window)
SDL_Surface* get_screen_surface(SDL_Window *window)
{
int w, h;
SDL_GetWindowSize(window, &w, &h);
unsigned char *pixels = (unsigned char *) malloc(24 * w * h);
printf("allocated %i bytes\n", 24 * w * h);
glReadPixels(0, 0, w, h, GL_BGR, GL_UNSIGNED_BYTE, pixels);
printf("read data into pixels memory\n");
GLenum format;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
format = GL_RGB;
#else
format = GL_BGR;
#endif
glReadPixels(0, 0, w, h, format, GL_UNSIGNED_BYTE, pixels);
SDL_Surface *surface = zoomSurface(
SDL_CreateRGBSurfaceFrom(pixels, w, h, 24, 3 * w,
0xff0000, 0x00ff00, 0x0000ff, 0), 1, -1, SMOOTHING_OFF);
printf("created RGB surface from pixels memory\n");
0, 0, 0, 0), 1, -1, SMOOTHING_OFF);
free(pixels);
return surface;
}
void capture_screen(SDL_Window *window)
{
SDL_Surface *surface = get_screen_surface(window);
IMG_SavePNG(surface, "screen.png");
printf("saved png to screen.png\n");
SDL_FreeSurface(surface);
free(pixels);
}
void start_recording(bool *is_recording)
{
*is_recording = true;
printf("start recording\n");
}
void end_recording(std::list<SDL_Surface*> frames, bool *is_recording)
{
*is_recording = false;
printf("end recording\n");
SDL_Surface *frame;
int ii = 0;
while (!frames.empty())
{
frame = frames.front();
char path[22];
sprintf(path, "frames/%03i.png", ii++);
IMG_SavePNG(frame, path);
frames.pop_front();
SDL_FreeSurface(frame);
}
}
int main(int argc, char *argv[])
{
setenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN", "0", true);
SDL_version version;
SDL_GetVersion(&version);
printf("SDL %d.%d.%d\n", version.major, version.minor, version.patch);
@ -120,7 +156,7 @@ int main(int argc, char *argv[])
SDL_WINDOWPOS_UNDEFINED,
sw,
sh,
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN);
if (window == NULL)
{
fprintf(stderr, "Could not create window: %s\n", SDL_GetError());
@ -346,47 +382,97 @@ int main(int argc, char *argv[])
glDepthFunc(GL_LESS);
int framerate = 60;
float frame_length = 1000.0 / framerate;
int last_frame_timestamp = SDL_GetTicks();
bool is_recording = false;
std::list<SDL_Surface*> frames;
int recording_capture_framerate = 100, last_capture_timestamp = SDL_GetTicks();
int frame_time_overflow = 0, capture_time_overflow = 0, ticks;
while (!done)
{
while (SDL_PollEvent(&event))
ticks = SDL_GetTicks();
if (ticks - last_frame_timestamp + frame_time_overflow >= frame_length)
{
if (event.type == SDL_QUIT)
printf("frame at %i, overflow %i\n", ticks, frame_time_overflow);
frame_time_overflow = ticks - last_frame_timestamp +
frame_time_overflow - frame_length;
last_frame_timestamp = ticks;
for (int ii = 1; frame_time_overflow > frame_length;
ii++, frame_time_overflow -= frame_length)
{
done = 1;
fprintf(stderr, "lost %i frame(s)\n", ii);
}
else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_F9)
while (SDL_PollEvent(&event))
{
capture_screen(window);
if (event.type == SDL_QUIT)
{
done = 1;
}
else if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.sym == SDLK_F9)
{
capture_screen(window);
}
else if (event.key.keysym.sym == SDLK_F10)
{
if (!is_recording)
{
start_recording(&is_recording);
}
else
{
end_recording(frames, &is_recording);
}
}
}
}
if (is_recording && ticks - last_capture_timestamp + capture_time_overflow >
recording_capture_framerate)
{
frames.push_back(get_screen_surface(window));
printf("added frame at %i\n", ticks);
capture_time_overflow = ticks - last_capture_timestamp + capture_time_overflow -
recording_capture_framerate;
last_capture_timestamp = ticks;
for (int ii = 1; capture_time_overflow > recording_capture_framerate;
ii++, capture_time_overflow -= recording_capture_framerate)
{
fprintf(stderr, "lost %i frame(s) during capture\n", ii);
}
}
// glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
// glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), diamond, GL_STATIC_DRAW);
// glClearColor((sin(r) + 1) / 2, (sin(r) + 1) / 2, .5, 1);
glClearColor(.7, .7, .5, 1);
r += .025;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glUseProgram(flat_program);
glBindTexture(GL_TEXTURE_2D, fake_texture_id);
glDisableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glDrawArrays(GL_TRIANGLES, 36, 6);
// printf("%s\n", glm::to_string(model).c_str());
model = glm::rotate(model, .0005f * frame_length, glm::vec3(0.0f, 1.0f, 0.0f));
mvp = projection * view * model;
glEnable(GL_DEPTH_TEST);
glUseProgram(world_program);
glUniformMatrix4fv(m_id, 1, GL_FALSE, &mvp[0][0]);
glBindTexture(GL_TEXTURE_2D, t_id);
glEnableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glVertexAttrib3f(2, 1, 1, 1);
glDrawArrays(GL_TRIANGLES, 0, 36);
//glFlush();
//SDL_Rect rect = {x++, 0, 240, 160};
//SDL_RenderCopy(renderer, texture, NULL, &rect);
//SDL_RenderPresent(renderer);
SDL_GL_SwapWindow(window);
}
// glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
// glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), diamond, GL_STATIC_DRAW);
// glClearColor((sin(r) + 1) / 2, (sin(r) + 1) / 2, .5, 1);
glClearColor(.7, .7, .5, 1);
r += .025;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glUseProgram(flat_program);
glBindTexture(GL_TEXTURE_2D, fake_texture_id);
glDisableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glDrawArrays(GL_TRIANGLES, 36, 6);
model = glm::rotate(model, .01f, glm::vec3(0.0f, 1.0f, 0.0f));
mvp = projection * view * model;
glEnable(GL_DEPTH_TEST);
glUseProgram(world_program);
glUniformMatrix4fv(m_id, 1, GL_FALSE, &mvp[0][0]);
glBindTexture(GL_TEXTURE_2D, t_id);
glEnableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glVertexAttrib3f(2, 1, 1, 1);
glDrawArrays(GL_TRIANGLES, 0, 36);
//glFlush();
//SDL_Rect rect = {x++, 0, 240, 160};
//SDL_RenderCopy(renderer, texture, NULL, &rect);
//SDL_RenderPresent(renderer);
SDL_GL_SwapWindow(window);
SDL_Delay(40);
SDL_Delay(15);
}
SDL_GL_DeleteContext(glcontext);
SDL_DestroyTexture(texture);