瀏覽代碼

build: move all games to a "games" subdirectory to clean up the root

directory layout mess.
master
Sam Hocevar 12 年之前
當前提交
0bfdffdd28
共有 18 個文件被更改,包括 1463 次插入0 次删除
  1. +2
    -0
      neercs/.gitignore
  2. +36
    -0
      neercs/Makefile.am
  3. +122
    -0
      neercs/neercs.cpp
  4. +34
    -0
      neercs/neercs.h
  5. +81
    -0
      neercs/neercs.vcxproj
  6. +49
    -0
      neercs/neercs.vcxproj.filters
  7. +36
    -0
      neercs/video/blurh.lolfx
  8. +36
    -0
      neercs/video/blurv.lolfx
  9. +31
    -0
      neercs/video/glow.lolfx
  10. +90
    -0
      neercs/video/postfx.lolfx
  11. +54
    -0
      neercs/video/radial.lolfx
  12. +607
    -0
      neercs/video/render.cpp
  13. +28
    -0
      neercs/video/render.h
  14. 二進制
      neercs/video/resource/map.png
  15. +20
    -0
      neercs/video/simple.lolfx
  16. +151
    -0
      neercs/video/text-render.cpp
  17. +31
    -0
      neercs/video/text-render.h
  18. +55
    -0
      neercs/video/text.lolfx

+ 2
- 0
neercs/.gitignore 查看文件

@@ -0,0 +1,2 @@
# Our binaries
neercs

+ 36
- 0
neercs/Makefile.am 查看文件

@@ -0,0 +1,36 @@

if USE_CACA
noinst_PROGRAMS = neercs
endif

neercs_SOURCES = \
neercs.cpp neercs.h \
\
video/render.cpp video/render.h \
video/text-render.cpp video/text-render.h \
video/blurh.lolfx video/blurv.lolfx video/glow.lolfx \
video/postfx.lolfx video/radial.lolfx video/simple.lolfx \
video/text.lolfx
neercs_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ @CACA_CFLAGS@
neercs_LDADD =
neercs_LDFLAGS = $(top_builddir)/src/liblol.a \
@LOL_LIBS@ @PIPI_LIBS@ @CACA_LIBS@ @UTIL_LIBS@ @PAM_LIBS@
neercs_DEPENDENCIES = $(top_builddir)/src/liblol.a

if USE_CACA
all-local: neercs$(EXEEXT)
test $(MAKE_FSELF) = no || make_fself neercs$(EXEEXT) neercs.self
endif

CLEANFILES = $(noinst_PROGRAMS:%$(EXEEXT)=%.self) \
$(noinst_PROGRAMS:%$(EXEEXT)=%.elf) \
$(noinst_PROGRAMS:%$(EXEEXT)=%.exe)

SUFFIXES = .lolfx
.lolfx.o:
(echo "char const *"; \
echo "lolfx_$(notdir $(basename $(filter %.lolfx, $^))) ="; \
$(SED) 's/"/\\"/g' $(filter %.lolfx, $^) | \
$(SED) 's/\([^\r]*\).*/"\1\\n"/'; \
echo ";") | $(CXXCOMPILE) -xc++ -c - -o $@


+ 122
- 0
neercs/neercs.cpp 查看文件

@@ -0,0 +1,122 @@
//
// Neercs
//
// Copyright: (c) 2012 Sam Hocevar <sam@hocevar.net>
//

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#if defined _WIN32
# include <direct.h>
#endif

#if defined _XBOX
# define _USE_MATH_DEFINES /* for M_PI */
# include <xtl.h>
# undef near /* Fuck Microsoft */
# undef far /* Fuck Microsoft again */
#elif defined _WIN32
# define _USE_MATH_DEFINES /* for M_PI */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# undef near /* Fuck Microsoft */
# undef far /* Fuck Microsoft again */
#else
# include <cmath>
#endif

#if USE_SDL && defined __APPLE__
# include <SDL_main.h>
#endif

#include <time.h>

#include <caca.h>

#include "core.h"
#include "loldebug.h"

using namespace std;
using namespace lol;

#include "neercs.h"
#include "video/render.h"

Neercs::Neercs()
: m_ready(false),
m_caca(caca_create_canvas(47, 32)),
m_render(new Render(m_caca)),
m_time(0.f)
{
Ticker::Ref(m_render);
}

