gl4es updated, added latest changes by ptitSeb

This commit is contained in:
lubomyr
2017-05-13 13:42:21 +03:00
parent 9e2035c21d
commit 360fc0b112
38 changed files with 1229 additions and 446 deletions

View File

@@ -16,11 +16,13 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) -DBCMHOST
LOCAL_SRC_FILES := \
src/gl/array.c \
src/gl/blend.c \
src/gl/buffers.c \
src/gl/debug.c \
src/gl/decompress.c \
src/gl/directstate.c \
src/gl/eval.c \
src/gl/fog.c \
src/gl/framebuffers.c \
src/gl/getter.c \
src/gl/gl.c \
@@ -46,6 +48,7 @@ LOCAL_SRC_FILES := \
src/glx/hardext.c \
src/glx/glx.c \
src/glx/lookup.c \
src/glx/rpi.c \
src/glx/streaming.c \
LOCAL_CFLAGS += -g -std=c99 -funwind-tables -O3 -DBCMHOST -fvisibility=hidden -include include/android_debug.h

View File

@@ -7,7 +7,7 @@ This is a fork a glshim (https://github.com/lunixbochs/glshim). Go check this li
The focus is on compatibility with a wide selection of game and software, as well as speed.
It has been tested successfully of a large selection of games and software, including: Mincraft, OpenMW, SeriousSam, RVGL, TSMC, TORCS, SpeedDreams, GL-117, Foobillard(plus), Blender 2.68 and many more.
It has been tested successfully of a large selection of games and software, including: Minecraft, OpenMW, SeriousSam (both First and Second Encounters), RVGL (ReVolt GL), TSMC (The Secret Maryo Chronicles), TORCS, SpeedDreams, GL-117, Foobillard(plus), Blender 2.68 to name just a few.
Most function of OpenGL up to 1.5 are supported, with some notable exceptions:
* Reading of Depth or Stencil buffer will not work
@@ -135,7 +135,7 @@ Experimental: enable Alpha test only when using texture that contains an alpha c
* 1 : Alpha Hack enabled
##### LIBGL_NODOWNSAMPLING
Texture downsampling control
Texture downsampling control (deprecated, use LIBGL_AVOID16BITS instead)
* 0 : Default, DXTc texture are downsampled to 16bits
* 1 : DXTc texture are left as 32bits RGBA
@@ -241,10 +241,26 @@ Merge of subsequent glBegin/glEnd blocks (will be non-effective if BATCH mode is
* 1 : Try to merge, even if there is a glColor / glNormal in between (default)
* 2 : Try hard to merge, even if there is a glColor / glNormal or Matrix operations in between
##### LIBGL_AVOID16BITS
Try to avoid 16bits textures
* 0 : Default, use 16bits texture if it can avoid a convertion or for DXTc textures
* 1 : Use 32bits texture unless specifically requested (using internalformat)
----
Version history
----
##### Current version
* Some fix with the PixMap glX context creation
##### 0.9.6
* Some fixes in GL_TEXTURE_RECTANGLE_ARB handling
* Some other fixes in texture handling (unpack and glList related)
* Some fix with the PBuffer glX context creation
* Tracking of glFog
* Exposed glBlendEquation if supported
* New LIBGL_AVOID16BITS parameter to prefer 32bits texture (usefull on ODroid)
* Some optimisations in texture conversion
##### 0.9.5
* Added some optimisations for sequencial glBegin/glEnd blocks, with a switch to control them

View File

@@ -29,5 +29,7 @@
#define GL_NOVAOCACHE_HINT_GL4ES 0xA10C
// same as using LIBGL_BEGINEND=x
#define GL_BEGINEND_HINT_GL4ES 0xA10D
// same as using LIBGL_AVOID16BITS=x
#define GL_AVOID16BITS_HINT_GL4ES 0xA10E
#endif

View File

@@ -0,0 +1,177 @@
glActiveTexture: [void, GLenum texture]
glAlphaFunc: [void, GLenum func, GLclampf ref]
glAlphaFuncx: [void, GLenum func, GLclampx ref]
glBindBuffer: [void, GLenum target, GLuint buffer]
glBindTexture: [void, GLenum target, GLuint texture]
glBlendFunc: [void, GLenum sfactor, GLenum dfactor]
glBufferData: [void, GLenum target, GLsizeiptr size, "const GLvoid *data", GLenum usage]
glBufferSubData: [void, GLenum target, GLintptr offset, GLsizeiptr size, "const GLvoid *data"]
glClear: [void, GLbitfield mask]
glClearColor: [void, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha]
glClearColorx: [void, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha]
glClearDepthf: [void, GLclampf depth]
glClearDepthx: [void, GLclampx depth]
glClearStencil: [void, GLint s]
glClientActiveTexture: [void, GLenum texture]
glClipPlanef: [void, GLenum plane, "const GLfloat *equation"]
glClipPlanex: [void, GLenum plane, "const GLfixed *equation"]
glColor4f: [void, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha]
glColor4ub: [void, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha]
glColor4x: [void, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha]
glColorMask: [void, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha]
glColorPointer: [void, GLint size, GLenum type, GLsizei stride, "const GLvoid *pointer"]
glCompressedTexImage2D: [void, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, "const GLvoid *data"]
glCompressedTexSubImage2D: [void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, "const GLvoid *data"]
glCopyTexImage2D: [void, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border]
glCopyTexSubImage2D: [void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height]
glCullFace: [void, GLenum mode]
glDeleteBuffers: [void, GLsizei n, "const GLuint *buffers"]
glDeleteTextures: [void, GLsizei n, "const GLuint *textures"]
glDepthFunc: [void, GLenum func]
glDepthMask: [void, GLboolean flag]
glDepthRangef: [void, GLclampf near, GLclampf far]
glDepthRangex: [void, GLclampx near, GLclampx far]
glDisable: [void, GLenum cap]
glDisableClientState: [void, GLenum array]
glDisableClientState: [void, GLenum array]
glDrawArrays: [void, GLenum mode, GLint first, GLsizei count]
glDrawElements: [void, GLenum mode, GLsizei count, GLenum type, "const GLvoid *indices"]
glEnable: [void, GLenum cap]
glEnableClientState: [void, GLenum array]
glEnableClientState: [void, GLenum array]
glFinish: [void, void]
glFlush: [void, void]
glFogf: [void, GLenum pname, GLfloat param]
glFogfv: [void, GLenum pname, "const GLfloat *params"]
glFogx: [void, GLenum pname, GLfixed param]
glFogxv: [void, GLenum pname, "const GLfixed *params"]
glFrontFace: [void, GLenum mode]
glFrustumf: [void, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far]
glFrustumx: [void, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed near, GLfixed far]
glGenBuffers: [void, GLsizei n, "GLuint *buffers"]
glGenTextures: [void, GLsizei n, "GLuint *textures"]
glGetBooleanv: [void, GLenum pname, "GLboolean *params"]
glGetBufferParameteriv: [void, GLenum target, GLenum pname, "GLint *params"]
glGetClipPlanef: [void, GLenum plane, "GLfloat *equation"]
glGetClipPlanex: [void, GLenum plane, "GLfixed *equation"]
glGetError: [GLenum, void]
glGetFixedv: [void, GLenum pname, "GLfixed *params"]
glGetFloatv: [void, GLenum pname, "GLfloat *params"]
glGetIntegerv: [void, GLenum pname, "GLint *params"]
glGetLightfv: [void, GLenum light, GLenum pname, "GLfloat *params"]
glGetLightxv: [void, GLenum light, GLenum pname, "GLfixed *params"]
glGetMaterialfv: [void, GLenum face, GLenum pname, "GLfloat *params"]
glGetMaterialxv: [void, GLenum face, GLenum pname, "GLfixed *params"]
glGetPointerv: [void, GLenum pname, "GLvoid **params"]
glGetString: [const GLubyte *, GLenum name]
glGetTexEnvfv: [void, GLenum target, GLenum pname, "GLfloat *params"]
glGetTexEnviv: [void, GLenum target, GLenum pname, "GLint *params"]
glGetTexEnvxv: [void, GLenum target, GLenum pname, "GLfixed *params"]
glGetTexParameterfv: [void, GLenum target, GLenum pname, "GLfloat *params"]
glGetTexParameteriv: [void, GLenum target, GLenum pname, "GLint *params"]
glGetTexParameterxv: [void, GLenum target, GLenum pname, "GLfixed *params"]
glHint: [void, GLenum target, GLenum mode]
glIsBuffer: [GLboolean, GLuint buffer]
glIsEnabled: [GLboolean, GLenum cap]
glIsTexture: [GLboolean, GLuint texture]
glLightf: [void, GLenum light, GLenum pname, GLfloat param]
glLightfv: [void, GLenum light, GLenum pname, "const GLfloat *params"]
glLightModelf: [void, GLenum pname, GLfloat param]
glLightModelfv: [void, GLenum pname, "const GLfloat *params"]
glLightModelx: [void, GLenum pname, GLfixed param]
glLightModelxv: [void, GLenum pname, "const GLfixed *params"]
glLightx: [void, GLenum light, GLenum pname, GLfixed param]
glLightxv: [void, GLenum light, GLenum pname, "const GLfixed *params"]
glLineWidth: [void, GLfloat width]
glLineWidthx: [void, GLfixed width]
glLoadIdentity: [void, void]
glLoadMatrixf: [void, "const GLfloat *m"]
glLoadMatrixx: [void, "const GLfixed *m"]
glLogicOp: [void, GLenum opcode]
glMaterialf: [void, GLenum face, GLenum pname, GLfloat param]
glMaterialfv: [void, GLenum face, GLenum pname, "const GLfloat *params"]
glMaterialx: [void, GLenum face, GLenum pname, GLfixed param]
glMaterialxv: [void, GLenum face, GLenum pname, "const GLfixed *params"]
glMatrixMode: [void, GLenum mode]
glMultiTexCoord4f: [void, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q]
glMultiTexCoord4x: [void, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q]
glMultMatrixf: [void, "const GLfloat *m"]
glMultMatrixx: [void, "const GLfixed *m"]
glNormal3f: [void, GLfloat nx, GLfloat ny, GLfloat nz]
glNormal3x: [void, GLfixed nx, GLfixed ny, GLfixed nz]
glNormalPointer: [void, GLenum type, GLsizei stride, "const GLvoid *pointer"]
glOrthof: [void, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far]
glOrthox: [void, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed near, GLfixed far]
glPixelStorei: [void, GLenum pname, GLint param]
glPointParameterf: [void, GLenum pname, GLfloat param]
glPointParameterfv: [void, GLenum pname, "const GLfloat *params"]
glPointParameterx: [void, GLenum pname, GLfixed param]
glPointParameterxv: [void, GLenum pname, "const GLfixed *params"]
glPointSize: [void, GLfloat size]
glPointSizePointerOES: [void, GLenum type, GLsizei stride, "const GLvoid *pointer"]
glPointSizex: [void, GLfixed size]
glPolygonOffset: [void, GLfloat factor, GLfloat units]
glPolygonOffsetx: [void, GLfixed factor, GLfixed units]
glPopMatrix: [void, void]
glPushMatrix: [void, void]
glReadPixels: [void, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, "GLvoid *pixels"]
glRotatef: [void, GLfloat angle, GLfloat x, GLfloat y, GLfloat z]
glRotatex: [void, GLfixed angle, GLfixed x, GLfixed y, GLfixed z]
glSampleCoverage: [void, GLclampf value, GLboolean invert]
glSampleCoveragex: [void, GLclampx value, GLboolean invert]
glScalef: [void, GLfloat x, GLfloat y, GLfloat z]
glScalex: [void, GLfixed x, GLfixed y, GLfixed z]
glScissor: [void, GLint x, GLint y, GLsizei width, GLsizei height]
glShadeModel: [void, GLenum mode]
glStencilFunc: [void, GLenum func, GLint ref, GLuint mask]
glStencilMask: [void, GLuint mask]
glStencilOp: [void, GLenum fail, GLenum zfail, GLenum zpass]
glTexCoordPointer: [void, GLint size, GLenum type, GLsizei stride, "const GLvoid *pointer"]
glTexEnvf: [void, GLenum target, GLenum pname, GLfloat param]
glTexEnvfv: [void, GLenum target, GLenum pname, "const GLfloat *params"]
glTexEnvi: [void, GLenum target, GLenum pname, GLint param]
glTexEnviv: [void, GLenum target, GLenum pname, "const GLint *params"]
glTexEnvx: [void, GLenum target, GLenum pname, GLfixed param]
glTexEnvxv: [void, GLenum target, GLenum pname, "const GLfixed *params"]
glTexImage2D: [void, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, "const GLvoid *data"]
glTexParameterf: [void, GLenum target, GLenum pname, GLfloat param]
glTexParameterfv: [void, GLenum target, GLenum pname, "const GLfloat *params"]
glTexParameteri: [void, GLenum target, GLenum pname, GLint param]
glTexParameteriv: [void, GLenum target, GLenum pname, "const GLint *params"]
glTexParameterx: [void, GLenum target, GLenum pname, GLfixed param]
glTexParameterxv: [void, GLenum target, GLenum pname, "const GLfixed *params"]
glTexSubImage2D: [void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, "const GLvoid *data"]
glTranslatef: [void, GLfloat x, GLfloat y, GLfloat z]
glTranslatex: [void, GLfixed x, GLfixed y, GLfixed z]
glVertexPointer: [void, GLint size, GLenum type, GLsizei stride, "const GLvoid *pointer"]
glViewport: [void, GLint x, GLint y, GLsizei width, GLsizei height]
glBlendColor_OES_: [void, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha]
glBlendEquation_OES_: [void, GLenum mode]
glBlendEquationSeparate_OES_: [void, GLenum modeRGB, GLenum modeA]
glBlendFuncSeparate_OES_: [void, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha]
# glTexGenfOES_OES_: [void, GLenum coord, GLenum pname, GLfloat param]
glTexGenfv_OES_: [void, GLenum coord, GLenum pname, "const GLfloat *params"]
glTexGeni_OES_: [void, GLenum coord, GLenum pname, GLint param]
# glTexGenivOES_OES_: [void, GLenum coord, GLenum pname, "const GLint *params"]
glGenFramebuffers_OES_: [void, GLsizei n, "GLuint *ids"]
glDeleteFramebuffers_OES_: [void, GLsizei n, "GLuint *framebuffers"]
glIsFramebuffer_OES_: [GLboolean, GLuint framebuffer]
glCheckFramebufferStatus_OES_: [GLenum, GLenum target]
glBindFramebuffer_OES_: [void, GLenum target, GLuint framebuffer]
glFramebufferTexture2D_OES_: [void, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level]
glGenRenderbuffers_OES_: [void, GLsizei n, "GLuint *renderbuffers"]
glFramebufferRenderbuffer_OES_: [void, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer]
glDeleteRenderbuffers_OES_: [void, GLsizei n, "GLuint *renderbuffers"]
glRenderbufferStorage_OES_: [void, GLenum target, GLenum internalformat, GLsizei width, GLsizei height]
glBindRenderbuffer_OES_: [void, GLenum target, GLuint renderbuffer]
glIsRenderbuffer_OES_: [GLboolean, GLuint renderbuffer]
glGenerateMipmap_OES_: [void, GLenum target]
glGetFramebufferAttachmentParameteriv_OES_: [void, GLenum target, GLenum attachment, GLenum pname, "GLint *params"]
glGetRenderbufferParameteriv_OES_: [void, GLenum target, GLenum pname, "GLint * params"]
glDrawTexi_OES_: [void, GLint x, GLint y, GLint z, GLint width, GLint height]
glDrawTexf_OES_: [void, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height]
glMultiDrawArrays_OES_: [void, GLenum mode, "const GLint *first", "const GLsizei *count", GLsizei primcount]
glMultiDrawElements_OES_: [void, GLenum mode, "GLsizei *count", GLenum type, "const void * const *indices", GLsizei primcount]

View File

@@ -133,14 +133,14 @@ glTexEnvi: [void, GLenum target, GLenum pname, GLint param]
glTexEnviv: [void, GLenum target, GLenum pname, "const GLint *params"]
glTexEnvx: [void, GLenum target, GLenum pname, GLfixed param]
glTexEnvxv: [void, GLenum target, GLenum pname, "const GLfixed *params"]
glTexImage2D: [void, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, "const GLvoid *pixels"]
glTexImage2D: [void, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, "const GLvoid *data"]
glTexParameterf: [void, GLenum target, GLenum pname, GLfloat param]
glTexParameterfv: [void, GLenum target, GLenum pname, "const GLfloat *params"]
glTexParameteri: [void, GLenum target, GLenum pname, GLint param]
glTexParameteriv: [void, GLenum target, GLenum pname, "const GLint *params"]
glTexParameterx: [void, GLenum target, GLenum pname, GLfixed param]
glTexParameterxv: [void, GLenum target, GLenum pname, "const GLfixed *params"]
glTexSubImage2D: [void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, "const GLvoid *pixels"]
glTexSubImage2D: [void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, "const GLvoid *data"]
glTranslatef: [void, GLfloat x, GLfloat y, GLfloat z]
glTranslatex: [void, GLfixed x, GLfixed y, GLfixed z]
glVertexPointer: [void, GLint size, GLenum type, GLsizei stride, "const GLvoid *pointer"]

View File

@@ -3,11 +3,13 @@ include_directories(util)
#file(GLOB_RECURSE GL_SOURCES gl/*.c)
SET(GL_SRC
gl/array.c
gl/blend.c
gl/buffers.c
gl/debug.c
gl/decompress.c
gl/directstate.c
gl/eval.c
gl/fog.c
gl/framebuffers.c
gl/getter.c
gl/gl.c
@@ -35,12 +37,14 @@ SET(GL_SRC
SET(GL_H
../version.h
gl/array.h
gl/blend.h
gl/buffers.h
gl/const.h
gl/debug.h
gl/decompress.h
gl/defines.h
gl/directstate.h
gl/fog.h
gl/eval.h
gl/framebuffers.h
gl/gles.h
@@ -78,12 +82,14 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
glx/hardext.c
glx/glx.c
glx/lookup.c
glx/rpi.c
glx/streaming.c
glx/utils.c
)
list(APPEND GL_H
glx/glx.h
glx/hardext.h
glx/rpi.h
glx/streaming.h
glx/utils.h
)

View File

@@ -31,17 +31,17 @@
#define skip_glBlendColor
#define skip_glBlendFunc
#define skip_glBlendEquation
#define skip_glBlendEquationSeparate
#define skip_glBlendEquationSeparatei
#define skip_glBlendFuncSeparate
#define skip_glBlendFuncSeparatei
#define skip_glFogfv
#define skip_glPointParameterfv
#define skip_glPointParameterf
//#define skip_glBlendEquation
#define skip_glBlendEquationSeparate
#define skip_glBlendEquationSeparatei
#define skip_glBlendFuncSeparate
#define skip_glBlendFuncSeparatei
// getter.c
#define skip_glGetError
@@ -78,6 +78,8 @@
#define skip_glTexImage2D
#define skip_glTexParameteri
#define skip_glTexParameterf
#define skip_glTexParameterfv
#define skip_glTexParameteriv
#define skip_glTexSubImage2D
#define skip_glActiveTexture
#define skip_glClientActiveTexture

150
project/jni/gl4es/src/gl/blend.c Executable file
View File

@@ -0,0 +1,150 @@
#include "blend.h"
#include "debug.h"
#include "../glx/hardext.h"
#include "init.h"
void gl4es_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
PUSH_IF_COMPILING(glBlendColor);
LOAD_GLES_OR_OES(glBlendColor);
if (gles_glBlendColor)
gles_glBlendColor(red, green, blue, alpha);
else {
static int test = 1;
if (test) {
LOGD("stub glBlendColor(%f, %f, %f, %f)\n", red, green, blue, alpha);
test = 0;
}
}
}
void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor");
void glBlendColorEXT(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor");
void glBlendColorARB(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor");
void gl4es_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
{
PUSH_IF_COMPILING(glBlendFuncSeparate);
LOAD_GLES_OES(glBlendFuncSeparate);
#ifndef PANDORA
if(gles_glBlendFuncSeparate==NULL) {
// some fallback function to have better rendering with SDL2, better then nothing...
if(sfactorRGB==GL_SRC_ALPHA && dfactorRGB==GL_ONE_MINUS_SRC_ALPHA && sfactorAlpha==GL_ONE && dfactorAlpha==GL_ONE_MINUS_SRC_ALPHA)
gl4es_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
else if (sfactorRGB==GL_SRC_ALPHA && dfactorRGB==GL_ONE && sfactorAlpha==GL_ZERO && dfactorAlpha==GL_ONE)
gl4es_glBlendFunc(GL_SRC_ALPHA, GL_ONE);
else if (sfactorRGB==GL_ZERO && dfactorRGB==GL_SRC_COLOR && sfactorAlpha==GL_ZERO && dfactorAlpha==GL_ONE)
gl4es_glBlendFunc(GL_ZERO, GL_SRC_COLOR);
else if (sfactorRGB==sfactorAlpha && dfactorRGB==dfactorAlpha)
gl4es_glBlendFunc(sfactorRGB, dfactorRGB);
} else
#endif
gles_glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
}
void glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) AliasExport("gl4es_glBlendFuncSeparate");
void glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) AliasExport("gl4es_glBlendFuncSeparate");
void gl4es_glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) {
PUSH_IF_COMPILING(glBlendEquationSeparate);
LOAD_GLES_OES(glBlendEquationSeparate);
#ifndef PANDORA
if(gles_glBlendEquationSeparate)
#endif
gles_glBlendEquationSeparate(modeRGB, modeA);
}
void glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) AliasExport("gl4es_glBlendEquationSeparate");
void glBlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) AliasExport("gl4es_glBlendEquationSeparate");
void gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor) {
if (glstate->list.active)
if (!glstate->list.compiling && glstate->gl_batch) {
if ((glstate->statebatch.blendfunc_s == sfactor) && (glstate->statebatch.blendfunc_d == dfactor))
return; // nothing to do...
if (!glstate->statebatch.blendfunc_s) {
glstate->statebatch.blendfunc_s = sfactor;
glstate->statebatch.blendfunc_d = dfactor;
}
}
PUSH_IF_COMPILING(glBlendFunc)
LOAD_GLES(glBlendFunc);
LOAD_GLES_OES(glBlendFuncSeparate);
errorGL();
// There are some limitations in GLES1.1 Blend functions
switch(sfactor) {
#if 0
case GL_SRC_COLOR:
if (gles_glBlendFuncSeparate) {
gles_glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
return;
}
sfactor = GL_ONE; // approx...
break;
case GL_ONE_MINUS_SRC_COLOR:
if (gles_glBlendFuncSeparate) {
gles_glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
return;
}
sfactor = GL_ONE; // not sure it make sense...
break;
#endif
// here, we need support for glBlendColor...
case GL_CONSTANT_COLOR:
case GL_CONSTANT_ALPHA:
if(hardext.blendcolor==0)
sfactor = GL_ONE;
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
case GL_ONE_MINUS_CONSTANT_ALPHA:
if(hardext.blendcolor==0)
sfactor = GL_ZERO;
break;
default:
break;
}
switch(dfactor) {
#if 0
case GL_DST_COLOR:
sfactor = GL_ONE; // approx...
break;
case GL_ONE_MINUS_DST_COLOR:
sfactor = GL_ZERO; // not sure it make sense...
break;
#endif
// here, we need support for glBlendColor...
case GL_CONSTANT_COLOR:
case GL_CONSTANT_ALPHA:
if(hardext.blendcolor==0)
sfactor = GL_ONE;
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
case GL_ONE_MINUS_CONSTANT_ALPHA:
if(hardext.blendcolor==0)
sfactor = GL_ZERO;
break;
default:
break;
}
if ((globals4es.blendhack) && (sfactor==GL_SRC_ALPHA) && (dfactor==GL_ONE)) {
// special case, as seen in Xash3D, but it breaks torus_trooper, so behind a parameter
sfactor = GL_ONE;
}
#ifdef ODROID
if(gles_glBlendFunc)
#endif
gles_glBlendFunc(sfactor, dfactor);
}
void glBlendFunc(GLenum sfactor, GLenum dfactor) AliasExport("gl4es_glBlendFunc");
void gl4es_glBlendEquation(GLenum mode) {
PUSH_IF_COMPILING(glBlendEquation)
LOAD_GLES_OR_OES(glBlendEquation);
errorGL();
#ifdef ODROID
if(gles_glBlendEquation)
#endif
gles_glBlendEquation(mode);
}
void glBlendEquation(GLenum mode) AliasExport("gl4es_glBlendEquation");
void glBlendEquationEXT(GLenum mode) AliasExport("gl4es_glBlendEquation");

