Merge pull request #186 from Wargus/tim/fix-screenshots-with-shaders
Fixes for screenshot code with opengl
This commit is contained in:
commit
fc2bc028d5
3 changed files with 67 additions and 10 deletions
src
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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, ¶ms);
|
||||
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, ¶ms);
|
||||
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, ¶ms);
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue