gl4es updated, added latest changes by ptitSeb

This commit is contained in:
lubomyr
2016-11-06 22:07:01 +02:00
parent aa4b72349d
commit 90a3f4dbf1
15 changed files with 184 additions and 87 deletions

View File

@@ -1,19 +1,21 @@
gl4es
====
This is a library providing OpenGL 1.x functionality for OpenGL ES accelerated cards.
This is a library providing OpenGL 1.x functionality for OpenGL ES accelerated hardware.
This is a fork a glshim (https://github.com/lunixbochs/glshim). Go check this lib if you need things like RemoteGL or if need support for TinyGLES (for 100% software rendering).
The focusse 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, Blender 2.68 and many more.
Most function of OpenGL up to 1.5 are supported, with some notable exceptions:
* Reading of Depth or Stencil buffer will not work
* GL_FEEDBACK mode is not implemented
Some know limitations:
* GL_SELECT as some limitation in its implementation (for exemple, current Depth buffer or binded texture are not taken into account)
* NPOT texture are supported, but not with GL_REPEAT / GL_MIRRORED, only GL_CLAMP will work properly
* NPOT texture are supported, but not with GL_REPEAT / GL_MIRRORED, only GL_CLAMP will work properly (unless the GLES Hardware support NPOT)
* Framebuffer use FRAMEBUFFER_OES extension (that must be present in the GLES 1.1 stack)
* Multiple Color attachment on Framebuffer are not supported
* OcclusionQuery is implemented, but with a 0 bits precision
@@ -214,6 +216,10 @@ Initial Hardware test
Version history
----
##### 0.9.2
* All matrix are tracked now
* Texture Matrix are 100% handled by gl4es. GLES Hardware keep an Identity matrix (TexCoord are transformed if needed). This allows a better handling of NPOT texture on hadware that doesn't support Full NPOT (fixed movies beiing horizontaly shifted in openmw with LIBGL_NPOT=1 for example)
##### 0.9.1
* Added gl4es specifics glHint capabilities. If the extension GL_GL4ES_hint is present, than a few Hint are accessible. Look in include/gl4eshint.h for the list.

View File

@@ -66,7 +66,7 @@ GLvoid *copy_gl_array(const GLvoid *src,
GLvoid *copy_gl_array_texcoord(const GLvoid *src,
GLenum from, GLsizei width, GLsizei stride,
GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, GLvoid* filler) {
GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, GLvoid* filler, void* dest) {
if (! src || !count)
return NULL;
@@ -74,7 +74,7 @@ GLvoid *copy_gl_array_texcoord(const GLvoid *src,
stride = width * gl_sizeof(from);
const char *unknown_str = "libGL: copy_gl_array -> unknown type: %x\n";
GLvoid *dst = malloc((count-skip) * to_width * gl_sizeof(to));
GLvoid *dst = (dest)?dest:malloc((count-skip) * to_width * gl_sizeof(to));
GLsizei from_size = gl_sizeof(from) * width;
GLsizei to_elem = gl_sizeof(to);
//texcoord are now 4 dim, so this should never happens
@@ -262,7 +262,13 @@ GLvoid *copy_gl_pointer_raw(pointer_state_t *ptr, GLsizei width, GLsizei skip, G
GLvoid *copy_gl_pointer_tex(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
float filler = 1.0f;
return copy_gl_array_texcoord(ptr->pointer, ptr->type, ptr->size, ptr->stride,
GL_FLOAT, width, skip, count, &filler);
GL_FLOAT, width, skip, count, &filler, 0);
}
void copy_gl_pointer_tex_noalloc(void* dest, pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
float filler = 1.0f;
copy_gl_array_texcoord(ptr->pointer, ptr->type, ptr->size, ptr->stride,
GL_FLOAT, width, skip, count, &filler, dest);
}
GLfloat *gl_pointer_index(pointer_state_t *p, GLint index) {

View File

@@ -18,6 +18,7 @@ GLvoid *copy_gl_pointer_color(pointer_state_t *ptr, GLsizei width, GLsizei skip,
GLvoid *copy_gl_pointer_bytecolor(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
GLvoid *copy_gl_pointer_raw(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
GLvoid *copy_gl_pointer_tex(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
void copy_gl_pointer_tex_noalloc(void* dest, pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
GLfloat *gl_pointer_index(pointer_state_t *ptr, GLint index);
GLfloat *copy_eval_double(GLenum target, GLint ustride, GLint uorder, GLint vstride, GLint vorder, const GLdouble *points);
void normalize_indices(GLushort *indices, GLsizei *max, GLsizei *min, GLsizei count);

View File

@@ -373,11 +373,6 @@ static inline bool should_intercept_render(GLenum mode) {
// check bounded tex that will be used if one need some transformations
for (int aa=0; aa<hardext.maxtex; aa++) {
if (glstate->enable.texture_2d[aa] || glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa]) {
if(glstate->texture.rect_arb[aa])
return true;
gltexture_t *bound = glstate->texture.bound[aa];
if (bound && (bound->width!=bound->nwidth || bound->height!=bound->nheight))
return true;
if ((glstate->enable.texgen_s[aa] || glstate->enable.texgen_t[aa] || glstate->enable.texgen_r[aa] || glstate->enable.texgen_q[aa]))
return true;
}

View File

@@ -3,6 +3,7 @@
#include "debug.h"
#include "../glx/hardext.h"
#include "init.h"
#include "matrix.h"
#define alloc_sublist(n, cap) \
(GLfloat *)malloc(n * sizeof(GLfloat) * cap)
@@ -682,10 +683,6 @@ void adjust_renderlist(renderlist_t *list) {
// in case of Texture bounding inside a list
if (list->set_texture && (list->tmu == a))
bound = gl4es_getTexture(list->target_texture, list->texture);
// adjust the tex_coord now
if ((list->tex[a]) && (bound) && ((bound->width != bound->nwidth) || (bound->height != bound->nheight))) {
tex_coord_npot(list->tex[a], list->len, bound->width, bound->height, bound->nwidth, bound->nheight);
}
// GL_ARB_texture_rectangle
if ((list->tex[a]) && glstate->texture.rect_arb[a] && (bound)) {
tex_coord_rect_arb(list->tex[a], list->len, bound->width, bound->height);
@@ -922,28 +919,47 @@ void draw_renderlist(renderlist_t *list) {
list->tex[0] = gen_stipple_tex_coords(list->vert, list->len);
}
}
GLfloat *texgened[MAX_TEX];
static GLfloat *texgened[MAX_TEX] = {0};
static int texgenedsz[MAX_TEX] = {0};
int use_texgen[MAX_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];
for (int a=0; a<hardext.maxtex; a++) {
texgened[a]=NULL;
needclean[a]=0;
use_texgen[a]=0;
if ((glstate->enable.texgen_s[a] || glstate->enable.texgen_t[a] || glstate->enable.texgen_r[a] || glstate->enable.texgen_q[a])) {
RS(a, list->len);
gen_tex_coords(list->vert, list->normal, &texgened[a], list->len, &needclean[a], a, (list->ilen<list->len)?indices:NULL, (list->ilen<list->len)?list->ilen:0);
} else if (glstate->enable.texture_2d[a] && (list->tex[a]==NULL) && !(list->mode==GL_POINT && glstate->texture.pscoordreplace[a])) {
RS(a, list->len);
gen_tex_coords(list->vert, list->normal, &texgened[a], list->len, &needclean[a], a, (list->ilen<list->len)?indices:NULL, (list->ilen<list->len)?list->ilen:0);
}
}
// adjust the tex_coord now if needed, even on texgened ones
gltexture_t *bound = glstate->texture.bound[a];
if((list->tex[a] || use_texgen[a]) && ((!glstate->texture_matrix[a]->identity) || (bound) && ((bound->width != bound->nwidth) || (bound->height != bound->nheight)))) {
if(!use_texgen[a]) {
RS(a, list->len);
memcpy(texgened[a], list->tex[a], 4*sizeof(GLfloat)*list->len);
}
if (!glstate->texture_matrix[a]->identity)
tex_coord_matrix(texgened[a], list->len, getTexMat(a));
if ((bound) && ((bound->width != bound->nwidth) || (bound->height != bound->nheight))) {
tex_coord_npot(texgened[a], list->len, bound->width, bound->height, bound->nwidth, bound->nheight);
}
}
}
#undef RS
old_tex = glstate->texture.client;
GLuint cur_tex = old_tex;
#define TEXTURE(A) if (cur_tex!=A) {gl4es_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;}
for (int a=0; a<hardext.maxtex; a++) {
if ((list->tex[a] || texgened[a])/* && glstate->enable.texture_2d[a]*/) {
if ((list->tex[a] || use_texgen[a])/* && glstate->enable.texture_2d[a]*/) {
TEXTURE(a);
if(!glstate->clientstate.tex_coord_array[a]) {
gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glstate->clientstate.tex_coord_array[a] = 1;
}
gles_glTexCoordPointer(4, GL_FLOAT, 0, (texgened[a])?texgened[a]:list->tex[a]);
gles_glTexCoordPointer(4, GL_FLOAT, 0, (use_texgen[a])?texgened[a]:list->tex[a]);
} else {
if (glstate->clientstate.tex_coord_array[a]) {
TEXTURE(a);
@@ -1158,10 +1174,6 @@ void draw_renderlist(renderlist_t *list) {
TEXTURE(a);
gen_tex_clean(needclean[a], a);
}
if (texgened[a]) {
free(texgened[a]);
texgened[a] = NULL;
}
if (!glstate->enable.texture_2d[a] && (glstate->enable.texture_1d[a] || glstate->enable.texture_3d[a])) {
TEXTURE(a);
gles_glDisable(GL_TEXTURE_2D);

View File

@@ -12,14 +12,10 @@
void alloc_matrix(matrixstack_t **matrixstack, int depth) {
*matrixstack = (matrixstack_t*)malloc(sizeof(matrixstack_t));
(*matrixstack)->top = 0;
(*matrixstack)->identity = 0;
(*matrixstack)->stack = (GLfloat*)malloc(sizeof(GLfloat)*depth*16);
}
void set_identity(GLfloat* mat) {
memset(mat, 0, 16*sizeof(GLfloat));
mat[0] = mat[1+4] = mat[2+8] = mat[3+12] = 1.0f;
}
#define TOP(A) (glstate->A->stack+(glstate->A->top*16))
static GLfloat* update_current_mat() {
@@ -34,19 +30,45 @@ static GLfloat* update_current_mat() {
return NULL;
}
static int update_current_identity(int I) {
switch(glstate->matrix_mode) {
case GL_MODELVIEW:
return glstate->modelview_matrix->identity = (I)?1:is_identity(TOP(modelview_matrix));
case GL_PROJECTION:
return glstate->projection_matrix->identity = (I)?1:is_identity(TOP(projection_matrix));
case GL_TEXTURE:
return glstate->texture_matrix[glstate->texture.active]->identity = (I)?1:is_identity(TOP(texture_matrix[glstate->texture.active]));
}
return 0;
}
static int send_to_hardware() {
switch(glstate->matrix_mode) {
case GL_PROJECTION:
return 1;
case GL_MODELVIEW:
return 1;
case GL_TEXTURE:
return 0;
}
return 0;
}
void init_matrix(glstate_t* glstate) {
alloc_matrix(&glstate->projection_matrix, MAX_STACK_PROJECTION);
set_identity(TOP(projection_matrix));
glstate->projection_matrix->identity = 1;
alloc_matrix(&glstate->modelview_matrix, MAX_STACK_MODELVIEW);
set_identity(TOP(modelview_matrix));
glstate->modelview_matrix->identity = 1;
glstate->texture_matrix = (matrixstack_t**)malloc(sizeof(matrixstack_t*)*MAX_TEX);
for (int i=0; i<MAX_TEX; i++) {
alloc_matrix(&glstate->texture_matrix[i], MAX_STACK_TEXTURE);
set_identity(TOP(texture_matrix[i]));
glstate->texture_matrix[i]->identity = 1;
}
}
void gl4es_glMatrixMode(GLenum mode) {
DBG(printf("glMatrixMode(%s), list=%p\n", PrintEnum(mode), glstate->list.active);)
PUSH_IF_COMPILING(glMatrixMode);
@@ -81,7 +103,7 @@ DBG(printf("glPushMatrix(), list=%p\n", glstate->list.active);)
P(modelview_matrix, MODELVIEW);
break;
case GL_TEXTURE:
P(texture_matrix[glstate->texture.active], PROJECTION);
P(texture_matrix[glstate->texture.active], TEXTURE);
break;
#undef P
default:
@@ -103,7 +125,8 @@ DBG(printf("glPopMatrix(), list=%p\n", glstate->list.active);)
switch(matrix_mode) {
#define P(A) if(glstate->A->top) { \
--glstate->A->top; \
gles_glLoadMatrixf(update_current_mat()); \
glstate->A->identity = is_identity(update_current_mat()); \
if (send_to_hardware()) gles_glLoadMatrixf(update_current_mat()); \
} else errorShim(GL_STACK_UNDERFLOW)
case GL_PROJECTION:
P(projection_matrix);
@@ -127,6 +150,7 @@ DBG(printf("glPopMatrix(), list=%p\n", glstate->list.active);)
void gl4es_glLoadMatrixf(const GLfloat * m) {
DBG(printf("glLoadMatrix(%f, %f, %f, %f, %f, %f, %f...), list=%p\n", m[0], m[1], m[2], m[3], m[4], m[5], m[6], glstate->list.active);)
LOAD_GLES(glLoadMatrixf);
LOAD_GLES(glLoadIdentity);
if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) {
NewStage(glstate->list.active, STAGE_MATRIX);
@@ -135,12 +159,16 @@ DBG(printf("glLoadMatrix(%f, %f, %f, %f, %f, %f, %f...), list=%p\n", m[0], m[1],
return;
}
memcpy(update_current_mat(), m, 16*sizeof(GLfloat));
gles_glLoadMatrixf(m);
const int id = update_current_identity(0);
if(send_to_hardware())
if(id) gles_glLoadIdentity(); // in case the driver as some special optimisations
else gles_glLoadMatrixf(m);
}
void gl4es_glMultMatrixf(const GLfloat * m) {
DBG(printf("glMultMatrix(%f, %f, %f, %f, %f, %f, %f...), list=%p\n", m[0], m[1], m[2], m[3], m[4], m[5], m[6], glstate->list.active);)
LOAD_GLES(glLoadMatrixf);
LOAD_GLES(glLoadIdentity);
if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) {
if(glstate->list.active->stage == STAGE_MATRIX) {
// multiply the matrix mith the current one....
@@ -154,7 +182,10 @@ DBG(printf("glMultMatrix(%f, %f, %f, %f, %f, %f, %f...), list=%p\n", m[0], m[1],
}
GLfloat *current_mat = update_current_mat();
matrix_mul(current_mat, m, current_mat);
gles_glLoadMatrixf(current_mat);
const int id = update_current_identity(0);
if(send_to_hardware())
if(id) gles_glLoadIdentity(); // in case the driver as some special optimisations
else gles_glLoadMatrixf(current_mat);
}
void gl4es_glLoadIdentity() {
@@ -168,7 +199,8 @@ DBG(printf("glLoadIdentity(), list=%p\n", glstate->list.active);)
}
set_identity(update_current_mat());
gles_glLoadIdentity();
update_current_identity(1);
if(send_to_hardware()) gles_glLoadIdentity();
}
void gl4es_glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
@@ -237,16 +269,14 @@ DBG(printf("glFrustumf(%f, %f, %f, %f, %f, %f) list=%p\n", left, right, top, bot
GLfloat tmp[16];
memset(tmp, 0, 16*sizeof(GLfloat));
tmp[0+0] = 2.0f*nearVal/(right-left); tmp[0+8] = -(right+left)/(right-left);
tmp[1+4] = 2.0f*nearVal/(top-bottom); tmp[1+8] = -(top+bottom)/(top-bottom);
tmp[2+8] =-(farVal+nearVal)/(farVal-nearVal); tmp[2+12] = -2.0f*farVal*nearVal/(farVal-nearVal);
tmp[0+0] = 2.0f*nearVal/(right-left); tmp[0+8] = (right+left)/(right-left);
tmp[1+4] = 2.0f*nearVal/(top-bottom); tmp[1+8] = (top+bottom)/(top-bottom);
tmp[2+8] =-(farVal+nearVal)/(farVal-nearVal); tmp[2+12] =-2.0f*farVal*nearVal/(farVal-nearVal);
tmp[3+8] = -1.0f;
gl4es_glMultMatrixf(tmp);
}
void glMatrixMode(GLenum mode) AliasExport("gl4es_glMatrixMode");
void glPushMatrix() AliasExport("gl4es_glPushMatrix");
void glPopMatrix() AliasExport("gl4es_glPopMatrix");

View File

@@ -11,3 +11,7 @@ void gl4es_glScalef(GLfloat x, GLfloat y, GLfloat z);
void gl4es_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
void gl4es_glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal);
void gl4es_glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal);
static inline GLfloat* getTexMat(int tmu) {
return glstate->texture_matrix[tmu]->stack+glstate->texture_matrix[tmu]->top*16;
}

View File

@@ -67,10 +67,11 @@ void vector_matrix(const float *a, const float *b, float *c) {
: "%2", "q0", "q1", "q2", "memory"
);
#else
c[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12];
c[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13];
c[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14];
c[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15];
const float a0=a[0], a1=a[1], a2=a[2], a3=a[3];
c[0] = a0 * b[0] + a1 * b[4] + a2 * b[8] + a3 * b[12];
c[1] = a0 * b[1] + a1 * b[5] + a2 * b[9] + a3 * b[13];
c[2] = a0 * b[2] + a1 * b[6] + a2 * b[10] + a3 * b[14];
c[3] = a0 * b[3] + a1 * b[7] + a2 * b[11] + a3 * b[15];
#endif
}
@@ -283,3 +284,14 @@ void matrix_mul(const float *a, const float *b, float *c) {
#endif
}
void set_identity(float* mat) {
memset(mat, 0, 16*sizeof(GLfloat));
mat[0] = mat[1+4] = mat[2+8] = mat[3+12] = 1.0f;
}
int is_identity(const float* mat) {
static float i1[16];
static int set=0;
if(!set) {set_identity(i1); set=1;}
return memcmp(mat, i1, 16*sizeof(float))==0?1:0;
}

View File

@@ -13,6 +13,7 @@ void vector4_normalize(float *a);
void matrix_transpose(const float *a, float *b);
void matrix_inverse(const float *m, float *r);
void matrix_mul(const float *a, const float *b, float *c);
void set_identity(float* mat);
int is_identity(const float* mat);
#endif

View File

@@ -117,6 +117,7 @@ typedef struct {
typedef struct {
int top;
int identity;
GLfloat *stack;
} matrixstack_t;

View File

@@ -19,7 +19,7 @@ void gl4es_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) {
generation function specified by pname.
*/
//printf("glTexGenfv(%s, %s, [%s, ...]), texture=%i\n", PrintEnum(coord), PrintEnum(pname), PrintEnum(param[0]), glstate->texture.active);
//printf("glTexGenf(%s, %s, %s/%f), texture=%i\n", PrintEnum(coord), PrintEnum(pname), PrintEnum(param[0]), param[0], glstate->texture.active);
if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) {
NewStage(glstate->list.active, STAGE_TEXGEN);
rlTexGenfv(glstate->list.active, coord, pname, param);
@@ -151,9 +151,7 @@ void sphere_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint
GLfloat ModelviewMatrix[16], InvModelview[16];
gl4es_glGetFloatv(GL_MODELVIEW_MATRIX, InvModelview);
// column major -> row major
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
ModelviewMatrix[i*4+j]=InvModelview[i+j*4];
matrix_transpose(InvModelview, ModelviewMatrix);
// And get the inverse
matrix_inverse(ModelviewMatrix, InvModelview);
GLfloat eye[4], eye_norm[4], reflect[4];
@@ -177,6 +175,36 @@ void sphere_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint
}
void reflection_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint count, GLushort *indices) {
// based on https://www.opengl.org/wiki/Mathematics_of_glTexGen
/* if (!norm) {
printf("LIBGL: GL_REFLECTION_MAP without Normals\n");
return;
}*/
// First get the ModelviewMatrix
GLfloat ModelviewMatrix[16], InvModelview[16];
gl4es_glGetFloatv(GL_MODELVIEW_MATRIX, InvModelview);
// column major -> row major
matrix_transpose(InvModelview, ModelviewMatrix);
// And get the inverse
matrix_inverse(ModelviewMatrix, InvModelview);
GLfloat eye[4], eye_norm[4];
GLfloat a;
for (int i=0; i<count; i++) {
GLushort k = indices?indices[i]:i;
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;
out[k*4+0] = eye[0] - eye_norm[0]*a;
out[k*4+1] = eye[1] - eye_norm[1]*a;
out[k*4+2] = eye[2] - eye_norm[2]*a;
out[k*4+3] = 1.0f;
}
}
void eye_loop(const GLfloat *verts, const GLfloat *param, GLfloat *out, GLint count, GLushort *indices) {
// based on https://www.opengl.org/wiki/Mathematics_of_glTexGen
// First get the ModelviewMatrix
@@ -231,10 +259,10 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count
// special case: SPHERE_MAP needs both texgen to make sense
if ((glstate->enable.texgen_s[texture] && (glstate->texgen[texture].S==GL_SPHERE_MAP)) && (glstate->enable.texgen_t[texture] && (glstate->texgen[texture].T==GL_SPHERE_MAP)))
{
if (!glstate->enable.texture_2d[texture])
return;
if ((*coords)==NULL)
*coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat));
if (!glstate->enable.texture_2d[texture])
return;
if ((*coords)==NULL)
*coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat));
sphere_loop(verts, norm, *coords, (indices)?ilen:count, indices);
return;
}
@@ -243,22 +271,11 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count
&& (glstate->enable.texgen_t[texture] && (glstate->texgen[texture].T==GL_REFLECTION_MAP))
&& (glstate->enable.texgen_r[texture] && (glstate->texgen[texture].R==GL_REFLECTION_MAP)))
{
*needclean=1;
// setup reflection map!
GLuint old_tex=glstate->texture.active;
if (old_tex!=texture) gl4es_glActiveTexture(GL_TEXTURE0 + texture);
LOAD_GLES_OES(glTexGeni);
LOAD_GLES_OES(glTexGenfv);
LOAD_GLES(glEnable);
// setup cube map mode
gles_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
gles_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
gles_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
// enable texgen
gles_glEnable(GL_TEXTURE_GEN_STR); //GLES only support the 3 gen at the same time!
if (old_tex!=texture) gl4es_glActiveTexture(GL_TEXTURE0 + old_tex);
if (!glstate->enable.texture_2d[texture])
return;
if ((*coords)==NULL)
*coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat));
reflection_loop(verts, norm, *coords, (indices)?ilen:count, indices);
return;
}
// special case: NORMAL_MAP needs the 3 texgen to make sense

View File

@@ -9,6 +9,7 @@
#include "../glx/streaming.h"
#include "../glx/hardext.h"
#include "init.h"
#include "matrix.h"
#ifndef GL_TEXTURE_STREAM_IMG
#define GL_TEXTURE_STREAM_IMG 0x8C0D
@@ -46,7 +47,6 @@ void tex_coord_npot(GLfloat *tex, GLsizei len,
GLsizei nwidth, GLsizei nheight) {
if (!tex || !nwidth || !nheight)
return;
GLfloat wratio = (width / (GLfloat)nwidth);
GLfloat hratio = (height / (GLfloat)nheight);
for (int i = 0; i < len; i++) {
@@ -56,42 +56,52 @@ void tex_coord_npot(GLfloat *tex, GLsizei len,
}
}
void tex_coord_matrix(GLfloat *tex, GLsizei len, const GLfloat* mat) {
if (!tex || !len || !mat)
return;
for (int i = 0; i < len; i++) {
vector_matrix(tex, mat, tex);
tex += 4;
}
}
/* Setup the texture coordinates
*
* Have to check is ARB_RECTANGLE is used
* Apply texture matrix if not identity
* Or some NPOT texture used
* Or SHRINKED texure used
*/
void tex_setup_texcoord(GLuint len) {
LOAD_GLES(glTexCoordPointer);
GLuint texunit = glstate->texture.client;
static void * tex[8] = {0,0,0,0,0,0,0,0}; // hugly but convenient...
static void * tex[MAX_TEX] = {0};
static int texlen[MAX_TEX] = {0};
if (tex[texunit]) {
free(tex[texunit]);
tex[texunit]=NULL;
}
gltexture_t *bound = glstate->texture.bound[texunit];
// check if some changes are needed
int changes = 0;
if ((glstate->texture.rect_arb[texunit]) ||
(bound && ((bound->width!=bound->nwidth)||(bound->height!=bound->nheight)||
(bound->shrink && (glstate->vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (glstate->vao->pointers.tex_coord[texunit].type!=GL_DOUBLE)))))
if ((glstate->texture.rect_arb[texunit])
|| (bound && ((bound->width!=bound->nwidth)||(bound->height!=bound->nheight)
)) || !glstate->texture_matrix[texunit]->identity
)
changes = 1;
if (changes) {
// first convert to GLfloat, without normalization
tex[texunit] = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[texunit], 4, 0, len);
if (!tex[texunit]) {
printf("LIBGL: Error with Texture tranform\n");
gles_glTexCoordPointer(glstate->vao->pointers.tex_coord[texunit].size, glstate->vao->pointers.tex_coord[texunit].type, glstate->vao->pointers.tex_coord[texunit].stride, glstate->vao->pointers.tex_coord[texunit].pointer);
return;
if(texlen[texunit]<len) {
if(tex[texunit]) free(tex[texunit]);
tex[texunit] = malloc(4*sizeof(GLfloat)*len);
texlen[texunit] = len;
}
copy_gl_pointer_tex_noalloc(tex[texunit], &glstate->vao->pointers.tex_coord[texunit], 4, 0, len);
// Normalize if needed
if ((glstate->texture.rect_arb[texunit]) || ((glstate->vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (glstate->vao->pointers.tex_coord[texunit].type!=GL_DOUBLE)))
if ((glstate->texture.rect_arb[texunit]))
tex_coord_rect_arb(tex[texunit], len, bound->width, bound->height);
// Apply transformation matrix if any
if (!glstate->texture_matrix[texunit]->identity)
tex_coord_matrix(tex[texunit], len, getTexMat(texunit));
// NPOT adjust
if ((bound->width!=bound->nwidth) || (bound->height!=bound->nheight))
tex_coord_npot(tex[texunit], len, bound->width, bound->height, bound->nwidth, bound->nheight);
// All done, setup the texcoord array now

View File

@@ -88,6 +88,9 @@ void tex_coord_rect_arb(GLfloat *tex, GLsizei len,
void tex_coord_npot(GLfloat *tex, GLsizei len,
GLsizei width, GLsizei height,
GLsizei nwidth, GLsizei nheight);
void tex_coord_matrix(GLfloat *tex, GLsizei len, const GLfloat* mat);
int npot(int n);
typedef struct {

View File

@@ -3,7 +3,6 @@
#endif
#include <fcntl.h>
#include "../../version.h"
#include "../gl/init.h"
#ifdef USE_FBIO

View File

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