void Neercs::TickGame(float seconds)
{
WorldEntity::TickGame(seconds);

m_time += seconds;

caca_set_color_ansi(m_caca, CACA_DEFAULT, CACA_DEFAULT);
caca_clear_canvas(m_caca);

caca_fill_ellipse(m_caca, 20+10 * lol::cos(m_time * 1.f), 10+10 * lol::sin(m_time * 1.f), 16+8 * lol::sin(m_time * 6.f), 12+6 * lol::cos(m_time * 5.f), '|');
caca_fill_ellipse(m_caca, 20+10 * lol::cos(m_time * 1.f), 10+10 * lol::sin(m_time * 1.f), 12+8 * lol::sin(m_time * 6.f), 8+6 * lol::cos(m_time * 5.f), ' ');

caca_set_color_ansi(m_caca, 2, CACA_DEFAULT);
int x1 = 12 + 10 * lol::cos(m_time * 5.f);
int y1 = 6 + 5 * lol::sin(m_time * 5.f);
int x2 = 30 + 5 * lol::cos(m_time * 8.f);
int y2 = 8 + 5 * lol::sin(m_time * 8.f);
int y3 = 8 + 5 * lol::cos(m_time * 5.f);
caca_draw_thin_line(m_caca, x1, y1, x2, y2);
caca_draw_thin_line(m_caca, 40, y3, x2, y2);
caca_draw_thin_line(m_caca, x1, y1, 40, y3);

int x3 = 13 + 7 * lol::cos(m_time * 3.f);
caca_set_color_ansi(m_caca, CACA_CYAN, CACA_BLUE);
caca_put_str(m_caca, x3, 3, " LOL WUT ");

int x4 = 6 + 5 * lol::cos(m_time * 2.f);
caca_set_color_ansi(m_caca, CACA_YELLOW, CACA_RED);
caca_put_str(m_caca, x4, 25, "Le Caca C'Est Surpuissant \\:D/");

caca_put_str(m_caca, 0, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
caca_put_str(m_caca, 0, 1, " !\"#$%&'()*+,-./0123456789");

if (Input::GetButtonState(27 /*SDLK_ESCAPE*/))
Ticker::Shutdown();

}

void Neercs::TickDraw(float seconds)
{
WorldEntity::TickDraw(seconds);
}

Neercs::~Neercs()
{
Ticker::Unref(m_render);
}

int main(int argc, char **argv)
{
Application app("Neercs", ivec2(800, 600), 60.0f);

#if defined _MSC_VER && !defined _XBOX
_chdir("..");
#elif defined _WIN32 && !defined _XBOX
_chdir("../..");
#endif

new Neercs();
new DebugFps(5, 5);
app.ShowPointer(false);

app.Run();

return EXIT_SUCCESS;
}


+ 34
- 0
neercs/neercs.h 查看文件

@@ -0,0 +1,34 @@
//
// Neercs
//
// Copyright: (c) 2012 Sam Hocevar <sam@hocevar.net>
//

#if !defined __NEERCS_H__
#define __NEERCS_H__

#include <caca.h>

#include "video/render.h"

class Neercs : public WorldEntity
{
public:
Neercs();
virtual ~Neercs();

char const *GetName() { return "<neercs>"; }

protected:
virtual void TickGame(float seconds);
virtual void TickDraw(float seconds);

private:
bool m_ready;
caca_canvas_t *m_caca;
Render *m_render;
float m_time;
};

#endif // __NEERCS_H__


+ 81
- 0
neercs/neercs.vcxproj 查看文件

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Xbox 360">
<Configuration>Debug</Configuration>
<Platform>Xbox 360</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Xbox 360">
<Configuration>Release</Configuration>
<Platform>Xbox 360</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="neercs.h" />
<ClInclude Include="video\render.h" />
<ClInclude Include="video\text-render.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="neercs.cpp" />
<ClCompile Include="video\render.cpp" />
<ClCompile Include="video\text-render.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\..\..\src\lolcore.vcxproj">
<Project>{9e62f2fe-3408-4eae-8238-fd84238ceeda}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<LolFxCompile Include="video\blurh.lolfx" />
<LolFxCompile Include="video\blurv.lolfx" />
<LolFxCompile Include="video\glow.lolfx" />
<LolFxCompile Include="video\postfx.lolfx" />
<LolFxCompile Include="video\radial.lolfx" />
<LolFxCompile Include="video\simple.lolfx" />
<LolFxCompile Include="video\text.lolfx" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{587FCCE9-1D8D-4398-B8B6-E8F4E9A92233}</ProjectGuid>
<ConfigurationType>Application</ConfigurationType>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(SolutionDir)\Lol.Core.Config.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(SolutionDir)\Lol.Fx.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)\Lol.Core.Vars.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<Import Project="$(SolutionDir)\Lol.Core.Rules.props" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(CacaIncludes);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>$(CacaDeps);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(CacaLibs);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(SolutionDir)\Lol.Fx.targets" />
</ImportGroup>
</Project>

