some more GLES hackage

This commit is contained in:
aap 2020-05-13 20:46:27 +02:00
parent 582d202ce5
commit 6c7d811096
14 changed files with 278 additions and 17 deletions

View File

@ -98,6 +98,10 @@ struct UniformObject
};
const char *shaderDecl330 = "#version 330\n";
const char *shaderDecl100es =
"#version 100\n"\
"precision highp float;\n"\
"precision highp int;\n";
const char *shaderDecl310es =
"#version 310 es\n"\
"precision highp float;\n"\
@ -105,17 +109,40 @@ const char *shaderDecl310es =
#ifdef RW_GLES3
const char *shaderDecl = shaderDecl310es;
#elif defined RW_GLES2
const char *shaderDecl = shaderDecl100es;
#else
const char *shaderDecl = shaderDecl330;
#endif
#ifndef RW_GLES2
static GLuint vao;
static GLuint ubo_state, ubo_scene, ubo_object;
#endif
static GLuint whitetex;
static UniformState uniformState;
static UniformScene uniformScene;
static UniformObject uniformObject;
#ifdef RW_GLES2
// State
int32 u_alphaRef;
int32 u_fogStart;
int32 u_fogEnd;
int32 u_fogRange;
int32 u_fogDisable;
int32 u_fogColor;
// Scene
int32 u_proj;
int32 u_view;
// Object
int32 u_world;
int32 u_ambLight;
// TODO: lights!
#endif
int32 u_matColor;
int32 u_surfProps;
@ -727,9 +754,62 @@ setViewMatrix(float32 *mat)
sceneDirty = 1;
}
Shader *lastShaderUploaded;
void
flushCache(void)
{
#ifdef RW_GLES2
#define U(i) currentShader->uniformLocations[i]
// TODO: this is probably a stupid way to do it with gl2
if(lastShaderUploaded != currentShader){
lastShaderUploaded = currentShader;
objectDirty = 1;
sceneDirty = 1;
stateDirty = 1;
}
if(objectDirty){
glUniformMatrix4fv(U(u_world), 1, 0, (float*)&uniformObject.world);
glUniform4fv(U(u_ambLight), 1, (float*)&uniformObject.ambLight);
// TODO: lights somehow
objectDirty = 0;
}
if(sceneDirty){
glUniformMatrix4fv(U(u_proj), 1, 0, uniformScene.proj);
glUniformMatrix4fv(U(u_view), 1, 0, uniformScene.view);
sceneDirty = 0;
}
if(stateDirty){
uniformState.fogDisable = rwStateCache.fogEnable ? 0.0f : 1.0f;
uniformState.fogStart = rwStateCache.fogStart;
uniformState.fogEnd = rwStateCache.fogEnd;
uniformState.fogRange = 1.0f/(rwStateCache.fogStart - rwStateCache.fogEnd);
switch(uniformState.alphaFunc){
case ALPHAALWAYS:
default:
glUniform2f(U(u_alphaRef), -1000.0f, 1000.0f);
break;
case ALPHAGREATEREQUAL:
glUniform2f(U(u_alphaRef), uniformState.alphaRef, 1000.0f);
break;
case ALPHALESS:
glUniform2f(U(u_alphaRef), -1000.0f, uniformState.alphaRef);
break;
}
glUniform1f(U(u_fogStart), uniformState.fogStart);
glUniform1f(U(u_fogEnd), uniformState.fogEnd);
glUniform1f(U(u_fogRange), uniformState.fogRange);
glUniform1f(U(u_fogDisable), uniformState.fogDisable);
glUniform4fv(U(u_fogColor), 1, (float*)&uniformState.fogColor);
stateDirty = 0;
}
#else
if(objectDirty){
glBindBuffer(GL_UNIFORM_BUFFER, ubo_object);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformObject),
@ -752,6 +832,7 @@ flushCache(void)
&uniformState);
stateDirty = 0;
}
#endif
}
static void
@ -1035,6 +1116,10 @@ openGLFW(EngineOpenParams *openparams)
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
#elif defined RW_GLES2
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
#else
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
@ -1087,6 +1172,7 @@ startGLFW(void)
return 0;
}
glfwMakeContextCurrent(win);
printf("version %s\n", glGetString(GL_VERSION));
/* Init GLEW */
glewExperimental = GL_TRUE;
@ -1119,9 +1205,23 @@ stopGLFW(void)
static int
initOpenGL(void)
{
#ifdef RW_GLES2
u_alphaRef = registerUniform("u_alphaRef");
u_fogStart = registerUniform("u_fogStart");
u_fogEnd = registerUniform("u_fogEnd");
u_fogRange = registerUniform("u_fogRange");
u_fogDisable = registerUniform("u_fogDisable");
u_fogColor = registerUniform("u_fogColor");
u_proj = registerUniform("u_proj");
u_view = registerUniform("u_view");
u_world = registerUniform("u_world");
u_ambLight = registerUniform("u_ambLight");
lastShaderUploaded = nil;
#else
registerBlock("Scene");
registerBlock("Object");
registerBlock("State");
#endif
u_matColor = registerUniform("u_matColor");
u_surfProps = registerUniform("u_surfProps");
@ -1137,6 +1237,7 @@ initOpenGL(void)
resetRenderState();
#ifndef RW_GLES2
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
@ -1160,9 +1261,15 @@ initOpenGL(void)
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformObject), &uniformObject,
GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
#endif
#ifdef RW_GLES2
#include "gl2_shaders/default_vs_gl2.inc"
#include "gl2_shaders/simple_fs_gl2.inc"
#else
#include "shaders/default_vs_gl3.inc"
#include "shaders/simple_fs_gl3.inc"
#endif
const char *vs[] = { shaderDecl, header_vert_src, default_vert_src, nil };
const char *fs[] = { shaderDecl, simple_frag_src, nil };
defaultShader = Shader::create(vs, fs);

