From 6be35badb2e320ca50d0f6df6f9ca998210dbdd8 Mon Sep 17 00:00:00 2001 From: chaoskagami Date: Tue, 30 Sep 2014 04:33:52 -0400 Subject: [PATCH] OpenGL code still not functional yet - but FBOs are *mostly* okay, code-wise, anyways. --- buildscripts/build.generic | 2 +- external/zero/include/ContextManager.hpp | 2 + external/zero/include/Zero.hpp | 1 + external/zero/src/ContextManager.cpp | 220 ++++++++++++++++++++++- external/zero/src/UDisplayable.cpp | 25 +-- vndc/include/Data.hpp | 2 +- vndc/src/Data.cpp | 4 +- vndc/src/Loop.cpp | 7 +- vndc/src/VNDC.cpp | 30 ++-- vndc/src/op_text.cpp | 2 +- 10 files changed, 259 insertions(+), 36 deletions(-) diff --git a/buildscripts/build.generic b/buildscripts/build.generic index 0285929..6ab687c 100755 --- a/buildscripts/build.generic +++ b/buildscripts/build.generic @@ -12,7 +12,7 @@ LIB=$ROOT/external/lib BIN=$ROOT/bin CXXFLAGS="-g `pkg-config sdl2 --cflags` `pkg-config SDL2_mixer --cflags` `pkg-config SDL2_image --cflags` `pkg-config SDL2_ttf --cflags`" -LDFLAGS="`pkg-config sdl2 --libs` `pkg-config SDL2_image --libs` `pkg-config SDL2_ttf --libs` `pkg-config SDL2_mixer --libs` -lGL" +LDFLAGS="-lSDL2 -lSDL2_mixer -lSDL2_image -lSDL2_ttf -lGL -lGLEW" INCLUDE="-I$ROOT/external/zero/include -I$ROOT/vndc/include" source buildscripts/mk diff --git a/external/zero/include/ContextManager.hpp b/external/zero/include/ContextManager.hpp index ca43ccf..1525ffd 100644 --- a/external/zero/include/ContextManager.hpp +++ b/external/zero/include/ContextManager.hpp @@ -104,6 +104,8 @@ class TextManager; // Forward decl bool accelerate; bool opengl_mode; + GLuint fg, bg, fg_tex, bg_tex; + bool StartQuit; AudioManager* audioMgr; diff --git a/external/zero/include/Zero.hpp b/external/zero/include/Zero.hpp index b99ccb2..c70d64b 100644 --- a/external/zero/include/Zero.hpp +++ b/external/zero/include/Zero.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #if SDL_BYTEORDER == SDL_BIG_ENDIAN diff --git a/external/zero/src/ContextManager.cpp b/external/zero/src/ContextManager.cpp index 5704621..aec0511 100644 --- a/external/zero/src/ContextManager.cpp +++ b/external/zero/src/ContextManager.cpp @@ -156,7 +156,6 @@ // OpenGL window. Note - a LOT functions different in this mode. void ContextManager::_InitWindowGL(int width, int height, bool fulls) { - opengl_mode = true; SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); @@ -175,6 +174,16 @@ glctx = SDL_GL_CreateContext(window); + glewExperimental = GL_TRUE; + glewInit(); + + if(glGenFramebuffers == NULL || glBindFramebuffer == NULL || glFramebufferTexture == NULL || glDrawBuffers == NULL) { + fprintf(stderr, "[ERR] Glew didn't load some extensions needed.\n"); + fprintf(stderr, "[ERR] I assume your card doesn't support them.\n"); + exit(-11); + } + + glEnable( GL_TEXTURE_2D ); glViewport( 0, 0, width, height ); @@ -190,6 +199,39 @@ glLoadIdentity(); vertCnt = new VertexController(this); + + // Create Renderable Textures. + // Unfortunately, GL is an asshole and I have no clue. + + glGenFramebuffers(1, &bg); + glBindFramebuffer(GL_FRAMEBUFFER, bg); + + glGenTextures(1, &bg_tex); + glBindTexture(GL_TEXTURE_2D, bg_tex); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, bg_tex, 0); + + GLenum colbuf_bg[1] = {GL_COLOR_ATTACHMENT0}; + glDrawBuffers(1, colbuf_bg); + + glGenFramebuffers(1, &fg); + glBindFramebuffer(GL_FRAMEBUFFER, fg); + + glGenTextures(1, &fg_tex); + glBindTexture(GL_TEXTURE_2D, fg_tex); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, fg_tex, 0); + + GLenum colbuf_fg[1] = {GL_COLOR_ATTACHMENT1}; + glDrawBuffers(1, colbuf_fg); } // Init window with a logical size and a real one. Determines which backend to use. @@ -213,6 +255,9 @@ this->surface_o = SDL_CreateRGBSurface(0, width_win, height_win, 32, RED_MASK, GREEN_MASK, BLUE_MASK, ALPHA_MASK); SDL_SetSurfaceBlendMode(this->surface_o, SDL_BLENDMODE_BLEND); } + else if (disp == OpenGL) { + _InitWindowLogicalGL(width_win, height_win, width_log, height_log, fulls); + } txtMgr = new TextManager(this); } @@ -274,6 +319,87 @@ } } + // OpenGL window. Note - a LOT functions different in this mode. + void ContextManager::_InitWindowLogicalGL(int width_win, int height_win, int width_log, int height_log, bool fulls) { + + opengl_mode = true; + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + + // Request OpenGL 3.0 context. Yes, not 3.1, 3.2, 4.0. THREE POINT O'. + // Why? I use the fixed function pipeline which is gonzo in >3.1 + // and I'm not about to learn a new api that consists of VBOs, FBOs, + // and shader code (which btw, is retarded.) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + + if(!fulls) + this->window = SDL_CreateWindow("Zero", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width_win, height_win, SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL); + else + this->window = SDL_CreateWindow("Zero", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width_win, height_win, SDL_WINDOW_FULLSCREEN|SDL_WINDOW_OPENGL); + + glctx = SDL_GL_CreateContext(window); + + glewExperimental = GL_TRUE; + glewInit(); + + if(glGenFramebuffers == NULL || glBindFramebuffer == NULL || glFramebufferTexture == NULL || glDrawBuffers == NULL) { + fprintf(stderr, "[ERR] Glew didn't load some extensions needed.\n"); + fprintf(stderr, "[ERR] I assume your card doesn't support them.\n"); + exit(-11); + } + + glEnable( GL_TEXTURE_2D ); + + glViewport( 0, 0, width_win, height_win ); + + glClear( GL_COLOR_BUFFER_BIT ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + + glOrtho(0.0f, width_win, height_win, 0.0f, -1.0f, 1.0f); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + vertCnt = new VertexController(this); + + fprintf(stderr, "[info] Generating FBOs...(bg) "); + + glGenFramebuffers(1, &bg); + glBindFramebuffer(GL_FRAMEBUFFER, bg); + + glGenTextures(1, &bg_tex); + glBindTexture(GL_TEXTURE_2D, bg_tex); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_log, height_log, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, bg_tex, 0); + + GLenum colbuf_bg[1] = {GL_COLOR_ATTACHMENT0}; + glDrawBuffers(1, colbuf_bg); + + glGenFramebuffers(1, &fg); + glBindFramebuffer(GL_FRAMEBUFFER, fg); + + glGenTextures(1, &fg_tex); + glBindTexture(GL_TEXTURE_2D, fg_tex); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_win, height_win, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, fg_tex, 0); + + GLenum colbuf_fg[1] = {GL_COLOR_ATTACHMENT1}; + glDrawBuffers(1, colbuf_fg); + + fprintf(stderr, "[info] OpenGL initialized.\n"); + } + // Clears the display to black. void ContextManager::Clear() { @@ -293,6 +419,18 @@ SDL_RenderClear(renderer); } else if (opengl_mode) { + glBindFramebuffer(GL_FRAMEBUFFER, this->bg); + glViewport(0,0,LOG_height,LOG_width); + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT); + + glBindFramebuffer(GL_FRAMEBUFFER, this->fg); + glViewport(0,0,WIN_height,WIN_width); + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0,0,WIN_height,WIN_width); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); } @@ -317,8 +455,13 @@ SDL_SetRenderTarget(renderer, NULL); } else if (opengl_mode) { + glBindFramebuffer(GL_FRAMEBUFFER, this->fg); + + glViewport(0,0,WIN_height,WIN_width); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); } else { SDL_FillRect(this->surface_o, NULL, SDL_MapRGBA(this->surface_o->format, 0, 0, 0, 0)); @@ -351,6 +494,65 @@ SDL_RenderPresent(renderer); } else if (opengl_mode) { + // Render prep. + + GLfloat x_tex, y_tex, x2_tex, y2_tex; + x_tex = 0.0f; + y_tex = 0.0f; + x2_tex = 1.0f; + y2_tex = 1.0f; + + + GLfloat x_box, y_box, x2_box, y2_box; + x_box = 0; + y_box = WIN_height; + x2_box = WIN_width; + y2_box = 0; + + glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); //Don't use special coloring + + glBindTexture( GL_TEXTURE_2D, bg_tex ); + + glBegin( GL_QUADS ); + //Bottom-left vertex (corner) + glTexCoord2f( x_tex, y_tex ); + glVertex3f( x_box, y2_box, 0.0f ); + + //Bottom-right vertex (corner) + glTexCoord2f( x2_tex, y_tex ); + glVertex3f( x2_box, y2_box, 0.0f ); + + //Top-right vertex (corner) + glTexCoord2f( x2_tex, y2_tex ); + glVertex3f( x2_box, y_box, 0.0f ); + + //Top-left vertex (corner) + glTexCoord2f( x_tex, y2_tex ); + glVertex3f( x_box, y_box, 0.0f ); + glEnd(); + + glBindTexture( GL_TEXTURE_2D, fg_tex ); + + glBegin( GL_QUADS ); + //Bottom-left vertex (corner) + glTexCoord2f( x_tex, y_tex ); + glVertex3f( x_box, y2_box, 0.0f ); + + //Bottom-right vertex (corner) + glTexCoord2f( x2_tex, y_tex ); + glVertex3f( x2_box, y2_box, 0.0f ); + + //Top-right vertex (corner) + glTexCoord2f( x2_tex, y2_tex ); + glVertex3f( x2_box, y_box, 0.0f ); + + //Top-left vertex (corner) + glTexCoord2f( x_tex, y2_tex ); + glVertex3f( x_box, y_box, 0.0f ); + glEnd(); + + glBindTexture( GL_TEXTURE_2D, 0 ); + SDL_GL_SwapWindow(window); } else { @@ -401,6 +603,9 @@ else if(opengl_mode) { GLuint in = ((GLuint*)inp)[0]; + glBindFramebuffer(GL_FRAMEBUFFER, this->bg); + glViewport(0,0,LOG_height,LOG_width); + // printf("[GL] (blit) in: %d\n", in); GLfloat x_tex, y_tex, x2_tex, y2_tex; @@ -456,6 +661,10 @@ glEnd(); glBindTexture( GL_TEXTURE_2D, 0 ); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0,0,WIN_height,WIN_width); + } else { SDL_BlitSurface((SDL_Surface*)inp, src, surface, dst); @@ -484,6 +693,9 @@ else if(opengl_mode) { GLuint in = ((GLuint*)inp)[0]; + glBindFramebuffer(GL_FRAMEBUFFER, this->fg); + glViewport(0,0,WIN_height,WIN_width); + GLfloat x, y, x2, y2; x = 1.0f / glrect->x; y = 1.0f / glrect->y; @@ -510,6 +722,12 @@ glTexCoord2f( x, y2 ); glVertex3i( dst->x, dst->y, 0.0f ); glEnd(); + + glBindTexture( GL_TEXTURE_2D, 0 ); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0,0,WIN_height,WIN_width); + } else { SDL_BlitSurface((SDL_Surface*)inp, src, surface_o, dst); diff --git a/external/zero/src/UDisplayable.cpp b/external/zero/src/UDisplayable.cpp index b2639f8..6c2618c 100644 --- a/external/zero/src/UDisplayable.cpp +++ b/external/zero/src/UDisplayable.cpp @@ -291,9 +291,9 @@ this->loc.x = (int)this->x; this->loc.y = (int)this->y; -// #ifdef DEBUG_OVERKILL + #ifdef DEBUG_OVERKILL printf("[UDisplayable::SetXY] x:%d y:%d\n", this->loc.x, this->loc.y); -// #endif + #endif } // Modifies the position on screen. Meant to avoid embedded retrievals. @@ -424,9 +424,9 @@ if (frameIndex == -1) { if(over) - ctx->OverlayBlit(bitmap, &src, &loc_adj, NULL); + ctx->OverlayBlit(bitmap, &src, &loc_adj, &src); else - ctx->Blit(bitmap, &src, &loc_adj, NULL); + ctx->Blit(bitmap, &src, &loc_adj, &src); return; } @@ -437,19 +437,10 @@ frameClip.w = frameWidth; frameClip.h = bmp_h; - if(ctx->GLMode()) { - if(over) - ctx->OverlayBlit(bitmap, &frameClip, &loc_adj, &src); // GL needs data that isn't inside of bitmap. - else - ctx->Blit(bitmap, &frameClip, &loc_adj, &src); // GL needs data that isn't inside of bitmap. - - } - else { - if(over) - ctx->OverlayBlit(bitmap, &frameClip, &loc_adj, NULL); - else - ctx->Blit(bitmap, &frameClip, &loc_adj, NULL); - } + if(over) + ctx->OverlayBlit(bitmap, &frameClip, &loc_adj, &src); + else + ctx->Blit(bitmap, &frameClip, &loc_adj, &src); } // Get SDL_Rect for collision calculation. In a base Displayable, it returns the image width. diff --git a/vndc/include/Data.hpp b/vndc/include/Data.hpp index 41105c6..e1dfd85 100644 --- a/vndc/include/Data.hpp +++ b/vndc/include/Data.hpp @@ -37,7 +37,7 @@ class DataContainer { bool verbose; int currentLine; bool skip_key_on; - bool sw_rendering; + int rendering_mode; bool fullscreen; bool eof; char* window_name; diff --git a/vndc/src/Data.cpp b/vndc/src/Data.cpp index 8b05151..654cb06 100644 --- a/vndc/src/Data.cpp +++ b/vndc/src/Data.cpp @@ -33,10 +33,10 @@ DataContainer::DataContainer() { currentLine = 0; skip_key_on = false; #ifdef USE_ANDROID - sw_rendering = true; + rendering_mode = 0; fullscreen = true; #else - sw_rendering = false; + rendering_mode = 1; fullscreen = false; #endif eof = false; diff --git a/vndc/src/Loop.cpp b/vndc/src/Loop.cpp index 2418d6e..18c41fe 100644 --- a/vndc/src/Loop.cpp +++ b/vndc/src/Loop.cpp @@ -39,7 +39,12 @@ void Loop() { void Setup() { // Init window - GetData()->ctx->InitWindowLogical(GetData()->physical_w, GetData()->physical_h, GetData()->screen_w, GetData()->screen_h, GetData()->fullscreen, (GetData()->sw_rendering ? Software : Accel2d )); + if (GetData()->rendering_mode == 0) + GetData()->ctx->InitWindowLogical(GetData()->physical_w, GetData()->physical_h, GetData()->screen_w, GetData()->screen_h, GetData()->fullscreen, Software); + else if (GetData()->rendering_mode == 1) + GetData()->ctx->InitWindowLogical(GetData()->physical_w, GetData()->physical_h, GetData()->screen_w, GetData()->screen_h, GetData()->fullscreen, Accel2d); + else if (GetData()->rendering_mode == 2) + GetData()->ctx->InitWindowLogical(GetData()->physical_w, GetData()->physical_h, GetData()->screen_w, GetData()->screen_h, GetData()->fullscreen, OpenGL); GetData()->window_name = (char*)calloc(sizeof(char), 400); sprintf(GetData()->window_name, "%s", "VNDC Interpreter "); diff --git a/vndc/src/VNDC.cpp b/vndc/src/VNDC.cpp index 4f502a4..f260b24 100644 --- a/vndc/src/VNDC.cpp +++ b/vndc/src/VNDC.cpp @@ -27,26 +27,32 @@ int main(int argc, char** argv) { bool newgame = false; char c; #ifdef USE_ANDROID - bool software = true; + int mode = 0; bool fulls = true; #else - bool software = false; + int mode = 1; bool fulls = false; #endif - while((c = getopt(argc, argv, "fwnbvx:y:d:m:s:ch")) != -1) { + while((c = getopt(argc, argv, "fr:nbvx:y:d:m:s:ch")) != -1) { switch(c) { case 'f': printf("[info] Starting in fullscreen mode.\n"); fulls = true; break; - case 'w': - #ifdef USE_ANDROID - printf("[info] Forcing Hardware Acceleration.\n"); - #else - printf("[info] Utilizing Software Rendering.\n"); - #endif - software = !software; + case 'r': + if(!strcmp(optarg, "sdlsw")) { + printf("[info] Using SDL software backend.\n"); + mode = 0; + } + if(!strcmp(optarg, "sdlhw")) { + printf("[info] Using SDL hardware backend.\n"); + mode = 1; + } + if(!strcmp(optarg, "gl")) { + printf("[info] Using OpenGL backend. (note - experimental)\n"); + mode = 2; + } break; case 'n': printf("[info] New game, not reloading save.\n"); @@ -85,7 +91,7 @@ int main(int argc, char** argv) { break; case 'h': printf("-x size -y size\tStretch display window to WxH\n"); - printf("-w\t\tUse Software Rendering (on android: force HW render)\n"); + printf("-r mode\t\tUse render mode (sdlsw, sdlhw, gl)\n"); printf("-f\t\tFullscreen mode.\n"); printf("-n\t\tNew Game. Do not reload default save.\n"); printf("-d dir\t\tChange to directory/Run game in directory\n"); @@ -120,7 +126,7 @@ int main(int argc, char** argv) { GetData()->vndc_enabled = vndc_extensions; GetData()->verbose = enable_v; - GetData()->sw_rendering = software; + GetData()->rendering_mode = mode; GetData()->fullscreen = fulls; if(debug_enable) { diff --git a/vndc/src/op_text.cpp b/vndc/src/op_text.cpp index de37750..d889271 100644 --- a/vndc/src/op_text.cpp +++ b/vndc/src/op_text.cpp @@ -73,7 +73,7 @@ void op_text(char* string) { op_cleartext(); for(int i=0; i < lines; i++) { - printf("[br] %s\n", ptrs[i]); + //printf("[br] %s\n", ptrs[i]); txt->Render(ptrs[i], GetData()->text_x, GetData()->text_y); GetData()->text_y += GetData()->text_gap; } -- 2.39.5