View File

@@ -0,0 +1,13 @@
#include "gl.h"
#ifndef GL_BLEND_H
#define GL_BLEND_H
void gl4es_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
void gl4es_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
void gl4es_glBlendEquationSeparate(GLenum modeRGB, GLenum modeA);
void gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor);
void gl4es_glBlendEquation(GLenum mode);
#endif //GL_BLEND_H

View File

@@ -61,7 +61,7 @@
#define GL_TEXTURE_LOD_BIAS 0x8501
#define GL_TEXTURE_CUBE_MAP 0x8513
#define GL_TEXTURE_GEN_STR 0x8D60
#define GL_CLAMP_TO_BORDER 0x812D
// GL_ARB_point_sprite
#define GL_POINT_SPRITE 0x8861
@@ -197,6 +197,11 @@
#define GL_LINEAR 0x2601
#define GL_EXP 0x0800
#define GL_EXP2 0x0801
#define GL_FOG_COORDINATE_SOURCE 0x8450
#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE
#define GL_FRAGMENT_DEPTH 0x8452
#define GL_FOG_COORDINATE 0x8451
#define GL_FOG_COORD GL_FOG_COORDINATE
// lighting
#define GL_LIGHTING 0x0B50

54
project/jni/gl4es/src/gl/fog.c Executable file
View File

@@ -0,0 +1,54 @@
#include "fog.h"
#include "../glx/hardext.h"
#include "matrix.h"
#include "matvec.h"
void gl4es_glFogfv(GLenum pname, const GLfloat* params) {
if (glstate->list.active)
if (glstate->list.compiling || glstate->gl_batch) {
NewStage(glstate->list.active, STAGE_FOG);
rlFogOp(glstate->list.active, pname, params);
return;
}
else flush();
noerrorShim();
#define GO(A,name, size) if(memcmp(A glstate->fog.name, params, size)==0) return; else memcpy(A glstate->fog.name, params, size);
switch (pname) {
case GL_FOG_MODE:
GO(&, mode, sizeof(GLfloat))
break;
case GL_FOG_DENSITY:
GO(&, density, sizeof(GLfloat))
break;
case GL_FOG_START:
GO(&, start, sizeof(GLfloat))
break;
case GL_FOG_END:
GO(&, end, sizeof(GLfloat))
break;
case GL_FOG_INDEX:
GO(&, index, sizeof(GLfloat))
return; // unsupported on GLES1.1
case GL_FOG_COLOR:
GO(, color, 4*sizeof(GLfloat))
break;
case GL_FOG_COORD_SRC:
GO(&, coord_src, sizeof(GLfloat))
return; // unsupported on GLES1.1
default:
errorShim(GL_INVALID_ENUM);
return;
}
#undef GO
LOAD_GLES(glFogfv);
gles_glFogfv(pname, params);
errorGL();
}
void glFogfv(GLenum pname, const GLfloat* params) AliasExport("gl4es_glFogfv");

18
project/jni/gl4es/src/gl/fog.h Executable file
View File

@@ -0,0 +1,18 @@
#include "gl.h"
#ifndef __FOG_H_
#define __FOG_H_
typedef struct {
GLenum mode;
GLfloat density;
GLfloat start;
GLfloat end;
GLfloat index;
GLfloat color[4];
GLenum coord_src;
} fog_t;
void gl4es_glFogfv(GLenum pname, const GLfloat* params);
#endif

View File