+ 49
- 0
neercs/neercs.vcxproj.filters 查看文件

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="neercs.cpp" />
<ClCompile Include="video\render.cpp">
<Filter>video</Filter>
</ClCompile>
<ClCompile Include="video\text-render.cpp">
<Filter>video</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="neercs.h" />
<ClInclude Include="video\render.h">
<Filter>video</Filter>
</ClInclude>
<ClInclude Include="video\text-render.h">
<Filter>video</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="video">
<UniqueIdentifier>{8598edd6-ce35-4250-b16e-4237b34ebd2a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<LolFxCompile Include="video\blurh.lolfx">
<Filter>video</Filter>
</LolFxCompile>
<LolFxCompile Include="video\blurv.lolfx">
<Filter>video</Filter>
</LolFxCompile>
<LolFxCompile Include="video\glow.lolfx">
<Filter>video</Filter>
</LolFxCompile>
<LolFxCompile Include="video\postfx.lolfx">
<Filter>video</Filter>
</LolFxCompile>
<LolFxCompile Include="video\radial.lolfx">
<Filter>video</Filter>
</LolFxCompile>
<LolFxCompile Include="video\simple.lolfx">
<Filter>video</Filter>
</LolFxCompile>
<LolFxCompile Include="video\text.lolfx">
<Filter>video</Filter>
</LolFxCompile>
</ItemGroup>
</Project>

+ 36
- 0
neercs/video/blurh.lolfx 查看文件

@@ -0,0 +1,36 @@
-- GLSL.Vert --

#version 120

void main()
{
gl_Position=gl_Vertex;
gl_TexCoord[0]=gl_MultiTexCoord0;
}

-- GLSL.Frag --

#version 120

uniform sampler2D texture;
uniform vec2 screen_size;
uniform float time;
uniform float value;

float blur=value;

void main(void)
{
vec4 total=vec4(0.0);
vec2 p=gl_TexCoord[0].xy/screen_size;
total+=texture2D(texture,vec2(p.x-blur*4.0,p.y))*0.04;
total+=texture2D(texture,vec2(p.x-blur*3.0,p.y))*0.08;
total+=texture2D(texture,vec2(p.x-blur*2.0,p.y))*0.12;
total+=texture2D(texture,vec2(p.x-blur ,p.y))*0.16;
total+=texture2D(texture,vec2(p.x ,p.y))*0.20;
total+=texture2D(texture,vec2(p.x+blur ,p.y))*0.16;
total+=texture2D(texture,vec2(p.x+blur*2.0,p.y))*0.12;
total+=texture2D(texture,vec2(p.x+blur*3.0,p.y))*0.08;
total+=texture2D(texture,vec2(p.x+blur*4.0,p.y))*0.04;
gl_FragColor=total;
}

+ 36
- 0
neercs/video/blurv.lolfx 查看文件

@@ -0,0 +1,36 @@
-- GLSL.Vert --

#version 120

void main()
{
gl_Position=gl_Vertex;
gl_TexCoord[0]=gl_MultiTexCoord0;
}

-- GLSL.Frag --

#version 120

uniform sampler2D texture;
uniform vec2 screen_size;
uniform float time;
uniform float value;

float blur=value;

void main(void)
{
vec4 total=vec4(0.0);
vec2 p=gl_TexCoord[0].xy/screen_size;
total+=texture2D(texture,vec2(p.x,p.y-blur*4.0))*0.04;
total+=texture2D(texture,vec2(p.x,p.y-blur*3.0))*0.08;
total+=texture2D(texture,vec2(p.x,p.y-blur*2.0))*0.12;
total+=texture2D(texture,vec2(p.x,p.y-blur ))*0.16;
total+=texture2D(texture,vec2(p.x,p.y ))*0.20;
total+=texture2D(texture,vec2(p.x,p.y+blur ))*0.16;
total+=texture2D(texture,vec2(p.x,p.y+blur*2.0))*0.12;
total+=texture2D(texture,vec2(p.x,p.y+blur*3.0))*0.08;
total+=texture2D(texture,vec2(p.x,p.y+blur*4.0))*0.04;
gl_FragColor=total;
}

+ 31
- 0
neercs/video/glow.lolfx 查看文件

@@ -0,0 +1,31 @@
-- GLSL.Vert --

#version 120

void main()
{
gl_Position=gl_Vertex;
gl_TexCoord[0]=gl_MultiTexCoord0;
}

-- GLSL.Frag --

#version 120

uniform sampler2D texture;
uniform sampler2D texture_prv;
uniform vec2 screen_size;
uniform float time;
uniform float step;
uniform float value1;
uniform float value2;

void main(void)
{
vec2 p=gl_TexCoord[0].xy;
vec4 source=texture2D(texture_prv,p);
vec4 glow=texture2D(texture,p);
source=smoothstep(step,1.0,source);
vec4 color=glow*value1+source*value2;
gl_FragColor=color;
}

+ 90
- 0
neercs/video/postfx.lolfx 查看文件

@@ -0,0 +1,90 @@
-- GLSL.Vert --

#version 120

void main()
{
gl_Position=gl_Vertex;
gl_TexCoord[0]=gl_MultiTexCoord0;
}

-- GLSL.Frag --

#version 120

uniform sampler2D texture;
uniform vec2 screen_size;
uniform float time;
uniform float flash;
uniform float value;
uniform float deform;
uniform bool scanline;
uniform float sync;

const float PI=3.14159265358979323846;
float lens=PI/(deform+sync*0.0625);

vec2 zoom(in vec2 p,in float radius)
{
float zoom=1.5-(radius*cos(p.x*PI/lens)+radius*cos(p.y*PI/lens));
return vec2(p.x*zoom-0.5,p.y*zoom-0.5);
}

vec3 get_color(in sampler2D tex,in vec2 p)
{
return (p.x<-1.0||p.x>0.0||p.y<-1.0||p.y>0.0)?vec3(0.0,0.0,0.0):texture2D(tex,p).xyz;
}

float rand(in vec2 p)
{
return fract(sin(dot(p.xy,vec2(12.9898,78.233)))*43758.5453);
}

void main(void)
{
vec2 q=gl_TexCoord[0].xy;
vec2 p=-1.0+2.0*gl_TexCoord[0].xy;
p.y+=0.025*sync;
vec2 z =zoom(p,0.5250);
vec2 z1=zoom(p,0.5225);
vec2 z2=zoom(p,0.5275);
float g=(2.0-cos(PI/lens/2.0+z.x*PI/lens)-cos(PI/lens/2.0+z.y*PI/lens))*32.0;

float rnd1=rand(vec2(p.x+time,p.y-time));
float rnd2=rand(vec2(p.x-time,p.y+time));
float d1=rnd1*value/float(screen_size.x);
float d2=rnd2*value/float(screen_size.y);

vec3 source;//=get_color(texture,z);
source.x=get_color(texture,vec2(z.x+d1,z.y)).x;
source.y=get_color(texture,vec2(z.x+d1,z.y)).y;
source.z=get_color(texture,vec2(z.x+d1,z.y)).z;

vec3 glass1=get_color(texture,z1);
vec3 glass2=get_color(texture,z2);

float v=value/float(screen_size.x)*g;

vec3 noise;
noise.x=get_color(texture,vec2(z.x+d1-v,z.y+d2)).x;
noise.y=get_color(texture,vec2(z.x+d1 ,z.y-d2)).y;
noise.z=get_color(texture,vec2(z.x+d1+v,z.y-d2)).z;

vec3 color=source+glass1*glass1*0.25+glass2*glass2*0.25+(scanline?noise:source);

color+=flash; // flash
if(scanline)
{
color-=0.0125*mod(z.y*4.0+time*0.25,1.0); // electron beam
color-=(vec3(rnd1,rnd1,rnd1)-vec3(rnd2,rnd2,rnd2))*0.1; // noise
color*=0.75+0.25*sin(z.x*float(screen_size.x*2)); // scanline w
color*=0.90+0.10*cos(z.y*float(screen_size.y))*sin(0.5+z.x*float(screen_size.x)); // scanline h
}
else
{
color*=0.675;
}
color=vec3(color.x*0.875,color.y*1.0,color.z*0.625);
color*=q.x*(6.0-q.x*6.0)*q.y*(6.0-q.y*6.0); // vignetting
gl_FragColor=vec4(color,1.0);
}

+ 54
- 0
neercs/video/radial.lolfx 查看文件

@@ -0,0 +1,54 @@
-- GLSL.Vert --

#version 120

void main()
{
gl_Position=gl_Vertex;
gl_TexCoord[0]=gl_MultiTexCoord0;
}

-- GLSL.Frag --

#version 120

uniform sampler2D texture;
uniform vec2 screen_size;
uniform float time;
uniform float value1;
uniform float value2;
uniform float color;

float PI=3.14159265358979323846;

vec3 deform(in vec2 p)
{
vec2 uv;
float zoom=0.5;
uv.x=p.x*zoom-0.5;
uv.y=p.y*zoom-0.5;
return texture2D(texture,uv).xyz;
}

void main(void)
{
int n=32;

vec2 p=-1.0+4.0*gl_TexCoord[0].xy;
vec2 s=p;
vec3 source=deform(s);

vec3 total=vec3(0,1.0,1.0);

vec2 d=-p/float(n*2);
float w=value1;
for(int i=0;i<n;i++)
{
vec3 c=deform(s);
vec3 data=c+vec3(c.x*color-p.x*color,c.z*color+p.y*color,c.y*color+p.x*color);
total+=data*w;
w*=value2;
s+=d;
}
gl_FragColor=vec4(source*0.625+total*0.025,1.0);
}

+ 607
- 0
neercs/video/render.cpp 查看文件

@@ -0,0 +1,607 @@
//
// Neercs
//

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#if defined _XBOX
# define _USE_MATH_DEFINES /* for M_PI */
# include <xtl.h>
#elif defined _WIN32
# define _USE_MATH_DEFINES /* for M_PI */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <string>

#include "core.h"
#include "lolgl.h"

using namespace std;
using namespace lol;

#include "../neercs.h"
#include "render.h"
#include "text-render.h"

extern char const *lolfx_blurh;
extern char const *lolfx_blurv;
extern char const *lolfx_glow;
extern char const *lolfx_postfx;
extern char const *lolfx_radial;
extern char const *lolfx_simple;

#define DEBUG 1 // debug flag //#if defined(_DEBUG)
#define PID M_PI/180.0f // pi ratio
#define CR 1.0f/256.0f // color ratio

/*
* Various variables
*/

int keys[256]; // keyboard array
int active = true; // window active flag
bool fullscreen = DEBUG?false:true; // fullscreen flag
bool paused = false; // pause flag
float nearplane = 0.1f; // nearplane
float farplane = 1000.0f; // farplane
bool polygon = true; // polygon mode
int polygon_fillmode = GL_FILL; // fill mode
/* window variable */
ivec2 screen_size; // screen size
int window_color = 32; // color depth
vec3 screen_color = CR * vec3(48, 56, 64); // screen color
/* object variable */
float main_angle = 0.0f; // main angle
float part_angle = 0.0f; // part angle
float fx_angle; // current angle
/* text variable */
char const *name = "cacaShell";
/* fs_quad variable */
float fs_quad_vtx[] = {-1.0f, 1.0f, 0, 1.0f, -1.0f, -1.0f, 0, 1.0f, 1.0f, -1.0f, 0, 1.0f, 1.0f, 1.0f, 0, 1.0f};
float fs_quad_tex[] = {0, 1.0f, 0, 0, 1.0f, 0, 1.0f, 1.0f};
/* flash variable */
bool flash_flag = false; // flag
float flash_angle = 0; // angle
float flash_value = 0; // value
float flash_speed = 1.5f; // speed
/* fade variable */
bool fade_flag = false; // flag
float fade_angle = 0; // angle
float fade_value = 0; // value
float fade_speed = 0.2f; // speed
/* sync variable */
bool sync_flag = false; // flag
float sync_angle = 0; // angle
float sync_value = 1.0f; // value
float sync_speed = 1.0f; // speed
/* beat variable */
bool beat_flag = false; // flag
float beat_angle = 0; // angle
float beat_value = 0; // value
float beat_speed = 2.0f; // speed
/* corner variable */
const int corner_n = 10; // polygon number
int corner_w = 24; // radius
int corner_vtx[corner_n*6];// vertex array
/* dos variable */
bool dos_flag = true; // flag
int dos_m; // margin
vec3 dos_color = CR * vec3(48, 56, 64); // color value
int dos_vtx[8]; // vertex array
ivec2 ratio_2d(2,4); // 2d ratio
ivec2 map_size(256,256); // texture map size
ivec2 font_size(8,8); // font size
vec2 car_size(1.0f/map_size.x*font_size.x, 1.0f/map_size.y*font_size.y);
int shell_vtx[8]; // vertex array
float shell_tex[] = {1.0f, 0.96875f, 1.0f, 1.0f, 0.78125f, 1.0f, 0.78125f, 0.96875f};
/* keyboard variable */
int key_code = 0; // keyboard code
/* common variable */
float value, angle, radius, scale, speed;
/* shader variable */
bool shader_flag = true;
bool shader_blur_flag = true;
bool shader_glow_flag = true;
bool shader_effect_flag = true;
bool shader_postfx_flag = true;

int glow_fbo_size = 2; // glow fbo size
float glow_smoothstep = 0.0f; // glow smoothstep value (try 0.025f)
float glow_mix_ratio1 = 0.5f; // glow mixing ratio
float glow_mix_ratio2 = 0.5f; // source mixing ratio

float radial_value1 = 2.0f;
float radial_value2 = 0.8f;
float radial_color = 0; // color

bool postfx_scanline = true;
float postfx_deform = 0.5f; // deformation ratio

Shader *shader_simple, *shader_blur_h, *shader_blur_v;
Shader *shader_glow, *shader_radial, *shader_postfx;
// shader variables
ShaderUniform shader_simple_texture;
ShaderUniform shader_blur_h_texture,
shader_blur_h_screen_size,
shader_blur_h_time,
shader_blur_h_value;
ShaderUniform shader_blur_v_texture,
shader_blur_v_screen_size,
shader_blur_v_time,
shader_blur_v_value;
ShaderUniform shader_glow_texture,
shader_glow_texture_prv,
shader_glow_screen_size,
shader_glow_time,
shader_glow_step,
shader_glow_value1,
shader_glow_value2;
ShaderUniform shader_radial_texture,
shader_radial_screen_size,
shader_radial_time,
shader_radial_value1,
shader_radial_value2,
shader_radial_color;
ShaderUniform shader_postfx_texture,
shader_postfx_texture_2d,
shader_postfx_screen_size,
shader_postfx_time,
shader_postfx_flash,
shader_postfx_value,
shader_postfx_deform,
shader_postfx_scanline,
shader_postfx_sync;

FrameBuffer *fbo_back, *fbo_front;
FrameBuffer *fbo_blur_h, *fbo_blur_v, *fbo_ping, *fbo_pong;

TextRender *text_render;

void fs_quad()
{
glLoadIdentity();
glDrawArrays(GL_QUADS, 0, 4);
}

void draw_shader_simple(FrameBuffer *fbo_output, int n)
{
shader_simple->Bind();
shader_simple->SetTexture(shader_simple_texture, fbo_output->GetTexture(), n);
fs_quad();
shader_simple->Unbind();
}

void rectangle(int x, int y, int w, int h)
{
glLoadIdentity();
glBegin(GL_QUADS);
glVertex2i(x+w, y );
glVertex2i(x , y );
glVertex2i(x , y+h);
glVertex2i(x+w, y+h);
glEnd();
}

void corner()
{
float vertex[6+corner_n*2];
vertex[0] = 0;
vertex[1] = 0;
for (int i = 1; i < corner_n + 1; i++)
{
int j = i*2;
float a = PID*90.0f/(corner_n-1)*(i-1);
vertex[j ] = corner_w-corner_w*cosf(a);
vertex[j+1] = corner_w-corner_w*sinf(a);
}
for (int i = 0; i < corner_n; i++)
{
int j = i*6;
int k = i*2;
corner_vtx[j ] = (int)vertex[0];
corner_vtx[j+1] = (int)vertex[1];
corner_vtx[j+2] = (int)vertex[2+k];
corner_vtx[j+3] = (int)vertex[3+k];
corner_vtx[j+4] = (int)vertex[4+k];
corner_vtx[j+5] = (int)vertex[5+k];
}
}

int InitGL(void)
{
glDepthMask(GL_TRUE); // do not write z-buffer
glEnable(GL_CULL_FACE); // disable cull face
glCullFace(GL_BACK); // don't draw front face

if (shader_flag)
{
/* Initialise framebuffer objects */
fbo_back = new FrameBuffer(screen_size);
fbo_front = new FrameBuffer(screen_size);
fbo_blur_h = new FrameBuffer(screen_size / glow_fbo_size);
fbo_blur_v = new FrameBuffer(screen_size / glow_fbo_size);
fbo_ping = new FrameBuffer(screen_size);
fbo_pong = new FrameBuffer(screen_size);
// shader simple
shader_simple = Shader::Create(lolfx_simple);
shader_simple_texture = shader_simple->GetUniformLocation("texture");
// shader blur horizontal
shader_blur_h = Shader::Create(lolfx_blurh);
shader_blur_h_texture = shader_blur_h->GetUniformLocation("texture");
shader_blur_h_screen_size = shader_blur_h->GetUniformLocation("screen_size");
shader_blur_h_time = shader_blur_h->GetUniformLocation("time");
shader_blur_h_value = shader_blur_h->GetUniformLocation("value");
// shader blur vertical
shader_blur_v = Shader::Create(lolfx_blurv);
shader_blur_v_texture = shader_blur_v->GetUniformLocation("texture");
shader_blur_v_screen_size = shader_blur_v->GetUniformLocation("screen_size");
shader_blur_v_time = shader_blur_v->GetUniformLocation("time");
shader_blur_v_value = shader_blur_v->GetUniformLocation("value");
// shader glow
shader_glow = Shader::Create(lolfx_glow);
shader_glow_texture = shader_glow->GetUniformLocation("texture");
shader_glow_texture_prv = shader_glow->GetUniformLocation("texture_prv");
shader_glow_screen_size = shader_glow->GetUniformLocation("screen_size");
shader_glow_time = shader_glow->GetUniformLocation("time");
shader_glow_step = shader_glow->GetUniformLocation("step");
shader_glow_value1 = shader_glow->GetUniformLocation("value1");
shader_glow_value2 = shader_glow->GetUniformLocation("value2");
// shader radial
shader_radial = Shader::Create(lolfx_radial);
shader_radial_texture = shader_radial->GetUniformLocation("texture");
shader_radial_screen_size = shader_radial->GetUniformLocation("screen_size");
shader_radial_time = shader_radial->GetUniformLocation("time");
shader_radial_value1 = shader_radial->GetUniformLocation("value1");
shader_radial_value2 = shader_radial->GetUniformLocation("value2");
shader_radial_color = shader_radial->GetUniformLocation("color");
// shader postfx
shader_postfx = Shader::Create(lolfx_postfx);
shader_postfx_texture = shader_postfx->GetUniformLocation("texture");
shader_postfx_texture_2d = shader_postfx->GetUniformLocation("texture_2d");
shader_postfx_screen_size = shader_postfx->GetUniformLocation("screen_size");
shader_postfx_time = shader_postfx->GetUniformLocation("time");
shader_postfx_flash = shader_postfx->GetUniformLocation("flash");
shader_postfx_value = shader_postfx->GetUniformLocation("value");
shader_postfx_deform = shader_postfx->GetUniformLocation("deform");
shader_postfx_scanline = shader_postfx->GetUniformLocation("scanline");
shader_postfx_sync = shader_postfx->GetUniformLocation("sync");
}

return true;
}

int CreateGLWindow(char const *title)
{
screen_size = Video::GetSize();
corner_w = 16*ratio_2d.x;
corner();
dos_m=12*ratio_2d.x;
dos_vtx[0]=font_size.x*ratio_2d.x/2.0f;
dos_vtx[1]=font_size.y*ratio_2d.y/2.0f;
dos_vtx[2]=font_size.x*ratio_2d.x/2.0f;
dos_vtx[3]=-font_size.y*ratio_2d.y/2.0f;
dos_vtx[4]=-font_size.x*ratio_2d.x/2.0f;
dos_vtx[5]=-font_size.y*ratio_2d.y/2.0f;
dos_vtx[6]=-font_size.x*ratio_2d.x/2.0f;
dos_vtx[7]=font_size.y*ratio_2d.y/2.0f;
shell_vtx[0]=dos_m+58*ratio_2d.x;
shell_vtx[1]=dos_m+(font_size.y+1)*ratio_2d.y;
shell_vtx[2]=dos_m+58*ratio_2d.x;
shell_vtx[3]=dos_m+ratio_2d.y;
shell_vtx[4]=dos_m+2*ratio_2d.x;
shell_vtx[5]=dos_m+ratio_2d.y;
shell_vtx[6]=dos_m+2*ratio_2d.x;
shell_vtx[7]=dos_m+(font_size.y+1)*ratio_2d.y;
InitGL();
return true;
}

Render::Render(caca_canvas_t *caca)
: m_caca(caca),
m_ready(false)
{
text_render = new TextRender(m_caca, font_size);
}

void Render::TickGame(float seconds)
{
Entity::TickGame(seconds);
}

void Render::TickDraw(float seconds)
{
Entity::TickDraw(seconds);

if (!m_ready)
{
CreateGLWindow("LOL");
text_render->Init();

m_ready = true;
}

// timer
if(!paused)
main_angle += seconds * 100.0f * PID;
if(sync_flag)
{
angle=(main_angle-sync_angle)*sync_speed;
sync_value=1.0f-sinf(angle);
if(angle>90.0f*PID)
{
sync_value=0;
sync_flag=false;
}
}
if(beat_flag)
{
angle=(main_angle-beat_angle)*beat_speed;
beat_value=1.0f-sinf(angle);
if(angle>90.0f*PID)
{
beat_value=0;
beat_flag=false;
}
}
if(flash_flag)
{
angle=(main_angle-flash_angle)*flash_speed;
flash_value=1.0f-sinf(angle);
if(angle>90.0f*PID)
{
flash_value=0;
flash_flag=false;
}
}
if(fade_flag)
{
angle=(main_angle-fade_angle)*fade_speed;
fade_value=1.0f-sinf(angle);
if(angle>90.0f*PID)
{
fade_value=0;
fade_flag=false;
}
}

Draw2D();
Draw3D();
}

void Render::Draw2D()
{
/* Draw text in an offline buffer */
text_render->Render();

if(shader_flag)
fbo_back->Bind();

glViewport(0, 0, screen_size.x, screen_size.y);

/* Clear the back buffer */
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_COLOR,GL_DST_ALPHA);
glClearColor(screen_color.r, screen_color.g, screen_color.b, 0.5f);
glClearDepth(1.0f); // set depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

ivec2 border_top = ivec2(dos_m, dos_m + font_size.y * ratio_2d.y)
+ ratio_2d * 2;
ivec2 border_bottom = ivec2(dos_m * 2, dos_m * 2 + font_size.y * ratio_2d.y)
+ ratio_2d * 2;
text_render->Blit(border_top, screen_size - border_bottom);

//if(polygon) glEnable(GL_LINE_SMOOTH); else glDisable(GL_LINE_SMOOTH);
glLineWidth((polygon)?2.0f:1.0f);
fx_angle=main_angle-part_angle;
if(polygon) glEnable(GL_TEXTURE_2D);

glMatrixMode(GL_PROJECTION);
mat4 m = mat4::ortho(0, screen_size.x, screen_size.y, 0, -1.f, 1.f);
glLoadMatrixf(&m[0][0]);
glMatrixMode(GL_MODELVIEW);
// draw dos
if(dos_flag)
{
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glColor3f(1.0f,1.0f,1.0f);
rectangle(dos_m,dos_m,screen_size.x-53*ratio_2d.x-dos_m*2,(font_size.y+2)*ratio_2d.y);
rectangle(screen_size.x-51*ratio_2d.x-dos_m,dos_m,22*ratio_2d.x,(font_size.y+2)*ratio_2d.y);
rectangle(screen_size.x-27*ratio_2d.x-dos_m,dos_m,22*ratio_2d.x,(font_size.y+2)*ratio_2d.y);
rectangle(screen_size.x-3*ratio_2d.x-dos_m,dos_m,3*ratio_2d.x,(font_size.y+2)*ratio_2d.y);
rectangle(dos_m,dos_m+(font_size.y+2)*ratio_2d.y,2*ratio_2d.x,screen_size.y-(font_size.y+2)*ratio_2d.y-dos_m*2);
rectangle(screen_size.x-2*ratio_2d.x-dos_m,dos_m+(font_size.y+2)*ratio_2d.y,2*ratio_2d.x,screen_size.y-(font_size.y+2)*ratio_2d.y-dos_m*2);
rectangle(dos_m+2*ratio_2d.x,screen_size.y-ratio_2d.y-dos_m,screen_size.x-4*ratio_2d.x-dos_m*2,ratio_2d.y);
glColor3f(dos_color.x,dos_color.y,dos_color.z);
rectangle(dos_m+2*ratio_2d.x,dos_m+ratio_2d.y,56*ratio_2d.x,font_size.y*ratio_2d.y);
rectangle(dos_m+60*ratio_2d.x,dos_m+2*ratio_2d.y,screen_size.x-115*ratio_2d.x-dos_m*2,2*ratio_2d.y);
rectangle(dos_m+60*ratio_2d.x,dos_m+6*ratio_2d.y,screen_size.x-115*ratio_2d.x-dos_m*2,2*ratio_2d.y);
rectangle(screen_size.x-49*ratio_2d.x-dos_m,dos_m+ratio_2d.y,14*ratio_2d.x,6*ratio_2d.y);
glColor3f(1.0f,1.0f,1.0f);
rectangle(screen_size.x-47*ratio_2d.x-dos_m,dos_m+2*ratio_2d.y,10*ratio_2d.x,4*ratio_2d.y);
glColor3f(0,0,0);
rectangle(screen_size.x-45*ratio_2d.x-dos_m,dos_m+3*ratio_2d.y,14*ratio_2d.x,6*ratio_2d.y);
rectangle(screen_size.x-25*ratio_2d.x-dos_m,dos_m+1*ratio_2d.y,14*ratio_2d.x,6*ratio_2d.y);
glColor3f(dos_color.x,dos_color.y,dos_color.z);
rectangle(screen_size.x-21*ratio_2d.x-dos_m,dos_m+2*ratio_2d.y,14*ratio_2d.x,7*ratio_2d.y);
glColor3f(1.0f,1.0f,1.0f);
rectangle(screen_size.x-19*ratio_2d.x-dos_m,dos_m+3*ratio_2d.y,10*ratio_2d.x,5*ratio_2d.y);
rectangle(screen_size.x-16*ratio_2d.x-dos_m,screen_size.y-9*ratio_2d.y-dos_m,14*ratio_2d.x,8*ratio_2d.y);
glColor3f(dos_color.x,dos_color.y,dos_color.z);
rectangle(screen_size.x-14*ratio_2d.x-dos_m,screen_size.y-8*ratio_2d.y-dos_m,12*ratio_2d.x,7*ratio_2d.y);
glColor3f(1.0f,1.0f,1.0f);
rectangle(screen_size.x-8*ratio_2d.x-dos_m,screen_size.y-8*ratio_2d.y-dos_m,8*ratio_2d.x,2*ratio_2d.y);
rectangle(screen_size.x-14*ratio_2d.x-dos_m,screen_size.y-5*ratio_2d.y-dos_m,4*ratio_2d.x,5*ratio_2d.y);
rectangle(screen_size.x-12*ratio_2d.x-dos_m,screen_size.y-7*ratio_2d.y-dos_m,2*ratio_2d.x,1*ratio_2d.y);
rectangle(screen_size.x-8*ratio_2d.x-dos_m,screen_size.y-5*ratio_2d.y-dos_m,4*ratio_2d.x,3*ratio_2d.y);
glEnable(GL_BLEND);
if(polygon) glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_ONE, GL_ONE);
glVertexPointer(2, GL_INT, 0, shell_vtx);
glTexCoordPointer(2, GL_FLOAT, 0, shell_tex);
glDrawArrays(GL_QUADS, 0, 4);
}
// draw corner
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glVertexPointer(2, GL_INT, 0, corner_vtx);
glLoadIdentity();
glColor3f(0, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, corner_n*3);
glTranslated(screen_size.x, 0, 0);
glRotated(90.0f, 0, 0, 1.0f);
glDrawArrays(GL_TRIANGLES, 0, corner_n*3);
glTranslated(screen_size.y, 0, 0);
glRotated(90.0f, 0, 0, 1.0f);
glDrawArrays(GL_TRIANGLES, 0, corner_n*3);
glTranslated(screen_size.x, 0, 0);
glRotated(90.0f, 0, 0, 1.0f);
glDrawArrays(GL_TRIANGLES, 0, corner_n*3);
glEnable(GL_BLEND);
}

