implement scaling for OpenGL

This commit is contained in:
Ted John 2016-06-11 02:24:39 +01:00
parent 36c71c1398
commit b0b0b82fd1
9 changed files with 190 additions and 26 deletions

View File

@ -2,6 +2,7 @@
uniform ivec2 uScreenSize;
uniform ivec4 uBounds;
uniform ivec4 uTextureCoordinates;
in int vIndex;
@ -14,19 +15,19 @@ void main()
switch (vIndex) {
case 0:
pos = uBounds.xy;
fTextureCoordinate = vec2(0, 0);
fTextureCoordinate = uTextureCoordinates.xy;
break;
case 1:
pos = uBounds.zy;
fTextureCoordinate = vec2(1, 0);
fTextureCoordinate = uTextureCoordinates.zy;
break;
case 2:
pos = uBounds.zw;
fTextureCoordinate = vec2(1, 1);
fTextureCoordinate = uTextureCoordinates.zw;
break;
case 3:
pos = uBounds.xw;
fTextureCoordinate = vec2(0, 1);
fTextureCoordinate = uTextureCoordinates.xw;
break;
}

View File

@ -53,6 +53,7 @@
<ClCompile Include="src\drawing\engines\opengl\FillRectShader.cpp" />
<ClCompile Include="src\drawing\engines\opengl\OpenGLAPI.cpp" />
<ClCompile Include="src\drawing\engines\opengl\OpenGLDrawingEngine.cpp" />
<ClCompile Include="src\drawing\engines\opengl\OpenGLFramebuffer.cpp" />
<ClCompile Include="src\drawing\engines\opengl\OpenGLShaderProgram.cpp" />
<ClCompile Include="src\drawing\engines\SoftwareDrawingEngine.cpp" />
<ClCompile Include="src\drawing\font.c" />
@ -353,6 +354,7 @@
<ClInclude Include="src\drawing\engines\opengl\FillRectShader.h" />
<ClInclude Include="src\drawing\engines\opengl\GLSLTypes.h" />
<ClInclude Include="src\drawing\engines\opengl\OpenGLAPI.h" />
<ClInclude Include="src\drawing\engines\opengl\OpenGLFramebuffer.h" />
<ClInclude Include="src\drawing\engines\opengl\OpenGLShaderProgram.h" />
<ClInclude Include="src\drawing\font.h" />
<ClInclude Include="src\drawing\IDrawingContext.h" />

View File

@ -31,7 +31,10 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage")
glBindVertexArray(_vao);
glEnableVertexAttribArray(vIndex);
glVertexAttribIPointer(vIndex, 1, GL_INT, 0, 0);
glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr);
Use();
SetTextureCoordinates(0, 0, 1, 1);
}
DrawImageShader::~DrawImageShader()
@ -44,12 +47,13 @@ DrawImageShader::~DrawImageShader()
void DrawImageShader::GetLocations()
{
uScreenSize = GetUniformLocation("uScreenSize");
uClip = GetUniformLocation("uClip");
uBounds = GetUniformLocation("uBounds");
uTexture = GetUniformLocation("uTexture");
uScreenSize = GetUniformLocation("uScreenSize");
uClip = GetUniformLocation("uClip");
uBounds = GetUniformLocation("uBounds");
uTextureCoordinates = GetUniformLocation("uTextureCoordinates");
uTexture = GetUniformLocation("uTexture");
vIndex = GetAttributeLocation("vIndex");
vIndex = GetAttributeLocation("vIndex");
}
void DrawImageShader::SetScreenSize(sint32 width, sint32 height)
@ -67,6 +71,11 @@ void DrawImageShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bo
glUniform4i(uBounds, left, top, right, bottom);
}
void DrawImageShader::SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom)
{
glUniform4i(uTextureCoordinates, left, top, right, bottom);
}
void DrawImageShader::SetTexture(GLuint texture)
{
glActiveTexture(GL_TEXTURE0);

View File

@ -25,6 +25,7 @@ private:
GLuint uScreenSize;
GLuint uClip;
GLuint uBounds;
GLuint uTextureCoordinates;
GLuint uTexture;
GLuint vIndex;
@ -39,6 +40,7 @@ public:
void SetScreenSize(sint32 width, sint32 height);
void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom);
void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom);
void SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom);
void SetTexture(GLuint texture);
void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom);

View File