@@ -5,6 +5,14 @@
#ifndef ANDROID
#include <execinfo.h>
#endif
//#define DEBUG
#ifdef DEBUG
#define DBG(a) a
#else
#define DBG(a)
#endif
//extern void* eglGetProcAddress(const char* name);
khash_t(dsr) *depthstencil = NULL;
@@ -31,7 +39,7 @@ int cap_fbos = 0;
int npot(int n);
void readfboBegin() {
//printf("readfboBegin, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb);
DBG(printf("readfboBegin, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb);)
LOAD_GLES_OES(glBindFramebuffer);
if (!(fbo_read || fbo_draw))
return;
@@ -42,7 +50,7 @@ void readfboBegin() {
}
void readfboEnd() {
//printf("readfboEnd, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb);
DBG(printf("readfboEnd, fbo status read=%u, draw=%u, main=%u, current=%u\n", fbo_read, fbo_draw, mainfbo_fbo, current_fb);)
LOAD_GLES_OES(glBindFramebuffer);
if (!(fbo_read || fbo_draw))
return;
@@ -53,11 +61,11 @@ void readfboEnd() {
}
void gl4es_glGenFramebuffers(GLsizei n, GLuint *ids) {
DBG(printf("glGenFramebuffers(%i, %p)\n", n, ids);)
LOAD_GLES_OES(glGenFramebuffers);
//printf("glGenFramebuffers(%i, %p)\n", n, ids);
GLsizei m = 0;
while(globals4es.recyclefbo && (nbr_fbos>0) && (n-m>0)) {
//printf("Recycled 1 FBO\n");
DBG(printf("Recycled 1 FBO\n");)
ids[m++] = old_fbos[--nbr_fbos];
}
noerrorShim();
@@ -68,10 +76,10 @@ void gl4es_glGenFramebuffers(GLsizei n, GLuint *ids) {
}
void gl4es_glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) {
//printf("glDeleteFramebuffers(%i, %p), framebuffers[0]=%u\n", n, framebuffers, framebuffers[0]);
DBG(printf("glDeleteFramebuffers(%i, %p), framebuffers[0]=%u\n", n, framebuffers, framebuffers[0]);)
if (glstate->gl_batch) flush();
if (globals4es.recyclefbo) {
//printf("Recycling %i FBOs\n", n);
DBG(printf("Recycling %i FBOs\n", n);)
noerrorShim();
if(cap_fbos == 0) {
cap_fbos = 16;
@@ -91,7 +99,7 @@ void gl4es_glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) {
}
GLboolean gl4es_glIsFramebuffer(GLuint framebuffer) {
//printf("glIsFramebuffer(%u)\n", framebuffer);
DBG(printf("glIsFramebuffer(%u)\n", framebuffer);)
if (glstate->gl_batch) flush();
LOAD_GLES_OES(glIsFramebuffer);
@@ -114,14 +122,14 @@ GLenum gl4es_glCheckFramebufferStatus(GLenum target) {
GLenum result = gles_glCheckFramebufferStatus(target);
#endif
#undef BEFORE
//printf("glCheckFramebufferStatus(0x%04X)=0x%04X\n", target, result);
DBG(printf("glCheckFramebufferStatus(0x%04X)=0x%04X\n", target, result);)
return result;
}
void gl4es_glBindFramebuffer(GLenum target, GLuint framebuffer) {
//printf("glBindFramebuffer(%s, %u), list=%s\n", PrintEnum(target), framebuffer, glstate->list.active?"active":"none");
//PUSH_IF_COMPILING(glBindFramebuffer);
DBG(printf("glBindFramebuffer(%s, %u), list=%s, current_fb=%d (draw=%d, read=%d)\n", PrintEnum(target), framebuffer, glstate->list.active?"active":"none", current_fb, fbo_draw, fbo_read);)
if (glstate->gl_batch) flush();
PUSH_IF_COMPILING(glBindFramebuffer);
LOAD_GLES_OES(glBindFramebuffer);
LOAD_GLES_OES(glCheckFramebufferStatus);
LOAD_GLES(glGetError);
@@ -162,8 +170,36 @@ void gl4es_glBindFramebuffer(GLenum target, GLuint framebuffer) {
fb_status = gles_glCheckFramebufferStatus(target);
}
GLenum ReadDraw_Push(GLenum target) {
if(target==GL_FRAMEBUFFER)
return GL_FRAMEBUFFER;
LOAD_GLES_OES(glBindFramebuffer);
if(target==GL_DRAW_FRAMEBUFFER) {
if(current_fb!=fbo_draw)
gles_glBindFramebuffer(GL_FRAMEBUFFER, fbo_draw);
return GL_FRAMEBUFFER;
}
if(target==GL_READ_FRAMEBUFFER) {
if(current_fb!=fbo_read)
gles_glBindFramebuffer(GL_FRAMEBUFFER, fbo_read);
return GL_FRAMEBUFFER;
}
return target;
}
void ReadDraw_Pop(GLenum target) {
if(target==GL_FRAMEBUFFER)
return;
LOAD_GLES_OES(glBindFramebuffer);
if(target==GL_DRAW_FRAMEBUFFER && current_fb!=fbo_draw) {
gles_glBindFramebuffer(GL_FRAMEBUFFER, (mainfbo_fbo && (current_fb==0))?mainfbo_fbo:current_fb);
}
if(target==GL_READ_FRAMEBUFFER && current_fb!=fbo_read) {
gles_glBindFramebuffer(GL_FRAMEBUFFER, (mainfbo_fbo && (current_fb==0))?mainfbo_fbo:current_fb);
}
}
void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
DBG(printf("glFramebufferTexture2D(%s, %s, %s, %u, %i) current_fb=%d (draw=%d, read=%d)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(textarget), texture, level, current_fb, fbo_draw, fbo_read);)
static GLuint scrap_tex = 0;
static int scrap_width = 0;
static int scrap_height = 0;
@@ -172,7 +208,6 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta
LOAD_GLES_OES(glFramebufferTexture2D);
LOAD_GLES(glTexImage2D);
LOAD_GLES(glBindTexture);
//printf("glFramebufferTexture2D(%s, %s, %s, %u, %i)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(textarget), texture, level);
// Ignore Color attachment 1 .. 9
if ((attachment>=GL_COLOR_ATTACHMENT0+1) && (attachment<=GL_COLOR_ATTACHMENT0+9)) {
@@ -227,10 +262,12 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta
gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL);
if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, oldtex);
}*/
//printf("found texture, glname=%u, size=%ix%i(%ix%i), format/type=0x%04X/0x%04X\n", texture, tex->width, tex->height, tex->nwidth, tex->nheight, tex->format, tex->type);
DBG(printf("found texture, glname=%u, size=%ix%i(%ix%i), format/type=0x%04X/0x%04X\n", texture, tex->width, tex->height, tex->nwidth, tex->nheight, tex->format, tex->type);)
}
}
GLenum ntarget = ReadDraw_Push(target);
if(attachment==GL_DEPTH_ATTACHMENT /*&& hardext.depthtex==0*/) {
noerrorShim();
if (level!=0) return;
@@ -241,7 +278,8 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta
gl4es_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, twidth, theight);
gl4es_glBindRenderbuffer(GL_RENDERBUFFER, 0);
errorGL();
gl4es_glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth);
gl4es_glFramebufferRenderbuffer(ntarget, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth);
ReadDraw_Pop(target);
return;
}
@@ -265,7 +303,8 @@ void gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texta
}
errorGL();
gles_glFramebufferTexture2D(target, attachment, textarget, texture, 0);
gles_glFramebufferTexture2D(ntarget, attachment, textarget, texture, 0);
ReadDraw_Pop(target);
}
void gl4es_glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
@@ -277,17 +316,17 @@ void gl4es_glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum texta
}
void gl4es_glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) {
DBG(printf("glGenRenderbuffers(%i, %p)\n", n, renderbuffers);)
LOAD_GLES_OES(glGenRenderbuffers);
//printf("glGenRenderbuffers(%i, %p)\n", n, renderbuffers);
errorGL();
gles_glGenRenderbuffers(n, renderbuffers);
}
void gl4es_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
DBG(printf("glFramebufferRenderbuffer(%s, %s, %s, %u)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(renderbuffertarget), renderbuffer);)
LOAD_GLES_OES(glFramebufferRenderbuffer);
LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv);
//printf("glFramebufferRenderbuffer(%s, %s, %s, %u)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(renderbuffertarget), renderbuffer);
//TODO: handle target=READBUFFER or DRAWBUFFER...
if (depthstencil && (attachment==GL_STENCIL_ATTACHMENT)) {
@@ -304,21 +343,26 @@ void gl4es_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum re
noerrorShim();
return;
}
GLenum ntarget = ReadDraw_Push(target);
if ((current_fb!=0) && (renderbuffer!=0) && ((attachment==GL_DEPTH_ATTACHMENT) || (attachment==GL_STENCIL_ATTACHMENT))) {
GLuint tmp;
gles_glGetFramebufferAttachmentParameteriv(target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tmp);
gles_glGetFramebufferAttachmentParameteriv(ntarget, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tmp);
if (tmp==renderbuffer) {
noerrorShim();
ReadDraw_Pop(target);
return;
}
}
errorGL();
gles_glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
gles_glFramebufferRenderbuffer(ntarget, attachment, renderbuffertarget, renderbuffer);
ReadDraw_Pop(target);
}
void gl4es_glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) {
DBG(printf("glDeleteRenderbuffer(%d, %p)\n", n, renderbuffers);)
if (glstate->gl_batch) flush();
LOAD_GLES_OES(glDeleteRenderbuffers);
@@ -345,10 +389,10 @@ void gl4es_glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) {
}
void gl4es_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
DBG(printf("glRenderbufferStorage(%s, %s, %i, %i)\n", PrintEnum(target), PrintEnum(internalformat), width, height);)
LOAD_GLES_OES(glRenderbufferStorage);
LOAD_GLES_OES(glGenRenderbuffers);
LOAD_GLES_OES(glBindRenderbuffer);
//printf("glRenderbufferStorage(0x%04X, 0x%04X, %i, %i)\n", target, internalformat, width, height);
errorGL();
width = hardext.npot==2?width:npot(width);
@@ -401,9 +445,9 @@ void gl4es_glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLen
}
void gl4es_glBindRenderbuffer(GLenum target, GLuint renderbuffer) {
DBG(printf("glBindRenderbuffer(%s, %u), binded Fbo=%u\n", PrintEnum(target), renderbuffer, current_fb);)
if (glstate->gl_batch) flush();
LOAD_GLES_OES(glBindRenderbuffer);
//printf("glBindRenderbuffer(%s, %u), binded Fbo=%u\n", PrintEnum(target), renderbuffer, current_fb);
current_rb = renderbuffer;
@@ -412,7 +456,7 @@ void gl4es_glBindRenderbuffer(GLenum target, GLuint renderbuffer) {
}
GLboolean gl4es_glIsRenderbuffer(GLuint renderbuffer) {
//printf("glIsRenderbuffer(%u)\n", renderbuffer);
DBG(printf("glIsRenderbuffer(%u)\n", renderbuffer);)
if (glstate->gl_batch) flush();
LOAD_GLES_OES(glIsRenderbuffer);
@@ -421,36 +465,40 @@ GLboolean gl4es_glIsRenderbuffer(GLuint renderbuffer) {
}
void gl4es_glGenerateMipmap(GLenum target) {
//printf("glGenerateMipmap(0x%04X)\n", target);
DBG(printf("glGenerateMipmap(%s)\n", PrintEnum(target));)
LOAD_GLES_OES(glGenerateMipmap);
errorGL();
return gles_glGenerateMipmap(target);
if(globals4es.automipmap != 3)
gles_glGenerateMipmap(target);
}
void gl4es_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) {
//printf("glGetFramebufferAttachmentParameteriv(%s, %s, %s, %p)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(pname), params);
DBG(printf("glGetFramebufferAttachmentParameteriv(%s, %s, %s, %p)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(pname), params);)
LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv);
GLenum ntarget = ReadDraw_Push(target);
// hack to return DEPTH size
if(target==GL_FRAMEBUFFER && attachment==GL_DEPTH_ATTACHMENT && pname==GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE && hardext.depthtex==0) {
if(ntarget==GL_FRAMEBUFFER && attachment==GL_DEPTH_ATTACHMENT && pname==GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE && hardext.depthtex==0) {
noerrorShim();
gl4es_glGetFramebufferAttachmentParameteriv(target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, params);
gl4es_glGetFramebufferAttachmentParameteriv(ntarget, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, params);
if (params)
*params = 16; //Depth buffer is 16 on GLES. No check for 24 bits here...
ReadDraw_Pop(target);
return;
}
errorGL();
return gles_glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
gles_glGetFramebufferAttachmentParameteriv(ntarget, attachment, pname, params);
ReadDraw_Pop(target);
}
void gl4es_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint * params) {
//printf("glGetRenderbufferParameteriv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(pname), params);
DBG(printf("glGetRenderbufferParameteriv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(pname), params);)
LOAD_GLES_OES(glGetRenderbufferParameteriv);
errorGL();
return gles_glGetRenderbufferParameteriv(target, pname, params);
gles_glGetRenderbufferParameteriv(target, pname, params);
}
void createMainFBO(int width, int height) {
@@ -737,8 +785,8 @@ void gl4es_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
// glCopyPixel of read FBO
// set viewport / matrixs
// glDraw of write FBO
printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, 0x%04X, 0x%04X)\n",
srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
DBG(printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, 0x%04X, 0x%04X)\n",
srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);)
}
// direct wrapper

View File

@@ -179,6 +179,12 @@ void gl4es_glGetIntegerv(GLenum pname, GLint *params) {
case GL_MAX_DRAW_BUFFERS_ARB: // fake...
*params = 1;
break;
case GL_PACK_ALIGNMENT:
*params = glstate->texture.pack_align;
break;
case GL_UNPACK_ALIGNMENT:
*params = glstate->texture.unpack_align;
break;
case GL_UNPACK_ROW_LENGTH:
*params = glstate->texture.unpack_row_length;
break;
@@ -310,39 +316,64 @@ void gl4es_glGetIntegerv(GLenum pname, GLint *params) {
for (dummy=0; dummy<4; dummy++)
params[dummy]=glstate->light.ambient[dummy];
break;
case GL_FOG_MODE:
*params=glstate->fog.mode;
break;
case GL_FOG_DENSITY:
*params=glstate->fog.density;
break;
case GL_FOG_START:
*params=glstate->fog.start;
break;
case GL_FOG_END:
*params=glstate->fog.end;
break;
case GL_FOG_INDEX:
*params=glstate->fog.start;
break;
case GL_FOG_COLOR:
for (dummy=0; dummy<4; dummy++)
params[dummy]=glstate->fog.color[dummy];
break;
case GL_FOG_COORD_SRC:
*params=glstate->fog.coord_src;
break;
case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
*params=hardext.maxsize;
break;
case GL_SHRINK_HINT_GL4ES:
*params=globals4es.texshrink;
break;
case GL_ALPHAHACK_HINT_GL4ES:
case GL_ALPHAHACK_HINT_GL4ES:
*params=globals4es.alphahack;
break;
case GL_RECYCLEFBO_HINT_GL4ES:
case GL_RECYCLEFBO_HINT_GL4ES:
*params=globals4es.recyclefbo;
break;
case GL_MIPMAP_HINT_GL4ES:
case GL_MIPMAP_HINT_GL4ES:
*params=globals4es.automipmap;
break;
case GL_TEXDUMP_HINT_GL4ES:
case GL_TEXDUMP_HINT_GL4ES:
*params=globals4es.texdump;
break;
case GL_COPY_HINT_GL4ES:
case GL_COPY_HINT_GL4ES:
*params=globals4es.copytex;
break;
case GL_NOLUMAPHA_HINT_GL4ES:
case GL_NOLUMAPHA_HINT_GL4ES:
*params=globals4es.nolumalpha;
break;
case GL_BLENDHACK_HINT_GL4ES:
case GL_BLENDHACK_HINT_GL4ES:
*params=globals4es.blendhack;
break;
case GL_BATCH_HINT_GL4ES:
case GL_BATCH_HINT_GL4ES:
*params=globals4es.batch;
break;
case GL_NOERROR_HINT_GL4ES:
case GL_NOERROR_HINT_GL4ES:
*params=globals4es.noerror;
break;
case GL_AVOID16BITS_HINT_GL4ES:
*params=globals4es.avoid16bits;
break;
default:
errorGL();
gles_glGetIntegerv(pname, params);
@@ -370,6 +401,12 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) {
case GL_AUX_BUFFERS:
*params = 0;
break;
case GL_PACK_ALIGNMENT:
*params = glstate->texture.pack_align;
break;
case GL_UNPACK_ALIGNMENT:
*params = glstate->texture.unpack_align;
break;
case GL_UNPACK_ROW_LENGTH:
*params = glstate->texture.unpack_row_length;
break;
@@ -489,6 +526,27 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) {
case GL_LIGHT_MODEL_AMBIENT:
memcpy(params, glstate->light.ambient, 4*sizeof(GLfloat));
break;
case GL_FOG_MODE:
*params=glstate->fog.mode;
break;
case GL_FOG_DENSITY:
*params=glstate->fog.density;
break;
case GL_FOG_START:
*params=glstate->fog.start;
break;
case GL_FOG_END:
*params=glstate->fog.end;
break;
case GL_FOG_INDEX:
*params=glstate->fog.start;
break;
case GL_FOG_COLOR:
memcpy(params, glstate->fog.color, 4*sizeof(GLfloat));
break;
case GL_FOG_COORD_SRC:
*params=glstate->fog.coord_src;
break;
case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
*params=hardext.maxsize;
break;
@@ -531,6 +589,9 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) {
case GL_BEGINEND_HINT_GL4ES:
*params=globals4es.beginend;
break;
case GL_AVOID16BITS_HINT_GL4ES:
*params=globals4es.avoid16bits;
break;
default:
errorGL();
gles_glGetFloatv(pname, params);

View File

@@ -53,6 +53,14 @@ void* NewGLState(void* shared_glstate) {
glvao->array = 0;
glstate->defaultvao = glvao;
}
// initialize gllists
{
khint_t k;
int ret;
khash_t(gllisthead) *list = glstate->headlists = kh_init(gllisthead);
kh_put(gllisthead, list, 1, &ret);
kh_del(gllisthead, list, 1);
}
// Bind defaults...
glstate->vao = glstate->defaultvao;
@@ -64,6 +72,10 @@ void* NewGLState(void* shared_glstate) {
glstate->raster.raster_zoomx=1.0f;
glstate->raster.raster_zoomy=1.0f;
// pack & unpack alignment
glstate->texture.pack_align = 4;
glstate->texture.unpack_align = 4;
// init the matrix tracking
init_matrix(glstate);
@@ -95,7 +107,12 @@ void* NewGLState(void* shared_glstate) {
glstate->material.front.emission[3] = 1.0f;
glstate->material.front.colormat = GL_AMBIENT_AND_DIFFUSE;
memcpy(&glstate->material.back, &glstate->material.front, sizeof(material_t));
// Fog
glstate->fog.mode = GL_EXP;
glstate->fog.density = 1.0f;
glstate->fog.end = 1.0f;
glstate->fog.coord_src = GL_FRAGMENT_DEPTH;
// Raster
for(int i=0; i<4; i++)
glstate->raster.raster_scale[i] = 1.0f;
LOAD_GLES(glGetFloatv);
@@ -117,18 +134,19 @@ void DeleteGLState(void* oldstate) {
glstate = NULL;
#define free_hashmap(T, N, K) \
#define free_hashmap(T, N, K, F) \
{ \
T *m; \
kh_foreach_value(state->N, m, \
free(m); \
F(m); \
) \
kh_destroy(K, state->N); \
}
free_hashmap(glvao_t, vaos, glvao);
free_hashmap(glbuffer_t, buffers, buff);
free_hashmap(glquery_t, queries, queries);
free_hashmap(gltexture_t, texture.list, tex);
free_hashmap(glvao_t, vaos, glvao, free);
free_hashmap(glbuffer_t, buffers, buff, free);
free_hashmap(glquery_t, queries, queries, free);
free_hashmap(gltexture_t, texture.list, tex, free);
free_hashmap(renderlist_t, headlists, gllisthead, free_renderlist);
#undef free_hashmap
// free eval maps
#define freemap(dims, name) \
@@ -143,12 +161,7 @@ void DeleteGLState(void* oldstate) {
freemap(2, vertex3); freemap(2, vertex4); freemap(2, index); freemap(2, color4); freemap(2, normal);
freemap(2, texture1); freemap(2, texture2); freemap(2, texture3); freemap(2, texture4);
#undef freemap
// free lists
if(state->lists) {
for (int i=0; i<state->list.count; i++)
free_renderlist(state->lists[i]);
free(state->lists);
}
// free active list
if(state->list.active) free_renderlist(state->list.active);
// free matrix stack
@@ -192,22 +205,15 @@ void gl_init() {
#endif
static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) {
#define proxy_enable(constant, name) \
#define proxy_GO(constant, name) \
case constant: glstate->enable.name = enable; next(cap); break
#define enable(constant, name) \
#define GO(constant, name) \
case constant: glstate->enable.name = enable; break;
#define proxy_clientenable(constant, name) \
#define proxy_clientGO(constant, name) \
case constant: glstate->vao->name = enable; next(cap); break
#define clientenable(constant, name) \
#define clientGO(constant, name) \
case constant: glstate->vao->name = enable; break;
// TODO: maybe could be weird behavior if someone tried to:
// 1. enable GL_TEXTURE_1D
// 2. enable GL_TEXTURE_2D
// 3. disable GL_TEXTURE_1D
// 4. render. GL_TEXTURE_2D would be disabled.
// cap = map_tex_target(cap);
// Alpha Hack
if (globals4es.alphahack && (cap==GL_ALPHA_TEST) && enable) {
if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D])
@@ -223,8 +229,8 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) {
glstate->enable.texture[glstate->texture.active] &= ~(1<<ENABLED_TEX2D);
#endif
switch (cap) {
enable(GL_AUTO_NORMAL, auto_normal);
proxy_enable(GL_BLEND, blend);
GO(GL_AUTO_NORMAL, auto_normal);
proxy_GO(GL_BLEND, blend);
case GL_TEXTURE_2D:
if(enable)
glstate->enable.texture[glstate->texture.active] |= (1<<ENABLED_TEX2D);
@@ -233,24 +239,24 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) {
next(cap);
break;
enable(GL_TEXTURE_GEN_S, texgen_s[glstate->texture.active]);
enable(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active]);
enable(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active]);
enable(GL_TEXTURE_GEN_Q, texgen_q[glstate->texture.active]);
enable(GL_LINE_STIPPLE, line_stipple);
GO(GL_TEXTURE_GEN_S, texgen_s[glstate->texture.active]);
GO(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active]);
GO(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active]);
GO(GL_TEXTURE_GEN_Q, texgen_q[glstate->texture.active]);
GO(GL_LINE_STIPPLE, line_stipple);
// point sprite
proxy_enable(GL_POINT_SPRITE, pointsprite);
proxy_GO(GL_POINT_SPRITE, pointsprite);
// Secondary color
enable(GL_COLOR_SUM, color_sum);
clientenable(GL_SECONDARY_COLOR_ARRAY, secondary_array);
GO(GL_COLOR_SUM, color_sum);
clientGO(GL_SECONDARY_COLOR_ARRAY, secondary_array);
// for glDrawArrays
clientenable(GL_VERTEX_ARRAY, vertex_array);
clientenable(GL_NORMAL_ARRAY, normal_array);
clientenable(GL_COLOR_ARRAY, color_array);
clientenable(GL_TEXTURE_COORD_ARRAY, tex_coord_array[glstate->texture.client]);
clientGO(GL_VERTEX_ARRAY, vertex_array);
clientGO(GL_NORMAL_ARRAY, normal_array);
clientGO(GL_COLOR_ARRAY, color_array);
clientGO(GL_TEXTURE_COORD_ARRAY, tex_coord_array[glstate->texture.client]);
// Texture 1D and 3D
case GL_TEXTURE_1D:
@@ -282,10 +288,10 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) {
default: errorGL(); next(cap); break;
}
#undef proxy_enable
#undef enable
#undef proxy_clientenable
#undef clientenable
#undef proxy_GO
#undef GO
#undef proxy_clientGO
#undef clientGO
}
int Cap2BatchState(GLenum cap) {
@@ -318,6 +324,11 @@ void gl4es_glEnable(GLenum cap) {
if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]->streamed)
cap = GL_TEXTURE_STREAM_IMG;
}
if (globals4es.texstream && (cap==GL_TEXTURE_RECTANGLE_ARB)) {
if (glstate->texture.bound[glstate->texture.active][ENABLED_TEXTURE_RECTANGLE])
if (glstate->texture.bound[glstate->texture.active][ENABLED_TEXTURE_RECTANGLE]->streamed)
cap = GL_TEXTURE_STREAM_IMG;
}
#endif
LOAD_GLES(glEnable);
proxy_glEnable(cap, true, gles_glEnable);
@@ -337,12 +348,18 @@ void gl4es_glDisable(GLenum cap) {
}
PUSH_IF_COMPILING(glDisable)
#ifdef TEXSTREAM
if (globals4es.texstream && (cap==GL_TEXTURE_2D)) {
if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D])
if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]->streamed)
cap = GL_TEXTURE_STREAM_IMG;
}
if (globals4es.texstream && (cap==GL_TEXTURE_RECTANGLE_ARB)) {
if (glstate->texture.bound[glstate->texture.active][ENABLED_TEXTURE_RECTANGLE])
if (glstate->texture.bound[glstate->texture.active][ENABLED_TEXTURE_RECTANGLE]->streamed)
cap = GL_TEXTURE_STREAM_IMG;
}
#endif
LOAD_GLES(glDisable);
proxy_glEnable(cap, false, gles_glDisable);
}
@@ -1051,20 +1068,25 @@ void gl4es_glEnd() {
for (int a=0; a<MAX_TEX; a++)
if (glstate->enable.texture[a] && ((glstate->list.active->tex[a]==0) && !(glstate->enable.texgen_s[a] || glstate->texture.pscoordreplace[a])))
rlMultiTexCoord4f(glstate->list.active, GL_TEXTURE0+a, glstate->texcoord[a][0], glstate->texcoord[a][1], glstate->texcoord[a][2], glstate->texcoord[a][3]);
int withColor = 0;
// render if we're not in a display list
if (!(glstate->list.compiling || glstate->gl_batch) && (!(globals4es.beginend) || (glstate->polygon_mode==GL_LINE))) {
renderlist_t *mylist = glstate->list.active;
withColor = (mylist->color!=NULL);
glstate->list.active = NULL;
mylist = end_renderlist(mylist);
draw_renderlist(mylist);
free_renderlist(mylist);
} else {
if(!(glstate->list.compiling || glstate->gl_batch)) {
withColor = (glstate->list.active->color!=NULL);
glstate->list.pending = 1;
NewStage(glstate->list.active, STAGE_POSTDRAW);
}
else glstate->list.active = extend_renderlist(glstate->list.active);
}
if(withColor)
gl4es_glColor4f(glstate->color[0], glstate->color[1], glstate->color[2], glstate->color[3]);
noerrorShim();
}
void glEnd() AliasExport("gl4es_glEnd");
@@ -1272,9 +1294,12 @@ void glUnlockArraysEXT() AliasExport("gl4es_glUnlockArrays");
// display lists
static renderlist_t *gl4es_glGetList(GLuint list) {
if (glIsList(list))
return glstate->lists[list - 1];
khint_t k;
int ret;
khash_t(gllisthead) *lists = glstate->headlists;
k = kh_get(gllisthead, lists, list);
if (k != kh_end(lists))
return kh_value(lists, k);
return NULL;
}
@@ -1284,18 +1309,18 @@ GLuint gl4es_glGenLists(GLsizei range) {
return 0;
}
noerrorShim();
khint_t k;
int ret;
khash_t(gllisthead) *lists = glstate->headlists;
int start = glstate->list.count;
if (glstate->lists == NULL) {
glstate->list.cap += range + 100;
glstate->lists = malloc(glstate->list.cap * sizeof(uintptr_t));
} else if (glstate->list.count + range > glstate->list.cap) {
glstate->list.cap += range + 100;
glstate->lists = realloc(glstate->lists, glstate->list.cap * sizeof(uintptr_t));
}
glstate->list.count += range;
for (int i = 0; i < range; i++) {
glstate->lists[start+i] = NULL;
k = kh_get(gllisthead, lists, start+i);
if (k == kh_end(lists)){
k = kh_put(gllisthead, lists, start+i, &ret);
kh_value(lists, k) = NULL; // create an empty gllist
}
}
return start + 1;
}
@@ -1306,8 +1331,16 @@ void gl4es_glNewList(GLuint list, GLenum mode) {
errorShim(GL_INVALID_VALUE);
if (list==0)
return;
if (! glIsList(list))
return;
{
khint_t k;
int ret;
khash_t(gllisthead) *lists = glstate->headlists;
k = kh_get(gllisthead, lists, list);
if (k == kh_end(lists)){
k = kh_put(gllisthead, lists, list, &ret);
kh_value(lists, k) = NULL;
}
}
noerrorShim();
if (glstate->gl_batch) {
glstate->gl_batch = 0;
@@ -1324,10 +1357,20 @@ void glNewList(GLuint list, GLenum mode) AliasExport("gl4es_glNewList");
void gl4es_glEndList() {
noerrorShim();
GLuint list = glstate->list.name;
khash_t(gllisthead) *lists = glstate->headlists;
khint_t k;
{
int ret;
k = kh_get(gllisthead, lists, list);
if (k == kh_end(lists)){
k = kh_put(gllisthead, lists, list, &ret);
kh_value(lists, k) = NULL;
}
}
if (glstate->list.compiling) {
// Free the previous list if it exist...
free_renderlist(glstate->lists[list - 1]);
glstate->lists[list - 1] = GetFirst(glstate->list.active);
free_renderlist(kh_value(lists, k));
kh_value(lists, k) = GetFirst(glstate->list.active);
glstate->list.compiling = false;
end_renderlist(glstate->list.active);
glstate->list.active = NULL;
@@ -1403,13 +1446,19 @@ void gl4es_glDeleteList(GLuint list) {
if(glstate->gl_batch) {
flush();
}
renderlist_t *l = gl4es_glGetList(list);
if (l) {
free_renderlist(l);
glstate->lists[list-1] = NULL;
renderlist_t *gllist = NULL;
{
khint_t k;
int ret;
khash_t(gllisthead) *lists = glstate->headlists;
k = kh_get(gllisthead, lists, list);
renderlist_t *gllist = NULL;
if (k != kh_end(lists)){
gllist = kh_value(lists, k);
free_renderlist(gllist);
kh_del(gllisthead, lists, k);
}
}
// lists just grow upwards, maybe use a better storage mechanism?
}
void gl4es_glDeleteLists(GLuint list, GLsizei range) {
@@ -1428,9 +1477,12 @@ void glListBase(GLuint base) AliasExport("gl4es_glListBase");
GLboolean gl4es_glIsList(GLuint list) {
noerrorShim();
if (list - 1 < glstate->list.count) {
khint_t k;
int ret;
khash_t(gllisthead) *lists = glstate->headlists;
k = kh_get(gllisthead, lists, list);
if (k != kh_end(lists))
return true;
}
return false;
}
GLboolean glIsList(GLuint list) AliasExport("gl4es_glIsList");
@@ -1463,122 +1515,6 @@ void gl4es_glPolygonMode(GLenum face, GLenum mode) {
}
void glPolygonMode(GLenum face, GLenum mode) AliasExport("gl4es_glPolygonMode");
void gl4es_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
PUSH_IF_COMPILING(glBlendColor);
LOAD_GLES_OES(glBlendColor);
if (gles_glBlendColor)
gles_glBlendColor(red, green, blue, alpha);
else {
static int test = 1;
if (test) {
LOGD("stub glBlendColor(%f, %f, %f, %f)\n", red, green, blue, alpha);
test = 0;
}
}
}
void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor");
void glBlendColorEXT(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor");
void glBlendColorARB(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) AliasExport("gl4es_glBlendColor");
void gl4es_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
{
PUSH_IF_COMPILING(glBlendFuncSeparate);
LOAD_GLES_OES(glBlendFuncSeparate);
#ifdef ODROID
if(gles_glBlendFuncSeparate)
#endif
gles_glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
}
void glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) AliasExport("gl4es_glBlendFuncSeparate");
void glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) AliasExport("gl4es_glBlendFuncSeparate");
void gl4es_glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) {
PUSH_IF_COMPILING(glBlendEquationSeparate);
LOAD_GLES_OES(glBlendEquationSeparate);
#ifdef ODROID
if(gles_glBlendEquationSeparate)
#endif
gles_glBlendEquationSeparate(modeRGB, modeA);
}
void glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) AliasExport("gl4es_glBlendEquationSeparate");
void glBlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) AliasExport("gl4es_glBlendEquationSeparate");
void gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor) {
if (glstate->list.active)
if (!glstate->list.compiling && glstate->gl_batch) {
if ((glstate->statebatch.blendfunc_s == sfactor) && (glstate->statebatch.blendfunc_d == dfactor))
return; // nothing to do...
if (!glstate->statebatch.blendfunc_s) {
glstate->statebatch.blendfunc_s = sfactor;
glstate->statebatch.blendfunc_d = dfactor;
}
}
PUSH_IF_COMPILING(glBlendFunc)
LOAD_GLES(glBlendFunc);
LOAD_GLES_OES(glBlendFuncSeparate);
errorGL();
// There are some limitations in GLES1.1 Blend functions
switch(sfactor) {
case GL_SRC_COLOR:
if (gles_glBlendFuncSeparate) {
gles_glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
return;
}
sfactor = GL_ONE; // approx...
break;
case GL_ONE_MINUS_SRC_COLOR:
if (gles_glBlendFuncSeparate) {
gles_glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
return;
}
sfactor = GL_ONE; // not sure it make sense...
break;
// here, we need support for glBlendColor...
case GL_CONSTANT_COLOR:
case GL_CONSTANT_ALPHA:
sfactor = GL_ONE;
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
case GL_ONE_MINUS_CONSTANT_ALPHA:
sfactor = GL_ZERO;
break;
default:
break;
}
switch(dfactor) {
case GL_DST_COLOR:
sfactor = GL_ONE; // approx...
break;
case GL_ONE_MINUS_DST_COLOR:
sfactor = GL_ZERO; // not sure it make sense...
break;
// here, we need support for glBlendColor...
case GL_CONSTANT_COLOR:
case GL_CONSTANT_ALPHA:
sfactor = GL_ONE;
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
case GL_ONE_MINUS_CONSTANT_ALPHA:
sfactor = GL_ZERO;
break;
default:
break;
}
if ((globals4es.blendhack) && (sfactor==GL_SRC_ALPHA) && (dfactor==GL_ONE)) {
// special case, as seen in Xash3D, but it breaks torus_trooper, so behind a parameter
sfactor = GL_ONE;
}
#ifdef ODROID
if(gles_glBlendFunc)
#endif
gles_glBlendFunc(sfactor, dfactor);
}
void glBlendFunc(GLenum sfactor, GLenum dfactor) AliasExport("gl4es_glBlendFunc");
void gl4es_glStencilMaskSeparate(GLenum face, GLuint mask) {
// fake function..., call it only for front or front_and_back, just ignore back (crappy, I know)
@@ -1647,21 +1583,6 @@ void gl4es_glFinish() {
}
void glFinish() AliasExport("gl4es_glFinish");
void gl4es_glFogfv(GLenum pname, const GLfloat* params) {
if (glstate->list.active)
if (glstate->list.compiling || glstate->gl_batch) {
NewStage(glstate->list.active, STAGE_FOG);
rlFogOp(glstate->list.active, pname, params);
return;
}
else flush();
LOAD_GLES(glFogfv);
gles_glFogfv(pname, params);
}
void glFogfv(GLenum pname, const GLfloat* params) AliasExport("gl4es_glFogfv");
void gl4es_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) {
static bool warning = false;
if(!warning) {

View File

@@ -369,6 +369,7 @@ static inline const GLboolean valid_vertex_type(GLenum type) {
#include "texture.h"
#include "array.h"
#include "framebuffers.h"
#include "blend.h"
const GLubyte *gl4es_glGetString(GLenum name);
void gl4es_glGetIntegerv(GLenum pname, GLint *params);
@@ -415,10 +416,6 @@ void gl4es_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, cons
void gl4es_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer);
void gl4es_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer);
void gl4es_glGetPointerv(GLenum pname, GLvoid* *params);
void gl4es_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
void gl4es_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
void gl4es_glBlendEquationSeparate(GLenum modeRGB, GLenum modeA);
void gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor);
void gl4es_glFlush();
void gl4es_glFinish();
void gl4es_glFogfv(GLenum pname, const GLfloat* params);