void Render::Draw3D()
{
if (!shader_flag)
return;

glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(4, GL_FLOAT, 0, fs_quad_vtx);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, fs_quad_tex);

fbo_back->Unbind();
if (shader_effect_flag && shader_blur_flag)
{
// shader blur horizontal
fbo_ping->Bind();
shader_blur_h->Bind();
shader_blur_h->SetTexture(shader_blur_h_texture, fbo_back->GetTexture(), 0);
shader_blur_h->SetUniform(shader_blur_h_screen_size, vec2(1.0f));
shader_blur_h->SetUniform(shader_blur_h_time, fx_angle);
shader_blur_h->SetUniform(shader_blur_h_value, 0.5f/screen_size.x);
fs_quad();
shader_blur_h->Unbind();
fbo_ping->Unbind();
// shader blur vertical
fbo_front->Bind();
shader_blur_v->Bind();
shader_blur_v->SetTexture(shader_blur_v_texture, fbo_ping->GetTexture(), 0);
shader_blur_v->SetUniform(shader_blur_v_screen_size, vec2(1.0f));
shader_blur_v->SetUniform(shader_blur_v_time, fx_angle);
shader_blur_v->SetUniform(shader_blur_v_value, 0.5f/screen_size.y);
fs_quad();
shader_blur_v->Unbind();
}
else
{
// shader simple
fbo_front->Bind();
draw_shader_simple(fbo_back, 0);
}
fbo_front->Unbind();
// shader glow
if(shader_effect_flag && shader_glow_flag)
{
// shader blur horizontal
fbo_blur_h->Bind();
shader_blur_h->Bind();
shader_blur_h->SetTexture(shader_blur_h_texture, fbo_ping->GetTexture(), 0);
shader_blur_h->SetUniform(shader_blur_h_screen_size, vec2(1.0f / glow_fbo_size));
shader_blur_h->SetUniform(shader_blur_h_time, fx_angle);
shader_blur_h->SetUniform(shader_blur_h_value, 2.5f/screen_size.x);
fs_quad();
shader_blur_h->Unbind();
fbo_blur_h->Unbind();
// shader blur vertical
fbo_blur_v->Bind();
shader_blur_v->Bind();
shader_blur_v->SetTexture(shader_blur_v_texture, fbo_blur_h->GetTexture(), 0);
shader_blur_v->SetUniform(shader_blur_v_screen_size, vec2(1.0f / glow_fbo_size));
shader_blur_v->SetUniform(shader_blur_v_time, fx_angle);
shader_blur_v->SetUniform(shader_blur_h_value, 2.5f/screen_size.y);
fs_quad();
shader_blur_v->Unbind();
fbo_blur_v->Unbind();
// shader blur horizontal
fbo_blur_h->Bind();
shader_blur_h->Bind();
shader_blur_h->SetTexture(shader_blur_h_texture, fbo_blur_v->GetTexture(), 0);
shader_blur_h->SetUniform(shader_blur_h_screen_size, vec2(1.0f / glow_fbo_size));
shader_blur_h->SetUniform(shader_blur_h_time, fx_angle);
shader_blur_h->SetUniform(shader_blur_h_value, 1.0f/screen_size.x);
fs_quad();
shader_blur_h->Unbind();
fbo_blur_h->Unbind();
// shader blur vertical
fbo_blur_v->Bind();
shader_blur_v->Bind();
shader_blur_v->SetTexture(shader_blur_v_texture, fbo_blur_h->GetTexture(), 0);
shader_blur_v->SetUniform(shader_blur_v_screen_size, vec2(1.0f / glow_fbo_size));
shader_blur_v->SetUniform(shader_blur_v_time, fx_angle);
shader_blur_v->SetUniform(shader_blur_h_value, 1.0f/screen_size.y);
fs_quad();
shader_blur_v->Unbind();
fbo_blur_v->Unbind();
// shader glow
fbo_pong->Bind();
shader_glow->Bind();
shader_glow->SetTexture(shader_glow_texture, fbo_blur_v->GetTexture(), 0);
shader_glow->SetTexture(shader_glow_texture_prv, fbo_front->GetTexture(), 1);
shader_glow->SetUniform(shader_glow_screen_size, vec2(1.0f));
shader_glow->SetUniform(shader_glow_time, fx_angle);
shader_glow->SetUniform(shader_glow_step, glow_smoothstep);
shader_glow->SetUniform(shader_glow_value1, glow_mix_ratio1);
shader_glow->SetUniform(shader_glow_value2, glow_mix_ratio2);
fs_quad();
shader_glow->Unbind();
}
if(!shader_effect_flag)
{
// shader simple
fbo_pong->Bind();
draw_shader_simple(fbo_front, 0);
}
fbo_pong->Unbind();
if(shader_postfx_flag)
{
// shader postfx
shader_postfx->Bind();
shader_postfx->SetTexture(shader_postfx_texture, fbo_pong->GetTexture(), 0);
shader_postfx->SetUniform(shader_postfx_screen_size, (vec2)screen_size);
shader_postfx->SetUniform(shader_postfx_time, fx_angle);
shader_postfx->SetUniform(shader_postfx_flash, flash_value);
shader_postfx->SetUniform(shader_postfx_value, 4.0f);
shader_postfx->SetUniform(shader_postfx_deform, postfx_deform);
shader_postfx->SetUniform(shader_postfx_scanline, postfx_scanline);
shader_postfx->SetUniform(shader_postfx_sync, (float)fabs(beat_value*cosf((main_angle-beat_angle)*8.0f)));
fs_quad();
shader_postfx->Unbind();
}
else
{
// shader simple
draw_shader_simple(fbo_pong, 0);
}

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

