glshim updated. added changes from https://github.com/ptitSeb/glshim

This commit is contained in:
lubomyr
2015-09-27 15:11:13 +03:00
parent c8fc91b310
commit 4f2acb52ad
15 changed files with 492 additions and 332 deletions

View File

@@ -1,4 +1,5 @@
#include "array.h"
#include "debug.h"
GLvoid *copy_gl_array(const GLvoid *src,
GLenum from, GLsizei width, GLsizei stride,
@@ -63,16 +64,51 @@ GLvoid *copy_gl_array(const GLvoid *src,
return dst;
}
GLvoid *copy_gl_array_quickconvert(const GLvoid *src,
GLenum from, GLsizei stride,
GLsizei skip, GLsizei count) {
if (! stride)
stride = 4 * gl_sizeof(from);
const char *unknown_str = "libGL: copy_gl_array_quickconvert -> unknown type: %x\n";
GLvoid *dst = malloc((count-skip) * 4 * gl_sizeof(GL_FLOAT));
GLsizei from_size = gl_sizeof(from) * 4;
GLsizei to_size = gl_sizeof(GL_FLOAT) * 4;
uintptr_t in = (uintptr_t)src;
in += stride*skip;
int j;
GLfloat *out = (GLfloat*)dst;
GL_TYPE_SWITCH2(input, in, from,
const GLfloat maxf = 1.0f/gl_max_value(from);
for (int i = skip; i < count; i++)
,
for (j = 0; j < 4; j++) {
out[j] = ((GLfloat)input[j])*maxf;
}
out += 4;
in += stride;
,
default:
printf(unknown_str, from);
return NULL;
)
return dst;
}
GLvoid *copy_gl_array_convert(const GLvoid *src,
GLenum from, GLsizei width, GLsizei stride,
GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, GLvoid* filler) {
if (! src || !count)
return NULL;
if(to==GL_FLOAT && width==to_width && width==4)
return copy_gl_array_quickconvert(src, from, stride, skip, count);
if (! stride)
stride = width * gl_sizeof(from);
const char *unknown_str = "libGL: copy_gl_array -> unknown type: %x\n";
const char *unknown_str = "libGL: copy_gl_array_convert -> unknown type: %x\n";
GLvoid *dst = malloc((count-skip) * to_width * gl_sizeof(to));
GLsizei from_size = gl_sizeof(from) * width;
GLsizei to_size = gl_sizeof(to) * to_width;
@@ -106,10 +142,12 @@ GLvoid *copy_gl_array_convert(const GLvoid *src,
)
} else {
GL_TYPE_SWITCH_MAX(out, dst, to,
for (int i = skip; i < count; i++) {
GL_TYPE_SWITCH(input, in, from,
GL_TYPE_SWITCH2(input, in, from,
const GLuint maxf = gl_max_value(from);
for (int i = skip; i < count; i++)
,
for (j = 0; j < width; j++) {
out[j] = input[j]*maxv/gl_max_value(from);
out[j] = input[j]*maxv/maxf;
}
for (; j < to_width-1; j++) {
out[j]=0;
@@ -119,12 +157,11 @@ GLvoid *copy_gl_array_convert(const GLvoid *src,
}
out += to_width;
in += stride;
,
,
default:
printf(unknown_str, from);
return NULL;
)
},
),
default:
printf(unknown_str, to);
return NULL;

View File

@@ -0,0 +1,59 @@
#include "debug.h"
#define p(a) \
case a: return #a
const char* PrintEnum(GLenum what) {
static char fallback[64];
switch(what)
{
// target
p(GL_TEXTURE_1D);
p(GL_TEXTURE_2D);
p(GL_TEXTURE_3D);
p(GL_FRAMEBUFFER);
p(GL_RENDERBUFFER);
p(GL_PROXY_TEXTURE_1D);
p(GL_PROXY_TEXTURE_2D);
p(GL_PROXY_TEXTURE_3D);
p(GL_READ_FRAMEBUFFER);
p(GL_DRAW_FRAMEBUFFER);
// format
p(GL_RED);
p(GL_RGB);
p(GL_RGBA);
p(GL_RGBA8);
p(GL_RGB8);
p(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
p(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
p(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
p(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
// type
p(GL_UNSIGNED_BYTE);
p(GL_UNSIGNED_BYTE_2_3_3_REV);
p(GL_UNSIGNED_BYTE_3_3_2);
p(GL_UNSIGNED_INT);
p(GL_UNSIGNED_SHORT);
p(GL_UNSIGNED_SHORT_5_5_5_1);
p(GL_UNSIGNED_SHORT_1_5_5_5_REV);
p(GL_UNSIGNED_SHORT_4_4_4_4);
p(GL_UNSIGNED_SHORT_4_4_4_4_REV);
p(GL_UNSIGNED_SHORT_5_6_5);
p(GL_UNSIGNED_SHORT_5_6_5_REV);
p(GL_FLOAT);
p(GL_DOUBLE);
// texture pack/unpack
p(GL_UNPACK_ALIGNMENT);
// framebuffer
p(GL_COLOR_ATTACHMENT0);
p(GL_COLOR_ATTACHMENT1);
p(GL_COLOR_ATTACHMENT2);
p(GL_COLOR_ATTACHMENT3);
p(GL_COLOR_ATTACHMENT4);
p(GL_DEPTH_ATTACHMENT);
p(GL_STENCIL_ATTACHMENT);
default:
sprintf(fallback, "0x%04X", what);
}
return fallback;
}

View File

@@ -0,0 +1,8 @@
#ifndef __DEBUG_H_
#define __DEBUG_H_
#include "gl.h"
const char* PrintEnum(GLenum what);
#endif

View File

@@ -1,4 +1,5 @@
#include "framebuffers.h"
#include "debug.h"
#ifndef ANDROID
#include <execinfo.h>
@@ -19,13 +20,19 @@ int mainfbo_height = 480;
int mainfbo_nwidth = 1024;
int mainfbo_nheight = 512;
extern bool g_recyclefbo;
GLuint fbo_read = 0; // if not 0, that's the READ only Framebuffer attached
GLuint fbo_draw = 0; // if not 0, that's the DRAW only Framebuffer attached
GLuint *old_fbos = NULL;
int nbr_fbos = 0;
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);
//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;
@@ -36,7 +43,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);
//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;
@@ -48,23 +55,44 @@ void readfboEnd() {
void glGenFramebuffers(GLsizei n, GLuint *ids) {
LOAD_GLES_OES(glGenFramebuffers);
//printf("glGenFramebuffers(%i, %p)\n", n, ids);
//printf("glGenFramebuffers(%i, %p)\n", n, ids);
GLsizei m = 0;
while(g_recyclefbo && (nbr_fbos>0) && (n-m>0)) {
//printf("Recycled 1 FBO\n");
ids[m++] = old_fbos[--nbr_fbos];
}
noerrorShim();
if(n-m == 0)
return;
errorGL();
gles_glGenFramebuffers(n, ids);
gles_glGenFramebuffers(n-m, ids+m);
}
void glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) {
//printf("glDeleteFramebuffers(%i, %p), framebuffers[0]=%u\n", n, framebuffers, framebuffers[0]);
//printf("glDeleteFramebuffers(%i, %p), framebuffers[0]=%u\n", n, framebuffers, framebuffers[0]);
if (state.gl_batch) flush();
LOAD_GLES_OES(glDeleteFramebuffers);
errorGL();
gles_glDeleteFramebuffers(n, framebuffers);
if (g_recyclefbo) {
//printf("Recycling %i FBOs\n", n);
noerrorShim();
if(cap_fbos == 0) {
cap_fbos = 16;
old_fbos = (GLuint*)malloc(cap_fbos * sizeof(GLuint));
}
if (nbr_fbos+n == cap_fbos) {
cap_fbos += n;
old_fbos = (GLuint*)realloc(old_fbos, cap_fbos *sizeof(GLuint));
}
memcpy(old_fbos+nbr_fbos, framebuffers, n*sizeof(GLuint));
nbr_fbos += n;
} else {
LOAD_GLES_OES(glDeleteFramebuffers);
errorGL();
gles_glDeleteFramebuffers(n, framebuffers);
}
}
GLboolean glIsFramebuffer(GLuint framebuffer) {
//printf("glIsFramebuffer(%u)\n", framebuffer);
//printf("glIsFramebuffer(%u)\n", framebuffer);
if (state.gl_batch) flush();
LOAD_GLES_OES(glIsFramebuffer);
@@ -92,7 +120,7 @@ GLenum glCheckFramebufferStatus(GLenum target) {
}
void glBindFramebuffer(GLenum target, GLuint framebuffer) {
//printf("glBindFramebuffer(0x%04X, %u), list=%s\n", target, framebuffer, state.list.active?"active":"none");
//printf("glBindFramebuffer(%s, %u), list=%s\n", PrintEnum(target), framebuffer, state.list.active?"active":"none");
//PUSH_IF_COMPILING(glBindFramebuffer);
if (state.gl_batch) flush();
LOAD_GLES_OES(glBindFramebuffer);
@@ -118,13 +146,16 @@ void glBindFramebuffer(GLenum target, GLuint framebuffer) {
fbo_draw = framebuffer;
}
if(target==GL_FRAMEBUFFER && framebuffer!=0) {
gles_glBindFramebuffer(target, 0);
gles_glCheckFramebufferStatus(target);
}
current_fb = framebuffer;
if (mainfbo_fbo && (framebuffer==0))
framebuffer = mainfbo_fbo;
//errorGL();
//noerrorShim();
gles_glBindFramebuffer(target, framebuffer);
GLenum err=gles_glGetError();
errorShim(err);
@@ -132,14 +163,17 @@ void glBindFramebuffer(GLenum target, GLuint framebuffer) {
fb_status = gles_glCheckFramebufferStatus(target);
}
void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
static GLuint scrap_tex = 0;
static int scrap_width = 0;
static int scrap_height = 0;
if (state.gl_batch) flush();
LOAD_GLES_OES(glFramebufferTexture2D);
LOAD_GLES(glTexImage2D);
LOAD_GLES(glBindTexture);
//printf("glFramebufferTexture2D(0x%04X, 0x%04X, 0x%04X, %u, %i)\n", target, attachment, textarget, texture, level);
if (level!=0)
return;
//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)) {
@@ -147,6 +181,7 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget,
return;
}
int twidth = 0, theight = 0;
// find texture and get it's real name
if (texture) {
gltexture_t *tex = NULL;
@@ -162,7 +197,7 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget,
k = kh_get(tex, list, texture);
if (k == kh_end(list)){
//printf("*WARNING* texture for FBO not found, name=%u\n", texture);
printf("*WARNING* texture for FBO not found, name=%u\n", texture);
} else {
tex = kh_value(list, k);
texture = tex->glname;
@@ -180,6 +215,8 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget,
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);
}
twidth = tex->nwidth;
theight = tex->nheight;
/* if ((tex->width<32) || (tex->height<32)) {
printf("LIBGL: enlarging too-small texture for FBO\n");
tex->nwidth = (tex->nwidth<32)?32:tex->nwidth;
@@ -191,10 +228,29 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget,
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);
//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);
}
}
twidth = twidth >> level; if(twidth<1) twidth=1;
theight = theight >> level; if(theight<1) theight=1;
if (level!=0) {
//bind a scrap texture, we don't want level != 0 binding on GLES
if(!scrap_tex)
glGenTextures(1, &scrap_tex);
if ((scrap_width!=twidth) || (scrap_height!=theight)) {
scrap_width = twidth;
scrap_height = theight;
gltexture_t *bound = state.texture.bound[state.texture.active];
GLuint oldtex = (bound)?bound->glname:0;
if (oldtex!=scrap_tex) gles_glBindTexture(GL_TEXTURE_2D, scrap_tex);
gles_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, scrap_width, scrap_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
if (oldtex!=scrap_tex) gles_glBindTexture(GL_TEXTURE_2D, oldtex);
}
texture = scrap_tex;
}
errorGL();
gles_glFramebufferTexture2D(target, attachment, textarget, texture, 0);
}
@@ -209,7 +265,7 @@ void glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget,
void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) {
LOAD_GLES_OES(glGenRenderbuffers);
//printf("glGenRenderbuffers(%i, %p)\n", n, renderbuffers);
//printf("glGenRenderbuffers(%i, %p)\n", n, renderbuffers);
errorGL();
gles_glGenRenderbuffers(n, renderbuffers);
@@ -218,9 +274,9 @@ void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) {
void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
LOAD_GLES_OES(glFramebufferRenderbuffer);
LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv);
//printf("glFramebufferRenderbuffer(0x%04X, 0x%04X, 0x%04X, %u)\n", target, attachment, renderbuffertarget, renderbuffer);
//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)) {
khint_t k = kh_get(dsr, depthstencil, renderbuffer);
if (k != kh_end(depthstencil)) {
@@ -235,15 +291,7 @@ void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbu
noerrorShim();
return;
}
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);
if (tmp==renderbuffer) {
noerrorShim();
return;
}
}
errorGL();
gles_glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
}
@@ -278,7 +326,7 @@ void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width,
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);
//printf("glRenderbufferStorage(0x%04X, 0x%04X, %i, %i)\n", target, internalformat, width, height);
errorGL();
width = npot(width);
@@ -325,7 +373,7 @@ void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum int
void glBindRenderbuffer(GLenum target, GLuint renderbuffer) {
if (state.gl_batch) flush();
LOAD_GLES_OES(glBindRenderbuffer);
//printf("glBindRenderbuffer(0x%04X, %u)\n", target, renderbuffer);
//printf("glBindRenderbuffer(%s, %u), binded Fbo=%u\n", PrintEnum(target), renderbuffer, current_fb);
current_rb = renderbuffer;
@@ -334,7 +382,7 @@ void glBindRenderbuffer(GLenum target, GLuint renderbuffer) {
}
GLboolean glIsRenderbuffer(GLuint renderbuffer) {
//printf("glIsRenderbuffer(%u)\n", renderbuffer);
//printf("glIsRenderbuffer(%u)\n", renderbuffer);
if (state.gl_batch) flush();
LOAD_GLES_OES(glIsRenderbuffer);
@@ -343,7 +391,7 @@ GLboolean glIsRenderbuffer(GLuint renderbuffer) {
}
void glGenerateMipmap(GLenum target) {
//printf("glGenerateMipmap(0x%04X)\n", target);
//printf("glGenerateMipmap(0x%04X)\n", target);
LOAD_GLES_OES(glGenerateMipmap);
errorGL();
@@ -351,6 +399,7 @@ void glGenerateMipmap(GLenum target) {
}
void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) {
//printf("glGetFramebufferAttachmentParameteriv(%s, %s, %s, %p)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(pname), params);
LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv);
errorGL();
@@ -358,6 +407,7 @@ void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLe
}
void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint * params) {
//printf("glGetRenderbufferParameteriv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(pname), params);
LOAD_GLES_OES(glGetRenderbufferParameteriv);
errorGL();
@@ -381,10 +431,12 @@ void createMainFBO(int width, int height) {
LOAD_GLES(glClientActiveTexture);
LOAD_GLES(glClear);
// If there is already a Framebuffer created, let's delete it....
if (mainfbo_fbo)
// If there is already a Framebuffer created, let's delete it.... unless it's already the right size!
if (mainfbo_fbo) {
if (width==mainfbo_width && height==mainfbo_height)
return;
deleteMainFBO();
}
// switch to texture unit 0 if needed
if (state.texture.active != 0)
gles_glActiveTexture(GL_TEXTURE0);
@@ -463,10 +515,12 @@ void blitMainFBO() {
return;
// switch to texture unit 0 if needed
int old_tex = state.texture.active;
int old_client = state.texture.client;
if (state.texture.active != 0)
gles_glActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
if (state.texture.client != 0)
gles_glClientActiveTexture(GL_TEXTURE0);
glClientActiveTexture(GL_TEXTURE0);
// bind the FBO texture
gles_glEnable(GL_TEXTURE_2D);
gles_glBindTexture(GL_TEXTURE_2D, mainfbo_tex);
@@ -475,7 +529,7 @@ void blitMainFBO() {
gles_glGetIntegerv(GL_VIEWPORT, old_vp);
gles_glViewport(0, 0, mainfbo_width, mainfbo_height);
// Draw the texture
#if 1
#if 0
gles_glDrawTexi(0, 0, 0, mainfbo_width, mainfbo_height);
#else
{
@@ -485,33 +539,29 @@ void blitMainFBO() {
LOAD_GLES(glVertexPointer);
LOAD_GLES(glTexCoordPointer);
LOAD_GLES(glDrawArrays);
LOAD_GLES(glOrthof);
LOAD_GLES(glPushMatrix);
LOAD_GLES(glPopMatrix);
glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT);
GLfloat old_projection[16], old_modelview[16], old_texture[16];
glMatrixMode(GL_TEXTURE);
glGetFloatv(GL_TEXTURE_MATRIX, old_texture);
gles_glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glGetFloatv(GL_PROJECTION_MATRIX, old_projection);
gles_glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glGetFloatv(GL_MODELVIEW_MATRIX, old_modelview);
gles_glPushMatrix();
glLoadIdentity();
float w2 = 800 / 2.0f;
float h2 = 480 / 2.0f;
float x1=0;
float x2=mainfbo_width;
float y1=0;
float y2=mainfbo_height;
GLfloat vert[] = {
(x1-w2)/w2, (y1-h2)/h2, 0,
(x2-w2)/w2, (y1-h2)/h2, 0,
(x2-w2)/w2, (y2-h2)/h2, 0,
(x1-w2)/w2, (y2-h2)/h2, 0,
-1, -1,
+1, -1,
+1, +1,
-1, +1,
};
float sw = mainfbo_width / mainfbo_nwidth;
float sh = mainfbo_height / mainfbo_nheight;
float sw = (float)mainfbo_width / (float)mainfbo_nwidth;
float sh = (float)mainfbo_height / (float)mainfbo_nheight;
GLfloat tex[] = {
0, 0,
sw, 0,
@@ -519,35 +569,35 @@ void blitMainFBO() {
0, sh
};
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT | GL_CLIENT_PIXEL_STORE_BIT);
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
gles_glEnableClientState(GL_VERTEX_ARRAY);
gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
gles_glDisableClientState(GL_COLOR_ARRAY);
gles_glDisableClientState(GL_NORMAL_ARRAY);
gles_glVertexPointer(3, GL_FLOAT, 0, vert);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
gles_glVertexPointer(2, GL_FLOAT, 0, vert);
gles_glTexCoordPointer(2, GL_FLOAT, 0, tex);
//glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
gles_glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// All the previous states are Pushed / Poped anyway...
glPopClientAttrib();
glMatrixMode(GL_TEXTURE);
glLoadMatrixf(old_texture);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(old_modelview);
gles_glPopMatrix();
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(old_projection);
gles_glPopMatrix();
glMatrixMode(GL_TEXTURE);
gles_glPopMatrix();
glPopAttrib();
}
#endif
@@ -560,10 +610,10 @@ void blitMainFBO() {
gles_glBindTexture(GL_TEXTURE_2D, 0);
if (!state.enable.texture_2d[0])
gles_glDisable(GL_TEXTURE_2D);
if (state.texture.active != 0)
gles_glActiveTexture(GL_TEXTURE0 + state.texture.active);
if (state.texture.client != 0)
gles_glClientActiveTexture(GL_TEXTURE0 + state.texture.client);
if (old_tex != 0)
glActiveTexture(GL_TEXTURE0 + old_tex);
if (old_client != 0)
glClientActiveTexture(GL_TEXTURE0 + old_client);
}
void bindMainFBO() {

View File

@@ -71,21 +71,16 @@ void initialize_glshim() {
// config functions
const GLubyte *glGetString(GLenum name) {
LOAD_GLES(glGetString);
// LOAD_GLES(glGetString);
const GLubyte *str;
errorShim(GL_NO_ERROR);
if ((str=gles_glGetString(name))==NULL)
printf("**warning** glGetString(%i) called with bad init\n", name);
/* if ((str=gles_glGetString(name))==NULL)
printf("**warning** glGetString(%i) called with bad init\n", name);*/
switch (name) {
case GL_VERSION:
#ifdef USE_ES2
return (GLubyte *)"4.3 glshim wrapper";
#else
return (GLubyte *)"1.5 glshim wrapper";
#endif
case GL_EXTENSIONS:
return (const GLubyte *)(char *){
#ifndef USE_ES2
"GL_ARB_vertex_buffer_object "
"GL_ARB_vertex_buffer "
"GL_EXT_vertex_array "
@@ -124,24 +119,13 @@ const GLubyte *glGetString(GLenum name) {
// "GL_EXT_blend_logic_op "
// "GL_EXT_blend_color "
// "GL_ARB_texture_cube_map "
#else
"GL_ARB_vertex_shader "
"GL_ARB_fragment_shader "
"GL_ARB_vertex_buffer_object "
"GL_EXT_framebuffer_object "
"GL_EXT_vertex_array "
#endif
};
case GL_VENDOR:
return (GLubyte *)"OpenPandora";
case GL_RENDERER:
#ifdef USE_ES2
return (GLubyte *)"GLESv2 wrapper";
#else
return (GLubyte *)"GLES_CM wrapper";
case GL_SHADING_LANGUAGE_VERSION:
return (GLubyte *)"";
#endif
default:
errorShim(GL_INVALID_ENUM);
return (str)?str:(GLubyte*)"";
@@ -436,6 +420,7 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) {
state.enable.texture_2d[state.texture.active] = enable;
#endif
switch (cap) {
enable(GL_AUTO_NORMAL, auto_normal);
proxy_enable(GL_BLEND, blend);
proxy_enable(GL_TEXTURE_2D, texture_2d[state.texture.active]);
enable(GL_TEXTURE_GEN_S, texgen_s[state.texture.active]);
@@ -541,35 +526,34 @@ void glDisableClientState(GLenum cap) {
}
#endif
#define isenabled(what, where) \
case what: return state.enable.where
GLboolean glIsEnabled(GLenum cap) {
// should flush for now... to be optimized later!
if (state.gl_batch) flush();
LOAD_GLES(glIsEnabled);
noerrorShim();
switch (cap) {
case GL_LINE_STIPPLE:
return state.enable.line_stipple;
case GL_TEXTURE_GEN_S:
return state.enable.texgen_s[state.texture.active];
case GL_TEXTURE_GEN_T:
return state.enable.texgen_t[state.texture.active];
case GL_TEXTURE_GEN_R:
return state.enable.texgen_t[state.texture.active];
case GL_TEXTURE_COORD_ARRAY:
return state.enable.tex_coord_array[state.texture.client];
case GL_COLOR_SUM:
return state.enable.color_sum;
case GL_SECONDARY_COLOR_ARRAY:
return state.enable.secondary_array;
case GL_TEXTURE_1D:
return state.enable.texture_1d[state.texture.active];
case GL_TEXTURE_3D:
return state.enable.texture_1d[state.texture.active];
isenabled(GL_AUTO_NORMAL, auto_normal);
isenabled(GL_LINE_STIPPLE, line_stipple);
isenabled(GL_TEXTURE_GEN_S, texgen_s[state.texture.active]);
isenabled(GL_TEXTURE_GEN_T, texgen_t[state.texture.active]);
isenabled(GL_TEXTURE_GEN_R, texgen_r[state.texture.active]);
isenabled(GL_COLOR_SUM, color_sum);
isenabled(GL_SECONDARY_COLOR_ARRAY, secondary_array);
isenabled(GL_TEXTURE_1D, texture_1d[state.texture.active]);
isenabled(GL_TEXTURE_3D, texture_3d[state.texture.active]);
isenabled(GL_VERTEX_ARRAY, vertex_array);
isenabled(GL_NORMAL_ARRAY, normal_array);
isenabled(GL_COLOR_ARRAY, color_array);
isenabled(GL_TEXTURE_COORD_ARRAY, tex_coord_array[state.texture.client]);
default:
errorGL();
return gles_glIsEnabled(cap);
}
}
#undef isenabled
static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode,
GLsizei skip, GLsizei count) {
@@ -648,7 +632,7 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic
list->indices = sindices;
list->ilen = count;
list->indice_cap = count;
end_renderlist(list);
//end_renderlist(list);
state.list.active = extend_renderlist(list);
return;
@@ -1371,12 +1355,12 @@ void glEndList() {
state.list.compiling = false;
end_renderlist(state.list.active);
state.list.active = NULL;
if (gl_batch==1) {
init_batch();
}
if (state.list.mode == GL_COMPILE_AND_EXECUTE) {
glCallList(list);
}
if (gl_batch) {
init_batch();
}
}
}
@@ -1437,6 +1421,9 @@ void glCallLists(GLsizei n, GLenum type, const GLvoid *lists) {
}
void glDeleteList(GLuint list) {
if(state.gl_batch) {
flush();
}
renderlist_t *l = glGetList(list);
if (l) {
free_renderlist(l);

View File

@@ -201,6 +201,15 @@ static void load_egl_lib() {
break; \
}
#define GL_TYPE_CASE2(name, var, magic, type, code2, code) \
case magic: { \
code2 { \
type *name = (type *)var; \
code \
} \
break; \
}
#define GL_TYPE_CASE_MAX(name, var, magic, type, code, max) \
case magic: { \
type *name = (type *)var; \
@@ -222,6 +231,19 @@ static void load_egl_lib() {
extra \
}
#define GL_TYPE_SWITCH2(name, var, type, code2, code, extra) \
switch (type) { \
GL_TYPE_CASE2(name, var, GL_DOUBLE, GLdouble, code2, code) \
GL_TYPE_CASE2(name, var, GL_FLOAT, GLfloat, code2, code) \
GL_TYPE_CASE2(name, var, GL_INT, GLint, code2, code) \
GL_TYPE_CASE2(name, var, GL_SHORT, GLshort, code2, code) \
GL_TYPE_CASE2(name, var, GL_BYTE, GLbyte, code2, code) \
GL_TYPE_CASE2(name, var, GL_UNSIGNED_BYTE, GLubyte, code2, code) \
GL_TYPE_CASE2(name, var, GL_UNSIGNED_INT, GLuint, code2, code) \
GL_TYPE_CASE2(name, var, GL_UNSIGNED_SHORT, GLushort, code2, code) \
extra \
}
#define GL_TYPE_SWITCH_MAX(name, var, type, code, extra) \
switch (type) { \
GL_TYPE_CASE_MAX(name, var, GL_DOUBLE, GLdouble, code, 1.0d) \

View File

@@ -726,13 +726,7 @@ void draw_renderlist(renderlist_t *list) {
khash_t(texgen) *tgn = list->texgen;
rendertexgen_t *m;
kh_foreach_value(tgn, m,
switch (m->pname) {
case GL_TEXTURE_GEN_MODE:
glTexGeni(m->coord, m->pname, m->color[0]);
break;
default:
glTexGenfv(m->coord, m->pname, m->color);
}
glTexGenfv(m->coord, m->pname, m->color);
)
}
@@ -853,74 +847,76 @@ void draw_renderlist(renderlist_t *list) {
if (state.polygon_mode == GL_LINE && list->mode_init>=GL_TRIANGLES) {
int n, s;
int ilen = list->ilen;
GLushort ind_line[ilen*3+1];
GLushort ind_line[ilen*4+2];
int k=0;
switch (list->mode_init) {
case GL_TRIANGLES:
// 1 triangle -> 3 lines
for (int i = 0; i<ilen; i+=3) {
ind_line[k++] = indices[i+0]; ind_line[k++] = indices[i+1];
ind_line[k++] = indices[i+1]; ind_line[k++] = indices[i+2];
ind_line[k++] = indices[i+2]; ind_line[k++] = indices[i+0];
if(ilen>2) {
// 1 triangle -> 3 lines
for (int i = 0; i<ilen-2; i+=3) {
ind_line[k++] = indices[i+0]; ind_line[k++] = indices[i+1];
ind_line[k++] = indices[i+1]; ind_line[k++] = indices[i+2];
ind_line[k++] = indices[i+2]; ind_line[k++] = indices[i+0];
}
}
break;
case GL_TRIANGLE_STRIP:
// first 3 points a triangle, then a 2 lines per new point
if (ilen>2) {
ind_line[k++] = indices[0]; ind_line[k++] = indices[1];
}
for (int i = 2; i<ilen; i++) {
ind_line[k++] = indices[i-2]; ind_line[k++] = indices[i];
ind_line[k++] = indices[i-1]; ind_line[k++] = indices[i];
for (int i = 2; i<ilen; i++) {
ind_line[k++] = indices[i-2]; ind_line[k++] = indices[i];
ind_line[k++] = indices[i-1]; ind_line[k++] = indices[i];
}
}
break;
case GL_TRIANGLE_FAN:
// first 3 points a triangle, then a 2 lines per new point too
if (ilen>2) {
ind_line[k++] = indices[0]; ind_line[k++] = indices[1];
}
for (int i = 2; i<ilen; i++) {
ind_line[k++] = indices[0]; ind_line[k++] = indices[i];
ind_line[k++] = indices[i-1]; ind_line[k++] = indices[i];
for (int i = 2; i<ilen; i++) {
ind_line[k++] = indices[0]; ind_line[k++] = indices[i];
ind_line[k++] = indices[i-1]; ind_line[k++] = indices[i];
}
}
break;
case GL_QUADS:
// 4 lines per quads, but dest may already be a triangles list...
if (list->mode == GL_TRIANGLE_FAN) {
// just 1 Quad
for (int i=0; i<4; i++) {
ind_line[k++] = indices[i+0]; ind_line[k++] = indices[(i+1)%4];
}
} else {
// list of triangles, 2 per quads...
for (int i=0; i<ilen; i+=6) {
ind_line[k++] = indices[i+0]; ind_line[k++] = indices[i+1];
ind_line[k++] = indices[i+1]; ind_line[k++] = indices[i+2];
ind_line[k++] = indices[i+2]; ind_line[k++] = indices[i+5];
ind_line[k++] = indices[i+5]; ind_line[k++] = indices[i+0];
if (ilen>3) {
// 4 lines per quads, but dest may already be a triangles list...
if (list->mode == GL_TRIANGLE_FAN) {
// just 1 Quad
for (int i=0; i<4; i++) {
ind_line[k++] = indices[i+0]; ind_line[k++] = indices[(i+1)%4];
}
} else {
// list of triangles, 2 per quads...
for (int i=0; i<ilen-5; i+=6) {
ind_line[k++] = indices[i+0]; ind_line[k++] = indices[i+1];
ind_line[k++] = indices[i+1]; ind_line[k++] = indices[i+2];
ind_line[k++] = indices[i+2]; ind_line[k++] = indices[i+5];
ind_line[k++] = indices[i+5]; ind_line[k++] = indices[i+0];
}
}
}
break;
case GL_QUAD_STRIP:
// first 4 points is a quad, then 2 points per new quad
if (ilen>2) {
if (ilen>3) {
ind_line[k++] = indices[0]; ind_line[k++] = indices[1];
}
for (int i = 2; i<ilen; i+=2) {
ind_line[k++] = indices[i-1]; ind_line[k++] = indices[i];
ind_line[k++] = indices[i-2]; ind_line[k++] = indices[i+1];
ind_line[k++] = indices[i+0]; ind_line[k++] = indices[i+1];
for (int i = 2; i<ilen-1; i+=2) {
ind_line[k++] = indices[i-1]; ind_line[k++] = indices[i];
ind_line[k++] = indices[i-2]; ind_line[k++] = indices[i+1];
ind_line[k++] = indices[i+0]; ind_line[k++] = indices[i+1];
}
}
break;
case GL_POLYGON:
// if polygons have been merged, then info is lost...
if (ilen) {
ind_line[k++] = indices[0]; ind_line[k++] = indices[1];
}
for (int i = 1; i<ilen; i++) {
ind_line[k++] = indices[i-1]; ind_line[k++] = indices[i];
}
if (ilen) {
for (int i = 1; i<ilen; i++) {
ind_line[k++] = indices[i-1]; ind_line[k++] = indices[i];
}
ind_line[k++] = indices[ilen-1]; ind_line[k++] = indices[0];
}
break;
@@ -943,68 +939,78 @@ void draw_renderlist(renderlist_t *list) {
int len = list->len;
if ((state.polygon_mode == GL_LINE) && (list->mode_init>=GL_TRIANGLES)) {
int n, s;
GLushort ind_line[len*3+1];
GLushort ind_line[len*4+2];
int k=0;
switch (list->mode_init) {
case GL_TRIANGLES:
// 1 triangle -> 3 lines
for (int i = 0; i<len; i+=3) {
ind_line[k++] = i+0; ind_line[k++] = i+1;
ind_line[k++] = i+1; ind_line[k++] = i+2;
ind_line[k++] = i+2; ind_line[k++] = i+0;
if(len>2) {
for (int i = 0; i<len-2; i+=3) {
ind_line[k++] = i+0; ind_line[k++] = i+1;
ind_line[k++] = i+1; ind_line[k++] = i+2;
ind_line[k++] = i+2; ind_line[k++] = i+0;
}
}
break;
case GL_TRIANGLE_STRIP:
// first 3 points a triangle, then a 2 lines per new point
if (len>2) {
ind_line[k++] = 0; ind_line[k++] = 1;
}
for (int i = 2; i<len; i++) {
ind_line[k++] = i-2; ind_line[k++] = i;
ind_line[k++] = i-1; ind_line[k++] = i;
for (int i = 2; i<len; i++) {
ind_line[k++] = i-2; ind_line[k++] = i;
ind_line[k++] = i-1; ind_line[k++] = i;
}
}
break;
case GL_TRIANGLE_FAN:
// first 3 points a triangle, then a 2 lines per new point too
if (len>2) {
ind_line[k++] = 0; ind_line[k++] = 1;
}
for (int i = 2; i<len; i++) {
ind_line[k++] = 0; ind_line[k++] = i;
ind_line[k++] = i-1; ind_line[k++] = i;
for (int i = 2; i<len; i++) {
ind_line[k++] = 0; ind_line[k++] = i;
ind_line[k++] = i-1; ind_line[k++] = i;
}
}
break;
case GL_QUADS:
// 4 lines per quads, QUAD without indices means 1 single quad
if (list->mode == GL_TRIANGLE_FAN) {
// just 1 Quad
for (int i=0; i<4; i++) {
ind_line[k++] = i+0; ind_line[k++] = (i+1)%4;
if(len>3) {
// 4 lines per quads, QUAD without indices means 1 single quad
if (list->mode == GL_TRIANGLE_FAN) {
// just 1 Quad
for (int i=0; i<4; i++) {
ind_line[k++] = i+0; ind_line[k++] = (i+1)%4;
}
} else {
// list of triangles, 2 per quads...
for (int i=0; i<len-5; i+=6) {
ind_line[k++] = i+0; ind_line[k++] = i+1;
ind_line[k++] = i+1; ind_line[k++] = i+2;
ind_line[k++] = i+2; ind_line[k++] = i+5;
ind_line[k++] = i+5; ind_line[k++] = i+0;
}
}
} else {
// cannot go there!
}
break;
case GL_QUAD_STRIP:
// first 4 points is a quad, then 2 points per new quad
if (len>2) {
ind_line[k++] = 0; ind_line[k++] = 1;
}
for (int i = 2; i<len; i+=2) {
ind_line[k++] = i-1; ind_line[k++] = i;
ind_line[k++] = i-2; ind_line[k++] = i+1;
ind_line[k++] = i+0; ind_line[k++] = i+1;
if(len>3) {
// first 4 points is a quad, then 2 points per new quad
if (len>2) {
ind_line[k++] = 0; ind_line[k++] = 1;
}
for (int i = 2; i<len-1; i+=2) {
ind_line[k++] = i-1; ind_line[k++] = i;
ind_line[k++] = i-2; ind_line[k++] = i+1;
ind_line[k++] = i+0; ind_line[k++] = i+1;
}
}
break;
case GL_POLYGON:
// if polygons have been merged, then info is lost...
if (len) {
ind_line[k++] = 0; ind_line[k++] = 1;
}
for (int i = 1; i<len; i++) {
ind_line[k++] = i-1; ind_line[k++] = i;
}
if (len) {
for (int i = 1; i<len; i++) {
ind_line[k++] = i-1; ind_line[k++] = i;
}
ind_line[k++] = len-1; ind_line[k++] = 0;
}
break;
@@ -1212,10 +1218,7 @@ void rlTexGenfv(renderlist_t *list, GLenum coord, GLenum pname, const GLfloat *
m->coord = coord;
m->pname = pname;
m->color[0] = params[0];
m->color[1] = params[1];
m->color[2] = params[2];
m->color[3] = params[3];
memcpy(m->color, params, 4*sizeof(GLfloat));
}
void rlTexCoord2f(renderlist_t *list, GLfloat s, GLfloat t) {

View File

@@ -575,7 +575,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
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 * 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(dst_format, dst_type);
//printf("pixel conversion: %ix%i - %04x, %04x -> %04x, %04x, transform=%i\n", width, height, src_format, src_type, dst_format, dst_type, raster_need_transform());
@@ -592,7 +592,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+yy*src_width, src_width);
memcpy((*dst)+yy*(dst_width+src_width), src+yy*src_width, src_width);
else
memcpy(*dst, src, dst_size);
return true;
@@ -614,7 +614,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width - src_width;
dst_pos += dst_width;
}
return true;
}
@@ -628,7 +628,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width - src_width;
dst_pos += dst_width;
}
return true;
}
@@ -642,7 +642,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width - src_width;
dst_pos += dst_width;
}
return true;
}
@@ -659,7 +659,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst,
dst_pos += dst_stride;
}
if (stride)
dst_pos += dst_width - src_width;
dst_pos += dst_width;
}
return true;
}

View File

@@ -224,8 +224,9 @@ void glPushAttrib(GLbitfield mask) {
int a;
for (a=0; a<MAX_TEX; a++) {
cur->texgen_r[a] = state.enable.texgen_r[a];
cur->texgen_r[a] = state.enable.texgen_s[a];
cur->texgen_r[a] = state.enable.texgen_t[a];
cur->texgen_s[a] = state.enable.texgen_s[a];
cur->texgen_t[a] = state.enable.texgen_t[a];
cur->texgen[a] = state.texgen[a]; // all mode and planes per texture in 1 line
cur->texture[a] = (state.texture.bound[a])?state.texture.bound[a]->texture:0;
}
//glActiveTexture(GL_TEXTURE0+cur->active);
@@ -478,6 +479,7 @@ void glPopAttrib() {
state.enable.texgen_r[a] = cur->texgen_r[a];
state.enable.texgen_s[a] = cur->texgen_s[a];
state.enable.texgen_t[a] = cur->texgen_t[a];
state.texgen[a] = cur->texgen[a]; // all mode and planes per texture in 1 line
if ((cur->texture[a]==0 && state.texture.bound[a] != 0) || (cur->texture[a]!=0 && state.texture.bound[a]==0)) {
glActiveTexture(GL_TEXTURE0+a);
glBindTexture(GL_TEXTURE_2D, cur->texture[a]);

View File

@@ -118,6 +118,7 @@ typedef struct {
// GL_TEXTURE_BIT
GLint texture[MAX_TEX];
texgen_state_t texgen[MAX_TEX];
GLint active;
// GL_TRANSFORM_BIT
@@ -159,18 +160,6 @@ typedef struct {
GLboolean normal_enable;
GLboolean secondary_enable;
pointer_states_t pointers;
/*pointer_state_t verts;
pointer_state_t color;
pointer_state_t normal;
pointer_state_t tex[MAX_TEX];
pointer_state_t secondary;*/
// lets track old pointer address to avoid useless copy back
/*GLvoid *ref_verts,
*ref_colors,
*ref_secondary,
*ref_normal,
*ref_tex[MAX_TEX];
*/
unsigned int len;
unsigned int cap;
} glclientstack_t;

View File

@@ -9,6 +9,7 @@
typedef struct {
GLboolean line_stipple,
auto_normal,
blend,
color_sum,
secondary_array,
@@ -29,9 +30,12 @@ typedef struct {
GLenum S;
GLenum T;
GLenum R;
GLfloat Sv[4];
GLfloat Tv[4];
GLfloat Rv[4];
GLfloat S_E[4]; // Eye Plane
GLfloat T_E[4];
GLfloat R_E[4];
GLfloat S_O[4]; // Object Plane
GLfloat T_O[4];
GLfloat R_O[4];
} texgen_state_t;
typedef struct {

View File

@@ -3,25 +3,23 @@
//extern void* eglGetProcAddress(const char*);
void glTexGeni(GLenum coord, GLenum pname, GLint param) {
// coord is in: GL_S, GL_T, GL_R, GL_Q
// pname == GL_TEXTURE_GEN_MODE
/* param is in:
GL_OBJECT_LINEAR, GL_EYE_LINEAR,
GL_SPHERE_MAP, GL_NORMAL_MAP, or GL_REFLECTION_MAP
*/
/*
switch (coord) {
case GL_S: state.texgen[state.texture.active].S = param; break;
case GL_T: state.texgen[state.texture.active].T = param; break;
}
*/
GLfloat params[4] = {0,0,0,0};
params[0]=param;
glTexGenfv(coord, pname, params);
}
void glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) {
//printf("glTexGenfv(0x%04X, 0x%04X, [%.02f, ...]), texture=%i\n", coord, pname, param[0], state.texture.active);
/*
If pname is GL_TEXTURE_GEN_MODE, then the array must contain
a single symbolic constant, one of
GL_OBJECT_LINEAR, GL_EYE_LINEAR, GL_SPHERE_MAP, GL_NORMAL_MAP,
or GL_REFLECTION_MAP.
Otherwise, params holds the coefficients for the texture-coordinate
generation function specified by pname.
*/
//printf("glTexGenfv(0x%04X, 0x%04X, [%.02f, ...]), texture=%i\n", coord, pname, param[0], state.texture.active);
if ((state.list.compiling || state.gl_batch) && state.list.active) {
NewStage(state.list.active, STAGE_TEXGEN);
rlTexGenfv(state.list.active, coord, pname, param);
@@ -31,38 +29,49 @@ void glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) {
// pname is in: GL_TEXTURE_GEN_MODE, GL_OBJECT_PLANE, GL_EYE_PLANE
noerrorShim();
if (pname == GL_TEXTURE_GEN_MODE) {
switch (coord) {
case GL_S: state.texgen[state.texture.active].S = param[0]; break;
case GL_T: state.texgen[state.texture.active].T = param[0]; break;
case GL_R: state.texgen[state.texture.active].R = param[0]; break;
default:
errorShim(GL_INVALID_ENUM);
}
} else {
switch (coord) {
case GL_S:
memcpy(state.texgen[state.texture.active].Sv, param, 4 * sizeof(GLfloat));
break;
case GL_T:
memcpy(state.texgen[state.texture.active].Tv, param, 4 * sizeof(GLfloat));
break;
case GL_R:
memcpy(state.texgen[state.texture.active].Rv, param, 4 * sizeof(GLfloat));
break;
default:
errorShim(GL_INVALID_ENUM);
}
switch(pname) {
case GL_TEXTURE_GEN_MODE:
switch (coord) {
case GL_S: state.texgen[state.texture.active].S = param[0]; break;
case GL_T: state.texgen[state.texture.active].T = param[0]; break;
case GL_R: state.texgen[state.texture.active].R = param[0]; break;
default:
errorShim(GL_INVALID_ENUM);
return;
}
case GL_OBJECT_PLANE:
switch (coord) {
case GL_S:
memcpy(state.texgen[state.texture.active].S_O, param, 4 * sizeof(GLfloat));
break;
case GL_T:
memcpy(state.texgen[state.texture.active].T_O, param, 4 * sizeof(GLfloat));
break;
case GL_R:
memcpy(state.texgen[state.texture.active].R_O, param, 4 * sizeof(GLfloat));
break;
default:
errorShim(GL_INVALID_ENUM);
return;
}
case GL_EYE_PLANE:
switch (coord) {
case GL_S:
memcpy(state.texgen[state.texture.active].S_E, param, 4 * sizeof(GLfloat));
break;
case GL_T:
memcpy(state.texgen[state.texture.active].T_E, param, 4 * sizeof(GLfloat));
break;
case GL_R:
memcpy(state.texgen[state.texture.active].R_E, param, 4 * sizeof(GLfloat));
break;
default:
errorShim(GL_INVALID_ENUM);
return;
}
default:
errorShim(GL_INVALID_ENUM);
}
/*
If pname is GL_TEXTURE_GEN_MODE, then the array must contain
a single symbolic constant, one of
GL_OBJECT_LINEAR, GL_EYE_LINEAR, GL_SPHERE_MAP, GL_NORMAL_MAP,
or GL_REFLECTION_MAP.
Otherwise, params holds the coefficients for the texture-coordinate
generation function specified by pname.
*/
}
void glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) {
if (gl_batch) flush();
@@ -77,16 +86,29 @@ void glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) {
}
break;
case GL_OBJECT_PLANE:
case GL_EYE_PLANE: // probably wrong...
switch (coord) {
case GL_S:
memcpy(params, state.texgen[state.texture.active].Sv, 4 * sizeof(GLfloat));
memcpy(params, state.texgen[state.texture.active].S_O, 4 * sizeof(GLfloat));
break;
case GL_T:
memcpy(params, state.texgen[state.texture.active].Tv, 4 * sizeof(GLfloat));
memcpy(params, state.texgen[state.texture.active].T_O, 4 * sizeof(GLfloat));
break;
case GL_R:
memcpy(params, state.texgen[state.texture.active].Rv, 4 * sizeof(GLfloat));
memcpy(params, state.texgen[state.texture.active].R_O, 4 * sizeof(GLfloat));
break;
default:
errorShim(GL_INVALID_ENUM);
}
case GL_EYE_PLANE:
switch (coord) {
case GL_S:
memcpy(params, state.texgen[state.texture.active].S_E, 4 * sizeof(GLfloat));
break;
case GL_T:
memcpy(params, state.texgen[state.texture.active].T_E, 4 * sizeof(GLfloat));
break;
case GL_R:
memcpy(params, state.texgen[state.texture.active].R_E, 4 * sizeof(GLfloat));
break;
default:
errorShim(GL_INVALID_ENUM);
@@ -261,13 +283,13 @@ void eye_loop(const GLfloat *verts, const GLfloat *param, GLfloat *out, GLint co
}
static inline void tex_coord_loop(GLfloat *verts, GLfloat *norm, GLfloat *out, GLint count, GLenum type, GLfloat *params, GLushort *indices) {
static inline void tex_coord_loop(GLfloat *verts, GLfloat *norm, GLfloat *out, GLint count, GLenum type, GLfloat *param_o, GLfloat *param_e, GLushort *indices) {
switch (type) {
case GL_OBJECT_LINEAR:
dot_loop(verts, params, out, count, indices);
dot_loop(verts, param_o, out, count, indices);
break;
case GL_EYE_LINEAR:
eye_loop(verts, params, out, count, indices);
eye_loop(verts, param_e, out, count, indices);
break;
case GL_SPHERE_MAP:
//printf("LIBGL: GL_SPHERE_MAP with only 1 TexGen available"); //Broken here
@@ -352,30 +374,10 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count
return;
if ((*coords)==NULL)
*coords = (GLfloat *)malloc(count * 2 * sizeof(GLfloat));
/* LOAD_GLES(glPushMatrix);
LOAD_GLES(glGetIntegerv);
LOAD_GLES(glMatrixMode);
LOAD_GLES(glLoadIdentity);
LOAD_GLES(glActiveTexture);
GLuint old=state.texture.active;
GLuint matmode;
gles_glGetIntegerv(GL_MATRIX_MODE, &matmode);
if (matmode!=GL_TEXTURE)
gles_glMatrixMode(GL_TEXTURE);
if (old!=texture)
gles_glActiveTexture(GL_TEXTURE0+texture);
gles_glPushMatrix();
gles_glLoadIdentity();
if (matmode!=GL_TEXTURE)
gles_glMatrixMode(matmode);
if (old!=texture)
gles_glActiveTexture(GL_TEXTURE0+old);
*needclean=2;
*/
if (state.enable.texgen_s[texture])
tex_coord_loop(verts, norm, *coords, (indices)?ilen:count, state.texgen[texture].S, state.texgen[texture].Sv, indices);
tex_coord_loop(verts, norm, *coords, (indices)?ilen:count, state.texgen[texture].S, state.texgen[texture].S_O, state.texgen[texture].S_E, indices);
if (state.enable.texgen_t[texture])
tex_coord_loop(verts, norm, *coords+1, (indices)?ilen:count, state.texgen[texture].T, state.texgen[texture].Tv, indices);
tex_coord_loop(verts, norm, *coords+1, (indices)?ilen:count, state.texgen[texture].T, state.texgen[texture].T_O, state.texgen[texture].T_E, indices);
}
void gen_tex_clean(GLint cleancode, int texture) {
@@ -389,24 +391,6 @@ void gen_tex_clean(GLint cleancode, int texture) {
if (old_tex!=texture) glActiveTexture(GL_TEXTURE0 + old_tex);
return;
}
/* if (cleancode == 2) {
LOAD_GLES(glPopMatrix);
LOAD_GLES(glGetIntegerv);
LOAD_GLES(glMatrixMode);
LOAD_GLES(glActiveTexture);
GLuint old=state.texture.active;
GLuint matmode;
gles_glGetIntegerv(GL_MATRIX_MODE, &matmode);
if (matmode!=GL_TEXTURE)
gles_glMatrixMode(GL_TEXTURE);
if (old!=texture)
gles_glActiveTexture(GL_TEXTURE0+texture);
gles_glPopMatrix();
if (matmode!=GL_TEXTURE)
gles_glMatrixMode(matmode);
if (old!=texture)
gles_glActiveTexture(GL_TEXTURE0+old);
}*/
}
void glLoadTransposeMatrixf(const GLfloat *m) {

View File

@@ -1,6 +1,7 @@
#include "texture.h"
#include "raster.h"
#include "decompress.h"
#include "debug.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include "../glx/streaming.h"
@@ -99,6 +100,8 @@ void tex_setup_texcoord(GLuint texunit, GLuint len) {
if (old!=texunit) glClientActiveTexture(old+GL_TEXTURE0);
}
int nolumalpha = 0;
static void *swizzle_texture(GLsizei width, GLsizei height,
GLenum *format, GLenum *type,
const GLvoid *data) {
@@ -112,7 +115,10 @@ static void *swizzle_texture(GLsizei width, GLsizei height,
break;
case GL_ALPHA:
case GL_RGBA:
break;
case GL_LUMINANCE_ALPHA:
if(nolumalpha)
convert = true;
break;
case GL_RGB5:
dest_type = GL_UNSIGNED_SHORT_5_6_5;
@@ -197,7 +203,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat,
GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, const GLvoid *data) {
//printf("glTexImage2D on target=0x%04X with unpack_row_length(%i), size(%i,%i) and skip(%i,%i), format(internal)=%04x(%04x), type=%04x, data=%08x, level=%i (mipmap_need=%i, mipmap_auto=%i) => texture=%u (streamed=%i)\n", target, state.texture.unpack_row_length, width, height, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, format, internalformat, type, data, level, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->mipmap_need:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->mipmap_auto:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->texture:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->streamed:0);
//printf("glTexImage2D on target=%s with unpack_row_length(%i), size(%i,%i) and skip(%i,%i), format(internal)=%s(%s), type=%s, data=%08x, level=%i (mipmap_need=%i, mipmap_auto=%i) => texture=%u (streamed=%i)\n", PrintEnum(target), state.texture.unpack_row_length, width, height, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, PrintEnum(format), PrintEnum(internalformat), PrintEnum(type), data, level, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->mipmap_need:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->mipmap_auto:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->texture:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->streamed:0);
// proxy case
if (target == GL_PROXY_TEXTURE_2D) {
@@ -301,6 +307,11 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat,
printf("LIBGL: No glCopyTexImage2D / glCopyTexSubImage2D hack\n");
copytex = 1;
}
char *env_lumalpha = getenv("LIBGL_NOLUMALPHA");
if (env_lumalpha && strcmp(env_lumalpha, "1") == 0) {
nolumalpha = 1;
printf("LIBGL: GL_LUMINANCE_ALPHA hardware support disabled\n");
}
tested_env = true;
}
@@ -582,7 +593,7 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
LOAD_GLES(glTexSubImage2D);
LOAD_GLES(glTexParameteri);
noerrorShim();
//printf("glTexSubImage2D on target=0x%04X with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, format=%04x, type=%04x, level=%i, texture=%u\n", target, state.texture.unpack_row_length, width, height, xoffset, yoffset, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, format, type, level, state.texture.bound[state.texture.active]->texture);
//printf("glTexSubImage2D on target=%s with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, format=%s, type=%s, level=%i, texture=%u\n", PrintEnum(target), state.texture.unpack_row_length, width, height, xoffset, yoffset, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, PrintEnum(format), PrintEnum(type), level, state.texture.bound[state.texture.active]->texture);
if (width==0 || height==0) {
state.gl_batch = old_glbatch;
return;
@@ -696,7 +707,7 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE );
if ((target==GL_TEXTURE_2D) && texcopydata && bound && ((texstream && !bound->streamed) || !texstream)) {
//printf("*texcopy* glTexSubImage2D, xy=%i,%i, size=%i,%i, format=0x%04X, type=0x%04X, tex=%u\n", xoffset, yoffset, width, height, format, type, bound->glname);
//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))
@@ -835,7 +846,7 @@ void glBindTexture(GLenum target, GLuint texture) {
int tex_changed = 1;
int streamingID = -1;
gltexture_t *tex = NULL;
//printf("glBindTexture(0x%04X, %u), active=%i, client=%i\n", target, texture, state.texture.active, state.texture.client);
//printf("glBindTexture(0x%04X, %u), active=%i, client=%i\n", target, texture, state.texture.active, state.texture.client);
if (texture) {
int ret;
khint_t k;
@@ -1162,7 +1173,7 @@ void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoi
gltexture_t* bound = state.texture.bound[state.texture.active];
int width = bound->width;
int height = bound->height;
//printf("glGetTexImage(0x%04X, %i, 0x%04X, 0x%04X, 0x%p), texture=%u, size=%i,%i\n", target, level, format, type, img, bound->glname, width, height);
//printf("glGetTexImage(0x%04X, %i, 0x%04X, 0x%04X, 0x%p), texture=%u, size=%i,%i\n", target, level, format, type, img, bound->glname, width, height);
GLvoid *dst = img;
if (state.buffers.pack)
@@ -1176,7 +1187,8 @@ void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoi
}
#endif
if (texcopydata && bound->data) {
errorShim(GL_INVALID_ENUM);
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))
printf("LIBGL: Error on pixel_convert while glGetTexImage\n");
} else {
@@ -1275,7 +1287,7 @@ void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format
void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height) {
//printf("glCopyTexSubImage2D(%i, %i, %i, %i, %i, %i, %i, %i), bounded texture=%u format/type=0x%04X, 0x%04X\n", target, level, xoffset, yoffset, x, y, width, height, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->texture:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->format:0, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->type:0);
//printf("glCopyTexSubImage2D(%s, %i, %i, %i, %i, %i, %i, %i), bounded texture=%u format/type=%s, %s\n", PrintEnum(target), level, xoffset, yoffset, x, y, width, height, (state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->texture:0, PrintEnum((state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->format:0), PrintEnum((state.texture.bound[state.texture.active])?state.texture.bound[state.texture.active]->type:0));
// PUSH_IF_COMPILING(glCopyTexSubImage2D);
GLuint old_glbatch = state.gl_batch;
if (state.gl_batch) {
@@ -1334,7 +1346,7 @@ void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffse
void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y,
GLsizei width, GLsizei height, GLint border) {
//printf("glCopyTexImage2D(0x%04X, %i, 0x%04X, %i, %i, %i, %i, %i), current_fb=%u\n", target, level, internalformat, x, y, width, height, border, current_fb);
//printf("glCopyTexImage2D(0x%04X, %i, 0x%04X, %i, %i, %i, %i, %i), current_fb=%u\n", target, level, internalformat, x, y, width, height, border, current_fb);
//PUSH_IF_COMPILING(glCopyTexImage2D);
GLuint old_glbatch = state.gl_batch;
if (state.gl_batch) {
@@ -1558,7 +1570,7 @@ void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
state.gl_batch = old_glbatch;
return;
}
//printf("glCompressedTexSubImage2D with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, internalformat=%04x, imagesize=%i\n", state.texture.unpack_row_length, width, height, xoffset, yoffset, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, format, imageSize);
//printf("glCompressedTexSubImage2D with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, internalformat=%s, imagesize=%i\n", state.texture.unpack_row_length, width, height, xoffset, yoffset, state.texture.unpack_skip_pixels, state.texture.unpack_skip_rows, PrintEnum(format), imageSize);
glbuffer_t *unpack = state.buffers.unpack;
state.buffers.unpack = NULL;
GLvoid *datab = (GLvoid*)data;

View File

@@ -678,11 +678,12 @@ void glTexCoord4fv(GLfloat *t) {
// texgen
void glTexGend(GLenum coord, GLenum pname, GLdouble param) {
glTexGeni(coord, pname, param);
glTexGenf(coord, pname, param);
}
void glTexGenf(GLenum coord, GLenum pname, GLfloat param) {
// TODO: this is gross/lossy.
glTexGeni(coord, pname, param);
GLfloat params[4] = {0,0,0,0};
params[0] = param;
glTexGenfv(coord, pname, params);
}
void glTexGendv(GLenum coord, GLenum pname, const GLdouble *params) {
GLfloat tmp[4];

View File

@@ -156,6 +156,7 @@ static bool g_usefbo = false;
static bool g_xrefresh = false;
static bool g_stacktrace = false;
static bool g_bcm_active = false;
bool g_recyclefbo = false;
static int g_width=0, g_height=0;
#ifndef BCMHOST
static bool g_bcmhost = false;
@@ -303,6 +304,7 @@ static void scan_env() {
printf("LIBGL: LiveInfo detected, fps will be shown\n");
}
#endif
env(LIBGL_RECYCLEFBO, g_recyclefbo, "Recycling of FBO enabled");
char cwd[1024];
if (getcwd(cwd, sizeof(cwd))!= NULL)
printf("LIBGL: Current folder is:%s\n", cwd);