View File

@@ -89,6 +89,12 @@ void gl4es_glHint(GLenum pname, GLenum mode) {
globals4es.beginend = mode;
else
errorShim(GL_INVALID_ENUM);
case GL_AVOID16BITS_HINT_GL4ES:
if (mode<=1)
globals4es.avoid16bits = mode;
else
errorShim(GL_INVALID_ENUM);
break;
default:
errorGL();
gles_glHint(pname, mode);

View File

@@ -86,14 +86,14 @@ void initialize_gl4es() {
}
if (env_fb && strcmp(env_fb, "2") == 0) {
SHUT(LOGD("LIBGL: using framebuffer + fbo\n"));
globals4es.usefb = true;
globals4es.usefbo = true;
globals4es.usefb = 1;
globals4es.usefbo = 1;
}
#ifndef ANDROID
if (env_fb && strcmp(env_fb, "3") == 0) {
SHUT(LOGD("LIBGL: using pbuffer\n"));
globals4es.usefb = 1;
globals4es.usepbuffer = true;
globals4es.usepbuffer = 1;
}
#endif
env(LIBGL_FPS, globals4es.showfps, "fps counter enabled");
@@ -283,6 +283,7 @@ void initialize_gl4es() {
SHUT(LOGD("LIBGL: Try hard to merge subsequent glBegin/glEnd blocks, even if there is a glColor / glNormal or Matrix operations in between\n"));
}
}
env(LIBGL_AVOID16BITS, globals4es.avoid16bits, "Avoid 16bits textures");
char cwd[1024];
if (getcwd(cwd, sizeof(cwd))!= NULL)