Render::~Render()
{
}


+ 28
- 0
neercs/video/render.h 查看文件

@@ -0,0 +1,28 @@
//
//

#if !defined __VIDEO_RENDER_H__
#define __VIDEO_RENDER_H__

class Render : public WorldEntity
{
public:
Render(caca_canvas_t *caca);
virtual ~Render();

char const *GetName() { return "<title>"; }

protected:
virtual void TickGame(float seconds);
virtual void TickDraw(float seconds);

void Draw2D();
void Draw3D();

private:
caca_canvas_t *m_caca;
bool m_ready;
};

#endif // __VIDEO_RENDER_H__


二進制
neercs/video/resource/map.png 查看文件

Before After
Width: 256  |  Height: 256  |  Size: 2.0 KiB

+ 20
- 0
neercs/video/simple.lolfx 查看文件

@@ -0,0 +1,20 @@
-- GLSL.Vert --

#version 120

void main()
{
gl_Position=gl_Vertex;
gl_TexCoord[0]=gl_MultiTexCoord0;
}

-- GLSL.Frag --

#version 120

uniform sampler2D texture;

void main(void)
{
gl_FragColor=vec4(texture2D(texture,gl_TexCoord[0].xy).xyz,1.0);
}

+ 151
- 0
neercs/video/text-render.cpp 查看文件