@ -57,6 +57,7 @@ static const char * TryLoadAllProcAddresses()
SetupOpenGLFunction(glClearColor);
SetupOpenGLFunction(glColor3f);
SetupOpenGLFunction(glColor4f);
SetupOpenGLFunction(glCullFace);
SetupOpenGLFunction(glDeleteTextures);
SetupOpenGLFunction(glDisable);
SetupOpenGLFunction(glDrawArrays);
@ -67,6 +68,7 @@ static const char * TryLoadAllProcAddresses()
SetupOpenGLFunction(glLoadIdentity);
SetupOpenGLFunction(glMatrixMode);
SetupOpenGLFunction(glOrtho);
SetupOpenGLFunction(glReadPixels);
SetupOpenGLFunction(glScalef);
SetupOpenGLFunction(glTexCoord2f);
SetupOpenGLFunction(glTexImage2D);
@ -79,19 +81,23 @@ static const char * TryLoadAllProcAddresses()
SetupOpenGLFunction(glAttachShader);
SetupOpenGLFunction(glBindBuffer);
SetupOpenGLFunction(glBindFragDataLocation);
SetupOpenGLFunction(glBindFramebuffer);
SetupOpenGLFunction(glBindVertexArray);
SetupOpenGLFunction(glBufferData);
SetupOpenGLFunction(glCompileShader);
SetupOpenGLFunction(glCreateProgram);
SetupOpenGLFunction(glCreateShader);
SetupOpenGLFunction(glDeleteBuffers);
SetupOpenGLFunction(glDeleteFramebuffers);
SetupOpenGLFunction(glDeleteProgram);
SetupOpenGLFunction(glDeleteShader);
SetupOpenGLFunction(glDeleteVertexArrays);
SetupOpenGLFunction(glDetachShader);
SetupOpenGLFunction(glEnableVertexAttribArray);
SetupOpenGLFunction(glFramebufferTexture2D);
SetupOpenGLFunction(glGetAttribLocation);
SetupOpenGLFunction(glGenBuffers);
SetupOpenGLFunction(glGenFramebuffers);
SetupOpenGLFunction(glGetProgramInfoLog);
SetupOpenGLFunction(glGetProgramiv);
SetupOpenGLFunction(glGetShaderInfoLog);

View File

@ -27,6 +27,7 @@
#define glClearColor __static__glClearColor
#define glColor3f __static__glColor3f
#define glColor4f __static__glColor4f
#define glCullFace __static__glCullFace
#define glDeleteTextures __static__glDeleteTextures
#define glDisable __static__glDisable
#define glDrawArrays __static__glDrawArrays
@ -37,6 +38,7 @@
#define glLoadIdentity __static__glLoadIdentity
#define glMatrixMode __static__glMatrixMode
#define glOrtho __static__glOrtho
#define glReadPixels __static__glReadPixels
#define glScalef __static__glScalef
#define glTexCoord2f __static__glTexCoord2f
#define glTexImage2D __static__glTexImage2D
@ -60,6 +62,7 @@
#undef glClearColor
#undef glColor3f
#undef glColor4f
#undef glCullFace
#undef glDeleteTextures
#undef glDisable
#undef glDrawArrays
@ -70,6 +73,7 @@
#undef glLoadIdentity
#undef glMatrixMode
#undef glOrtho
#undef glReadPixels
#undef glScalef
#undef glTexCoord2f
#undef glTexImage2D
@ -86,6 +90,7 @@ typedef void (APIENTRYP PFNGLCLEARPROC )(GLbitfield mask);
typedef void (APIENTRYP PFNGLCLEARCOLORPROC )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
typedef void (APIENTRYP PFNGLCOLOR3FPROC )(GLfloat red, GLfloat green, GLfloat blue);
typedef void (APIENTRYP PFNGLCOLOR4FPROC )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef void (APIENTRYP PFNGLCULLFACEPROC )(GLenum mode);
typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint *textures);
typedef void (APIENTRYP PFNGLDISABLEPROC )(GLenum cap);
typedef void (APIENTRYP PFNGLDRAWARRAYSPROC )(GLenum mode, GLint first, GLsizei count);
@ -96,6 +101,7 @@ typedef void (APIENTRYP PFNGLGENTEXTURESPROC )(GLsizei n, GLuint *textures);
typedef void (APIENTRYP PFNGLLOADIDENTITYPROC )(void);
typedef void (APIENTRYP PFNGLMATRIXMODEPROC )(GLenum mode);
typedef void (APIENTRYP PFNGLORTHOPROC )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val);
typedef void (APIENTRYP PFNGLREADPIXELSPROC )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * pixels);
typedef void (APIENTRYP PFNGLSCALEFPROC )(GLfloat x, GLfloat y, GLfloat z);
typedef void (APIENTRYP PFNGLTEXCOORD2FPROC )(GLfloat s, GLfloat t);
typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC )(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
@ -123,6 +129,7 @@ GLAPI_DECL PFNGLCLEARPROC glClear GLAP
GLAPI_DECL PFNGLCLEARCOLORPROC glClearColor GLAPI_SET;
GLAPI_DECL PFNGLCOLOR3FPROC glColor3f GLAPI_SET;
GLAPI_DECL PFNGLCOLOR4FPROC glColor4f GLAPI_SET;
GLAPI_DECL PFNGLCULLFACEPROC glCullFace GLAPI_SET;
GLAPI_DECL PFNGLDELETETEXTURESPROC glDeleteTextures GLAPI_SET;
GLAPI_DECL PFNGLDISABLEPROC glDisable GLAPI_SET;
GLAPI_DECL PFNGLDRAWARRAYSPROC glDrawArrays GLAPI_SET;
@ -133,6 +140,7 @@ GLAPI_DECL PFNGLGETERRORPROC glGetError GLAP
GLAPI_DECL PFNGLLOADIDENTITYPROC glLoadIdentity GLAPI_SET;
GLAPI_DECL PFNGLMATRIXMODEPROC glMatrixMode GLAPI_SET;
GLAPI_DECL PFNGLORTHOPROC glOrtho GLAPI_SET;
GLAPI_DECL PFNGLREADPIXELSPROC glReadPixels GLAPI_SET;
GLAPI_DECL PFNGLSCALEFPROC glScalef GLAPI_SET;
GLAPI_DECL PFNGLTEXCOORD2FPROC glTexCoord2f GLAPI_SET;
GLAPI_DECL PFNGLTEXIMAGE2DPROC glTexImage2D GLAPI_SET;
@ -145,19 +153,23 @@ GLAPI_DECL PFNGLVIEWPORTPROC glViewport GLAP
GLAPI_DECL PFNGLATTACHSHADERPROC glAttachShader GLAPI_SET;
GLAPI_DECL PFNGLBINDBUFFERPROC glBindBuffer GLAPI_SET;
GLAPI_DECL PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation GLAPI_SET;
GLAPI_DECL PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer GLAPI_SET;
GLAPI_DECL PFNGLBINDVERTEXARRAYPROC glBindVertexArray GLAPI_SET;
GLAPI_DECL PFNGLBUFFERDATAPROC glBufferData GLAPI_SET;
GLAPI_DECL PFNGLCOMPILESHADERPROC glCompileShader GLAPI_SET;
GLAPI_DECL PFNGLCREATEPROGRAMPROC glCreateProgram GLAPI_SET;
GLAPI_DECL PFNGLCREATESHADERPROC glCreateShader GLAPI_SET;
GLAPI_DECL PFNGLDELETEBUFFERSPROC glDeleteBuffers GLAPI_SET;
GLAPI_DECL PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers GLAPI_SET;
GLAPI_DECL PFNGLDELETEPROGRAMPROC glDeleteProgram GLAPI_SET;
GLAPI_DECL PFNGLDELETESHADERPROC glDeleteShader GLAPI_SET;
GLAPI_DECL PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays GLAPI_SET;
GLAPI_DECL PFNGLDETACHSHADERPROC glDetachShader GLAPI_SET;
GLAPI_DECL PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray GLAPI_SET;
GLAPI_DECL PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D GLAPI_SET;
GLAPI_DECL PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation GLAPI_SET;
GLAPI_DECL PFNGLGENBUFFERSPROC glGenBuffers GLAPI_SET;
GLAPI_DECL PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers GLAPI_SET;
GLAPI_DECL PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog GLAPI_SET;
GLAPI_DECL PFNGLGETPROGRAMIVPROC glGetProgramiv GLAPI_SET;
GLAPI_DECL PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog GLAPI_SET;

View File

@ -31,6 +31,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL()
#include "GLSLTypes.h"
#include "OpenGLAPI.h"
#include "OpenGLFramebuffer.h"
#include "DrawImageShader.h"
#include "DrawImageMaskedShader.h"
#include "FillRectShader.h"
@ -219,6 +220,10 @@ private:
OpenGLDrawingContext * _drawingContext;
DrawImageShader * _drawImageShader = nullptr;
OpenGLFramebuffer * _screenFramebuffer = nullptr;
OpenGLFramebuffer * _canvasFramebuffer = nullptr;
public:
SDL_Color Palette[256];
vec4f GLPalette[256];
@ -230,6 +235,8 @@ public:
~OpenGLDrawingEngine() override
{
delete _drawImageShader;
delete _drawingContext;
delete [] _bits;
@ -252,13 +259,18 @@ public:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Do not draw the unseen side of the primitives
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
_drawImageShader = new DrawImageShader();
}
void Resize(uint32 width, uint32 height) override
{
ConfigureBits(width, height, width);
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
ConfigureCanvas();
}
void SetPalette(SDL_Color * palette) override
@ -282,18 +294,10 @@ public:
void Draw() override
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
assert(_screenFramebuffer != nullptr);
assert(_canvasFramebuffer != nullptr);
// glMatrixMode(GL_PROJECTION_MATRIX);
// glLoadIdentity();
// glOrtho(0, _width, _height, 0, -1.0, 1.0);
// glMatrixMode(GL_MODELVIEW_MATRIX);
// glLoadIdentity();
// glScalef(1, -1.0f, 0);
// glTranslatef(-1.0f, -1.0f, 0);
// glScalef(2.0f / _width, 2.0f / _height, 0);
_canvasFramebuffer->Bind();
if (gIntroState != INTRO_STATE_NONE) {
intro_draw(&_bitsDPI);
@ -301,11 +305,24 @@ public:
window_update_all_viewports();
window_draw_all(&_bitsDPI, 0, 0, _width, _height);
window_update_all();
gfx_draw_pickedup_peep(&_bitsDPI);
rct2_draw(&_bitsDPI);
}
// Scale up to window
_screenFramebuffer->Bind();
sint32 width = _screenFramebuffer->GetWidth();
sint32 height = _screenFramebuffer->GetHeight();
_drawImageShader->Use();
_drawImageShader->SetScreenSize(width, height);
_drawImageShader->SetClip(0, 0, width, height);
_drawImageShader->SetTexture(_canvasFramebuffer->GetTexture());
_drawImageShader->SetTextureCoordinates(0, 1, 1, 0);
_drawImageShader->Draw(0, 0, width, height);
Display();
}
@ -347,7 +364,6 @@ public:
}
private:
void ConfigureBits(uint32 width, uint32 height, uint32 pitch)
{
size_t newBitsSize = pitch * height;
@ -398,6 +414,22 @@ private:
dpi->pitch = _pitch - width;
}
void ConfigureCanvas()
{
// Re-create screen framebuffer
delete _screenFramebuffer;
_screenFramebuffer = new OpenGLFramebuffer(_window);
// Re-create canvas framebuffer
delete _canvasFramebuffer;
_canvasFramebuffer = new OpenGLFramebuffer(_width, _height);
_drawImageShader->Use();
_drawImageShader->SetScreenSize(_width, _height);
_drawImageShader->SetClip(0, 0, _width, _height);
_drawImageShader->SetTexture(_canvasFramebuffer->GetTexture());
}
void Display()
{
SDL_GL_SwapWindow(_window);

View File

@ -0,0 +1,58 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#include <SDL_video.h>
#include "OpenGLFramebuffer.h"
constexpr GLuint BACKBUFFER_ID = 0;
OpenGLFramebuffer::OpenGLFramebuffer(SDL_Window * window)
{
_id = BACKBUFFER_ID;
_texture = 0;
SDL_GetWindowSize(window, &_width, &_height);
}
OpenGLFramebuffer::OpenGLFramebuffer(sint32 width, sint32 height)
{
_width = width;
_height = height;
glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_2D, _texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenFramebuffers(1, &_id);
glBindFramebuffer(GL_FRAMEBUFFER, _id);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0);
}
OpenGLFramebuffer::~OpenGLFramebuffer()
{
if (_id != BACKBUFFER_ID)
{
glDeleteTextures(1, &_texture);
glDeleteFramebuffers(1, &_id);
}
}
void OpenGLFramebuffer::Bind()
{
glBindFramebuffer(GL_FRAMEBUFFER, _id);
glViewport(0, 0, (GLsizei)_width, (GLsizei)_height);
}

View File

@ -0,0 +1,42 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#pragma once
#include "../../../common.h"
#include "OpenGLAPI.h"
struct SDL_Window;
class OpenGLFramebuffer
{
private:
GLuint _id;
GLuint _texture;
sint32 _width;
sint32 _height;
public:
explicit OpenGLFramebuffer(SDL_Window * window);
OpenGLFramebuffer(sint32 width, sint32 height);
~OpenGLFramebuffer();
GLuint GetWidth() const { return _width; }
GLuint GetHeight() const { return _height; }
GLuint GetTexture() const { return _texture; }
void Bind();
};