Merge pull request from Wargus/tim/fix-screenshots-with-shaders

Fixes for screenshot code with opengl
This commit is contained in:
Tim Felgentreff 2016-03-15 07:21:21 +01:00
commit fc2bc028d5
3 changed files with 67 additions and 10 deletions

View file

@ -2,8 +2,14 @@
#define __SHADERS_H__
#ifdef USE_OPENGL
#define MAX_SHADERS 5
#ifndef __APPLE__
extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebuffer;
#else
#define glBindFramebuffer glBindFramebufferEXT
#endif
extern GLuint fullscreenFramebuffer;
extern unsigned ShaderIndex;
extern void LoadShaders();
extern bool LoadShaders();
extern bool LoadShaderExtensions();
extern void SetupFramebuffer();
extern void RenderFramebufferToScreen();

View file

@ -318,7 +318,19 @@ void SaveScreenshotPNG(const char *name)
/* set up the output control if you are using standard C streams */
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, Video.Width, Video.Height, 8,
int pngw, pngh;
#if defined(USE_OPENGL) || defined(USE_GLES)
if (UseOpenGL) {
pngw = Video.ViewportWidth;
pngh = Video.ViewportHeight;
}
else
#endif
{
pngw = Video.Width;
pngh = Video.Height;
}
png_set_IHDR(png_ptr, info_ptr, pngw, pngh, 8,
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
@ -328,15 +340,23 @@ void SaveScreenshotPNG(const char *name)
#if defined(USE_OPENGL) || defined(USE_GLES)
if (UseOpenGL) {
std::vector<unsigned char> pixels;
pixels.resize(Video.Width * Video.Height * 3);
unsigned char* pixels = new unsigned char[Video.ViewportWidth * Video.ViewportHeight * 3];
if (GLShaderPipelineSupported) {
// switch to real display
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}
#ifdef USE_OPENGL
glReadBuffer(GL_FRONT);
#endif
glReadPixels(0, 0, Video.Width, Video.Height, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]);
for (int i = 0; i < Video.Height; ++i) {
png_write_row(png_ptr, &pixels[(Video.Height - 1 - i) * Video.Width * 3]);
glReadPixels(0, 0, Video.ViewportWidth, Video.ViewportHeight, GL_RGB, GL_UNSIGNED_BYTE, pixels);
if (GLShaderPipelineSupported) {
// switch back to framebuffer
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fullscreenFramebuffer);
}
for (int i = 0; i < Video.Height; ++i) {
png_write_row(png_ptr, &pixels[(Video.ViewportHeight - 1 - i) * Video.ViewportWidth * 3]);
}
delete []pixels;
} else
#endif
{

View file

@ -394,27 +394,59 @@ void printProgramInfoLog(GLuint obj, const char* prefix)
unsigned ShaderIndex = 0;
extern void LoadShaders() {
extern bool LoadShaders() {
GLuint vs, fs;
GLint params;
fs = glCreateShader(GL_FRAGMENT_SHADER);
if (fs == 0) {
return false;
}
glShaderSource(fs, 1, (const char**)&(fragment_shaders[ShaderIndex]), NULL);
glCompileShader(fs);
glGetShaderiv(fs, GL_COMPILE_STATUS, &params);
if (params == GL_FALSE) {
glDeleteShader(fs);
return false;
}
//printShaderInfoLog(fs, "Fragment Shader");
ShaderIndex = (ShaderIndex + 1) % MAX_SHADERS;
vs = glCreateShader(GL_VERTEX_SHADER);
if (fs == 0) {
glDeleteShader(fs);
return false;
}
glShaderSource(vs, 1, (const char**)&vertex_shader, NULL);
glCompileShader(vs);
glGetShaderiv(fs, GL_COMPILE_STATUS, &params);
if (params == GL_FALSE) {
glDeleteShader(fs);
glDeleteShader(vs);
return false;
}
//printShaderInfoLog(vs, "Vertex Shader");
if (glIsProgram(fullscreenShader)) {
glDeleteProgram(fullscreenShader);
}
fullscreenShader = glCreateProgram();
if (fullscreenShader == 0) {
glDeleteShader(fs);
glDeleteShader(vs);
return false;
}
glAttachShader(fullscreenShader, vs);
glAttachShader(fullscreenShader, fs);
glLinkProgram(fullscreenShader);
glGetProgramiv(fullscreenShader, GL_LINK_STATUS, &params);
if (params == GL_FALSE) {
glDeleteShader(fs);
glDeleteShader(vs);
glDeleteProgram(fullscreenShader);
return false;
}
glDeleteShader(fs);
glDeleteShader(vs);
//printProgramInfoLog(fullscreenShader, "Shader Program");
return true;
}
extern bool LoadShaderExtensions() {
@ -449,8 +481,7 @@ extern bool LoadShaderExtensions() {
glDrawBuffers = (PFNGLDRAWBUFFERSPROC)(uintptr_t)SDL_GL_GetProcAddress("glDrawBuffers");
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glCheckFramebufferStatus");
if (glCreateShader && glGenFramebuffers && glGetUniformLocation && glActiveTextureProc) {
LoadShaders();
return true;
return LoadShaders();
} else {
return false;
}