@@ -0,0 +1,151 @@
//
// Neercs
//

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <string>

#include "core.h"
#include "lolgl.h"

using namespace std;
using namespace lol;

#include "../neercs.h"
#include "render.h"
#include "text-render.h"

extern char const *lolfx_text;

/*
* Text rendering interface
*/

TextRender::TextRender(caca_canvas_t *caca, ivec2 font_size)
: m_caca(caca),
m_font_size(font_size),
m_canvas_size(caca_get_canvas_width(m_caca),
caca_get_canvas_height(m_caca)),
m_fbo_size(m_font_size * m_canvas_size),
m_cells(m_canvas_size.x * m_canvas_size.y)
{
for (int j = 0; j < m_canvas_size.y; j++)
for (int i = 0; i < m_canvas_size.x; i++)
m_vertices << vec2(i, j);
}

void TextRender::Init()
{
m_font = new TileSet("neercs/video/resource/map.png",
ivec2(256, 256), ivec2(1));

m_shader = Shader::Create(lolfx_text);
m_coord = m_shader->GetAttribLocation("in_Position",
VertexUsage::Position, 0);
m_color = m_shader->GetAttribLocation("in_Attr",
VertexUsage::Color, 0);
m_char = m_shader->GetAttribLocation("in_Char",
VertexUsage::Color, 1);
m_texture = m_shader->GetUniformLocation("in_Texture");
m_transform = m_shader->GetUniformLocation("in_Transform");
m_vdecl
= new VertexDeclaration(VertexStream<vec2>(VertexUsage::Position),
VertexStream<uint32_t>(VertexUsage::Color),
VertexStream<uint32_t>(VertexUsage::Color));

m_vbo1 = new VertexBuffer(m_vertices.Bytes());
void *vertices = m_vbo1->Lock(0, 0);
memcpy(vertices, &m_vertices[0], m_vertices.Bytes());
m_vbo1->Unlock();

m_vbo2 = new VertexBuffer(m_cells * sizeof(int32_t));
m_vbo3 = new VertexBuffer(m_cells * sizeof(int32_t));

m_fbo = new FrameBuffer(m_fbo_size);
}