View File

@ -50,8 +50,13 @@ openIm2D(void)
{
u_xform = registerUniform("u_xform");
#ifdef RW_GLES2
#include "gl2_shaders/im2d_gl2.inc"
#include "gl2_shaders/simple_fs_gl2.inc"
#else
#include "shaders/im2d_gl3.inc"
#include "shaders/simple_fs_gl3.inc"
#endif
const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
const char *fs[] = { shaderDecl, simple_frag_src, nil };
im2dShader = Shader::create(vs, fs);
@ -179,8 +184,13 @@ static int32 num3DVertices; // not actually needed here
void
openIm3D(void)
{
#ifdef RW_GLES2
#include "gl2_shaders/im3d_gl2.inc"
#include "gl2_shaders/simple_fs_gl2.inc"
#else
#include "shaders/im3d_gl3.inc"
#include "shaders/simple_fs_gl3.inc"
#endif
const char *vs[] = { shaderDecl, header_vert_src, im3d_vert_src, nil };
const char *fs[] = { shaderDecl, simple_frag_src, nil };
im3dShader = Shader::create(vs, fs);

View File

@ -41,7 +41,11 @@ matfxOpen(void *o, int32, int32)
u_colorClamp = registerUniform("u_colorClamp");
matFXGlobals.pipelines[PLATFORM_GL3] = makeMatFXPipeline();
#ifdef RW_GLES2
#include "gl2_shaders/matfx_gl2.inc"
#else
#include "shaders/matfx_gl3.inc"
#endif
const char *vs[] = { shaderDecl, header_vert_src, matfx_env_vert_src, nil };
const char *fs[] = { shaderDecl, matfx_env_frag_src, nil };
envShader = Shader::create(vs, fs);

View File

@ -33,7 +33,7 @@ rasterCreateTexture(Raster *raster)
natras->format = GL_RGBA;
natras->type = GL_UNSIGNED_BYTE;
natras->hasAlpha = 1;
natras->bbp = 4;
natras->bpp = 4;
raster->depth = 32;
break;
case Raster::C888:
@ -41,7 +41,7 @@ rasterCreateTexture(Raster *raster)
natras->format = GL_RGB;
natras->type = GL_UNSIGNED_BYTE;
natras->hasAlpha = 0;
natras->bbp = 3;
natras->bpp = 3;
raster->depth = 24;
break;
case Raster::C1555:
@ -49,7 +49,7 @@ rasterCreateTexture(Raster *raster)
natras->format = GL_RGBA;
natras->type = GL_UNSIGNED_SHORT_5_5_5_1;
natras->hasAlpha = 1;
natras->bbp = 2;
natras->bpp = 2;
raster->depth = 16;
break;
default:
@ -57,7 +57,15 @@ rasterCreateTexture(Raster *raster)
return nil;
}
raster->stride = raster->width*natras->bbp;
#ifdef RW_GLES
// glReadPixels only supports GL_RGBA
natras->internalFormat = GL_RGBA8;
natras->format = GL_RGBA;
natras->type = GL_UNSIGNED_BYTE;
natras->bpp = 4;
#endif
raster->stride = raster->width*natras->bpp;
glGenTextures(1, &natras->texid);
glBindTexture(GL_TEXTURE_2D, natras->texid);
@ -91,6 +99,7 @@ rasterCreateCameraTexture(Raster *raster)
natras->format = GL_RGBA;
natras->type = GL_UNSIGNED_BYTE;
natras->hasAlpha = 1;
natras->bpp = 4;
break;
case Raster::C888:
default:
@ -98,15 +107,27 @@ rasterCreateCameraTexture(Raster *raster)
natras->format = GL_RGB;
natras->type = GL_UNSIGNED_BYTE;
natras->hasAlpha = 0;
natras->bpp = 3;
break;
case Raster::C1555:
natras->internalFormat = GL_RGB5_A1;
natras->format = GL_RGBA;
natras->type = GL_UNSIGNED_SHORT_5_5_5_1;
natras->hasAlpha = 1;
natras->bpp = 2;
break;
}
#ifdef RW_GLES
// glReadPixels only supports GL_RGBA
// natras->internalFormat = GL_RGBA8;
// natras->format = GL_RGBA;
// natras->type = GL_UNSIGNED_BYTE;
// natras->bpp = 4;
#endif
raster->stride = raster->width*natras->bpp;
glGenTextures(1, &natras->texid);
glBindTexture(GL_TEXTURE_2D, natras->texid);
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
@ -218,13 +239,28 @@ rasterLock(Raster *raster, int32 level, int32 lockMode)
case Raster::TEXTURE:
case Raster::CAMERATEXTURE:
px = (uint8*)rwMalloc(raster->stride*raster->height, MEMDUR_EVENT | ID_DRIVER);
memset(px, 0, raster->stride*raster->height);
assert(raster->pixels == nil);
raster->pixels = px;
if(lockMode & Raster::LOCKREAD || !(lockMode & Raster::LOCKNOFETCH)){
#ifdef RW_GLES
GLuint fbo;
GLenum e;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, natras->texid, 0);
e = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(natras->format == GL_RGBA);
glReadPixels(0, 0, raster->width, raster->height, natras->format, natras->type, px);
//e = glGetError(); printf("GL err4 %x (%x)\n", e, natras->format);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbo);
#else
uint32 prev = bindTexture(natras->texid);
glGetTexImage(GL_TEXTURE_2D, level, natras->format, natras->type, px);
bindTexture(prev);
#endif
}
raster->privateFlags = lockMode;
@ -342,26 +378,38 @@ rasterFromImage(Raster *raster, Image *image)
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
switch(image->depth){
case 32:
#ifdef RW_GLES
conv = conv_RGBA8888_to_RGBA8888;
#else
if(raster->format == Raster::C8888)
conv = conv_RGBA8888_to_RGBA8888;
else if(raster->format == Raster::C888)
conv = conv_RGB888_to_RGB888;
else
goto err;
#endif
break;
case 24:
#ifdef RW_GLES
conv = conv_RGB888_to_RGBA8888;
#else
if(raster->format == Raster::C8888)
conv = conv_RGB888_to_RGBA8888;
else if(raster->format == Raster::C888)
conv = conv_RGB888_to_RGB888;
else
goto err;
#endif
break;
case 16:
#ifdef RW_GLES
conv = conv_RGBA1555_to_RGBA8888;
#else
if(raster->format == Raster::C1555)
conv = conv_RGBA1555_to_RGBA5551;
else
goto err;
#endif
break;
case 8:
@ -387,7 +435,7 @@ rasterFromImage(Raster *raster, Image *image)
for(x = 0; x < image->width; x++){
conv(rasrow, imgrow);
imgrow += image->bpp;
rasrow += natras->bbp;
rasrow += natras->bpp;
}
imgpixels -= image->stride;
pixels += raster->stride;

View File

@ -16,7 +16,11 @@
namespace rw {
namespace gl3 {
#ifdef RW_GLES2
#include "gl2_shaders/header_vs.inc"
#else
#include "shaders/header_vs.inc"
#endif
UniformRegistry uniformRegistry;
@ -68,6 +72,27 @@ findBlock(const char *name)
Shader *currentShader;
static void
printShaderSource(const char **src)
{
int f, l;
const char *file;
bool printline;
int line = 1;
for(f = 0; src[f]; f++){
char c;
file = src[f];
printline = true;
while(c = *file++, c != '\0'){
if(printline)
printf("%.4d: ", line++);
putchar(c);
printline = c == '\n';
}
putchar('\n');
}
}
static int
compileshader(GLenum type, const char **src, GLuint *shader)
{
@ -83,6 +108,7 @@ compileshader(GLenum type, const char **src, GLuint *shader)
glCompileShader(shdr);
glGetShaderiv(shdr, GL_COMPILE_STATUS, &success);
if(!success){
printShaderSource(src);
fprintf(stderr, "Error in %s shader\n",
type == GL_VERTEX_SHADER ? "vertex" : "fragment");
glGetShaderiv(shdr, GL_INFO_LOG_LENGTH, &len);
@ -105,6 +131,16 @@ linkprogram(GLint vs, GLint fs, GLuint *program)
prog = glCreateProgram();
#ifdef RW_GLES2
// TODO: perhaps just do this always and get rid of the layout stuff?
glBindAttribLocation(prog, ATTRIB_POS, "in_pos");
glBindAttribLocation(prog, ATTRIB_NORMAL, "in_normal");
glBindAttribLocation(prog, ATTRIB_COLOR, "in_color");
glBindAttribLocation(prog, ATTRIB_TEXCOORDS0, "in_tex0");
glBindAttribLocation(prog, ATTRIB_WEIGHTS, "in_weights");
glBindAttribLocation(prog, ATTRIB_INDICES, "in_indices");
#endif
glAttachShader(prog, vs);
glAttachShader(prog, fs);
glLinkProgram(prog);
@ -150,6 +186,33 @@ Shader::create(const char **vsrc, const char **fsrc)
Shader *sh = rwNewT(Shader, 1, MEMDUR_EVENT | ID_DRIVER); // or global?
#ifdef xxxRW_GLES2
int numUniforms;
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms);
for(i = 0; i < numUniforms; i++){
GLint size;
GLenum type;
char name[100];
glGetActiveUniform(program, i, 100, nil, &size, &type, name);
printf("%d %d %s\n", size, type, name);
}
printf("\n");
#endif
#ifdef xxxRW_GLES2
int numAttribs;
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttribs);
for(i = 0; i < numAttribs; i++){
GLint size;
GLenum type;
char name[100];
glGetActiveAttrib(program, i, 100, nil, &size, &type, name);
GLint bind = glGetAttribLocation(program, name);
printf("%d %d %s. %d\n", size, type, name, bind);
}
printf("\n");
#endif
// set uniform block binding
for(i = 0; i < uniformRegistry.numBlocks; i++){
int idx = glGetUniformBlockIndex(program,

View File

@ -37,8 +37,13 @@ skinOpen(void *o, int32, int32)
u_boneMatrices = registerUniform("u_boneMatrices");
skinGlobals.pipelines[PLATFORM_GL3] = makeSkinPipeline();
#ifdef RW_GLES2
#include "gl2_shaders/simple_fs_gl2.inc"
#include "gl2_shaders/skin_gl2.inc"
#else
#include "shaders/simple_fs_gl3.inc"
#include "shaders/skin_gl3.inc"
#endif
const char *vs[] = { shaderDecl, header_vert_src, skin_vert_src, nil };
const char *fs[] = { shaderDecl, simple_frag_src, nil };
skinShader = Shader::create(vs, fs);
@ -60,12 +65,6 @@ initSkin(void)
skinOpen, skinClose);
}
enum
{
ATTRIB_WEIGHTS = ATTRIB_TEXCOORDS7+1,
ATTRIB_INDICES
};
void
skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance)
{

View File

@ -47,12 +47,16 @@ enum AttribIndices
ATTRIB_COLOR,
ATTRIB_TEXCOORDS0,
ATTRIB_TEXCOORDS1,
#ifndef RW_GLES2
ATTRIB_TEXCOORDS2,
ATTRIB_TEXCOORDS3,
ATTRIB_TEXCOORDS4,
ATTRIB_TEXCOORDS5,
ATTRIB_TEXCOORDS6,
ATTRIB_TEXCOORDS7
ATTRIB_TEXCOORDS7,
#endif
ATTRIB_WEIGHTS,
ATTRIB_INDICES
};
// default uniform indices
@ -217,7 +221,7 @@ struct Gl3Raster
int32 internalFormat;
int32 type;
int32 format;
int32 bbp; // bytes per pixel
int32 bpp; // bytes per pixel
// texture object
uint32 texid;

View File

@ -82,5 +82,5 @@ float DoFog(float w)
}
#define DIRECTIONALS
#define POINTLIGHTS
#define SPOTLIGHTS
//#define POINTLIGHTS
//#define SPOTLIGHTS

View File

@ -83,6 +83,6 @@ const char *header_vert_src =
"}\n"
"#define DIRECTIONALS\n"
"#define POINTLIGHTS\n"
"#define SPOTLIGHTS\n"
"//#define POINTLIGHTS\n"
"//#define SPOTLIGHTS\n"
;

View File

@ -12,6 +12,7 @@ void
main(void)
{
gl_Position = in_pos;
gl_Position.w = 1.0;
gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;
v_fog = DoFog(gl_Position.z);
gl_Position.xyz *= gl_Position.w;

View File

@ -13,6 +13,7 @@ const char *im2d_vert_src =
"main(void)\n"
"{\n"
" gl_Position = in_pos;\n"
" gl_Position.w = 1.0;\n"
" gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;\n"
" v_fog = DoFog(gl_Position.z);\n"
" gl_Position.xyz *= gl_Position.w;\n"

View File

@ -259,4 +259,18 @@ conv_RGBA1555_to_RGBA5551(uint8 *out, uint8 *in)
out[1] = g>>2 | r<<3;
}
void
conv_RGBA1555_to_RGBA8888(uint8 *out, uint8 *in)
{
uint32 r, g, b, a;
a = (in[1]>>7) & 1;
r = (in[1]>>2) & 0x1F;
g = (in[1]&3)<<3 | (in[0]>>5)&7;
b = in[0] & 0x1F;
out[0] = r*0xFF/0x1f;
out[1] = g*0xFF/0x1f;
out[2] = b*0xFF/0x1f;
out[3] = a*0xFF;
}
}

View File

@ -6,11 +6,20 @@
#define M_PI 3.14159265358979323846
#endif
// TODO: clean up the opengl defines
// and figure out what we even want here...
#ifdef RW_GL3
#define RW_OPENGL
#define RWDEVICE gl3
#endif
#ifdef RW_GLES2
#define RW_GLES
#endif
#ifdef RW_GLES3
#define RW_GLES
#endif
#ifdef RW_D3D9
#define RWDEVICE d3d
#define RWHALFPIXEL

View File

@ -269,6 +269,7 @@ void conv_RGBA8888_to_RGBA8888(uint8 *out, uint8 *in);
void conv_RGB888_to_RGBA8888(uint8 *out, uint8 *in);
void conv_RGB888_to_RGB888(uint8 *out, uint8 *in);
void conv_RGBA1555_to_RGBA5551(uint8 *out, uint8 *in);
void conv_RGBA1555_to_RGBA8888(uint8 *out, uint8 *in);
#define IGNORERASTERIMP 0