View File

@@ -41,6 +41,7 @@ typedef struct _globals4es {
int texmat;
int novaocache;
int beginend;
int avoid16bits;
char version[50];
} globals4es_t;

View File

@@ -173,16 +173,23 @@ void gl4es_glLightf(GLenum light, GLenum pname, const GLfloat params) {
}
void gl4es_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
ERROR_IN_BEGIN // that not true, but don't know how to handle it
if(glstate->list.active)
if (glstate->list.compiling || glstate->gl_batch) {
//TODO: Materialfv can be done per vertex, how to handle that ?!
//NewStage(glstate->list.active, STAGE_MATERIAL);
rlMaterialfv(glstate->list.active, face, pname, params);
noerrorShim();
return;
} else flush();
if(glstate->list.begin) {
// if a glMaterialfv is called inside a glBegin/glEnd block
// then use rlMaterial to store in current list the material wanted
// as if the material was asked before the glBegin()
// It's not real behavour, but it's better then nothing
rlMaterialfv(glstate->list.active, face, pname, params);
noerrorShim();
return;
} else {
if (glstate->list.compiling || glstate->gl_batch) {
NewStage(glstate->list.active, STAGE_MATERIAL);
rlMaterialfv(glstate->list.active, face, pname, params);
noerrorShim();
return;
} else flush();
}
if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) {
errorShim(GL_INVALID_ENUM);
return;

View File

@@ -500,7 +500,7 @@ renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a)
a->shared_indices = (int*)malloc(sizeof(int));
*a->shared_indices = 0;
}
if(a->calls.cap && !a->shared_calls) {
if(a->calls.len && !a->shared_calls) {
a->shared_calls = (int*)malloc(sizeof(int));
*a->shared_calls = 0;
}
@@ -523,7 +523,7 @@ renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a)
}
}
}
if (list->calls.cap > 0) {
if (list->calls.len > 0) {
++(*list->shared_calls);
/*
list->calls.calls = (packed_call_t**)malloc(sizeof(packed_call_t*)*a->calls.cap);
@@ -548,7 +548,6 @@ renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a)
if(list->len) {
++(*list->shared_arrays);
}
#undef PROCESS
if(list->ilen) {
++(*list->shared_indices);
}
@@ -603,7 +602,7 @@ void free_renderlist(renderlist_t *list) {
renderlist_t *next;
do {
if ((list->calls.cap > 0) && (!list->shared_calls || ((*list->shared_calls)--)==0)) {
if ((list->calls.len > 0) && (!list->shared_calls || ((*list->shared_calls)--)==0)) {
if(list->shared_calls) free(list->shared_calls);
for (int i = 0; i < list->calls.len; i++) {
free(list->calls.calls[i]);
@@ -971,11 +970,11 @@ void draw_renderlist(renderlist_t *list) {
static GLfloat *texgened[MAX_TEX] = {0};
static int texgenedsz[MAX_TEX] = {0};
int use_texgen[MAX_TEX] = {0};
#define TEXTURE(A) if (cur_tex!=A) {gl4es_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;}
old_tex = glstate->texture.client;
GLuint cur_tex = old_tex;
#define RS(A, len) if(texgenedsz[A]<len) {free(texgened[A]); texgened[A]=malloc(4*sizeof(GLfloat)*len); texgenedsz[A]=len; } use_texgen[A]=1
GLint needclean[MAX_TEX] = {0};
#define TEXTURE(A) if (cur_tex!=A) {gl4es_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;}
#define RS(A, len) if(texgenedsz[A]<len) {free(texgened[A]); texgened[A]=malloc(4*sizeof(GLfloat)*len); texgenedsz[A]=len; } use_texgen[A]=1
for (int a=0; a<hardext.maxtex; a++) {
if(glstate->enable.texture[a]) {
const GLint itarget = get_target(glstate->enable.texture[a]);
@@ -1003,9 +1002,6 @@ void draw_renderlist(renderlist_t *list) {
}
}
}
}
#undef RS
for (int a=0; a<hardext.maxtex; a++) {
if ((list->tex[a] || (use_texgen[a] && !needclean[a]))/* && glstate->enable.texture[a]*/) {
TEXTURE(a);
if(!glstate->clientstate.tex_coord_array[a]) {
@@ -1028,7 +1024,8 @@ void draw_renderlist(renderlist_t *list) {
}
}
if (glstate->texture.client != old_tex) TEXTURE(old_tex);
#undef TEXTURE
#undef RS
#undef TEXTURE
GLenum mode;
mode = list->mode;
if ((glstate->polygon_mode == GL_LINE) && (mode>=GL_TRIANGLES))

View File

@@ -7,7 +7,6 @@ typedef enum {
STAGE_NONE = 0,
STAGE_PUSH,
STAGE_POP,
STAGE_CALLLIST,
STAGE_GLCALL,
STAGE_RENDER,
STAGE_FOG,
@@ -33,7 +32,6 @@ static int StageExclusive[] = {
0, // STAGE_NONE
1, // STAGE_PUSH
1, // STAGE_POP
1, // STAGE_CALLLIST
0, // STAGE_GLCALL
1, // STAGE_RENDER
1, // STAGE_FOG
@@ -182,6 +180,8 @@ typedef struct _renderlist_t {
GLboolean open;
} renderlist_t;
KHASH_MAP_INIT_INT(gllisthead, renderlist_t*)
#define DEFAULT_CALL_LIST_CAPACITY 20
#define DEFAULT_RENDER_LIST_CAPACITY 64

View File

@@ -30,6 +30,17 @@ void *open_lib(const char **names, const char *override);
WARN_NULL(lib##_##name); \
} \
}
#define LOAD_RAW_SILENT(lib, name, ...) \
{ \
static bool first = true; \
if (first) { \
first = false; \
if (lib != NULL) { \
lib##_##name = (name##_PTR)__VA_ARGS__; \
} \
} \
}
#endif
#define LOAD_LIB(lib, name) DEFINE_RAW(lib, name); LOAD_RAW(lib, name, dlsym(lib, #name))
@@ -55,4 +66,11 @@ void *open_lib(const char **names, const char *override);
LOAD_RAW(gles, name, egl_eglGetProcAddress(#name"EXT")); \
}
#define LOAD_GLES_OR_OES(name) \
DEFINE_RAW(gles, name); \
{ \
LOAD_EGL(eglGetProcAddress); \
LOAD_RAW_SILENT(gles, name, (egl_eglGetProcAddress(#name"OES")!=NULL)?(void*)egl_eglGetProcAddress(#name"OES"):(void*)dlsym(gles, #name)); \
}
#endif

View File

@@ -656,12 +656,17 @@ bool quarter_pixel(const GLvoid *src[16],
bool pixel_convert(const GLvoid *src, GLvoid **dst,
GLuint width, GLuint height,
GLenum src_format, GLenum src_type,
GLenum dst_format, GLenum dst_type, GLuint stride) {
GLenum dst_format, GLenum dst_type, GLuint stride, GLuint align) {
const colorlayout_t *src_color, *dst_color;
GLuint pixels = width * height;
GLuint dst_size = pixels * pixel_sizeof(dst_format, dst_type);
GLuint dst_width = ((stride?stride:width) - width) * pixel_sizeof(dst_format, dst_type);
GLuint src_width = width * pixel_sizeof(src_format, src_type);
if(src_type==GL_UNSIGNED_INT_8_8_8_8_REV) src_type=GL_UNSIGNED_BYTE;
if(dst_type==GL_UNSIGNED_INT_8_8_8_8_REV) dst_type=GL_UNSIGNED_BYTE;
GLuint dst_size = height * widthalign(width*pixel_sizeof(dst_format, dst_type), align);
GLuint dst_width2 = widthalign((stride?stride:width) * pixel_sizeof(dst_format, dst_type), align);
GLuint dst_width = dst_width2 - (width * pixel_sizeof(dst_format, dst_type));
GLuint src_width = widthalign(width * pixel_sizeof(src_format, src_type), align);
GLuint src_widthadj = src_width -(width * pixel_sizeof(src_format, src_type));
//printf("pixel conversion: %ix%i - %s, %s (%d) ==> %s, %s (%d), transform=%i\n", width, height, PrintEnum(src_format), PrintEnum(src_type),pixel_sizeof(src_format, src_type), PrintEnum(dst_format), PrintEnum(dst_type), pixel_sizeof(dst_format, dst_type), raster_need_transform());
src_color = get_color_map(src_format);
@@ -679,7 +684,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
*dst = malloc(dst_size);
if (stride) // for in-place conversion
for (int yy=0; yy<height; yy++)
memcpy((*dst)+yy*(dst_width+src_width), src+yy*src_width, src_width);
memcpy((*dst)+yy*dst_width2, src+yy*src_width, src_width);
else
memcpy(*dst, src, dst_size);
return true;
@@ -694,7 +699,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
// TODO: Rewrite that with some Macro, it's obviously doable to simplify the reading (and writting) of all this
// simple BGRA <-> RGBA / UNSIGNED_BYTE
if ((((src_format == GL_BGRA) && (dst_format == GL_RGBA)) || ((src_format == GL_RGBA) && (dst_format == GL_BGRA)))
&& (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
&& (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) {
GLuint tmp;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -703,8 +708,8 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
@@ -721,13 +726,13 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// RGBA -> LA
if ((src_format == GL_RGBA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if ((src_format == GL_RGBA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) {
GLuint tmp;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -737,13 +742,13 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// BGRA -> LA
if ((src_format == GL_BGRA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if ((src_format == GL_BGRA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) {
GLuint tmp;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -753,13 +758,13 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// RGB(A) -> L
if (((src_format == GL_RGBA)||(src_format == GL_RGB)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if (((src_format == GL_RGBA)||(src_format == GL_RGB)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) {
GLuint tmp;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -769,13 +774,13 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// BGR(A) -> L
if (((src_format == GL_BGRA)||(src_format == GL_BGR)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if (((src_format == GL_BGRA)||(src_format == GL_BGR)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) {
GLuint tmp;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -785,13 +790,13 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// BGR(A) -> RGB
if (((src_format == GL_BGR)||(src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if (((src_format == GL_BGR)||(src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
((char*)dst_pos)[0] = ((char*)src_pos)[2];
@@ -800,13 +805,29 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// BGR -> RGBA
if (((src_format == GL_BGR)) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
((char*)dst_pos)[0] = ((char*)src_pos)[2];
((char*)dst_pos)[1] = ((char*)src_pos)[1];
((char*)dst_pos)[2] = ((char*)src_pos)[0];
((char*)dst_pos)[3] = 255;
src_pos += src_stride;
dst_pos += dst_stride;
}
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// RGBA -> RGB
if ((src_format == GL_RGBA) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if ((src_format == GL_RGBA) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
((char*)dst_pos)[0] = ((char*)src_pos)[0];
@@ -815,86 +836,86 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// RGB(A) -> RGB565
if (((src_format == GL_RGB)||(src_format == GL_RGBA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if (((src_format == GL_RGB)||(src_format == GL_RGBA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
*(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[2]&0xf8)>>(3)) | ((GLushort)(((char*)src_pos)[1]&0xfc)<<(5-2)) | ((GLushort)(((char*)src_pos)[0]&0xf8)<<(11-3));
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// BGR(A) -> RGB565
if (((src_format == GL_BGR) || (src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if (((src_format == GL_BGR) || (src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
*(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[0]&0xf8)>>(3)) | ((GLushort)(((char*)src_pos)[1]&0xfc)<<(5-2)) | ((GLushort)(((char*)src_pos)[2]&0xf8)<<(11-3));
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// RGBA -> RGBA5551
if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
*(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[2]&0xf8)>>(3-1)) | ((GLushort)(((char*)src_pos)[1]&0xf8)<<(5-2)) | ((GLushort)(((char*)src_pos)[0]&0xf8)<<(10-2)) | ((GLushort)(((char*)src_pos)[3])>>15);
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// BGRA -> RGBA5551
if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
*(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[0]&0xf8)>>(3-1)) | ((GLushort)(((char*)src_pos)[1]&0xf8)<<(5-2)) | ((GLushort)(((char*)src_pos)[2]&0xf8)<<(10-2)) | ((GLushort)(((char*)src_pos)[3])>>15);
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// RGBA -> RGBA4444
if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
*(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[3]&0xf0))>>(4) | ((GLushort)(((char*)src_pos)[2]&0xf0)) | ((GLushort)(((char*)src_pos)[1]&0xf0))<<(4) | ((GLushort)(((char*)src_pos)[0]&0xf0))<<(8);
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
// BGRA -> RGBA4444
if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) {
if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE))) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
*(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[3]&0xf0)>>(4)) | ((GLushort)(((char*)src_pos)[0]&0xf0)) | ((GLushort)(((char*)src_pos)[1]&0xf0)<<(4)) | ((GLushort)(((char*)src_pos)[2]&0xf0)<<(8));
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
@@ -910,8 +931,8 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
@@ -927,8 +948,8 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
@@ -944,8 +965,8 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
src_pos += src_stride;
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width;
dst_pos += dst_width;
src_pos += src_widthadj;
}
return true;
}
@@ -1165,7 +1186,8 @@ bool pixel_doublescale(const GLvoid *old, GLvoid **new,
}
bool pixel_to_ppm(const GLvoid *pixels, GLuint width, GLuint height,
GLenum format, GLenum type, GLuint name) {
GLenum format, GLenum type, GLuint name, GLuint align) {
// this function should be redone, using write_png from STB for example
if (! pixels)
return false;
@@ -1175,7 +1197,7 @@ bool pixel_to_ppm(const GLvoid *pixels, GLuint width, GLuint height,
if (format == GL_RGB && type == GL_UNSIGNED_BYTE) {
src = (GLvoid*)pixels;
} else {
if (! pixel_convert(pixels, (GLvoid **)&src, width, height, format, type, GL_RGB, GL_UNSIGNED_BYTE, 0)) {
if (! pixel_convert(pixels, (GLvoid **)&src, width, height, format, type, GL_RGB, GL_UNSIGNED_BYTE, 0, align)) {
return false;
}
}

View File

@@ -12,10 +12,12 @@ typedef struct {
GLfloat r, g, b, a;
} pixel_t;
#define widthalign(width, align) ((width+(align-1))&(~(align-1)))
bool pixel_convert(const GLvoid *src, GLvoid **dst,
GLuint width, GLuint height,
GLenum src_format, GLenum src_type,
GLenum dst_format, GLenum dst_type, GLuint stride);
GLenum dst_format, GLenum dst_type, GLuint stride, GLuint align);
bool pixel_transform(const GLvoid *src, GLvoid **dst,
GLuint width, GLuint height,
@@ -45,6 +47,6 @@ bool pixel_doublescale(const GLvoid *src, GLvoid **dst,
bool pixel_to_ppm(const GLvoid *pixels,
GLuint width, GLuint height,
GLenum format, GLenum type, GLuint name);
GLenum format, GLenum type, GLuint name, GLuint align);
#endif

View File

@@ -343,7 +343,7 @@ void gl4es_glDrawPixels(GLsizei width, GLsizei height, GLenum format,
GLsizei bmp_width = (glstate->texture.unpack_row_length)?glstate->texture.unpack_row_length:width;
if (! pixel_convert(data, &dst, bmp_width, height,
format, type, GL_RGBA, GL_UNSIGNED_BYTE, 0)) {
format, type, GL_RGBA, GL_UNSIGNED_BYTE, 0, 1)) { // pack_align is forced to 1 when drawing
return;
}

View File

@@ -8,6 +8,7 @@
#include "buffers.h"
#include "queries.h"
#include "light.h"
#include "fog.h"
typedef struct _glstack_t glstack_t;
typedef struct _glclientstack_t glclientstack_t;
@@ -51,6 +52,8 @@ typedef struct {
pack_skip_pixels,
pack_skip_rows,
pack_image_height;
GLuint pack_align,
unpack_align;
GLboolean pack_lsb_first;
gltexture_t *bound[MAX_TEX][ENABLED_TEXTURE_LAST];
GLboolean pscoordreplace[MAX_TEX];
@@ -158,7 +161,7 @@ typedef struct {
enable_state_t enable;
map_state_t *map_grid;
map_states_t map1, map2;
renderlist_t **lists;
khash_t(gllisthead) *headlists;
texgen_state_t texgen[MAX_TEX];
texture_state_t texture;
GLfloat color[4];
@@ -193,6 +196,7 @@ typedef struct {
int emulatedWin;
int shared_cnt;
light_state_t light;
fog_t fog;
material_state_t material;
int immediateMV;
} glstate_t;

View File

@@ -167,12 +167,12 @@ void sphere_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint
matrix_vector(ModelviewMatrix, verts+k*4, eye);
vector4_normalize(eye);
vector3_matrix((norm)?(norm+k*3):glstate->normal, InvModelview, eye_norm);
vector4_normalize(eye_norm);
a=dot4(eye, eye_norm)*2.0f;
for (int j=0; j<4; j++)
vector_normalize(eye_norm);
a=dot(eye, eye_norm)*2.0f;
for (int j=0; j<3; j++)
reflect[j]=eye[j]-eye_norm[j]*a;
reflect[2]+=1.0f;
a = 0.5f / sqrtf(dot4(reflect, reflect));
a = 0.5f / sqrtf(dot(reflect, reflect));
out[k*4+0] = reflect[0]*a + 0.5f;
out[k*4+1] = reflect[1]*a + 0.5f;
out[k*4+2] = 0.0f;

View File

@@ -300,7 +300,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height,
if (convert) {
GLvoid *pixels = (GLvoid *)data;
if (! pixel_convert(data, &pixels, width, height,
*format, *type, dest_format, dest_type, 0)) {
*format, *type, dest_format, dest_type, 0, glstate->texture.unpack_align)) {
printf("LIBGL: swizzle error: (%s, %s -> %s, %s)\n",
PrintEnum(*format), PrintEnum(*type), PrintEnum(dest_format), PrintEnum(dest_type));
return NULL;
@@ -311,7 +311,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height,
GLvoid *pix2 = (GLvoid *)pixels;
internal2format_type(internalformat, &dest_format, &dest_type);
if (! pixel_convert(pixels, &pix2, width, height,
*format, *type, dest_format, dest_type, 0)) {
*format, *type, dest_format, dest_type, 0, glstate->texture.unpack_align)) {
printf("LIBGL: swizzle error: (%s, %s -> %s, %s)\n",
PrintEnum(dest_format), PrintEnum(dest_type), PrintEnum(internalformat), PrintEnum(dest_type));
return NULL;
@@ -346,7 +346,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height,
return (void *)data;
}
GLenum swizzle_internalformat(GLenum *internalformat, GLenum format) {
GLenum swizzle_internalformat(GLenum *internalformat, GLenum format, GLenum type) {
GLenum ret = *internalformat;
GLenum sret;
switch(*internalformat) {
@@ -365,8 +365,12 @@ GLenum swizzle_internalformat(GLenum *internalformat, GLenum format) {
case GL_RGB5:
sret = GL_RGB5;
break;
case GL_RGB8:
case GL_RGB:
if(globals4es.avoid16bits==0 && format==GL_RGB && type==GL_UNSIGNED_SHORT_5_6_5) {
sret = ret = GL_RGB5;
break;
}
case GL_RGB8:
case GL_BGR:
case GL_RGB16:
case GL_RGB16F:
@@ -381,6 +385,14 @@ GLenum swizzle_internalformat(GLenum *internalformat, GLenum format) {
sret = GL_RGB5_A1;
break;
case GL_RGBA:
if(globals4es.avoid16bits==0 && format==GL_RGBA && type==GL_UNSIGNED_SHORT_5_5_5_1) {
sret = ret = GL_RGB5_A1;
break;
}
if(globals4es.avoid16bits==0 && format==GL_RGBA && type==GL_UNSIGNED_SHORT_4_4_4_4) {
sret = ret = GL_RGBA4;
break;
}
case GL_RGBA8:
case GL_RGBA16:
case GL_RGBA16F:
@@ -564,20 +576,21 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat,
if (globals4es.texshrink>=8 && max1>8192) max1=8192;
proxy_width = ((width<<level)>max1)?0:width;
proxy_height = ((height<<level)>max1)?0:height;
proxy_intformat = swizzle_internalformat(&internalformat, format);
proxy_intformat = swizzle_internalformat(&internalformat, format, type);
return;
}
//PUSH_IF_COMPILING(glTexImage2D);
GLuint old_glbatch = glstate->gl_batch;
if (glstate->gl_batch || glstate->list.pending) {
flush();
glstate->gl_batch = 0;
} else {
PUSH_IF_COMPILING(glTexImage2D);
}
GLvoid *datab = (GLvoid*)data;
if (glstate->vao->unpack)
datab += (uintptr_t)glstate->vao->pack->data;
datab += (uintptr_t)glstate->vao->unpack->data;
GLvoid *pixels = (GLvoid *)datab;
border = 0; //TODO: something?
@@ -594,7 +607,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat,
else
bound->mipmap_need = 1;
}
GLenum new_format = swizzle_internalformat(&internalformat, format);
GLenum new_format = swizzle_internalformat(&internalformat, format, type);
if (bound && (level==0)) {
bound->orig_internal = internalformat;
bound->internalformat = new_format;
@@ -675,7 +688,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat,
if (globals4es.texdump) {
if (bound) {
pixel_to_ppm(pixels, width, height, format, type, bound->texture);
pixel_to_ppm(pixels, width, height, format, type, bound->texture, glstate->texture.pack_align);
}
}
} else {
@@ -861,7 +874,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat,
else
bound->data = malloc(width*height*4);
if (datab) {
if (!pixel_convert(pixels, &bound->data, width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE, 0))
if (!pixel_convert(pixels, &bound->data, width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE, 0, glstate->texture.pack_align))
printf("LIBGL: Error on pixel_convert when TEXCOPY in glTexImage2D\n");
} else {
//memset(bound->data, 0, width*height*4);
@@ -877,16 +890,17 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff
GLsizei width, GLsizei height, GLenum format, GLenum type,
const GLvoid *data) {
//PUSH_IF_COMPILING(glTexSubImage2D);
GLuint old_glbatch = glstate->gl_batch;
if (glstate->gl_batch || glstate->list.pending) {
flush();
glstate->gl_batch = 0;
} else {
PUSH_IF_COMPILING(glTexSubImage2D);
}
GLvoid *datab = (GLvoid*)data;
if (glstate->vao->unpack)
datab += (uintptr_t)glstate->vao->pack->data;
datab += (uintptr_t)glstate->vao->unpack->data;
GLvoid *pixels = (GLvoid*)datab;
const GLuint itarget = what_target(target);
@@ -944,7 +958,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff
GLvoid *tmp = GetStreamingBuffer(bound->streamingID);
tmp += (yoffset*bound->width+xoffset)*2;
if (! pixel_convert(old, &tmp, width, height,
format, type, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bound->width)) {
format, type, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bound->width, glstate->texture.pack_align)) {
printf("LIBGL: swizzle error: (%#4x, %#4x -> GL_RGB, UNSIGNED_SHORT_5_6_5)\n",
format, type);
}
@@ -956,7 +970,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff
//pixels = (GLvoid *)swizzle_texture(width, height, &format, &type, old);
GLenum dest_format, dest_type;
internal2format_type(orig_internal, &dest_format, &dest_type);
if (!pixel_convert(old, &pixels, width, height, format, type, dest_format, dest_type, 0)) {
if (!pixel_convert(old, &pixels, width, height, format, type, dest_format, dest_type, 0, glstate->texture.pack_align)) {
printf("LIBGL: Error in pixel_convert while glTexSubImage2D\n");
} else {
format = dest_format;
@@ -964,7 +978,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff
if(orig_internal!=internalformat) {
GLvoid* pix2 = pixels;
internal2format_type(internalformat, &dest_format, &dest_type);
if (!pixel_convert(pixels, &pix2, width, height, format, type, dest_format, dest_type, 0)) {
if (!pixel_convert(pixels, &pix2, width, height, format, type, dest_format, dest_type, 0, glstate->texture.pack_align)) {
printf("LIBGL: Error in pixel_convert while glTexSubImage2D\n");
}
if (pixels != pix2 && pixels != old)
@@ -1009,7 +1023,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff
if (globals4es.texdump) {
if (bound) {
pixel_to_ppm(pixels, width, height, format, type, bound->texture);
pixel_to_ppm(pixels, width, height, format, type, bound->texture, glstate->texture.pack_align);
}
}
@@ -1082,7 +1096,7 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff
//printf("*texcopy* glTexSubImage2D, xy=%i,%i, size=%i,%i=>%i,%i, format=%s, type=%s, tex=%u\n", xoffset, yoffset, width, height, bound->width, bound->height, PrintEnum(format), PrintEnum(type), bound->glname);
GLvoid * tmp = bound->data;
tmp += (yoffset*bound->width + xoffset)*4;
if (!pixel_convert(pixels, &tmp, width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE, bound->width))
if (!pixel_convert(pixels, &tmp, width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE, bound->width, glstate->texture.pack_align))
printf("LIBGL: Error on pixel_convert while TEXCOPY in glTexSubImage2D\n");
}
@@ -1152,45 +1166,62 @@ void gl4es_glPixelStorei(GLenum pname, GLint param) {
switch (pname) {
case GL_UNPACK_ROW_LENGTH:
glstate->texture.unpack_row_length = param;
break;
return;
case GL_UNPACK_SKIP_PIXELS:
glstate->texture.unpack_skip_pixels = param;
break;
return;
case GL_UNPACK_SKIP_ROWS:
glstate->texture.unpack_skip_rows = param;
break;
return;
case GL_UNPACK_LSB_FIRST:
glstate->texture.unpack_lsb_first = param;
break;
return;
case GL_UNPACK_IMAGE_HEIGHT:
glstate->texture.unpack_image_height = param;
break;
return;
case GL_UNPACK_SWAP_BYTES:
case GL_PACK_SWAP_BYTES:
// Fake... TODO?
//glstate->texture.unpack_lsb_first = param;
break;
return;
case GL_PACK_ROW_LENGTH:
glstate->texture.pack_row_length = param;
break;
return;
case GL_PACK_SKIP_PIXELS:
glstate->texture.pack_skip_pixels = param;
break;
return;
case GL_PACK_SKIP_ROWS:
glstate->texture.pack_skip_rows = param;
break;
return;
case GL_PACK_LSB_FIRST:
glstate->texture.pack_lsb_first = param;
break;
return;
case GL_PACK_IMAGE_HEIGHT:
glstate->texture.pack_image_height = param;
return;
case GL_PACK_ALIGNMENT:
if(glstate->texture.pack_align==param)
return;
if (param!=1 && param!=2 && param!=4 && param!=8) {
errorShim(GL_INVALID_VALUE);
return;
}
glstate->texture.pack_align=param;
break;
default:
errorGL();
gles_glPixelStorei(pname, param);
case GL_UNPACK_ALIGNMENT:
if(glstate->texture.unpack_align==param)
return;
if (param!=1 && param!=2 && param!=4 && param!=8) {
errorShim(GL_INVALID_VALUE);
return;
}
glstate->texture.unpack_align=param;
break;
}
errorGL();
gles_glPixelStorei(pname, param);
}
GLboolean gl4es_glIsTexture(GLuint texture) {
noerrorShim();
if (!texture) {
@@ -1256,7 +1287,7 @@ gltexture_t* gl4es_getTexture(GLenum target, GLuint texture) {
#define batch_activetex (glstate->statebatch.active_tex_changed?(glstate->statebatch.active_tex-GL_TEXTURE0):glstate->texture.active)
void gl4es_glBindTexture(GLenum target, GLuint texture) {
noerrorShim();
//printf("glBindTexture(%s, %u), active=%i, client=%i\n", PrintEnum(target), texture, glstate->texture.active, glstate->texture.client);
//printf("glBindTexture(%s, %u), active=%i, client=%i, list.active=%p (compiling=%d, pending=%d)\n", PrintEnum(target), texture, glstate->texture.active, glstate->texture.client, glstate->list.active, glstate->list.compiling, glstate->list.pending);
if(glstate->list.pending) flush();
if ((target!=GL_PROXY_TEXTURE_2D) && (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling))) {
if ((glstate->statebatch.bound_targ[batch_activetex] == target) && (glstate->statebatch.bound_tex[batch_activetex] == texture))
@@ -1363,6 +1394,7 @@ void gl4es_glTexParameteri(GLenum target, GLenum pname, GLint param) {
case GL_TEXTURE_WRAP_T:
switch (param) {
case GL_CLAMP:
case GL_CLAMP_TO_BORDER:
param = GL_CLAMP_TO_EDGE;
break;
}
@@ -1402,6 +1434,61 @@ void gl4es_glTexParameterf(GLenum target, GLenum pname, GLfloat param) {
gl4es_glTexParameteri(target, pname, param);
}
void gl4es_glTexParameterfv(GLenum target, GLenum pname, const GLfloat * params) {
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_WRAP_R:
case GL_TEXTURE_MAX_LEVEL:
case GL_TEXTURE_BASE_LEVEL:
case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD:
case GL_TEXTURE_LOD_BIAS:
case GL_GENERATE_MIPMAP:
gl4es_glTexParameteri(target, pname, params[0]);
return;
case GL_TEXTURE_BORDER_COLOR:
// not supported on GLES,
noerrorShim();
return;
}
PUSH_IF_COMPILING(glTexParameterfv);
LOAD_GLES(glTexParameterfv);
errorGL();
const GLuint rtarget = map_tex_target(target);
gles_glTexParameterfv(rtarget, pname, params);
}
void gl4es_glTexParameteriv(GLenum target, GLenum pname, const GLint * params) {
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_WRAP_R:
case GL_TEXTURE_MAX_LEVEL:
case GL_TEXTURE_BASE_LEVEL:
case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD:
case GL_TEXTURE_LOD_BIAS:
case GL_GENERATE_MIPMAP:
gl4es_glTexParameteri(target, pname, params[0]);
return;
case GL_TEXTURE_BORDER_COLOR:
// not supported on GLES,
noerrorShim();
return;
}
PUSH_IF_COMPILING(glTexParameteriv);
LOAD_GLES(glTexParameteriv);
errorGL();
const GLuint rtarget = map_tex_target(target);
gles_glTexParameteriv(rtarget, pname, params);
}
void gl4es_glDeleteTextures(GLsizei n, const GLuint *textures) {
if (glstate->gl_batch || glstate->list.pending) flush();
noerrorShim();
@@ -1662,7 +1749,7 @@ void gl4es_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type,
#ifdef TEXSTREAM
if (globals4es.texstream && bound->streamed) {
noerrorShim();
pixel_convert(GetStreamingBuffer(bound->streamingID), &dst, width, height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format, type, 0);
pixel_convert(GetStreamingBuffer(bound->streamingID), &dst, width, height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format, type, 0, glstate->texture.unpack_align);
readfboEnd();
if (old_glbatch)
glstate->gl_batch=old_glbatch;
@@ -1672,7 +1759,7 @@ void gl4es_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type,
if (globals4es.texcopydata && bound->data) {
//printf("texcopydata* glGetTexImage(0x%04X, %d, 0x%04x, 0x%04X, %p)\n", target, level, format, type, img);
noerrorShim();
if (!pixel_convert(bound->data, &dst, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0))
if (!pixel_convert(bound->data, &dst, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0, glstate->texture.unpack_align))
printf("LIBGL: Error on pixel_convert while glGetTexImage\n");
} else {
// Setup an FBO the same size of the texture
@@ -1891,7 +1978,7 @@ void gl4es_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
GLvoid *pixels = malloc(width*height*4);
gles_glReadPixels(x, y, width, height, use_bgra?GL_BGRA:GL_RGBA, GL_UNSIGNED_BYTE, pixels);
if (! pixel_convert(pixels, &dst, width, height,
use_bgra?GL_BGRA:GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) {
use_bgra?GL_BGRA:GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0,glstate->texture.unpack_align)) {
LOGE("LIBGL: ReadPixels error: (%s, UNSIGNED_BYTE -> %s, %s )\n",
PrintEnum(use_bgra?GL_BGRA:GL_RGBA), PrintEnum(format), PrintEnum(type));
}
@@ -2140,23 +2227,26 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor
// automaticaly reduce the pixel size
half=pixels;
bound->alpha = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true;
if(globals4es.nodownsampling==1) {
if(globals4es.nodownsampling==1) { // will be removed soon, avoid16bits is better
format = GL_RGBA;
type = GL_UNSIGNED_BYTE;
} else {
format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA;
#ifdef PANDORA
type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:(internalformat==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_5_5_1:GL_UNSIGNED_SHORT_4_4_4_4;
#else
type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4;
#endif
if (pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0))
fact = 0;
// if (pixel_thirdscale(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE))
// fact = 1;
else {
if(globals4es.avoid16bits) {
format = GL_RGBA;
type = GL_UNSIGNED_BYTE;
} else {
format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA;
#ifdef PANDORA
type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:(internalformat==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_5_5_1:GL_UNSIGNED_SHORT_4_4_4_4;
#else
type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4;
#endif
if (pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0, glstate->texture.pack_align))
fact = 0;
else {
format = GL_RGBA;
type = GL_UNSIGNED_BYTE;
}
}
}
bound->format = format; //internalformat;
@@ -2251,7 +2341,7 @@ void gl4es_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
#else
GLenum format = bound->format;
GLenum type = bound->type;
pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0);
pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0, glstate->texture.pack_align);
gl4es_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, half);
#endif
if (half!=pixels)
@@ -2411,6 +2501,8 @@ void glGenTextures(GLsizei n, GLuint * textures) AliasExport("gl4es_glGenTexture
void glDeleteTextures(GLsizei n, const GLuint * textures) AliasExport("gl4es_glDeleteTextures");
void glTexParameteri(GLenum target, GLenum pname, GLint param) AliasExport("gl4es_glTexParameteri");
void glTexParameterf(GLenum target, GLenum pname, GLfloat param) AliasExport("gl4es_glTexParameterf");
void glTexParameterfv(GLenum target, GLenum pname, const GLfloat * params) AliasExport("gl4es_glTexParameterfv");
void glTexParameteriv(GLenum target, GLenum pname, const GLint * params) AliasExport("gl4es_glTexParameteriv");
GLboolean glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences) AliasExport("gl4es_glAreTexturesResident");
void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) AliasExport("gl4es_glGetTexLevelParameteriv");
void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid * img) AliasExport("gl4es_glGetTexImage");

View File

@@ -55,7 +55,9 @@ void gl4es_glFogiv(GLenum pname, GLint *iparams) {
case GL_FOG_START:
case GL_FOG_END:
case GL_FOG_MODE:
case GL_FOG_INDEX: {
case GL_FOG_INDEX:
case GL_FOG_COORD_SRC:
{
gl4es_glFogf(pname, *iparams);
break;
}

View File

@@ -1580,14 +1580,14 @@ void gl4es_glTexGeni(GLenum coord, GLenum pname, GLint param) {
void glTexGeni(GLenum coord, GLenum pname, GLint param) __attribute__((alias("gl4es_glTexGeni"))) __attribute__((visibility("default")));
#endif
#ifndef skip_glTexImage2D
void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels) {
void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data) {
LOAD_GLES(glTexImage2D);
#ifndef direct_glTexImage2D
PUSH_IF_COMPILING(glTexImage2D)
#endif
gles_glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
gles_glTexImage2D(target, level, internalformat, width, height, border, format, type, data);
}
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels) __attribute__((alias("gl4es_glTexImage2D"))) __attribute__((visibility("default")));
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data) __attribute__((alias("gl4es_glTexImage2D"))) __attribute__((visibility("default")));
#endif
#ifndef skip_glTexParameterf
void gl4es_glTexParameterf(GLenum target, GLenum pname, GLfloat param) {
@@ -1650,14 +1650,14 @@ void gl4es_glTexParameterxv(GLenum target, GLenum pname, const GLfixed * params)
void glTexParameterxv(GLenum target, GLenum pname, const GLfixed * params) __attribute__((alias("gl4es_glTexParameterxv"))) __attribute__((visibility("default")));
#endif
#ifndef skip_glTexSubImage2D
void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels) {
void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data) {
LOAD_GLES(glTexSubImage2D);
#ifndef direct_glTexSubImage2D
PUSH_IF_COMPILING(glTexSubImage2D)
#endif
gles_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
gles_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
}
void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels) __attribute__((alias("gl4es_glTexSubImage2D"))) __attribute__((visibility("default")));
void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data) __attribute__((alias("gl4es_glTexSubImage2D"))) __attribute__((visibility("default")));
#endif
#ifndef skip_glTranslatef
void gl4es_glTranslatef(GLfloat x, GLfloat y, GLfloat z) {

20
project/jni/gl4es/src/gl/wrap/gles.h Normal file → Executable file
View File

@@ -1340,7 +1340,7 @@ typedef struct {
int func;
ARGS_void_GLenum_GLenum_const_GLint___GENPT__ args;
} INDEXED_void_GLenum_GLenum_const_GLint___GENPT__;
typedef void (*FUNC_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels);
typedef void (*FUNC_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data);
typedef struct {
GLenum a1;
GLint a2;
@@ -1361,7 +1361,7 @@ typedef struct {
int func;
ARGS_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__ args;
} INDEXED_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__;
typedef void (*FUNC_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels);
typedef void (*FUNC_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data);
typedef struct {
GLenum a1;
GLint a2;
@@ -2496,8 +2496,8 @@ packed_call_t* glCopyPackedCall(const packed_call_t *packed);
#define glTexGeni_FORMAT FORMAT_void_GLenum_GLenum_GLint
#define glTexImage2D_INDEX 159
#define glTexImage2D_RETURN void
#define glTexImage2D_ARG_NAMES target, level, internalformat, width, height, border, format, type, pixels
#define glTexImage2D_ARG_EXPAND GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels
#define glTexImage2D_ARG_NAMES target, level, internalformat, width, height, border, format, type, data
#define glTexImage2D_ARG_EXPAND GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data
#define glTexImage2D_PACKED PACKED_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__
#define glTexImage2D_INDEXED INDEXED_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__
#define glTexImage2D_FORMAT FORMAT_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__
@@ -2545,8 +2545,8 @@ packed_call_t* glCopyPackedCall(const packed_call_t *packed);
#define glTexParameterxv_FORMAT FORMAT_void_GLenum_GLenum_const_GLfixed___GENPT__
#define glTexSubImage2D_INDEX 166
#define glTexSubImage2D_RETURN void
#define glTexSubImage2D_ARG_NAMES target, level, xoffset, yoffset, width, height, format, type, pixels
#define glTexSubImage2D_ARG_EXPAND GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels
#define glTexSubImage2D_ARG_NAMES target, level, xoffset, yoffset, width, height, format, type, data
#define glTexSubImage2D_ARG_EXPAND GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data
#define glTexSubImage2D_PACKED PACKED_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__
#define glTexSubImage2D_INDEXED INDEXED_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__
#define glTexSubImage2D_FORMAT FORMAT_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__
@@ -4597,7 +4597,7 @@ typedef void (*glViewport_PTR)(glViewport_ARG_EXPAND);
}
#endif
#ifndef direct_glTexImage2D
#define push_glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels) { \
#define push_glTexImage2D(target, level, internalformat, width, height, border, format, type, data) { \
glTexImage2D_PACKED *packed_data = malloc(sizeof(glTexImage2D_PACKED)); \
packed_data->format = glTexImage2D_FORMAT; \
packed_data->func = gl4es_glTexImage2D; \
@@ -4609,7 +4609,7 @@ typedef void (*glViewport_PTR)(glViewport_ARG_EXPAND);
packed_data->args.a6 = (GLint)border; \
packed_data->args.a7 = (GLenum)format; \
packed_data->args.a8 = (GLenum)type; \
packed_data->args.a9 = (GLvoid *)pixels; \
packed_data->args.a9 = (GLvoid *)data; \
glPushCall((void *)packed_data); \
}
#endif
@@ -4680,7 +4680,7 @@ typedef void (*glViewport_PTR)(glViewport_ARG_EXPAND);
}
#endif
#ifndef direct_glTexSubImage2D
#define push_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) { \
#define push_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data) { \
glTexSubImage2D_PACKED *packed_data = malloc(sizeof(glTexSubImage2D_PACKED)); \
packed_data->format = glTexSubImage2D_FORMAT; \
packed_data->func = gl4es_glTexSubImage2D; \
@@ -4692,7 +4692,7 @@ typedef void (*glViewport_PTR)(glViewport_ARG_EXPAND);
packed_data->args.a6 = (GLsizei)height; \
packed_data->args.a7 = (GLenum)format; \
packed_data->args.a8 = (GLenum)type; \
packed_data->args.a9 = (GLvoid *)pixels; \
packed_data->args.a9 = (GLvoid *)data; \
glPushCall((void *)packed_data); \
}
#endif

View File

@@ -29,6 +29,7 @@
#endif
//#define DEBUG
#ifdef DEBUG
#define DBG(a) a
@@ -62,7 +63,6 @@ typedef struct {
Display *dpy;
int Type; GC gc;
XImage* frame;
GLXContext glxcontext;
} glx_buffSize;
//PBuffer should work under ANDROID
@@ -86,7 +86,7 @@ static GLXContext fbContext = NULL;
#endif //ANDROID
// hmm...
static EGLContext eglContext;
static EGLContext eglContext = EGL_NO_CONTEXT;
static int fbcontext_count = 0;
@@ -98,11 +98,24 @@ static int fbdev = -1;
#endif
static int g_width=0, g_height=0;
// RPI stuffs
// **** RPI stuffs ****
static bool g_bcmhost = false;
static bool g_bcm_active = false;
void (*bcm_host_init)();
void (*bcm_host_deinit)();
#ifndef ANDROID
#include "rpi.h"
#endif
// ***** end of RPI stuffs ****
// Generic create native window to use with "LIBGL_FB=1" (so with EGL_DEFAULT_DISPLAY and without X11)
static void* create_native_window(int w, int h) {
#ifndef ANDROID
if(bcm_host) return create_rpi_window(w, h);
#endif
return NULL;
}
#define SHUT(a) if(!globals4es.nobanner) a
@@ -219,7 +232,7 @@ static int get_config_default(Display *display, int attribute, int *value) {
*value = GLX_WINDOW_BIT;
break;
case GLX_BUFFER_SIZE:
*value = 0;
*value = 16;
break;
case GLX_X_VISUAL_TYPE:
case GLX_CONFIG_CAVEAT:
@@ -348,8 +361,10 @@ void glx_init() {
if (bcm_host) {
bcm_host_init = dlsym(bcm_host, "bcm_host_init");
bcm_host_deinit = dlsym(bcm_host, "bcm_host_deinit");
if (bcm_host_init && bcm_host_deinit)
if (bcm_host_init && bcm_host_deinit) {
g_bcmhost = true;
rpi_init();
}
}
if (globals4es.xrefresh || globals4es.stacktrace || g_bcmhost) {
// TODO: a bit gross. Maybe look at this: http://stackoverflow.com/a/13290134/293352
@@ -394,7 +409,7 @@ GLXContext gl4es_glXCreateContext(Display *display,
XVisualInfo *visual,
GLXContext shareList,
Bool isDirect) {
DBG(printf("glXCreateContext(%p, %p, %p, %i), latest_visual=%p\n", display, visual, shareList, isDirect, latest_visual);)
DBG(printf("glXCreateContext(%p, %p, %p, %i), latest_visual=%p, fbcontext_count=%d", display, visual, shareList, isDirect, latest_visual, fbcontext_count);)
static struct __GLXFBConfigRec default_glxfbconfig;
GLXFBConfig glxfbconfig;
@@ -411,6 +426,11 @@ GLXContext gl4es_glXCreateContext(Display *display,
default_glxfbconfig.depthBits = 16;
default_glxfbconfig.stencilBits = 8;
}
int depthBits = glxfbconfig->depthBits;
#ifdef PANDORA
if(depthBits==24 && glxfbconfig->stencilBits==8 && !(globals4es.usefbo || globals4es.usepbuffer))
depthBits = 16;
#endif
EGLint configAttribs[] = {
#ifdef PANDORA
@@ -429,7 +449,7 @@ GLXContext gl4es_glXCreateContext(Display *display,
#else
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
#endif
EGL_BUFFER_SIZE, glxfbconfig->depthBits,
EGL_BUFFER_SIZE, depthBits,
EGL_STENCIL_SIZE, glxfbconfig->stencilBits,
EGL_SAMPLE_BUFFERS, glxfbconfig->nMultiSampleBuffers,
@@ -438,10 +458,14 @@ GLXContext gl4es_glXCreateContext(Display *display,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
EGL_NONE
};
if (globals4es.usefb && fbcontext_count>0) {
if (globals4es.usefb && fbcontext_count++>0) {
// don't create a new context, one FB is enough...
fbcontext_count++;
return fbContext;
GLXContext fake = malloc(sizeof(struct __GLXContextRec));
memcpy(fake, fbContext, sizeof(struct __GLXContextRec));
fake->glstate = NewGLState(fbContext->glstate); // let's create a new shared glsate
DBG(printf(" => %p\n", fake);)
return fake;
}
#ifdef BCMHOST
@@ -463,13 +487,12 @@ GLXContext gl4es_glXCreateContext(Display *display,
GLXContext fake = malloc(sizeof(struct __GLXContextRec));
memset(fake, 0, sizeof(struct __GLXContextRec));
if(globals4es.usefb)
fbContext = fake;
// make an egl context here...
EGLBoolean result;
if (eglDisplay == NULL || eglDisplay == EGL_NO_DISPLAY) {
init_display(display);
if (eglDisplay == EGL_NO_DISPLAY) {
DBG(printf(" => %p\n", 0);)
LOGE("LIBGL: Unable to create EGL display.\n");
free(fake);
return 0;
@@ -481,6 +504,7 @@ GLXContext gl4es_glXCreateContext(Display *display,
egl_eglBindAPI(EGL_OPENGL_ES_API);
result = egl_eglInitialize(eglDisplay, NULL, NULL);
if (result != EGL_TRUE) {
DBG(printf(" => %p\n", 0);)
LOGE("LIBGL: Unable to initialize EGL display.\n");
free(fake);
return 0;
@@ -495,7 +519,8 @@ GLXContext gl4es_glXCreateContext(Display *display,
CheckEGLErrors();
if (result != EGL_TRUE || configsFound == 0) {
LOGE("LIBGL: No EGL configs found.\n");
DBG(printf(" => %p\n", 0);)
LOGE("LIBGL: No EGL configs found (depth=%d, stencil=%d).\n", depthBits, glxfbconfig->stencilBits);
free(fake);
return 0;
}
@@ -529,7 +554,11 @@ GLXContext gl4es_glXCreateContext(Display *display,
egl_eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT);
}
*/
if(globals4es.usefb) {
fbContext = malloc(sizeof(struct __GLXContextRec));
memcpy(fbContext, fake, sizeof(struct __GLXContextRec));
}
DBG(printf(" => %p\n", fake);)
return fake;
}
@@ -719,7 +748,7 @@ GLXContext gl4es_glXCreateContextAttribsARB(Display *display, GLXFBConfig config
fake->display = (globals4es.usefb)?g_display:display;
fake->direct = true;
fake->xid = 1; //TODO: Proper handling of that id...
fake->contextType = 0; //Window
fake->contextType = (config->drawableType)==GLX_PIXMAP_BIT?2:0; //Pixmap:Window
egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_RED_SIZE, &fake->rbits);
egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_GREEN_SIZE, &fake->gbits);
@@ -735,14 +764,17 @@ GLXContext gl4es_glXCreateContextAttribsARB(Display *display, GLXFBConfig config
}
void gl4es_glXDestroyContext(Display *display, GLXContext ctx) {
DBG(printf("glXDestroyContext(%p, %p)\n", display, ctx);)
DBG(printf("glXDestroyContext(%p, %p), fbcontext_count=%d, ctx_type=%d\n", display, ctx, fbcontext_count, (ctx)?ctx->contextType:0);)
if (globals4es.usefb && ctx->contextType==0) {
if (fbcontext_count==0)
return; // Should not happens!
if (--fbcontext_count > 0)
return; // Nothing to do...
if (--fbcontext_count > 0) {
DeleteGLState(ctx->glstate);
free(ctx);
return; // Not much to do...
}
}
if ((!globals4es.usefb && ctx->eglContext) || (globals4es.usefb && eglContext)) {
if (ctx->eglContext) {
if (globals4es.usefbo && ctx->contextType==0) {
deleteMainFBO();
}
@@ -775,6 +807,7 @@ void gl4es_glXDestroyContext(Display *display, GLXContext ctx) {
if (globals4es.usefb)
fbContext = NULL;
free(ctx);
return;
}
@@ -827,7 +860,7 @@ not set to EGL_NO_CONTEXT.
Bool gl4es_glXMakeCurrent(Display *display,
GLXDrawable drawable,
GLXContext context) {
DBG(printf("glXMakeCurrent(%p, %p, %p) 'isPBuffer(drawable)=%d, context->drawable=%p, context->eglSurface=%p\n", display, drawable, context, isPBuffer(drawable), context?context->drawable:0, context?context->eglSurface:0);)
DBG(printf("glXMakeCurrent(%p, %p, %p), isPBuffer(drawable)=%d, context->drawable=%p, context->eglSurface=%p", display, drawable, context, isPBuffer(drawable), context?context->drawable:0, context?context->eglSurface:0);)
LOAD_EGL(eglMakeCurrent);
LOAD_EGL(eglDestroySurface);
LOAD_EGL(eglCreateWindowSurface);
@@ -842,6 +875,7 @@ Bool gl4es_glXMakeCurrent(Display *display,
EGLSurface eglSurf = 0;
EGLConfig eglConfig = 0;
if(context && glxContext==context && context->drawable==drawable) {
DBG(printf(" => True\n");)
//same context, all is done bye
DBG(printf("Same context and drawable, doing nothing\n");)
return true;
@@ -857,16 +891,24 @@ Bool gl4es_glXMakeCurrent(Display *display,
#ifndef ANDROID
eglSurf = context->eglSurface = pbuffersize[created-1].Surface; //(EGLSurface)drawable;
context->eglContext = eglContext = pbuffersize[created-1].Context; // this context is ok for the PBuffer
if (context->contextType != pbuffersize[created-1].Type) { // Context / buffer not aligned, create a new glstate tracker
DeleteGLState(context->glstate);
context->glstate = NewGLState(NULL);
}
#endif
} else {
unsigned int width = 0, height = 0, depth = 0;
#ifndef ANDROID
if(globals4es.usefb && (bcm_host || globals4es.usepbuffer)) {
// Get Window size and all...
unsigned int border;
Window root;
int x, y;
XGetGeometry(display, drawable, &root, &x, &y, &width, &height, &border, &depth);
DBG(printf("XGetGeometry gives %dx%d for drawable %p\n", width, height, drawable);)
}
if(globals4es.usefb) {
if(globals4es.usepbuffer) {
// Get Window size and all...
unsigned int width, height, border, depth;
Window root;
int x, y;
XGetGeometry(display, drawable, &root, &x, &y, &width, &height, &border, &depth);
//let's create a PBuffer attributes
EGLint egl_attribs[10]; // should be enough
int i = 0;
@@ -897,7 +939,7 @@ Bool gl4es_glXMakeCurrent(Display *display,
if(eglSurface)
eglSurf = context->eglSurface = eglSurface;
else
eglSurface = eglSurf = context->eglSurface = egl_eglCreateWindowSurface(eglDisplay, context->eglConfigs[0], 0, (globals4es.glx_surface_srgb)?sRGB:NULL);
eglSurface = eglSurf = context->eglSurface = egl_eglCreateWindowSurface(eglDisplay, context->eglConfigs[0], (EGLNativeWindowType)create_native_window(width,height), (globals4es.glx_surface_srgb)?sRGB:NULL);
} else {
if(context->eglSurface)
egl_eglDestroySurface(eglDisplay, context->eglSurface);
@@ -925,7 +967,6 @@ Bool gl4es_glXMakeCurrent(Display *display,
map->surface = eglSurf;
map->PBuffer = created;
if(created) pbuffersize[created-1].glxcontext = context;
}
if (context) {
@@ -933,7 +974,7 @@ Bool gl4es_glXMakeCurrent(Display *display,
ActivateGLState(context->glstate);
#ifdef PANDORA
if(created) pandora_set_gamma();
if(!created) pandora_set_gamma();
#endif
glstate->emulatedPixmap = 0;
glstate->emulatedWin = 0;
@@ -944,7 +985,7 @@ Bool gl4es_glXMakeCurrent(Display *display,
CheckEGLErrors();
if (result) {
if (globals4es.usefbo && created) {
if (globals4es.usefbo && !created) {
// get size of the surface...
egl_eglQuerySurface(eglDisplay,eglSurf,EGL_WIDTH,&g_width);
egl_eglQuerySurface(eglDisplay,eglSurf,EGL_HEIGHT,&g_height);
@@ -953,10 +994,13 @@ Bool gl4es_glXMakeCurrent(Display *display,
createMainFBO(g_width, g_height);
}
// finished
DBG(printf(" => True\n");)
return true;
}
DBG(printf(" => False\n");)
return false;
}
DBG(printf(" => True\n");)
return true;
}
@@ -1087,7 +1131,7 @@ const char *gl4es_glXQueryServerString(Display *display, int screen, int name) {
}
Bool gl4es_glXQueryExtension(Display *display, int *errorBase, int *eventBase) {
DBG(printf("glXQuesryExtension(%p, %p, %p)\n", display, errorBase, eventBase);)
DBG(printf("glXQueryExtension(%p, %p, %p)\n", display, errorBase, eventBase);)
if (errorBase)
*errorBase = 0;
@@ -1499,24 +1543,36 @@ void gl4es_glXReleaseBuffersMESA() {}
#ifndef ANDROID
/* TODO proper implementation */
int gl4es_glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) {
DBG(printf("glXQueryDrawable(%p, %p, %d, %p)\n", dpy, draw, attribute, value);)
DBG(printf("glXQueryDrawable(%p, %p", dpy, draw);)
int pbuf=isPBuffer(draw);
*value = 0;
switch(attribute) {
case GLX_WIDTH:
*value = (pbuf)?pbuffersize[pbuf-1].Width:800;
DBG(printf("(%d), GLX_WIDTH, %p = %d)\n", pbuf, value, *value);)
return 1;
case GLX_HEIGHT:
*value = (pbuf)?pbuffersize[pbuf-1].Height:480;
DBG(printf("(%d), GLX_HEIGHT, %p = %d)\n", pbuf, value, *value);)
return 1;
case GLX_PRESERVED_CONTENTS:
return 0;
if(pbuf) *value = 1;
DBG(printf("(%d), GLX_PRESERVED_CONTENTS, %p = %d)\n", pbuf, value, *value);)
return 1;
case GLX_LARGEST_PBUFFER:
return 0;
if(pbuf) *value = 0;
DBG(printf("(%d), GLX_LARGEST_PBUFFER, %p = %d)\n", pbuf, value, *value);)
return 1;
case GLX_FBCONFIG_ID:
*value = 1;
DBG(printf("(%d), GLX_FBCONFIG_ID, %p = %d)\n", pbuf, value, *value);)
return 1;
case GLX_SWAP_INTERVAL_EXT:
*value = 0;
DBG(printf("(%d), GLX_SWAP_INTERVAL_EXT, %p = %d)\n", pbuf, value, *value);)
return 1;
}
DBG(printf("(%d), %04x, %p)\n", pbuf, attribute, value);)
return 0;
}
@@ -1551,12 +1607,14 @@ void gl4es_glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf) {
DBG(printf("glxDestroyPBuffer(%p, %p)\n", dpy, pbuf);)
LOAD_EGL(eglDestroySurface);
int j=0;
while(j<pbufferlist_size || pbufferlist[j]==pbuf) j++;
if(j==pbufferlist_size)
while(j<pbufferlist_size && pbufferlist[j]!=pbuf) j++;
if(j==pbufferlist_size) {
DBG(printf("PBuff not found in pbufferlist\n");)
return;
}
// delete de Surface
EGLSurface surface = (EGLSurface)pbufferlist[j];
egl_eglDestroySurface(dpy, surface);
egl_eglDestroySurface(eglDisplay, surface);
delPBuffer(j);
}
@@ -1621,7 +1679,6 @@ int createPBuffer(Display * dpy, const EGLint * egl_attribs, EGLSurface* Surface
LOGD("LIBGL: Error creating PBuffer\n");
return 0;
}
(*Context) = egl_eglCreateContext(eglDisplay, pbufConfigs[0], EGL_NO_CONTEXT, egl_context_attrib);
return 1;
@@ -1837,12 +1894,12 @@ void gl4es_glXDestroyGLXPixmap(Display *display, void *pixmap) {
DBG(printf("glXDestroyGLXPixmap(%p, %p)\n", display, pixmap);)
LOAD_EGL(eglDestroySurface);
int j=0;
while(j<pbufferlist_size || pbufferlist[j]==(GLXPbuffer)pixmap) j++;
while(j<pbufferlist_size && pbufferlist[j]!=(GLXPbuffer)pixmap) j++;
if(j==pbufferlist_size)
return;
// delete de Surface
EGLSurface surface = pbuffersize[j].Surface;// (EGLSurface)pbufferlist[j];
egl_eglDestroySurface(display, surface);
egl_eglDestroySurface(eglDisplay, surface);
delPixBuffer(j);
}
@@ -1900,7 +1957,7 @@ void BlitEmulatedPixmap() {
dst_pos -= 2*stride;
}
} else
pixel_convert(tmp, (void**)&pix, Width, Height, GL_BGRA, GL_UNSIGNED_BYTE, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
pixel_convert(tmp, (void**)&pix, Width, Height, GL_BGRA, GL_UNSIGNED_BYTE, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0, glstate->texture.unpack_align);
free(tmp);
} else {
gles_glReadPixels(0, 0, Width, Height, GL_BGRA, GL_UNSIGNED_BYTE, (void*)pix);
@@ -1978,8 +2035,6 @@ void BlitEmulatedPixmap() {
EGLSurface Surface = egl_eglCreatePbufferSurface(eglDisplay, pbufConfigs[0], egl_attribs);
buff->glxcontext->eglSurface = Surface;
egl_eglMakeCurrent(eglDisplay, Surface, Surface, eglContext);
egl_eglDestroySurface(eglDisplay, buff->Surface);

View File

@@ -125,6 +125,7 @@
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
#define GLX_SWAP_INTERVAL_EXT 0x20F1
typedef int GLXDrawable;
#ifndef ANDROID

View File

@@ -110,6 +110,14 @@ void GetHardwareExtensions(int notest)
S("GL_OES_blend_equation_separate", blendeq, 1);
S("GL_EXT_blend_minmax", blendminmax, 1);
S("GL_EXT_blend_color", blendcolor, 1);
if(hardext.blendcolor==0) {
// try by just loading the function
LOAD_GLES_OR_OES(glBlendColor);
if(gles_glBlendColor != NULL) {
hardext.blendcolor = 1;
SHUT(LOGD("LIBGL: Extension glBlendColor found and used\n"));
}
}
S("GL_OES_point_sprite", pointsprite, 1);
S("GL_OES_point_size_array", pointsize, 0);
S("GL_OES_element_index_uint", elementuint, 0);
@@ -146,4 +154,4 @@ void GetHardwareExtensions(int notest)
egl_eglMakeCurrent(eglDisplay, 0, 0, EGL_NO_CONTEXT);
egl_eglDestroySurface(eglDisplay, eglSurface);
egl_eglDestroyContext(eglDisplay, eglContext);
}
}

View File

@@ -0,0 +1,84 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <dlfcn.h>
#include "rpi.h"
// Code specific to RPI
// everything is dynamicaly linked, so this can be saffely compiled everywhere
extern void* bcm_host;
extern void* vcos;
typedef uint32_t DISPMANX_DISPLAY_HANDLE_T;
typedef uint32_t DISPMANX_UPDATE_HANDLE_T;
typedef uint32_t DISPMANX_ELEMENT_HANDLE_T;
typedef uint32_t DISPMANX_RESOURCE_HANDLE_T;
typedef uint32_t DISPMANX_PROTECTION_T;
typedef struct tag_VC_RECT_T {
int32_t x;
int32_t y;
int32_t width;
int32_t height;
} VC_RECT_T;
typedef struct {
DISPMANX_ELEMENT_HANDLE_T element;
int width;
int height;
} EGL_DISPMANX_WINDOW_T;
int32_t (*graphics_get_display_size)(const uint16_t, uint32_t *, uint32_t*);
DISPMANX_DISPLAY_HANDLE_T (*vc_dispmanx_display_open)(uint32_t);
DISPMANX_UPDATE_HANDLE_T (*vc_dispmanx_update_start)(int32_t);
DISPMANX_ELEMENT_HANDLE_T (*vc_dispmanx_element_add)(
DISPMANX_UPDATE_HANDLE_T, DISPMANX_DISPLAY_HANDLE_T, int32_t,
VC_RECT_T *, DISPMANX_RESOURCE_HANDLE_T,
VC_RECT_T *, DISPMANX_PROTECTION_T,
/*VC_DISPMANX_ALPHA_T*/void*, /*DISPMANX_CLAMP_T*/void*,
/*DISPMANX_TRANSFORM_T*/ int32_t);
int (*vc_dispmanx_update_submit_sync)(DISPMANX_RESOURCE_HANDLE_T);
static DISPMANX_UPDATE_HANDLE_T dispman_update;
static DISPMANX_DISPLAY_HANDLE_T dispman_display;
static VC_RECT_T dst_rect;
static VC_RECT_T src_rect;
void rpi_init() {
#define GO(A) A=dlsym(bcm_host, #A); if(A==NULL) A=dlsym(vcos, #A); if(A==NULL) printf("LIBGL: Warning, " #A " is null")
GO(graphics_get_display_size);
GO(vc_dispmanx_display_open);
GO(vc_dispmanx_update_start);
GO(vc_dispmanx_element_add);
GO(vc_dispmanx_update_submit_sync);
#undef GO
}
void* create_rpi_window(int w, int h) {
static EGL_DISPMANX_WINDOW_T nativewindow;
if(!bcm_host) return NULL;
// create a simple RPI nativewindow of size w*h, on output 0 (i.e. LCD)...
// code heavily inspired from Allegro 5.2
uint32_t screenwidth, screenheight;
graphics_get_display_size(/*LCD*/ 0, &screenwidth, & screenheight);
if(w==0) w=screenwidth;
if(h==0) h=screenheight;
DISPMANX_ELEMENT_HANDLE_T dispman_element;
VC_RECT_T dst_rect, src_rect;
dst_rect.x = 0; dst_rect.y = 0;
dst_rect.width = screenwidth;
dst_rect.height = screenheight;
src_rect.x = 0; src_rect.y = 0;
src_rect.width = w << 16;
src_rect.height = h << 16;
dispman_display = vc_dispmanx_display_open(/*LCD*/ 0);
dispman_update = vc_dispmanx_update_start(0);
dispman_element = vc_dispmanx_element_add(
dispman_update,dispman_display, 0, &dst_rect,
0, &src_rect, /*DISPMANX_PROTECTION_NONE*/ 0, 0, 0,
/*DISPMAN_NO_ROTATE*/ 0);
nativewindow.element = dispman_element;
nativewindow.width = w;
nativewindow.height = h;
vc_dispmanx_update_submit_sync(dispman_update);
return &nativewindow;
}

View File

@@ -0,0 +1,10 @@
#ifndef __RPI_H_
#define __RPI_H_
// Code specific to RPI
void rpi_init();
void* create_rpi_window(int w, int h);
#endif //__RPI_H_

View File

@@ -3,6 +3,6 @@
#define MAJOR 0
#define MINOR 9
#define REVISION 5
#define REVISION 6
#endif //_GL4ES_VERSION_H