void TextRender::Render()
{
/* Transform matrix for the scene:
* - translate to the centre of the glyph
* - scale by 2.f * font_size / fbo_size
* - translate to the lower left corner */
mat4 xform = mat4::translate(-1.f, -1.f + 2.0f * m_font_size.y
* m_canvas_size.y / m_fbo_size.y, 0.f)
* mat4::scale(vec3(2.f * m_font_size / m_fbo_size, 1.f)
* vec3(1.f, -1.f, 1.f))
* mat4::translate(0.5f, 0.5f, 0.f);

/* Upload libcaca canvas contents to the vertex buffers */
uint32_t *colors = (uint32_t *)m_vbo2->Lock(0, 0);
for (int j = 0; j < m_canvas_size.y; j++)
for (int i = 0; i < m_canvas_size.x; i++)
{
uint32_t attr = caca_get_attr(m_caca, i, j);
uint16_t fg = caca_attr_to_rgb12_fg(attr);
uint16_t bg = caca_attr_to_rgb12_bg(attr);
caca_set_color_argb(m_caca, fg, bg);
attr = caca_get_attr(m_caca, -1, -1);
caca_put_attr(m_caca, i, j, attr);
}
memcpy(colors, caca_get_canvas_attrs(m_caca),
m_cells * sizeof(uint32_t));
m_vbo2->Unlock();

uint32_t *chars = (uint32_t *)m_vbo3->Lock(0, 0);
memcpy(chars, caca_get_canvas_chars(m_caca),
m_cells * sizeof(uint32_t));
m_vbo3->Unlock();

m_fbo->Bind();
glViewport(0, 0, m_fbo_size.x, m_fbo_size.y);
glDisable(GL_DEPTH_TEST);
glEnable(GL_POINT_SPRITE);
//glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDisable(GL_POINT_SMOOTH);
glPointSize((float)max(m_font_size.x, m_font_size.y));
m_shader->Bind();
m_font->Bind();
m_shader->SetUniform(m_texture, 0);
m_shader->SetUniform(m_transform, xform);
m_vdecl->SetStream(m_vbo1, m_coord);
m_vdecl->SetStream(m_vbo2, m_color);
m_vdecl->SetStream(m_vbo3, m_char);
m_vdecl->Bind();
m_vdecl->DrawElements(MeshPrimitive::Points, 0, m_cells);
m_vdecl->Unbind();
m_font->Unbind();
m_shader->Unbind();
glDisable(GL_POINT_SPRITE);
m_fbo->Unbind();
}

void TextRender::Blit(ivec2 pos, ivec2 size)
{
glDisable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_fbo->GetTexture());
glColor3f(1.0f, 1.0f, 1.0f);

vec2 tc = (vec2)m_canvas_size * m_font_size / m_fbo_size;

glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2f(tc.x, tc.y);
glVertex2i(pos.x + size.x, pos.y);
glTexCoord2f(0.0f, tc.y);
glVertex2i(pos.x, pos.y);
glTexCoord2f(0.0f, 0.0f);
glVertex2i(pos.x, pos.y + size.y);
glTexCoord2f(tc.x, 0.0f);
glVertex2i(pos.x + size.x, pos.y + size.y);
glEnd();
}


+ 31
- 0
neercs/video/text-render.h 查看文件

@@ -0,0 +1,31 @@
//
// Neercs
//

#if !defined __TEXT_RENDER_H__
#define __TEXT_RENDER_H__

struct TextRender
{
TextRender(caca_canvas_t *caca, ivec2 font_size);
void Init();
void Render();
void Blit(ivec2 pos, ivec2 size);

private:
caca_canvas_t *m_caca;
ivec2 m_font_size, m_canvas_size, m_fbo_size;
int m_cells;

Array<vec2> m_vertices;
TileSet *m_font;
Shader *m_shader;
ShaderAttrib m_coord, m_color, m_char;
ShaderUniform m_texture, m_transform;
VertexDeclaration *m_vdecl;
VertexBuffer *m_vbo1, *m_vbo2, *m_vbo3;
FrameBuffer *m_fbo;
};

#endif // __TEXT_RENDER_H__


+ 55
- 0
neercs/video/text.lolfx 查看文件

@@ -0,0 +1,55 @@
-- GLSL.Vert --

#version 130

attribute vec2 in_Position;
attribute uint in_Char, in_Attr;

varying vec4 pass_Foreground;
varying vec4 pass_Background;
varying vec2 pass_UV;

uniform mat4 in_Transform;

void main()
{
float u = float(in_Char & 0xfu) / 32.0 + 0.0;
float v = float((in_Char >> 4u) & 0xfu) / 32.0 + 0.5;
pass_UV = vec2(u, v);

float A = float(in_Attr >> 29u) / 7.0;
float B = float((in_Attr >> 25u) & 0xfu) / 15.0;
float C = float((in_Attr >> 21u) & 0xfu) / 15.0;
float D = float((in_Attr >> 18u) & 0x7u) / 7.0;

float E = float((in_Attr >> 15u) & 0x7u) / 7.0;
float F = float((in_Attr >> 11u) & 0xfu) / 15.0;
float G = float((in_Attr >> 7u) & 0xfu) / 15.0;
float H = float((in_Attr >> 4u) & 0x7u) / 7.0;

pass_Background = vec4(B, C, D, 1.0 - A);
pass_Foreground = vec4(F, G, H, 1.0 - E);

// This only works with glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
//gl_PointSize = 40;

gl_Position = in_Transform * vec4(in_Position, 0.0, 1.0);
}

-- GLSL.Frag --

#version 130

varying vec4 pass_Foreground;
varying vec4 pass_Background;
varying vec2 pass_UV;

uniform sampler2D in_Texture;

void main(void)
{
vec2 c = gl_PointCoord * (1.0 / 32.0) + pass_UV;
float t = texture2D(in_Texture, c).x;
gl_FragColor = mix(pass_Background, pass_Foreground, t);
}


Loading…
取消
儲存