- xr_input.c/h: an OpenXR action set (aim pose, trigger/select click, a menu-toggle button) plus ray/quad hit-testing, and a visible laser-pointer line drawn from the controller toward the hit point. - xr_menu.c/h + MenuOverlay.java: a second composition-layer quad, toggled by a controller button, showing an off-screen, never-attached Android View tree (one "Keyboard" button so far) driven by synthetic touch events computed from the laser ray's hit UV. - Migrate gl4es from a prebuilt binary baked into the Docker build-image to a vendored source snapshot (android/gl4es-src/) compiled from source at APK build time via CMake add_subdirectory(), patched through a new android/gl4es-patches/ (mirrors the existing engine-patches/ pattern). This was needed to track down and fix a bug hit while building the menu: gl4es's fixed-pipeline emulation (fpe.c) was unconditionally substituting its own shader onto the menu's draw call (fpe_ReleventState() always sets alphafunc to a nonzero sentinel, so its fpe_IsEmpty() check could never see the state as empty), making the menu quad show the game's own rendering instead of its own content. Fixed by routing the menu's blit through a real glBlitFramebuffer() call instead of a shader-based draw, which gl4es's fpe.c has nothing to intercept - documented in README.md's new "Debugging notes" section. - Renumber android/engine-patches/ to close the gap left by removing an unrelated diagnostic-only patch, and strip investigation-journal comments and dead diagnostic code (temporary tracing, env-var probes) left over from finding the bug above. - Restructure README.md into numbered sections, document every engine/gl4es patch, add Android Studio dev/testing-cycle instructions, and generalize Quest-specific wording to any OpenXR headset. Update NOTICE.txt to match (gl4es is now vendored/patched source, not a prebuilt binary; add the OpenXR-SDK loader).
This commit is contained in:
@@ -0,0 +1,255 @@
|
||||
include_directories(util)
|
||||
|
||||
#file(GLOB_RECURSE GL_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/gl/*.c)
|
||||
SET(GL_SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/arbconverter.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/arbgenerator.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/arbhelper.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/arbparser.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/array.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/blit.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/blend.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/buffers.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/build_info.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/debug.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/decompress.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/depth.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/directstate.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/drawing.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/enable.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/envvars.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/eval.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/face.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/fog.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/fpe.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/fpe_cache.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/fpe_shader.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/framebuffers.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/gl_lookup.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/getter.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/gl4es.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/glstate.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/hint.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/init.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/light.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/line.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/list.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/listdraw.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/listrl.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/loader.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/logs.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/matrix.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/matvec.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/oldprogram.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/pixel.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/planes.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/pointsprite.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/preproc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/program.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/queries.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/raster.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/render.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/samplers.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/shader.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/shaderconv.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/shader_hacks.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/stack.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/stencil.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/string_utils.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/stubs.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/texenv.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/texgen.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/texture.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/texture_compressed.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/texture_params.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/texture_read.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/texture_3d.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/uniform.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/vertexattrib.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/wrap/gl4eswraps.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/wrap/gles.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/wrap/glstub.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/math/matheval.c
|
||||
)
|
||||
|
||||
SET(GL_H
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../version.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/arbconverter.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/arbgenerator.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/arbhelper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/arbparser.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/array.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/blend.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/blit.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/buffers.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/build_info.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/const.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/debug.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/decompress.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/depth.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/directstate.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/envvars.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/eval.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/face.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/fog.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/fpe.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/fpe_shader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/framebuffers.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/gl_lookup.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/gles.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/gl4es.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/glstate.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/hint.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/init.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/light.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/line.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/list.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/loader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/logs.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/matrix.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/matvec.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/oldprogram.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/pixel.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/planes.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/pointsprite.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/preproc.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/program.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/queries.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/raster.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/render.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/samplers.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/shader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/shaderconv.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/shader_hacks.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/stack.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/state.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/stencil.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/stb_dxt_104.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/string_utils.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/texenv.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/texgen.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/uniform.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/texture.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/vertexattrib.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/math/eval.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/wrap/gl4es.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/wrap/gles.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gl/wrap/stub.h
|
||||
)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND NOT NO_LOADER)
|
||||
include_directories(glx)
|
||||
# aux_source_directory(glx GLX_SOURCES)
|
||||
# list(APPEND GL_SOURCES ${GLX_SOURCES})
|
||||
list(APPEND GL_SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/hardext.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/gbm.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/glx.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/glx_stubs.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/lookup.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/rpi.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/streaming.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/utils.c
|
||||
)
|
||||
list(APPEND GL_H
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/glx_gbm.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/gbmfunc.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/drmfunc.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/glx.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/hardext.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/rpi.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/streaming.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/utils.h
|
||||
)
|
||||
else()
|
||||
include_directories(glx)
|
||||
list(APPEND GL_SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/hardext.c
|
||||
)
|
||||
message(STATUS "Not on Linux: building without GLX support.")
|
||||
endif()
|
||||
|
||||
if(AMIGAOS4)
|
||||
include_directories(agl)
|
||||
list(APPEND GL_SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/gbm.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/glx.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/agl/lookup.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/agl/amigaos.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/agl/agl.c
|
||||
)
|
||||
list(APPEND GL_H
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/hardext.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/glx/glx.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/agl/amigaos.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/agl/agl.h
|
||||
)
|
||||
endif()
|
||||
|
||||
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/gl/build_info.c PROPERTIES OBJECT_DEPENDS "${GL_SRC};${GL_H}")
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
if(STATICLIB)
|
||||
add_library(OPENGL32 STATIC ${GL_SRC})
|
||||
else()
|
||||
add_library(OPENGL32 SHARED ${GL_SRC})
|
||||
# some ES simulators used opengl32.dll :(
|
||||
set_target_properties(OPENGL32 PROPERTIES OUTPUT_NAME "GL32")
|
||||
set_target_properties(OPENGL32 PROPERTIES IMPORT_PREFIX "OPEN")
|
||||
endif()
|
||||
elseif(STATICLIB)
|
||||
add_library(GL STATIC ${GL_SRC})
|
||||
else()
|
||||
add_library(GL SHARED ${GL_SRC})
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
if(NOX11)
|
||||
if(AMIGAOS4)
|
||||
target_link_libraries(GL m)
|
||||
else()
|
||||
target_link_libraries(GL m dl)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(GL X11 m dl)
|
||||
endif()
|
||||
endif()
|
||||
if(USE_CLOCK)
|
||||
target_link_libraries(GL rt)
|
||||
endif()
|
||||
if(USE_ANDROID_LOG)
|
||||
target_link_libraries(GL ${log-lib})
|
||||
endif()
|
||||
|
||||
if(CMAKE_SHARED_LIBRARY_SUFFIX MATCHES ".so")
|
||||
set_target_properties(GL PROPERTIES SUFFIX ".so.1")
|
||||
endif()
|
||||
install(TARGETS GL
|
||||
LIBRARY
|
||||
DESTINATION "/usr/lib/gl4es/"
|
||||
)
|
||||
install(FILES "../include/gl4esinit.h" "../include/gl4eshint.h"
|
||||
DESTINATION "/usr/include/gl4es/"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
SET(EGL_SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/egl/egl.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/egl/lookup.c
|
||||
)
|
||||
|
||||
SET(EGL_H
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/egl/egl.h
|
||||
)
|
||||
|
||||
if(EGL_WRAPPER)
|
||||
add_library(EGL SHARED ${EGL_SRC})
|
||||
target_link_libraries(EGL GL dl)
|
||||
if(USE_ANDROID_LOG)
|
||||
target_link_libraries(EGL ${log-lib})
|
||||
endif()
|
||||
if(CMAKE_SHARED_LIBRARY_SUFFIX MATCHES ".so")
|
||||
set_target_properties(EGL PROPERTIES SUFFIX ".so.1")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
#include "agl.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
//#include <stdarg.h>
|
||||
#undef __USE_INLINE__
|
||||
#include <proto/exec.h>
|
||||
#include <interfaces/ogles2.h>
|
||||
|
||||
extern struct OGLES2IFace *IOGLES2;
|
||||
|
||||
void* NewGLState(void* shared_glstate, int es2only);
|
||||
void DeleteGLState(void* oldstate);
|
||||
void ActivateGLState(void* new_glstate);
|
||||
void GetHardwareExtensions(int notest);
|
||||
|
||||
typedef struct _agl_ctx_glstate {
|
||||
void* context;
|
||||
void* glstate;
|
||||
} agl_ctx_glstate;
|
||||
|
||||
static agl_ctx_glstate *agl_context = NULL;
|
||||
static int agl_context_len = 0;
|
||||
static int agl_context_cap = 0;
|
||||
static void* agl_current_ctx = NULL;
|
||||
|
||||
// find (or add if not found) a context in the list, and activate glstate...
|
||||
void agl_context_find(void* ctx) {
|
||||
if(!ctx)
|
||||
return;
|
||||
if(!agl_context) {
|
||||
agl_context_cap = 10;
|
||||
agl_context = (agl_ctx_glstate*)malloc(sizeof(agl_ctx_glstate)*agl_context_cap);
|
||||
memset(agl_context, 0, sizeof(agl_ctx_glstate)*agl_context_cap);
|
||||
}
|
||||
int idx = 0;
|
||||
while (idx<agl_context_len && agl_context[idx].context!=ctx) idx++;
|
||||
if(idx==agl_context_len) {
|
||||
agl_context = (agl_ctx_glstate*)realloc(agl_context, sizeof(agl_ctx_glstate)*(agl_context_cap+10));
|
||||
memset(agl_context+agl_context_cap, 0, sizeof(agl_ctx_glstate)*10);
|
||||
agl_context_cap+=10;
|
||||
}
|
||||
agl_context[idx].context = ctx;
|
||||
if(idx==agl_context_len) ++agl_context_len;
|
||||
|
||||
// create glstate if needed
|
||||
if(!agl_context[idx].glstate) {
|
||||
agl_context[idx].glstate = NewGLState(NULL, 0);
|
||||
// Hardware testing
|
||||
GetHardwareExtensions(0);
|
||||
}
|
||||
ActivateGLState(agl_context[idx].glstate);
|
||||
}
|
||||
|
||||
// remove a context (delete array if size is null)
|
||||
void agl_context_remove(void* ctx) {
|
||||
if (!ctx)
|
||||
return;
|
||||
if(!agl_context)
|
||||
return; // empty list?
|
||||
int idx = 0;
|
||||
while (idx<agl_context_len && agl_context[idx].context!=ctx) idx++;
|
||||
if(idx==agl_context_len)
|
||||
return; // not found...
|
||||
if(agl_context[idx].glstate) {
|
||||
DeleteGLState(agl_context[idx].glstate);
|
||||
agl_context[idx].glstate = NULL;
|
||||
}
|
||||
agl_context[idx].context = 0;
|
||||
// shrink if possible
|
||||
while(agl_context_len && !agl_context[agl_context_len-1].context) --agl_context_len;
|
||||
if(!agl_context_len) {
|
||||
agl_context_cap = 0;
|
||||
free(agl_context);
|
||||
agl_context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// AGL functions
|
||||
|
||||
void* aglCreateContext(ULONG * errcode, struct TagItem * tags) {
|
||||
if(IOGLES2)
|
||||
return IOGLES2->aglCreateContext2(errcode, tags);
|
||||
return NULL;
|
||||
}
|
||||
void* aglCreateContext2(ULONG * errcode, struct TagItem * tags) {
|
||||
return aglCreateContext(errcode, tags);
|
||||
}
|
||||
/*
|
||||
void* VARARGS68K aglCreateContextTags(ULONG * errcode, ...) {
|
||||
void* ret = NULL;
|
||||
if(IOGLES2) {
|
||||
struct TagItem tags[100];
|
||||
VA_LIST args;
|
||||
VA_START(args, errcode);
|
||||
int i = 0;
|
||||
do {
|
||||
struct Tagitem tag = VA_ARG(args, struct TagItem);
|
||||
tags[i++] = tag;
|
||||
} while (tag!=TAG_DONE);
|
||||
VA_END(args);
|
||||
ret = IOGLES2->aglCreateContext2(errcode, tags);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
void aglDestroyContext(void* context) {
|
||||
if(IOGLES2) {
|
||||
//bind the context before deleting stuffs.
|
||||
if(context!=agl_current_ctx)
|
||||
IOGLES2->aglMakeCurrent(context);
|
||||
|
||||
agl_context_remove(context); // remove the associated glstate
|
||||
|
||||
if(context!=agl_current_ctx) // rebind old context if needed
|
||||
IOGLES2->aglMakeCurrent(agl_current_ctx);
|
||||
IOGLES2->aglDestroyContext(context);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void aglMakeCurrent(void* context) {
|
||||
agl_current_ctx = context;
|
||||
if(IOGLES2) {
|
||||
IOGLES2->aglMakeCurrent(context);
|
||||
|
||||
if (context)
|
||||
agl_context_find(context); // activate (and create if needed) the correct glstate
|
||||
}
|
||||
}
|
||||
|
||||
void aglSetParams2(struct TagItem * tags) {
|
||||
if(IOGLES2) {
|
||||
return IOGLES2->aglSetParams2(tags);
|
||||
}
|
||||
}
|
||||
|
||||
void amiga_pre_swap();
|
||||
void amiga_post_swap();
|
||||
void aglSwapBuffers() {
|
||||
amiga_pre_swap();
|
||||
// Swap the Buffers!
|
||||
if(IOGLES2) {
|
||||
IOGLES2->aglSwapBuffers();
|
||||
}
|
||||
amiga_post_swap();
|
||||
}
|
||||
|
||||
// what is the use of this function?
|
||||
void aglSetBitmap(struct BitMap *bitmap) {
|
||||
if(IOGLES2) {
|
||||
IOGLES2->aglSetBitmap(bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
//void* aglGetProcAddress(const char* name); //-> declared in agl/lookup.c
|
||||
|
||||
#ifdef GL4ES_COMPILE_FOR_USE_IN_SHARED_LIB
|
||||
void agl_reset_internals() {
|
||||
if(agl_context) {
|
||||
free(agl_context);
|
||||
agl_context=NULL;
|
||||
}
|
||||
agl_context_len=0;
|
||||
agl_context_cap=0;
|
||||
agl_current_ctx=NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef _AGL_H_
|
||||
#define _AGL_H_
|
||||
|
||||
#ifndef EXEC_TYPES_H
|
||||
#include <exec/types.h>
|
||||
#endif
|
||||
#ifndef EXEC_EXEC_H
|
||||
#include <exec/exec.h>
|
||||
#endif
|
||||
#ifndef EXEC_INTERFACES_H
|
||||
#include <exec/interfaces.h>
|
||||
#endif
|
||||
|
||||
#ifndef GRAPHICS_GFX_H
|
||||
#include <graphics/gfx.h>
|
||||
#endif
|
||||
|
||||
#ifndef OGLES2_OGLES2_DEFS_H
|
||||
// it would be better to have an include with only the CreateContextTags enum difed, to avoid conflict
|
||||
// of other typedef with full OpenGL header file...
|
||||
//#include <ogles2/ogles2_defs.h>
|
||||
#endif
|
||||
|
||||
void* aglCreateContext(ULONG * errcode, struct TagItem * tags);
|
||||
void* aglCreateContext2(ULONG * errcode, struct TagItem * tags);
|
||||
//void* aglCreateContextTags(ULONG * errcode, ...);
|
||||
void aglDestroyContext(void* context);
|
||||
void aglMakeCurrent(void* context);
|
||||
void aglSwapBuffers();
|
||||
void aglSetParams2(struct TagItem * tags);
|
||||
void aglSetBitmap(struct BitMap *bitmap);
|
||||
void* aglGetProcAddress(const char* name);
|
||||
|
||||
#endif //_AGL_H_
|
||||
@@ -0,0 +1,814 @@
|
||||
#include "amigaos.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <proto/exec.h>
|
||||
// make sure we don't use inline version here
|
||||
#undef __USE_INLINE__
|
||||
#include <proto/ogles2.h>
|
||||
#include <proto/Warp3DNova.h>
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "../gl/logs.h"
|
||||
|
||||
#define MIN_W3DNOVA_LIB_VERSION 1
|
||||
#define MIN_W3DNOVA_LIB_REVISION 62
|
||||
#define MIN_OGLES2_LIB_VERSION 1
|
||||
#define MIN_OGLES2_LIB_REVISION 22
|
||||
|
||||
struct Library *LOGLES2 = NULL;
|
||||
struct OGLES2IFace *IOGLES2 = NULL;
|
||||
|
||||
struct so_bases
|
||||
{
|
||||
struct ExecIFace *IExec;
|
||||
};
|
||||
|
||||
struct so_bases so_exec;
|
||||
|
||||
// Open OGLES2 library and interface
|
||||
void os4OpenLib(void** lib)
|
||||
{
|
||||
so_exec.IExec = (struct ExecIFace *)(*(struct ExecBase **)4)->MainInterface;
|
||||
if(!IOGLES2) {
|
||||
// first check version for Warp3DNova lib
|
||||
struct Library *Warp3DNovaBase = NULL;
|
||||
Warp3DNovaBase = so_exec.IExec->OpenLibrary("Warp3DNova.library", MIN_W3DNOVA_LIB_VERSION);
|
||||
if(!Warp3DNovaBase) {
|
||||
SHUT_LOGE("Error, cannot open Warp3DNova.library!\n");
|
||||
return;
|
||||
}
|
||||
SHUT_LOGD("Using Warp3DNova.library v%d revision %d\n", Warp3DNovaBase->lib_Version, Warp3DNovaBase->lib_Revision);
|
||||
if (!(Warp3DNovaBase->lib_Version > MIN_W3DNOVA_LIB_VERSION || (Warp3DNovaBase->lib_Version == MIN_W3DNOVA_LIB_VERSION && Warp3DNovaBase->lib_Revision >= MIN_W3DNOVA_LIB_REVISION))) {
|
||||
SHUT_LOGE("Warning, your Warp3DNovaBase.library is too old, minimum is v%d.%d, please update!\n", MIN_W3DNOVA_LIB_VERSION,MIN_W3DNOVA_LIB_REVISION);
|
||||
}
|
||||
//close warp3dnova.library, we open it just for version check
|
||||
so_exec.IExec->CloseLibrary(Warp3DNovaBase);
|
||||
Warp3DNovaBase = NULL;
|
||||
|
||||
LOGLES2 = so_exec.IExec->OpenLibrary("ogles2.library", MIN_OGLES2_LIB_VERSION);
|
||||
if(!LOGLES2) {
|
||||
SHUT_LOGE("Error, cannot open ogles2 Library!\n");
|
||||
return;
|
||||
}
|
||||
SHUT_LOGD("Using OGLES2.library v%d revision %d\n", LOGLES2->lib_Version, LOGLES2->lib_Revision);
|
||||
if (!(LOGLES2->lib_Version > MIN_OGLES2_LIB_VERSION || (LOGLES2->lib_Version == MIN_OGLES2_LIB_VERSION && LOGLES2->lib_Revision >= MIN_OGLES2_LIB_REVISION))) {
|
||||
SHUT_LOGE("Warning, your OGLES2.library is too old, minimum is v%d.%d, please update!\n", MIN_OGLES2_LIB_VERSION,MIN_OGLES2_LIB_REVISION);
|
||||
}
|
||||
IOGLES2 = (struct OGLES2IFace *)so_exec.IExec->GetInterface(LOGLES2, "main", 1, NULL);
|
||||
if(!IOGLES2) {
|
||||
SHUT_LOGE("Error, cannot open ogles2 Interface!\n");
|
||||
so_exec.IExec->CloseLibrary(LOGLES2);
|
||||
LOGLES2 = NULL;
|
||||
return;
|
||||
}
|
||||
if (LOGLES2->lib_Version > 2 || (LOGLES2->lib_Version == 2 && LOGLES2->lib_Revision >= 9)) {
|
||||
hardext.prgbin_n = 1;
|
||||
}
|
||||
}
|
||||
*lib = LOGLES2;
|
||||
// small debug message, always helpfull at beggining
|
||||
SHUT_LOGD("OGLES2 Library and Interface open successfuly\n");
|
||||
}
|
||||
|
||||
// Close OGLES2 lib and interface
|
||||
void os4CloseLib()
|
||||
{
|
||||
if(IOGLES2) {
|
||||
so_exec.IExec->DropInterface((struct Interface*)IOGLES2);
|
||||
IOGLES2 = NULL;
|
||||
}
|
||||
if(LOGLES2) {
|
||||
so_exec.IExec->CloseLibrary(LOGLES2);
|
||||
LOGLES2 = NULL;
|
||||
}
|
||||
SHUT_LOGD("OGLES2 Library and Interface closed\n");
|
||||
}
|
||||
|
||||
|
||||
static void AmiglActiveTexture (GLenum texture) {
|
||||
return IOGLES2->glActiveTexture(texture);
|
||||
}
|
||||
|
||||
static void AmiglAttachShader (GLuint program, GLuint shader) {
|
||||
return IOGLES2->glAttachShader(program, shader);
|
||||
}
|
||||
|
||||
static void AmiglBindAttribLocation (GLuint program, GLuint index, const GLchar *name) {
|
||||
return IOGLES2->glBindAttribLocation(program, index, name);
|
||||
}
|
||||
|
||||
static void AmiglBindBuffer (GLenum target, GLuint buffer) {
|
||||
return IOGLES2->glBindBuffer(target, buffer);
|
||||
}
|
||||
|
||||
static void AmiglBindFramebuffer (GLenum target, GLuint framebuffer) {
|
||||
return IOGLES2->glBindFramebuffer(target, framebuffer);
|
||||
}
|
||||
|
||||
static void AmiglBindRenderbuffer (GLenum target, GLuint renderbuffer) {
|
||||
return IOGLES2->glBindRenderbuffer(target, renderbuffer);
|
||||
}
|
||||
|
||||
static void AmiglBindTexture (GLenum target, GLuint texture) {
|
||||
return IOGLES2->glBindTexture(target, texture);
|
||||
}
|
||||
|
||||
static void AmiglBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
|
||||
return IOGLES2->glBlendColor(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
static void AmiglBlendEquation (GLenum mode) {
|
||||
return IOGLES2->glBlendEquation(mode);
|
||||
}
|
||||
|
||||
static void AmiglBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha) {
|
||||
return IOGLES2->glBlendEquationSeparate(modeRGB, modeAlpha);
|
||||
}
|
||||
|
||||
static void AmiglBlendFunc (GLenum sfactor, GLenum dfactor) {
|
||||
return IOGLES2->glBlendFunc(sfactor, dfactor);
|
||||
}
|
||||
|
||||
static void AmiglBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
|
||||
return IOGLES2->glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
|
||||
}
|
||||
|
||||
static void AmiglBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage) {
|
||||
return IOGLES2->glBufferData(target, size, data, usage);
|
||||
}
|
||||
|
||||
static void AmiglBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data) {
|
||||
return IOGLES2->glBufferSubData(target, offset, size, data);
|
||||
}
|
||||
|
||||
static GLenum AmiglCheckFramebufferStatus (GLenum target) {
|
||||
return IOGLES2->glCheckFramebufferStatus(target);
|
||||
}
|
||||
|
||||
static void AmiglClear (GLbitfield mask) {
|
||||
return IOGLES2->glClear(mask);
|
||||
}
|
||||
|
||||
static void AmiglClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
|
||||
return IOGLES2->glClearColor(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
static void AmiglClearDepthf (GLfloat d) {
|
||||
return IOGLES2->glClearDepthf(d);
|
||||
}
|
||||
|
||||
static void AmiglClearStencil (GLint s) {
|
||||
return IOGLES2->glClearStencil(s);
|
||||
}
|
||||
|
||||
static void AmiglColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
|
||||
return IOGLES2->glColorMask(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
static void AmiglCompileShader (GLuint shader) {
|
||||
return IOGLES2->glCompileShader(shader);
|
||||
}
|
||||
|
||||
static void AmiglCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) {
|
||||
return IOGLES2->glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
|
||||
}
|
||||
|
||||
static void AmiglCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) {
|
||||
return IOGLES2->glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
|
||||
}
|
||||
|
||||
static void AmiglCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
|
||||
return IOGLES2->glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
|
||||
}
|
||||
|
||||
static void AmiglCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
return IOGLES2->glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
|
||||
}
|
||||
|
||||
static GLuint AmiglCreateProgram (void) {
|
||||
return IOGLES2->glCreateProgram();
|
||||
}
|
||||
|
||||
static GLuint AmiglCreateShader (GLenum type) {
|
||||
return IOGLES2->glCreateShader(type);
|
||||
}
|
||||
|
||||
static void AmiglCullFace (GLenum mode) {
|
||||
return IOGLES2->glCullFace(mode);
|
||||
}
|
||||
|
||||
static void AmiglDeleteBuffers (GLsizei n, const GLuint *buffers) {
|
||||
return IOGLES2->glDeleteBuffers(n, buffers);
|
||||
}
|
||||
|
||||
static void AmiglDeleteFramebuffers (GLsizei n, const GLuint *framebuffers) {
|
||||
return IOGLES2->glDeleteFramebuffers(n, framebuffers);
|
||||
}
|
||||
|
||||
static void AmiglDeleteProgram (GLuint program) {
|
||||
return IOGLES2->glDeleteProgram(program);
|
||||
}
|
||||
|
||||
static void AmiglDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers) {
|
||||
return IOGLES2->glDeleteRenderbuffers(n, renderbuffers);
|
||||
}
|
||||
|
||||
static void AmiglDeleteShader (GLuint shader) {
|
||||
return IOGLES2->glDeleteShader(shader);
|
||||
}
|
||||
|
||||
static void AmiglDeleteTextures (GLsizei n, const GLuint *textures) {
|
||||
return IOGLES2->glDeleteTextures(n, textures);
|
||||
}
|
||||
|
||||
static void AmiglDepthFunc (GLenum func) {
|
||||
return IOGLES2->glDepthFunc(func);
|
||||
}
|
||||
|
||||
static void AmiglDepthMask (GLboolean flag) {
|
||||
return IOGLES2->glDepthMask(flag);
|
||||
}
|
||||
|
||||
static void AmiglDepthRangef (GLfloat n, GLfloat f) {
|
||||
return IOGLES2->glDepthRangef(n, f);
|
||||
}
|
||||
|
||||
static void AmiglDetachShader (GLuint program, GLuint shader) {
|
||||
return IOGLES2->glDetachShader(program, shader);
|
||||
}
|
||||
|
||||
static void AmiglDisable (GLenum cap) {
|
||||
return IOGLES2->glDisable(cap);
|
||||
}
|
||||
|
||||
static void AmiglDisableVertexAttribArray (GLuint index) {
|
||||
return IOGLES2->glDisableVertexAttribArray(index);
|
||||
}
|
||||
|
||||
static void AmiglDrawArrays (GLenum mode, GLint first, GLsizei count) {
|
||||
return IOGLES2->glDrawArrays(mode, first, count);
|
||||
}
|
||||
|
||||
static void AmiglDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices) {
|
||||
return IOGLES2->glDrawElements(mode, count, type, indices);
|
||||
}
|
||||
|
||||
static void AmiglEnable (GLenum cap) {
|
||||
return IOGLES2->glEnable(cap);
|
||||
}
|
||||
|
||||
static void AmiglEnableVertexAttribArray (GLuint index) {
|
||||
return IOGLES2->glEnableVertexAttribArray(index);
|
||||
}
|
||||
|
||||
static void AmiglFinish (void) {
|
||||
return IOGLES2->glFinish();
|
||||
}
|
||||
|
||||
static void AmiglFlush (void) {
|
||||
return IOGLES2->glFlush();
|
||||
}
|
||||
|
||||
static void AmiglFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
|
||||
return IOGLES2->glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
|
||||
}
|
||||
|
||||
static void AmiglFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
|
||||
return IOGLES2->glFramebufferTexture2D(target, attachment, textarget, texture, level);
|
||||
}
|
||||
|
||||
static void AmiglFrontFace (GLenum mode) {
|
||||
return IOGLES2->glFrontFace(mode);
|
||||
}
|
||||
|
||||
static void AmiglGenBuffers (GLsizei n, GLuint *buffers) {
|
||||
return IOGLES2->glGenBuffers(n, buffers);
|
||||
}
|
||||
|
||||
static void AmiglGenerateMipmap (GLenum target) {
|
||||
return IOGLES2->glGenerateMipmap(target);
|
||||
}
|
||||
|
||||
static void AmiglGenFramebuffers (GLsizei n, GLuint *framebuffers) {
|
||||
return IOGLES2->glGenFramebuffers(n, framebuffers);
|
||||
}
|
||||
|
||||
static void AmiglGenRenderbuffers (GLsizei n, GLuint *renderbuffers) {
|
||||
return IOGLES2->glGenRenderbuffers(n, renderbuffers);
|
||||
}
|
||||
|
||||
static void AmiglGenTextures (GLsizei n, GLuint *textures) {
|
||||
return IOGLES2->glGenTextures(n, textures);
|
||||
}
|
||||
|
||||
static void AmiglGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {
|
||||
return IOGLES2->glGetActiveAttrib(program, index, bufSize, length, size, type, name);
|
||||
}
|
||||
|
||||
static void AmiglGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {
|
||||
return IOGLES2->glGetActiveUniform(program, index, bufSize, length, size, type, name);
|
||||
}
|
||||
|
||||
static void AmiglGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders) {
|
||||
return IOGLES2->glGetAttachedShaders(program, maxCount, count, shaders);
|
||||
}
|
||||
|
||||
static GLint AmiglGetAttribLocation (GLuint program, const GLchar *name) {
|
||||
return IOGLES2->glGetAttribLocation(program, name);
|
||||
}
|
||||
|
||||
static void AmiglGetBooleanv (GLenum pname, GLboolean *data) {
|
||||
return IOGLES2->glGetBooleanv(pname, data);
|
||||
}
|
||||
|
||||
static void AmiglGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) {
|
||||
return IOGLES2->glGetBufferParameteriv(target, pname, params);
|
||||
}
|
||||
|
||||
static GLenum AmiglGetError (void) {
|
||||
return IOGLES2->glGetError();
|
||||
}
|
||||
|
||||
static void AmiglGetFloatv (GLenum pname, GLfloat *data) {
|
||||
return IOGLES2->glGetFloatv(pname, data);
|
||||
}
|
||||
|
||||
static void AmiglGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params) {
|
||||
return IOGLES2->glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
|
||||
}
|
||||
|
||||
static void AmiglGetIntegerv (GLenum pname, GLint *data) {
|
||||
return IOGLES2->glGetIntegerv(pname, data);
|
||||
}
|
||||
|
||||
static void AmiglGetProgramiv (GLuint program, GLenum pname, GLint *params) {
|
||||
return IOGLES2->glGetProgramiv(program, pname, params);
|
||||
}
|
||||
|
||||
static void AmiglGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) {
|
||||
return IOGLES2->glGetProgramInfoLog(program, bufSize, length, infoLog);
|
||||
}
|
||||
|
||||
static void AmiglGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params) {
|
||||
return IOGLES2->glGetRenderbufferParameteriv(target, pname, params);
|
||||
}
|
||||
|
||||
static void AmiglGetShaderiv (GLuint shader, GLenum pname, GLint *params) {
|
||||
return IOGLES2->glGetShaderiv(shader, pname, params);
|
||||
}
|
||||
|
||||
static void AmiglGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) {
|
||||
return IOGLES2->glGetShaderInfoLog(shader, bufSize, length, infoLog);
|
||||
}
|
||||
|
||||
static void AmiglGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision) {
|
||||
return IOGLES2->glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
|
||||
}
|
||||
|
||||
static void AmiglGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) {
|
||||
return IOGLES2->glGetShaderSource(shader, bufSize, length, source);
|
||||
}
|
||||
|
||||
static const GLubyte *AmiglGetString (GLenum name) {
|
||||
return IOGLES2->glGetString(name);
|
||||
}
|
||||
|
||||
static void AmiglGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params) {
|
||||
return IOGLES2->glGetTexParameterfv(target, pname, params);
|
||||
}
|
||||
|
||||
static void AmiglGetTexParameteriv (GLenum target, GLenum pname, GLint *params) {
|
||||
return IOGLES2->glGetTexParameteriv(target, pname, params);
|
||||
}
|
||||
|
||||
static void AmiglGetUniformfv (GLuint program, GLint location, GLfloat *params) {
|
||||
return IOGLES2->glGetUniformfv(program, location, params);
|
||||
}
|
||||
|
||||
static void AmiglGetUniformiv (GLuint program, GLint location, GLint *params) {
|
||||
return IOGLES2->glGetUniformiv(program, location, params);
|
||||
}
|
||||
|
||||
static GLint AmiglGetUniformLocation (GLuint program, const GLchar *name) {
|
||||
return IOGLES2->glGetUniformLocation(program, name);
|
||||
}
|
||||
|
||||
static void AmiglGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params) {
|
||||
return IOGLES2->glGetVertexAttribfv(index, pname, params);
|
||||
}
|
||||
|
||||
static void AmiglGetVertexAttribiv (GLuint index, GLenum pname, GLint *params) {
|
||||
return IOGLES2->glGetVertexAttribiv(index, pname, params);
|
||||
}
|
||||
|
||||
static void AmiglGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer) {
|
||||
return IOGLES2->glGetVertexAttribPointerv(index, pname, pointer);
|
||||
}
|
||||
|
||||
static void AmiglHint (GLenum target, GLenum mode) {
|
||||
return IOGLES2->glHint(target, mode);
|
||||
}
|
||||
|
||||
static GLboolean AmiglIsBuffer (GLuint buffer) {
|
||||
return IOGLES2->glIsBuffer(buffer);
|
||||
}
|
||||
|
||||
static GLboolean AmiglIsEnabled (GLenum cap) {
|
||||
return IOGLES2->glIsEnabled(cap);
|
||||
}
|
||||
|
||||
static GLboolean AmiglIsFramebuffer (GLuint framebuffer) {
|
||||
return IOGLES2->glIsFramebuffer(framebuffer);
|
||||
}
|
||||
|
||||
static GLboolean AmiglIsProgram (GLuint program) {
|
||||
return IOGLES2->glIsProgram(program);
|
||||
}
|
||||
|
||||
static GLboolean AmiglIsRenderbuffer (GLuint renderbuffer) {
|
||||
return IOGLES2->glIsRenderbuffer(renderbuffer);
|
||||
}
|
||||
|
||||
static GLboolean AmiglIsShader (GLuint shader) {
|
||||
return IOGLES2->glIsShader(shader);
|
||||
}
|
||||
|
||||
static GLboolean AmiglIsTexture (GLuint texture) {
|
||||
return IOGLES2->glIsTexture(texture);
|
||||
}
|
||||
|
||||
static void AmiglLineWidth (GLfloat width) {
|
||||
return IOGLES2->glLineWidth(width);
|
||||
}
|
||||
|
||||
static void AmiglLinkProgram (GLuint program) {
|
||||
return IOGLES2->glLinkProgram(program);
|
||||
}
|
||||
|
||||
static void AmiglPixelStorei (GLenum pname, GLint param) {
|
||||
return IOGLES2->glPixelStorei(pname, param);
|
||||
}
|
||||
|
||||
static void AmiglPolygonOffset (GLfloat factor, GLfloat units) {
|
||||
return IOGLES2->glPolygonOffset(factor, units);
|
||||
}
|
||||
|
||||
static void AmiglReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) {
|
||||
return IOGLES2->glReadPixels(x, y, width, height, format, type, pixels);
|
||||
}
|
||||
|
||||
static void AmiglReleaseShaderCompiler (void) {
|
||||
return IOGLES2->glReleaseShaderCompiler();
|
||||
}
|
||||
|
||||
static void AmiglRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
|
||||
return IOGLES2->glRenderbufferStorage(target, internalformat, width, height);
|
||||
}
|
||||
|
||||
static void AmiglSampleCoverage (GLfloat value, GLboolean invert) {
|
||||
return IOGLES2->glSampleCoverage(value, invert);
|
||||
}
|
||||
|
||||
static void AmiglScissor (GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
return IOGLES2->glScissor(x, y, width, height);
|
||||
}
|
||||
|
||||
static void AmiglShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length) {
|
||||
return IOGLES2->glShaderBinary(count, shaders, binaryformat, binary, length);
|
||||
}
|
||||
|
||||
static void AmiglShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length) {
|
||||
return IOGLES2->glShaderSource(shader, count, string, length);
|
||||
}
|
||||
|
||||
static void AmiglStencilFunc (GLenum func, GLint ref, GLuint mask) {
|
||||
return IOGLES2->glStencilFunc(func, ref, mask);
|
||||
}
|
||||
|
||||
static void AmiglStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask) {
|
||||
return IOGLES2->glStencilFuncSeparate(face, func, ref, mask);
|
||||
}
|
||||
|
||||
static void AmiglStencilMask (GLuint mask) {
|
||||
return IOGLES2->glStencilMask(mask);
|
||||
}
|
||||
|
||||
static void AmiglStencilMaskSeparate (GLenum face, GLuint mask) {
|
||||
return IOGLES2->glStencilMaskSeparate(face, mask);
|
||||
}
|
||||
|
||||
static void AmiglStencilOp (GLenum fail, GLenum zfail, GLenum zpass) {
|
||||
return IOGLES2->glStencilOp(fail, zfail, zpass);
|
||||
}
|
||||
|
||||
static void AmiglStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
|
||||
return IOGLES2->glStencilOpSeparate(face, sfail, dpfail, dppass);
|
||||
}
|
||||
|
||||
static void AmiglTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) {
|
||||
return IOGLES2->glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
|
||||
}
|
||||
|
||||
static void AmiglTexParameterf (GLenum target, GLenum pname, GLfloat param) {
|
||||
return IOGLES2->glTexParameterf(target, pname, param);
|
||||
}
|
||||
|
||||
static void AmiglTexParameterfv (GLenum target, GLenum pname, const GLfloat *params) {
|
||||
return IOGLES2->glTexParameterfv(target, pname, params);
|
||||
}
|
||||
|
||||
static void AmiglTexParameteri (GLenum target, GLenum pname, GLint param) {
|
||||
return IOGLES2->glTexParameteri(target, pname, param);
|
||||
}
|
||||
|
||||
static void AmiglTexParameteriv (GLenum target, GLenum pname, const GLint *params) {
|
||||
return IOGLES2->glTexParameteriv(target, pname, params);
|
||||
}
|
||||
|
||||
static void AmiglTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) {
|
||||
return IOGLES2->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
|
||||
}
|
||||
|
||||
static void AmiglUniform1f (GLint location, GLfloat v0) {
|
||||
return IOGLES2->glUniform1f(location, v0);
|
||||
}
|
||||
|
||||
static void AmiglUniform1fv (GLint location, GLsizei count, const GLfloat *value) {
|
||||
return IOGLES2->glUniform1fv(location, count, value);
|
||||
}
|
||||
|
||||
static void AmiglUniform1i (GLint location, GLint v0) {
|
||||
return IOGLES2->glUniform1i(location, v0);
|
||||
}
|
||||
|
||||
static void AmiglUniform1iv (GLint location, GLsizei count, const GLint *value) {
|
||||
return IOGLES2->glUniform1iv(location, count, value);
|
||||
}
|
||||
|
||||
static void AmiglUniform2f (GLint location, GLfloat v0, GLfloat v1) {
|
||||
return IOGLES2->glUniform2f(location, v0, v1);
|
||||
}
|
||||
|
||||
static void AmiglUniform2fv (GLint location, GLsizei count, const GLfloat *value) {
|
||||
return IOGLES2->glUniform2fv(location, count, value);
|
||||
}
|
||||
|
||||
static void AmiglUniform2i (GLint location, GLint v0, GLint v1) {
|
||||
return IOGLES2->glUniform2i(location, v0, v1);
|
||||
}
|
||||
|
||||
static void AmiglUniform2iv (GLint location, GLsizei count, const GLint *value) {
|
||||
return IOGLES2->glUniform2iv(location, count, value);
|
||||
}
|
||||
|
||||
static void AmiglUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
|
||||
return IOGLES2->glUniform3f(location, v0, v1, v2);
|
||||
}
|
||||
|
||||
static void AmiglUniform3fv (GLint location, GLsizei count, const GLfloat *value) {
|
||||
return IOGLES2->glUniform3fv(location, count, value);
|
||||
}
|
||||
|
||||
static void AmiglUniform3i (GLint location, GLint v0, GLint v1, GLint v2) {
|
||||
return IOGLES2->glUniform3i(location, v0, v1, v2);
|
||||
}
|
||||
|
||||
static void AmiglUniform3iv (GLint location, GLsizei count, const GLint *value) {
|
||||
return IOGLES2->glUniform3iv(location, count, value);
|
||||
}
|
||||
|
||||
static void AmiglUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
|
||||
return IOGLES2->glUniform4f(location, v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
static void AmiglUniform4fv (GLint location, GLsizei count, const GLfloat *value) {
|
||||
return IOGLES2->glUniform4fv(location, count, value);
|
||||
}
|
||||
|
||||
static void AmiglUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
|
||||
return IOGLES2->glUniform4i(location, v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
static void AmiglUniform4iv (GLint location, GLsizei count, const GLint *value) {
|
||||
return IOGLES2->glUniform4iv(location, count, value);
|
||||
}
|
||||
|
||||
static void AmiglUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
|
||||
return IOGLES2->glUniformMatrix2fv(location, count, transpose, value);
|
||||
}
|
||||
|
||||
static void AmiglUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
|
||||
return IOGLES2->glUniformMatrix3fv(location, count, transpose, value);
|
||||
}
|
||||
|
||||
static void AmiglUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
|
||||
return IOGLES2->glUniformMatrix4fv(location, count, transpose, value);
|
||||
}
|
||||
|
||||
static void AmiglUseProgram (GLuint program) {
|
||||
return IOGLES2->glUseProgram(program);
|
||||
}
|
||||
|
||||
static void AmiglValidateProgram (GLuint program) {
|
||||
return IOGLES2->glValidateProgram(program);
|
||||
}
|
||||
|
||||
static void AmiglVertexAttrib1f (GLuint index, GLfloat x) {
|
||||
return IOGLES2->glVertexAttrib1f(index, x);
|
||||
}
|
||||
|
||||
static void AmiglVertexAttrib1fv (GLuint index, const GLfloat *v) {
|
||||
return IOGLES2->glVertexAttrib1fv(index, v);
|
||||
}
|
||||
|
||||
static void AmiglVertexAttrib2f (GLuint index, GLfloat x, GLfloat y) {
|
||||
return IOGLES2->glVertexAttrib2f(index, x, y);
|
||||
}
|
||||
|
||||
static void AmiglVertexAttrib2fv (GLuint index, const GLfloat *v) {
|
||||
return IOGLES2->glVertexAttrib2fv(index, v);
|
||||
}
|
||||
|
||||
static void AmiglVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z) {
|
||||
return IOGLES2->glVertexAttrib3f(index, x, y, z);
|
||||
}
|
||||
|
||||
static void AmiglVertexAttrib3fv (GLuint index, const GLfloat *v) {
|
||||
return IOGLES2->glVertexAttrib3fv(index, v);
|
||||
}
|
||||
|
||||
static void AmiglVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
|
||||
return IOGLES2->glVertexAttrib4f(index, x, y, z, w);
|
||||
}
|
||||
|
||||
static void AmiglVertexAttrib4fv (GLuint index, const GLfloat *v) {
|
||||
return IOGLES2->glVertexAttrib4fv(index, v);
|
||||
}
|
||||
|
||||
static void AmiglVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) {
|
||||
return IOGLES2->glVertexAttribPointer(index, size, type, normalized, stride, pointer);
|
||||
}
|
||||
|
||||
static void AmiglViewport (GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
return IOGLES2->glViewport(x, y, width, height);
|
||||
}
|
||||
|
||||
// Using glXXX name, return the function pointer of that function in ogles2 library
|
||||
#define MAP(func_name, func) \
|
||||
if (strcmp(name, func_name) == 0) return (void *)Ami##func;
|
||||
|
||||
#define EX(func_name) MAP(#func_name, func_name)
|
||||
|
||||
void* os4GetProcAddress(const char* name)
|
||||
{
|
||||
if(!IOGLES2)
|
||||
return NULL;
|
||||
// All GL functions from OGLES2 drivers
|
||||
EX(glActiveTexture)
|
||||
EX(glAttachShader)
|
||||
EX(glBindAttribLocation)
|
||||
EX(glBindBuffer)
|
||||
EX(glBindFramebuffer)
|
||||
EX(glBindRenderbuffer)
|
||||
EX(glBindTexture)
|
||||
EX(glBlendColor)
|
||||
EX(glBlendEquation)
|
||||
EX(glBlendEquationSeparate)
|
||||
EX(glBlendFunc)
|
||||
EX(glBlendFuncSeparate)
|
||||
EX(glBufferData)
|
||||
EX(glBufferSubData)
|
||||
EX(glCheckFramebufferStatus)
|
||||
EX(glClear)
|
||||
EX(glClearColor)
|
||||
EX(glClearDepthf)
|
||||
EX(glClearStencil)
|
||||
EX(glColorMask)
|
||||
EX(glCompileShader)
|
||||
EX(glCompressedTexImage2D)
|
||||
EX(glCompressedTexSubImage2D)
|
||||
EX(glCopyTexImage2D)
|
||||
EX(glCopyTexSubImage2D)
|
||||
EX(glCreateProgram)
|
||||
EX(glCreateShader)
|
||||
EX(glCullFace)
|
||||
EX(glDeleteBuffers)
|
||||
EX(glDeleteFramebuffers)
|
||||
EX(glDeleteProgram)
|
||||
EX(glDeleteRenderbuffers)
|
||||
EX(glDeleteShader)
|
||||
EX(glDeleteTextures)
|
||||
EX(glDepthFunc)
|
||||
EX(glDepthMask)
|
||||
EX(glDepthRangef)
|
||||
EX(glDetachShader)
|
||||
EX(glDisable)
|
||||
EX(glDisableVertexAttribArray)
|
||||
EX(glDrawArrays)
|
||||
EX(glDrawElements)
|
||||
EX(glEnable)
|
||||
EX(glEnableVertexAttribArray)
|
||||
EX(glFinish)
|
||||
EX(glFlush)
|
||||
EX(glFramebufferRenderbuffer)
|
||||
EX(glFramebufferTexture2D)
|
||||
EX(glFrontFace)
|
||||
EX(glGenBuffers)
|
||||
EX(glGenerateMipmap)
|
||||
EX(glGenFramebuffers)
|
||||
EX(glGenRenderbuffers)
|
||||
EX(glGenTextures)
|
||||
EX(glGetActiveAttrib)
|
||||
EX(glGetActiveUniform)
|
||||
EX(glGetAttachedShaders)
|
||||
EX(glGetAttribLocation)
|
||||
EX(glGetBooleanv)
|
||||
EX(glGetBufferParameteriv)
|
||||
EX(glGetError)
|
||||
EX(glGetFloatv)
|
||||
EX(glGetFramebufferAttachmentParameteriv)
|
||||
EX(glGetIntegerv)
|
||||
EX(glGetProgramiv)
|
||||
EX(glGetProgramInfoLog)
|
||||
EX(glGetRenderbufferParameteriv)
|
||||
EX(glGetShaderiv)
|
||||
EX(glGetShaderInfoLog)
|
||||
EX(glGetShaderPrecisionFormat)
|
||||
EX(glGetShaderSource)
|
||||
EX(glGetString)
|
||||
EX(glGetTexParameterfv)
|
||||
EX(glGetTexParameteriv)
|
||||
EX(glGetUniformfv)
|
||||
EX(glGetUniformiv)
|
||||
EX(glGetUniformLocation)
|
||||
EX(glGetVertexAttribfv)
|
||||
EX(glGetVertexAttribiv)
|
||||
EX(glGetVertexAttribPointerv)
|
||||
EX(glHint)
|
||||
EX(glIsBuffer)
|
||||
EX(glIsEnabled)
|
||||
EX(glIsFramebuffer)
|
||||
EX(glIsProgram)
|
||||
EX(glIsRenderbuffer)
|
||||
EX(glIsShader)
|
||||
EX(glIsTexture)
|
||||
EX(glLineWidth)
|
||||
EX(glLinkProgram)
|
||||
EX(glPixelStorei)
|
||||
EX(glPolygonOffset)
|
||||
EX(glReadPixels)
|
||||
EX(glReleaseShaderCompiler)
|
||||
EX(glRenderbufferStorage)
|
||||
EX(glSampleCoverage)
|
||||
EX(glScissor)
|
||||
EX(glShaderBinary)
|
||||
EX(glShaderSource)
|
||||
EX(glStencilFunc)
|
||||
EX(glStencilFuncSeparate)
|
||||
EX(glStencilMask)
|
||||
EX(glStencilMaskSeparate)
|
||||
EX(glStencilOp)
|
||||
EX(glStencilOpSeparate)
|
||||
EX(glTexImage2D)
|
||||
EX(glTexParameterf)
|
||||
EX(glTexParameterfv)
|
||||
EX(glTexParameteri)
|
||||
EX(glTexParameteriv)
|
||||
EX(glTexSubImage2D)
|
||||
EX(glUniform1f)
|
||||
EX(glUniform1fv)
|
||||
EX(glUniform1i)
|
||||
EX(glUniform1iv)
|
||||
EX(glUniform2f)
|
||||
EX(glUniform2fv)
|
||||
EX(glUniform2i)
|
||||
EX(glUniform2iv)
|
||||
EX(glUniform3f)
|
||||
EX(glUniform3fv)
|
||||
EX(glUniform3i)
|
||||
EX(glUniform3iv)
|
||||
EX(glUniform4f)
|
||||
EX(glUniform4fv)
|
||||
EX(glUniform4i)
|
||||
EX(glUniform4iv)
|
||||
EX(glUniformMatrix2fv)
|
||||
EX(glUniformMatrix3fv)
|
||||
EX(glUniformMatrix4fv)
|
||||
EX(glUseProgram)
|
||||
EX(glValidateProgram)
|
||||
EX(glVertexAttrib1f)
|
||||
EX(glVertexAttrib1fv)
|
||||
EX(glVertexAttrib2f)
|
||||
EX(glVertexAttrib2fv)
|
||||
EX(glVertexAttrib3f)
|
||||
EX(glVertexAttrib3fv)
|
||||
EX(glVertexAttrib4f)
|
||||
EX(glVertexAttrib4fv)
|
||||
EX(glVertexAttribPointer)
|
||||
EX(glViewport)
|
||||
//EX(glPolygonMode) //This is a non-standard function, and gl4es will ignore it (and emulate it), even if Amiga OGLES2 driver implement it
|
||||
|
||||
return IOGLES2->aglGetProcAddress(name);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef _AMIGAOS_H_
|
||||
#define _AMIGAOS_H_
|
||||
|
||||
void* os4GetProcAddress(const char* name);
|
||||
|
||||
void os4OpenLib(void** lib);
|
||||
void os4CloseLib();
|
||||
|
||||
#endif //_AMIGAOS_H_
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "../gl/attributes.h"
|
||||
#include "../gl/init.h"
|
||||
#include "../gl/logs.h"
|
||||
#define STUB_FCT aglStub
|
||||
#include "../gl/gl_lookup.h"
|
||||
|
||||
#include "../glx/glx.h"
|
||||
#include "../glx/hardext.h"
|
||||
|
||||
void aglStub(void *x, ...) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy/ Paste of agl specifics function, but simplified whithout the Amiga speicifc types
|
||||
void* aglCreateContext(void * errcode, void * tags);
|
||||
void* aglCreateContext2(void * errcode, void * tags);
|
||||
void aglDestroyContext(void* context);
|
||||
void aglMakeCurrent(void* context);
|
||||
void aglSwapBuffers();
|
||||
void aglSetParams2(void * tags);
|
||||
void aglSetBitmap(void * bitmap);
|
||||
void* aglGetProcAddress(const char* name);
|
||||
// TODO: something less error prone, but agl.h cannot be included here, as some Amiga header conflict with some GLES ones
|
||||
|
||||
void *gl4es_aglGetProcAddress(const char *name) {
|
||||
|
||||
MAP("glXSwapIntervalMESA", gl4es_glXSwapInterval);
|
||||
MAP("glXSwapIntervalSGI", gl4es_glXSwapInterval);
|
||||
_EX(aglGetProcAddress);
|
||||
MAP("glXGetProcAddress", gl4es_aglGetProcAddress);
|
||||
MAP("glXGetProcAddressARB", gl4es_aglGetProcAddress);
|
||||
// direct mapping
|
||||
MAP("aglCreateContext", aglCreateContext);
|
||||
MAP("aglCreateContext2", aglCreateContext2);
|
||||
MAP("aglDestroyContext", aglDestroyContext);
|
||||
MAP("aglMakeCurrent", aglMakeCurrent);
|
||||
MAP("aglSwapBuffers", aglSwapBuffers);
|
||||
MAP("aglSetParams2", aglSetParams2);
|
||||
MAP("aglSetBitmap", aglSetBitmap);
|
||||
|
||||
return gl4es_GetProcAddress(name);
|
||||
}
|
||||
AliasExport(void*,aglGetProcAddress,,(const char* name));
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _GL4ES_MAIN_CONFIG_H
|
||||
#define _GL4ES_MAIN_CONFIG_H
|
||||
|
||||
#define SYS_proxy 9999
|
||||
#define MAX_EVAL_ORDER 30
|
||||
#define MAX_TEX 16
|
||||
#define MAX_LIGHT 8
|
||||
#define MAX_STACK_PROJECTION 16
|
||||
#define MAX_STACK_TEXTURE 16
|
||||
#define MAX_STACK_MODELVIEW 64
|
||||
#define MAX_STACK_COLOR 16
|
||||
#define MAX_STACK_ARB_MATRIX 8
|
||||
#define MAX_CLIP_PLANES 6
|
||||
#define MAX_VATTRIB 32
|
||||
#define MAX_MAP_SIZE 256
|
||||
#define MAX_ARB_MATRIX 8
|
||||
#define MAX_VTX_PROG_ENV_PARAMS 96
|
||||
#define MAX_VTX_PROG_LOC_PARAMS 96
|
||||
#define MAX_FRG_PROG_ENV_PARAMS 24
|
||||
#define MAX_FRG_PROG_LOC_PARAMS 24
|
||||
#define MAX_DRAW_BUFFERS 16
|
||||
|
||||
#endif // _GL4ES_MAIN_CONFIG_H
|
||||
@@ -0,0 +1,263 @@
|
||||
|
||||
#include "egl.h"
|
||||
#include "../gl/loader.h"
|
||||
#include "../glx/hardext.h"
|
||||
|
||||
#ifndef AliasExport
|
||||
#define AliasExport(name) __attribute__((alias(name))) __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
static EGLint egl_context_attrib_es2[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
static EGLint egl_context_attrib[] = {
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
EGLint gl4es_eglGetError(void) {
|
||||
LOAD_EGL(eglGetError);
|
||||
return egl_eglGetError();
|
||||
}
|
||||
|
||||
EGLDisplay gl4es_eglGetDisplay(EGLNativeDisplayType display_id) {
|
||||
LOAD_EGL(eglGetDisplay);
|
||||
return egl_eglGetDisplay(display_id);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) {
|
||||
LOAD_EGL(eglInitialize);
|
||||
return egl_eglInitialize(dpy, major, minor);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglTerminate(EGLDisplay dpy) {
|
||||
LOAD_EGL(eglTerminate);
|
||||
return egl_eglTerminate(dpy);
|
||||
}
|
||||
|
||||
const char * gl4es_eglQueryString(EGLDisplay dpy, EGLint name) {
|
||||
LOAD_EGL(eglQueryString);
|
||||
return egl_eglQueryString(dpy, name);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) {
|
||||
LOAD_EGL(eglGetConfigs);
|
||||
return egl_eglGetConfigs(dpy, configs, config_size, num_config);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) {
|
||||
LOAD_EGL(eglChooseConfig);
|
||||
return egl_eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) {
|
||||
EGLint old_value = 0;
|
||||
LOAD_EGL(eglGetConfigAttrib);
|
||||
EGLBoolean ret = egl_eglGetConfigAttrib(dpy, config, attribute, &old_value);
|
||||
switch (attribute) {
|
||||
case EGL_RENDERABLE_TYPE:
|
||||
*value = old_value | EGL_OPENGL_BIT;
|
||||
break;
|
||||
default:
|
||||
*value = old_value;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
EGLSurface gl4es_eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) {
|
||||
LOAD_EGL(eglCreateWindowSurface);
|
||||
return egl_eglCreateWindowSurface(dpy, config, win, attrib_list);
|
||||
}
|
||||
|
||||
EGLSurface gl4es_eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) {
|
||||
LOAD_EGL(eglCreatePbufferSurface);
|
||||
return egl_eglCreatePbufferSurface(dpy, config, attrib_list);
|
||||
}
|
||||
|
||||
EGLSurface gl4es_eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) {
|
||||
LOAD_EGL(eglCreatePixmapSurface);
|
||||
return egl_eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglDestroySurface(EGLDisplay dpy, EGLSurface surface) {
|
||||
LOAD_EGL(eglDestroySurface);
|
||||
return egl_eglDestroySurface(dpy, surface);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) {
|
||||
LOAD_EGL(eglQuerySurface);
|
||||
return egl_eglQuerySurface(dpy, surface, attribute, value);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglBindAPI(EGLenum api) {
|
||||
LOAD_EGL(eglBindAPI);
|
||||
return egl_eglBindAPI(EGL_OPENGL_ES_API);
|
||||
}
|
||||
|
||||
EGLenum gl4es_eglQueryAPI(void) {
|
||||
return EGL_OPENGL_API;
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglWaitClient(void) {
|
||||
LOAD_EGL(eglWaitClient);
|
||||
return egl_eglWaitClient();
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglReleaseThread(void) {
|
||||
LOAD_EGL(eglReleaseThread);
|
||||
return egl_eglReleaseThread();
|
||||
}
|
||||
|
||||
EGLSurface gl4es_eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) {
|
||||
LOAD_EGL(eglCreatePbufferFromClientBuffer);
|
||||
return egl_eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) {
|
||||
LOAD_EGL(eglSurfaceAttrib);
|
||||
return egl_eglSurfaceAttrib(dpy, surface, attribute, value);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
|
||||
LOAD_EGL(eglBindTexImage);
|
||||
return egl_eglBindTexImage(dpy, surface, buffer);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
|
||||
LOAD_EGL(eglReleaseTexImage);
|
||||
return egl_eglReleaseTexImage(dpy, surface, buffer);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglSwapInterval(EGLDisplay dpy, EGLint interval) {
|
||||
LOAD_EGL(eglSwapInterval);
|
||||
return egl_eglSwapInterval(dpy, interval);
|
||||
}
|
||||
|
||||
EGLContext gl4es_eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) {
|
||||
LOAD_EGL(eglCreateContext);
|
||||
return egl_eglCreateContext(dpy, config, share_context, (hardext.esversion == 1) ? egl_context_attrib : egl_context_attrib_es2);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
|
||||
LOAD_EGL(eglDestroyContext);
|
||||
return egl_eglDestroyContext(dpy, ctx);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) {
|
||||
LOAD_EGL(eglMakeCurrent);
|
||||
return egl_eglMakeCurrent(dpy, draw, read, ctx);
|
||||
}
|
||||
|
||||
EGLContext gl4es_eglGetCurrentContext(void) {
|
||||
LOAD_EGL(eglGetCurrentContext);
|
||||
return egl_eglGetCurrentContext();
|
||||
}
|
||||
|
||||
EGLSurface gl4es_eglGetCurrentSurface(EGLint readdraw) {
|
||||
LOAD_EGL(eglGetCurrentSurface);
|
||||
return egl_eglGetCurrentSurface(readdraw);
|
||||
}
|
||||
|
||||
EGLDisplay gl4es_eglGetCurrentDisplay(void) {
|
||||
LOAD_EGL(eglGetCurrentDisplay);
|
||||
return egl_eglGetCurrentDisplay();
|
||||
}
|
||||
|
||||
EGLDisplay gl4es_eglGetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list) {
|
||||
LOAD_EGL_EXT(eglGetPlatformDisplay);
|
||||
if (egl_eglGetPlatformDisplay)
|
||||
return egl_eglGetPlatformDisplay(platform, native_display, attrib_list);
|
||||
else {
|
||||
LOAD_EGL(eglGetDisplay);
|
||||
return egl_eglGetDisplay((EGLNativeDisplayType)native_display);
|
||||
}
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) {
|
||||
LOAD_EGL(eglQueryContext);
|
||||
return egl_eglQueryContext(dpy, ctx, attribute, value);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglWaitGL(void) {
|
||||
LOAD_EGL(eglWaitGL);
|
||||
return egl_eglWaitGL();
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglWaitNative(EGLint engine) {
|
||||
LOAD_EGL(eglWaitNative);
|
||||
return egl_eglWaitNative(engine);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
|
||||
LOAD_EGL(eglSwapBuffers);
|
||||
return egl_eglSwapBuffers(dpy, surface);
|
||||
}
|
||||
|
||||
EGLBoolean gl4es_eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) {
|
||||
LOAD_EGL(eglCopyBuffers);
|
||||
return egl_eglCopyBuffers(dpy, surface, target);
|
||||
}
|
||||
|
||||
EGLSyncKHR gl4es_eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) {
|
||||
LOAD_EGL(eglCreateSyncKHR);
|
||||
return egl_eglCreateSyncKHR(dpy, type, attrib_list);
|
||||
}
|
||||
|
||||
EGLint gl4es_eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
|
||||
LOAD_EGL(eglClientWaitSyncKHR);
|
||||
return egl_eglClientWaitSyncKHR(dpy, sync, flags, timeout);
|
||||
}
|
||||
|
||||
NativePixmapType gl4es_egl_create_pixmap_ID_mapping(void *pixmap)
|
||||
{
|
||||
LOAD_EGL(egl_create_pixmap_ID_mapping);
|
||||
return egl_egl_create_pixmap_ID_mapping(pixmap);
|
||||
}
|
||||
|
||||
NativePixmapType gl4es_egl_destroy_pixmap_ID_mapping(int id)
|
||||
{
|
||||
LOAD_EGL(egl_destroy_pixmap_ID_mapping);
|
||||
return egl_egl_destroy_pixmap_ID_mapping(id);
|
||||
}
|
||||
|
||||
AliasExport(EGLint, eglGetError,,(void));
|
||||
AliasExport(EGLDisplay, eglGetDisplay,,(EGLNativeDisplayType display_id));
|
||||
AliasExport(EGLBoolean, eglInitialize,,(EGLDisplay dpy, EGLint *major, EGLint *minor));
|
||||
AliasExport(EGLBoolean, eglTerminate,,(EGLDisplay dpy));
|
||||
AliasExport(const char *, eglQueryString,,(EGLDisplay dpy, EGLint name));
|
||||
AliasExport(EGLBoolean, eglGetConfigs,,(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config));
|
||||
AliasExport(EGLBoolean, eglChooseConfig,,(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config));
|
||||
AliasExport(EGLBoolean, eglGetConfigAttrib,,(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value));
|
||||
AliasExport(EGLSurface, eglCreateWindowSurface,,(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list));
|
||||
AliasExport(EGLSurface, eglCreatePbufferSurface,,(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list));
|
||||
AliasExport(EGLSurface, eglCreatePixmapSurface,,(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list));
|
||||
AliasExport(EGLBoolean, eglDestroySurface,,(EGLDisplay dpy, EGLSurface surface));
|
||||
AliasExport(EGLBoolean, eglQuerySurface,,(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value));
|
||||
AliasExport(EGLBoolean, eglBindAPI,,(EGLenum api));
|
||||
AliasExport(EGLenum, eglQueryAPI,,(void));
|
||||
AliasExport(EGLBoolean, eglWaitClient,,(void));
|
||||
AliasExport(EGLBoolean, eglReleaseThread,,(void));
|
||||
AliasExport(EGLSurface, eglCreatePbufferFromClientBuffer,,(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list));
|
||||
AliasExport(EGLBoolean, eglSurfaceAttrib,,(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value));
|
||||
AliasExport(EGLBoolean, eglBindTexImage,,(EGLDisplay dpy, EGLSurface surface, EGLint buffer));
|
||||
AliasExport(EGLBoolean, eglReleaseTexImage,,(EGLDisplay dpy, EGLSurface surface, EGLint buffer));
|
||||
AliasExport(EGLBoolean, eglSwapInterval,,(EGLDisplay dpy, EGLint interval));
|
||||
AliasExport(EGLContext, eglCreateContext,,(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list));
|
||||
AliasExport(EGLBoolean, eglDestroyContext,,(EGLDisplay dpy, EGLContext ctx));
|
||||
AliasExport(EGLBoolean, eglMakeCurrent,,(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx));
|
||||
AliasExport(EGLContext, eglGetCurrentContext,,(void));
|
||||
AliasExport(EGLSurface, eglGetCurrentSurface,,(EGLint readdraw));
|
||||
AliasExport(EGLDisplay, eglGetCurrentDisplay,,(void));
|
||||
AliasExport(EGLDisplay, eglGetPlatformDisplay,, (EGLenum platform, void *native_display, const EGLAttrib *attrib_list));
|
||||
AliasExport(EGLDisplay, eglGetPlatformDisplay, EXT, (EGLenum platform, void *native_display, const EGLAttrib *attrib_list));
|
||||
AliasExport(EGLBoolean, eglQueryContext,,(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value));
|
||||
AliasExport(EGLBoolean, eglWaitGL,,(void));
|
||||
AliasExport(EGLBoolean, eglWaitNative,,(EGLint engine));
|
||||
AliasExport(EGLBoolean, eglSwapBuffers,,(EGLDisplay dpy, EGLSurface surface));
|
||||
AliasExport(EGLBoolean, eglCopyBuffers,,(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target));
|
||||
AliasExport(EGLSyncKHR, eglCreateSyncKHR,,(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list));
|
||||
AliasExport(EGLint, eglClientWaitSyncKHR,,(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout));
|
||||
|
||||
AliasExport(NativePixmapType, egl_create_pixmap_ID_mapping,,(void *pixmap));
|
||||
AliasExport(NativePixmapType, egl_destroy_pixmap_ID_mapping,,(int id));
|
||||
@@ -0,0 +1,59 @@
|
||||
#ifndef _EGL_EGL_H_
|
||||
#define _EGL_EGL_H_
|
||||
|
||||
#ifdef NOEGL
|
||||
# error Building EGL wrapper without EGL
|
||||
#endif
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
EGLint gl4es_eglGetError(void);
|
||||
EGLDisplay gl4es_eglGetDisplay(EGLNativeDisplayType display_id);
|
||||
EGLBoolean gl4es_eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
|
||||
EGLBoolean gl4es_eglTerminate(EGLDisplay dpy);
|
||||
const char * gl4es_eglQueryString(EGLDisplay dpy, EGLint name);
|
||||
EGLBoolean gl4es_eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||
EGLBoolean gl4es_eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||
EGLBoolean gl4es_eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
|
||||
|
||||
EGLSurface gl4es_eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
|
||||
EGLSurface gl4es_eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
|
||||
EGLSurface gl4es_eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
|
||||
EGLBoolean gl4es_eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
|
||||
EGLBoolean gl4es_eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
|
||||
EGLBoolean gl4es_eglBindAPI(EGLenum api);
|
||||
EGLenum gl4es_eglQueryAPI(void);
|
||||
|
||||
EGLBoolean gl4es_eglWaitClient(void);
|
||||
EGLBoolean gl4es_eglReleaseThread(void);
|
||||
EGLSurface gl4es_eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
|
||||
EGLBoolean gl4es_eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
|
||||
EGLBoolean gl4es_eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
EGLBoolean gl4es_eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
EGLBoolean gl4es_eglSwapInterval(EGLDisplay dpy, EGLint interval);
|
||||
EGLContext gl4es_eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
|
||||
EGLBoolean gl4es_eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
|
||||
EGLBoolean gl4es_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
|
||||
EGLContext gl4es_eglGetCurrentContext(void);
|
||||
EGLSurface gl4es_eglGetCurrentSurface(EGLint readdraw);
|
||||
EGLDisplay gl4es_eglGetCurrentDisplay(void);
|
||||
EGLDisplay gl4es_eglGetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
|
||||
EGLBoolean gl4es_eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
|
||||
EGLBoolean gl4es_eglWaitGL(void);
|
||||
EGLBoolean gl4es_eglWaitNative(EGLint engine);
|
||||
EGLBoolean gl4es_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
|
||||
EGLBoolean gl4es_eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
|
||||
void* gl4es_eglGetProcAddress(const char *name);
|
||||
|
||||
EGLSyncKHR gl4es_eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
|
||||
EGLint gl4es_eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
|
||||
|
||||
// Undocumented libmali internals, needed for ODROID Go Ultra
|
||||
NativePixmapType gl4es_egl_create_pixmap_ID_mapping(void *pixmap);
|
||||
NativePixmapType gl4es_egl_destroy_pixmap_ID_mapping(int id);
|
||||
|
||||
#endif // _EGL_EGL_H
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "../gl/attributes.h"
|
||||
#include "../gl/init.h"
|
||||
#include "../gl/logs.h"
|
||||
|
||||
#define STUB_FCT eglStub
|
||||
#include "../gl/gl_lookup.h"
|
||||
|
||||
#include "egl.h"
|
||||
#include "../glx/hardext.h"
|
||||
|
||||
extern void *gl4es_glXGetProcAddress(const char *name);
|
||||
|
||||
void eglStub(void *x, ...) {
|
||||
return;
|
||||
}
|
||||
|
||||
void* gl4es_eglGetProcAddress(const char *name) {
|
||||
_EX(eglGetError);
|
||||
_EX(eglGetDisplay);
|
||||
_EX(eglInitialize);
|
||||
_EX(eglTerminate);
|
||||
_EX(eglQueryString);
|
||||
_EX(eglGetConfigs);
|
||||
_EX(eglChooseConfig);
|
||||
_EX(eglGetConfigAttrib);
|
||||
|
||||
_EX(eglCreateWindowSurface);
|
||||
_EX(eglCreatePbufferSurface);
|
||||
_EX(eglCreatePixmapSurface);
|
||||
_EX(eglDestroySurface);
|
||||
_EX(eglQuerySurface);
|
||||
_EX(eglBindAPI);
|
||||
_EX(eglQueryAPI);
|
||||
|
||||
_EX(eglWaitClient);
|
||||
_EX(eglReleaseThread);
|
||||
_EX(eglCreatePbufferFromClientBuffer);
|
||||
_EX(eglSurfaceAttrib);
|
||||
_EX(eglBindTexImage);
|
||||
_EX(eglReleaseTexImage);
|
||||
_EX(eglSwapInterval);
|
||||
_EX(eglCreateContext);
|
||||
_EX(eglDestroyContext);
|
||||
_EX(eglMakeCurrent);
|
||||
_EX(eglGetCurrentContext);
|
||||
_EX(eglGetCurrentSurface);
|
||||
_EX(eglGetCurrentDisplay);
|
||||
_EX(eglGetPlatformDisplay);
|
||||
_EXT(eglGetPlatformDisplay);
|
||||
_EX(eglQueryContext);
|
||||
_EX(eglWaitGL);
|
||||
_EX(eglWaitNative);
|
||||
_EX(eglSwapBuffers);
|
||||
_EX(eglCopyBuffers);
|
||||
_EX(eglCreateSyncKHR);
|
||||
_EX(eglClientWaitSyncKHR);
|
||||
|
||||
_EX(egl_create_pixmap_ID_mapping);
|
||||
_EX(egl_destroy_pixmap_ID_mapping);
|
||||
|
||||
_EX(glXGetProcAddress);
|
||||
_ARB(glXGetProcAddress);
|
||||
_EX(eglGetProcAddress);
|
||||
|
||||
return gl4es_GetProcAddress(name);
|
||||
}
|
||||
|
||||
AliasExport(__eglMustCastToProperFunctionPointerType, eglGetProcAddress,, (const char *name));
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
#include "arbconverter.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "arbgenerator.h"
|
||||
#include "arbhelper.h"
|
||||
#include "arbparser.h"
|
||||
#include "khash.h"
|
||||
|
||||
#define FAIL(str) curStatus.status = ST_ERROR; if (*error_msg) free(*error_msg); \
|
||||
*error_msg = strdup(str); continue
|
||||
#define curStatusPtr &curStatus
|
||||
char* gl4es_convertARB(const char* const code, int vertex, char **error_msg, int *error_ptr) {
|
||||
*error_ptr = -1; // Reinit error pointer
|
||||
|
||||
struct sSpecialCases specialCases = {0, 0};
|
||||
const char *codeStart = code;
|
||||
// Not sure this is really OK...
|
||||
if ((codeStart[0] != '!') || (codeStart[1] != '!')) {
|
||||
while (1) {
|
||||
while ((*codeStart != '!') && (*codeStart != '\0')) {
|
||||
++codeStart;
|
||||
}
|
||||
if (*codeStart == '\0') {
|
||||
// Invalid start
|
||||
if (*error_msg)
|
||||
free(*error_msg);
|
||||
*error_msg = strdup("Invalid program start");
|
||||
*error_ptr = 0;
|
||||
return NULL;
|
||||
}
|
||||
if ((codeStart[0] == '!') && (codeStart[1] == '!')) {
|
||||
break;
|
||||
}
|
||||
++codeStart;
|
||||
}
|
||||
}
|
||||
if (vertex) {
|
||||
if (strncmp(codeStart, "!!ARBvp1.0", 10)) {
|
||||
if (*error_msg)
|
||||
free(*error_msg);
|
||||
*error_msg = strdup("Invalid program start");
|
||||
*error_ptr = codeStart - code;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (strncmp(codeStart, "!!ARBfp1.0", 10)) {
|
||||
if (*error_msg)
|
||||
free(*error_msg);
|
||||
*error_msg = strdup("Invalid program start");
|
||||
*error_ptr = codeStart - code;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
codeStart += 10;
|
||||
|
||||
ARBCONV_DBG_HEAVY(printf("Generating code for:\n%s\n", codeStart);)
|
||||
|
||||
sCurStatus curStatus = {0};
|
||||
initStatus(&curStatus, codeStart);
|
||||
readNextToken(&curStatus);
|
||||
if ((curStatus.curToken != TOK_NEWLINE) && (curStatus.curToken != TOK_WHITESPACE)) {
|
||||
curStatus.status = ST_ERROR;
|
||||
} else {
|
||||
readNextToken(&curStatus);
|
||||
}
|
||||
|
||||
while ((curStatus.status != ST_ERROR) && (curStatus.status != ST_DONE)) {
|
||||
ARBCONV_DBG_LP(
|
||||
printf(
|
||||
"%-13s",
|
||||
STATUS2STR(curStatus.status)
|
||||
);
|
||||
if (curStatus.valueType == TYPE_INST_DECL) {
|
||||
printf(
|
||||
"-%3s%4s (%2d)",
|
||||
INST2STR(curStatus.curValue.newInst.inst.type),
|
||||
curStatus.curValue.newInst.inst.saturated ? "_SAT" : " ",
|
||||
curStatus.curValue.newInst.state
|
||||
);
|
||||
} else if (curStatus.valueType == TYPE_VARIABLE_DECL) {
|
||||
printf(
|
||||
"-%-10s (%2d)",
|
||||
VARTYPE2STR(curStatus.curValue.newVar.var->type),
|
||||
curStatus.curValue.newVar.state
|
||||
);
|
||||
} else if (curStatus.valueType == TYPE_ALIAS_DECL) {
|
||||
printf("-(string) ");
|
||||
} else if (curStatus.valueType == TYPE_OPTION_DECL) {
|
||||
printf("-%15s", curStatus.curValue.newOpt.optName ? curStatus.curValue.newOpt.optName : "");
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
printf(" / %-11s: %p - %p (%ld)\n",
|
||||
TOKEN2STR(curStatus.curToken),
|
||||
curStatus.codePtr,
|
||||
curStatus.endOfToken,
|
||||
curStatus.endOfToken - curStatus.codePtr
|
||||
);
|
||||
fflush(stdout);
|
||||
)
|
||||
|
||||
parseToken(&curStatus, vertex, error_msg, &specialCases);
|
||||
|
||||
readNextToken(&curStatus);
|
||||
}
|
||||
|
||||
if (curStatus.status == ST_ERROR) {
|
||||
ARBCONV_DBG(
|
||||
char *codeDup = strdup(code);
|
||||
codeDup[curStatus.codePtr - code] = '\0';
|
||||
printf(
|
||||
"Failure, copy until EOF\n\n%s\033[91m%s\033[m\n",
|
||||
codeDup,
|
||||
curStatus.codePtr
|
||||
);
|
||||
free(codeDup);
|
||||
|
||||
printf("\nVariables:\n==========\n");
|
||||
{
|
||||
const char *kvar;
|
||||
sVariable *vvar;
|
||||
kh_foreach(curStatus.varsMap, kvar, vvar,
|
||||
if (vvar) {
|
||||
printf("Variable %10s pointing to %p (%10s)\n", kvar, vvar, vvar->names[0]);
|
||||
} else {
|
||||
printf("\033[91mVariable %10s pointing to NULLptr!\033[m\n", kvar);
|
||||
}
|
||||
)
|
||||
}
|
||||
for (size_t i = 0; i < curStatus.variables.size; ++i) {
|
||||
sVariable *varPtr = curStatus.variables.vars[i];
|
||||
printf("Variable %p %10s (%lu): %-10s (init = %3lu %s)\n", varPtr, varPtr->names[0], varPtr->names_count, VARTYPE2STR(varPtr->type), varPtr->init.strings_total_len, varPtr->init.strings_count ? varPtr->init.strings[0] : "(none)");
|
||||
}
|
||||
printf("\nInstructions:\n=============\n");
|
||||
for (size_t i = 0; i < curStatus.instructions.size; ++i) {
|
||||
sInstruction *instPtr = curStatus.instructions.insts[i];
|
||||
instPtr = curStatus.instructions.insts[i];
|
||||
if (INSTTEX(instPtr->type)) {
|
||||
printf("Instruction %3s%4s %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c %ctexture[%2s] %c%19s\n", INST2STR(instPtr->type), instPtr->saturated ? "_SAT" : " ",
|
||||
instPtr->vars[0].sign ? (instPtr->vars[0].sign == -1 ? '-' : '+') : ' ', instPtr->vars[0].var ? ((instPtr->vars[0].var->type == VARTYPE_CONST) ? instPtr->vars[0].var->init.strings[0] : instPtr->vars[0].var->names[0]) : "(none)", instPtr->vars[0].floatArrAddr ? instPtr->vars[0].floatArrAddr : "", (instPtr->vars[0].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[1].sign ? (instPtr->vars[1].sign == -1 ? '-' : '+') : ' ', instPtr->vars[1].var ? ((instPtr->vars[1].var->type == VARTYPE_CONST) ? instPtr->vars[1].var->init.strings[0] : instPtr->vars[1].var->names[0]) : "(none)", instPtr->vars[1].floatArrAddr ? instPtr->vars[1].floatArrAddr : "", (instPtr->vars[1].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[2].sign ? (instPtr->vars[2].sign == -1 ? '-' : '+') : ' ', instPtr->vars[2].var->names[0],
|
||||
instPtr->vars[3].sign ? (instPtr->vars[3].sign == -1 ? '-' : '+') : ' ', (instPtr->vars[3].var == curStatus.tex1D) ? "1D" : (instPtr->vars[3].var == curStatus.tex2D) ? "2D" : (instPtr->vars[3].var == curStatus.tex3D) ? "3D" : (instPtr->vars[3].var == curStatus.texCUBE) ? "CUBE" : (instPtr->vars[3].var == curStatus.texRECT) ? "RECT" : "!!!"
|
||||
);
|
||||
} else {
|
||||
printf("Instruction %3s%4s %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c\n", INST2STR(instPtr->type), instPtr->saturated ? "_SAT" : " ",
|
||||
instPtr->vars[0].sign ? (instPtr->vars[0].sign == -1 ? '-' : '+') : ' ', instPtr->vars[0].var ? ((instPtr->vars[0].var->type == VARTYPE_CONST) ? instPtr->vars[0].var->init.strings[0] : instPtr->vars[0].var->names[0]) : "(none)", instPtr->vars[0].floatArrAddr ? instPtr->vars[0].floatArrAddr : "", (instPtr->vars[0].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[1].sign ? (instPtr->vars[1].sign == -1 ? '-' : '+') : ' ', instPtr->vars[1].var ? ((instPtr->vars[1].var->type == VARTYPE_CONST) ? instPtr->vars[1].var->init.strings[0] : instPtr->vars[1].var->names[0]) : "(none)", instPtr->vars[1].floatArrAddr ? instPtr->vars[1].floatArrAddr : "", (instPtr->vars[1].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[2].sign ? (instPtr->vars[2].sign == -1 ? '-' : '+') : ' ', instPtr->vars[2].var ? ((instPtr->vars[2].var->type == VARTYPE_CONST) ? instPtr->vars[2].var->init.strings[0] : instPtr->vars[2].var->names[0]) : "(none)", instPtr->vars[2].floatArrAddr ? instPtr->vars[2].floatArrAddr : "", (instPtr->vars[2].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[2].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[2].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[2].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[3].sign ? (instPtr->vars[3].sign == -1 ? '-' : '+') : ' ', instPtr->vars[3].var ? ((instPtr->vars[3].var->type == VARTYPE_CONST) ? instPtr->vars[3].var->init.strings[0] : instPtr->vars[3].var->names[0]) : "(none)", instPtr->vars[3].floatArrAddr ? instPtr->vars[3].floatArrAddr : "", (instPtr->vars[3].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[3].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[3].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[3].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[3] == SWIZ_W) ? 'w' : ' '
|
||||
);
|
||||
}
|
||||
}
|
||||
printf("\n");)
|
||||
|
||||
*error_ptr = curStatus.codePtr - code;
|
||||
|
||||
// We have errored, output NULL
|
||||
freeStatus(&curStatus);
|
||||
free(curStatus.outputString);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ARBCONV_DBG(printf("Success!\n");)
|
||||
|
||||
// Variables are automatically created, only need to write main()
|
||||
size_t varIdx = (size_t)0;
|
||||
sVariable *varPtr;
|
||||
size_t instIdx = (size_t)0;
|
||||
sInstruction *instPtr;
|
||||
|
||||
do {
|
||||
if (vertex) {
|
||||
// Add a structure (for addresses) with only an 'x' component
|
||||
APPEND_OUTPUT("#version 120\n\nstruct _structOnlyX { int x; };\n\nvoid main() {\n", 61)
|
||||
if (specialCases.hasFogFragCoord) {
|
||||
APPEND_OUTPUT("\tvec4 gl4es_FogFragCoordTemp = vec4(gl_FogFragCoord);\n", 54)
|
||||
}
|
||||
} else {
|
||||
// No address
|
||||
APPEND_OUTPUT("#version 120\n\nvoid main() {\n", 28)
|
||||
if (specialCases.isDepthReplacing) {
|
||||
APPEND_OUTPUT("\tvec4 gl4es_FragDepthTemp = vec4(gl_FragDepth);\n", 48)
|
||||
}
|
||||
}
|
||||
|
||||
for (; (varIdx < curStatus.variables.size) && (curStatus.status != ST_ERROR); ++varIdx) {
|
||||
varPtr = curStatus.variables.vars[varIdx];
|
||||
|
||||
ARBCONV_DBG_AS(
|
||||
printf("Variable #%2ld: %10s (%10s)\n", varIdx, varPtr->names[0], VARTYPE2STR(varPtr->type));
|
||||
fflush(stdout);
|
||||
)
|
||||
|
||||
generateVariablePre(&curStatus, vertex, error_msg, varPtr);
|
||||
}
|
||||
if (curStatus.status == ST_ERROR) {
|
||||
--varIdx;
|
||||
*error_ptr = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
APPEND_OUTPUT("\t\n", 2)
|
||||
for (; (instIdx < curStatus.instructions.size) && (curStatus.status != ST_ERROR); ++instIdx) {
|
||||
instPtr = curStatus.instructions.insts[instIdx];
|
||||
|
||||
ARBCONV_DBG_AS(
|
||||
if (INSTTEX(instPtr->type)) {
|
||||
printf("Instruction #%3ld: %3s%4s %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c %ctexture[%2s] %c%19s\n", instIdx, INST2STR(instPtr->type), instPtr->saturated ? "_SAT" : " ",
|
||||
instPtr->vars[0].sign ? (instPtr->vars[0].sign == -1 ? '-' : '+') : ' ', instPtr->vars[0].var ? ((instPtr->vars[0].var->type == VARTYPE_CONST) ? instPtr->vars[0].var->init.strings[0] : instPtr->vars[0].var->names[0]) : "(none)", instPtr->vars[0].floatArrAddr ? instPtr->vars[0].floatArrAddr : "", (instPtr->vars[0].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[1].sign ? (instPtr->vars[1].sign == -1 ? '-' : '+') : ' ', instPtr->vars[1].var ? ((instPtr->vars[1].var->type == VARTYPE_CONST) ? instPtr->vars[1].var->init.strings[0] : instPtr->vars[1].var->names[0]) : "(none)", instPtr->vars[1].floatArrAddr ? instPtr->vars[1].floatArrAddr : "", (instPtr->vars[1].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[2].sign ? (instPtr->vars[2].sign == -1 ? '-' : '+') : ' ', instPtr->vars[2].var->names[0],
|
||||
instPtr->vars[3].sign ? (instPtr->vars[3].sign == -1 ? '-' : '+') : ' ', (instPtr->vars[3].var == curStatus.tex1D) ? "1D" : (instPtr->vars[3].var == curStatus.tex2D) ? "2D" : (instPtr->vars[3].var == curStatus.tex3D) ? "3D" : (instPtr->vars[3].var == curStatus.texCUBE) ? "CUBE" : (instPtr->vars[3].var == curStatus.texRECT) ? "RECT" : "!!!"
|
||||
);
|
||||
} else {
|
||||
printf("Instruction #%3ld: %3s%4s %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c\n", instIdx, INST2STR(instPtr->type), instPtr->saturated ? "_SAT" : " ",
|
||||
instPtr->vars[0].sign ? (instPtr->vars[0].sign == -1 ? '-' : '+') : ' ', instPtr->vars[0].var ? ((instPtr->vars[0].var->type == VARTYPE_CONST) ? instPtr->vars[0].var->init.strings[0] : instPtr->vars[0].var->names[0]) : "(none)", instPtr->vars[0].floatArrAddr ? instPtr->vars[0].floatArrAddr : "", (instPtr->vars[0].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[1].sign ? (instPtr->vars[1].sign == -1 ? '-' : '+') : ' ', instPtr->vars[1].var ? ((instPtr->vars[1].var->type == VARTYPE_CONST) ? instPtr->vars[1].var->init.strings[0] : instPtr->vars[1].var->names[0]) : "(none)", instPtr->vars[1].floatArrAddr ? instPtr->vars[1].floatArrAddr : "", (instPtr->vars[1].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[2].sign ? (instPtr->vars[2].sign == -1 ? '-' : '+') : ' ', instPtr->vars[2].var ? ((instPtr->vars[2].var->type == VARTYPE_CONST) ? instPtr->vars[2].var->init.strings[0] : instPtr->vars[2].var->names[0]) : "(none)", instPtr->vars[2].floatArrAddr ? instPtr->vars[2].floatArrAddr : "", (instPtr->vars[2].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[2].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[2].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[2].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[3].sign ? (instPtr->vars[3].sign == -1 ? '-' : '+') : ' ', instPtr->vars[3].var ? ((instPtr->vars[3].var->type == VARTYPE_CONST) ? instPtr->vars[3].var->init.strings[0] : instPtr->vars[3].var->names[0]) : "(none)", instPtr->vars[3].floatArrAddr ? instPtr->vars[3].floatArrAddr : "", (instPtr->vars[3].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[3].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[3].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[3].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[3] == SWIZ_W) ? 'w' : ' '
|
||||
);
|
||||
}
|
||||
fflush(stdout);
|
||||
)
|
||||
|
||||
generateInstruction(&curStatus, vertex, error_msg, instPtr);
|
||||
}
|
||||
if (curStatus.status == ST_ERROR) {
|
||||
--instIdx;
|
||||
*error_ptr = curStatus.instructions.insts[instIdx]->codeLocation - code;
|
||||
break;
|
||||
}
|
||||
|
||||
APPEND_OUTPUT("\t\n", 2)
|
||||
for (varIdx = 0; (varIdx < curStatus.variables.size) && (curStatus.status != ST_ERROR); ++varIdx) {
|
||||
varPtr = curStatus.variables.vars[varIdx];
|
||||
|
||||
ARBCONV_DBG_AS(
|
||||
printf("Variable #%2ld (output): %10s (%10s)\n", varIdx, varPtr->names[0], VARTYPE2STR(varPtr->type));
|
||||
fflush(stdout);
|
||||
)
|
||||
|
||||
generateVariablePst(&curStatus, vertex, error_msg, varPtr);
|
||||
}
|
||||
if (curStatus.status == ST_ERROR) {
|
||||
--varIdx;
|
||||
*error_ptr = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (specialCases.hasFogFragCoord) {
|
||||
APPEND_OUTPUT("\tgl_FogFragCoord = gl4es_FogFragCoordTemp.x;\n", 45)
|
||||
}
|
||||
if (specialCases.isDepthReplacing) {
|
||||
APPEND_OUTPUT("\tgl_FragDepth = gl4es_FragDepthTemp.z;\n", 39)
|
||||
}
|
||||
switch (curStatus.fogType) {
|
||||
case FOG_NONE:
|
||||
break;
|
||||
case FOG_EXP:
|
||||
APPEND_OUTPUT(
|
||||
"\tgl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_FragColor.rgb, "
|
||||
"clamp(exp(-gl_Fog.density * gl_FogFragCoord), 0., 1.));\n",
|
||||
116
|
||||
)
|
||||
break;
|
||||
case FOG_EXP2:
|
||||
APPEND_OUTPUT(
|
||||
"\tgl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_FragColor.rgb, "
|
||||
"clamp(exp(-(gl_Fog.density * gl_FogFragCoord)*(gl_Fog.density * gl_FogFragCoord)), 0., 1.));\n",
|
||||
153
|
||||
)
|
||||
break;
|
||||
case FOG_LINEAR:
|
||||
APPEND_OUTPUT(
|
||||
"\tgl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_FragColor.rgb, "
|
||||
"clamp((gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale, 0., 1.));\n",
|
||||
123
|
||||
)
|
||||
break;
|
||||
}
|
||||
if(curStatus.position_invariant) {
|
||||
APPEND_OUTPUT("\tgl_Position = ftransform();\n", 29)
|
||||
}
|
||||
APPEND_OUTPUT("}\n", 2)
|
||||
} while (0);
|
||||
|
||||
#undef FAIL
|
||||
#undef APPEND_OUTPUT
|
||||
#undef APPEND_OUTPUT2
|
||||
|
||||
if (curStatus.status == ST_ERROR) {
|
||||
ARBCONV_DBG(printf("Failure!\n");
|
||||
|
||||
printf("\nVariables:\n==========\n");
|
||||
{
|
||||
const char *kvar;
|
||||
sVariable *vvar;
|
||||
kh_foreach(curStatus.varsMap, kvar, vvar,
|
||||
if (vvar) {
|
||||
printf("Variable %10s pointing to %p (%10s)\n", kvar, vvar, vvar->names[0]);
|
||||
} else {
|
||||
printf("\033[91mVariable %10s pointing to NULLptr!\033[m\n", kvar);
|
||||
}
|
||||
)
|
||||
}
|
||||
for (size_t i = 0; i < curStatus.variables.size; ++i) {
|
||||
varPtr = curStatus.variables.vars[i];
|
||||
printf("%sVariable %p %10s (%lu): %-10s (init = %3lu %s)\033[m\n", (i < varIdx) ? "" : "\033[91m", varPtr, varPtr->names[0], varPtr->names_count, VARTYPE2STR(varPtr->type), varPtr->init.strings_total_len, varPtr->init.strings_count ? varPtr->init.strings[0] : "(none)");
|
||||
}
|
||||
printf("\nInstructions:\n=============\n");
|
||||
for (size_t i = 0; i < curStatus.instructions.size; ++i) {
|
||||
instPtr = curStatus.instructions.insts[i];
|
||||
if (INSTTEX(instPtr->type)) {
|
||||
printf("%sInstruction %3s%4s %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c %ctexture[%2s] %c%19s\033[m\n", (i < instIdx) ? "" : "\033[91m", INST2STR(instPtr->type), instPtr->saturated ? "_SAT" : " ",
|
||||
instPtr->vars[0].sign ? (instPtr->vars[0].sign == -1 ? '-' : '+') : ' ', instPtr->vars[0].var ? ((instPtr->vars[0].var->type == VARTYPE_CONST) ? instPtr->vars[0].var->init.strings[0] : instPtr->vars[0].var->names[0]) : "(none)", instPtr->vars[0].floatArrAddr ? instPtr->vars[0].floatArrAddr : "", (instPtr->vars[0].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[1].sign ? (instPtr->vars[1].sign == -1 ? '-' : '+') : ' ', instPtr->vars[1].var ? ((instPtr->vars[1].var->type == VARTYPE_CONST) ? instPtr->vars[1].var->init.strings[0] : instPtr->vars[1].var->names[0]) : "(none)", instPtr->vars[1].floatArrAddr ? instPtr->vars[1].floatArrAddr : "", (instPtr->vars[1].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[2].sign ? (instPtr->vars[2].sign == -1 ? '-' : '+') : ' ', instPtr->vars[2].var->names[0],
|
||||
instPtr->vars[3].sign ? (instPtr->vars[3].sign == -1 ? '-' : '+') : ' ', (instPtr->vars[3].var == curStatus.tex1D) ? "1D" : (instPtr->vars[3].var == curStatus.tex2D) ? "2D" : (instPtr->vars[3].var == curStatus.tex3D) ? "3D" : (instPtr->vars[3].var == curStatus.texCUBE) ? "CUBE" : (instPtr->vars[3].var == curStatus.texRECT) ? "RECT" : "!!!"
|
||||
);
|
||||
} else {
|
||||
printf("%sInstruction %3s%4s %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c %c%10s[%2s].%c%c%c%c\033[m\n", (i < instIdx) ? "" : "\033[91m", INST2STR(instPtr->type), instPtr->saturated ? "_SAT" : " ",
|
||||
instPtr->vars[0].sign ? (instPtr->vars[0].sign == -1 ? '-' : '+') : ' ', instPtr->vars[0].var ? ((instPtr->vars[0].var->type == VARTYPE_CONST) ? instPtr->vars[0].var->init.strings[0] : instPtr->vars[0].var->names[0]) : "(none)", instPtr->vars[0].floatArrAddr ? instPtr->vars[0].floatArrAddr : "", (instPtr->vars[0].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[0].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[0].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[0].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[0].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[1].sign ? (instPtr->vars[1].sign == -1 ? '-' : '+') : ' ', instPtr->vars[1].var ? ((instPtr->vars[1].var->type == VARTYPE_CONST) ? instPtr->vars[1].var->init.strings[0] : instPtr->vars[1].var->names[0]) : "(none)", instPtr->vars[1].floatArrAddr ? instPtr->vars[1].floatArrAddr : "", (instPtr->vars[1].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[1].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[1].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[1].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[1].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[2].sign ? (instPtr->vars[2].sign == -1 ? '-' : '+') : ' ', instPtr->vars[2].var ? ((instPtr->vars[2].var->type == VARTYPE_CONST) ? instPtr->vars[2].var->init.strings[0] : instPtr->vars[2].var->names[0]) : "(none)", instPtr->vars[2].floatArrAddr ? instPtr->vars[2].floatArrAddr : "", (instPtr->vars[2].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[2].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[2].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[2].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[2].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[2].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[2].swizzle[3] == SWIZ_W) ? 'w' : ' ',
|
||||
instPtr->vars[3].sign ? (instPtr->vars[3].sign == -1 ? '-' : '+') : ' ', instPtr->vars[3].var ? ((instPtr->vars[3].var->type == VARTYPE_CONST) ? instPtr->vars[3].var->init.strings[0] : instPtr->vars[3].var->names[0]) : "(none)", instPtr->vars[3].floatArrAddr ? instPtr->vars[3].floatArrAddr : "", (instPtr->vars[3].swizzle[0] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[0] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[0] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[0] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[3].swizzle[1] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[1] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[1] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[1] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[3].swizzle[2] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[2] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[2] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[2] == SWIZ_W) ? 'w' : ' ', (instPtr->vars[3].swizzle[3] == SWIZ_X) ? 'x' : (instPtr->vars[3].swizzle[3] == SWIZ_Y) ? 'y' : (instPtr->vars[3].swizzle[3] == SWIZ_Z) ? 'z' : (instPtr->vars[3].swizzle[3] == SWIZ_W) ? 'w' : ' '
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nBuffered output:\n%s\n", curStatus.outputString);)
|
||||
|
||||
if (*error_ptr == -1) {
|
||||
if (*error_msg)
|
||||
free(*error_msg);
|
||||
*error_msg = strdup("Not enough memory(?)");
|
||||
*error_ptr = 0;
|
||||
}
|
||||
|
||||
// We have errored, output NULL
|
||||
freeStatus(&curStatus);
|
||||
free(curStatus.outputString);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ARBCONV_DBG(printf("Success!\n\nOutput:\n%s", curStatus.outputString);)
|
||||
|
||||
freeStatus(&curStatus);
|
||||
return curStatus.outputString;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef _GL4ES_ARBCONVERTER_H_
|
||||
#define _GL4ES_ARBCONVERTER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
char* gl4es_convertARB(const char* const code, int vertex, char **error_msg, int *error_ptr);
|
||||
|
||||
#endif // _GL4ES_ARBCONVERTER_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
#ifndef _GL4ES_ARBGENERATOR_H_
|
||||
#define _GL4ES_ARBGENERATOR_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "arbhelper.h"
|
||||
|
||||
#define APPEND_OUTPUT(str, len) \
|
||||
if (appendString(curStatusPtr, str, len)) { \
|
||||
FAIL("Unknown error (not enough memory?"); \
|
||||
}
|
||||
#define APPEND_OUTPUT2(str) APPEND_OUTPUT(str, (size_t)-1)
|
||||
|
||||
void generateVariablePre(sCurStatus *curStatusPtr, int vertex, char **error_msg, sVariable *varPtr);
|
||||
void generateInstruction(sCurStatus *curStatusPtr, int vertex, char **error_msg, sInstruction *instPtr);
|
||||
void generateVariablePst(sCurStatus *curStatusPtr, int vertex, char **error_msg, sVariable *varPtr);
|
||||
|
||||
#endif // _GL4ES_ARBGENERATOR_H_
|
||||
@@ -0,0 +1,383 @@
|
||||
#include "arbhelper.h"
|
||||
|
||||
#include "../config.h"
|
||||
|
||||
#define SIZE_THRESHOLD 0x40
|
||||
void *resize(void** obj, size_t* cap, size_t esize) {
|
||||
size_t oldSize = *cap * esize;
|
||||
size_t newSize;
|
||||
if (oldSize >= SIZE_THRESHOLD) {
|
||||
newSize = oldSize + SIZE_THRESHOLD * esize;
|
||||
} else {
|
||||
newSize = oldSize * 2;
|
||||
}
|
||||
void *reloc = realloc(*obj, newSize);
|
||||
if (reloc) {
|
||||
*obj = reloc;
|
||||
*cap = newSize;
|
||||
}
|
||||
return reloc;
|
||||
}
|
||||
|
||||
void initArray(sArray* arr) {
|
||||
arr->objs = calloc(DEFAULT_MALLOC_COUNT, sizeof(void*));
|
||||
arr->size = 0;
|
||||
arr->cap = DEFAULT_MALLOC_COUNT;
|
||||
}
|
||||
int pushArray(sArray* arr, void* obj) {
|
||||
if (arr->size >= arr->cap) {
|
||||
if (!resize((void**)&arr->objs, &arr->cap, sizeof(void*))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
arr->objs[arr->size] = obj;
|
||||
++arr->size;
|
||||
return 1;
|
||||
}
|
||||
void* popArray(sArray* arr) {
|
||||
if (!arr->size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
--arr->size;
|
||||
void *ret = arr->objs[arr->size];
|
||||
arr->objs[arr->size] = NULL;
|
||||
return ret;
|
||||
}
|
||||
void* popFIFO(sArray* arr) {
|
||||
if (!arr->size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
--arr->size;
|
||||
void *ret = arr->objs[0];
|
||||
memmove(arr->objs, arr->objs + 1, arr->size * sizeof(void*));
|
||||
arr->objs[arr->size] = NULL;
|
||||
return ret;
|
||||
}
|
||||
void freeArray(sArray* arr) {
|
||||
while (arr->size) {
|
||||
--arr->size;
|
||||
free(arr->objs[arr->size]);
|
||||
}
|
||||
free(arr->objs);
|
||||
arr->objs = NULL;
|
||||
}
|
||||
|
||||
#define TST_STR_VAL_PREF(str, pref, inst) (!strncmp(str, #inst, strlen(#inst))) ? pref##inst :
|
||||
eVariableType STR2VARTYPE(char *str) {
|
||||
return
|
||||
TST_STR_VAL_PREF(str, VARTYPE_, ADDRESS) TST_STR_VAL_PREF(str, VARTYPE_, ATTRIB)
|
||||
TST_STR_VAL_PREF(str, VARTYPE_, PARAM) TST_STR_VAL_PREF(str, VARTYPE_, TEMP)
|
||||
TST_STR_VAL_PREF(str, VARTYPE_, ALIAS) TST_STR_VAL_PREF(str, VARTYPE_, OUTPUT)
|
||||
VARTYPE_UNK;
|
||||
}
|
||||
eInstruction STR2INST(char *str, int *sat) {
|
||||
if ((str[0] == '\0') || (str[1] == '\0') || (str[2] == '\0')) return INST_UNK;
|
||||
*sat = !strcmp(str + 3, "_SAT");
|
||||
if ((((str[0] < 'A') || (str[0] > 'Z')) && ((str[0] < '0') || (str[0] > '9')))
|
||||
|| (((str[1] < 'A') || (str[1] > 'Z')) && ((str[1] < '0') || (str[1] > '9')))
|
||||
|| (((str[2] < 'A') || (str[2] > 'Z')) && ((str[2] < '0') || (str[2] > '9')))
|
||||
|| ((str[3] != '\0') && !*sat)) {
|
||||
return INST_UNK;
|
||||
}
|
||||
|
||||
switch (str[0]) {
|
||||
case 'A':
|
||||
switch (str[1]) {
|
||||
case 'B':
|
||||
return (str[2] == 'S') ? INST_ABS : INST_UNK;
|
||||
case 'D':
|
||||
return (str[2] == 'D') ? INST_ADD : INST_UNK;
|
||||
case 'R':
|
||||
return (str[2] == 'L') ? INST_ARL : INST_UNK;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
case 'C':
|
||||
switch (str[1]) {
|
||||
case 'M':
|
||||
return (str[2] == 'P') ? INST_CMP : INST_UNK;
|
||||
case 'O':
|
||||
return (str[2] == 'S') ? INST_COS : INST_UNK;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
case 'D':
|
||||
switch (str[2]) {
|
||||
case '3':
|
||||
return (str[1] == 'P') ? INST_DP3 : INST_UNK;
|
||||
case '4':
|
||||
return (str[1] == 'P') ? INST_DP4 : INST_UNK;
|
||||
case 'H':
|
||||
return (str[1] == 'P') ? INST_DPH : INST_UNK;
|
||||
case 'T':
|
||||
return (str[1] == 'S') ? INST_DST : INST_UNK;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
case 'E':
|
||||
if (str[1] != 'X') return INST_UNK;
|
||||
switch (str[2]) {
|
||||
case '2':
|
||||
return INST_EX2;
|
||||
case 'P':
|
||||
return INST_EXP;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
case 'F':
|
||||
switch (str[1]) {
|
||||
case 'L':
|
||||
return (str[2] == 'R') ? INST_FLR : INST_UNK;
|
||||
case 'R':
|
||||
return (str[2] == 'C') ? INST_FRC : INST_UNK;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
case 'K':
|
||||
return ((str[1] == 'I') && (str[2] == 'L')) ? INST_KIL : INST_UNK;
|
||||
case 'L':
|
||||
switch (str[1]) {
|
||||
case 'G':
|
||||
return (str[2] == '2') ? INST_LG2 : INST_UNK;
|
||||
case 'I':
|
||||
return (str[2] == 'T') ? INST_LIT : INST_UNK;
|
||||
case 'O':
|
||||
return (str[2] == 'G') ? INST_LOG : INST_UNK;
|
||||
case 'R':
|
||||
return (str[2] == 'P') ? INST_LRP : INST_UNK;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
case 'M':
|
||||
switch (str[2]) {
|
||||
case 'D':
|
||||
return (str[1] == 'A') ? INST_MAD : INST_UNK;
|
||||
case 'X':
|
||||
return (str[1] == 'A') ? INST_MAX : INST_UNK;
|
||||
case 'N':
|
||||
return (str[1] == 'I') ? INST_MIN : INST_UNK;
|
||||
case 'V':
|
||||
return (str[1] == 'O') ? INST_MOV : INST_UNK;
|
||||
case 'L':
|
||||
return (str[1] == 'U') ? INST_MUL : INST_UNK;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
case 'P':
|
||||
return ((str[1] == 'O') && (str[2] == 'W')) ? INST_POW : INST_UNK;
|
||||
case 'R':
|
||||
switch (str[1]) {
|
||||
case 'C':
|
||||
return (str[2] == 'P') ? INST_RCP : INST_UNK;
|
||||
case 'S':
|
||||
return (str[2] == 'Q') ? INST_RSQ : INST_UNK;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
case 'S':
|
||||
switch (str[1]) {
|
||||
case 'C':
|
||||
return (str[2] == 'S') ? INST_SCS : INST_UNK;
|
||||
case 'G':
|
||||
return (str[2] == 'E') ? INST_SGE : INST_UNK;
|
||||
case 'I':
|
||||
return (str[2] == 'N') ? INST_SIN : INST_UNK;
|
||||
case 'L':
|
||||
return (str[2] == 'T') ? INST_SLT : INST_UNK;
|
||||
case 'U':
|
||||
return (str[2] == 'B') ? INST_SUB : INST_UNK;
|
||||
case 'W':
|
||||
return (str[2] == 'Z') ? INST_SWZ : INST_UNK;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
case 'T':
|
||||
switch (str[2]) {
|
||||
case 'X':
|
||||
return (str[1] == 'E') ? INST_TEX : INST_UNK;
|
||||
case 'B':
|
||||
return (str[1] == 'X') ? INST_TXB : INST_UNK;
|
||||
case 'P':
|
||||
return (str[1] == 'X') ? INST_TXP : INST_UNK;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
case 'X':
|
||||
return ((str[1] == 'P') && (str[2] == 'D')) ? INST_XPD : INST_UNK;
|
||||
default:
|
||||
return INST_UNK;
|
||||
}
|
||||
}
|
||||
#define INSTTEX(i) (((i) == INST_TEX) || ((i) == INST_TXB) || ((i) == INST_TXP))
|
||||
|
||||
KHASH_MAP_IMPL_STR(variables, sVariable*)
|
||||
|
||||
sVariable *createVariable(eVariableType type) {
|
||||
sVariable *var = (sVariable*)calloc(1, sizeof(sVariable)); // malloc *should* be fine here
|
||||
initArray((sArray*)var);
|
||||
initArray((sArray*)&var->init);
|
||||
var->type = type;
|
||||
var->init.strings_total_len = 0;
|
||||
var->size = 0;
|
||||
return var;
|
||||
}
|
||||
void deleteVariable(sVariable **var) {
|
||||
freeArray((sArray*)*var);
|
||||
|
||||
char *stringPtr;
|
||||
while ((stringPtr = popArray((sArray*)&(*var)->init))) {
|
||||
free(stringPtr);
|
||||
}
|
||||
freeArray((sArray*)&(*var)->init);
|
||||
free(*var);
|
||||
*var = NULL;
|
||||
}
|
||||
|
||||
sInstruction *copyInstruction(const sInstruction *orig) {
|
||||
sInstruction *dup = (sInstruction*)malloc(sizeof(sInstruction));
|
||||
memcpy(dup, orig, sizeof(sInstruction));
|
||||
return dup;
|
||||
}
|
||||
|
||||
void initStatus(sCurStatus* curStatus, const char* code) {
|
||||
curStatus->status = ST_LINE_START;
|
||||
curStatus->arbVersion = 10; // Todo?
|
||||
curStatus->codePtr = code;
|
||||
curStatus->endOfToken = code;
|
||||
|
||||
curStatus->outputString = malloc(DEFAULT_STRING_MALLOC_SIZE);
|
||||
curStatus->outputString[0] = '\0';
|
||||
curStatus->outputEnd = curStatus->outputString;
|
||||
curStatus->outLen = 0;
|
||||
curStatus->outCap = DEFAULT_STRING_CAP;
|
||||
curStatus->outLeft = DEFAULT_STRING_CAP - 1;
|
||||
|
||||
curStatus->valueType = TYPE_NONE;
|
||||
|
||||
curStatus->texVars = (sVariable**)malloc(MAX_TEX * sizeof(sVariable*));
|
||||
for (size_t i = 0; i < MAX_TEX; ++i) {
|
||||
curStatus->texVars[i] = createVariable(VARTYPE_TEXTURE);
|
||||
}
|
||||
curStatus->tex1D = (sVariable*)malloc(sizeof(sVariable));
|
||||
curStatus->tex1D->type = VARTYPE_TEXTARGET;
|
||||
curStatus->tex2D = (sVariable*)malloc(sizeof(sVariable));
|
||||
curStatus->tex2D->type = VARTYPE_TEXTARGET;
|
||||
curStatus->tex3D = (sVariable*)malloc(sizeof(sVariable));
|
||||
curStatus->tex3D->type = VARTYPE_TEXTARGET;
|
||||
curStatus->texCUBE = (sVariable*)malloc(sizeof(sVariable));
|
||||
curStatus->texCUBE->type = VARTYPE_TEXTARGET;
|
||||
curStatus->texRECT = (sVariable*)malloc(sizeof(sVariable));
|
||||
curStatus->texRECT->type = VARTYPE_TEXTARGET;
|
||||
|
||||
curStatus->varsMap = kh_init(variables);
|
||||
initArray((sArray*)&curStatus->variables);
|
||||
initArray((sArray*)&curStatus->instructions);
|
||||
curStatus->fogType = FOG_NONE;
|
||||
|
||||
initArray((sArray*)&curStatus->_fixedNewVar);
|
||||
curStatus->_fixedNewVar.var = NULL;
|
||||
}
|
||||
|
||||
void freeStatus(sCurStatus* curStatus) {
|
||||
if (curStatus->valueType == TYPE_INST_DECL) {
|
||||
for (int i = 0; i < MAX_OPERANDS; ++i) {
|
||||
if (curStatus->curValue.newInst.inst.vars[i].floatArrAddr) {
|
||||
free(curStatus->curValue.newInst.inst.vars[i].floatArrAddr);
|
||||
}
|
||||
}
|
||||
} else if (curStatus->valueType == TYPE_VARIABLE_DECL) {
|
||||
char *strPtr;
|
||||
while ((strPtr = (char*)popArray((sArray*)&curStatus->curValue.newVar))) {
|
||||
free(strPtr);
|
||||
}
|
||||
freeArray((sArray*)&curStatus->curValue.newVar);
|
||||
|
||||
deleteVariable(&curStatus->curValue.newVar.var);
|
||||
} else if (curStatus->valueType == TYPE_ALIAS_DECL) {
|
||||
if (curStatus->curValue.string) {
|
||||
free(curStatus->curValue.string);
|
||||
}
|
||||
} else if (curStatus->valueType == TYPE_OPTION_DECL) {
|
||||
if (curStatus->curValue.newOpt.optName) {
|
||||
free(curStatus->curValue.newOpt.optName);
|
||||
}
|
||||
}
|
||||
curStatus->valueType = TYPE_NONE;
|
||||
|
||||
for (size_t i = 0; i < MAX_TEX; ++i) {
|
||||
deleteVariable(&curStatus->texVars[i]);
|
||||
}
|
||||
free(curStatus->texVars);
|
||||
free(curStatus->tex1D);
|
||||
free(curStatus->tex2D);
|
||||
free(curStatus->tex3D);
|
||||
free(curStatus->texCUBE);
|
||||
free(curStatus->texRECT);
|
||||
|
||||
kh_destroy(variables, curStatus->varsMap);
|
||||
|
||||
sVariable *varPtr;
|
||||
while ((varPtr = (sVariable*)popArray((sArray*)&curStatus->variables))) {
|
||||
deleteVariable(&varPtr);
|
||||
}
|
||||
sInstruction *instPtr;
|
||||
while ((instPtr = (sInstruction*)popArray((sArray*)&curStatus->instructions))) {
|
||||
for (int i = 0; i < MAX_OPERANDS; ++i) {
|
||||
if (instPtr->vars[i].floatArrAddr) {
|
||||
free(instPtr->vars[i].floatArrAddr);
|
||||
}
|
||||
}
|
||||
free(instPtr);
|
||||
}
|
||||
|
||||
freeArray((sArray*)&curStatus->variables);
|
||||
freeArray((sArray*)&curStatus->instructions);
|
||||
|
||||
freeArray((sArray*)&curStatus->_fixedNewVar);
|
||||
}
|
||||
|
||||
int appendString(sCurStatus *curStatusPtr, const char *str, size_t strLen) {
|
||||
if (strLen == (size_t)-1) {
|
||||
strLen = strlen(str);
|
||||
}
|
||||
|
||||
if (curStatusPtr->outLeft < strLen) {
|
||||
char *oldOut = curStatusPtr->outputString;
|
||||
while (curStatusPtr->outLeft < strLen) {
|
||||
if (curStatusPtr->outCap >= SIZE_THRESHOLD) {
|
||||
curStatusPtr->outLeft += SIZE_THRESHOLD * sizeof(char);
|
||||
} else {
|
||||
curStatusPtr->outLeft *= 2;
|
||||
}
|
||||
if (!resize((void**)&curStatusPtr->outputString, &curStatusPtr->outCap, sizeof(char))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
curStatusPtr->outputEnd += curStatusPtr->outputString - oldOut;
|
||||
}
|
||||
|
||||
ARBCONV_DBG_HEAVY(ARBCONV_DBG(
|
||||
char *dup = malloc((strLen + 1) * sizeof(char)); memcpy(dup, str, strLen); dup[strLen] = '\0'; printf(
|
||||
"Appending '%s' to %p (%p + %ld = %p)\n",
|
||||
dup,
|
||||
curStatusPtr->outputEnd,
|
||||
curStatusPtr->outputString,
|
||||
curStatusPtr->outLen,
|
||||
curStatusPtr->outputString + curStatusPtr->outLen
|
||||
); free(dup); fflush(stdout);)
|
||||
if (curStatusPtr->outputEnd != curStatusPtr->outputString + curStatusPtr->outLen) {
|
||||
printf("\033[01;31mERROR!!!\033[m\n%s\n", str);
|
||||
curStatusPtr->status = ST_ERROR;
|
||||
return 1;
|
||||
})
|
||||
|
||||
strcpy(curStatusPtr->outputEnd, str);
|
||||
curStatusPtr->outLen += strLen;
|
||||
curStatusPtr->outLeft -= strLen;
|
||||
curStatusPtr->outputEnd += strLen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
#ifndef _GL4ES_ARBHELPER_H_
|
||||
#define _GL4ES_ARBHELPER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "khash.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
|
||||
// ARBCONV_DBG - general ArbConverter debug logs
|
||||
#define ARBCONV_DBG(a) a
|
||||
// ARBCONV_DBG_LP - code loop ArbConverter debug logs
|
||||
#define ARBCONV_DBG_LP(a) a
|
||||
// ARBCONV_DBG_AS - reassembly loop (2nd loop) ArbConverter debug logs
|
||||
#define ARBCONV_DBG_AS(a) a
|
||||
// ARBCONV_DBG_HEAVY - heavy ArbConverter debug logs and operations (e.g. check for pointer correctness...)
|
||||
#define ARBCONV_DBG_HEAVY(a) a
|
||||
#else
|
||||
// ARBCONV_DBG - general ArbConverter debug logs
|
||||
#define ARBCONV_DBG(a)
|
||||
// ARBCONV_DBG_LP - code loop ArbConverter debug logs
|
||||
#define ARBCONV_DBG_LP(a)
|
||||
// ARBCONV_DBG_AS - reassembly loop (2nd loop) ArbConverter debug logs
|
||||
#define ARBCONV_DBG_AS(a)
|
||||
// ARBCONV_DBG_HEAVY - heavy ArbConverter debug logs and operations (e.g. check for pointer correctness...)
|
||||
#define ARBCONV_DBG_HEAVY(a)
|
||||
#endif
|
||||
|
||||
#ifdef MAX_TEX
|
||||
#if MAX_TEX != 16
|
||||
#error Please update the string
|
||||
#endif
|
||||
#define MAX_TEX_STR "16"
|
||||
#define MAX_TEX_STRLEN 2
|
||||
#endif
|
||||
|
||||
#define DEFAULT_MALLOC_COUNT 32
|
||||
#define DEFAULT_STRING_CAP 1024
|
||||
#define DEFAULT_STRING_MALLOC_SIZE (DEFAULT_STRING_CAP * sizeof(char))
|
||||
|
||||
void *resize(void** obj, size_t* cap, size_t esize);
|
||||
|
||||
typedef struct _sArray {
|
||||
void **objs; // Array of pointers
|
||||
size_t size;
|
||||
size_t cap;
|
||||
} sArray;
|
||||
|
||||
void initArray(sArray* arr);
|
||||
int pushArray(sArray* arr, void* obj);
|
||||
void* popArray(sArray* arr);
|
||||
void* popFIFO(sArray* arr);
|
||||
void freeArray(sArray* arr);
|
||||
|
||||
typedef enum _eVariableType {
|
||||
VARTYPE_ADDRESS = 0,
|
||||
VARTYPE_ATTRIB,
|
||||
VARTYPE_PARAM,
|
||||
VARTYPE_PARAM_MULT,
|
||||
VARTYPE_TEMP,
|
||||
VARTYPE_ALIAS,
|
||||
VARTYPE_OUTPUT,
|
||||
|
||||
VARTYPE_CONST, // Used when having an anonymous variable
|
||||
VARTYPE_TEXTURE, // Not available in vertex programs, fixed name in fragment programs
|
||||
VARTYPE_TEXTARGET, // Not available in vertex programs, fixed name in fragment programs
|
||||
VARTYPE_UNK
|
||||
} eVariableType;
|
||||
typedef enum _eInstruction {
|
||||
INST_ABS = 0, INST_ADD, INST_ARL, INST_CMP, INST_COS, INST_DP3, INST_DP4, INST_DPH,
|
||||
INST_DST, INST_EX2, INST_EXP, INST_FLR, INST_FRC, INST_KIL, INST_LG2, INST_LIT,
|
||||
INST_LOG, INST_LRP, INST_MAD, INST_MAX, INST_MIN, INST_MOV, INST_MUL, INST_POW,
|
||||
INST_RCP, INST_RSQ, INST_SCS, INST_SGE, INST_SIN, INST_SLT, INST_SUB, INST_SWZ,
|
||||
INST_TEX, INST_TXB, INST_TXP, INST_XPD,
|
||||
|
||||
INST_UNK
|
||||
} eInstruction;
|
||||
typedef enum _eStatus {
|
||||
ST_LINE_START = 0,
|
||||
|
||||
ST_LINE_COMMENT,
|
||||
|
||||
ST_VARIABLE,
|
||||
ST_VARIABLE_INIT,
|
||||
ST_ALIAS,
|
||||
ST_ALIASING,
|
||||
ST_INSTRUCTION,
|
||||
|
||||
ST_OPTION,
|
||||
|
||||
ST_DONE,
|
||||
ST_ERROR
|
||||
} eStatus;
|
||||
typedef enum _eToken {
|
||||
TOK_NULL = 0,
|
||||
|
||||
TOK_WHITESPACE,
|
||||
|
||||
TOK_SIGN,
|
||||
TOK_INTEGER,
|
||||
TOK_FLOATCONST,
|
||||
|
||||
TOK_IDENTIFIER,
|
||||
TOK_POINT,
|
||||
TOK_UPTO,
|
||||
TOK_COMMA,
|
||||
TOK_EQUALS,
|
||||
TOK_LSQBRACKET,
|
||||
TOK_RSQBRACKET,
|
||||
TOK_LBRACE,
|
||||
TOK_RBRACE,
|
||||
TOK_END_OF_INST,
|
||||
|
||||
TOK_LINE_COMMENT,
|
||||
|
||||
TOK_NEWLINE,
|
||||
|
||||
TOK_END,
|
||||
|
||||
TOK_UNKNOWN
|
||||
} eToken;
|
||||
|
||||
eVariableType STR2VARTYPE(char *str);
|
||||
eInstruction STR2INST(char *str, int *sat);
|
||||
#define INSTTEX(i) (((i) == INST_TEX) || ((i) == INST_TXB) || ((i) == INST_TXP))
|
||||
|
||||
#define ENUMVALUE2STR(v, e, v2) (v == e##v2) ? #v2 :
|
||||
#ifdef DEBUG
|
||||
#define VARTYPE2STR(vartype) ( \
|
||||
ENUMVALUE2STR(vartype, VARTYPE_,ADDRESS) \
|
||||
ENUMVALUE2STR(vartype, VARTYPE_,ATTRIB) \
|
||||
ENUMVALUE2STR(vartype, VARTYPE_,PARAM) \
|
||||
ENUMVALUE2STR(vartype, VARTYPE_,PARAM_MULT) \
|
||||
ENUMVALUE2STR(vartype, VARTYPE_,TEMP) \
|
||||
ENUMVALUE2STR(vartype, VARTYPE_,OUTPUT) \
|
||||
ENUMVALUE2STR(vartype, VARTYPE_,CONST) \
|
||||
"???")
|
||||
#define INST2STR(inst) ( \
|
||||
ENUMVALUE2STR(inst, INST_,ABS) ENUMVALUE2STR(inst, INST_,ADD) \
|
||||
ENUMVALUE2STR(inst, INST_,ARL) ENUMVALUE2STR(inst, INST_,CMP) \
|
||||
ENUMVALUE2STR(inst, INST_,COS) ENUMVALUE2STR(inst, INST_,DP3) \
|
||||
ENUMVALUE2STR(inst, INST_,DP4) ENUMVALUE2STR(inst, INST_,DPH) \
|
||||
ENUMVALUE2STR(inst, INST_,DST) ENUMVALUE2STR(inst, INST_,EX2) \
|
||||
ENUMVALUE2STR(inst, INST_,EXP) ENUMVALUE2STR(inst, INST_,FLR) \
|
||||
ENUMVALUE2STR(inst, INST_,FRC) ENUMVALUE2STR(inst, INST_,KIL) \
|
||||
ENUMVALUE2STR(inst, INST_,LG2) ENUMVALUE2STR(inst, INST_,LIT) \
|
||||
ENUMVALUE2STR(inst, INST_,LOG) ENUMVALUE2STR(inst, INST_,LRP) \
|
||||
ENUMVALUE2STR(inst, INST_,MAD) ENUMVALUE2STR(inst, INST_,MAX) \
|
||||
ENUMVALUE2STR(inst, INST_,MIN) ENUMVALUE2STR(inst, INST_,MOV) \
|
||||
ENUMVALUE2STR(inst, INST_,MUL) ENUMVALUE2STR(inst, INST_,POW) \
|
||||
ENUMVALUE2STR(inst, INST_,RCP) ENUMVALUE2STR(inst, INST_,RSQ) \
|
||||
ENUMVALUE2STR(inst, INST_,SCS) ENUMVALUE2STR(inst, INST_,SGE) \
|
||||
ENUMVALUE2STR(inst, INST_,SIN) ENUMVALUE2STR(inst, INST_,SLT) \
|
||||
ENUMVALUE2STR(inst, INST_,SUB) ENUMVALUE2STR(inst, INST_,SWZ) \
|
||||
ENUMVALUE2STR(inst, INST_,TEX) ENUMVALUE2STR(inst, INST_,TXB) \
|
||||
ENUMVALUE2STR(inst, INST_,TXP) ENUMVALUE2STR(inst, INST_,XPD) \
|
||||
"???")
|
||||
#define STATUS2STR(s) (\
|
||||
ENUMVALUE2STR(s, ST_,LINE_START) \
|
||||
ENUMVALUE2STR(s, ST_,LINE_COMMENT) \
|
||||
ENUMVALUE2STR(s, ST_,VARIABLE) \
|
||||
ENUMVALUE2STR(s, ST_,VARIABLE_INIT) \
|
||||
ENUMVALUE2STR(s, ST_,ALIAS) \
|
||||
ENUMVALUE2STR(s, ST_,ALIASING) \
|
||||
ENUMVALUE2STR(s, ST_,INSTRUCTION) \
|
||||
ENUMVALUE2STR(s, ST_,OPTION) \
|
||||
ENUMVALUE2STR(s, ST_,DONE) \
|
||||
ENUMVALUE2STR(s, ST_,ERROR) \
|
||||
"???")
|
||||
#endif
|
||||
#define TOKEN2STR(t) (\
|
||||
ENUMVALUE2STR(t, TOK_,NULL) \
|
||||
ENUMVALUE2STR(t, TOK_,WHITESPACE) \
|
||||
ENUMVALUE2STR(t, TOK_,SIGN) \
|
||||
ENUMVALUE2STR(t, TOK_,INTEGER) \
|
||||
ENUMVALUE2STR(t, TOK_,FLOATCONST) \
|
||||
ENUMVALUE2STR(t, TOK_,IDENTIFIER) \
|
||||
ENUMVALUE2STR(t, TOK_,POINT) \
|
||||
ENUMVALUE2STR(t, TOK_,UPTO) \
|
||||
ENUMVALUE2STR(t, TOK_,COMMA) \
|
||||
ENUMVALUE2STR(t, TOK_,EQUALS) \
|
||||
ENUMVALUE2STR(t, TOK_,LSQBRACKET) \
|
||||
ENUMVALUE2STR(t, TOK_,RSQBRACKET) \
|
||||
ENUMVALUE2STR(t, TOK_,LBRACE) \
|
||||
ENUMVALUE2STR(t, TOK_,RBRACE) \
|
||||
ENUMVALUE2STR(t, TOK_,END_OF_INST) \
|
||||
ENUMVALUE2STR(t, TOK_,LINE_COMMENT) \
|
||||
ENUMVALUE2STR(t, TOK_,NEWLINE) \
|
||||
ENUMVALUE2STR(t, TOK_,END) \
|
||||
ENUMVALUE2STR(t, TOK_,UNKNOWN) \
|
||||
"???")
|
||||
|
||||
typedef struct _sVariableInit { // sArray manipulable
|
||||
char **strings;
|
||||
size_t strings_count;
|
||||
size_t strings_cap;
|
||||
|
||||
size_t strings_total_len;
|
||||
} sVariableInit;
|
||||
typedef struct _sVariable { // sArray manipulable
|
||||
char **names;
|
||||
size_t names_count;
|
||||
size_t names_cap;
|
||||
|
||||
eVariableType type;
|
||||
|
||||
sVariableInit init;
|
||||
int size; // Optional (VARTYPE_PARAM_MULT)
|
||||
} sVariable;
|
||||
typedef struct _sVariables {
|
||||
sVariable **vars;
|
||||
size_t size;
|
||||
size_t cap;
|
||||
} sVariables;
|
||||
|
||||
sVariable *createVariable(eVariableType type);
|
||||
void deleteVariable(sVariable **var);
|
||||
|
||||
KHASH_MAP_DECLARE_STR(variables, sVariable*)
|
||||
#define kh_truly_exist(h, i) ((i < kh_end(h)) && kh_exist(h, i))
|
||||
#define kh_str_exist(h, s) kh_truly_exist(h, kh_get(variables, h, s))
|
||||
|
||||
#define MAX_OPERANDS 4
|
||||
typedef struct _sInstruction {
|
||||
eInstruction type;
|
||||
int saturated;
|
||||
|
||||
struct _sInstruction_Vars {
|
||||
sVariable *var;
|
||||
|
||||
char *floatArrAddr;
|
||||
int sign;
|
||||
enum {
|
||||
SWIZ_NONE = 0, SWIZ_X, SWIZ_Y, SWIZ_Z, SWIZ_W
|
||||
} swizzle[4];
|
||||
} vars[MAX_OPERANDS];
|
||||
|
||||
const char *codeLocation;
|
||||
} sInstruction;
|
||||
typedef struct _sInstruction_Vars sInstruction_Vars;
|
||||
typedef struct _sInstructions {
|
||||
sInstruction **insts;
|
||||
size_t size;
|
||||
size_t cap;
|
||||
} sInstructions;
|
||||
|
||||
sInstruction *copyInstruction(const sInstruction *orig);
|
||||
|
||||
typedef struct _sCurStatus_NewInst {
|
||||
sInstruction inst; // duplicateInstruction(&newInst);
|
||||
unsigned int curArg;
|
||||
int state; // Dependant on variable type and current status
|
||||
} sCurStatus_NewInst;
|
||||
typedef struct _sCurStatus_NewVar { // sArray manipulable
|
||||
char **strParts; // copyToken();
|
||||
size_t strLen;
|
||||
size_t strCap;
|
||||
|
||||
sVariable *var; // createVariable();
|
||||
int state; // Dependant on variable type and current status
|
||||
} sCurStatus_NewVar;
|
||||
typedef struct _sCurStatus_NewOpt {
|
||||
char *optName;
|
||||
} sCurStatus_NewOpt;
|
||||
typedef struct _sCurStatus {
|
||||
eStatus status;
|
||||
|
||||
int arbVersion;
|
||||
|
||||
const char *codePtr;
|
||||
|
||||
const char *endOfToken;
|
||||
eToken curToken;
|
||||
unsigned int tokInt;
|
||||
float tokFloat;
|
||||
|
||||
char *outputString;
|
||||
char *outputEnd;
|
||||
size_t outLen;
|
||||
size_t outCap;
|
||||
size_t outLeft;
|
||||
|
||||
enum {
|
||||
TYPE_NONE, TYPE_INST_DECL, TYPE_VARIABLE_DECL, TYPE_ALIAS_DECL, TYPE_OPTION_DECL
|
||||
} valueType;
|
||||
union {
|
||||
sCurStatus_NewInst newInst;
|
||||
sCurStatus_NewVar newVar;
|
||||
char *string; // getToken();
|
||||
sCurStatus_NewOpt newOpt;
|
||||
} curValue;
|
||||
|
||||
sCurStatus_NewVar _fixedNewVar;
|
||||
|
||||
sVariable **texVars;
|
||||
sVariable *tex1D;
|
||||
sVariable *tex2D;
|
||||
sVariable *tex3D;
|
||||
sVariable *texCUBE;
|
||||
sVariable *texRECT;
|
||||
|
||||
khash_t(variables) *varsMap;
|
||||
sVariables variables;
|
||||
sInstructions instructions;
|
||||
enum { FOG_NONE, FOG_EXP, FOG_EXP2, FOG_LINEAR } fogType;
|
||||
int position_invariant;
|
||||
} sCurStatus;
|
||||
|
||||
void initStatus(sCurStatus* curStatus, const char* code);
|
||||
void freeStatus(sCurStatus* curStatus);
|
||||
|
||||
int appendString(sCurStatus *curStatusPtr, const char *str, size_t strLen);
|
||||
|
||||
|
||||
#endif // _GL4ES_ARBHELPER_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
#ifndef _GL4ES_ARBPARSER_H_
|
||||
#define _GL4ES_ARBPARSER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "arbhelper.h"
|
||||
|
||||
struct sSpecialCases {
|
||||
int hasFogFragCoord;
|
||||
int isDepthReplacing;
|
||||
};
|
||||
|
||||
eToken readNextToken(sCurStatus* curStatus);
|
||||
void parseToken(sCurStatus *curStatus, int vertex, char **error_msg, struct sSpecialCases *hasFogFragCoord);
|
||||
|
||||
#endif // _GL4ES_ARBPARSER_H_
|
||||
@@ -0,0 +1,508 @@
|
||||
#include "array.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "enum_info.h"
|
||||
#include "glcase.h"
|
||||
#include "light.h"
|
||||
#include "state.h"
|
||||
|
||||
GLvoid *copy_gl_array(const GLvoid *src,
|
||||
GLenum from, GLsizei width, GLsizei stride,
|
||||
GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, void* dst) {
|
||||
if (! src || !count)
|
||||
return NULL;
|
||||
|
||||
if (! stride)
|
||||
stride = width * gl_sizeof(from);
|
||||
|
||||
const char *unknown_str = "LIBGL: copy_gl_array -> unknown type: %x\n";
|
||||
if(!dst) {
|
||||
dst = malloc((count-skip) * to_width * gl_sizeof(to));
|
||||
}
|
||||
GLsizei from_size = gl_sizeof(from) * width;
|
||||
if (to_width < width) {
|
||||
/* printf("Warning: copy_gl_array: %i < %i\n", to_width, width);
|
||||
return NULL;*/
|
||||
width = to_width;
|
||||
}
|
||||
// quick path if just copying same to same and no specific stride involved
|
||||
if(stride == (to_width*gl_sizeof(to)) && width==to_width && from==to) {
|
||||
memcpy(dst, (char*)src + stride*skip, (count-skip) * to_width * gl_sizeof(to));
|
||||
return dst;
|
||||
}
|
||||
|
||||
// if stride is weird, we need to be able to arbitrarily shift src
|
||||
// so we leave it in a uintptr_t and cast after incrementing
|
||||
uintptr_t in = (uintptr_t)src;
|
||||
in += stride*skip;
|
||||
if (from == to && to_width >= width) {
|
||||
GL_TYPE_SWITCH(out, dst, to,
|
||||
for (int i = skip; i < count; i++) {
|
||||
memcpy(out, (GLvoid *)in, from_size);
|
||||
for (int j = width; j < to_width; j++) {
|
||||
out[j] = 0;
|
||||
}
|
||||
out += to_width;
|
||||
in += stride;
|
||||
},
|
||||
default:
|
||||
printf(unknown_str, from);
|
||||
return NULL;
|
||||
)
|
||||
} else {
|
||||
GL_TYPE_SWITCH(out, dst, to,
|
||||
for (int i = skip; i < count; i++) {
|
||||
GL_TYPE_SWITCH(input, in, from,
|
||||
for (int j = 0; j < width; j++) {
|
||||
out[j] = input[j];
|
||||
}
|
||||
for (int j = width; j < to_width; j++) {
|
||||
out[j] = 0;
|
||||
}
|
||||
out += to_width;
|
||||
in += stride;
|
||||
,
|
||||
default:
|
||||
printf(unknown_str, from);
|
||||
return NULL;
|
||||
)
|
||||
},
|
||||
default:
|
||||
printf(unknown_str, to);
|
||||
return NULL;
|
||||
)
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
GLvoid *copy_gl_array_texcoord(const GLvoid *src,
|
||||
GLenum from, GLsizei width, GLsizei stride,
|
||||
GLsizei to_width, GLsizei skip, GLsizei count, void* dst) {
|
||||
if (! src || !count)
|
||||
return NULL;
|
||||
|
||||
if (! stride)
|
||||
stride = width * gl_sizeof(from);
|
||||
|
||||
static const char *unknown_str = "LIBGL: copy_gl_array -> unknown type: %x\n";
|
||||
if(!dst)
|
||||
dst = malloc((count-skip) * to_width * gl_sizeof(GL_FLOAT));
|
||||
GLsizei from_size = gl_sizeof(from) * width;
|
||||
GLsizei to_elem = gl_sizeof(GL_FLOAT);
|
||||
uintptr_t in = (uintptr_t)src;
|
||||
in += stride*skip;
|
||||
GLfloat* out = (GLfloat*)dst;
|
||||
if (from == GL_FLOAT && to_width >= width) {
|
||||
for (int i = skip; i < count; i++) {
|
||||
GLfloat* input = (GLfloat*)in;
|
||||
//memcpy(out, (GLvoid *)in, from_size); // which one is faster ?
|
||||
for (int j = 0; j < width; j++) {
|
||||
out[j] = input[j];
|
||||
}
|
||||
for (int j = width; j < to_width; j++) {
|
||||
if(j==3)
|
||||
out[j] = 1.0f;
|
||||
else
|
||||
out[j] = 0.0f;
|
||||
}
|
||||
out += to_width;
|
||||
in += stride;
|
||||
}
|
||||
} else {
|
||||
for (int i = skip; i < count; i++) {
|
||||
GL_TYPE_SWITCH(input, in, from,
|
||||
for (int j = 0; j < width; j++) {
|
||||
out[j] = input[j];
|
||||
}
|
||||
for (int j = width; j < to_width; j++) {
|
||||
if(j==3)
|
||||
out[j] = 1.0f;
|
||||
else
|
||||
out[j] = 0.0f;
|
||||
}
|
||||
out += to_width;
|
||||
in += stride;
|
||||
,
|
||||
default:
|
||||
printf(unknown_str, from);
|
||||
return NULL;
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
GLvoid *copy_gl_array_quickconvert(const GLvoid *src,
|
||||
GLenum from, GLsizei stride,
|
||||
GLsizei skip, GLsizei count, void* dest) {
|
||||
|
||||
if (! stride)
|
||||
stride = 4 * gl_sizeof(from);
|
||||
const char *unknown_str = "LIBGL: copy_gl_array_quickconvert -> unknown type: %x\n";
|
||||
GLvoid *dst = (dest)?dest:malloc((count-skip) * 4 * gl_sizeof(GL_FLOAT));
|
||||
|
||||
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, void* dst) {
|
||||
if (! src || !count)
|
||||
return NULL;
|
||||
|
||||
if (! stride)
|
||||
stride = width * gl_sizeof(from);
|
||||
GLsizei from_size = gl_sizeof(from) * width;
|
||||
|
||||
if(to==from && width==to_width && stride==(to_width * gl_sizeof(to))) {
|
||||
if(!dst) dst = malloc((count-skip) * stride);
|
||||
memcpy(dst, (char*)src+stride*skip, (count-skip)*stride);
|
||||
return dst;
|
||||
}
|
||||
|
||||
if(to==GL_FLOAT && width==to_width && width==4)
|
||||
return copy_gl_array_quickconvert(src, from, stride, skip, count, dst);
|
||||
if(to==GL_FLOAT && from==GL_FLOAT)
|
||||
if(width<4 || *(GLfloat*)filler==1.0f) // no need to convert
|
||||
return copy_gl_array_texcoord(src, from, width, stride, to_width, skip, count, dst);
|
||||
else
|
||||
return copy_gl_array(src, from, width, stride, to, to_width, skip, count, dst);
|
||||
|
||||
const char *unknown_str = "LIBGL: copy_gl_array_convert -> unknown type: %x\n";
|
||||
if(!dst) dst = malloc((count-skip) * to_width * gl_sizeof(to));
|
||||
if (to_width < width) {
|
||||
/*printf("Warning: copy_gl_array: %i < %i\n", to_width, width);
|
||||
return NULL;*/
|
||||
width = to_width;
|
||||
}
|
||||
|
||||
// if stride is weird, we need to be able to arbitrarily shift src
|
||||
// so we leave it in a uintptr_t and cast after incrementing
|
||||
uintptr_t in = (uintptr_t)src;
|
||||
in += stride*skip;
|
||||
int j;
|
||||
if (from == to && to_width >= width) {
|
||||
GL_TYPE_SWITCH(out, dst, to,
|
||||
for (int i = skip; i < count; i++) {
|
||||
memcpy(out, (GLvoid *)in, from_size);
|
||||
for (j = width; j < to_width-1; j++) {
|
||||
out[j]=0;
|
||||
}
|
||||
for (; j < to_width; j++) {
|
||||
memcpy(&out[j], filler, gl_sizeof(to));
|
||||
}
|
||||
out += to_width;
|
||||
in += stride;
|
||||
},
|
||||
default:
|
||||
printf(unknown_str, from);
|
||||
return NULL;
|
||||
)
|
||||
} else {
|
||||
GL_TYPE_SWITCH_MAX(out, dst, to,
|
||||
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/maxf;
|
||||
}
|
||||
for (; j < to_width-1; j++) {
|
||||
out[j]=0;
|
||||
}
|
||||
for (; j < to_width; j++) {
|
||||
memcpy(&out[j], filler, gl_sizeof(to));
|
||||
}
|
||||
out += to_width;
|
||||
in += stride;
|
||||
,
|
||||
default:
|
||||
printf(unknown_str, from);
|
||||
return NULL;
|
||||
),
|
||||
default:
|
||||
printf(unknown_str, to);
|
||||
return NULL;
|
||||
)
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
GLvoid *copy_gl_pointer(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
float filler = 0.0f;
|
||||
return copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride,
|
||||
GL_FLOAT, width, skip, count, &filler, NULL);
|
||||
}
|
||||
GLvoid *copy_gl_pointer_color(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
float filler = 1.0f;
|
||||
return copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride,
|
||||
GL_FLOAT, width, skip, count, &filler, NULL);
|
||||
}
|
||||
GLvoid *copy_gl_pointer_bytecolor(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
GLubyte filler = 255;
|
||||
return copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride,
|
||||
GL_UNSIGNED_BYTE, width, skip, count, &filler, NULL);
|
||||
}
|
||||
|
||||
GLvoid *copy_gl_pointer_raw(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
return copy_gl_array((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride,
|
||||
GL_FLOAT, width, skip, count, NULL);
|
||||
}
|
||||
|
||||
GLvoid *copy_gl_pointer_tex(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
//float filler = 1.0f;
|
||||
return copy_gl_array_texcoord((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride,
|
||||
/*GL_FLOAT,*/ width, skip, count, /*&filler,*/ NULL);
|
||||
}
|
||||
|
||||
void copy_gl_pointer_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
float filler = 0.0f;
|
||||
copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride,
|
||||
GL_FLOAT, width, skip, count, &filler, dest);
|
||||
}
|
||||
void copy_gl_pointer_color_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
float filler = 1.0f;
|
||||
copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride,
|
||||
GL_FLOAT, width, skip, count, &filler, dest);
|
||||
}
|
||||
void copy_gl_pointer_bytecolor_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
GLubyte filler = 255;
|
||||
copy_gl_array_convert((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride,
|
||||
GL_UNSIGNED_BYTE, width, skip, count, &filler, dest);
|
||||
}
|
||||
void copy_gl_pointer_raw_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
copy_gl_array((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride,
|
||||
GL_FLOAT, width, skip, count, dest);
|
||||
}
|
||||
void copy_gl_pointer_tex_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
//float filler = 1.0f;
|
||||
copy_gl_array_texcoord((const GLvoid*)((uintptr_t)ptr->pointer+(uintptr_t)ptr->real_pointer), ptr->type, ptr->size, ptr->stride,
|
||||
/*GL_FLOAT,*/ width, skip, count, /*&filler,*/ dest);
|
||||
}
|
||||
|
||||
GLfloat *gl_pointer_index(vertexattrib_t *p, GLint index) {
|
||||
static GLfloat buf[4];
|
||||
GLsizei size = gl_sizeof(p->type);
|
||||
GLsizei stride = p->stride ? p->stride : (size * p->size);
|
||||
uintptr_t ptr = (uintptr_t)p->pointer+(uintptr_t)p->real_pointer + (stride * index);
|
||||
|
||||
GL_TYPE_SWITCH(src, ptr, p->type,
|
||||
for (int i = 0; i < p->size; i++) {
|
||||
buf[i] = src[i];
|
||||
}
|
||||
// zero anything not set by the pointer
|
||||
for (int i = p->size; i < 4; i++) {
|
||||
buf[i] = 0;
|
||||
},
|
||||
default:
|
||||
printf("LIBGL: unknown pointer type: 0x%x\n", p->type);
|
||||
)
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
GLfloat *copy_eval_double1(GLenum target, GLint ustride, GLint uorder,
|
||||
const GLdouble *src) {
|
||||
|
||||
GLsizei width = get_map_width(target);
|
||||
GLfloat* out;
|
||||
|
||||
if(!src || !width)
|
||||
return NULL;
|
||||
|
||||
out = malloc(uorder*width*sizeof(GLfloat));
|
||||
|
||||
GLfloat *p = out;
|
||||
|
||||
for (int i=0; i<uorder; i++, src+=ustride)
|
||||
for (int k=0; k<width; k++)
|
||||
*p++ = src[k];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
GLfloat *copy_eval_float1(GLenum target, GLint ustride, GLint uorder,
|
||||
const GLfloat *src) {
|
||||
|
||||
GLsizei width = get_map_width(target);
|
||||
GLfloat* out;
|
||||
|
||||
if(!src || !width)
|
||||
return NULL;
|
||||
|
||||
out = malloc(uorder*width*sizeof(GLfloat));
|
||||
|
||||
GLfloat *p = out;
|
||||
|
||||
for (int i=0; i<uorder; i++, src+=ustride)
|
||||
for (int k=0; k<width; k++)
|
||||
*p++ = src[k];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
GLfloat *copy_eval_double2(GLenum target, GLint ustride, GLint uorder,
|
||||
GLint vstride, GLint vorder,
|
||||
const GLdouble *src) {
|
||||
/* Additional memory is allocated to be used by the horner and
|
||||
* de Casteljau evaluation schemes.*/
|
||||
GLsizei width = get_map_width(target);
|
||||
GLfloat* out;
|
||||
|
||||
if(!src || !width)
|
||||
return NULL;
|
||||
|
||||
int dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
|
||||
int hsize = (uorder > vorder ? uorder : vorder)*width;
|
||||
|
||||
if(hsize>dsize)
|
||||
out = malloc((uorder*vorder*width+hsize)*sizeof(GLfloat));
|
||||
else
|
||||
out = malloc((uorder*vorder*width+dsize)*sizeof(GLfloat));
|
||||
|
||||
int uinc = ustride - vorder*vstride;
|
||||
GLfloat* p = out;
|
||||
|
||||
for (int i=0; i<uorder; i++, src += uinc)
|
||||
for (int j=0; j<vorder; j++, src += vstride)
|
||||
for (int k=0; k<width; k++)
|
||||
*p++ = src[k];
|
||||
|
||||
return out;
|
||||
}
|
||||
GLfloat *copy_eval_float2(GLenum target, GLint ustride, GLint uorder,
|
||||
GLint vstride, GLint vorder,
|
||||
const GLfloat *src) {
|
||||
/* Additional memory is allocated to be used by the horner and
|
||||
* de Casteljau evaluation schemes.*/
|
||||
GLsizei width = get_map_width(target);
|
||||
GLfloat* out;
|
||||
|
||||
if(!src || !width)
|
||||
return NULL;
|
||||
|
||||
int dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
|
||||
int hsize = (uorder > vorder ? uorder : vorder)*width;
|
||||
|
||||
if(hsize>dsize)
|
||||
out = malloc((uorder*vorder*width+hsize)*sizeof(GLfloat));
|
||||
else
|
||||
out = malloc((uorder*vorder*width+dsize)*sizeof(GLfloat));
|
||||
|
||||
int uinc = ustride - vorder*vstride;
|
||||
GLfloat* p = out;
|
||||
|
||||
for (int i=0; i<uorder; i++, src += uinc)
|
||||
for (int j=0; j<vorder; j++, src += vstride)
|
||||
for (int k=0; k<width; k++)
|
||||
*p++ = src[k];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void getminmax_indices_us(const GLushort *indices, GLsizei *max, GLsizei *min, GLsizei count) {
|
||||
if (!count) return;
|
||||
*max = indices[0];
|
||||
*min = indices[0];
|
||||
for (int i = 1; i < count; i++) {
|
||||
GLsizei n = indices[i];
|
||||
if( n < *min) *min = n;
|
||||
if (n > *max) *max = n;
|
||||
}
|
||||
}
|
||||
void normalize_indices_us(GLushort *indices, GLsizei *max, GLsizei *min, GLsizei count) {
|
||||
getminmax_indices_us(indices, max, min, count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
indices[i] -= *min;
|
||||
}
|
||||
}
|
||||
|
||||
void getminmax_indices_ui(const GLuint *indices, GLsizei *max, GLsizei *min, GLsizei count) {
|
||||
if (!count) return;
|
||||
*max = indices[0];
|
||||
*min = indices[0];
|
||||
for (int i = 1; i < count; i++) {
|
||||
GLsizei n = indices[i];
|
||||
if( n < *min) *min = n;
|
||||
if (n > *max) *max = n;
|
||||
}
|
||||
}
|
||||
void normalize_indices_ui(GLuint *indices, GLsizei *max, GLsizei *min, GLsizei count) {
|
||||
getminmax_indices_ui(indices, max, min, count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
indices[i] -= *min;
|
||||
}
|
||||
}
|
||||
|
||||
void *copy_gl_array_bgra(void* dest, const void *ptr, GLint stride, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
// this one only convert from BGRA (unsigned byte) to RGBA FLOAT
|
||||
GLubyte* src = (GLubyte*)ptr;
|
||||
|
||||
if (! src || !(count-skip))
|
||||
return NULL;
|
||||
|
||||
if (! stride)
|
||||
stride = 4;
|
||||
|
||||
if(!dest)
|
||||
dest = malloc(4*sizeof(GLfloat)*(count-skip));
|
||||
GLfloat* dst = dest;
|
||||
src += skip*(stride);
|
||||
|
||||
static const float d = 1.0f/255.0f;
|
||||
for (int i=skip; i<count; i++) {
|
||||
#if defined(__ARM_NEON__) && !defined(__APPLE__)
|
||||
int lsrc = *(int*)src;
|
||||
lsrc = (lsrc&0xff00ff00) | ((lsrc&0x00ff0000)>>16) | ((lsrc&0x000000ff)<<16);
|
||||
asm volatile (
|
||||
"vmov s12, %1 \n\t" // because you cannot vmovl.u8 d6, s11
|
||||
"vmovl.u8 q3, d6 \n\t" // Expand to 16-bit (so unsetuped s13 is expanded in d7)
|
||||
"vmovl.u16 q3, d6 \n\t" // Expand to 32-bit, ignoring expanded d7
|
||||
"vcvt.f32.u32 q3, q3 \n\t" // Convert to float
|
||||
"vmul.f32 q3, q3, %y2 \n\t" // Normalize
|
||||
"vst1.f32 {q3}, [%0]! \n\t" // Store, next
|
||||
:"+r"(dst) :"r"(lsrc), "w"(d)
|
||||
: "q3", "memory"
|
||||
);
|
||||
#else
|
||||
const GLubyte b = src[0], g = src[1], r = src[2], a = src[3];
|
||||
*dst++ = r*d;
|
||||
*dst++ = g*d;
|
||||
*dst++ = b*d;
|
||||
*dst++ = a*d;
|
||||
#endif
|
||||
src+=stride;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
GLvoid *copy_gl_pointer_color_bgra(const void *ptr, GLint stride, GLsizei width, GLsizei skip, GLsizei count) {
|
||||
return copy_gl_array_bgra(NULL, ptr, stride, width, skip, count);
|
||||
}
|
||||
|
||||
void copy_gl_pointer_color_bgra_noalloc(void* dest, const void *ptr, GLint stride, GLsizei width, GLsizei skip, GLsizei count)
|
||||
{
|
||||
copy_gl_array_bgra(dest, ptr, stride, width, skip, count);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef _GL4ES_ARRAY_H_
|
||||
#define _GL4ES_ARRAY_H_
|
||||
|
||||
#include "buffers.h"
|
||||
#include "gles.h"
|
||||
|
||||
GLvoid *copy_gl_array(const GLvoid *src,
|
||||
GLenum from, GLsizei width, GLsizei stride,
|
||||
GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, void* 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, void* dst);
|
||||
|
||||
GLvoid *copy_gl_pointer(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
|
||||
GLvoid *copy_gl_pointer_color(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
|
||||
GLvoid *copy_gl_pointer_color_bgra(const void *ptr, GLint stride, GLsizei width, GLsizei skip, GLsizei count);
|
||||
GLvoid *copy_gl_pointer_bytecolor(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
|
||||
GLvoid *copy_gl_pointer_raw(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
|
||||
GLvoid *copy_gl_pointer_tex(vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
|
||||
void copy_gl_pointer_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
|
||||
void copy_gl_pointer_color_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
|
||||
void copy_gl_pointer_color_bgra_noalloc(void* dest, const void *ptr, GLint stride, GLsizei width, GLsizei skip, GLsizei count);
|
||||
void copy_gl_pointer_bytecolor_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
|
||||
void copy_gl_pointer_raw_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
|
||||
void copy_gl_pointer_tex_noalloc(void* dest, vertexattrib_t *ptr, GLsizei width, GLsizei skip, GLsizei count);
|
||||
GLfloat *gl_pointer_index(vertexattrib_t *ptr, GLint index);
|
||||
void normalize_indices_us(GLushort *indices, GLsizei *max, GLsizei *min, GLsizei count);
|
||||
void getminmax_indices_us(const GLushort *indices, GLsizei *max, GLsizei *min, GLsizei count);
|
||||
void normalize_indices_ui(GLuint *indices, GLsizei *max, GLsizei *min, GLsizei count);
|
||||
void getminmax_indices_ui(const GLuint *indices, GLsizei *max, GLsizei *min, GLsizei count);
|
||||
|
||||
GLfloat *copy_eval_double1(GLenum target, GLint ustride, GLint uorder, const GLdouble *points);
|
||||
GLfloat *copy_eval_float1(GLenum target, GLint ustride, GLint uorder, const GLfloat *points);
|
||||
GLfloat *copy_eval_double2(GLenum target, GLint ustride, GLint uorder, GLint vstride, GLint vorder, const GLdouble *points);
|
||||
GLfloat *copy_eval_float2(GLenum target, GLint ustride, GLint uorder, GLint vstride, GLint vorder, const GLfloat *points);
|
||||
|
||||
#endif // _GL4ES_ARRAY_H_
|
||||
@@ -0,0 +1,189 @@
|
||||
#ifndef _GL4ES_ATTRIBUTES_H_
|
||||
#define _GL4ES_ATTRIBUTES_H_
|
||||
|
||||
#ifndef EXPORT
|
||||
#if defined(__EMSCRIPTEN__) || defined(__APPLE__)
|
||||
#define EXPORT
|
||||
#elif defined(STATICLIB)
|
||||
#define EXPORT
|
||||
#elif defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#elif defined(__GNUC__)
|
||||
#define EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
#endif // EXPORT
|
||||
|
||||
#ifndef _STR
|
||||
#define _STR(n) #n
|
||||
#endif
|
||||
#ifndef _MNG
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
#ifdef _MSC_VER
|
||||
#define _MNG(NAME,SUF) "_" _STR(NAME) "@" SUF
|
||||
#elif defined(__GNUC__)
|
||||
#define _MNG(NAME,SUF) _STR(NAME) "@" SUF
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _MNG
|
||||
#define _STM(NAME,DEF) _MNG(NAME,_VCR(_SUF1 DEF))
|
||||
#define _SUFF(...) _VCR(_SUF1 __VA_ARGS__)
|
||||
#define _SU2F(...) _VCR(_SUF2 __VA_ARGS__)
|
||||
#define _S2F1(...) _VCR(_SU21 __VA_ARGS__)
|
||||
#define _SUF1(...) \
|
||||
_VCS(_SUFS,(0,##__VA_ARGS__,100,96,92,88,84,80,76,72,68,64,60,56,52,\
|
||||
48,44,40,36,32,28,24,20,16,12,8,4,0))
|
||||
#define _SUF2(...) \
|
||||
_VCS(_SUFS,(0,##__VA_ARGS__,200,192,184,176,168,160,152,144,136,128,120,\
|
||||
112,104,96,88,80,72,64,56,48,40,32,24,16,8,0))
|
||||
#define _SU21(...) \
|
||||
_VCS(_SUFS,(0,##__VA_ARGS__,196,188,180,172,164,156,148,140,132,124,116,\
|
||||
108,100,92,84,76,68,60,52,44,36,28,20,12,4))
|
||||
#define _SUFS(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,\
|
||||
a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,\
|
||||
a20,a21,a22,a23,a24,a25,n,...) #n
|
||||
#define _VCS(a,b) a b
|
||||
#define _VCR(n) n
|
||||
#endif
|
||||
#endif
|
||||
#ifndef _MNG
|
||||
#define _MNG(NAME,SUF) _STR(NAME)
|
||||
#define _STM(NAME,DEF) _STR(NAME)
|
||||
#endif
|
||||
|
||||
#ifndef AliasDecl
|
||||
#ifdef __GNUC__
|
||||
#define AliasDecl(RET,NAME,DEF,OLD) \
|
||||
RET APIENTRY_GL4ES NAME DEF __attribute__((alias(_STM(OLD,DEF))))
|
||||
#elif defined(_MSC_VER)
|
||||
#define AliasDecl(RET,NAME,DEF,OLD) \
|
||||
__pragma(comment(linker, "/ALTERNATENAME:" _STM(NAME,DEF) "=" _STM(OLD,DEF))) \
|
||||
RET APIENTRY_GL4ES NAME DEF
|
||||
#else
|
||||
#define AliasDecl(RET,NAME,DEF,OLD) \
|
||||
RET APIENTRY_GL4ES NAME DEF
|
||||
#endif
|
||||
#endif // AliasDecl
|
||||
|
||||
#ifndef AliasExport
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(__APPLE__)
|
||||
#ifdef __GNUC__
|
||||
#define _AliasExport_(RET,ENM,DEF,INM,SUF) EXPORT \
|
||||
RET APIENTRY_GL4ES ENM DEF __attribute__((alias(_MNG(gl4es_##INM,SUF))))
|
||||
#define NonAliasExportDecl(RET,NAME,DEF) EXPORT \
|
||||
RET APIENTRY_GL4ES NAME DEF
|
||||
#elif defined(_MSC_VER)
|
||||
#define _DIR(DIR,ENM,INM,OP) \
|
||||
__pragma(comment(linker, "/" DIR ":" ENM OP INM))
|
||||
#ifdef STATICLIB
|
||||
#define _EXP(ENM,SUF)
|
||||
#elif !defined(_WIN64) && (_MSC_VER >= 1911 || defined(LINK_ULINK))
|
||||
#define _EXP(ENM,SUF) _DIR("EXPORT",_MNG(ENM,SUF),_STR(ENM),",exportas,")
|
||||
#else
|
||||
#ifndef _WIN64
|
||||
/* Unfortunatelly, old MS-link can create undecorated dll-names
|
||||
* with decorated library names only when use DEF-file.
|
||||
* Create stdcall-alias.*/
|
||||
#define _DOPEXP(ENM,SUF) _DIR("EXPORT",_MNG(ENM,SUF),,)
|
||||
#else
|
||||
#define _DOPEXP(ENM,SUF)
|
||||
#endif
|
||||
#define _EXP(ENM,SUF) _DIR("EXPORT",_STR(ENM),_MNG(ENM,SUF),"=") \
|
||||
_DOPEXP(ENM,SUF)
|
||||
#endif
|
||||
#define _DECL(ENM,INM,SUF) \
|
||||
_EXP(ENM,SUF) _DIR("ALTERNATENAME",_MNG(ENM,SUF),_MNG(INM,SUF), "=")
|
||||
#define _AliasExport_(RET,ENM,DEF,INM,SUF) _DECL(ENM,gl4es_##INM,SUF) \
|
||||
RET APIENTRY_GL4ES ENM DEF
|
||||
#define NonAliasExportDecl(RET,NAME,DEF) _EXP(NAME,_SUFF(DEF)) \
|
||||
RET APIENTRY_GL4ES NAME DEF
|
||||
#endif
|
||||
#define AliasExport(RET,NAME,X,DEF) \
|
||||
_AliasExport_(RET,NAME##X,DEF,NAME,_SUFF(DEF))
|
||||
#define AliasExport_A(RET,NAME,X,DEF,INM) \
|
||||
_AliasExport_(RET,NAME##X,DEF,INM,_SUFF(DEF))
|
||||
#define AliasExport_D(RET,NAME,X,DEF) \
|
||||
_AliasExport_(RET,NAME##X,DEF,NAME,_SU2F(DEF))
|
||||
#define AliasExport_D_1(RET,NAME,X,DEF) \
|
||||
_AliasExport_(RET,NAME##X,DEF,NAME,_S2F1(DEF))
|
||||
#define AliasExport_M(RET,NAME,X,DEF,SUF) \
|
||||
_AliasExport_(RET,NAME##X,DEF,NAME,_STR(SUF))
|
||||
#define AliasExport_V(RET,NAME) \
|
||||
_AliasExport_(RET,NAME,(void),NAME,"0")
|
||||
#endif
|
||||
#ifndef _AliasExport_
|
||||
#define AliasExport(RET,NAME,X,DEF) RET NAME##X DEF
|
||||
#define AliasExport_A(RET,NAME,X,DEF,INM) AliasExport(RET,NAME,X,DEF)
|
||||
#define AliasExport_D(RET,NAME,X,DEF) AliasExport(RET,NAME,X,DEF)
|
||||
#define AliasExport_D_1(RET,NAME,X,DEF) AliasExport(RET,NAME,X,DEF)
|
||||
#define AliasExport_M(RET,NAME,X,DEF,SUF) AliasExport(RET,NAME,X,DEF)
|
||||
#define AliasExport_V(RET,NAME) AliasExport(RET,NAME,,(void))
|
||||
#define NonAliasExportDecl(RET,NAME,DEF) RET NAME DEF
|
||||
#endif
|
||||
#define AliasExport_1(RET,NAME,X,DEF) AliasExport(RET,NAME,X,DEF)
|
||||
#endif // AliasExport
|
||||
|
||||
// ensure APIENTRY used from platform if it defined, win32 should use STDCALL conversion
|
||||
#include <GLES/glplatform.h>
|
||||
#ifndef NOEGL
|
||||
#include <EGL/eglplatform.h>
|
||||
#endif
|
||||
|
||||
#ifndef APIENTRY
|
||||
# if defined(_WIN32) || defined(__MINGW32__)
|
||||
# define APIENTRY __stdcall
|
||||
# else
|
||||
# define APIENTRY
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SOFTFLOAT
|
||||
#ifdef __arm__
|
||||
#define SOFTFLOAT __attribute__((pcs("aapcs")))
|
||||
#else
|
||||
#define SOFTFLOAT
|
||||
#endif
|
||||
#endif // SOFTFLOAT
|
||||
|
||||
#ifndef APIENTRY_GLES
|
||||
#ifdef GLES_SOFTFLOAT
|
||||
#define APIENTRY_GLES APIENTRY SOFTFLOAT
|
||||
#else
|
||||
#define APIENTRY_GLES APIENTRY
|
||||
#endif
|
||||
#endif // APIENTRY_GLES
|
||||
|
||||
|
||||
#ifndef APIENTRY_GL4ES
|
||||
#ifdef GL_SOFTFLOAT
|
||||
#define APIENTRY_GL4ES APIENTRY SOFTFLOAT
|
||||
#else
|
||||
#define APIENTRY_GL4ES APIENTRY
|
||||
#endif
|
||||
#endif //APIENTRY_GL4ES
|
||||
|
||||
#ifndef FASTMATH
|
||||
#ifdef __GNUC__
|
||||
#ifdef __arm__
|
||||
#ifdef __ARM_PCS_VFP
|
||||
//#warning Arm Hardfloat detected
|
||||
#define FASTMATH
|
||||
#else // __ARM_PCS_VFP
|
||||
#if defined(__ARM_FP) && defined(PANDORA)
|
||||
//#warning Arm SoftFP detected
|
||||
#define FASTMATH __attribute__((pcs("aapcs-vfp")))
|
||||
#else // defined(__ARM_FP) && defined(PANDORA)
|
||||
//#warning Arm no FP detected
|
||||
#define FASTMATH
|
||||
#endif // defined(__ARM_FP) && defined(PANDORA)
|
||||
#endif // __ARM_PCS_VFP
|
||||
#else // __arm__
|
||||
#define FASTMATH
|
||||
#endif // __arm__
|
||||
#else // __GNUC__
|
||||
#define FASTMATH
|
||||
#endif // __GNUC__
|
||||
#endif // FASTMATH
|
||||
|
||||
#endif // _GL4ES_ATTRIBUTES_H_
|
||||
@@ -0,0 +1,297 @@
|
||||
#include "blend.h"
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "debug.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "init.h"
|
||||
#include "loader.h"
|
||||
#include "logs.h"
|
||||
|
||||
static int fpeBlendFunc(GLenum func)
|
||||
{
|
||||
int ret = -1;
|
||||
#define GO(A) case GL_##A: ret = FPE_BLEND_##A; break
|
||||
switch(func) {
|
||||
GO(ZERO);
|
||||
GO(ONE);
|
||||
GO(SRC_COLOR);
|
||||
GO(ONE_MINUS_SRC_COLOR);
|
||||
GO(DST_COLOR);
|
||||
GO(ONE_MINUS_DST_COLOR);
|
||||
GO(SRC_ALPHA);
|
||||
GO(ONE_MINUS_SRC_ALPHA);
|
||||
GO(DST_ALPHA);
|
||||
GO(ONE_MINUS_DST_ALPHA);
|
||||
GO(CONSTANT_COLOR);
|
||||
GO(ONE_MINUS_CONSTANT_COLOR);
|
||||
GO(CONSTANT_ALPHA);
|
||||
GO(ONE_MINUS_CONSTANT_ALPHA);
|
||||
GO(SRC_ALPHA_SATURATE);
|
||||
}
|
||||
#undef GO
|
||||
return ret;
|
||||
}
|
||||
static int fpeBlendEq(GLenum func)
|
||||
{
|
||||
int ret = -1;
|
||||
#define GO(A) case GL_##A: ret = FPE_BLENDEQ_##A; break
|
||||
switch(func) {
|
||||
GO(FUNC_ADD);
|
||||
GO(FUNC_SUBTRACT);
|
||||
GO(FUNC_REVERSE_SUBTRACT);
|
||||
GO(MIN);
|
||||
GO(MAX);
|
||||
}
|
||||
#undef GO
|
||||
return ret;
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
|
||||
if(!glstate->list.pending)
|
||||
PUSH_IF_COMPILING(glBlendColor)
|
||||
|
||||
if(glstate->blend_color[0]==red
|
||||
&& glstate->blend_color[1]==green
|
||||
&& glstate->blend_color[2]==blue
|
||||
&& glstate->blend_color[3]==alpha)
|
||||
return;
|
||||
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
glstate->blend_color[0] = red;
|
||||
glstate->blend_color[1] = green;
|
||||
glstate->blend_color[2] = blue;
|
||||
glstate->blend_color[3] = alpha;
|
||||
|
||||
if(!globals4es.shaderblend) {
|
||||
LOAD_GLES2_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AliasExport(void,glBlendColor,,(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
|
||||
AliasExport(void,glBlendColor,EXT,(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
|
||||
AliasExport(void,glBlendColor,ARB,(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
|
||||
{
|
||||
if(!glstate->list.pending)
|
||||
PUSH_IF_COMPILING(glBlendFuncSeparate)
|
||||
|
||||
LOAD_GLES2_OR_OES(glBlendFuncSeparate);
|
||||
if(sfactorRGB==glstate->blendsfactorrgb && dfactorRGB==glstate->blenddfactorrgb
|
||||
&& sfactorAlpha==glstate->blendsfactoralpha && dfactorAlpha==glstate->blenddfactoralpha)
|
||||
return; // no change...
|
||||
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
if(globals4es.shaderblend) {
|
||||
int srcrgb = fpeBlendFunc(sfactorRGB);
|
||||
int dstrgb = fpeBlendFunc(dfactorRGB);
|
||||
int srcalpha = fpeBlendFunc(sfactorAlpha);
|
||||
int dstalpha = fpeBlendFunc(dfactorAlpha);
|
||||
if(srcrgb<0 || dstrgb<0 || srcalpha<0 || dstalpha<0) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glstate->fpe_state->blendsrcrgb = srcrgb;
|
||||
glstate->fpe_state->blenddstrgb = dstrgb;
|
||||
glstate->fpe_state->blendsrcalpha = srcalpha;
|
||||
glstate->fpe_state->blenddstalpha = dstalpha;
|
||||
} else {
|
||||
#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);
|
||||
}
|
||||
|
||||
glstate->blendsfactorrgb = sfactorRGB;
|
||||
glstate->blenddfactorrgb = dfactorRGB;
|
||||
glstate->blendsfactoralpha = sfactorAlpha;
|
||||
glstate->blenddfactoralpha = dfactorAlpha;
|
||||
}
|
||||
AliasExport(void,glBlendFuncSeparate,,(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha));
|
||||
AliasExport(void,glBlendFuncSeparate,EXT,(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) {
|
||||
if(!glstate->list.pending)
|
||||
PUSH_IF_COMPILING(glBlendEquationSeparate);
|
||||
|
||||
if(glstate->blendeqrgb==modeRGB
|
||||
&& glstate->blendeqalpha==modeA)
|
||||
return;
|
||||
|
||||
if(globals4es.shaderblend) {
|
||||
int rgb = fpeBlendEq(modeRGB);
|
||||
int alpha = fpeBlendEq(modeA);
|
||||
if(rgb<0 || alpha<0) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glstate->fpe_state->blendeqrgb = rgb;
|
||||
glstate->fpe_state->blendeqalpha = alpha;
|
||||
} else {
|
||||
LOAD_GLES2_OR_OES(glBlendEquationSeparate);
|
||||
#ifndef PANDORA
|
||||
if(gles_glBlendEquationSeparate)
|
||||
#endif
|
||||
gles_glBlendEquationSeparate(modeRGB, modeA);
|
||||
}
|
||||
|
||||
glstate->blendeqrgb = modeRGB;
|
||||
glstate->blendeqalpha = modeA;
|
||||
}
|
||||
AliasExport(void,glBlendEquationSeparate,,(GLenum modeRGB, GLenum modeA));
|
||||
AliasExport(void,glBlendEquationSeparate,EXT,(GLenum modeRGB, GLenum modeA));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor) {
|
||||
if(!glstate->list.pending)
|
||||
PUSH_IF_COMPILING(glBlendFunc)
|
||||
|
||||
if(sfactor==glstate->blendsfactorrgb && dfactor==glstate->blenddfactorrgb
|
||||
&& sfactor==glstate->blendsfactoralpha && dfactor==glstate->blenddfactoralpha)
|
||||
return; // already set
|
||||
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
glstate->blendsfactorrgb = sfactor;
|
||||
glstate->blenddfactorrgb = dfactor;
|
||||
glstate->blendsfactoralpha = sfactor;
|
||||
glstate->blenddfactoralpha = dfactor;
|
||||
|
||||
if(globals4es.shaderblend) {
|
||||
int srcrgb = fpeBlendFunc(sfactor);
|
||||
int dstrgb = fpeBlendFunc(dfactor);
|
||||
int srcalpha = fpeBlendFunc(sfactor);
|
||||
int dstalpha = fpeBlendFunc(dfactor);
|
||||
if(srcrgb<0 || dstrgb<0 || srcalpha<0 || dstalpha<0) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glstate->fpe_state->blendsrcrgb = srcrgb;
|
||||
glstate->fpe_state->blenddstrgb = dstrgb;
|
||||
glstate->fpe_state->blendsrcalpha = srcalpha;
|
||||
glstate->fpe_state->blenddstalpha = dstalpha;
|
||||
} else {
|
||||
LOAD_GLES(glBlendFunc);
|
||||
LOAD_GLES2_OR_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);
|
||||
}
|
||||
}
|
||||
AliasExport(void,glBlendFunc,,(GLenum sfactor, GLenum dfactor));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBlendEquation(GLenum mode) {
|
||||
if(!glstate->list.pending)
|
||||
PUSH_IF_COMPILING(glBlendEquation)
|
||||
|
||||
if(glstate->blendeqrgb==mode
|
||||
&& glstate->blendeqalpha==mode)
|
||||
return;
|
||||
|
||||
glstate->blendeqrgb = mode;
|
||||
glstate->blendeqalpha = mode;
|
||||
|
||||
if(globals4es.shaderblend) {
|
||||
int rgb = fpeBlendEq(mode);
|
||||
int alpha = fpeBlendEq(mode);
|
||||
if(rgb<0 || alpha<0) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glstate->fpe_state->blendeqrgb = rgb;
|
||||
glstate->fpe_state->blendeqalpha = alpha;
|
||||
} else {
|
||||
LOAD_GLES2_OR_OES(glBlendEquation);
|
||||
errorGL();
|
||||
#ifdef ODROID
|
||||
if(gles_glBlendEquation)
|
||||
#endif
|
||||
gles_glBlendEquation(mode);
|
||||
}
|
||||
}
|
||||
AliasExport(void,glBlendEquation,,(GLenum mode));
|
||||
AliasExport(void,glBlendEquation,EXT,(GLenum mode));
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef _GL4ES_BLEND_H_
|
||||
#define _GL4ES_BLEND_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||
void APIENTRY_GL4ES gl4es_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
|
||||
void APIENTRY_GL4ES gl4es_glBlendEquationSeparate(GLenum modeRGB, GLenum modeA);
|
||||
void APIENTRY_GL4ES gl4es_glBlendFunc(GLenum sfactor, GLenum dfactor);
|
||||
void APIENTRY_GL4ES gl4es_glBlendEquation(GLenum mode);
|
||||
|
||||
#endif //_GL4ES_BLEND_H_
|
||||
@@ -0,0 +1,417 @@
|
||||
/* Blit utility function */
|
||||
#include "blit.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "fpe.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "init.h"
|
||||
#include "loader.h"
|
||||
#include "logs.h"
|
||||
#ifdef TEXSTREAM
|
||||
# ifndef GL_TEXTURE_STREAM_IMG
|
||||
# define GL_TEXTURE_STREAM_IMG 0x8C0D
|
||||
# endif
|
||||
#include "../glx/streaming.h"
|
||||
#endif
|
||||
|
||||
// hacky viewport temporary changes
|
||||
void pushViewport(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void popViewport();
|
||||
|
||||
void gl4es_blitTexture_gles1(GLuint texture,
|
||||
GLfloat sx, GLfloat sy,
|
||||
GLfloat width, GLfloat height,
|
||||
GLfloat nwidth, GLfloat nheight,
|
||||
GLfloat zoomx, GLfloat zoomy,
|
||||
GLfloat vpwidth, GLfloat vpheight,
|
||||
GLfloat x, GLfloat y, GLint mode) {
|
||||
|
||||
LOAD_GLES(glClientActiveTexture);
|
||||
|
||||
GLfloat old_projection[16], old_modelview[16], old_texture[16];
|
||||
|
||||
int customvp = (vpwidth>0.0);
|
||||
int drawtexok = (hardext.drawtex) && (zoomx==1.0f) && (zoomy==1.0f);
|
||||
|
||||
GLuint old_cli = glstate->texture.client;
|
||||
if (old_cli!=0) gles_glClientActiveTexture(GL_TEXTURE0);
|
||||
|
||||
gl4es_glDisable(GL_LIGHTING);
|
||||
gl4es_glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
gl4es_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
switch (mode) {
|
||||
case BLIT_OPAQUE:
|
||||
gl4es_glDisable(GL_ALPHA_TEST);
|
||||
gl4es_glDisable(GL_BLEND);
|
||||
break;
|
||||
case BLIT_ALPHA:
|
||||
gl4es_glEnable(GL_ALPHA_TEST);
|
||||
gl4es_glAlphaFunc(GL_GREATER, 0.0f);
|
||||
break;
|
||||
case BLIT_COLOR:
|
||||
break;
|
||||
}
|
||||
|
||||
if(drawtexok) {
|
||||
LOAD_GLES_OES(glDrawTexf);
|
||||
LOAD_GLES(glTexParameteriv);
|
||||
// setup texture first
|
||||
int sourceRect[4] = {sx, sy, width, height};
|
||||
gles_glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, sourceRect);
|
||||
// take x/y of ViewPort into account
|
||||
GLfloat dx = (customvp)?0.0f:glstate->raster.viewport.x;
|
||||
GLfloat dy = (customvp)?0.0f:glstate->raster.viewport.y;
|
||||
//TODO: do something with width / height of ViewPort?
|
||||
// then draw it
|
||||
gles_glDrawTexf(x+dx, y+dy, 0.0f, width, height);
|
||||
} else {
|
||||
LOAD_GLES(glVertexPointer);
|
||||
LOAD_GLES(glTexCoordPointer);
|
||||
LOAD_GLES(glDrawArrays);
|
||||
|
||||
GLfloat w2 = 2.0f / (customvp?vpwidth:glstate->raster.viewport.width);
|
||||
GLfloat h2 = 2.0f / (customvp?vpheight:glstate->raster.viewport.height);
|
||||
GLfloat blit_x1=roundf(x);
|
||||
GLfloat blit_x2=roundf(x+width*zoomx);
|
||||
GLfloat blit_y1=roundf(y);
|
||||
GLfloat blit_y2=roundf(y+height*zoomy);
|
||||
GLfloat blit_vert[] = {
|
||||
blit_x1*w2-1.0f, blit_y1*h2-1.0f,
|
||||
blit_x2*w2-1.0f, blit_y1*h2-1.0f,
|
||||
blit_x2*w2-1.0f, blit_y2*h2-1.0f,
|
||||
blit_x1*w2-1.0f, blit_y2*h2-1.0f
|
||||
};
|
||||
GLfloat sw = sx/nwidth;
|
||||
GLfloat sh = sy/nheight;
|
||||
GLfloat rw = (sx+width)/nwidth;
|
||||
GLfloat rh = (sy+height)/nheight;
|
||||
GLfloat blit_tex[] = {
|
||||
sw, sh,
|
||||
rw, sh,
|
||||
rw, rh,
|
||||
sw, rh
|
||||
};
|
||||
|
||||
gl4es_glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT | GL_CLIENT_PIXEL_STORE_BIT);
|
||||
gl4es_glGetFloatv(GL_TEXTURE_MATRIX, old_texture);
|
||||
gl4es_glGetFloatv(GL_PROJECTION_MATRIX, old_projection);
|
||||
gl4es_glGetFloatv(GL_MODELVIEW_MATRIX, old_modelview);
|
||||
gl4es_glMatrixMode(GL_TEXTURE);
|
||||
gl4es_glLoadIdentity();
|
||||
gl4es_glMatrixMode(GL_PROJECTION);
|
||||
gl4es_glLoadIdentity();
|
||||
gl4es_glMatrixMode(GL_MODELVIEW);
|
||||
gl4es_glLoadIdentity();
|
||||
|
||||
if(customvp)
|
||||
pushViewport(0,0,vpwidth, vpheight);
|
||||
|
||||
fpe_glEnableClientState(GL_VERTEX_ARRAY);
|
||||
gles_glVertexPointer(2, GL_FLOAT, 0, blit_vert);
|
||||
fpe_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
gles_glTexCoordPointer(2, GL_FLOAT, 0, blit_tex);
|
||||
for (int a=1; a <hardext.maxtex; a++)
|
||||
if(glstate->gleshard->vertexattrib[ATT_MULTITEXCOORD0+a].enabled) {
|
||||
gles_glClientActiveTexture(GL_TEXTURE0 + a);
|
||||
fpe_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
gles_glClientActiveTexture(GL_TEXTURE0);
|
||||
fpe_glDisableClientState(GL_COLOR_ARRAY);
|
||||
fpe_glDisableClientState(GL_NORMAL_ARRAY);
|
||||
gles_glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
if(customvp)
|
||||
popViewport();
|
||||
|
||||
gl4es_glPopClientAttrib();
|
||||
gl4es_glMatrixMode(GL_TEXTURE);
|
||||
gl4es_glLoadMatrixf(old_texture);
|
||||
gl4es_glMatrixMode(GL_MODELVIEW);
|
||||
gl4es_glLoadMatrixf(old_modelview);
|
||||
gl4es_glMatrixMode(GL_PROJECTION);
|
||||
gl4es_glLoadMatrixf(old_projection);
|
||||
}
|
||||
|
||||
if (old_cli!=0) gles_glClientActiveTexture(GL_TEXTURE0+old_cli);
|
||||
|
||||
}
|
||||
|
||||
const char _blit_vsh[] = "#version 100 \n" \
|
||||
"attribute highp vec2 aPosition; \n" \
|
||||
"attribute highp vec2 aTexCoord; \n" \
|
||||
"varying mediump vec2 vTexCoord; \n" \
|
||||
"void main(){ \n" \
|
||||
"gl_Position = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n" \
|
||||
"vTexCoord = aTexCoord; \n" \
|
||||
"} \n";
|
||||
|
||||
const char _blit_fsh[] = "#version 100 \n" \
|
||||
"uniform sampler2D uTex; \n" \
|
||||
"varying mediump vec2 vTexCoord; \n" \
|
||||
"void main(){ \n" \
|
||||
"gl_FragColor = texture2D(uTex, vTexCoord); \n" \
|
||||
"} \n";
|
||||
|
||||
const char _blit_vsh_alpha[] = "#version 100 \n" \
|
||||
"attribute highp vec2 aPosition; \n" \
|
||||
"attribute highp vec2 aTexCoord; \n" \
|
||||
"varying mediump vec2 vTexCoord; \n" \
|
||||
"void main(){ \n" \
|
||||
"gl_Position = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n" \
|
||||
"vTexCoord = aTexCoord; \n" \
|
||||
"} \n";
|
||||
|
||||
const char _blit_fsh_alpha[] = "#version 100 \n" \
|
||||
"uniform sampler2D uTex; \n" \
|
||||
"varying mediump vec2 vTexCoord; \n" \
|
||||
"void main(){ \n" \
|
||||
"lowp vec4 p = texture2D(uTex, vTexCoord); \n" \
|
||||
"if (p.a==0.0) discard; \n" \
|
||||
"gl_FragColor = p; \n" \
|
||||
"} \n";
|
||||
|
||||
void gl4es_blitTexture_gles2(GLuint texture,
|
||||
GLfloat sx, GLfloat sy,
|
||||
GLfloat width, GLfloat height,
|
||||
GLfloat nwidth, GLfloat nheight,
|
||||
GLfloat zoomx, GLfloat zoomy,
|
||||
GLfloat vpwidth, GLfloat vpheight,
|
||||
GLfloat x, GLfloat y, GLint mode) {
|
||||
|
||||
LOAD_GLES(glDrawArrays);
|
||||
|
||||
if(!glstate->blit) {
|
||||
LOAD_GLES2(glCreateShader);
|
||||
LOAD_GLES2(glShaderSource);
|
||||
LOAD_GLES2(glCompileShader);
|
||||
LOAD_GLES2(glGetShaderiv);
|
||||
LOAD_GLES2(glBindAttribLocation);
|
||||
LOAD_GLES2(glAttachShader);
|
||||
LOAD_GLES2(glCreateProgram);
|
||||
LOAD_GLES2(glLinkProgram);
|
||||
LOAD_GLES2(glGetProgramiv);
|
||||
LOAD_GLES(glGetUniformLocation);
|
||||
LOAD_GLES2(glUniform1i);
|
||||
LOAD_GLES2(glUseProgram);
|
||||
|
||||
glstate->blit = (glesblit_t*)malloc(sizeof(glesblit_t));
|
||||
memset(glstate->blit, 0, sizeof(glesblit_t));
|
||||
|
||||
GLint success;
|
||||
const char *src[1];
|
||||
src[0] = _blit_fsh;
|
||||
glstate->blit->pixelshader = gles_glCreateShader( GL_FRAGMENT_SHADER );
|
||||
gles_glShaderSource( glstate->blit->pixelshader, 1, (const char**) src, NULL );
|
||||
gles_glCompileShader( glstate->blit->pixelshader );
|
||||
gles_glGetShaderiv( glstate->blit->pixelshader, GL_COMPILE_STATUS, &success );
|
||||
if (!success)
|
||||
{
|
||||
LOAD_GLES(glGetShaderInfoLog);
|
||||
char log[400];
|
||||
gles_glGetShaderInfoLog(glstate->blit->pixelshader_alpha, 399, NULL, log);
|
||||
SHUT_LOGE("Failed to produce blit fragment shader.\n%s", log);
|
||||
free(glstate->blit);
|
||||
glstate->blit = NULL;
|
||||
}
|
||||
|
||||
src[0] = _blit_fsh_alpha;
|
||||
glstate->blit->pixelshader_alpha = gles_glCreateShader( GL_FRAGMENT_SHADER );
|
||||
gles_glShaderSource( glstate->blit->pixelshader_alpha, 1, (const char**) src, NULL );
|
||||
gles_glCompileShader( glstate->blit->pixelshader_alpha );
|
||||
gles_glGetShaderiv( glstate->blit->pixelshader_alpha, GL_COMPILE_STATUS, &success );
|
||||
if (!success)
|
||||
{
|
||||
LOAD_GLES(glGetShaderInfoLog);
|
||||
char log[400];
|
||||
gles_glGetShaderInfoLog(glstate->blit->pixelshader_alpha, 399, NULL, log);
|
||||
SHUT_LOGE("Failed to produce blit with alpha fragment shader.\n%s", log);
|
||||
free(glstate->blit);
|
||||
glstate->blit = NULL;
|
||||
}
|
||||
|
||||
src[0] = _blit_vsh;
|
||||
glstate->blit->vertexshader = gles_glCreateShader( GL_VERTEX_SHADER );
|
||||
gles_glShaderSource( glstate->blit->vertexshader, 1, (const char**) src, NULL );
|
||||
gles_glCompileShader( glstate->blit->vertexshader );
|
||||
gles_glGetShaderiv( glstate->blit->vertexshader, GL_COMPILE_STATUS, &success );
|
||||
if( !success )
|
||||
{
|
||||
LOAD_GLES(glGetShaderInfoLog);
|
||||
char log[400];
|
||||
gles_glGetShaderInfoLog(glstate->blit->pixelshader_alpha, 399, NULL, log);
|
||||
SHUT_LOGE("Failed to produce blit vertex shader.\n%s", log);
|
||||
free(glstate->blit);
|
||||
glstate->blit = NULL;
|
||||
}
|
||||
|
||||
src[0] = _blit_vsh_alpha;
|
||||
glstate->blit->vertexshader_alpha = gles_glCreateShader( GL_VERTEX_SHADER );
|
||||
gles_glShaderSource( glstate->blit->vertexshader_alpha, 1, (const char**) src, NULL );
|
||||
gles_glCompileShader( glstate->blit->vertexshader_alpha );
|
||||
gles_glGetShaderiv( glstate->blit->vertexshader_alpha, GL_COMPILE_STATUS, &success );
|
||||
if( !success )
|
||||
{
|
||||
LOAD_GLES(glGetShaderInfoLog);
|
||||
char log[400];
|
||||
gles_glGetShaderInfoLog(glstate->blit->pixelshader_alpha, 399, NULL, log);
|
||||
SHUT_LOGE("Failed to produce blit with alpha vertex shader.\n%s", log);
|
||||
free(glstate->blit);
|
||||
glstate->blit = NULL;
|
||||
}
|
||||
|
||||
glstate->blit->program = gles_glCreateProgram();
|
||||
gles_glBindAttribLocation( glstate->blit->program, 0, "aPosition" );
|
||||
gles_glBindAttribLocation( glstate->blit->program, 1, "aTexCoord" );
|
||||
gles_glAttachShader( glstate->blit->program, glstate->blit->pixelshader );
|
||||
gles_glAttachShader( glstate->blit->program, glstate->blit->vertexshader );
|
||||
gles_glLinkProgram( glstate->blit->program );
|
||||
gles_glGetProgramiv( glstate->blit->program, GL_LINK_STATUS, &success );
|
||||
if( !success )
|
||||
{
|
||||
SHUT_LOGE("Failed to link blit program.\n");
|
||||
free(glstate->blit);
|
||||
glstate->blit = NULL;
|
||||
}
|
||||
GLuint oldprog = glstate->gleshard->program;
|
||||
gles_glUseProgram(glstate->blit->program);
|
||||
gles_glUniform1i( gles_glGetUniformLocation( glstate->blit->program, "uTex" ), 0 );
|
||||
|
||||
glstate->blit->program_alpha = gles_glCreateProgram();
|
||||
gles_glBindAttribLocation( glstate->blit->program_alpha, 0, "aPosition" );
|
||||
gles_glBindAttribLocation( glstate->blit->program_alpha, 1, "aTexCoord" );
|
||||
gles_glAttachShader( glstate->blit->program_alpha, glstate->blit->pixelshader_alpha );
|
||||
gles_glAttachShader( glstate->blit->program_alpha, glstate->blit->vertexshader_alpha );
|
||||
gles_glLinkProgram( glstate->blit->program_alpha );
|
||||
gles_glGetProgramiv( glstate->blit->program_alpha, GL_LINK_STATUS, &success );
|
||||
if( !success )
|
||||
{
|
||||
SHUT_LOGE("Failed to link blit program.\n");
|
||||
free(glstate->blit);
|
||||
glstate->blit = NULL;
|
||||
}
|
||||
gles_glUseProgram(glstate->blit->program_alpha);
|
||||
gles_glUniform1i( gles_glGetUniformLocation( glstate->blit->program_alpha, "uTex" ), 0 );
|
||||
gles_glUseProgram(oldprog);
|
||||
}
|
||||
|
||||
int customvp = (vpwidth>0.0);
|
||||
GLfloat w2 = 2.0f / (customvp?vpwidth:glstate->raster.viewport.width);
|
||||
GLfloat h2 = 2.0f / (customvp?vpheight:glstate->raster.viewport.height);
|
||||
GLfloat blit_x1=roundf(x);
|
||||
GLfloat blit_x2=roundf(x+width*zoomx);
|
||||
GLfloat blit_y1=roundf(y);
|
||||
GLfloat blit_y2=roundf(y+height*zoomy);
|
||||
GLfloat *vert = glstate->blit->vert;
|
||||
GLfloat *tex = glstate->blit->tex;
|
||||
vert[0] = blit_x1*w2-1.0f; vert[1] = blit_y1*h2-1.0f;
|
||||
vert[2] = blit_x2*w2-1.0f; vert[3] = vert[1];
|
||||
vert[4] = vert[2]; vert[5] = blit_y2*h2-1.0f;
|
||||
vert[6] = vert[0]; vert[7] = vert[5];
|
||||
GLfloat sw = sx/nwidth;
|
||||
GLfloat sh = sy/nheight;
|
||||
GLfloat rw = (sx+width)/nwidth;
|
||||
GLfloat rh = (sy+height)/nheight;
|
||||
tex[0] = sw; tex[1] = sh;
|
||||
tex[2] = rw; tex[3] = sh;
|
||||
tex[4] = rw; tex[5] = rh;
|
||||
tex[6] = sw; tex[7] = rh;
|
||||
gl4es_glDisable(GL_BLEND);
|
||||
int alpha = 0;
|
||||
switch (mode) {
|
||||
case BLIT_OPAQUE:
|
||||
//gl4es_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
break;
|
||||
case BLIT_ALPHA:
|
||||
alpha = 1;
|
||||
break;
|
||||
case BLIT_COLOR:
|
||||
//gl4es_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
realize_blitenv(alpha);
|
||||
|
||||
gles_glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
||||
void gl4es_blitTexture(GLuint texture,
|
||||
GLfloat sx, GLfloat sy,
|
||||
GLfloat width, GLfloat height,
|
||||
GLfloat nwidth, GLfloat nheight,
|
||||
GLfloat zoomx, GLfloat zoomy,
|
||||
GLfloat vpwidth, GLfloat vpheight,
|
||||
GLfloat x, GLfloat y, GLint mode) {
|
||||
//printf("blitTexture(%d, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %d) customvp=%d, vp=%d/%d/%d/%d\n", texture, sx, sy, width, height, nwidth, nheight, zoomx, zoomy, vpwidth, vpheight, x, y, mode, (vpwidth>0.0), glstate->raster.viewport.x, glstate->raster.viewport.y, glstate->raster.viewport.width, glstate->raster.viewport.height);
|
||||
LOAD_GLES(glBindTexture);
|
||||
LOAD_GLES(glActiveTexture);
|
||||
LOAD_GLES(glEnable);
|
||||
LOAD_GLES(glDisable);
|
||||
|
||||
realize_textures(1);
|
||||
|
||||
gl4es_glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT);
|
||||
|
||||
if(glstate->gleshard->active) {
|
||||
glstate->gleshard->active = 0;
|
||||
gles_glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
GLint depthwrite = glstate->depth.mask;
|
||||
|
||||
gl4es_glDisable(GL_DEPTH_TEST);
|
||||
gl4es_glDisable(GL_CULL_FACE);
|
||||
gl4es_glDisable(GL_STENCIL_TEST);
|
||||
|
||||
if(depthwrite)
|
||||
gl4es_glDepthMask(GL_FALSE);
|
||||
|
||||
#ifdef TEXSTREAM
|
||||
if(glstate->bound_stream[0] && hardext.esversion==1) {
|
||||
//printf("TMU%d, turning off Streaming (blit)\n", 0);
|
||||
gles_glDisable(GL_TEXTURE_STREAM_IMG);
|
||||
DeactivateStreaming();
|
||||
}
|
||||
#endif
|
||||
int tmp = glstate->enable.texture[0];
|
||||
|
||||
if(glstate->actual_tex2d[0] != texture)
|
||||
gles_glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
if(hardext.esversion==1) {
|
||||
if(!IS_TEX2D(tmp))
|
||||
gles_glEnable(GL_TEXTURE_2D);
|
||||
if(IS_CUBE_MAP(tmp))
|
||||
gles_glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
|
||||
gl4es_blitTexture_gles1(texture, sx, sy, width, height,
|
||||
nwidth, nheight, zoomx, zoomy,
|
||||
vpwidth, vpheight, x, y, mode);
|
||||
if(!IS_TEX2D(tmp))
|
||||
gles_glDisable(GL_TEXTURE_2D);
|
||||
if(IS_CUBE_MAP(tmp))
|
||||
gles_glEnable(GL_TEXTURE_CUBE_MAP);
|
||||
} else {
|
||||
gl4es_blitTexture_gles2(texture, sx, sy, width, height,
|
||||
nwidth, nheight, zoomx, zoomy,
|
||||
vpwidth, vpheight, x, y, mode);
|
||||
}
|
||||
|
||||
// All the previous states are Pushed / Poped anyway...
|
||||
#ifdef TEXSTREAM
|
||||
if(glstate->bound_stream[0] && hardext.esversion==1) {
|
||||
//printf("TMU%d, turning ON Streaming (blit)\n", 0);
|
||||
gltexture_t *tex = glstate->texture.bound[0][ENABLED_TEX2D];
|
||||
ActivateStreaming(tex->streamingID);
|
||||
gles_glEnable(GL_TEXTURE_STREAM_IMG);
|
||||
} else
|
||||
#endif
|
||||
if (glstate->actual_tex2d[0] != texture)
|
||||
gles_glBindTexture(GL_TEXTURE_2D, glstate->actual_tex2d[0]);
|
||||
|
||||
if(depthwrite)
|
||||
gl4es_glDepthMask(GL_TRUE);
|
||||
|
||||
gl4es_glPopAttrib();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef _GL4ES_BLIT_H_
|
||||
#define _GL4ES_BLIT_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
#define BLIT_ALPHA 0
|
||||
#define BLIT_OPAQUE 1
|
||||
#define BLIT_COLOR 2
|
||||
|
||||
void gl4es_blitTexture(GLuint texture,
|
||||
GLfloat sx, GLfloat sy,
|
||||
GLfloat width, GLfloat height,
|
||||
GLfloat nwidth, GLfloat nheight,
|
||||
GLfloat zoomx, GLfloat zoomy,
|
||||
GLfloat vpwidth, GLfloat vpheight,
|
||||
GLfloat x, GLfloat y, GLint mode);
|
||||
|
||||
#endif // _GL4ES_BLIT_H_
|
||||
@@ -0,0 +1,942 @@
|
||||
#include "buffers.h"
|
||||
|
||||
#include "khash.h"
|
||||
#include "../glx/hardext.h"
|
||||
#include "attributes.h"
|
||||
#include "debug.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "logs.h"
|
||||
#include "init.h"
|
||||
#include "loader.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DBG(a) a
|
||||
#else
|
||||
#define DBG(a)
|
||||
#endif
|
||||
|
||||
|
||||
KHASH_MAP_IMPL_INT(buff, glbuffer_t *);
|
||||
KHASH_MAP_IMPL_INT(glvao, glvao_t*);
|
||||
|
||||
static GLuint lastbuffer = 1;
|
||||
|
||||
// Utility function to bind / unbind a particular buffer
|
||||
|
||||
glbuffer_t** BUFF(GLenum target) {
|
||||
switch(target) {
|
||||
case GL_ARRAY_BUFFER:
|
||||
return &glstate->vao->vertex;
|
||||
break;
|
||||
case GL_ELEMENT_ARRAY_BUFFER:
|
||||
return &glstate->vao->elements;
|
||||
break;
|
||||
case GL_PIXEL_PACK_BUFFER:
|
||||
return &glstate->vao->pack;
|
||||
break;
|
||||
case GL_PIXEL_UNPACK_BUFFER:
|
||||
return &glstate->vao->unpack;
|
||||
break;
|
||||
default:
|
||||
LOGD("Warning, unknown buffer target 0x%04X\n", target);
|
||||
}
|
||||
return (glbuffer_t**)NULL;
|
||||
}
|
||||
|
||||
void unbind_buffer(GLenum target) {
|
||||
glbuffer_t **t = BUFF(target);
|
||||
if (t)
|
||||
*t=(glbuffer_t*)NULL;
|
||||
}
|
||||
void bind_buffer(GLenum target, glbuffer_t* buff) {
|
||||
glbuffer_t ** t = BUFF(target);
|
||||
if (t)
|
||||
*t = buff;
|
||||
}
|
||||
glbuffer_t* getbuffer_buffer(GLenum target) {
|
||||
glbuffer_t ** t = BUFF(target);
|
||||
if (t)
|
||||
return *t;
|
||||
return NULL;
|
||||
}
|
||||
glbuffer_t* getbuffer_id(GLuint buffer) {
|
||||
if(!buffer)
|
||||
return NULL;
|
||||
khint_t k;
|
||||
khash_t(buff) *list = glstate->buffers;
|
||||
k = kh_get(buff, list, buffer);
|
||||
if (k == kh_end(list))
|
||||
return NULL;
|
||||
return kh_value(list, k);
|
||||
}
|
||||
|
||||
int buffer_target(GLenum target) {
|
||||
if (target==GL_ARRAY_BUFFER)
|
||||
return 1;
|
||||
if (target==GL_ELEMENT_ARRAY_BUFFER)
|
||||
return 1;
|
||||
if (target==GL_PIXEL_PACK_BUFFER)
|
||||
return 1;
|
||||
if (target==GL_PIXEL_UNPACK_BUFFER)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rebind_real_buff_arrays(int old_buffer, int new_buffer) {
|
||||
for (int j = 0; j < hardext.maxvattrib; j++) {
|
||||
if (glstate->vao->vertexattrib[j].real_buffer == old_buffer) {
|
||||
glstate->vao->vertexattrib[j].real_buffer = new_buffer;
|
||||
/*if(!new_buffer)
|
||||
glstate->vao->vertexattrib[j].real_pointer = 0;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGenBuffers(GLsizei n, GLuint * buffers) {
|
||||
DBG(printf("glGenBuffers(%i, %p)\n", n, buffers);)
|
||||
noerrorShim();
|
||||
if (n<1) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
khash_t(buff) *list = glstate->buffers;
|
||||
for (int i=0; i<n; i++) { // create buffer, and check uniqueness...
|
||||
int b;
|
||||
while(getbuffer_id(b=lastbuffer++));
|
||||
buffers[i] = b;
|
||||
// create the buffer
|
||||
khint_t k;
|
||||
int ret;
|
||||
k = kh_put(buff, list, b, &ret);
|
||||
glbuffer_t *buff = kh_value(list, k) = malloc(sizeof(glbuffer_t));
|
||||
buff->buffer = b;
|
||||
buff->type = 0; // no target for now
|
||||
buff->data = NULL;
|
||||
buff->usage = GL_STATIC_DRAW;
|
||||
buff->size = 0;
|
||||
buff->access = GL_READ_WRITE;
|
||||
buff->mapped = 0;
|
||||
buff->real_buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBindBuffer(GLenum target, GLuint buffer) {
|
||||
DBG(printf("glBindBuffer(%s, %u)\n", PrintEnum(target), buffer);)
|
||||
// this flush is probably not needed as long as real VBO are not used
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
khint_t k;
|
||||
int ret;
|
||||
khash_t(buff) *list = glstate->buffers;
|
||||
if (!buffer_target(target)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
// if buffer = 0 => unbind buffer!
|
||||
if (buffer == 0) {
|
||||
// unbind buffer
|
||||
bindBuffer(target, 0);
|
||||
unbind_buffer(target);
|
||||
} else {
|
||||
// search for an existing buffer
|
||||
k = kh_get(buff, list, buffer);
|
||||
glbuffer_t *buff = NULL;
|
||||
if (k == kh_end(list)){
|
||||
k = kh_put(buff, list, buffer, &ret);
|
||||
buff = kh_value(list, k) = malloc(sizeof(glbuffer_t));
|
||||
buff->buffer = buffer;
|
||||
buff->type = target;
|
||||
buff->data = NULL;
|
||||
buff->usage = GL_STATIC_DRAW;
|
||||
buff->size = 0;
|
||||
buff->access = GL_READ_WRITE;
|
||||
buff->mapped = 0;
|
||||
buff->real_buffer = 0;
|
||||
} else {
|
||||
buff = kh_value(list, k);
|
||||
buff->type = target; //TODO: check if old binding?
|
||||
}
|
||||
bind_buffer(target, buff);
|
||||
}
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
|
||||
DBG(printf("glBufferData(%s, %zi, %p, %s)\n", PrintEnum(target), size, data, PrintEnum(usage));)
|
||||
if (!buffer_target(target)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
glbuffer_t *buff = getbuffer_buffer(target);
|
||||
if (buff==NULL) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
LOGE("Warning, null buffer for target=0x%04X for glBufferData\n", target);
|
||||
return;
|
||||
}
|
||||
if(target==GL_ARRAY_BUFFER)
|
||||
VaoSharedClear(glstate->vao);
|
||||
|
||||
int go_real = 0;
|
||||
if( (target==GL_ARRAY_BUFFER || target==GL_ELEMENT_ARRAY_BUFFER)
|
||||
&& (usage==GL_STREAM_DRAW || usage==GL_STATIC_DRAW || usage==GL_DYNAMIC_DRAW) && globals4es.usevbo)
|
||||
go_real = 1;
|
||||
|
||||
if(buff->real_buffer && !go_real) {
|
||||
rebind_real_buff_arrays(buff->real_buffer, 0);
|
||||
|
||||
deleteSingleBuffer(buff->real_buffer);
|
||||
// what about VA already pointing there?
|
||||
buff->real_buffer = 0;
|
||||
}
|
||||
if(go_real) {
|
||||
if(!buff->real_buffer) {
|
||||
LOAD_GLES(glGenBuffers);
|
||||
gles_glGenBuffers(1, &buff->real_buffer);
|
||||
}
|
||||
LOAD_GLES(glBufferData);
|
||||
LOAD_GLES(glBindBuffer);
|
||||
bindBuffer(target, buff->real_buffer);
|
||||
gles_glBufferData(target, size, data, usage);
|
||||
DBG(printf(" => real VBO %d\n", buff->real_buffer);)
|
||||
}
|
||||
|
||||
if (buff->data && buff->size<size) {
|
||||
free(buff->data);
|
||||
buff->data = NULL;
|
||||
}
|
||||
if(!buff->data)
|
||||
buff->data = malloc(size);
|
||||
buff->size = size;
|
||||
buff->usage = usage;
|
||||
DBG(printf("\t buff->data = %p (size=%zd)\n", buff->data, size);)
|
||||
buff->access = GL_READ_WRITE;
|
||||
if (data)
|
||||
memcpy(buff->data, data, size);
|
||||
// update binded VA
|
||||
for (int i=0; i<hardext.maxvattrib; ++i) {
|
||||
vertexattrib_t *v = &glstate->vao->vertexattrib[i];
|
||||
if( v->buffer == buff ) {
|
||||
v->real_buffer = v->buffer->real_buffer;
|
||||
// do not update real_pointer, as it's the relative start in the buffer
|
||||
}
|
||||
}
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glNamedBufferData(GLuint buffer, GLsizeiptr size, const GLvoid * data, GLenum usage) {
|
||||
DBG(printf("glNamedBufferData(%u, %zi, %p, %s)\n", buffer, size, data, PrintEnum(usage));)
|
||||
glbuffer_t *buff = getbuffer_id(buffer);
|
||||
if (buff==NULL) {
|
||||
DBG(printf("Named Buffer not found\n");)
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
if (buff->data) {
|
||||
free(buff->data);
|
||||
|
||||
}
|
||||
int go_real = 0;
|
||||
if( (buff->type==GL_ARRAY_BUFFER || buff->type==GL_ELEMENT_ARRAY_BUFFER)
|
||||
&& (usage==GL_STREAM_DRAW || usage==GL_STATIC_DRAW || usage==GL_DYNAMIC_DRAW) && globals4es.usevbo)
|
||||
go_real = 1;
|
||||
|
||||
if(buff->real_buffer && !go_real) {
|
||||
deleteSingleBuffer(buff->real_buffer);
|
||||
// what about VA already pointing there?
|
||||
buff->real_buffer = 0;
|
||||
}
|
||||
if(go_real) {
|
||||
if(!buff->real_buffer) {
|
||||
LOAD_GLES(glGenBuffers);
|
||||
gles_glGenBuffers(1, &buff->real_buffer);
|
||||
}
|
||||
LOAD_GLES(glBufferData);
|
||||
LOAD_GLES(glBindBuffer);
|
||||
bindBuffer(buff->type, buff->real_buffer);
|
||||
gles_glBufferData(buff->type, size, data, usage);
|
||||
}
|
||||
|
||||
buff->size = size;
|
||||
buff->usage = usage;
|
||||
buff->data = malloc(size);
|
||||
buff->access = GL_READ_WRITE;
|
||||
if (data)
|
||||
memcpy(buff->data, data, size);
|
||||
// update binded VA
|
||||
for (int i=0; i<hardext.maxvattrib; ++i) {
|
||||
vertexattrib_t *v = &glstate->vao->vertexattrib[i];
|
||||
if( v->buffer == buff ) {
|
||||
v->real_buffer = v->buffer->real_buffer;
|
||||
// do not update real_pointer, as it's the relative start in the buffer
|
||||
}
|
||||
}
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
|
||||
DBG(printf("glBufferSubData(%s, %p, %zi, %p)\n", PrintEnum(target), (void*)offset, size, data);)
|
||||
if (!buffer_target(target)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
glbuffer_t *buff = getbuffer_buffer(target);
|
||||
if (buff==NULL) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
DBG(printf("LIBGL: Warning, null buffer for target=0x%04X for glBufferSubData\n", target);)
|
||||
return;
|
||||
}
|
||||
|
||||
if(target==GL_ARRAY_BUFFER)
|
||||
VaoSharedClear(glstate->vao);
|
||||
|
||||
if (offset<0 || size<0 || offset+size>buff->size) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if((target==GL_ARRAY_BUFFER || target==GL_ELEMENT_ARRAY_BUFFER) && buff->real_buffer) {
|
||||
LOAD_GLES(glBufferSubData);
|
||||
LOAD_GLES(glBindBuffer);
|
||||
bindBuffer(target, buff->real_buffer);
|
||||
gles_glBufferSubData(target, offset, size, data);
|
||||
}
|
||||
|
||||
memcpy((char*)buff->data + offset, data, size);
|
||||
noerrorShim();
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
|
||||
DBG(printf("glNamedBufferSubData(%u, %p, %zi, %p)\n", buffer, (void*)offset, size, data);)
|
||||
glbuffer_t *buff = getbuffer_id(buffer);
|
||||
if (buff==NULL) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset<0 || size<0 || offset+size>buff->size) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if((buff->type==GL_ARRAY_BUFFER || buff->type==GL_ELEMENT_ARRAY_BUFFER) && buff->real_buffer) {
|
||||
LOAD_GLES(glBufferSubData);
|
||||
LOAD_GLES(glBindBuffer);
|
||||
bindBuffer(buff->type, buff->real_buffer);
|
||||
gles_glBufferSubData(buff->type, offset, size, data);
|
||||
}
|
||||
memcpy((char*)buff->data + offset, data, size);
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDeleteBuffers(GLsizei n, const GLuint * buffers) {
|
||||
DBG(printf("glDeleteBuffers(%i, %p)\n", n, buffers);)
|
||||
if(!glstate) return;
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
VaoSharedClear(glstate->vao);
|
||||
khash_t(buff) *list = glstate->buffers;
|
||||
if (list) {
|
||||
khint_t k;
|
||||
glbuffer_t *buff;
|
||||
for (int i = 0; i < n; i++) {
|
||||
GLuint t = buffers[i];
|
||||
DBG(printf("\t deleting %d\n", t);)
|
||||
if (t) { // don't allow to remove default one
|
||||
k = kh_get(buff, list, t);
|
||||
if (k != kh_end(list)) {
|
||||
buff = kh_value(list, k);
|
||||
if(buff->real_buffer) {
|
||||
rebind_real_buff_arrays(buff->real_buffer, 0); // unbind
|
||||
LOAD_GLES(glDeleteBuffers);
|
||||
deleteSingleBuffer(buff->real_buffer);
|
||||
}
|
||||
if (glstate->vao->vertex == buff)
|
||||
glstate->vao->vertex = NULL;
|
||||
if (glstate->vao->elements == buff)
|
||||
glstate->vao->elements = NULL;
|
||||
if (glstate->vao->pack == buff)
|
||||
glstate->vao->pack = NULL;
|
||||
if (glstate->vao->unpack == buff)
|
||||
glstate->vao->unpack = NULL;
|
||||
for (int j = 0; j < hardext.maxvattrib; j++)
|
||||
if (glstate->vao->vertexattrib[j].buffer == buff) {
|
||||
glstate->vao->vertexattrib[j].buffer = NULL;
|
||||
glstate->vao->vertexattrib[j].real_buffer = 0;
|
||||
glstate->vao->vertexattrib[j].real_pointer = 0;
|
||||
}
|
||||
DBG(printf("\t buff->data = %p\n", buff->data);)
|
||||
if (buff->data) free(buff->data);
|
||||
kh_del(buff, list, k);
|
||||
free(buff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DBG(printf("\t done\n");)
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsBuffer(GLuint buffer) {
|
||||
DBG(printf("glIsBuffer(%u)\n", buffer);)
|
||||
khash_t(buff) *list = glstate->buffers;
|
||||
khint_t k;
|
||||
noerrorShim();
|
||||
if (list) {
|
||||
k = kh_get(buff, list, buffer);
|
||||
if (k != kh_end(list)) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void bufferGetParameteriv(glbuffer_t* buff, GLenum value, GLint * data) {
|
||||
noerrorShim();
|
||||
switch (value) {
|
||||
case GL_BUFFER_ACCESS:
|
||||
data[0] = buff->access;
|
||||
break;
|
||||
case GL_BUFFER_ACCESS_FLAGS:
|
||||
data[0] = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
|
||||
break;
|
||||
case GL_BUFFER_MAPPED:
|
||||
data[0]=(buff->mapped)?GL_TRUE:GL_FALSE;
|
||||
break;
|
||||
case GL_BUFFER_MAP_LENGTH:
|
||||
data[0]=(buff->mapped)?buff->size:0;
|
||||
break;
|
||||
case GL_BUFFER_MAP_OFFSET:
|
||||
data[0]=0;
|
||||
break;
|
||||
case GL_BUFFER_SIZE:
|
||||
data[0] = buff->size;
|
||||
break;
|
||||
case GL_BUFFER_USAGE:
|
||||
data[0] = buff->usage;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
/* TODO Error if something else */
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetBufferParameteriv(GLenum target, GLenum value, GLint * data) {
|
||||
DBG(printf("glGetBufferParameteriv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(value), data);)
|
||||
if (!buffer_target(target)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
glbuffer_t* buff = getbuffer_buffer(target);
|
||||
if (buff==NULL) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return; // Should generate an error!
|
||||
}
|
||||
bufferGetParameteriv(buff, value, data);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetNamedBufferParameteriv(GLuint buffer, GLenum value, GLint * data) {
|
||||
DBG(printf("glGetNamedBufferParameteriv(%u, %s, %p)\n", buffer, PrintEnum(value), data);)
|
||||
glbuffer_t* buff = getbuffer_id(buffer);
|
||||
if (buff==NULL) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return; // Should generate an error!
|
||||
}
|
||||
bufferGetParameteriv(buff, value, data);
|
||||
}
|
||||
|
||||
void* APIENTRY_GL4ES gl4es_glMapBuffer(GLenum target, GLenum access) {
|
||||
DBG(printf("glMapBuffer(%s, %s)\n", PrintEnum(target), PrintEnum(access));)
|
||||
if (!buffer_target(target)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return (void*)NULL;
|
||||
}
|
||||
|
||||
if(target==GL_ARRAY_BUFFER)
|
||||
VaoSharedClear(glstate->vao);
|
||||
|
||||
glbuffer_t *buff = getbuffer_buffer(target);
|
||||
if (buff==NULL) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return NULL;
|
||||
}
|
||||
if(buff->mapped) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return NULL;
|
||||
}
|
||||
buff->access = access; // not used
|
||||
buff->mapped = 1;
|
||||
buff->ranged = 0;
|
||||
noerrorShim();
|
||||
return buff->data; // Not nice, should do some copy or something probably
|
||||
}
|
||||
void* APIENTRY_GL4ES gl4es_glMapNamedBuffer(GLuint buffer, GLenum access) {
|
||||
DBG(printf("glMapNamedBuffer(%u, %s)\n", buffer, PrintEnum(access));)
|
||||
|
||||
glbuffer_t *buff = getbuffer_id(buffer);
|
||||
if (buff==NULL) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return NULL;
|
||||
}
|
||||
if(buff->mapped) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return NULL;
|
||||
}
|
||||
buff->access = access; // not used
|
||||
buff->mapped = 1;
|
||||
buff->ranged = 0;
|
||||
noerrorShim();
|
||||
return buff->data; // Not nice, should do some copy or something probably
|
||||
}
|
||||
|
||||
GLboolean APIENTRY_GL4ES gl4es_glUnmapBuffer(GLenum target) {
|
||||
DBG(printf("glUnmapBuffer(%s)\n", PrintEnum(target));)
|
||||
if(glstate->list.compiling) {errorShim(GL_INVALID_OPERATION); return GL_FALSE;}
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
if (!buffer_target(target)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if(target==GL_ARRAY_BUFFER)
|
||||
VaoSharedClear(glstate->vao);
|
||||
|
||||
glbuffer_t *buff = getbuffer_buffer(target);
|
||||
if (buff==NULL) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return GL_FALSE;
|
||||
}
|
||||
noerrorShim();
|
||||
if(buff->real_buffer && (buff->type==GL_ARRAY_BUFFER || buff->type==GL_ELEMENT_ARRAY_BUFFER) && buff->mapped && !buff->ranged && (buff->access==GL_WRITE_ONLY || buff->access==GL_READ_WRITE)) {
|
||||
LOAD_GLES(glBufferSubData);
|
||||
LOAD_GLES(glBindBuffer);
|
||||
bindBuffer(buff->type, buff->real_buffer);
|
||||
gles_glBufferSubData(buff->type, 0, buff->size, buff->data);
|
||||
}
|
||||
if(buff->real_buffer && (buff->type==GL_ARRAY_BUFFER || buff->type==GL_ELEMENT_ARRAY_BUFFER) && buff->mapped && buff->ranged && (buff->access&GL_MAP_WRITE_BIT_EXT) && !(buff->access&GL_MAP_FLUSH_EXPLICIT_BIT_EXT)) {
|
||||
LOAD_GLES(glBufferSubData);
|
||||
bindBuffer(buff->type, buff->real_buffer);
|
||||
gles_glBufferSubData(buff->type, buff->offset, buff->length, (void*)((uintptr_t)buff->data+buff->offset));
|
||||
}
|
||||
if (buff->mapped) {
|
||||
buff->mapped = 0;
|
||||
buff->ranged = 0;
|
||||
return GL_TRUE;
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
GLboolean APIENTRY_GL4ES gl4es_glUnmapNamedBuffer(GLuint buffer) {
|
||||
DBG(printf("glUnmapNamedBuffer(%u)\n", buffer);)
|
||||
if(glstate->list.compiling) {errorShim(GL_INVALID_OPERATION); return GL_FALSE;}
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
glbuffer_t *buff = getbuffer_id(buffer);
|
||||
if (buff==NULL)
|
||||
return GL_FALSE; // Should generate an error!
|
||||
noerrorShim();
|
||||
if(buff->real_buffer && (buff->type==GL_ARRAY_BUFFER || buff->type==GL_ELEMENT_ARRAY_BUFFER) && buff->mapped && (buff->access==GL_WRITE_ONLY || buff->access==GL_READ_WRITE)) {
|
||||
LOAD_GLES(glBufferSubData);
|
||||
LOAD_GLES(glBindBuffer);
|
||||
bindBuffer(buff->type, buff->real_buffer);
|
||||
gles_glBufferSubData(buff->type, 0, buff->size, buff->data);
|
||||
}
|
||||
if(buff->real_buffer && (buff->type==GL_ARRAY_BUFFER || buff->type==GL_ELEMENT_ARRAY_BUFFER) && buff->mapped && buff->ranged && (buff->access&GL_MAP_WRITE_BIT_EXT) && !(buff->access&GL_MAP_FLUSH_EXPLICIT_BIT_EXT)) {
|
||||
LOAD_GLES(glBufferSubData);
|
||||
LOAD_GLES(glBindBuffer);
|
||||
bindBuffer(buff->type, buff->real_buffer);
|
||||
gles_glBufferSubData(buff->type, buff->offset, buff->length, (void*)((uintptr_t)buff->data+buff->offset));
|
||||
}
|
||||
if (buff->mapped) {
|
||||
buff->mapped = 0;
|
||||
buff->ranged = 0;
|
||||
return GL_TRUE;
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid * data) {
|
||||
DBG(printf("glGetBufferSubData(%s, %p, %zi, %p)\n", PrintEnum(target), (void*)offset, size, data);)
|
||||
if (!buffer_target(target)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
glbuffer_t *buff = getbuffer_buffer(target);
|
||||
|
||||
if (buff==NULL)
|
||||
return; // Should generate an error!
|
||||
// TODO, check parameter consistancie
|
||||
memcpy(data, (char*)buff->data+offset, size);
|
||||
noerrorShim();
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid * data) {
|
||||
DBG(printf("glGetNamedBufferSubData(%u, %p, %zi, %p)\n", buffer, (void*)offset, size, data);)
|
||||
glbuffer_t *buff = getbuffer_id(buffer);
|
||||
|
||||
if (buff==NULL)
|
||||
return; // Should generate an error!
|
||||
// TODO, check parameter consistancie
|
||||
memcpy(data, (char*)buff->data+offset, size);
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetBufferPointerv(GLenum target, GLenum pname, GLvoid ** params) {
|
||||
DBG(printf("glGetBufferPointerv(%s, %s, %p)\n", PrintEnum(target), PrintEnum(pname), params);)
|
||||
if (!buffer_target(target)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
glbuffer_t *buff = getbuffer_buffer(target);
|
||||
if (buff==NULL)
|
||||
return; // Should generate an error!
|
||||
if (pname != GL_BUFFER_MAP_POINTER) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if (!buff->mapped) {
|
||||
params[0] = NULL;
|
||||
} else {
|
||||
params[0] = buff->data;
|
||||
}
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetNamedBufferPointerv(GLuint buffer, GLenum pname, GLvoid ** params) {
|
||||
DBG(printf("glGetNamedBufferPointerv(%u, %s, %p)\n", buffer, PrintEnum(pname), params);)
|
||||
glbuffer_t *buff = getbuffer_id(buffer);
|
||||
if (buff==NULL)
|
||||
return; // Should generate an error!
|
||||
if (pname != GL_BUFFER_MAP_POINTER) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if (!buff->mapped) {
|
||||
params[0] = NULL;
|
||||
} else {
|
||||
params[0] = buff->data;
|
||||
}
|
||||
}
|
||||
|
||||
void* APIENTRY_GL4ES gl4es_glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
|
||||
{
|
||||
DBG(printf("glMapBufferRange(%s, %p, %zd, 0x%x)\n", PrintEnum(target), (void*)offset, length, access);)
|
||||
if (!buffer_target(target)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
glbuffer_t *buff = getbuffer_buffer(target);
|
||||
if (buff==NULL) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return NULL; // Should generate an error!
|
||||
}
|
||||
if(buff->mapped) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return NULL;
|
||||
}
|
||||
buff->access = access;
|
||||
buff->mapped = 1;
|
||||
buff->ranged = 1;
|
||||
buff->offset = offset;
|
||||
buff->length = length;
|
||||
noerrorShim();
|
||||
uintptr_t ret = (uintptr_t)buff->data;
|
||||
ret += offset;
|
||||
return (void*)ret;
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
|
||||
{
|
||||
DBG(printf("glFlushMappedBufferRange(%s, %p, %zd)\n", PrintEnum(target), (void*)offset, length);)
|
||||
if (!buffer_target(target)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
|
||||
if(target==GL_ARRAY_BUFFER)
|
||||
VaoSharedClear(glstate->vao);
|
||||
|
||||
glbuffer_t *buff = getbuffer_buffer(target);
|
||||
if(!buff) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(!buff->mapped || !buff->ranged || !(buff->access&GL_MAP_FLUSH_EXPLICIT_BIT_EXT)) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
if(buff->real_buffer && (buff->type==GL_ARRAY_BUFFER || buff->type==GL_ELEMENT_ARRAY_BUFFER) && (buff->access&GL_MAP_WRITE_BIT_EXT)) {
|
||||
LOAD_GLES(glBufferSubData);
|
||||
bindBuffer(buff->type, buff->real_buffer);
|
||||
gles_glBufferSubData(buff->type, buff->offset+offset, length, (void*)((uintptr_t)buff->data+buff->offset+offset));
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
|
||||
{
|
||||
DBG(printf("glCopyBufferSubData(%s, %s, %p, %p, %zd)\n", PrintEnum(readTarget), PrintEnum(writeTarget), (void*)readOffset, (void*)writeOffset, size);)
|
||||
//TODO: Add GL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER (and GL_QUERY_BUFFER?)
|
||||
glbuffer_t *readbuff = getbuffer_buffer(readTarget);
|
||||
glbuffer_t *writebuff = getbuffer_buffer(writeTarget);
|
||||
if(!readbuff || !writebuff) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(writebuff->ranged && !(writebuff->access&GL_MAP_PERSISTENT_BIT)) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
// TODO: check memory overlap and overread/overwrite
|
||||
memcpy((char*)writebuff->data+writeOffset, (char*)readbuff->data+readOffset, size);
|
||||
if(writebuff->real_buffer && (writebuff->type==GL_ARRAY_BUFFER || writebuff->type==GL_ELEMENT_ARRAY_BUFFER) && writebuff->mapped && (writebuff->access==GL_WRITE_ONLY || writebuff->access==GL_READ_WRITE)) {
|
||||
LOAD_GLES(glBufferSubData);
|
||||
bindBuffer(writebuff->type, writebuff->real_buffer);
|
||||
gles_glBufferSubData(writebuff->type, writeOffset, size, (char*)writebuff->data+writeOffset);
|
||||
}
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
void bindBuffer(GLenum target, GLuint buffer)
|
||||
{
|
||||
LOAD_GLES(glBindBuffer);
|
||||
if(target==GL_ARRAY_BUFFER) {
|
||||
if(glstate->bind_buffer.array == buffer)
|
||||
return;
|
||||
DBG(printf("Bind buffer %d to GL_ARRAY_BUFFER\n", buffer);)
|
||||
glstate->bind_buffer.array = buffer;
|
||||
gles_glBindBuffer(target, buffer);
|
||||
|
||||
} else if (target==GL_ELEMENT_ARRAY_BUFFER) {
|
||||
glstate->bind_buffer.want_index = buffer;
|
||||
if(glstate->bind_buffer.index == buffer)
|
||||
return;
|
||||
glstate->bind_buffer.index = buffer;
|
||||
DBG(printf("Bind buffer %d to GL_ELEMENT_ARRAY_BUFFER\n", buffer);)
|
||||
gles_glBindBuffer(target, buffer);
|
||||
} else {
|
||||
LOGE("Warning, unhandled Buffer type %s in bindBuffer\n", PrintEnum(target));
|
||||
return;
|
||||
}
|
||||
glstate->bind_buffer.used = (glstate->bind_buffer.index && glstate->bind_buffer.array)?1:0;
|
||||
}
|
||||
|
||||
GLuint wantBufferIndex(GLuint buffer)
|
||||
{
|
||||
GLuint ret = glstate->bind_buffer.want_index;
|
||||
glstate->bind_buffer.want_index = buffer;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void realize_bufferIndex()
|
||||
{
|
||||
LOAD_GLES(glBindBuffer);
|
||||
if(glstate->bind_buffer.index != glstate->bind_buffer.want_index) {
|
||||
glstate->bind_buffer.index = glstate->bind_buffer.want_index;
|
||||
gles_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glstate->bind_buffer.index);
|
||||
DBG(printf("Bind buffer %d to GL_ELEMENT_ARRAY_BUFFER\n", glstate->bind_buffer.index);)
|
||||
glstate->bind_buffer.used = (glstate->bind_buffer.index && glstate->bind_buffer.array)?1:0;
|
||||
}
|
||||
}
|
||||
|
||||
void deleteSingleBuffer(GLuint buffer) {
|
||||
LOAD_GLES(glDeleteBuffers);
|
||||
if(glstate->bind_buffer.index == buffer) glstate->bind_buffer.index = 0;
|
||||
else if(glstate->bind_buffer.want_index == buffer) glstate->bind_buffer.want_index = 0;
|
||||
else if(glstate->bind_buffer.array == buffer) glstate->bind_buffer.array = 0;
|
||||
gles_glDeleteBuffers(1, &buffer);
|
||||
}
|
||||
|
||||
void unboundBuffers()
|
||||
{
|
||||
if(!glstate->bind_buffer.used)
|
||||
return;
|
||||
LOAD_GLES(glBindBuffer);
|
||||
if(glstate->bind_buffer.array) {
|
||||
glstate->bind_buffer.array = 0;
|
||||
gles_glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
DBG(printf("Bind buffer %d to GL_ARRAY_BUFFER\n", 0);)
|
||||
}
|
||||
if(glstate->bind_buffer.index) {
|
||||
glstate->bind_buffer.index = 0;
|
||||
glstate->bind_buffer.want_index = 0;
|
||||
gles_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
DBG(printf("Bind buffer %d to GL_ELEMENT_ARRAY_BUFFER\n", 0);)
|
||||
}
|
||||
glstate->bind_buffer.used = 0;
|
||||
}
|
||||
|
||||
|
||||
//Direct wrapper
|
||||
AliasExport(void,glGenBuffers,,(GLsizei n, GLuint * buffers));
|
||||
AliasExport(void,glBindBuffer,,(GLenum target, GLuint buffer));
|
||||
AliasExport(void,glBufferData,,(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage));
|
||||
AliasExport(void,glBufferSubData,,(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data));
|
||||
AliasExport(void,glDeleteBuffers,,(GLsizei n, const GLuint * buffers));
|
||||
AliasExport(GLboolean,glIsBuffer,,(GLuint buffer));
|
||||
AliasExport(void,glGetBufferParameteriv,,(GLenum target, GLenum value, GLint * data));
|
||||
AliasExport(void*,glMapBuffer,,(GLenum target, GLenum access));
|
||||
AliasExport(GLboolean,glUnmapBuffer,,(GLenum target));
|
||||
AliasExport(void,glGetBufferSubData,,(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid * data));
|
||||
AliasExport(void,glGetBufferPointerv,,(GLenum target, GLenum pname, GLvoid ** params));
|
||||
|
||||
AliasExport(void*,glMapBufferRange,,(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access));
|
||||
AliasExport(void,glFlushMappedBufferRange,,(GLenum target, GLintptr offset, GLsizeiptr length));
|
||||
|
||||
AliasExport(void,glCopyBufferSubData,,(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size));
|
||||
//ARB wrapper
|
||||
#ifndef AMIGAOS4
|
||||
AliasExport(void,glGenBuffers,ARB,(GLsizei n, GLuint * buffers));
|
||||
AliasExport(void,glBindBuffer,ARB,(GLenum target, GLuint buffer));
|
||||
AliasExport(void,glBufferData,ARB,(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage));
|
||||
AliasExport(void,glBufferSubData,ARB,(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data));
|
||||
AliasExport(void,glDeleteBuffers,ARB,(GLsizei n, const GLuint * buffers));
|
||||
AliasExport(GLboolean,glIsBuffer,ARB,(GLuint buffer));
|
||||
AliasExport(void,glGetBufferParameteriv,ARB,(GLenum target, GLenum value, GLint * data));
|
||||
AliasExport(void*,glMapBuffer,ARB,(GLenum target, GLenum access));
|
||||
AliasExport(GLboolean,glUnmapBuffer,ARB,(GLenum target));
|
||||
AliasExport(void,glGetBufferSubData,ARB,(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid * data));
|
||||
AliasExport(void,glGetBufferPointerv,ARB,(GLenum target, GLenum pname, GLvoid ** params));
|
||||
#endif
|
||||
|
||||
//Direct Access
|
||||
AliasExport(void,glNamedBufferData,,(GLuint buffer, GLsizeiptr size, const GLvoid * data, GLenum usage));
|
||||
AliasExport(void,glNamedBufferSubData,,(GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid * data));
|
||||
AliasExport(void,glGetNamedBufferParameteriv,,(GLuint buffer, GLenum value, GLint * data));
|
||||
AliasExport(void*,glMapNamedBuffer,,(GLuint buffer, GLenum access));
|
||||
AliasExport(GLboolean,glUnmapNamedBuffer,,(GLuint buffer));
|
||||
AliasExport(void,glGetNamedBufferSubData,,(GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid * data));
|
||||
AliasExport(void,glGetNamedBufferPointerv,,(GLuint buffer, GLenum pname, GLvoid ** params));
|
||||
|
||||
AliasExport(void,glNamedBufferData,EXT,(GLuint buffer, GLsizeiptr size, const GLvoid * data, GLenum usage));
|
||||
AliasExport(void,glNamedBufferSubData,EXT,(GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid * data));
|
||||
AliasExport(void,glGetNamedBufferParameteriv,EXT,(GLuint buffer, GLenum value, GLint * data));
|
||||
AliasExport(void*,glMapNamedBuffer,EXT,(GLuint buffer, GLenum access));
|
||||
AliasExport(GLboolean,glUnmapNamedBuffer,EXT,(GLuint buffer));
|
||||
AliasExport(void,glGetNamedBufferSubData,EXT,(GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid * data));
|
||||
AliasExport(void,glGetNamedBufferPointerv,EXT,(GLuint buffer, GLenum pname, GLvoid ** params));
|
||||
|
||||
|
||||
// VAO ****************
|
||||
static GLuint lastvao = 1;
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGenVertexArrays(GLsizei n, GLuint *arrays) {
|
||||
DBG(printf("glGenVertexArrays(%i, %p)\n", n, arrays);)
|
||||
noerrorShim();
|
||||
if (n<1) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
for (int i=0; i<n; i++) { // TODO: create VAO here and check unicity
|
||||
arrays[i] = lastvao++;
|
||||
}
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glBindVertexArray(GLuint array) {
|
||||
DBG(printf("glBindVertexArray(%u)\n", array);)
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
khint_t k;
|
||||
int ret;
|
||||
khash_t(glvao) *list = glstate->vaos;
|
||||
// if array = 0 => unbind buffer!
|
||||
if (array == 0) {
|
||||
// unbind buffer
|
||||
glstate->vao = glstate->defaultvao;
|
||||
} else {
|
||||
// search for an existing buffer
|
||||
k = kh_get(glvao, list, array);
|
||||
glvao_t *glvao = NULL;
|
||||
if (k == kh_end(list)){
|
||||
k = kh_put(glvao, list, array, &ret);
|
||||
glvao = kh_value(list, k) = malloc(sizeof(glvao_t));
|
||||
// new vao is binded to nothing
|
||||
VaoInit(glvao);
|
||||
// Copy current status to new VAO
|
||||
glvao->vertex = glstate->vao->vertex;
|
||||
glvao->elements = glstate->vao->elements;
|
||||
glvao->pack = glstate->vao->pack;
|
||||
glvao->unpack = glstate->vao->unpack;
|
||||
glvao->maxtex = glstate->vao->maxtex;
|
||||
|
||||
// just put is number
|
||||
glvao->array = array;
|
||||
} else {
|
||||
glvao = kh_value(list, k);
|
||||
}
|
||||
glstate->vao = glvao;
|
||||
}
|
||||
|
||||
noerrorShim();
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glDeleteVertexArrays(GLsizei n, const GLuint *arrays) {
|
||||
DBG(printf("glDeleteVertexArrays(%i, %p)\n", n, arrays);)
|
||||
if(!glstate) return;
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
khash_t(glvao) *list = glstate->vaos;
|
||||
if (list) {
|
||||
khint_t k;
|
||||
glvao_t *glvao;
|
||||
for (int i = 0; i < n; i++) {
|
||||
GLuint t = arrays[i];
|
||||
if (t) { // don't allow to remove the default one
|
||||
k = kh_get(glvao, list, t);
|
||||
if (k != kh_end(list)) {
|
||||
glvao = kh_value(list, k);
|
||||
VaoSharedClear(glvao);
|
||||
kh_del(glvao, list, k);
|
||||
//free(glvao); //let the use delete those
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
noerrorShim();
|
||||
}
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsVertexArray(GLuint array) {
|
||||
DBG(printf("glIsVertexArray(%u)\n", array);)
|
||||
if(!glstate)
|
||||
return GL_FALSE;
|
||||
khash_t(glvao) *list = glstate->vaos;
|
||||
khint_t k;
|
||||
noerrorShim();
|
||||
if (list) {
|
||||
k = kh_get(glvao, list, array);
|
||||
if (k != kh_end(list)) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
void VaoSharedClear(glvao_t *vao) {
|
||||
if(vao==NULL || vao->shared_arrays==NULL)
|
||||
return;
|
||||
if(!(--(*vao->shared_arrays))) {
|
||||
free(vao->vert.ptr);
|
||||
free(vao->color.ptr);
|
||||
free(vao->secondary.ptr);
|
||||
free(vao->normal.ptr);
|
||||
for (int i=0; i<hardext.maxtex; i++)
|
||||
free(vao->tex[i].ptr);
|
||||
free(vao->shared_arrays);
|
||||
}
|
||||
vao->vert.ptr = NULL;
|
||||
vao->color.ptr = NULL;
|
||||
vao->secondary.ptr = NULL;
|
||||
vao->normal.ptr = NULL;
|
||||
for (int i=0; i<hardext.maxtex; i++)
|
||||
vao->tex[i].ptr = NULL;
|
||||
vao->shared_arrays = NULL;
|
||||
}
|
||||
|
||||
void VaoInit(glvao_t *vao) {
|
||||
memset(vao, 0, sizeof(glvao_t));
|
||||
for (int i=0; i<hardext.maxvattrib; i++) {
|
||||
vao->vertexattrib[i].size = 4;
|
||||
vao->vertexattrib[i].type = GL_FLOAT;
|
||||
}
|
||||
}
|
||||
|
||||
//Direct wrapper
|
||||
AliasExport(void,glGenVertexArrays,,(GLsizei n, GLuint *arrays));
|
||||
AliasExport(void,glBindVertexArray,,(GLuint array));
|
||||
AliasExport(void,glDeleteVertexArrays,,(GLsizei n, const GLuint *arrays));
|
||||
AliasExport(GLboolean,glIsVertexArray,,(GLuint array));
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
#ifndef _GL4ES_BUFFERS_H_
|
||||
#define _GL4ES_BUFFERS_H_
|
||||
|
||||
#include "khash.h"
|
||||
#include "../config.h"
|
||||
#include "gles.h"
|
||||
|
||||
// VBO *****************
|
||||
typedef struct {
|
||||
GLuint buffer;
|
||||
GLuint real_buffer;
|
||||
GLenum type;
|
||||
GLsizeiptr size;
|
||||
GLenum usage;
|
||||
GLint access;
|
||||
int mapped;
|
||||
int ranged;
|
||||
GLintptr offset;
|
||||
GLsizeiptr length;
|
||||
GLvoid *data;
|
||||
} glbuffer_t;
|
||||
|
||||
KHASH_MAP_DECLARE_INT(buff, glbuffer_t *);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGenBuffers(GLsizei n, GLuint * buffers);
|
||||
void APIENTRY_GL4ES gl4es_glBindBuffer(GLenum target, GLuint buffer);
|
||||
void APIENTRY_GL4ES gl4es_glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
|
||||
void APIENTRY_GL4ES gl4es_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
|
||||
void APIENTRY_GL4ES gl4es_glDeleteBuffers(GLsizei n, const GLuint * buffers);
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsBuffer(GLuint buffer);
|
||||
void APIENTRY_GL4ES gl4es_glGetBufferParameteriv(GLenum target, GLenum value, GLint * data);
|
||||
|
||||
void* APIENTRY_GL4ES gl4es_glMapBuffer(GLenum target, GLenum access);
|
||||
GLboolean APIENTRY_GL4ES gl4es_glUnmapBuffer(GLenum target);
|
||||
void APIENTRY_GL4ES gl4es_glGetBufferPointerv(GLenum target, GLenum pname, GLvoid ** params);
|
||||
void APIENTRY_GL4ES gl4es_glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid * data);
|
||||
|
||||
void* APIENTRY_GLES gl4es_glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
|
||||
void APIENTRY_GL4ES gl4es_glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
|
||||
|
||||
void APIENTRY_GL4ES glGenBuffers(GLsizei n, GLuint * buffers);
|
||||
void APIENTRY_GL4ES glBindBuffer(GLenum target, GLuint buffer);
|
||||
void APIENTRY_GL4ES glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
|
||||
void APIENTRY_GL4ES glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
|
||||
void APIENTRY_GL4ES glDeleteBuffers(GLsizei n, const GLuint * buffers);
|
||||
GLboolean APIENTRY_GL4ES glIsBuffer(GLuint buffer);
|
||||
void APIENTRY_GL4ES glGetBufferParameteriv(GLenum target, GLenum value, GLint * data);
|
||||
void* APIENTRY_GL4ES glMapBuffer(GLenum target, GLenum access);
|
||||
GLboolean APIENTRY_GL4ES glUnmapBuffer(GLenum target);
|
||||
void APIENTRY_GL4ES glGetBufferPointerv(GLenum target, GLenum pname, GLvoid ** params);
|
||||
void APIENTRY_GL4ES glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid * data);
|
||||
|
||||
void* APIENTRY_GL4ES glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
|
||||
void APIENTRY_GL4ES glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
|
||||
|
||||
void APIENTRY_GL4ES glGenBuffersARB(GLsizei n, GLuint * buffers);
|
||||
void APIENTRY_GL4ES glBindBufferARB(GLenum target, GLuint buffer);
|
||||
void APIENTRY_GL4ES glBufferDataARB(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
|
||||
void APIENTRY_GL4ES glBufferSubDataARB(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
|
||||
void APIENTRY_GL4ES glDeleteBuffersARB(GLsizei n, const GLuint * buffers);
|
||||
GLboolean APIENTRY_GL4ES glIsBufferARB(GLuint buffer);
|
||||
void APIENTRY_GL4ES glGetBufferParameterivARB(GLenum target, GLenum value, GLint * data);
|
||||
void* APIENTRY_GL4ES glMapBufferARB(GLenum target, GLenum access);
|
||||
GLboolean APIENTRY_GL4ES glUnmapBufferARB(GLenum target);
|
||||
void APIENTRY_GL4ES glGetBufferSubDataARB(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid * data);
|
||||
void APIENTRY_GL4ES glGetBufferPointervARB(GLenum target, GLenum pname, GLvoid ** params);
|
||||
|
||||
// internal actual BindBuffer with cache
|
||||
void bindBuffer(GLenum target, GLuint buffer);
|
||||
// delete a single buffer (and erase it from the cache)
|
||||
void deleteSingleBuffer(GLuint buffer);
|
||||
// unbound all buffer
|
||||
void unboundBuffers();
|
||||
// update wanted Index Buffer
|
||||
GLuint wantBufferIndex(GLuint buffer);
|
||||
// Bind the wanted index buffer if needed
|
||||
void realize_bufferIndex();
|
||||
|
||||
|
||||
// Pointer..... ****** => map them in vertexattrib (even with GLES1.1). So no more pointer_state_t, use vertexattrib_t
|
||||
// and map .enabled to .vaarray
|
||||
|
||||
// This map correspond to ARB_vertex_program map
|
||||
typedef enum {
|
||||
ARB_VERTEX = 0,
|
||||
//ARB_WEIGHT
|
||||
ARB_NORMAL = 2,
|
||||
ARB_COLOR,
|
||||
ARB_SECONDARY,
|
||||
ARB_FOGCOORD,
|
||||
// 6 and 7 are nothing specifics
|
||||
ARB_MULTITEXCOORD0 = 8,
|
||||
ARB_MULTITEXCOORD1,
|
||||
ARB_MULTITEXCOORD2,
|
||||
ARB_MULTITEXCOORD3,
|
||||
ARB_MULTITEXCOORD4,
|
||||
ARB_MULTITEXCOORD5,
|
||||
ARB_MULTITEXCOORD6,
|
||||
ARB_MULTITEXCOORD7,
|
||||
ARB_MULTITEXCOORD8,
|
||||
ARB_MULTITEXCOORD9,
|
||||
ARB_MULTITEXCOORD10,
|
||||
ARB_MULTITEXCOORD11,
|
||||
ARB_MULTITEXCOORD12,
|
||||
ARB_MULTITEXCOORD13,
|
||||
ARB_MULTITEXCOORD14,
|
||||
ARB_MULTITEXCOORD15,
|
||||
//ARB_POINTSIZE, //this one is supported by GLES hardware
|
||||
ARB_MAX
|
||||
} reserved_attrib_t;
|
||||
|
||||
// This map correspond tries to fit as much as possible in 8 VA
|
||||
typedef enum {
|
||||
COMP_VERTEX = 0,
|
||||
COMP_FOGCOORD,
|
||||
COMP_NORMAL,
|
||||
COMP_COLOR,
|
||||
COMP_SECONDARY,
|
||||
COMP_MULTITEXCOORD0,
|
||||
COMP_MULTITEXCOORD1,
|
||||
COMP_MULTITEXCOORD2,
|
||||
COMP_MULTITEXCOORD3,
|
||||
COMP_MULTITEXCOORD4,
|
||||
COMP_MULTITEXCOORD5,
|
||||
COMP_MULTITEXCOORD6,
|
||||
COMP_MULTITEXCOORD7,
|
||||
COMP_MULTITEXCOORD8,
|
||||
COMP_MULTITEXCOORD9,
|
||||
COMP_MULTITEXCOORD10,
|
||||
COMP_MULTITEXCOORD11,
|
||||
COMP_MULTITEXCOORD12,
|
||||
COMP_MULTITEXCOORD13,
|
||||
COMP_MULTITEXCOORD14,
|
||||
COMP_MULTITEXCOORD15,
|
||||
//COMP_WEIGHT
|
||||
//COMP_POINTSIZE, //this one is supported by GLES hardware
|
||||
COMP_MAX
|
||||
} compressed_attrib_t;
|
||||
|
||||
#define ATT_VERTEX ((hardext.maxvattrib>8)?ARB_VERTEX:COMP_VERTEX)
|
||||
#define ATT_NORMAL ((hardext.maxvattrib>8)?ARB_NORMAL:COMP_NORMAL)
|
||||
#define ATT_COLOR ((hardext.maxvattrib>8)?ARB_COLOR:COMP_COLOR)
|
||||
#define ATT_SECONDARY ((hardext.maxvattrib>8)?ARB_SECONDARY:COMP_SECONDARY)
|
||||
#define ATT_FOGCOORD ((hardext.maxvattrib>8)?ARB_FOGCOORD:COMP_FOGCOORD)
|
||||
#define ATT_MULTITEXCOORD0 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD0:COMP_MULTITEXCOORD0)
|
||||
#define ATT_MULTITEXCOORD1 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD1:COMP_MULTITEXCOORD1)
|
||||
#define ATT_MULTITEXCOORD2 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD2:COMP_MULTITEXCOORD2)
|
||||
#define ATT_MULTITEXCOORD3 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD3:COMP_MULTITEXCOORD3)
|
||||
#define ATT_MULTITEXCOORD4 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD4:COMP_MULTITEXCOORD4)
|
||||
#define ATT_MULTITEXCOORD5 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD5:COMP_MULTITEXCOORD5)
|
||||
#define ATT_MULTITEXCOORD6 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD6:COMP_MULTITEXCOORD6)
|
||||
#define ATT_MULTITEXCOORD7 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD7:COMP_MULTITEXCOORD7)
|
||||
#define ATT_MULTITEXCOORD8 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD8:COMP_MULTITEXCOORD8)
|
||||
#define ATT_MULTITEXCOORD9 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD9:COMP_MULTITEXCOORD9)
|
||||
#define ATT_MULTITEXCOORD10 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD10:COMP_MULTITEXCOORD10)
|
||||
#define ATT_MULTITEXCOORD11 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD11:COMP_MULTITEXCOORD11)
|
||||
#define ATT_MULTITEXCOORD12 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD12:COMP_MULTITEXCOORD12)
|
||||
#define ATT_MULTITEXCOORD13 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD13:COMP_MULTITEXCOORD13)
|
||||
#define ATT_MULTITEXCOORD14 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD14:COMP_MULTITEXCOORD14)
|
||||
#define ATT_MULTITEXCOORD15 ((hardext.maxvattrib>8)?ARB_MULTITEXCOORD15:COMP_MULTITEXCOORD15)
|
||||
#define ATT_MAX ARB_MAX
|
||||
|
||||
#define NB_VA (ATT_MAX)
|
||||
|
||||
// glLockArrays should lock all arrays, but Quake3 do change values on Color and Textures UV, so limit Lock to 3D" Coords arrays
|
||||
#define NB_LOCKVA (ATT_NORMAL+1)
|
||||
|
||||
// Vertex Attrib.. ***
|
||||
typedef struct {
|
||||
GLint size;
|
||||
GLenum type;
|
||||
GLsizei stride;
|
||||
const GLvoid* pointer;
|
||||
int enabled;
|
||||
int normalized;
|
||||
glbuffer_t *buffer; // reference buffer
|
||||
GLint divisor;
|
||||
GLuint real_buffer; // If there is a real VBO binded
|
||||
const GLvoid* real_pointer; // the pointer related to real VBO
|
||||
int integer;
|
||||
} vertexattrib_t;
|
||||
|
||||
typedef struct {
|
||||
GLfloat *ptr;
|
||||
vertexattrib_t state;
|
||||
int enabled;
|
||||
} pointer_cache_t;
|
||||
|
||||
// VAO ****************
|
||||
typedef struct {
|
||||
GLuint array;
|
||||
// buffer state
|
||||
glbuffer_t *vertex;
|
||||
glbuffer_t *elements;
|
||||
glbuffer_t *pack;
|
||||
glbuffer_t *unpack;
|
||||
// locked arrays
|
||||
int locked;
|
||||
GLsizei count;
|
||||
GLint first;
|
||||
int locked_mapped[NB_VA];
|
||||
|
||||
int maxtex; // upper limit enabled tex_coord
|
||||
// VAO optimisation: keep a shared copy of the digested datas (unless the vao is the default one)
|
||||
int *shared_arrays;
|
||||
pointer_cache_t vert;
|
||||
pointer_cache_t normal;
|
||||
pointer_cache_t color;
|
||||
pointer_cache_t secondary;
|
||||
pointer_cache_t fog;
|
||||
pointer_cache_t tex[MAX_TEX];
|
||||
int cache_count;
|
||||
// Vertex Attrib
|
||||
vertexattrib_t vertexattrib[MAX_VATTRIB];
|
||||
// TODO: Cache VA also?
|
||||
} glvao_t;
|
||||
|
||||
void VaoSharedClear(glvao_t *vao);
|
||||
void VaoInit(glvao_t *vao);
|
||||
|
||||
KHASH_MAP_DECLARE_INT(glvao, glvao_t*);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGenVertexArrays(GLsizei n, GLuint *arrays);
|
||||
void APIENTRY_GL4ES gl4es_glBindVertexArray(GLuint array);
|
||||
void APIENTRY_GL4ES gl4es_glDeleteVertexArrays(GLsizei n, const GLuint *arrays);
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsVertexArray(GLuint array);
|
||||
|
||||
void APIENTRY_GL4ES glGenVertexArrays(GLsizei n, GLuint *arrays);
|
||||
void APIENTRY_GL4ES glBindVertexArray(GLuint array);
|
||||
void APIENTRY_GL4ES glDeleteVertexArrays(GLsizei n, const GLuint *arrays);
|
||||
GLboolean APIENTRY_GL4ES glIsVertexArray(GLuint array);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glNamedBufferData(GLuint buffer, GLsizeiptr size, const GLvoid * data, GLenum usage);
|
||||
void APIENTRY_GL4ES gl4es_glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid * data);
|
||||
void APIENTRY_GL4ES gl4es_glGetNamedBufferParameteriv(GLuint buffer, GLenum value, GLint * data);
|
||||
void* APIENTRY_GL4ES gl4es_glMapNamedBuffer(GLuint buffer, GLenum access);
|
||||
GLboolean APIENTRY_GL4ES gl4es_glUnmapNamedBuffer(GLuint buffer);
|
||||
void APIENTRY_GL4ES gl4es_glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid * data);
|
||||
void APIENTRY_GL4ES gl4es_glGetNamedBufferPointerv(GLuint buffer, GLenum pname, GLvoid ** params);
|
||||
|
||||
#endif // _GL4ES_BUFFERS_H_
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <stdio.h>
|
||||
#include "build_info.h"
|
||||
#include "logs.h"
|
||||
#include "../../version.h"
|
||||
|
||||
void print_build_infos()
|
||||
{
|
||||
SHUT_LOGD("v%d.%d.%d built on %s %s\n", MAJOR, MINOR, REVISION, __DATE__, __TIME__);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _GL4ES_BUILD_INFO_H_
|
||||
#define _GL4ES_BUILD_INFO_H_
|
||||
|
||||
void print_build_infos();
|
||||
|
||||
#endif // _GL4ES_BUILD_INFO_H_
|
||||
@@ -0,0 +1,935 @@
|
||||
#ifndef _GL4ES_CONST_H_
|
||||
#define _GL4ES_CONST_H_
|
||||
|
||||
#define GL_QUADS 7
|
||||
#define GL_QUAD_STRIP 8
|
||||
#define GL_POLYGON 9
|
||||
|
||||
#define GL_MAJOR_VERSION 0x821B
|
||||
#define GL_MINOR_VERSION 0x821C
|
||||
#define GL_DOUBLEBUFFER 0x0C32
|
||||
/* texture mapping */
|
||||
#define GL_TEXTURE_ENV 0x2300
|
||||
#define GL_TEXTURE_ENV_MODE 0x2200
|
||||
#define GL_TEXTURE_1D 0x0DE0
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
#define GL_TEXTURE_3D 0x806F
|
||||
#define GL_TEXTURE_WRAP_S 0x2802
|
||||
#define GL_TEXTURE_WRAP_T 0x2803
|
||||
#define GL_TEXTURE_WRAP_R 0x8072
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
#define GL_TEXTURE_ENV_COLOR 0x2201
|
||||
#define GL_TEXTURE_GEN_S 0x0C60
|
||||
#define GL_TEXTURE_GEN_T 0x0C61
|
||||
#define GL_TEXTURE_GEN_MODE 0x2500
|
||||
#define GL_TEXTURE_BORDER_COLOR 0x1004
|
||||
#define GL_TEXTURE_BORDER 0x1005
|
||||
#define GL_TEXTURE_WIDTH 0x1000
|
||||
#define GL_TEXTURE_HEIGHT 0x1001
|
||||
#define GL_TEXTURE_BORDER 0x1005
|
||||
#define GL_TEXTURE_COMPONENTS 0x1003
|
||||
#define GL_TEXTURE_RED_SIZE 0x805C
|
||||
#define GL_TEXTURE_GREEN_SIZE 0x805D
|
||||
#define GL_TEXTURE_BLUE_SIZE 0x805E
|
||||
#define GL_TEXTURE_ALPHA_SIZE 0x805F
|
||||
#define GL_TEXTURE_LUMINANCE_SIZE 0x8060
|
||||
#define GL_TEXTURE_INTENSITY_SIZE 0x8061
|
||||
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
|
||||
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
|
||||
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
|
||||
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
|
||||
#define GL_OBJECT_LINEAR 0x2401
|
||||
#define GL_OBJECT_PLANE 0x2501
|
||||
#define GL_EYE_LINEAR 0x2400
|
||||
#define GL_EYE_PLANE 0x2502
|
||||
#define GL_SPHERE_MAP 0x2402
|
||||
#define GL_NORMAL_MAP 0x8511
|
||||
#define GL_REFLECTION_MAP 0x8512
|
||||
#define GL_DECAL 0x2101
|
||||
#define GL_MODULATE 0x2100
|
||||
#define GL_NEAREST 0x2600
|
||||
#define GL_REPEAT 0x2901
|
||||
#define GL_CLAMP 0x2900
|
||||
#define GL_S 0x2000
|
||||
#define GL_T 0x2001
|
||||
#define GL_R 0x2002
|
||||
#define GL_Q 0x2003
|
||||
#define GL_TEXTURE_GEN_R 0x0C62
|
||||
#define GL_TEXTURE_GEN_Q 0x0C63
|
||||
#define GL_PROXY_TEXTURE_1D 0x8063
|
||||
#define GL_PROXY_TEXTURE_2D 0x8064
|
||||
#define GL_PROXY_TEXTURE_3D 0x8070
|
||||
#define GL_TEXTURE_MIN_LOD 0x813A
|
||||
#define GL_TEXTURE_MAX_LOD 0x813B
|
||||
#define GL_TEXTURE_FILTER_CONTROL 0x8500
|
||||
#define GL_TEXTURE_LOD_BIAS 0x8501
|
||||
#define GL_TEXTURE_CUBE_MAP 0x8513
|
||||
#define GL_TEXTURE_GEN_STR 0x8D60
|
||||
#define GL_CLAMP_TO_BORDER 0x812D
|
||||
#define GL_MAX_TEXTURE_COORDS 0x8871
|
||||
|
||||
#define GL_TEXTURE_COMPARE_MODE 0x884C
|
||||
|
||||
// GL_ARB_point_sprite
|
||||
#define GL_POINT_SPRITE 0x8861
|
||||
#define GL_COORD_REPLACE 0x8862
|
||||
|
||||
// GL_ARB_texture_rectangle
|
||||
#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
|
||||
#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
|
||||
#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7
|
||||
#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
|
||||
|
||||
#define GL_LINE_SMOOTH 0x0B20
|
||||
#define GL_LINE_STIPPLE 0x0B24
|
||||
#define GL_LINE_STIPPLE_PATTERN 0x0B25
|
||||
#define GL_LINE_STIPPLE_REPEAT 0x0B26
|
||||
#define GL_LINE_WIDTH 0x0B21
|
||||
#define GL_LINE_WIDTH_GRANULARITY 0x0B23
|
||||
#define GL_LINE_WIDTH_RANGE 0x0B22
|
||||
|
||||
#define GL_OBJECT_LINEAR 0x2401
|
||||
#define GL_OBJECT_PLANE 0x2501
|
||||
#define GL_EYE_LINEAR 0x2400
|
||||
#define GL_EYE_PLANE 0x2502
|
||||
#define GL_SPHERE_MAP 0x2402
|
||||
|
||||
#define GL_CURRENT_BIT 0x00001
|
||||
#define GL_POINT_BIT 0x00002
|
||||
#define GL_LINE_BIT 0x00004
|
||||
#define GL_POLYGON_BIT 0x00008
|
||||
#define GL_POLYGON_STIPPLE_BIT 0x00010
|
||||
#define GL_PIXEL_MODE_BIT 0x00020
|
||||
#define GL_LIGHTING_BIT 0x00040
|
||||
#define GL_FOG_BIT 0x00080
|
||||
// some of these are already defined in GLES
|
||||
// #define GL_DEPTH_BUFFER_BIT 0x00100
|
||||
#define GL_ACCUM_BUFFER_BIT 0x00200
|
||||
// #define GL_STENCIL_BUFFER_BIT 0x00400
|
||||
#define GL_VIEWPORT_BIT 0x00800
|
||||
#define GL_TRANSFORM_BIT 0x01000
|
||||
#define GL_ENABLE_BIT 0x02000
|
||||
// #define GL_COLOR_BUFFER_BIT 0x04000
|
||||
#define GL_HINT_BIT 0x08000
|
||||
#define GL_EVAL_BIT 0x10000
|
||||
#define GL_LIST_BIT 0x20000
|
||||
#define GL_TEXTURE_BIT 0x40000
|
||||
#define GL_SCISSOR_BIT 0x80000
|
||||
#define GL_ALL_ATTRIB_BITS 0xFFFFF
|
||||
#define GL_MULTISAMPLE_BIT 0x20000000
|
||||
|
||||
#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001
|
||||
#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002
|
||||
#define GL_ALL_CLIENT_ATTRIB_BITS 0xFFFFFFFF
|
||||
#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF
|
||||
|
||||
// secondary color
|
||||
#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A
|
||||
#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B
|
||||
#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C
|
||||
#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
|
||||
#define GL_SECONDARY_COLOR_ARRAY 0x845E
|
||||
#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
|
||||
#define GL_COLOR_SUM 0x8458
|
||||
#define GL_CURRENT_SECONDARY_COLOR 0x8459
|
||||
|
||||
|
||||
// pixel formats
|
||||
#define GL_COLOR_INDEX 0x1900
|
||||
#define GL_RED 0x1903
|
||||
#define GL_R3_G3_B2 0x2A10
|
||||
#define GL_RG 0x8227
|
||||
#define GL_BGR 0x80E0
|
||||
#define GL_BGRA 0x80E1
|
||||
#define GL_UNSIGNED_BYTE_3_3_2 0x8032
|
||||
#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
|
||||
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
|
||||
#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
|
||||
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
|
||||
#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
|
||||
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
|
||||
#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
|
||||
#define GL_UNSIGNED_INT_8_8_8_8 0x8035
|
||||
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
|
||||
#define GL_UNSIGNED_INT_10_10_10_2 0x8036
|
||||
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
|
||||
#define GL_R8 0x8229
|
||||
#define GL_RGB8 0x8051
|
||||
#define GL_RGB5 0x8050
|
||||
#define GL_RGB4 0x804F
|
||||
#define GL_RGBA8 0x8058
|
||||
#define GL_RGBA16 0x805B
|
||||
#define GL_ALPHA4 0x803B
|
||||
#define GL_ALPHA8 0x803C
|
||||
#define GL_ALPHA12 0x803D
|
||||
#define GL_ALPHA16 0x803E
|
||||
#define GL_ALPHA16F 0x881C
|
||||
#define GL_ALPHA32F 0x8816
|
||||
#define GL_LUMINANCE4 0x803F
|
||||
#define GL_LUMINANCE8 0x8040
|
||||
#define GL_LUMINANCE12 0x8041
|
||||
#define GL_LUMINANCE16 0x8042
|
||||
#define GL_LUMINANCE16F 0x881E
|
||||
#define GL_LUMINANCE32F 0x8818
|
||||
#define GL_LUMINANCE4_ALPHA4 0x8043
|
||||
#define GL_LUMINANCE6_ALPHA2 0x8044
|
||||
#define GL_LUMINANCE8_ALPHA8 0x8045
|
||||
#define GL_LUMINANCE12_ALPHA4 0x8046
|
||||
#define GL_LUMINANCE12_ALPHA12 0x8047
|
||||
#define GL_LUMINANCE16_ALPHA16 0x8048
|
||||
#define GL_LUMINANCE_ALPHA16F 0x881F
|
||||
#define GL_LUMINANCE_ALPHA32F 0x8819
|
||||
#define GL_INTENSITY 0x8049
|
||||
#define GL_INTENSITY4 0x804A
|
||||
#define GL_INTENSITY8 0x804B
|
||||
#define GL_INTENSITY12 0x804C
|
||||
#define GL_INTENSITY16 0x804D
|
||||
#define GL_INTENSITY16F 0x881D
|
||||
#define GL_INTENSITY32F 0x8817
|
||||
#define GL_RGB10_A2 0x8059
|
||||
#define GL_RGBA16F 0x881A
|
||||
#define GL_RGB16F 0x881B
|
||||
#define GL_RGBA32F 0x8814
|
||||
#define GL_RGB32F 0x8815
|
||||
#define GL_LUMINANCE16_ALPHA16 0x8048
|
||||
#define GL_RGB16 0x8054
|
||||
#define GL_RGBA4 0x8056
|
||||
#define GL_RGB5_A1 0x8057
|
||||
#define GL_COMPRESSED_ALPHA 0x84E9
|
||||
#define GL_COMPRESSED_LUMINANCE 0x84EA
|
||||
#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
|
||||
#define GL_COMPRESSED_INTENSITY 0x84EC
|
||||
#define GL_COMPRESSED_RGB 0x84ED
|
||||
#define GL_COMPRESSED_RGBA 0x84EE
|
||||
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
|
||||
#define GL_HALF_FLOAT_OES 0x8D61
|
||||
#define GL_RGB565 0x8D62
|
||||
|
||||
// types
|
||||
#define GL_BYTE 0x1400
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
#define GL_SHORT 0x1402
|
||||
#define GL_UNSIGNED_SHORT 0x1403
|
||||
#define GL_INT 0x1404
|
||||
#define GL_UNSIGNED_INT 0x1405
|
||||
#define GL_FLOAT 0x1406
|
||||
#define GL_2_BYTES 0x1407
|
||||
#define GL_3_BYTES 0x1408
|
||||
#define GL_4_BYTES 0x1409
|
||||
#define GL_DOUBLE 0x140A
|
||||
#define GL_HALF_FLOAT 0x140B
|
||||
#define GL_BITMAP 0x1A00
|
||||
|
||||
#define GL_COMPILE 0x1300
|
||||
#define GL_COMPILE_AND_EXECUTE 0x1301
|
||||
|
||||
// fog
|
||||
#define GL_FOG 0x0B60
|
||||
#define GL_FOG_MODE 0x0B65
|
||||
#define GL_FOG_DENSITY 0x0B62
|
||||
#define GL_FOG_COLOR 0x0B66
|
||||
#define GL_FOG_INDEX 0x0B61
|
||||
#define GL_FOG_START 0x0B63
|
||||
#define GL_FOG_END 0x0B64
|
||||
#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
|
||||
#define GL_CURRENT_FOG_COORD 0x8453
|
||||
#define GL_FOG_COORD_ARRAY_TYPE 0x8454
|
||||
#define GL_FOG_COORD_ARRAY_STRIDE 0x8455
|
||||
#define GL_FOG_COORD_ARRAY_POINTER 0x8456
|
||||
#define GL_FOG_COORD_ARRAY 0x8457
|
||||
#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D
|
||||
|
||||
// lighting
|
||||
#define GL_LIGHTING 0x0B50
|
||||
#define GL_LIGHT0 0x4000
|
||||
#define GL_LIGHT1 0x4001
|
||||
#define GL_LIGHT2 0x4002
|
||||
#define GL_LIGHT3 0x4003
|
||||
#define GL_LIGHT4 0x4004
|
||||
#define GL_LIGHT5 0x4005
|
||||
#define GL_LIGHT6 0x4006
|
||||
#define GL_LIGHT7 0x4007
|
||||
#define GL_SPOT_EXPONENT 0x1205
|
||||
#define GL_SPOT_CUTOFF 0x1206
|
||||
#define GL_CONSTANT_ATTENUATION 0x1207
|
||||
#define GL_LINEAR_ATTENUATION 0x1208
|
||||
#define GL_QUADRATIC_ATTENUATION 0x1209
|
||||
#define GL_AMBIENT 0x1200
|
||||
#define GL_DIFFUSE 0x1201
|
||||
#define GL_SPECULAR 0x1202
|
||||
#define GL_SHININESS 0x1601
|
||||
#define GL_EMISSION 0x1600
|
||||
#define GL_POSITION 0x1203
|
||||
#define GL_SPOT_DIRECTION 0x1204
|
||||
#define GL_AMBIENT_AND_DIFFUSE 0x1602
|
||||
#define GL_COLOR_INDEXES 0x1603
|
||||
#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52
|
||||
#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
|
||||
#define GL_LIGHT_MODEL_AMBIENT 0x0B53
|
||||
#define GL_FRONT_AND_BACK 0x0408
|
||||
#define GL_SHADE_MODEL 0x0B54
|
||||
#define GL_FLAT 0x1D00
|
||||
#define GL_SMOOTH 0x1D01
|
||||
#define GL_COLOR_MATERIAL 0x0B57
|
||||
#define GL_COLOR_MATERIAL_FACE 0x0B55
|
||||
#define GL_COLOR_MATERIAL_PARAMETER 0x0B56
|
||||
#define GL_NORMALIZE 0x0BA1
|
||||
#define GL_DRAW_BUFFER 0x0C01
|
||||
#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
|
||||
#define GL_SINGLE_COLOR 0x81F9
|
||||
#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
|
||||
|
||||
// stencil
|
||||
#define GL_STENCIL_BACK_FUNC 0x8800
|
||||
#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
|
||||
#define GL_STENCIL_BACK_REF 0x8CA3
|
||||
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
|
||||
#define GL_STENCIL_BACK_FAIL 0x8801
|
||||
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
|
||||
#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
|
||||
|
||||
// pixel transfer
|
||||
#define GL_MAP_COLOR 0x0D10
|
||||
#define GL_MAP_STENCIL 0x0D11
|
||||
#define GL_INDEX_SHIFT 0x0D12
|
||||
#define GL_INDEX_OFFSET 0x0D13
|
||||
#define GL_RED_SCALE 0x0D14
|
||||
#define GL_RED_BIAS 0x0D15
|
||||
#define GL_GREEN_SCALE 0x0D18
|
||||
#define GL_GREEN_BIAS 0x0D19
|
||||
#define GL_BLUE_SCALE 0x0D1A
|
||||
#define GL_BLUE_BIAS 0x0D1B
|
||||
#define GL_ALPHA_SCALE 0x0D1C
|
||||
#define GL_ALPHA_BIAS 0x0D1D
|
||||
#define GL_DEPTH_SCALE 0x0D1E
|
||||
#define GL_DEPTH_BIAS 0x0D1F
|
||||
#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1
|
||||
#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0
|
||||
#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2
|
||||
#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3
|
||||
#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4
|
||||
#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5
|
||||
#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6
|
||||
#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7
|
||||
#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8
|
||||
#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9
|
||||
#define GL_PIXEL_MAP_S_TO_S 0x0C71
|
||||
#define GL_PIXEL_MAP_I_TO_I 0x0C70
|
||||
#define GL_PIXEL_MAP_I_TO_R 0x0C72
|
||||
#define GL_PIXEL_MAP_I_TO_G 0x0C73
|
||||
#define GL_PIXEL_MAP_I_TO_B 0x0C74
|
||||
#define GL_PIXEL_MAP_I_TO_A 0x0C75
|
||||
#define GL_PIXEL_MAP_R_TO_R 0x0C76
|
||||
#define GL_PIXEL_MAP_G_TO_G 0x0C77
|
||||
#define GL_PIXEL_MAP_B_TO_B 0x0C78
|
||||
#define GL_PIXEL_MAP_A_TO_A 0x0C79
|
||||
#define GL_PACK_ALIGNMENT 0x0D05
|
||||
#define GL_PACK_LSB_FIRST 0x0D01
|
||||
#define GL_PACK_ROW_LENGTH 0x0D02
|
||||
#define GL_PACK_SKIP_PIXELS 0x0D04
|
||||
#define GL_PACK_SKIP_ROWS 0x0D03
|
||||
#define GL_PACK_SWAP_BYTES 0x0D00
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
#define GL_UNPACK_LSB_FIRST 0x0CF1
|
||||
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||
#define GL_UNPACK_SKIP_PIXELS 0x0CF4
|
||||
#define GL_UNPACK_SKIP_ROWS 0x0CF3
|
||||
#define GL_UNPACK_SWAP_BYTES 0x0CF0
|
||||
#define GL_UNPACK_IMAGE_HEIGHT 0x806E
|
||||
#define GL_PACK_IMAGE_HEIGHT 0x806C
|
||||
#define GL_ZOOM_X 0x0D16
|
||||
#define GL_ZOOM_Y 0x0D17
|
||||
#define GL_MAX_PIXEL_MAP_TABLE 0x0D34
|
||||
#define GL_TEXTURE_BASE_LEVEL 0x813C
|
||||
|
||||
// blending
|
||||
#define GL_BLEND 0x0BE2
|
||||
#define GL_BLEND_SRC 0x0BE1
|
||||
#define GL_BLEND_DST 0x0BE0
|
||||
#define GL_SRC_COLOR 0x0300
|
||||
#define GL_ONE_MINUS_SRC_COLOR 0x0301
|
||||
#define GL_SRC_ALPHA 0x0302
|
||||
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
|
||||
#define GL_DST_ALPHA 0x0304
|
||||
#define GL_ONE_MINUS_DST_ALPHA 0x0305
|
||||
#define GL_DST_COLOR 0x0306
|
||||
#define GL_ONE_MINUS_DST_COLOR 0x0307
|
||||
#define GL_SRC_ALPHA_SATURATE 0x0308
|
||||
#define GL_CONSTANT_COLOR 0x8001
|
||||
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
|
||||
#define GL_CONSTANT_ALPHA 0x8003
|
||||
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
|
||||
#define GL_DOT3_RGB_EXT 0x8740
|
||||
#define GL_DOT3_RGBA_EXT 0x8741
|
||||
#define GL_BLEND_DST_RGB 0x80C8
|
||||
#define GL_BLEND_SRC_RGB 0x80C9
|
||||
#define GL_BLEND_DST_ALPHA 0x80CA
|
||||
#define GL_BLEND_SRC_ALPHA 0x80CB
|
||||
|
||||
// glGet
|
||||
#define GL_AUX_BUFFERS 0x0C00
|
||||
#define GL_MAX_ELEMENTS_VERTICES 0x80E8
|
||||
#define GL_MAX_ELEMENTS_INDICES 0x80E9
|
||||
#define GL_POINT_SIZE_RANGE 0x0B12
|
||||
#define GL_RENDER_MODE 0x0C40
|
||||
#define GL_NAME_STACK_DEPTH 0x0D70
|
||||
#define GL_MAX_NAME_STACK_DEPTH 0x0D37
|
||||
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
|
||||
#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
|
||||
#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
|
||||
#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
|
||||
#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
|
||||
#define GL_INDEX_ARRAY_POINTER 0x8091
|
||||
#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093
|
||||
#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0
|
||||
#define GL_SELECTION_BUFFER_POINTER 0x0DF3
|
||||
|
||||
// evaluators
|
||||
#define GL_AUTO_NORMAL 0x0D80
|
||||
#define GL_MAP1_COLOR_4 0x0D90
|
||||
#define GL_MAP1_INDEX 0x0D91
|
||||
#define GL_MAP1_NORMAL 0x0D92
|
||||
#define GL_MAP1_TEXTURE_COORD_1 0x0D93
|
||||
#define GL_MAP1_TEXTURE_COORD_2 0x0D94
|
||||
#define GL_MAP1_TEXTURE_COORD_3 0x0D95
|
||||
#define GL_MAP1_TEXTURE_COORD_4 0x0D96
|
||||
#define GL_MAP1_VERTEX_3 0x0D97
|
||||
#define GL_MAP1_VERTEX_4 0x0D98
|
||||
#define GL_MAP2_COLOR_4 0x0DB0
|
||||
#define GL_MAP2_INDEX 0x0DB1
|
||||
#define GL_MAP2_NORMAL 0x0DB2
|
||||
#define GL_MAP2_TEXTURE_COORD_1 0x0DB3
|
||||
#define GL_MAP2_TEXTURE_COORD_2 0x0DB4
|
||||
#define GL_MAP2_TEXTURE_COORD_3 0x0DB5
|
||||
#define GL_MAP2_TEXTURE_COORD_4 0x0DB6
|
||||
#define GL_MAP2_VERTEX_3 0x0DB7
|
||||
#define GL_MAP2_VERTEX_4 0x0DB8
|
||||
#define GL_MAP1_GRID_DOMAIN 0x0DD0
|
||||
#define GL_MAP1_GRID_SEGMENTS 0x0DD1
|
||||
#define GL_MAP2_GRID_DOMAIN 0x0DD2
|
||||
#define GL_MAP2_GRID_SEGMENTS 0x0DD3
|
||||
#define GL_COEFF 0x0A00
|
||||
#define GL_ORDER 0x0A01
|
||||
#define GL_DOMAIN 0x0A02
|
||||
#define GL_MAX_LIST_NESTING 0x0B31
|
||||
|
||||
/* polygons */
|
||||
#define GL_POINT 0x1B00
|
||||
#define GL_LINE 0x1B01
|
||||
#define GL_FILL 0x1B02
|
||||
#define GL_CW 0x0900
|
||||
#define GL_CCW 0x0901
|
||||
#define GL_FRONT 0x0404
|
||||
#define GL_BACK 0x0405
|
||||
#define GL_POLYGON_MODE 0x0B40
|
||||
#define GL_POLYGON_SMOOTH 0x0B41
|
||||
#define GL_POLYGON_STIPPLE 0x0B42
|
||||
#define GL_EDGE_FLAG 0x0B43
|
||||
#define GL_CULL_FACE 0x0B44
|
||||
#define GL_CULL_FACE_MODE 0x0B45
|
||||
#define GL_FRONT_FACE 0x0B46
|
||||
#define GL_POLYGON_OFFSET_FACTOR 0x8038
|
||||
#define GL_POLYGON_OFFSET_UNITS 0x2A00
|
||||
#define GL_POLYGON_OFFSET_POINT 0x2A01
|
||||
#define GL_POLYGON_OFFSET_LINE 0x2A02
|
||||
|
||||
/* Shader Source */
|
||||
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
|
||||
#define GL_COMPILE_STATUS 0x8B81
|
||||
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||
#define GL_SHADER_SOURCE_LENGTH 0x8B88
|
||||
#define GL_SHADER_COMPILER 0x8DFA
|
||||
|
||||
/* Shader Binary */
|
||||
#define GL_SHADER_BINARY_FORMATS 0x8DF8
|
||||
#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
|
||||
|
||||
/* Shader Precision-Specified Types */
|
||||
#define GL_LOW_FLOAT 0x8DF0
|
||||
#define GL_MEDIUM_FLOAT 0x8DF1
|
||||
#define GL_HIGH_FLOAT 0x8DF2
|
||||
#define GL_LOW_INT 0x8DF3
|
||||
#define GL_MEDIUM_INT 0x8DF4
|
||||
#define GL_HIGH_INT 0x8DF5
|
||||
|
||||
/* Texture Parameters */
|
||||
#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
|
||||
#define GL_TEXTURE_RED_SIZE 0x805C
|
||||
#define GL_TEXTURE_GREEN_SIZE 0x805D
|
||||
#define GL_TEXTURE_BLUE_SIZE 0x805E
|
||||
#define GL_TEXTURE_ALPHA_SIZE 0x805F
|
||||
#define GL_TEXTURE_LUMINANCE_SIZE 0x8060
|
||||
#define GL_TEXTURE_INTENSITY_SIZE 0x8061
|
||||
#define GL_TEXTURE_RED_TYPE 0x8C10
|
||||
#define GL_TEXTURE_GREEN_TYPE 0x8C11
|
||||
#define GL_TEXTURE_BLUE_TYPE 0x8C12
|
||||
#define GL_TEXTURE_ALPHA_TYPE 0x8C13
|
||||
#define GL_TEXTURE_DEPTH_TYPE 0x8C16
|
||||
#define GL_TEXTURE_DEPTH 0x8071
|
||||
#define GL_TEXTURE_DEPTH_SIZE 0x884A
|
||||
#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
|
||||
#define GL_TEXTURE_COMPRESSED 0x86A1
|
||||
#define GL_TEXTURE_MAX_LEVEL 0x813D
|
||||
|
||||
/* Compressed Textures */
|
||||
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||
#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
|
||||
|
||||
/* S3TC with sRGB */
|
||||
#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
|
||||
|
||||
|
||||
/* Render Mode */
|
||||
#define GL_SELECT 0x1c02
|
||||
#define GL_RENDER 0x1C00
|
||||
|
||||
/* Interleaved Array */
|
||||
#define GL_V2F 0x2A20
|
||||
#define GL_V3F 0x2A21
|
||||
#define GL_C4UB_V2F 0x2A22
|
||||
#define GL_C4UB_V3F 0x2A23
|
||||
#define GL_C3F_V3F 0x2A24
|
||||
#define GL_N3F_V3F 0x2A25
|
||||
#define GL_C4F_N3F_V3F 0x2A26
|
||||
#define GL_T2F_V3F 0x2A27
|
||||
#define GL_T4F_V4F 0x2A28
|
||||
#define GL_T2F_C4UB_V3F 0x2A29
|
||||
#define GL_T2F_C3F_V3F 0x2A2A
|
||||
#define GL_T2F_N3F_V3F 0x2A2B
|
||||
#define GL_T2F_C4F_N3F_V3F 0x2A2C
|
||||
#define GL_T4F_C4F_N3F_V4F 0x2A2D
|
||||
|
||||
/* Buffers Array */
|
||||
#define GL_BUFFER_SIZE 0x8764
|
||||
#define GL_BUFFER_USAGE 0x8765
|
||||
#define GL_QUERY_COUNTER_BITS 0x8864
|
||||
#define GL_CURRENT_QUERY 0x8865
|
||||
#define GL_QUERY_RESULT 0x8866
|
||||
#define GL_QUERY_RESULT_AVAILABLE 0x8867
|
||||
#define GL_ARRAY_BUFFER 0x8892
|
||||
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
|
||||
#define GL_ARRAY_BUFFER_BINDING 0x8894
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
|
||||
#define GL_READ_ONLY 0x88B8
|
||||
#define GL_WRITE_ONLY 0x88B9
|
||||
#define GL_READ_WRITE 0x88BA
|
||||
#define GL_BUFFER_ACCESS 0x88BB
|
||||
#define GL_BUFFER_MAPPED 0x88BC
|
||||
#define GL_BUFFER_MAP_POINTER 0x88BD
|
||||
#define GL_STREAM_DRAW 0x88E0
|
||||
#define GL_STREAM_READ 0x88E1
|
||||
#define GL_STREAM_COPY 0x88E2
|
||||
#define GL_STATIC_DRAW 0x88E4
|
||||
#define GL_STATIC_READ 0x88E5
|
||||
#define GL_STATIC_COPY 0x88E6
|
||||
#define GL_DYNAMIC_DRAW 0x88E8
|
||||
#define GL_DYNAMIC_READ 0x88E9
|
||||
#define GL_DYNAMIC_COPY 0x88EA
|
||||
#define GL_SRC1_ALPHA 0x8589
|
||||
#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
|
||||
#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
|
||||
#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
|
||||
#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
|
||||
#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
|
||||
#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
|
||||
#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
|
||||
#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
|
||||
#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
|
||||
#define GL_MAP_READ_BIT 0x0001
|
||||
#define GL_MAP_WRITE_BIT 0x0002
|
||||
#define GL_BUFFER_ACCESS_FLAGS 0x911F
|
||||
#define GL_BUFFER_MAP_LENGTH 0x9120
|
||||
#define GL_BUFFER_MAP_OFFSET 0x9121
|
||||
#define GL_READ_ONLY 0x88B8
|
||||
#define GL_WRITE_ONLY 0x88B9
|
||||
#define GL_READ_WRITE 0x88BA
|
||||
#define GL_PIXEL_PACK_BUFFER 0x88EB
|
||||
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
|
||||
#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
|
||||
#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
|
||||
#define GL_CURRENT_VERTEX_ATTRIB 0x8626
|
||||
#define GL_MAP_PERSISTENT_BIT 0x00000040
|
||||
#define GL_QUERY_BUFFER_BINDING_AMD 0x9193
|
||||
#define GL_COPY_READ_BUFFER_BINDING 0x8F36
|
||||
#define GL_COPY_READ_BUFFER GL_COPY_READ_BUFFER_BINDING
|
||||
#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
|
||||
#define GL_COPY_WRITE_BUFFER GL_COPY_WRITE_BUFFER_BINDING
|
||||
|
||||
|
||||
/* Framebuffers */
|
||||
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
|
||||
#define GL_FRAMEBUFFER_DEFAULT 0x8218
|
||||
#define GL_FRAMEBUFFER_UNDEFINED 0x8219
|
||||
#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
|
||||
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
|
||||
#define GL_DEPTH_STENCIL 0x84F9
|
||||
#define GL_UNSIGNED_INT_24_8 0x84FA
|
||||
#define GL_DEPTH24_STENCIL8 0x88F0
|
||||
#define GL_TEXTURE_STENCIL_SIZE 0x88F1
|
||||
#define GL_TEXTURE_RED_TYPE 0x8C10
|
||||
#define GL_TEXTURE_GREEN_TYPE 0x8C11
|
||||
#define GL_TEXTURE_BLUE_TYPE 0x8C12
|
||||
#define GL_TEXTURE_ALPHA_TYPE 0x8C13
|
||||
#define GL_TEXTURE_DEPTH_TYPE 0x8C16
|
||||
#define GL_UNSIGNED_NORMALIZED 0x8C17
|
||||
#define GL_FRAMEBUFFER_BINDING 0x8CA6
|
||||
#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING
|
||||
#define GL_RENDERBUFFER_BINDING 0x8CA7
|
||||
#define GL_READ_FRAMEBUFFER 0x8CA8
|
||||
#define GL_DRAW_FRAMEBUFFER 0x8CA9
|
||||
#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
|
||||
#define GL_RENDERBUFFER_SAMPLES 0x8CAB
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
|
||||
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
|
||||
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
|
||||
#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
|
||||
#define GL_COLOR_ATTACHMENT0 0x8CE0
|
||||
#define GL_COLOR_ATTACHMENT1 0x8CE1
|
||||
#define GL_COLOR_ATTACHMENT2 0x8CE2
|
||||
#define GL_COLOR_ATTACHMENT3 0x8CE3
|
||||
#define GL_COLOR_ATTACHMENT4 0x8CE4
|
||||
#define GL_COLOR_ATTACHMENT5 0x8CE5
|
||||
#define GL_COLOR_ATTACHMENT6 0x8CE6
|
||||
#define GL_COLOR_ATTACHMENT7 0x8CE7
|
||||
#define GL_COLOR_ATTACHMENT8 0x8CE8
|
||||
#define GL_COLOR_ATTACHMENT9 0x8CE9
|
||||
#define GL_COLOR_ATTACHMENT10 0x8CEA
|
||||
#define GL_COLOR_ATTACHMENT11 0x8CEB
|
||||
#define GL_COLOR_ATTACHMENT12 0x8CEC
|
||||
#define GL_COLOR_ATTACHMENT13 0x8CED
|
||||
#define GL_COLOR_ATTACHMENT14 0x8CEE
|
||||
#define GL_COLOR_ATTACHMENT15 0x8CEF
|
||||
#define GL_DEPTH_ATTACHMENT 0x8D00
|
||||
#define GL_STENCIL_ATTACHMENT 0x8D20
|
||||
#define GL_FRAMEBUFFER 0x8D40
|
||||
#define GL_RENDERBUFFER 0x8D41
|
||||
#define GL_RENDERBUFFER_WIDTH 0x8D42
|
||||
#define GL_RENDERBUFFER_HEIGHT 0x8D43
|
||||
#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
|
||||
#define GL_STENCIL_INDEX1 0x8D46
|
||||
#define GL_STENCIL_INDEX4 0x8D47
|
||||
#define GL_STENCIL_INDEX8 0x8D48
|
||||
#define GL_STENCIL_INDEX16 0x8D49
|
||||
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
|
||||
#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
|
||||
#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
|
||||
#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
|
||||
#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
|
||||
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
|
||||
#define GL_MAX_SAMPLES 0x8D57
|
||||
#define GL_INDEX 0x8222
|
||||
#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14
|
||||
#define GL_TEXTURE_INTENSITY_TYPE 0x8C15
|
||||
#define GL_DEPTH_COMPONENT32 0x81A7
|
||||
#define GL_DEPTH_COMPONENT24 0x81A6
|
||||
#define GL_DEPTH_COMPONENT16 0x81A5
|
||||
#define GL_DEPTH_COMPONENT 0x1902
|
||||
#define GL_MAX_DRAW_BUFFERS_ARB 0x8824
|
||||
|
||||
// point sprite extension
|
||||
#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
|
||||
#define GL_LOWER_LEFT 0x8CA1
|
||||
#define GL_UPPER_LEFT 0x8CA2
|
||||
#define GL_PROGRAM_POINT_SIZE 0x8642
|
||||
|
||||
// clear buffer
|
||||
#define GL_COLOR 0x1800
|
||||
#define GL_DEPTH 0x1801
|
||||
#define GL_STENCIL 0x1802
|
||||
|
||||
|
||||
// direct state
|
||||
#define GL_MATRIX0_ARB 0x88C0
|
||||
#define GL_PROGRAM_MATRIX_EXT 0x8E2D
|
||||
#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E
|
||||
#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F
|
||||
#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
|
||||
#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
|
||||
#define GL_CURRENT_MATRIX_ARB 0x8641
|
||||
#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E
|
||||
#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
|
||||
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
|
||||
#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
|
||||
#define GL_TEXTURE_BINDING_1D 0x8068
|
||||
#define GL_TEXTURE_BINDING_2D 0x8069
|
||||
#define GL_TEXTURE_BINDING_3D 0x806A
|
||||
#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
|
||||
#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
|
||||
#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06
|
||||
#define GL_TEXTURE_COORD_ARRAY_COUNT 0x808B
|
||||
|
||||
// cube mapping
|
||||
#define GL_TEXTURE_CUBE_MAP 0x8513
|
||||
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
|
||||
#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
|
||||
#define GL_AX_CUBE_MAP_TEXTURE_SIZE 0x851C
|
||||
|
||||
// Shaders
|
||||
#define GL_FRAGMENT_SHADER 0x8B30
|
||||
#define GL_VERTEX_SHADER 0x8B31
|
||||
#define GL_MAX_VERTEX_ATTRIBS 0x8869
|
||||
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
|
||||
#define GL_MAX_VARYING_VECTORS 0x8DFC
|
||||
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
|
||||
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
|
||||
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
|
||||
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
|
||||
#define GL_SHADER_TYPE 0x8B4F
|
||||
#define GL_DELETE_STATUS 0x8B80
|
||||
#define GL_LINK_STATUS 0x8B82
|
||||
#define GL_VALIDATE_STATUS 0x8B83
|
||||
#define GL_ATTACHED_SHADERS 0x8B85
|
||||
#define GL_ACTIVE_UNIFORMS 0x8B86
|
||||
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
|
||||
#define GL_ACTIVE_ATTRIBUTES 0x8B89
|
||||
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
|
||||
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
|
||||
#define GL_CURRENT_PROGRAM 0x8B8D
|
||||
// Shaders extensions
|
||||
#define GL_PROGRAM_BINARY_LENGTH 0x8741
|
||||
#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
|
||||
#define GL_PROGRAM_BINARY_FORMATS 0x87FF
|
||||
#define GL_PROGRAM_OBJECT_ARB 0x8B40
|
||||
|
||||
// Vertex Arrays
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
|
||||
|
||||
// Uniform Types
|
||||
#define GL_FLOAT_VEC2 0x8B50
|
||||
#define GL_FLOAT_VEC3 0x8B51
|
||||
#define GL_FLOAT_VEC4 0x8B52
|
||||
#define GL_INT_VEC2 0x8B53
|
||||
#define GL_INT_VEC3 0x8B54
|
||||
#define GL_INT_VEC4 0x8B55
|
||||
#define GL_BOOL 0x8B56
|
||||
#define GL_BOOL_VEC2 0x8B57
|
||||
#define GL_BOOL_VEC3 0x8B58
|
||||
#define GL_BOOL_VEC4 0x8B59
|
||||
#define GL_FLOAT_MAT2 0x8B5A
|
||||
#define GL_FLOAT_MAT3 0x8B5B
|
||||
#define GL_FLOAT_MAT4 0x8B5C
|
||||
#define GL_SAMPLER_2D 0x8B5E
|
||||
#define GL_SAMPLER_CUBE 0x8B60
|
||||
|
||||
// Getter
|
||||
#define GL_NUM_EXTENSIONS 0x821D
|
||||
|
||||
// Anisotropic
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
|
||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
|
||||
|
||||
// ATI_texture_env_combine3
|
||||
#define GL_MODULATE_ADD_ATI 0x8744
|
||||
#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
|
||||
#define GL_MODULATE_SUBTRACT_ATI 0x8746
|
||||
|
||||
// ATIX_texture_env_route
|
||||
#define GL_SECONDARY_COLOR_ATIX 0x8747
|
||||
#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748
|
||||
#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749
|
||||
|
||||
//GL_NV_texture_env_combine4
|
||||
#define GL_COMBINE4 0x8503
|
||||
#define GL_SRC3_RGB 0x8583
|
||||
#define GL_SRC3_ALPHA 0x858B
|
||||
#define GL_OPERAND3_RGB 0x8593
|
||||
#define GL_OPERAND3_ALPHA 0x859B
|
||||
|
||||
//GL_NV_fog_distance
|
||||
#define GL_FOG_DISTANCE_MODE_NV 0x855A
|
||||
#define GL_EYE_RADIAL_NV 0x855B
|
||||
#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C
|
||||
|
||||
//GL_ARB_instanced_arrays
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
|
||||
|
||||
//GL_OES_get_program_binary
|
||||
#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741
|
||||
#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE
|
||||
#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF
|
||||
|
||||
//Clamp color
|
||||
#define GL_CLAMP_READ_COLOR 0x891C
|
||||
|
||||
//GL_ARB_vertex_program
|
||||
#define GL_MATRIX0_ARB 0x88C0
|
||||
#define GL_MATRIX1_ARB 0x88C1
|
||||
#define GL_MATRIX2_ARB 0x88C2
|
||||
#define GL_MATRIX3_ARB 0x88C3
|
||||
#define GL_MATRIX4_ARB 0x88C4
|
||||
#define GL_MATRIX5_ARB 0x88C5
|
||||
#define GL_MATRIX6_ARB 0x88C6
|
||||
#define GL_MATRIX7_ARB 0x88C7
|
||||
#define GL_MATRIX8_ARB 0x88C8
|
||||
#define GL_MATRIX9_ARB 0x88C9
|
||||
#define GL_MATRIX10_ARB 0x88CA
|
||||
#define GL_MATRIX11_ARB 0x88CB
|
||||
#define GL_MATRIX12_ARB 0x88CC
|
||||
#define GL_MATRIX13_ARB 0x88CD
|
||||
#define GL_MATRIX14_ARB 0x88CE
|
||||
#define GL_MATRIX15_ARB 0x88CF
|
||||
#define GL_MATRIX16_ARB 0x88D0
|
||||
#define GL_MATRIX17_ARB 0x88D1
|
||||
#define GL_MATRIX18_ARB 0x88D2
|
||||
#define GL_MATRIX19_ARB 0x88D3
|
||||
#define GL_MATRIX20_ARB 0x88D4
|
||||
#define GL_MATRIX21_ARB 0x88D5
|
||||
#define GL_MATRIX22_ARB 0x88D6
|
||||
#define GL_MATRIX23_ARB 0x88D7
|
||||
#define GL_MATRIX24_ARB 0x88D8
|
||||
#define GL_MATRIX25_ARB 0x88D9
|
||||
#define GL_MATRIX26_ARB 0x88DA
|
||||
#define GL_MATRIX27_ARB 0x88DB
|
||||
#define GL_MATRIX28_ARB 0x88DC
|
||||
#define GL_MATRIX29_ARB 0x88DD
|
||||
#define GL_MATRIX30_ARB 0x88DE
|
||||
#define GL_MATRIX31_ARB 0x88DF
|
||||
|
||||
#define GL_PROGRAM_ERROR_STRING_ARB 0x8874
|
||||
|
||||
#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B
|
||||
#define GL_CURRENT_MATRIX_ARB 0x8641
|
||||
#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
|
||||
#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
|
||||
#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869
|
||||
#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F
|
||||
#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
|
||||
|
||||
#define GL_PROGRAM_STRING_ARB 0x8628
|
||||
|
||||
#define GL_PROGRAM_LENGTH_ARB 0x8627
|
||||
#define GL_PROGRAM_FORMAT_ARB 0x8876
|
||||
#define GL_PROGRAM_BINDING_ARB 0x8677
|
||||
#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0
|
||||
#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1
|
||||
#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
|
||||
#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
|
||||
#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4
|
||||
#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5
|
||||
#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
|
||||
#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
|
||||
#define GL_PROGRAM_PARAMETERS_ARB 0x88A8
|
||||
#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9
|
||||
#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA
|
||||
#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
|
||||
#define GL_PROGRAM_ATTRIBS_ARB 0x88AC
|
||||
#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD
|
||||
#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE
|
||||
#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
|
||||
#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0
|
||||
#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
|
||||
#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
|
||||
#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
|
||||
#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
|
||||
#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
|
||||
#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
|
||||
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
|
||||
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
|
||||
#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626
|
||||
|
||||
#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
|
||||
|
||||
#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
|
||||
#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643
|
||||
#define GL_COLOR_SUM_ARB 0x8458
|
||||
|
||||
#define GL_VERTEX_PROGRAM_ARB 0x8620
|
||||
|
||||
// ARB_fragment_program
|
||||
|
||||
#define GL_MAX_TEXTURE_COORDS_ARB 0x8871
|
||||
#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
|
||||
|
||||
#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805
|
||||
#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806
|
||||
#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807
|
||||
#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
|
||||
#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
|
||||
#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
|
||||
#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
|
||||
#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
|
||||
#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
|
||||
#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
|
||||
#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
|
||||
#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
|
||||
|
||||
#define GL_FRAGMENT_PROGRAM_ARB 0x8804
|
||||
|
||||
// EXT_draw_buffers
|
||||
|
||||
#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
|
||||
|
||||
// Sampler
|
||||
#define GL_SAMPLER_BINDING 0x8919
|
||||
#define GL_TEXTURE_COMPARE_FUNC 0x884D
|
||||
#define GL_COMPARE_REF_TO_TEXTURE 0x884E
|
||||
#define GL_NONE 0x0
|
||||
|
||||
// Queries
|
||||
#define GL_TIME_ELAPSED 0x88BF
|
||||
#define GL_TIMESTAMP 0x8E28
|
||||
#define GL_SAMPLES_PASSED 0x8914
|
||||
#define GL_ANY_SAMPLES_PASSED 0x8C2F
|
||||
#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
|
||||
#define GL_PRIMITIVES_GENERATED 0x8C87
|
||||
#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
|
||||
#define GL_QUERY_RESULT_NO_WAIT 0x9194
|
||||
|
||||
// Blend
|
||||
#define GL_FUNC_ADD 0x8006
|
||||
#define GL_FUNC_SUBTRACT 0x800A
|
||||
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
|
||||
#define GL_MIN 0x8007
|
||||
#define GL_MAX 0x8008
|
||||
|
||||
#endif // _GL4ES_CONST_H_
|
||||
@@ -0,0 +1,430 @@
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "wrap/gles.h"
|
||||
#include "const.h"
|
||||
#include "loader.h"
|
||||
#include "logs.h"
|
||||
#include "gl4es.h"
|
||||
#include "gles.h"
|
||||
|
||||
#define p(a) \
|
||||
case a: return #a
|
||||
|
||||
const char* PrintEnum(GLenum what) {
|
||||
static char fallback[64];
|
||||
switch(what)
|
||||
{
|
||||
// error
|
||||
p(GL_INVALID_ENUM);
|
||||
p(GL_INVALID_VALUE);
|
||||
p(GL_INVALID_OPERATION);
|
||||
// target
|
||||
p(GL_TEXTURE_1D);
|
||||
p(GL_TEXTURE_2D);
|
||||
p(GL_TEXTURE_3D);
|
||||
p(GL_TEXTURE_RECTANGLE_ARB);
|
||||
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);
|
||||
p(GL_TEXTURE_CUBE_MAP);
|
||||
p(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
|
||||
p(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
|
||||
p(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
|
||||
p(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
|
||||
p(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
|
||||
p(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
|
||||
// format
|
||||
p(GL_COLOR_INDEX);
|
||||
p(GL_RED);
|
||||
p(GL_R);
|
||||
p(GL_R8);
|
||||
p(GL_R3_G3_B2);
|
||||
p(GL_RGB);
|
||||
p(GL_BGR);
|
||||
p(GL_RGB8);
|
||||
p(GL_RGB5);
|
||||
p(GL_RGB16);
|
||||
p(GL_RGB16F);
|
||||
p(GL_RGB32F);
|
||||
p(GL_BGRA);
|
||||
p(GL_RGBA);
|
||||
p(GL_RGBA4);
|
||||
p(GL_RGB5_A1);
|
||||
p(GL_RGB10_A2);
|
||||
p(GL_RGBA8);
|
||||
p(GL_RGBA16);
|
||||
p(GL_RGBA16F);
|
||||
p(GL_RGBA32F);
|
||||
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);
|
||||
p(GL_LUMINANCE8_ALPHA8);
|
||||
p(GL_LUMINANCE_ALPHA);
|
||||
p(GL_LUMINANCE4_ALPHA4);
|
||||
p(GL_LUMINANCE16_ALPHA16);
|
||||
p(GL_LUMINANCE_ALPHA16F);
|
||||
p(GL_LUMINANCE_ALPHA32F);
|
||||
p(GL_LUMINANCE);
|
||||
p(GL_ALPHA);
|
||||
p(GL_LUMINANCE8);
|
||||
p(GL_LUMINANCE16);
|
||||
p(GL_LUMINANCE16F);
|
||||
p(GL_LUMINANCE32F);
|
||||
p(GL_ALPHA8);
|
||||
p(GL_ALPHA16F);
|
||||
p(GL_ALPHA32F);
|
||||
p(GL_COMPRESSED_ALPHA);
|
||||
p(GL_COMPRESSED_LUMINANCE);
|
||||
p(GL_COMPRESSED_LUMINANCE_ALPHA);
|
||||
p(GL_COMPRESSED_RGB);
|
||||
p(GL_COMPRESSED_RGBA);
|
||||
p(GL_HALF_FLOAT);
|
||||
p(GL_INTENSITY);
|
||||
p(GL_INTENSITY8);
|
||||
p(GL_INTENSITY16F);
|
||||
p(GL_INTENSITY32F);
|
||||
p(GL_DEPTH_STENCIL);
|
||||
// type
|
||||
p(GL_BYTE);
|
||||
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_UNSIGNED_INT_8_8_8_8_REV);
|
||||
p(GL_UNSIGNED_INT_8_8_8_8);
|
||||
p(GL_FLOAT);
|
||||
p(GL_DOUBLE);
|
||||
p(GL_UNSIGNED_INT_24_8);
|
||||
// texture infos
|
||||
p(GL_TEXTURE_WIDTH);
|
||||
p(GL_TEXTURE_HEIGHT);
|
||||
p(GL_TEXTURE_COMPRESSED);
|
||||
p(GL_TEXTURE_BORDER);
|
||||
p(GL_TEXTURE_INTERNAL_FORMAT);
|
||||
p(GL_MAX_TEXTURE_SIZE);
|
||||
p(GL_MAX_TEXTURE_COORDS);
|
||||
// texture pack/unpack
|
||||
p(GL_UNPACK_ALIGNMENT);
|
||||
p(GL_UNPACK_ROW_LENGTH);
|
||||
p(GL_UNPACK_SKIP_PIXELS);
|
||||
p(GL_UNPACK_SKIP_ROWS);
|
||||
p(GL_PACK_ALIGNMENT);
|
||||
p(GL_PACK_ROW_LENGTH);
|
||||
p(GL_PACK_SKIP_PIXELS);
|
||||
p(GL_PACK_SKIP_ROWS);
|
||||
// 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_DEPTH_STENCIL_ATTACHMENT);
|
||||
p(GL_STENCIL_ATTACHMENT);
|
||||
p(GL_DEPTH_COMPONENT);
|
||||
p(GL_DEPTH24_STENCIL8);
|
||||
p(GL_MAX_DRAW_BUFFERS_ARB);
|
||||
p(GL_DRAW_FRAMEBUFFER_BINDING);
|
||||
p(GL_READ_FRAMEBUFFER_BINDING);
|
||||
// VBO
|
||||
p(GL_STATIC_DRAW);
|
||||
p(GL_STREAM_DRAW);
|
||||
p(GL_READ_WRITE);
|
||||
p(GL_ARRAY_BUFFER);
|
||||
p(GL_ELEMENT_ARRAY_BUFFER);
|
||||
p(GL_PIXEL_PACK_BUFFER);
|
||||
p(GL_PIXEL_UNPACK_BUFFER);
|
||||
p(GL_WRITE_ONLY);
|
||||
// Texture
|
||||
p(GL_TEXTURE0);
|
||||
p(GL_TEXTURE1);
|
||||
p(GL_TEXTURE2);
|
||||
p(GL_TEXTURE3);
|
||||
p(GL_TEXTURE4);
|
||||
p(GL_TEXTURE5);
|
||||
p(GL_TEXTURE6);
|
||||
p(GL_TEXTURE7);
|
||||
p(GL_TEXTURE8);
|
||||
p(GL_TEXTURE9);
|
||||
p(GL_TEXTURE10);
|
||||
p(GL_TEXTURE11);
|
||||
p(GL_TEXTURE12);
|
||||
p(GL_TEXTURE13);
|
||||
p(GL_TEXTURE14);
|
||||
p(GL_TEXTURE15);
|
||||
p(GL_TEXTURE_WRAP_S);
|
||||
p(GL_TEXTURE_WRAP_T);
|
||||
p(GL_LINEAR);
|
||||
p(GL_NEAREST);
|
||||
p(GL_NEAREST_MIPMAP_NEAREST);
|
||||
p(GL_NEAREST_MIPMAP_LINEAR);
|
||||
p(GL_LINEAR_MIPMAP_NEAREST);
|
||||
p(GL_LINEAR_MIPMAP_LINEAR);
|
||||
p(GL_TEXTURE_MAX_LEVEL);
|
||||
p(GL_TEXTURE_BASE_LEVEL);
|
||||
p(GL_TEXTURE_MIN_FILTER);
|
||||
p(GL_TEXTURE_MAG_FILTER);
|
||||
p(GL_CLAMP_TO_EDGE);
|
||||
p(GL_REPEAT);
|
||||
p(GL_MIRRORED_REPEAT_OES);
|
||||
p(GL_GENERATE_MIPMAP);
|
||||
// mode
|
||||
p(GL_POINTS);
|
||||
p(GL_LINES);
|
||||
p(GL_LINE_LOOP);
|
||||
p(GL_LINE_STRIP);
|
||||
p(GL_TRIANGLES);
|
||||
p(GL_TRIANGLE_STRIP);
|
||||
p(GL_TRIANGLE_FAN);
|
||||
p(GL_QUADS);
|
||||
p(GL_QUAD_STRIP);
|
||||
p(GL_POLYGON);
|
||||
// texgen
|
||||
p(GL_S);
|
||||
p(GL_T);
|
||||
p(GL_Q);
|
||||
p(GL_TEXTURE_GEN_MODE);
|
||||
p(GL_OBJECT_LINEAR);
|
||||
p(GL_EYE_LINEAR);
|
||||
p(GL_SPHERE_MAP);
|
||||
p(GL_NORMAL_MAP);
|
||||
p(GL_REFLECTION_MAP);
|
||||
p(GL_TEXTURE_GEN_S);
|
||||
p(GL_TEXTURE_GEN_T);
|
||||
p(GL_TEXTURE_GEN_R);
|
||||
p(GL_TEXTURE_GEN_Q);
|
||||
// matrix mode
|
||||
p(GL_PROJECTION);
|
||||
p(GL_MODELVIEW);
|
||||
p(GL_TEXTURE);
|
||||
// blend
|
||||
p(GL_SRC_ALPHA);
|
||||
p(GL_DST_ALPHA);
|
||||
p(GL_ONE_MINUS_SRC_ALPHA);
|
||||
p(GL_ONE_MINUS_DST_ALPHA);
|
||||
// lights
|
||||
p(GL_LIGHT0);
|
||||
p(GL_LIGHT1);
|
||||
p(GL_LIGHT2);
|
||||
p(GL_LIGHT3);
|
||||
p(GL_LIGHT4);
|
||||
p(GL_LIGHT5);
|
||||
p(GL_LIGHT6);
|
||||
p(GL_LIGHT7);
|
||||
p(GL_AMBIENT);
|
||||
p(GL_DIFFUSE);
|
||||
p(GL_SPECULAR);
|
||||
p(GL_POSITION);
|
||||
p(GL_SPOT_DIRECTION);
|
||||
p(GL_SPOT_EXPONENT);
|
||||
p(GL_SPOT_CUTOFF);
|
||||
p(GL_CONSTANT_ATTENUATION);
|
||||
p(GL_LINEAR_ATTENUATION);
|
||||
p(GL_QUADRATIC_ATTENUATION);
|
||||
// Misc enabled
|
||||
p(GL_LIGHTING);
|
||||
p(GL_NORMALIZE);
|
||||
p(GL_CULL_FACE);
|
||||
p(GL_DEPTH_TEST);
|
||||
p(GL_RESCALE_NORMAL);
|
||||
p(GL_ALPHA_TEST);
|
||||
p(GL_ALPHA_TEST_FUNC);
|
||||
p(GL_BLEND);
|
||||
p(GL_BLEND_SRC);
|
||||
p(GL_BLEND_DST);
|
||||
p(GL_LOGIC_OP_MODE);
|
||||
p(GL_SCISSOR_TEST);
|
||||
p(GL_STENCIL_TEST);
|
||||
// uniform type
|
||||
p(GL_FLOAT_VEC2);
|
||||
p(GL_FLOAT_VEC3);
|
||||
p(GL_FLOAT_VEC4);
|
||||
p(GL_INT_VEC2);
|
||||
p(GL_INT_VEC3);
|
||||
p(GL_INT_VEC4);
|
||||
p(GL_BOOL);
|
||||
p(GL_BOOL_VEC2);
|
||||
p(GL_BOOL_VEC3);
|
||||
p(GL_BOOL_VEC4);
|
||||
p(GL_FLOAT_MAT2);
|
||||
p(GL_FLOAT_MAT3);
|
||||
p(GL_FLOAT_MAT4);
|
||||
p(GL_SAMPLER_2D);
|
||||
p(GL_SAMPLER_CUBE);
|
||||
// Shaders
|
||||
p(GL_FRAGMENT_SHADER);
|
||||
p(GL_VERTEX_SHADER);
|
||||
p(GL_MAX_VERTEX_ATTRIBS);
|
||||
p(GL_MAX_VERTEX_UNIFORM_VECTORS);
|
||||
p(GL_MAX_VARYING_VECTORS);
|
||||
p(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
|
||||
p(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
|
||||
p(GL_MAX_TEXTURE_IMAGE_UNITS);
|
||||
p(GL_MAX_FRAGMENT_UNIFORM_VECTORS);
|
||||
p(GL_SHADER_TYPE);
|
||||
p(GL_DELETE_STATUS);
|
||||
p(GL_LINK_STATUS);
|
||||
p(GL_COMPILE_STATUS);
|
||||
p(GL_VALIDATE_STATUS);
|
||||
p(GL_ATTACHED_SHADERS);
|
||||
p(GL_ACTIVE_UNIFORMS);
|
||||
p(GL_ACTIVE_UNIFORM_MAX_LENGTH);
|
||||
p(GL_ACTIVE_ATTRIBUTES);
|
||||
p(GL_ACTIVE_ATTRIBUTE_MAX_LENGTH);
|
||||
p(GL_SHADING_LANGUAGE_VERSION);
|
||||
p(GL_CURRENT_PROGRAM);
|
||||
p(GL_PROGRAM_BINARY_LENGTH);
|
||||
p(GL_NUM_PROGRAM_BINARY_FORMATS);
|
||||
p(GL_PROGRAM_BINARY_FORMATS);
|
||||
p(GL_INFO_LOG_LENGTH);
|
||||
// Client State
|
||||
p(GL_VERTEX_ARRAY);
|
||||
p(GL_COLOR_ARRAY);
|
||||
p(GL_NORMAL_ARRAY);
|
||||
p(GL_TEXTURE_COORD_ARRAY);
|
||||
p(GL_SECONDARY_COLOR_ARRAY);
|
||||
p(GL_FOG_COORD_ARRAY);
|
||||
// TexEnv
|
||||
p(GL_POINT_SPRITE);
|
||||
p(GL_COORD_REPLACE);
|
||||
p(GL_TEXTURE_FILTER_CONTROL);
|
||||
p(GL_TEXTURE_LOD_BIAS);
|
||||
p(GL_TEXTURE_ENV);
|
||||
p(GL_TEXTURE_ENV_MODE);
|
||||
p(GL_MODULATE);
|
||||
p(GL_ADD);
|
||||
p(GL_DECAL);
|
||||
p(GL_REPLACE);
|
||||
p(GL_COMBINE);
|
||||
p(GL_COMBINE_RGB);
|
||||
p(GL_ADD_SIGNED);
|
||||
p(GL_INTERPOLATE);
|
||||
p(GL_SUBTRACT);
|
||||
p(GL_DOT3_RGB);
|
||||
p(GL_DOT3_RGBA);
|
||||
p(GL_COMBINE_ALPHA);
|
||||
p(GL_SRC0_RGB);
|
||||
p(GL_SRC1_RGB);
|
||||
p(GL_SRC2_RGB);
|
||||
p(GL_CONSTANT);
|
||||
p(GL_PRIMARY_COLOR);
|
||||
p(GL_PREVIOUS);
|
||||
p(GL_SRC0_ALPHA);
|
||||
p(GL_SRC1_ALPHA);
|
||||
p(GL_SRC2_ALPHA);
|
||||
p(GL_OPERAND0_RGB);
|
||||
p(GL_OPERAND1_RGB);
|
||||
p(GL_OPERAND2_RGB);
|
||||
p(GL_SRC_COLOR);
|
||||
p(GL_ONE_MINUS_SRC_COLOR);
|
||||
p(GL_OPERAND0_ALPHA);
|
||||
p(GL_OPERAND1_ALPHA);
|
||||
p(GL_OPERAND2_ALPHA);
|
||||
p(GL_RGB_SCALE);
|
||||
p(GL_ALPHA_SCALE);
|
||||
p(GL_TEXTURE_ENV_COLOR);
|
||||
// misc
|
||||
p(GL_NUM_EXTENSIONS);
|
||||
// ARB_program
|
||||
p(GL_VERTEX_PROGRAM_ARB);
|
||||
p(GL_FRAGMENT_PROGRAM_ARB);
|
||||
p(GL_PROGRAM_FORMAT_ASCII_ARB);
|
||||
p(GL_PROGRAM_LENGTH_ARB);
|
||||
p(GL_PROGRAM_FORMAT_ARB);
|
||||
p(GL_PROGRAM_BINDING_ARB);
|
||||
p(GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
|
||||
p(GL_MAX_PROGRAM_ENV_PARAMETERS_ARB);
|
||||
p(GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
|
||||
p(GL_MAX_PROGRAM_ATTRIBS_ARB);
|
||||
p(GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
|
||||
p(GL_MAX_PROGRAM_INSTRUCTIONS_ARB);
|
||||
p(GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
|
||||
p(GL_MAX_PROGRAM_TEMPORARIES_ARB);
|
||||
p(GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
|
||||
p(GL_MAX_PROGRAM_PARAMETERS_ARB);
|
||||
p(GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
|
||||
p(GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
|
||||
p(GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
|
||||
p(GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
|
||||
p(GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
|
||||
p(GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
|
||||
p(GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
|
||||
p(GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
|
||||
p(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB);
|
||||
p(GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
|
||||
p(GL_PROGRAM_INSTRUCTIONS_ARB);
|
||||
p(GL_PROGRAM_NATIVE_TEMPORARIES_ARB);
|
||||
p(GL_PROGRAM_TEMPORARIES_ARB);
|
||||
p(GL_PROGRAM_NATIVE_PARAMETERS_ARB);
|
||||
p(GL_PROGRAM_PARAMETERS_ARB);
|
||||
p(GL_PROGRAM_NATIVE_ATTRIBS_ARB);
|
||||
p(GL_PROGRAM_ATTRIBS_ARB);
|
||||
p(GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
|
||||
p(GL_PROGRAM_ADDRESS_REGISTERS_ARB);
|
||||
p(GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
|
||||
p(GL_PROGRAM_ALU_INSTRUCTIONS_ARB);
|
||||
p(GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
|
||||
p(GL_PROGRAM_TEX_INSTRUCTIONS_ARB);
|
||||
p(GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
|
||||
p(GL_PROGRAM_TEX_INDIRECTIONS_ARB);
|
||||
default:
|
||||
sprintf(fallback, "0x%04X", what);
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
const char* PrintEGLError(int onlyerror) {
|
||||
#ifdef NOEGL
|
||||
return "";
|
||||
#else
|
||||
LOAD_EGL(eglGetError);
|
||||
static char fallback[64];
|
||||
GLenum what = egl_eglGetError();
|
||||
if(onlyerror && what==EGL_SUCCESS)
|
||||
return NULL;
|
||||
switch(what)
|
||||
{
|
||||
p(EGL_SUCCESS);
|
||||
p(EGL_NOT_INITIALIZED);
|
||||
p(EGL_BAD_ACCESS);
|
||||
p(EGL_BAD_ALLOC);
|
||||
p(EGL_BAD_ATTRIBUTE);
|
||||
p(EGL_BAD_CONTEXT);
|
||||
p(EGL_BAD_CONFIG);
|
||||
p(EGL_BAD_CURRENT_SURFACE);
|
||||
p(EGL_BAD_DISPLAY);
|
||||
p(EGL_BAD_SURFACE);
|
||||
p(EGL_BAD_MATCH);
|
||||
p(EGL_BAD_PARAMETER);
|
||||
p(EGL_BAD_NATIVE_PIXMAP);
|
||||
p(EGL_BAD_NATIVE_WINDOW);
|
||||
p(EGL_CONTEXT_LOST);
|
||||
default:
|
||||
sprintf(fallback, "0x%04X", what);
|
||||
}
|
||||
return fallback;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CheckGLError(int fwd) {
|
||||
LOAD_GLES(glGetError);
|
||||
GLenum err=gles_glGetError();
|
||||
if(err!=GL_NO_ERROR) {
|
||||
printf("LIBGL: glGetError(): %s\n", PrintEnum(err));
|
||||
if(fwd)
|
||||
errorShim(err);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef _GL4ES_DEBUG_H_
|
||||
#define _GL4ES_DEBUG_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
const char* PrintEnum(GLenum what);
|
||||
|
||||
const char* PrintEGLError(int onlyerror);
|
||||
|
||||
void CheckGLError(int fwd);
|
||||
|
||||
#endif // _GL4ES_DEBUG_H_
|
||||
@@ -0,0 +1,341 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
DXT1/DXT3/DXT5 texture decompression
|
||||
|
||||
The original code is from Benjamin Dobell, see below for details. Compared to
|
||||
the original this one adds DXT3 decompression, is valid C89, and is x64
|
||||
compatible as it uses fixed size integers everywhere. It also uses a different
|
||||
PackRGBA order.
|
||||
|
||||
---
|
||||
|
||||
Copyright (c) 2012, Matth�us G. "Anteru" Chajdas (http://anteru.net)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
Copyright (C) 2009 Benjamin Dobell, Glass Echidna
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
*/
|
||||
static uint32_t PackRGBA (uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
{
|
||||
return r | (g << 8) | (b << 16) | (a << 24);
|
||||
}
|
||||
|
||||
static void DecompressBlockDXT1Internal (const uint8_t* block,
|
||||
uint32_t* output,
|
||||
uint32_t outputStride,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
const uint8_t* alphaValues)
|
||||
{
|
||||
uint32_t temp, code;
|
||||
|
||||
uint16_t color0, color1;
|
||||
uint8_t r0, g0, b0, r1, g1, b1;
|
||||
|
||||
int i, j;
|
||||
|
||||
color0 = *(const uint16_t*)(block);
|
||||
color1 = *(const uint16_t*)(block + 2);
|
||||
|
||||
temp = (color0 >> 11) * 255 + 16;
|
||||
r0 = (uint8_t)((temp/32 + temp)/32);
|
||||
temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
|
||||
g0 = (uint8_t)((temp/64 + temp)/64);
|
||||
temp = (color0 & 0x001F) * 255 + 16;
|
||||
b0 = (uint8_t)((temp/32 + temp)/32);
|
||||
|
||||
temp = (color1 >> 11) * 255 + 16;
|
||||
r1 = (uint8_t)((temp/32 + temp)/32);
|
||||
temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
|
||||
g1 = (uint8_t)((temp/64 + temp)/64);
|
||||
temp = (color1 & 0x001F) * 255 + 16;
|
||||
b1 = (uint8_t)((temp/32 + temp)/32);
|
||||
|
||||
code = *(const uint32_t*)(block + 4);
|
||||
|
||||
if (color0 > color1) {
|
||||
for (j = 0; j < 4; ++j) {
|
||||
for (i = 0; i < 4; ++i) {
|
||||
uint32_t finalColor, positionCode;
|
||||
uint8_t alpha;
|
||||
|
||||
alpha = alphaValues [j*4+i];
|
||||
|
||||
finalColor = 0;
|
||||
positionCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
|
||||
switch (positionCode) {
|
||||
case 0:
|
||||
finalColor = PackRGBA(r0, g0, b0, alpha);
|
||||
break;
|
||||
case 1:
|
||||
finalColor = PackRGBA(r1, g1, b1, alpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, alpha);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, alpha);
|
||||
break;
|
||||
}
|
||||
if(!alpha)
|
||||
*simpleAlpha = 1;
|
||||
else if(alpha<0xff)
|
||||
*complexAlpha = 1;
|
||||
output [j*outputStride + i] = finalColor;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 4; ++j) {
|
||||
for (i = 0; i < 4; ++i) {
|
||||
uint32_t finalColor, positionCode;
|
||||
uint8_t alpha;
|
||||
|
||||
alpha = alphaValues [j*4+i];
|
||||
|
||||
finalColor = 0;
|
||||
positionCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
|
||||
switch (positionCode) {
|
||||
case 0:
|
||||
finalColor = PackRGBA(r0, g0, b0, alpha);
|
||||
break;
|
||||
case 1:
|
||||
finalColor = PackRGBA(r1, g1, b1, alpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA((r0+r1)/2, (g0+g1)/2, (b0+b1)/2, alpha);
|
||||
break;
|
||||
case 3:
|
||||
if(transparent0) alpha=0;
|
||||
finalColor = PackRGBA(0, 0, 0, alpha);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!alpha)
|
||||
*simpleAlpha = 1;
|
||||
else if(alpha<0xff)
|
||||
*complexAlpha = 1;
|
||||
|
||||
output [j*outputStride + i] = finalColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void DecompressBlockDXT1(): Decompresses one block of a DXT1 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
|
||||
uint32_t x: x-coordinate of the first pixel in the block.
|
||||
uint32_t y: y-coordinate of the first pixel in the block.
|
||||
uint32_t width: width of the texture being decompressed.
|
||||
const uint8_t *blockStorage: pointer to the block to decompress.
|
||||
uint32_t *image: pointer to image where the decompressed pixel data should be stored.
|
||||
*/
|
||||
void DecompressBlockDXT1(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
uint32_t* image)
|
||||
{
|
||||
static const uint8_t const_alpha [] = {
|
||||
255, 255, 255, 255,
|
||||
255, 255, 255, 255,
|
||||
255, 255, 255, 255,
|
||||
255, 255, 255, 255
|
||||
};
|
||||
|
||||
DecompressBlockDXT1Internal (blockStorage,
|
||||
image + x + (y * width), width, transparent0, simpleAlpha, complexAlpha, const_alpha);
|
||||
}
|
||||
|
||||
/*
|
||||
void DecompressBlockDXT5(): Decompresses one block of a DXT5 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
|
||||
uint32_t x: x-coordinate of the first pixel in the block.
|
||||
uint32_t y: y-coordinate of the first pixel in the block.
|
||||
uint32_t width: width of the texture being decompressed.
|
||||
const uint8_t *blockStorage: pointer to the block to decompress.
|
||||
uint32_t *image: pointer to image where the decompressed pixel data should be stored.
|
||||
*/
|
||||
void DecompressBlockDXT5(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
uint32_t* image)
|
||||
{
|
||||
uint8_t alpha0, alpha1;
|
||||
const uint8_t* bits;
|
||||
uint32_t alphaCode1;
|
||||
uint16_t alphaCode2;
|
||||
|
||||
uint16_t color0, color1;
|
||||
uint8_t r0, g0, b0, r1, g1, b1;
|
||||
|
||||
int i, j;
|
||||
|
||||
uint32_t temp, code;
|
||||
|
||||
alpha0 = *(blockStorage);
|
||||
alpha1 = *(blockStorage + 1);
|
||||
|
||||
bits = blockStorage + 2;
|
||||
alphaCode1 = bits[2] | (bits[3] << 8) | (bits[4] << 16) | (bits[5] << 24);
|
||||
alphaCode2 = bits[0] | (bits[1] << 8);
|
||||
|
||||
color0 = *(const uint16_t*)(blockStorage + 8);
|
||||
color1 = *(const uint16_t*)(blockStorage + 10);
|
||||
|
||||
temp = (color0 >> 11) * 255 + 16;
|
||||
r0 = (uint8_t)((temp/32 + temp)/32);
|
||||
temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
|
||||
g0 = (uint8_t)((temp/64 + temp)/64);
|
||||
temp = (color0 & 0x001F) * 255 + 16;
|
||||
b0 = (uint8_t)((temp/32 + temp)/32);
|
||||
|
||||
temp = (color1 >> 11) * 255 + 16;
|
||||
r1 = (uint8_t)((temp/32 + temp)/32);
|
||||
temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
|
||||
g1 = (uint8_t)((temp/64 + temp)/64);
|
||||
temp = (color1 & 0x001F) * 255 + 16;
|
||||
b1 = (uint8_t)((temp/32 + temp)/32);
|
||||
|
||||
code = *(const uint32_t*)(blockStorage + 12);
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
uint8_t finalAlpha;
|
||||
int alphaCode, alphaCodeIndex;
|
||||
uint8_t colorCode;
|
||||
uint32_t finalColor;
|
||||
|
||||
alphaCodeIndex = 3*(4*j+i);
|
||||
if (alphaCodeIndex <= 12) {
|
||||
alphaCode = (alphaCode2 >> alphaCodeIndex) & 0x07;
|
||||
} else if (alphaCodeIndex == 15) {
|
||||
alphaCode = (alphaCode2 >> 15) | ((alphaCode1 << 1) & 0x06);
|
||||
} else /* alphaCodeIndex >= 18 && alphaCodeIndex <= 45 */ {
|
||||
alphaCode = (alphaCode1 >> (alphaCodeIndex - 16)) & 0x07;
|
||||
}
|
||||
|
||||
if (alphaCode == 0) {
|
||||
finalAlpha = alpha0;
|
||||
} else if (alphaCode == 1) {
|
||||
finalAlpha = alpha1;
|
||||
} else {
|
||||
if (alpha0 > alpha1) {
|
||||
finalAlpha = (uint8_t)(((8-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/7);
|
||||
} else {
|
||||
if (alphaCode == 6) {
|
||||
finalAlpha = 0;
|
||||
} else if (alphaCode == 7) {
|
||||
finalAlpha = 255;
|
||||
} else {
|
||||
finalAlpha = (uint8_t)(((6-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
colorCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
finalColor = 0;
|
||||
|
||||
switch (colorCode) {
|
||||
case 0:
|
||||
finalColor = PackRGBA(r0, g0, b0, finalAlpha);
|
||||
break;
|
||||
case 1:
|
||||
finalColor = PackRGBA(r1, g1, b1, finalAlpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, finalAlpha);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, finalAlpha);
|
||||
break;
|
||||
}
|
||||
|
||||
if(finalAlpha==0) *simpleAlpha = 1;
|
||||
else if(finalAlpha<0xff) *complexAlpha = 1;
|
||||
|
||||
image [i + x + (width* (y+j))] = finalColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void DecompressBlockDXT3(): Decompresses one block of a DXT3 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
|
||||
uint32_t x: x-coordinate of the first pixel in the block.
|
||||
uint32_t y: y-coordinate of the first pixel in the block.
|
||||
uint32_t height: height of the texture being decompressed.
|
||||
const uint8_t *blockStorage: pointer to the block to decompress.
|
||||
uint32_t *image: pointer to image where the decompressed pixel data should be stored.
|
||||
*/
|
||||
void DecompressBlockDXT3(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
uint32_t* image)
|
||||
{
|
||||
int i;
|
||||
|
||||
uint8_t alphaValues [16] = { 0 };
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
const uint16_t* alphaData = (const uint16_t*) (blockStorage);
|
||||
|
||||
alphaValues [i*4 + 0] = (((*alphaData) >> 0) & 0xF ) * 17;
|
||||
alphaValues [i*4 + 1] = (((*alphaData) >> 4) & 0xF ) * 17;
|
||||
alphaValues [i*4 + 2] = (((*alphaData) >> 8) & 0xF ) * 17;
|
||||
alphaValues [i*4 + 3] = (((*alphaData) >> 12) & 0xF) * 17;
|
||||
|
||||
blockStorage += 2;
|
||||
}
|
||||
|
||||
DecompressBlockDXT1Internal (blockStorage,
|
||||
image + x + (y * width), width, transparent0, simpleAlpha, complexAlpha, alphaValues);
|
||||
}
|
||||
|
||||
// Texture DXT1 / DXT5 compression
|
||||
// Using STB "on file" library
|
||||
// go there https://github.com/nothings/stb
|
||||
// for more details and other libs
|
||||
|
||||
#define STB_DXT_IMPLEMENTATION
|
||||
#include "stb_dxt_104.h"
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef _GL4ES_DECOMPRESS_H_
|
||||
#define _GL4ES_DECOMPRESS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void DecompressBlockDXT1(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
uint32_t* image);
|
||||
|
||||
void DecompressBlockDXT3(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
uint32_t* image);
|
||||
|
||||
void DecompressBlockDXT5(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
uint32_t* image);
|
||||
|
||||
#endif // _GL4ES_DECOMPRESS_H_
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "depth.h"
|
||||
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "loader.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDepthFunc(GLenum func) {
|
||||
if(glstate->list.compiling) {
|
||||
PUSH_IF_COMPILING(glDepthFunc);
|
||||
}
|
||||
noerrorShim();
|
||||
if (glstate->depth.func == func)
|
||||
return;
|
||||
FLUSH_BEGINEND;
|
||||
glstate->depth.func = func;
|
||||
LOAD_GLES(glDepthFunc);
|
||||
errorGL();
|
||||
gles_glDepthFunc(func);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDepthMask(GLboolean flag) {
|
||||
if(glstate->list.compiling) {
|
||||
PUSH_IF_COMPILING(glDepthMask);
|
||||
}
|
||||
noerrorShim();
|
||||
if (glstate->depth.mask == flag)
|
||||
return;
|
||||
FLUSH_BEGINEND;
|
||||
glstate->depth.mask = flag;
|
||||
LOAD_GLES(glDepthMask);
|
||||
errorGL();
|
||||
gles_glDepthMask(flag);
|
||||
}
|
||||
|
||||
GLfloat clamp(GLfloat a) {
|
||||
return (a<0.f)?0.f:((a>1.f)?1.f:a);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDepthRangef(GLclampf Near, GLclampf Far) {
|
||||
Near = clamp(Near);
|
||||
Far = clamp(Far);
|
||||
if(glstate->list.compiling) {
|
||||
PUSH_IF_COMPILING(glDepthRangef);
|
||||
}
|
||||
noerrorShim();
|
||||
if ((glstate->depth.Near == Near) && (glstate->depth.Far == Far))
|
||||
return;
|
||||
FLUSH_BEGINEND;
|
||||
glstate->depth.Near = Near;
|
||||
glstate->depth.Far = Far;
|
||||
LOAD_GLES(glDepthRangef);
|
||||
errorGL();
|
||||
gles_glDepthRangef(Near, Far);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glClearDepthf(GLclampf depth) {
|
||||
depth = clamp(depth);
|
||||
if(glstate->list.compiling) {
|
||||
PUSH_IF_COMPILING(glClearDepthf);
|
||||
}
|
||||
noerrorShim();
|
||||
glstate->depth.clear = depth;
|
||||
LOAD_GLES(glClearDepthf);
|
||||
errorGL();
|
||||
gles_glClearDepthf(depth);
|
||||
}
|
||||
|
||||
AliasExport(void,glDepthFunc,,(GLenum func));
|
||||
AliasExport(void,glDepthMask,,(GLboolean flag));
|
||||
AliasExport(void,glDepthRangef,,(GLclampf nearVal, GLclampf farVal));
|
||||
AliasExport(void,glClearDepthf,,(GLclampf depth));
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef _GL4ES_DEPTH_H_
|
||||
#define _GL4ES_DEPTH_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDepthFunc(GLenum func);
|
||||
void APIENTRY_GL4ES gl4es_glDepthMask(GLboolean flag);
|
||||
void APIENTRY_GL4ES gl4es_glDepthRangef(GLclampf nearVal, GLclampf farVal);
|
||||
void APIENTRY_GL4ES gl4es_glClearDepthf(GLclampf depth);
|
||||
|
||||
#endif // _GL4ES_DEPTH_H_
|
||||
@@ -0,0 +1,655 @@
|
||||
#include "directstate.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wrap/gl4es.h"
|
||||
#include "gles.h"
|
||||
#include "stack.h"
|
||||
#include "texgen.h"
|
||||
#include "debug.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DBG(a) a
|
||||
#else
|
||||
#define DBG(a)
|
||||
#endif
|
||||
|
||||
// Client State
|
||||
void APIENTRY_GL4ES gl4es_glClientAttribDefault(GLbitfield mask) {
|
||||
if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
|
||||
gl4es_glPixelStorei(GL_PACK_ALIGNMENT, 0);
|
||||
gl4es_glPixelStorei(GL_UNPACK_ALIGNMENT, 0);
|
||||
gl4es_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
gl4es_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
gl4es_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
gl4es_glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
gl4es_glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
|
||||
gl4es_glPixelStorei(GL_PACK_SKIP_ROWS, 0);
|
||||
}
|
||||
#define enable_disable(pname, enabled) \
|
||||
if (enabled) gl4es_glEnableClientState(pname); \
|
||||
else gl4es_glDisableClientState(pname)
|
||||
|
||||
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
|
||||
int client = glstate->texture.client;
|
||||
|
||||
enable_disable(GL_VERTEX_ARRAY, false);
|
||||
enable_disable(GL_NORMAL_ARRAY, false);
|
||||
enable_disable(GL_COLOR_ARRAY, false);
|
||||
enable_disable(GL_SECONDARY_COLOR_ARRAY, false);
|
||||
for (int a=0; a<MAX_TEX; a++) {
|
||||
gl4es_glClientActiveTexture(GL_TEXTURE0+a);
|
||||
enable_disable(GL_TEXTURE_COORD_ARRAY, false);
|
||||
}
|
||||
#undef enable_disable
|
||||
if (glstate->texture.client != client) gl4es_glClientActiveTexture(GL_TEXTURE0+client);
|
||||
}
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glPushClientAttribDefault(GLbitfield mask) {
|
||||
gl4es_glPushClientAttrib(mask);
|
||||
gl4es_glClientAttribDefault(mask);
|
||||
}
|
||||
|
||||
// Matrix
|
||||
#define mat(f) \
|
||||
GLenum old_mat; \
|
||||
gl4es_glGetIntegerv(GL_MATRIX_MODE, (GLint *) &old_mat); \
|
||||
gl4es_glMatrixMode(matrixMode); \
|
||||
gl4es_##f; \
|
||||
gl4es_glMatrixMode(old_mat)
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMatrixLoadf(GLenum matrixMode, const GLfloat *m) {
|
||||
mat(glLoadMatrixf(m));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixLoadd(GLenum matrixMode, const GLdouble *m) {
|
||||
mat(glLoadMatrixd(m));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixMultf(GLenum matrixMode, const GLfloat *m) {
|
||||
mat(glMultMatrixf(m));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixMultd(GLenum matrixMode, const GLdouble *m) {
|
||||
mat(glMultMatrixd(m));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixLoadIdentity(GLenum matrixMode) {
|
||||
mat(glLoadIdentity());
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixRotatef(GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
|
||||
mat(glRotatef(angle, x, y, z));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixRotated(GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z) {
|
||||
mat(glRotated(angle, x, y, z));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixScalef(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z) {
|
||||
mat(glScalef(x, y, z));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixScaled(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z) {
|
||||
mat(glScaled(x, y, z));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixTranslatef(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z) {
|
||||
mat(glTranslatef(x, y, z));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixTranslated(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z) {
|
||||
mat(glTranslated(x, y, z));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixOrtho(GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f) {
|
||||
mat(glOrtho(l, r, b ,t, n, f));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixFrustum(GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f) {
|
||||
mat(glFrustum(l, r, b, t, n, f));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixPush(GLenum matrixMode) {
|
||||
mat(glPushMatrix());
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixPop(GLenum matrixMode) {
|
||||
mat(glPopMatrix());
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixLoadTransposef(GLenum matrixMode, const GLfloat *m) {
|
||||
mat(glLoadTransposeMatrixf(m));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixLoadTransposed(GLenum matrixMode, const GLdouble *m) {
|
||||
mat(glLoadTransposeMatrixd(m));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixMultTransposef(GLenum matrixMode, const GLfloat *m) {
|
||||
mat(glMultTransposeMatrixf(m));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMatrixMultTransposed(GLenum matrixMode, const GLdouble *m) {
|
||||
mat(glMultTransposeMatrixd(m));
|
||||
}
|
||||
#undef mat
|
||||
|
||||
// Textures
|
||||
#define text(f) \
|
||||
gl4es_glBindTexture(target, texture); \
|
||||
gl4es_##f
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glTextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param) {
|
||||
text(glTexParameteri(target, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glTextureParameteriv(GLuint texture, GLenum target, GLenum pname, const GLint *param) {
|
||||
text(glTexParameteriv(target, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glTextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param) {
|
||||
text(glTexParameterf(target, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glTextureParameterfv(GLuint texture, GLenum target, GLenum pname, const GLfloat *param) {
|
||||
text(glTexParameterfv(target, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glTextureImage1D(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexImage1D(target, level, internalformat, width, border, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glTextureImage2D(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexSubImage1D(target, level, xoffset, width, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCopyTextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) {
|
||||
text(glCopyTexImage1D(target, level, internalformat, x, y, width, border));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCopyTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
|
||||
text(glCopyTexImage2D(target, level, internalformat, x, y, width, height, border));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCopyTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {
|
||||
text(glCopyTexSubImage1D(target, level, xoffset, x, y, width));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCopyTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
text(glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetTextureImage(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) {
|
||||
text(glGetTexImage(target, level, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetTextureParameterfv(GLuint texture, GLenum target, GLenum pname, GLfloat *params) {
|
||||
text(glGetTexParameterfv(target, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetTextureParameteriv(GLuint texture, GLenum target, GLenum pname, GLint *params) {
|
||||
text(glGetTexParameteriv(target, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetTextureLevelParameterfv(GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params) {
|
||||
text(glGetTexLevelParameterfv(target, level, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetTextureLevelParameteriv(GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params) {
|
||||
text(glGetTexLevelParameteriv(target, level, pname, params));
|
||||
}
|
||||
|
||||
// Texture 3D
|
||||
void APIENTRY_GL4ES gl4es_glTextureImage3D(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCopyTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
text(glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height));
|
||||
}
|
||||
// Compressed texture
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureImage3D(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexImage1D(target, level, internalformat, width, border, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetCompressedTextureImage(GLuint texture, GLenum target, GLint level, GLvoid *img) {
|
||||
text(glGetCompressedTexImage(target, level, img));
|
||||
}
|
||||
|
||||
#undef text
|
||||
#define text(f) \
|
||||
GLenum old_tex = glstate->texture.active; \
|
||||
if(texunit != old_tex) gl4es_glActiveTexture(texunit); \
|
||||
gl4es_##f; \
|
||||
if(texunit != old_tex) gl4es_glActiveTexture(old_tex)
|
||||
#define texc(f) \
|
||||
GLenum old_tex = glstate->texture.client; \
|
||||
if(texunit != old_tex) gl4es_glClientActiveTexture(texunit); \
|
||||
gl4es_##f; \
|
||||
if(texunit != old_tex) gl4es_glClientActiveTexture(old_tex)
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBindMultiTexture(GLenum texunit, GLenum target, GLuint texture) {
|
||||
text(glBindTexture(target, texture));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexCoordPointer(GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
|
||||
texc(glTexCoordPointer(size, type, stride, pointer));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexEnvf(GLenum texunit, GLenum target, GLenum pname, GLfloat param) {
|
||||
text(glTexEnvf(target, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexEnvfv(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params) {
|
||||
text(glTexEnvfv(target, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexEnvi(GLenum texunit, GLenum target, GLenum pname, GLint param) {
|
||||
text(glTexEnvi(target, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexEnviv(GLenum texunit, GLenum target, GLenum pname, const GLint *params) {
|
||||
text(glTexEnviv(target, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGend(GLenum texunit, GLenum coord, GLenum pname, GLdouble param) {
|
||||
text(glTexGend(coord, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGendv(GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params) {
|
||||
text(glTexGendv(coord, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGenf(GLenum texunit, GLenum coord, GLenum pname, GLfloat param) {
|
||||
text(glTexGenf(coord, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGenfv(GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params) {
|
||||
text(glTexGenfv(coord, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGeni(GLenum texunit, GLenum coord, GLenum pname, GLint param) {
|
||||
text(glTexGeni(coord, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGeniv(GLenum texunit, GLenum coord, GLenum pname, const GLint *params) {
|
||||
text(glTexGeniv(coord, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexEnvfv(GLenum texunit, GLenum target, GLenum pname, GLfloat *params) {
|
||||
text(glGetTexEnvfv(target, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexEnviv(GLenum texunit, GLenum target, GLenum pname, GLint *params) {
|
||||
text(glGetTexEnviv(target, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexGendv(GLenum texunit, GLenum coord, GLenum pname, GLdouble *params) {
|
||||
text(glGetTexGendv(coord, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexGenfv(GLenum texunit, GLenum coord, GLenum pname, GLfloat *params) {
|
||||
text(glGetTexGenfv(coord, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexGeniv(GLenum texunit, GLenum coord, GLenum pname, GLint *params) {
|
||||
text(glGetTexGeniv(coord, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexParameteri(GLenum texunit, GLenum target, GLenum pname, GLint param) {
|
||||
text(glTexParameteri(target, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexParameteriv(GLenum texunit, GLenum target, GLenum pname, const GLint *param) {
|
||||
text(glTexParameteriv(target, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexParameterf(GLenum texunit, GLenum target, GLenum pname, GLfloat param) {
|
||||
text(glTexParameterf(target, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexParameterfv(GLenum texunit, GLenum target, GLenum pname, const GLfloat *param) {
|
||||
text(glTexParameterfv(target, pname, param));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexImage1D(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexImage1D(target, level, internalformat, width, border, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexImage2D(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexSubImage1D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexSubImage1D(target, level, xoffset, width, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexSubImage2D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCopyMultiTexImage1D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) {
|
||||
text(glCopyTexImage1D(target, level, internalformat, x, y, width, border));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCopyMultiTexImage2D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
|
||||
text(glCopyTexImage2D(target, level, internalformat, x, y, width, height, border));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCopyMultiTexSubImage1D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {
|
||||
text(glCopyTexSubImage1D(target, level, xoffset, x, y, width));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCopyMultiTexSubImage2D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
text(glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexImage(GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) {
|
||||
text(glGetTexImage(target, level, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexParameterfv(GLenum texunit, GLenum target, GLenum pname, GLfloat *params) {
|
||||
text(glGetTexParameterfv(target, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexParameteriv(GLenum texunit, GLenum target, GLenum pname, GLint *params) {
|
||||
text(glGetTexParameteriv(target, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexLevelParameterfv(GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params) {
|
||||
text(glGetTexLevelParameterfv(target, level, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexLevelParameteriv(GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params) {
|
||||
text(glGetTexLevelParameteriv(target, level, pname, params));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexImage3D(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexSubImage3D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
text(glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCopyMultiTexSubImage3D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
text(glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height));
|
||||
}
|
||||
// Compressed texture
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexImage3D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexImage2D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexImage1D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexImage1D(target, level, internalformat, width, border, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexSubImage3D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexSubImage2D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexSubImage1D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) {
|
||||
text(glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, data));
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetCompressedMultiTexImage(GLenum texunit, GLenum target, GLint level, GLvoid *img) {
|
||||
text(glGetCompressedTexImage(target, level, img));
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEnableClientStateIndexed(GLenum array, GLuint index) {
|
||||
DBG(printf("glEnableClientStateIndexed(%s, %d)\n", PrintEnum(array), index);)
|
||||
if (array == GL_TEXTURE_COORD_ARRAY) {
|
||||
int old = glstate->texture.client;
|
||||
if(old!=index) gl4es_glClientActiveTexture(GL_TEXTURE0+index);
|
||||
gl4es_glEnableClientState(array);
|
||||
if(old!=index) gl4es_glClientActiveTexture(GL_TEXTURE0+old);
|
||||
errorGL();
|
||||
} else {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
AliasDecl(void,gl4es_glEnableClientStatei,(GLenum array, GLuint index),gl4es_glEnableClientStateIndexed);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDisableClientStateIndexed(GLenum array, GLuint index) {
|
||||
DBG(printf("glDisableClientStateIndexed(%s, %d)\n", PrintEnum(array), index);)
|
||||
if (array == GL_TEXTURE_COORD_ARRAY) {
|
||||
int old = glstate->texture.client;
|
||||
if(old!=index) gl4es_glClientActiveTexture(GL_TEXTURE0+index);
|
||||
gl4es_glDisableClientState(array);
|
||||
if(old!=index) gl4es_glClientActiveTexture(GL_TEXTURE0+old);
|
||||
errorGL();
|
||||
} else {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
AliasDecl(void,gl4es_glDisableClientStatei,(GLenum array, GLuint index),gl4es_glDisableClientStateIndexed);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEnableVertexArray(GLuint vaobj, GLenum array) {
|
||||
DBG(printf("glEnableVertexArray(%d, %s)\n", vaobj, PrintEnum(array));)
|
||||
GLuint old = glstate->vao->array;
|
||||
gl4es_glBindVertexArray(vaobj);
|
||||
gl4es_glEnableClientState(array);
|
||||
gl4es_glBindVertexArray(old);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glDisableVertexArray(GLuint vaobj, GLenum array) {
|
||||
DBG(printf("glDisableVertexArray(%d, %s)\n", vaobj, PrintEnum(array));)
|
||||
GLuint old = glstate->vao->array;
|
||||
gl4es_glBindVertexArray(vaobj);
|
||||
gl4es_glDisableClientState(array);
|
||||
gl4es_glBindVertexArray(old);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glEnableVertexArrayAttrib(GLuint vaobj, GLuint index) {
|
||||
DBG(printf("glEnableVertexArrayAttrib(%d, %d)\n", vaobj, index);)
|
||||
GLuint old = glstate->vao->array;
|
||||
gl4es_glBindVertexArray(vaobj);
|
||||
gl4es_glEnableVertexAttribArray(index);
|
||||
gl4es_glBindVertexArray(old);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glDisableVertexArrayAttrib(GLuint vaobj, GLuint index) {
|
||||
DBG(printf("glDisableVertexArrayAttrib(%d, %d)\n", vaobj, index);)
|
||||
GLuint old = glstate->vao->array;
|
||||
gl4es_glBindVertexArray(vaobj);
|
||||
gl4es_glDisableVertexAttribArray(index);
|
||||
gl4es_glBindVertexArray(old);
|
||||
}
|
||||
|
||||
#define GETXXX(XXX, xxx) \
|
||||
void APIENTRY_GL4ES gl4es_glGet##XXX##Indexedv(GLenum target, GLuint index, GL##xxx *data) { \
|
||||
switch(target) { \
|
||||
case GL_PROGRAM_MATRIX_EXT: \
|
||||
case GL_TRANSPOSE_PROGRAM_MATRIX_EXT: \
|
||||
case GL_PROGRAM_MATRIX_STACK_DEPTH_EXT: \
|
||||
{ \
|
||||
int old = glstate->matrix_mode; \
|
||||
gl4es_glMatrixMode(GL_MATRIX0_ARB+index); \
|
||||
switch(target) { \
|
||||
case GL_PROGRAM_MATRIX_EXT: \
|
||||
gl4es_glGet##XXX##v(GL_CURRENT_MATRIX_ARB, data); \
|
||||
break; \
|
||||
case GL_TRANSPOSE_PROGRAM_MATRIX_EXT: \
|
||||
gl4es_glGet##XXX##v(GL_TRANSPOSE_CURRENT_MATRIX_ARB, data); \
|
||||
break; \
|
||||
case GL_PROGRAM_MATRIX_STACK_DEPTH_EXT: \
|
||||
gl4es_glGet##XXX##v(GL_CURRENT_MATRIX_STACK_DEPTH_ARB, data); \
|
||||
break; \
|
||||
} \
|
||||
gl4es_glMatrixMode(old); \
|
||||
} \
|
||||
break; \
|
||||
case GL_CURRENT_RASTER_TEXTURE_COORDS: \
|
||||
case GL_CURRENT_TEXTURE_COORDS: \
|
||||
case GL_TEXTURE_BINDING_1D: \
|
||||
case GL_TEXTURE_BINDING_1D_ARRAY: \
|
||||
case GL_TEXTURE_BINDING_2D: \
|
||||
case GL_TEXTURE_BINDING_2D_ARRAY: \
|
||||
case GL_TEXTURE_BINDING_3D: \
|
||||
case GL_TEXTURE_BINDING_BUFFER_EXT: \
|
||||
case GL_TEXTURE_BINDING_CUBE_MAP: \
|
||||
case GL_TEXTURE_BINDING_RECTANGLE_ARB: \
|
||||
case GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT: \
|
||||
case GL_TEXTURE_BUFFER_FORMAT_EXT: \
|
||||
case GL_TEXTURE_GEN_Q: \
|
||||
case GL_TEXTURE_GEN_R: \
|
||||
case GL_TEXTURE_GEN_S: \
|
||||
case GL_TEXTURE_GEN_T: \
|
||||
case GL_TEXTURE_MATRIX: \
|
||||
case GL_TEXTURE_STACK_DEPTH: \
|
||||
case GL_TRANSPOSE_TEXTURE_MATRIX: \
|
||||
case GL_TEXTURE_1D: \
|
||||
case GL_TEXTURE_2D: \
|
||||
case GL_TEXTURE_3D: \
|
||||
case GL_TEXTURE_CUBE_MAP: \
|
||||
case GL_TEXTURE_RECTANGLE_ARB: \
|
||||
{ \
|
||||
int old = glstate->texture.active; \
|
||||
if(old!=index+GL_TEXTURE0) gl4es_glActiveTexture(index+GL_TEXTURE0); \
|
||||
gl4es_glGet##XXX##v(target, data); \
|
||||
if(old!=index+GL_TEXTURE0) gl4es_glActiveTexture(old); \
|
||||
} \
|
||||
break; \
|
||||
case GL_TEXTURE_COORD_ARRAY: \
|
||||
case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: \
|
||||
case GL_TEXTURE_COORD_ARRAY_COUNT: \
|
||||
case GL_TEXTURE_COORD_ARRAY_SIZE: \
|
||||
case GL_TEXTURE_COORD_ARRAY_STRIDE: \
|
||||
case GL_TEXTURE_COORD_ARRAY_TYPE: \
|
||||
{ \
|
||||
int old = glstate->texture.client; \
|
||||
if(old!=index) gl4es_glClientActiveTexture(index+GL_TEXTURE0); \
|
||||
gl4es_glGet##XXX##v(target, data); \
|
||||
if(old!=index) gl4es_glClientActiveTexture(old+GL_TEXTURE0); \
|
||||
} \
|
||||
break; \
|
||||
default: \
|
||||
gl4es_glGet##XXX##v(target, data); \
|
||||
} \
|
||||
}
|
||||
|
||||
GETXXX(Float, float);
|
||||
GETXXX(Double, double);
|
||||
GETXXX(Integer, int);
|
||||
GETXXX(Boolean, boolean);
|
||||
#undef GETXXX
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetPointerIndexedv(GLenum pname, GLuint index, GLvoid **params) {
|
||||
int old = glstate->texture.client;
|
||||
if(old!=index) gl4es_glClientActiveTexture(index+GL_TEXTURE0);
|
||||
gl4es_glGetPointerv(pname, params);
|
||||
if(old!=index) gl4es_glClientActiveTexture(old+GL_TEXTURE0);
|
||||
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEnableIndexed(GLenum cap, GLuint index) {
|
||||
DBG(printf("glEnableIndexed(%s, %d)\n", PrintEnum(cap), index);)
|
||||
int old = glstate->texture.active;
|
||||
if(old!=index) gl4es_glActiveTexture(index+GL_TEXTURE0);
|
||||
gl4es_glEnable(cap);
|
||||
if(old!=index) gl4es_glActiveTexture(old);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDisableIndexed(GLenum cap, GLuint index) {
|
||||
DBG(printf("glDisableIndexed(%s, %d)\n", PrintEnum(cap), index);)
|
||||
int old = glstate->texture.active;
|
||||
if(old!=index) gl4es_glActiveTexture(index+GL_TEXTURE0);
|
||||
gl4es_glDisable(cap);
|
||||
if(old!=index) gl4es_glActiveTexture(old);
|
||||
}
|
||||
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsEnabledIndexed(GLenum cap, GLuint index) {
|
||||
DBG(printf("glIsEnabledIndexed(%s, %d)\n", PrintEnum(cap), index);)
|
||||
int old;
|
||||
GLboolean rv;
|
||||
switch(cap) {
|
||||
case GL_TEXTURE_1D:
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_3D:
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
case GL_TEXTURE_RECTANGLE_ARB:
|
||||
case GL_TEXTURE_GEN_S:
|
||||
case GL_TEXTURE_GEN_T:
|
||||
case GL_TEXTURE_GEN_R:
|
||||
case GL_TEXTURE_GEN_Q:
|
||||
old = glstate->texture.active;
|
||||
if(old!=index) gl4es_glActiveTexture(index+GL_TEXTURE0);
|
||||
rv = gl4es_glIsEnabled(cap);
|
||||
if(old!=index) gl4es_glActiveTexture(old);
|
||||
return rv;
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
old = glstate->texture.client;
|
||||
if(old!=index) gl4es_glClientActiveTexture(index+GL_TEXTURE0);
|
||||
rv = gl4es_glIsEnabled(cap);
|
||||
if(old!=index) gl4es_glClientActiveTexture(old+GL_TEXTURE0);
|
||||
return rv;
|
||||
}
|
||||
return gl4es_glIsEnabled(cap);
|
||||
}
|
||||
|
||||
//EXT wrapper
|
||||
AliasExport(void,glClientAttribDefault,EXT,(GLbitfield mask));
|
||||
AliasExport(void,glPushClientAttribDefault,EXT,(GLbitfield mask));
|
||||
AliasExport(void,glMatrixLoadf,EXT,(GLenum matrixMode, const GLfloat *m));
|
||||
AliasExport(void,glMatrixLoadd,EXT,(GLenum matrixMode, const GLdouble *m));
|
||||
AliasExport(void,glMatrixMultf,EXT,(GLenum matrixMode, const GLfloat *m));
|
||||
AliasExport(void,glMatrixMultd,EXT,(GLenum matrixMode, const GLdouble *m));
|
||||
AliasExport(void,glMatrixLoadIdentity,EXT,(GLenum matrixMode));
|
||||
AliasExport(void,glMatrixRotatef,EXT,(GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z));
|
||||
AliasExport_D_1(void,glMatrixRotated,EXT,(GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z));
|
||||
AliasExport(void,glMatrixScalef,EXT,(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z));
|
||||
AliasExport_D_1(void,glMatrixScaled,EXT,(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z));
|
||||
AliasExport(void,glMatrixTranslatef,EXT,(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z));
|
||||
AliasExport_D_1(void,glMatrixTranslated,EXT,(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z));
|
||||
AliasExport_D_1(void,glMatrixOrtho,EXT,(GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f));
|
||||
AliasExport_D_1(void,glMatrixFrustum,EXT,(GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f));
|
||||
AliasExport(void,glMatrixPush,EXT,(GLenum matrixMode));
|
||||
AliasExport(void,glMatrixPop,EXT,(GLenum matrixMode));
|
||||
AliasExport(void,glTextureParameteri,EXT,(GLuint texture, GLenum target, GLenum pname, GLint param));
|
||||
AliasExport(void,glTextureParameteriv,EXT,(GLuint texture, GLenum target, GLenum pname, const GLint *param));
|
||||
AliasExport(void,glTextureParameterf,EXT,(GLuint texture, GLenum target, GLenum pname, GLfloat param));
|
||||
AliasExport(void,glTextureParameterfv,EXT,(GLuint texture, GLenum target, GLenum pname, const GLfloat *param));
|
||||
AliasExport(void,glTextureImage1D,EXT,(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glTextureImage2D,EXT,(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glTextureSubImage1D,EXT,(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glTextureSubImage2D,EXT,(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glCopyTextureImage1D,EXT,(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border));
|
||||
AliasExport(void,glCopyTextureImage2D,EXT,(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border));
|
||||
AliasExport(void,glCopyTextureSubImage1D,EXT,(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width));
|
||||
AliasExport(void,glCopyTextureSubImage2D,EXT,(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height));
|
||||
AliasExport(void,glGetTextureImage,EXT,(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels));
|
||||
AliasExport(void,glGetTextureParameterfv,EXT,(GLuint texture, GLenum target, GLenum pname, GLfloat *params));
|
||||
AliasExport(void,glGetTextureParameteriv,EXT,(GLuint texture, GLenum target, GLenum pname, GLint *params));
|
||||
AliasExport(void,glGetTextureLevelParameterfv,EXT,(GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params));
|
||||
AliasExport(void,glGetTextureLevelParameteriv,EXT,(GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params));
|
||||
AliasExport(void,glTextureImage3D,EXT,(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glTextureSubImage3D,EXT,(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glCopyTextureSubImage3D,EXT,(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height));
|
||||
AliasExport(void,glBindMultiTexture,EXT,(GLenum texunit, GLenum target, GLuint texture));
|
||||
AliasExport(void,glMultiTexCoordPointer,EXT,(GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer));
|
||||
AliasExport(void,glMultiTexEnvf,EXT,(GLenum texunit, GLenum target, GLenum pname, GLfloat param));
|
||||
AliasExport(void,glMultiTexEnvfv,EXT,(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params));
|
||||
AliasExport(void,glMultiTexEnvi,EXT,(GLenum texunit, GLenum target, GLenum pname, GLint param));
|
||||
AliasExport(void,glMultiTexEnviv,EXT,(GLenum texunit, GLenum target, GLenum pname, const GLint *params));
|
||||
AliasExport_M(void,glMultiTexGend,EXT,(GLenum texunit, GLenum coord, GLenum pname, GLdouble param),20);
|
||||
AliasExport(void,glMultiTexGendv,EXT,(GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params));
|
||||
AliasExport(void,glMultiTexGenf,EXT,(GLenum texunit, GLenum coord, GLenum pname, GLfloat param));
|
||||
AliasExport(void,glMultiTexGenfv,EXT,(GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params));
|
||||
AliasExport(void,glMultiTexGeni,EXT,(GLenum texunit, GLenum coord, GLenum pname, GLint param));
|
||||
AliasExport(void,glMultiTexGeniv,EXT,(GLenum texunit, GLenum coord, GLenum pname, const GLint *params));
|
||||
AliasExport(void,glGetMultiTexEnvfv,EXT,(GLenum texunit, GLenum target, GLenum pname, GLfloat *params));
|
||||
AliasExport(void,glGetMultiTexEnviv,EXT,(GLenum texunit, GLenum target, GLenum pname, GLint *params));
|
||||
AliasExport(void,glGetMultiTexGendv,EXT,(GLenum texunit, GLenum coord, GLenum pname, GLdouble *params));
|
||||
AliasExport(void,glGetMultiTexGenfv,EXT,(GLenum texunit, GLenum coord, GLenum pname, GLfloat *params));
|
||||
AliasExport(void,glGetMultiTexGeniv,EXT,(GLenum texunit, GLenum coord, GLenum pname, GLint *params));
|
||||
AliasExport(void,glMultiTexParameteri,EXT,(GLenum texunit, GLenum target, GLenum pname, GLint param));
|
||||
AliasExport(void,glMultiTexParameteriv,EXT,(GLenum texunit, GLenum target, GLenum pname, const GLint *param));
|
||||
AliasExport(void,glMultiTexParameterf,EXT,(GLenum texunit, GLenum target, GLenum pname, GLfloat param));
|
||||
AliasExport(void,glMultiTexParameterfv,EXT,(GLenum texunit, GLenum target, GLenum pname, const GLfloat *param));
|
||||
AliasExport(void,glMultiTexImage1D,EXT,(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glMultiTexImage2D,EXT,(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glMultiTexSubImage1D,EXT,(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glMultiTexSubImage2D,EXT,(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glCopyMultiTexImage1D,EXT,(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border));
|
||||
AliasExport(void,glCopyMultiTexImage2D,EXT,(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border));
|
||||
AliasExport(void,glCopyMultiTexSubImage1D,EXT,(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width));
|
||||
AliasExport(void,glCopyMultiTexSubImage2D,EXT,(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height));
|
||||
AliasExport(void,glGetMultiTexImage,EXT,(GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels));
|
||||
AliasExport(void,glGetMultiTexParameterfv,EXT,(GLenum texunit, GLenum target, GLenum pname, GLfloat *params));
|
||||
AliasExport(void,glGetMultiTexParameteriv,EXT,(GLenum texunit, GLenum target, GLenum pname, GLint *params));
|
||||
AliasExport(void,glGetMultiTexLevelParameterfv,EXT,(GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params));
|
||||
AliasExport(void,glGetMultiTexLevelParameteriv,EXT,(GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params));
|
||||
AliasExport(void,glMultiTexImage3D,EXT,(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glMultiTexSubImage3D,EXT,(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels));
|
||||
AliasExport(void,glCopyMultiTexSubImage3D,EXT,(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height));
|
||||
AliasExport(void,glCompressedTextureImage3D,EXT,(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glCompressedTextureImage2D,EXT,(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glCompressedTextureImage1D,EXT,(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glCompressedTextureSubImage3D,EXT,(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glCompressedTextureSubImage2D,EXT,(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glCompressedTextureSubImage1D,EXT,(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glGetCompressedTextureImage,EXT,(GLuint texture, GLenum target, GLint level, GLvoid *img));
|
||||
AliasExport(void,glCompressedMultiTexImage3D,EXT,(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glCompressedMultiTexImage2D,EXT,(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glCompressedMultiTexImage1D,EXT,(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glCompressedMultiTexSubImage3D,EXT,(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glCompressedMultiTexSubImage2D,EXT,(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glCompressedMultiTexSubImage1D,EXT,(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data));
|
||||
AliasExport(void,glGetCompressedMultiTexImage,EXT,(GLenum texunit, GLenum target, GLint level, GLvoid *img));
|
||||
AliasExport(void,glMatrixLoadTransposef,EXT,(GLenum matrixMode, const GLfloat *m));
|
||||
AliasExport(void,glMatrixLoadTransposed,EXT,(GLenum matrixMode, const GLdouble *m));
|
||||
AliasExport(void,glMatrixMultTransposef,EXT,(GLenum matrixMode, const GLfloat *m));
|
||||
AliasExport(void,glMatrixMultTransposed,EXT,(GLenum matrixMode, const GLdouble *m));
|
||||
AliasExport(void,glEnableClientStateIndexed,EXT,(GLenum array, GLuint index));
|
||||
AliasExport(void,glDisableClientStateIndexed,EXT,(GLenum array, GLuint index));
|
||||
AliasExport_A(void,glEnableClientStatei,EXT,(GLenum array, GLuint index),glEnableClientStateIndexed);
|
||||
AliasExport_A(void,glDisableClientStatei,EXT,(GLenum array, GLuint index),glEnableClientStateIndexed);
|
||||
AliasExport(void,glEnableVertexArray,EXT,(GLuint vaobj, GLenum array));
|
||||
AliasExport(void,glDisableVertexArray,EXT,(GLuint vaobj, GLenum array));
|
||||
AliasExport(void,glEnableVertexArrayAttrib,EXT,(GLuint vaobj, GLuint index));
|
||||
AliasExport(void,glDisableVertexArrayAttrib,EXT,(GLuint vaobj, GLuint index));
|
||||
AliasExport(void,glGetPointerIndexedv,EXT,(GLenum pname, GLuint index, GLvoid **params));
|
||||
AliasExport(void,glGetFloatIndexedv,EXT,(GLenum target, GLuint index, GLfloat *data));
|
||||
AliasExport(void,glGetDoubleIndexedv,EXT,(GLenum target, GLuint index, GLdouble *data));
|
||||
AliasExport(void,glGetIntegerIndexedv,EXT,(GLenum target, GLuint index, GLint *data));
|
||||
AliasExport(void,glGetBooleanIndexedv,EXT,(GLenum target, GLuint index, GLboolean *data));
|
||||
AliasExport(void,glEnableIndexed,EXT,(GLenum cap, GLuint index));
|
||||
AliasExport(void,glDisableIndexed,EXT,(GLenum cap, GLuint index));
|
||||
AliasExport(GLboolean,glIsEnabledIndexed,EXT,(GLenum cap, GLuint index));
|
||||
#undef text
|
||||
#undef texc
|
||||
@@ -0,0 +1,126 @@
|
||||
#ifndef _GL4ES_DIRECTSTATE_H_
|
||||
#define _GL4ES_DIRECTSTATE_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glClientAttribDefault(GLbitfield mask);
|
||||
void APIENTRY_GL4ES gl4es_glPushClientAttribDefault(GLbitfield mask);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMatrixLoadf(GLenum matrixMode, const GLfloat *m);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixLoadd(GLenum matrixMode, const GLdouble *m);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixMultf(GLenum matrixMode, const GLfloat *m);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixMultd(GLenum matrixMode, const GLdouble *m);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixLoadIdentity(GLenum matrixMode);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixRotatef(GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixRotated(GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixScalef(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixScaled(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixTranslatef(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixTranslated(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixOrtho(GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixFrustum(GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixPush(GLenum matrixMode);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixPop(GLenum matrixMode);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glTextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param);
|
||||
void APIENTRY_GL4ES gl4es_glTextureParameteriv(GLuint texture, GLenum target, GLenum pname, const GLint *param);
|
||||
void APIENTRY_GL4ES gl4es_glTextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param);
|
||||
void APIENTRY_GL4ES gl4es_glTextureParameterfv(GLuint texture, GLenum target, GLenum pname, const GLfloat *param);
|
||||
void APIENTRY_GL4ES gl4es_glTextureImage1D(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glTextureImage2D(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glCopyTextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
|
||||
void APIENTRY_GL4ES gl4es_glCopyTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
void APIENTRY_GL4ES gl4es_glCopyTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
|
||||
void APIENTRY_GL4ES gl4es_glCopyTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void APIENTRY_GL4ES gl4es_glGetTextureImage(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glGetTextureParameterfv(GLuint texture, GLenum target, GLenum pname, GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetTextureParameteriv(GLuint texture, GLenum target, GLenum pname, GLint *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetTextureLevelParameterfv(GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetTextureLevelParameteriv(GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glTextureImage3D(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glCopyTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBindMultiTexture(GLenum texunit, GLenum target, GLuint texture);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexCoordPointer(GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexEnvf(GLenum texunit, GLenum target, GLenum pname, GLfloat param);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexEnvfv(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexEnvi(GLenum texunit, GLenum target, GLenum pname, GLint param);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexEnviv(GLenum texunit, GLenum target, GLenum pname, const GLint *params);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGend(GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGendv(GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGenf(GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGenfv(GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGeni(GLenum texunit, GLenum coord, GLenum pname, GLint param);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexGeniv(GLenum texunit, GLenum coord, GLenum pname, const GLint *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexEnvfv(GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexEnviv(GLenum texunit, GLenum target, GLenum pname, GLint *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexGendv(GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexGenfv(GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexGeniv(GLenum texunit, GLenum coord, GLenum pname, GLint *params);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexParameteri(GLenum texunit, GLenum target, GLenum pname, GLint param);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexParameteriv(GLenum texunit, GLenum target, GLenum pname, const GLint *param);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexParameterf(GLenum texunit, GLenum target, GLenum pname, GLfloat param);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexParameterfv(GLenum texunit, GLenum target, GLenum pname, const GLfloat *param);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexImage1D(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexImage2D(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexSubImage1D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexSubImage2D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glCopyMultiTexImage1D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
|
||||
void APIENTRY_GL4ES gl4es_glCopyMultiTexImage2D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
void APIENTRY_GL4ES gl4es_glCopyMultiTexSubImage1D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
|
||||
void APIENTRY_GL4ES gl4es_glCopyMultiTexSubImage2D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexImage(GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexParameterfv(GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexParameteriv(GLenum texunit, GLenum target, GLenum pname, GLint *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexLevelParameterfv(GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetMultiTexLevelParameteriv(GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexImage3D(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexSubImage3D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void APIENTRY_GL4ES gl4es_glCopyMultiTexSubImage3D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureImage3D(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glCompressedTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glGetCompressedTextureImage(GLuint texture, GLenum target, GLint level, GLvoid *img);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexImage3D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexImage2D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexImage1D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexSubImage3D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexSubImage2D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glCompressedMultiTexSubImage1D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
|
||||
void APIENTRY_GL4ES gl4es_glGetCompressedMultiTexImage(GLenum texunit, GLenum target, GLint level, GLvoid *img);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMatrixLoadTransposef(GLenum matrixMode, const GLfloat *m);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixLoadTransposed(GLenum matrixMode, const GLdouble *m);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixMultTransposef(GLenum matrixMode, const GLfloat *m);
|
||||
void APIENTRY_GL4ES gl4es_glMatrixMultTransposed(GLenum matrixMode, const GLdouble *m);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEnableClientStateIndexed(GLenum array, GLuint index);
|
||||
void APIENTRY_GL4ES gl4es_glDisableClientStateIndexed(GLenum array, GLuint index);
|
||||
void APIENTRY_GL4ES gl4es_glEnableClientStatei(GLenum array, GLuint index);
|
||||
void APIENTRY_GL4ES gl4es_glDisableClientStatei(GLenum array, GLuint index);
|
||||
void APIENTRY_GL4ES gl4es_glEnableVertexArray(GLuint vaobj, GLenum array);
|
||||
void APIENTRY_GL4ES gl4es_glDisableVertexArray(GLuint vaobj, GLenum array);
|
||||
void APIENTRY_GL4ES gl4es_glEnableVertexArrayAttrib(GLuint vaobj, GLuint index);
|
||||
void APIENTRY_GL4ES gl4es_glDisableVertexArrayAttrib(GLuint vaobj, GLuint index);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetFloatIndexedv(GLenum target, GLuint index, GLfloat *data);
|
||||
void APIENTRY_GL4ES gl4es_glGetDoubleIndexedv(GLenum target, GLuint index, GLdouble *data);
|
||||
void APIENTRY_GL4ES gl4es_glGetIntegerIndexedv(GLenum target, GLuint index, GLint *data);
|
||||
void APIENTRY_GL4ES gl4es_glGetBooleanIndexedv(GLenum target, GLuint index, GLboolean *data);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetPointerIndexedv(GLenum pname, GLuint index, GLvoid **params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEnableIndexed(GLenum cap, GLuint index);
|
||||
void APIENTRY_GL4ES gl4es_glDisableIndexed(GLenum cap, GLuint index);
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsEnabledIndexed(GLenum cap, GLuint index);
|
||||
|
||||
#endif // _GL4ES_DIRECTSTATE_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,426 @@
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "init.h"
|
||||
#include "loader.h"
|
||||
#include "debug.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DBG(a) a
|
||||
#else
|
||||
#define DBG(a)
|
||||
#endif
|
||||
|
||||
static void gl_changetex(int n)
|
||||
{
|
||||
if(glstate->bound_changed < n+1)
|
||||
glstate->bound_changed = n+1;
|
||||
}
|
||||
|
||||
static void fpe_changeplane(int n, bool enable)
|
||||
{
|
||||
glstate->fpe = NULL;
|
||||
if(enable)
|
||||
glstate->fpe_state->plane |= 1<<n;
|
||||
else
|
||||
glstate->fpe_state->plane &= ~(1<<n);
|
||||
}
|
||||
static void fpe_changelight(int n, bool enable)
|
||||
{
|
||||
glstate->fpe = NULL;
|
||||
if(enable)
|
||||
glstate->fpe_state->light |= 1<<n;
|
||||
else
|
||||
glstate->fpe_state->light &= ~(1<<n);
|
||||
}
|
||||
static void fpe_changetex(int n)
|
||||
{
|
||||
if(glstate->fpe_bound_changed < n+1)
|
||||
glstate->fpe_bound_changed = n+1;
|
||||
}
|
||||
#define generate_changetexgen(C) \
|
||||
static void fpe_changetexgen_##C(int n, bool enable) \
|
||||
{ \
|
||||
glstate->fpe_state->texgen[n].texgen_##C = enable?1:0; \
|
||||
}
|
||||
generate_changetexgen(s)
|
||||
generate_changetexgen(t)
|
||||
generate_changetexgen(r)
|
||||
generate_changetexgen(q)
|
||||
#undef generate_changetexgen
|
||||
|
||||
void change_vao_texcoord(int tmu, bool enable)
|
||||
{
|
||||
glstate->vao->vertexattrib[ATT_MULTITEXCOORD0+tmu].enabled = enable;
|
||||
if(enable) {
|
||||
if(glstate->vao->maxtex<tmu+1) glstate->vao->maxtex=tmu+1;
|
||||
} else {
|
||||
if(glstate->vao->maxtex==tmu+1) {
|
||||
glstate->vao->maxtex=tmu;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef GL_TEXTURE_STREAM_IMG
|
||||
#define GL_TEXTURE_STREAM_IMG 0x8C0D
|
||||
#endif
|
||||
|
||||
static void proxy_glEnable(GLenum cap, bool enable, void (APIENTRY_GLES *next)(GLenum)) {
|
||||
#define proxy_GO(constant, name) \
|
||||
case constant: if(glstate->enable.name != enable) {FLUSH_BEGINEND; glstate->enable.name = enable; next(cap);} break
|
||||
#define proxy_GOFPE(constant, name, fct) \
|
||||
case constant: if(glstate->enable.name != enable) {FLUSH_BEGINEND; glstate->enable.name = enable; if(glstate->fpe_state) { fct; } else next(cap);} break
|
||||
#define GO(constant, name) \
|
||||
case constant: if(glstate->list.pending && glstate->enable.name!=enable) gl4es_flush(); glstate->enable.name = enable; break;
|
||||
#define GONF(constant, name) \
|
||||
case constant: glstate->enable.name = enable; break;
|
||||
#define GOFPE(constant, name, fct) \
|
||||
case constant: if(glstate->list.pending && glstate->enable.name!=enable) gl4es_flush(); glstate->enable.name = enable; if(glstate->fpe_state) { fct; } break;
|
||||
#define proxy_clientGO(constant, name) \
|
||||
case constant: if (glstate->vao->name != enable) {glstate->vao->name = enable; next(cap);} break
|
||||
#define clientGO(constant, name) \
|
||||
case constant: glstate->vao->name = enable; break;
|
||||
#define clientGO_proxyFPE(constant, name) \
|
||||
case constant: glstate->vao->name = enable; if(glstate->fpe_state) { next(cap);} break;
|
||||
// Alpha Hack
|
||||
if (globals4es.alphahack && (cap==GL_ALPHA_TEST) && enable) {
|
||||
if (!glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]->alpha)
|
||||
enable = false;
|
||||
}
|
||||
noerrorShim();
|
||||
#ifdef TEXSTREAM
|
||||
if (cap==GL_TEXTURE_STREAM_IMG) {
|
||||
FLUSH_BEGINEND;
|
||||
if(enable)
|
||||
glstate->enable.texture[glstate->texture.active] |= (1<<ENABLED_TEX2D);
|
||||
else
|
||||
glstate->enable.texture[glstate->texture.active] &= ~(1<<ENABLED_TEX2D);
|
||||
gl_changetex(glstate->texture.active);
|
||||
if(glstate->fpe_state)
|
||||
fpe_changetex(glstate->texture.active);
|
||||
else
|
||||
next(cap);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (cap) {
|
||||
GO(GL_AUTO_NORMAL, auto_normal);
|
||||
proxy_GOFPE(GL_ALPHA_TEST, alpha_test,glstate->fpe_state->alphatest=enable);
|
||||
proxy_GOFPE(GL_FOG, fog, glstate->fpe_state->fog=enable);
|
||||
case GL_BLEND: if(glstate->enable.blend != enable) {FLUSH_BEGINEND; glstate->enable.blend = enable; if(glstate->fpe_state && globals4es.shaderblend) { glstate->fpe_state->blend_enable = enable; } else next(cap);} break;
|
||||
proxy_GO(GL_CULL_FACE, cull_face);
|
||||
proxy_GO(GL_DEPTH_TEST, depth_test);
|
||||
proxy_GO(GL_STENCIL_TEST, stencil_test);
|
||||
// texgen
|
||||
GOFPE(GL_TEXTURE_GEN_S, texgen_s[glstate->texture.active], fpe_changetexgen_s(glstate->texture.active, enable)); //TODO: FPE stuffs
|
||||
GOFPE(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active], fpe_changetexgen_t(glstate->texture.active, enable));
|
||||
GOFPE(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active], fpe_changetexgen_r(glstate->texture.active, enable));
|
||||
GOFPE(GL_TEXTURE_GEN_Q, texgen_q[glstate->texture.active], fpe_changetexgen_q(glstate->texture.active, enable));
|
||||
GO(GL_LINE_STIPPLE, line_stipple);
|
||||
|
||||
// clip plane
|
||||
proxy_GOFPE(GL_CLIP_PLANE0, plane[0], fpe_changeplane(0, enable));
|
||||
proxy_GOFPE(GL_CLIP_PLANE1, plane[1], fpe_changeplane(1, enable));
|
||||
proxy_GOFPE(GL_CLIP_PLANE2, plane[2], fpe_changeplane(2, enable));
|
||||
proxy_GOFPE(GL_CLIP_PLANE3, plane[3], fpe_changeplane(3, enable));
|
||||
proxy_GOFPE(GL_CLIP_PLANE4, plane[4], fpe_changeplane(4, enable));
|
||||
proxy_GOFPE(GL_CLIP_PLANE5, plane[5], fpe_changeplane(5, enable));
|
||||
|
||||
// lights
|
||||
proxy_GOFPE(GL_LIGHT0, light[0], fpe_changelight(0, enable));
|
||||
proxy_GOFPE(GL_LIGHT1, light[1], fpe_changelight(1, enable));
|
||||
proxy_GOFPE(GL_LIGHT2, light[2], fpe_changelight(2, enable));
|
||||
proxy_GOFPE(GL_LIGHT3, light[3], fpe_changelight(3, enable));
|
||||
proxy_GOFPE(GL_LIGHT4, light[4], fpe_changelight(4, enable));
|
||||
proxy_GOFPE(GL_LIGHT5, light[5], fpe_changelight(5, enable));
|
||||
proxy_GOFPE(GL_LIGHT6, light[6], fpe_changelight(6, enable));
|
||||
proxy_GOFPE(GL_LIGHT7, light[7], fpe_changelight(7, enable));
|
||||
proxy_GOFPE(GL_LIGHTING, lighting, glstate->fpe_state->lighting=enable);
|
||||
proxy_GOFPE(GL_NORMALIZE, normalize, glstate->fpe_state->normalize=enable);
|
||||
proxy_GOFPE(GL_RESCALE_NORMAL, normal_rescale, glstate->fpe_state->rescaling=enable);
|
||||
proxy_GOFPE(GL_COLOR_MATERIAL, color_material, glstate->fpe_state->color_material=enable);
|
||||
|
||||
// point sprite
|
||||
proxy_GOFPE(GL_POINT_SPRITE, pointsprite, glstate->fpe_state->pointsprite=enable); // TODO: plugin fpe stuffs
|
||||
proxy_GO(GL_PROGRAM_POINT_SIZE, point_size);
|
||||
|
||||
// Smooth and multisample (todo: do somthing with fpe?)
|
||||
proxy_GOFPE(GL_MULTISAMPLE, multisample, );
|
||||
proxy_GOFPE(GL_SAMPLE_COVERAGE, sample_coverage, );
|
||||
proxy_GOFPE(GL_SAMPLE_ALPHA_TO_COVERAGE, sample_alpha_to_coverage, );
|
||||
proxy_GOFPE(GL_SAMPLE_ALPHA_TO_ONE, sample_alpha_to_one, );
|
||||
proxy_GOFPE(GL_POINT_SMOOTH, point_smooth, );
|
||||
proxy_GOFPE(GL_LINE_SMOOTH, line_smooth, );
|
||||
|
||||
proxy_GO(GL_POLYGON_OFFSET_FILL, polyfill_offset);
|
||||
|
||||
// color logic op
|
||||
proxy_GOFPE(GL_COLOR_LOGIC_OP, color_logic_op, );
|
||||
|
||||
// Secondary color
|
||||
GOFPE(GL_COLOR_SUM, color_sum, glstate->fpe_state->colorsum = enable);
|
||||
//cannot use clientGO_proxyFPE here, has the ClientArray are really enabled / disabled elsewhere in fact (inside glDraw or list_draw)
|
||||
clientGO(GL_SECONDARY_COLOR_ARRAY, vertexattrib[ATT_SECONDARY].enabled);
|
||||
clientGO(GL_FOG_COORD_ARRAY, vertexattrib[ATT_FOGCOORD].enabled);
|
||||
|
||||
// for glDrawArrays
|
||||
clientGO(GL_VERTEX_ARRAY, vertexattrib[ATT_VERTEX].enabled);
|
||||
clientGO(GL_NORMAL_ARRAY, vertexattrib[ATT_NORMAL].enabled);
|
||||
clientGO(GL_COLOR_ARRAY, vertexattrib[ATT_COLOR].enabled);
|
||||
case GL_TEXTURE_COORD_ARRAY: change_vao_texcoord(glstate->texture.client, enable); break;
|
||||
|
||||
// map eval
|
||||
GONF(GL_MAP1_COLOR_4 , map1_color4);
|
||||
GONF(GL_MAP1_INDEX , map1_index);
|
||||
GONF(GL_MAP1_NORMAL , map1_normal);
|
||||
GONF(GL_MAP1_TEXTURE_COORD_1 , map1_texture1);
|
||||
GONF(GL_MAP1_TEXTURE_COORD_2 , map1_texture2);
|
||||
GONF(GL_MAP1_TEXTURE_COORD_3 , map1_texture3);
|
||||
GONF(GL_MAP1_TEXTURE_COORD_4 , map1_texture4);
|
||||
GONF(GL_MAP1_VERTEX_3 , map1_vertex3);
|
||||
GONF(GL_MAP1_VERTEX_4 , map1_vertex4);
|
||||
GONF(GL_MAP2_COLOR_4 , map2_color4);
|
||||
GONF(GL_MAP2_INDEX , map2_index);
|
||||
GONF(GL_MAP2_NORMAL , map2_normal);
|
||||
GONF(GL_MAP2_TEXTURE_COORD_1 , map2_texture1);
|
||||
GONF(GL_MAP2_TEXTURE_COORD_2 , map2_texture2);
|
||||
GONF(GL_MAP2_TEXTURE_COORD_3 , map2_texture3);
|
||||
GONF(GL_MAP2_TEXTURE_COORD_4 , map2_texture4);
|
||||
GONF(GL_MAP2_VERTEX_3 , map2_vertex3);
|
||||
GONF(GL_MAP2_VERTEX_4 , map2_vertex4);
|
||||
|
||||
// ARB_vertex_program
|
||||
proxy_GOFPE(GL_VERTEX_PROGRAM_ARB, vertex_arb, glstate->fpe_state->vertex_prg_enable=enable);
|
||||
GONF(GL_VERTEX_PROGRAM_TWO_SIDE_ARB, vertex_two_side_arb);
|
||||
// ARB_fragment_program
|
||||
proxy_GOFPE(GL_FRAGMENT_PROGRAM_ARB, fragment_arb, glstate->fpe_state->fragment_prg_enable=enable);
|
||||
|
||||
// Texture 1D and 3D
|
||||
case GL_TEXTURE_1D:
|
||||
FLUSH_BEGINEND;
|
||||
if(enable)
|
||||
glstate->enable.texture[glstate->texture.active] |= (1<<ENABLED_TEX1D);
|
||||
else
|
||||
glstate->enable.texture[glstate->texture.active] &= ~(1<<ENABLED_TEX1D);
|
||||
gl_changetex(glstate->texture.active);
|
||||
if(glstate->fpe_state)
|
||||
fpe_changetex(glstate->texture.active);
|
||||
break;
|
||||
case GL_TEXTURE_2D:
|
||||
if(glstate->list.pending && ((glstate->enable.texture[glstate->texture.active]>>ENABLED_TEX2D)&1)!=enable) gl4es_flush();
|
||||
if(enable == ((glstate->enable.texture[glstate->texture.active]>>ENABLED_TEX2D)&1))
|
||||
return; // no change
|
||||
if(enable)
|
||||
glstate->enable.texture[glstate->texture.active] |= (1<<ENABLED_TEX2D);
|
||||
else
|
||||
glstate->enable.texture[glstate->texture.active] &= ~(1<<ENABLED_TEX2D);
|
||||
gl_changetex(glstate->texture.active);
|
||||
if(glstate->fpe_state)
|
||||
fpe_changetex(glstate->texture.active);
|
||||
else {
|
||||
realize_active();
|
||||
next(cap);
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_3D:
|
||||
FLUSH_BEGINEND;
|
||||
if(enable)
|
||||
glstate->enable.texture[glstate->texture.active] |= (1<<ENABLED_TEX3D);
|
||||
else
|
||||
glstate->enable.texture[glstate->texture.active] &= ~(1<<ENABLED_TEX3D);
|
||||
gl_changetex(glstate->texture.active);
|
||||
if(glstate->fpe_state)
|
||||
fpe_changetex(glstate->texture.active);
|
||||
break;
|
||||
case GL_TEXTURE_RECTANGLE_ARB:
|
||||
FLUSH_BEGINEND;
|
||||
if(enable)
|
||||
glstate->enable.texture[glstate->texture.active] |= (1<<ENABLED_TEXTURE_RECTANGLE);
|
||||
else
|
||||
glstate->enable.texture[glstate->texture.active] &= ~(1<<ENABLED_TEXTURE_RECTANGLE);
|
||||
gl_changetex(glstate->texture.active);
|
||||
if(glstate->fpe_state)
|
||||
fpe_changetex(glstate->texture.active);
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
FLUSH_BEGINEND;
|
||||
if(enable)
|
||||
glstate->enable.texture[glstate->texture.active] |= (1<<ENABLED_CUBE_MAP);
|
||||
else
|
||||
glstate->enable.texture[glstate->texture.active] &= ~(1<<ENABLED_CUBE_MAP);
|
||||
gl_changetex(glstate->texture.active);
|
||||
if(glstate->fpe_state)
|
||||
fpe_changetex(glstate->texture.active);
|
||||
else {
|
||||
realize_active();
|
||||
next(cap);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default: errorGL(); FLUSH_BEGINEND; realize_active(); next(cap); break;
|
||||
}
|
||||
#undef proxy_GO
|
||||
#undef GO
|
||||
#undef proxy_clientGO
|
||||
#undef clientGO
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEnable(GLenum cap) {
|
||||
DBG(printf("glEnable(%s), glstate->list.pending=%d\n", PrintEnum(cap), glstate->list.pending);)
|
||||
if(!glstate->list.pending) {
|
||||
PUSH_IF_COMPILING(glEnable)
|
||||
}
|
||||
#ifdef TEXSTREAM00
|
||||
if (globals4es.texstream && (cap==GL_TEXTURE_2D)) {
|
||||
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]->streamed)
|
||||
cap = GL_TEXTURE_STREAM_IMG;
|
||||
}
|
||||
#endif
|
||||
LOAD_GLES(glEnable);
|
||||
proxy_glEnable(cap, true, gles_glEnable);
|
||||
}
|
||||
AliasExport(void,glEnable,,(GLenum cap));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDisable(GLenum cap) {
|
||||
DBG(printf("glDisable(%s), glstate->list.pending=%d\n", PrintEnum(cap), glstate->list.pending);)
|
||||
if(!glstate->list.pending) {
|
||||
PUSH_IF_COMPILING(glDisable)
|
||||
}
|
||||
|
||||
#ifdef TEXSTREAM00
|
||||
if (globals4es.texstream && (cap==GL_TEXTURE_2D)) {
|
||||
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]->streamed)
|
||||
cap = GL_TEXTURE_STREAM_IMG;
|
||||
}
|
||||
#endif
|
||||
LOAD_GLES(glDisable);
|
||||
proxy_glEnable(cap, false, gles_glDisable);
|
||||
}
|
||||
AliasExport(void,glDisable,,(GLenum cap));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEnableClientState(GLenum cap) {
|
||||
DBG(printf("glEnableClientState(%s), list.begin=%dn", PrintEnum(cap), glstate->list.begin);)
|
||||
ERROR_IN_BEGIN
|
||||
// should flush for now... to be optimized later!
|
||||
/*if (glstate->list.active && !glstate->list.compiling && !glstate->list.pending)
|
||||
gl4es_flush();*/
|
||||
proxy_glEnable(cap, true, fpe_glEnableClientState);
|
||||
}
|
||||
AliasExport(void,glEnableClientState,,(GLenum cap));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDisableClientState(GLenum cap) {
|
||||
DBG(printf("glDisableClientState(%s), list.begin=%d\n", PrintEnum(cap), glstate->list.begin);)
|
||||
ERROR_IN_BEGIN
|
||||
// should flush for now... to be optimized later!
|
||||
/*if (glstate->list.active && !glstate->list.compiling && !glstate->list.pending)
|
||||
gl4es_flush();*/
|
||||
proxy_glEnable(cap, false, fpe_glDisableClientState);
|
||||
}
|
||||
AliasExport(void,glDisableClientState,,(GLenum cap));
|
||||
|
||||
|
||||
#define isenabled(what, where) \
|
||||
case what: return glstate->enable.where
|
||||
#define clientisenabled(what, where) \
|
||||
case what: return glstate->vao->where
|
||||
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsEnabled(GLenum cap) {
|
||||
DBG(printf("glIsEnabed(%s), list.begin=%d, list.compiling=%d, list.pending=%d\n", PrintEnum(cap), glstate->list.begin, glstate->list.compiling, glstate->list.pending);)
|
||||
if(glstate->list.begin) {errorShim(GL_INVALID_OPERATION); return GL_FALSE;}
|
||||
if(glstate->list.compiling) {errorShim(GL_INVALID_OPERATION); return GL_FALSE;}
|
||||
// should flush for now... but no need if it's just a pending list...
|
||||
if (glstate->list.active && !glstate->list.pending)
|
||||
gl4es_flush();
|
||||
LOAD_GLES(glIsEnabled);
|
||||
noerrorShim();
|
||||
switch (cap) {
|
||||
isenabled(GL_AUTO_NORMAL, auto_normal);
|
||||
isenabled(GL_ALPHA_TEST, alpha_test);
|
||||
isenabled(GL_FOG, fog);
|
||||
isenabled(GL_BLEND, blend);
|
||||
isenabled(GL_CULL_FACE, cull_face);
|
||||
isenabled(GL_DEPTH_TEST, depth_test);
|
||||
isenabled(GL_STENCIL_TEST, stencil_test);
|
||||
isenabled(GL_LINE_STIPPLE, line_stipple);
|
||||
isenabled(GL_TEXTURE_GEN_S, texgen_s[glstate->texture.active]);
|
||||
isenabled(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active]);
|
||||
isenabled(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active]);
|
||||
isenabled(GL_TEXTURE_GEN_Q, texgen_q[glstate->texture.active]);
|
||||
isenabled(GL_COLOR_MATERIAL, color_material);
|
||||
isenabled(GL_COLOR_SUM, color_sum);
|
||||
isenabled(GL_POINT_SPRITE, pointsprite);
|
||||
isenabled(GL_PROGRAM_POINT_SIZE, point_size);
|
||||
isenabled(GL_CLIP_PLANE0, plane[0]);
|
||||
isenabled(GL_CLIP_PLANE1, plane[1]);
|
||||
isenabled(GL_CLIP_PLANE2, plane[2]);
|
||||
isenabled(GL_CLIP_PLANE3, plane[3]);
|
||||
isenabled(GL_CLIP_PLANE4, plane[4]);
|
||||
isenabled(GL_CLIP_PLANE5, plane[5]);
|
||||
isenabled(GL_LIGHT0, light[0]);
|
||||
isenabled(GL_LIGHT1, light[1]);
|
||||
isenabled(GL_LIGHT2, light[2]);
|
||||
isenabled(GL_LIGHT3, light[3]);
|
||||
isenabled(GL_LIGHT4, light[4]);
|
||||
isenabled(GL_LIGHT5, light[5]);
|
||||
isenabled(GL_LIGHT6, light[6]);
|
||||
isenabled(GL_LIGHT7, light[7]);
|
||||
isenabled(GL_LIGHTING, lighting);
|
||||
isenabled(GL_MULTISAMPLE, multisample);
|
||||
isenabled(GL_SAMPLE_COVERAGE, sample_coverage);
|
||||
isenabled(GL_SAMPLE_ALPHA_TO_COVERAGE, sample_alpha_to_coverage);
|
||||
isenabled(GL_SAMPLE_ALPHA_TO_ONE, sample_alpha_to_one);
|
||||
isenabled(GL_POINT_SMOOTH, point_smooth);
|
||||
isenabled(GL_LINE_SMOOTH, line_smooth);
|
||||
isenabled(GL_POLYGON_OFFSET_FILL, polyfill_offset);
|
||||
isenabled(GL_COLOR_LOGIC_OP, color_logic_op);
|
||||
clientisenabled(GL_SECONDARY_COLOR_ARRAY, vertexattrib[ATT_SECONDARY].enabled);
|
||||
clientisenabled(GL_FOG_COORD_ARRAY, vertexattrib[ATT_FOGCOORD].enabled);
|
||||
case GL_TEXTURE_1D: return glstate->enable.texture[glstate->texture.active]&(1<<ENABLED_TEX1D);
|
||||
case GL_TEXTURE_2D: return glstate->enable.texture[glstate->texture.active]&(1<<ENABLED_TEX2D);
|
||||
case GL_TEXTURE_3D: return glstate->enable.texture[glstate->texture.active]&(1<<ENABLED_TEX3D);
|
||||
case GL_TEXTURE_CUBE_MAP: return glstate->enable.texture[glstate->texture.active]&(1<<ENABLED_CUBE_MAP);
|
||||
clientisenabled(GL_VERTEX_ARRAY, vertexattrib[ATT_VERTEX].enabled);
|
||||
clientisenabled(GL_NORMAL_ARRAY, vertexattrib[ATT_NORMAL].enabled);
|
||||
clientisenabled(GL_COLOR_ARRAY, vertexattrib[ATT_COLOR].enabled);
|
||||
clientisenabled(GL_TEXTURE_COORD_ARRAY, vertexattrib[ATT_MULTITEXCOORD0+glstate->texture.client].enabled);
|
||||
isenabled(GL_NORMALIZE, normalize);
|
||||
isenabled(GL_RESCALE_NORMAL, normal_rescale);
|
||||
isenabled(GL_MAP1_COLOR_4, map1_color4);
|
||||
isenabled(GL_MAP1_INDEX, map1_index);
|
||||
isenabled(GL_MAP1_NORMAL, map1_normal);
|
||||
isenabled(GL_MAP1_TEXTURE_COORD_1, map1_texture1);
|
||||
isenabled(GL_MAP1_TEXTURE_COORD_2, map1_texture2);
|
||||
isenabled(GL_MAP1_TEXTURE_COORD_3, map1_texture3);
|
||||
isenabled(GL_MAP1_TEXTURE_COORD_4, map1_texture4);
|
||||
isenabled(GL_MAP1_VERTEX_3, map1_vertex3);
|
||||
isenabled(GL_MAP1_VERTEX_4, map1_vertex4);
|
||||
isenabled(GL_MAP2_COLOR_4, map2_color4);
|
||||
isenabled(GL_MAP2_INDEX, map2_index);
|
||||
isenabled(GL_MAP2_NORMAL, map2_normal);
|
||||
isenabled(GL_MAP2_TEXTURE_COORD_1, map2_texture1);
|
||||
isenabled(GL_MAP2_TEXTURE_COORD_2, map2_texture2);
|
||||
isenabled(GL_MAP2_TEXTURE_COORD_3, map2_texture3);
|
||||
isenabled(GL_MAP2_TEXTURE_COORD_4, map2_texture4);
|
||||
isenabled(GL_MAP2_VERTEX_3, map2_vertex3);
|
||||
isenabled(GL_MAP2_VERTEX_4, map2_vertex4);
|
||||
// ARB_vertex_program
|
||||
isenabled(GL_VERTEX_PROGRAM_ARB, vertex_arb);
|
||||
isenabled(GL_VERTEX_PROGRAM_TWO_SIDE_ARB, vertex_two_side_arb);
|
||||
default:
|
||||
errorGL();
|
||||
return gles_glIsEnabled(cap);
|
||||
}
|
||||
}
|
||||
#undef isenabled
|
||||
#undef clientisenabled
|
||||
AliasExport(GLboolean,glIsEnabled,,(GLenum cap));
|
||||
@@ -0,0 +1,171 @@
|
||||
#ifndef _GL4ES_ENUM_INFO_H
|
||||
#define _GL4ES_ENUM_INFO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "const.h"
|
||||
#include "debug.h"
|
||||
#include "logs.h"
|
||||
|
||||
static const GLsizei gl_sizeof(GLenum type) {
|
||||
// types
|
||||
switch (type) {
|
||||
case GL_DOUBLE:
|
||||
return 8;
|
||||
case GL_FLOAT:
|
||||
case GL_INT:
|
||||
case GL_UNSIGNED_INT:
|
||||
case GL_UNSIGNED_INT_10_10_10_2:
|
||||
case GL_UNSIGNED_INT_2_10_10_10_REV:
|
||||
case GL_UNSIGNED_INT_8_8_8_8:
|
||||
case GL_UNSIGNED_INT_8_8_8_8_REV:
|
||||
case GL_UNSIGNED_INT_24_8:
|
||||
case GL_4_BYTES:
|
||||
return 4;
|
||||
case GL_3_BYTES:
|
||||
return 3;
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
case GL_SHORT:
|
||||
case GL_HALF_FLOAT:
|
||||
case GL_HALF_FLOAT_OES:
|
||||
case GL_UNSIGNED_SHORT:
|
||||
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
|
||||
case GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
|
||||
case GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
case GL_UNSIGNED_SHORT_5_6_5:
|
||||
case GL_UNSIGNED_SHORT_5_6_5_REV:
|
||||
case GL_2_BYTES:
|
||||
return 2;
|
||||
case GL_ALPHA:
|
||||
case GL_LUMINANCE:
|
||||
case GL_BYTE:
|
||||
case GL_UNSIGNED_BYTE:
|
||||
case GL_UNSIGNED_BYTE_2_3_3_REV:
|
||||
case GL_UNSIGNED_BYTE_3_3_2:
|
||||
case GL_DEPTH_COMPONENT:
|
||||
case GL_COLOR_INDEX:
|
||||
return 1;
|
||||
}
|
||||
// formats
|
||||
LOGD("Unsupported pixel data type: %s\n", PrintEnum(type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const GLuint gl_max_value(GLenum type) {
|
||||
switch (type) {
|
||||
// float/double only make sense on tex/color
|
||||
// be careful about using this
|
||||
case GL_DOUBLE:
|
||||
case GL_FLOAT:
|
||||
case GL_HALF_FLOAT:
|
||||
case GL_HALF_FLOAT_OES:
|
||||
return 1;
|
||||
case GL_BYTE: return 127;
|
||||
case GL_UNSIGNED_BYTE: return 255;
|
||||
case GL_SHORT: return 32767;
|
||||
case GL_UNSIGNED_SHORT: return 65535;
|
||||
case GL_INT: return 2147483647;
|
||||
case GL_UNSIGNED_INT: return 4294967295;
|
||||
}
|
||||
LOGD("unknown gl max value type: %s\n", PrintEnum(type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const GLboolean is_type_packed(GLenum type) {
|
||||
switch (type) {
|
||||
case GL_4_BYTES:
|
||||
case GL_3_BYTES:
|
||||
case GL_2_BYTES:
|
||||
case GL_UNSIGNED_BYTE_2_3_3_REV:
|
||||
case GL_UNSIGNED_BYTE_3_3_2:
|
||||
case GL_UNSIGNED_INT_10_10_10_2:
|
||||
case GL_UNSIGNED_INT_2_10_10_10_REV:
|
||||
case GL_UNSIGNED_INT_8_8_8_8:
|
||||
case GL_UNSIGNED_INT_8_8_8_8_REV:
|
||||
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
|
||||
case GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
|
||||
case GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
case GL_UNSIGNED_SHORT_5_6_5:
|
||||
case GL_UNSIGNED_SHORT_5_6_5_REV:
|
||||
case GL_DEPTH_STENCIL:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static const GLsizei pixel_sizeof(GLenum format, GLenum type) {
|
||||
GLsizei width = 0;
|
||||
switch (format) {
|
||||
case GL_R:
|
||||
case GL_RED:
|
||||
case GL_ALPHA:
|
||||
case GL_LUMINANCE:
|
||||
case GL_DEPTH_COMPONENT:
|
||||
case GL_DEPTH_STENCIL:
|
||||
case GL_COLOR_INDEX:
|
||||
width = 1;
|
||||
break;
|
||||
case GL_RG:
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
width = 2;
|
||||
break;
|
||||
case GL_RGB:
|
||||
case GL_BGR:
|
||||
case GL_RGB8:
|
||||
width = 3;
|
||||
break;
|
||||
case GL_RGBA:
|
||||
case GL_BGRA:
|
||||
case GL_RGBA8:
|
||||
width = 4;
|
||||
break;
|
||||
default:
|
||||
LOGD("unsupported pixel format %s\n", PrintEnum(format));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_type_packed(type))
|
||||
width = 1;
|
||||
|
||||
return width * gl_sizeof(type);
|
||||
}
|
||||
|
||||
static const GLboolean pixel_hasalpha(GLenum format) {
|
||||
switch (format) {
|
||||
case GL_ALPHA:
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
case GL_RGBA:
|
||||
case GL_BGRA:
|
||||
case GL_RGBA8:
|
||||
case GL_COLOR_INDEX:
|
||||
return true;
|
||||
case GL_RED:
|
||||
case GL_LUMINANCE:
|
||||
case GL_RG:
|
||||
case GL_RGB:
|
||||
case GL_BGR:
|
||||
case GL_RGB8:
|
||||
case GL_DEPTH_COMPONENT:
|
||||
case GL_DEPTH_STENCIL:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline const GLboolean valid_vertex_type(GLenum type) {
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
case GL_BYTE:
|
||||
case GL_FIXED:
|
||||
case GL_FLOAT:
|
||||
case GL_SHORT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _GL4ES_ENUM_INFO_H
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "envvars.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
//----------------------------------------------------------------------------
|
||||
const char* GetEnvVar(const char *name)
|
||||
{
|
||||
return getenv(name);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int HasEnvVar(const char *name)
|
||||
{
|
||||
return GetEnvVar(name)!=NULL;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int ReturnEnvVarInt(const char *name)
|
||||
{
|
||||
const char *s=GetEnvVar(name);
|
||||
return s ? atoi(s) : 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int ReturnEnvVarIntDef(const char *name,int def)
|
||||
{
|
||||
const char *s=GetEnvVar(name);
|
||||
return s ? atoi(s) : def;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int IsEnvVarTrue(const char *name)
|
||||
{
|
||||
const char *s=GetEnvVar(name);
|
||||
return s && atoi(s)!=0;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int IsEnvVarFalse(const char *name)
|
||||
{
|
||||
const char *s=GetEnvVar(name);
|
||||
return s && *s=='0';
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int IsEnvVarInt(const char *name,int i)
|
||||
{
|
||||
const char *s=GetEnvVar(name);
|
||||
return s && atoi(s)==i;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int GetEnvVarInt(const char *name,int *i,int def)
|
||||
{
|
||||
const char *s=GetEnvVar(name);
|
||||
*i=s ? atoi(s) : def;
|
||||
return s!=NULL;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int GetEnvVarBool(const char *name,int *b,int def)
|
||||
{
|
||||
const char *s=GetEnvVar(name);
|
||||
*b=s ? atoi(s) : def;
|
||||
if(*b) *b=1;
|
||||
return s!=NULL;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int GetEnvVarFloat(const char *name,float *f,float def)
|
||||
{
|
||||
const char *s=GetEnvVar(name);
|
||||
*f=s ? atof(s) : def;
|
||||
return s!=NULL;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int GetEnvVarFmt(const char *name,const char *fmt,...)
|
||||
{
|
||||
int cnt=0;
|
||||
const char *s=GetEnvVar(name);
|
||||
if(s) {
|
||||
va_list args;
|
||||
va_start(args,fmt);
|
||||
cnt=vsscanf(s,fmt,args);
|
||||
va_end(args);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef _GL4ES_ENVVARS_H_
|
||||
#define _GL4ES_ENVVARS_H_
|
||||
//----------------------------------------------------------------------------
|
||||
const char* GetEnvVar(const char *name);
|
||||
//----------------------------------------------------------------------------
|
||||
int HasEnvVar(const char *name);
|
||||
int ReturnEnvVarInt(const char *name);
|
||||
int ReturnEnvVarIntDef(const char *name,int def);
|
||||
//----------------------------------------------------------------------------
|
||||
int IsEnvVarTrue(const char *name);
|
||||
int IsEnvVarFalse(const char *name);
|
||||
int IsEnvVarInt(const char *name,int i);
|
||||
//----------------------------------------------------------------------------
|
||||
int GetEnvVarInt(const char *name,int *i,int def);
|
||||
int GetEnvVarBool(const char *name,int *b,int def);
|
||||
int GetEnvVarFloat(const char *name,float *f,float def);
|
||||
//----------------------------------------------------------------------------
|
||||
int GetEnvVarFmt(const char *name,const char *fmt,...);
|
||||
//----------------------------------------------------------------------------
|
||||
#endif
|
||||
@@ -0,0 +1,370 @@
|
||||
// TODO: glIsEnabled(), glGetMap()
|
||||
// TODO: GL_AUTO_NORMAL
|
||||
|
||||
#include "eval.h"
|
||||
|
||||
#include "math/eval.h"
|
||||
#include "wrap/gl4es.h"
|
||||
#include "array.h"
|
||||
#include "logs.h"
|
||||
#include "matvec.h"
|
||||
|
||||
static inline map_state_t **get_map_pointer(GLenum target) {
|
||||
switch (target) {
|
||||
case GL_MAP1_COLOR_4: return &glstate->map1.color4;
|
||||
case GL_MAP1_INDEX: return &glstate->map1.index;
|
||||
case GL_MAP1_TEXTURE_COORD_1: return &glstate->map1.texture1;
|
||||
case GL_MAP1_TEXTURE_COORD_2: return &glstate->map1.texture2;
|
||||
case GL_MAP1_TEXTURE_COORD_3: return &glstate->map1.texture3;
|
||||
case GL_MAP1_TEXTURE_COORD_4: return &glstate->map1.texture4;
|
||||
case GL_MAP1_VERTEX_3: return &glstate->map1.vertex3;
|
||||
case GL_MAP1_VERTEX_4: return &glstate->map1.vertex4;
|
||||
case GL_MAP2_COLOR_4: return &glstate->map2.color4;
|
||||
case GL_MAP2_INDEX: return &glstate->map2.index;
|
||||
case GL_MAP2_TEXTURE_COORD_1: return &glstate->map2.texture1;
|
||||
case GL_MAP2_TEXTURE_COORD_2: return &glstate->map2.texture2;
|
||||
case GL_MAP2_TEXTURE_COORD_3: return &glstate->map2.texture3;
|
||||
case GL_MAP2_TEXTURE_COORD_4: return &glstate->map2.texture4;
|
||||
case GL_MAP2_VERTEX_3: return &glstate->map2.vertex3;
|
||||
case GL_MAP2_VERTEX_4: return &glstate->map2.vertex4;
|
||||
default:
|
||||
LOGE("unknown glMap target 0x%x\n", target);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define set_map_coords(n) \
|
||||
map->n._1 = n##1; \
|
||||
map->n._2 = n##2; \
|
||||
map->n.d = 1.0/(n##2 - n##1); \
|
||||
map->n.order = n##order;
|
||||
|
||||
#define case_state(dims, magic, name) \
|
||||
case magic: { \
|
||||
map->width = get_map_width(magic); \
|
||||
map_statef_t *m = (map_statef_t *)glstate->map##dims.name; \
|
||||
if (m) { \
|
||||
free((void *)m->points); \
|
||||
free(m); \
|
||||
} \
|
||||
glstate->map##dims.name = (map_state_t *)map; \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define map_switch(dims) \
|
||||
switch (target) { \
|
||||
case_state(dims, GL_MAP##dims##_COLOR_4, color4); \
|
||||
case_state(dims, GL_MAP##dims##_INDEX, index); \
|
||||
case_state(dims, GL_MAP##dims##_NORMAL, normal); \
|
||||
case_state(dims, GL_MAP##dims##_TEXTURE_COORD_1, texture1); \
|
||||
case_state(dims, GL_MAP##dims##_TEXTURE_COORD_2, texture2); \
|
||||
case_state(dims, GL_MAP##dims##_TEXTURE_COORD_3, texture3); \
|
||||
case_state(dims, GL_MAP##dims##_TEXTURE_COORD_4, texture4); \
|
||||
case_state(dims, GL_MAP##dims##_VERTEX_3, vertex3); \
|
||||
case_state(dims, GL_MAP##dims##_VERTEX_4, vertex4); \
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMap1d(GLenum target, GLdouble u1, GLdouble u2,
|
||||
GLint ustride, GLint uorder, const GLdouble *points) {
|
||||
noerrorShim();
|
||||
map_statef_t *map = malloc(sizeof(map_statef_t));
|
||||
map->type = GL_FLOAT; map->dims = 1;
|
||||
set_map_coords(u);
|
||||
map_switch(1);
|
||||
map->points = copy_eval_double1(target, ustride, uorder, points);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMap1f(GLenum target, GLfloat u1, GLfloat u2,
|
||||
GLint ustride, GLint uorder, const GLfloat *points) {
|
||||
noerrorShim();
|
||||
map_statef_t *map = malloc(sizeof(map_statef_t));
|
||||
map->type = GL_FLOAT; map->dims = 1;
|
||||
set_map_coords(u);
|
||||
map_switch(1);
|
||||
map->points = copy_eval_float1(target, ustride, uorder, points);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMap2d(GLenum target, GLdouble u1, GLdouble u2,
|
||||
GLint ustride, GLint uorder, GLdouble v1, GLdouble v2,
|
||||
GLint vstride, GLint vorder, const GLdouble *points) {
|
||||
noerrorShim();
|
||||
map_statef_t *map = malloc(sizeof(map_statef_t));
|
||||
map->type = GL_FLOAT; map->dims = 2;
|
||||
set_map_coords(u);
|
||||
set_map_coords(v);
|
||||
map_switch(2);
|
||||
map->points = copy_eval_double2(target, ustride, uorder, vstride, vorder, points);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMap2f(GLenum target, GLfloat u1, GLfloat u2,
|
||||
GLint ustride, GLint uorder, GLfloat v1, GLfloat v2,
|
||||
GLint vstride, GLint vorder, const GLfloat *points) {
|
||||
noerrorShim();
|
||||
map_statef_t *map = malloc(sizeof(map_statef_t));
|
||||
map->type = GL_FLOAT; map->dims = 2;
|
||||
set_map_coords(u);
|
||||
set_map_coords(v);
|
||||
map_switch(2);
|
||||
map->points = copy_eval_float2(target, ustride, uorder, vstride, vorder, points);;
|
||||
}
|
||||
|
||||
#undef set_map_coords
|
||||
#undef case_state
|
||||
#undef map_switch
|
||||
|
||||
#define p_map(d, name, func, code) \
|
||||
if (glstate->map##d.name && glstate->enable.map##d##_##name) { \
|
||||
map_state_t *_map = glstate->map##d.name; \
|
||||
if (_map->type == GL_DOUBLE) { \
|
||||
map_stated_t *map = (map_stated_t *)_map; \
|
||||
LOGE("double: not implemented\n"); \
|
||||
} else if (_map->type == GL_FLOAT) { \
|
||||
map_statef_t *map = (map_statef_t *)_map; \
|
||||
code \
|
||||
gl4es_##func##v(out); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define iter_maps(d, code) \
|
||||
p_map(d, color4, glColor4f, code); \
|
||||
p_map(d, index, glIndexf, code); \
|
||||
if(!glstate->enable.auto_normal) \
|
||||
p_map(d, normal, glNormal3f, code); \
|
||||
p_map(d, texture4, glTexCoord4f, code) \
|
||||
else \
|
||||
p_map(d, texture3, glTexCoord3f, code) \
|
||||
else \
|
||||
p_map(d, texture2, glTexCoord2f, code) \
|
||||
else \
|
||||
p_map(d, texture1, glTexCoord1f, code); \
|
||||
p_map(d, vertex4, glVertex4f, code) \
|
||||
else \
|
||||
p_map(d, vertex3, glVertex3f, code);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEvalCoord1f(GLfloat u) {
|
||||
noerrorShim();
|
||||
GLfloat out[4]; \
|
||||
iter_maps(1,
|
||||
GLfloat uu = (u - map->u._1) * map->u.d;
|
||||
_math_horner_bezier_curve((GLfloat*)map->points, out, uu, map->width, map->u.order);
|
||||
)
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEvalCoord2f(GLfloat u, GLfloat v) {
|
||||
noerrorShim();
|
||||
GLfloat out[4]; \
|
||||
iter_maps(2,
|
||||
GLfloat uu = (u - map->u._1) * map->u.d;
|
||||
GLfloat vv = (v - map->v._1) * map->v.d;
|
||||
if(glstate->enable.auto_normal && (map == (map_statef_t *)glstate->map2.vertex3 || map == (map_statef_t *)glstate->map2.vertex4)) {
|
||||
GLfloat norm[3];
|
||||
GLfloat du[4];
|
||||
GLfloat dv[4];
|
||||
memset(out, 0, 3*sizeof(GLfloat)); out[3] = 1.0f;
|
||||
_math_de_casteljau_surf((GLfloat*)map->points, out, du, dv, uu, vv,
|
||||
map->width, map->u.order, map->v.order);
|
||||
if(map->width == 4) {
|
||||
du[0] = du[0]*out[3] - du[3]*out[0];
|
||||
du[1] = du[1]*out[3] - du[3]*out[1];
|
||||
du[2] = du[2]*out[3] - du[3]*out[2];
|
||||
dv[0] = dv[0]*out[3] - dv[3]*out[0];
|
||||
dv[1] = dv[1]*out[3] - dv[3]*out[1];
|
||||
dv[2] = dv[2]*out[3] - dv[3]*out[2];
|
||||
}
|
||||
cross3(du, dv, norm);
|
||||
vector_normalize(norm);
|
||||
gl4es_glNormal3fv(norm);
|
||||
} else
|
||||
_math_horner_bezier_surf((GLfloat*)map->points, out, uu, vv,
|
||||
map->width, map->u.order, map->v.order);
|
||||
)
|
||||
}
|
||||
|
||||
#undef p_map
|
||||
#undef iter_maps
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMapGrid1f(GLint un, GLfloat u1, GLfloat u2) {
|
||||
if(un<1) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->list.begin) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
noerrorShim();
|
||||
|
||||
glstate->map_grid[0].n = un;
|
||||
glstate->map_grid[0]._1 = u1;
|
||||
glstate->map_grid[0]._2 = u2;
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMapGrid2f(GLint un, GLfloat u1, GLfloat u2,
|
||||
GLint vn, GLfloat v1, GLfloat v2) {
|
||||
|
||||
if((un<1) || (vn<1)) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->list.begin) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
noerrorShim();
|
||||
|
||||
glstate->map_grid[0].n = un;
|
||||
glstate->map_grid[0]._1 = u1;
|
||||
glstate->map_grid[0]._2 = u2;
|
||||
glstate->map_grid[0].d = (glstate->map_grid[0]._2 - glstate->map_grid[0]._1)/glstate->map_grid[0].n;
|
||||
glstate->map_grid[1].n = vn;
|
||||
glstate->map_grid[1]._1 = v1;
|
||||
glstate->map_grid[1]._2 = v2;
|
||||
glstate->map_grid[1].d = (glstate->map_grid[1]._2 - glstate->map_grid[1]._1)/glstate->map_grid[1].n;
|
||||
}
|
||||
|
||||
static inline GLenum eval_mesh_prep(GLenum mode) {
|
||||
if ((!glstate->map2.vertex4) && (!glstate->map2.vertex3)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case GL_POINT: return GL_POINTS;
|
||||
case GL_LINE: return GL_LINE_STRIP;
|
||||
case GL_FILL: return GL_TRIANGLE_STRIP;
|
||||
case 0: return 1;
|
||||
default:
|
||||
LOGE("unknown glEvalMesh mode: %x\n", mode);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEvalMesh1(GLenum mode, GLint i1, GLint i2) {
|
||||
GLenum renderMode = eval_mesh_prep(mode);
|
||||
if (! renderMode) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
|
||||
noerrorShim();
|
||||
GLfloat u, du, u1;
|
||||
du = glstate->map_grid[0].d;
|
||||
u1 = glstate->map_grid[0]._1 + du*i1;
|
||||
GLint i;
|
||||
gl4es_glBegin(renderMode);
|
||||
for (u = u1, i = i1; i <= i2; i++, u += du) {
|
||||
gl4es_glEvalCoord1f(u);
|
||||
}
|
||||
gl4es_glEnd();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) {
|
||||
GLenum renderMode = eval_mesh_prep(mode);
|
||||
if (! renderMode) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
|
||||
noerrorShim();
|
||||
GLfloat u, du, u1, v, dv, v1;
|
||||
du = glstate->map_grid[0].d;
|
||||
dv = glstate->map_grid[1].d;
|
||||
u1 = glstate->map_grid[0]._1 + du*i1;
|
||||
v1 = glstate->map_grid[1]._1 + dv*j1;
|
||||
GLint i, j;
|
||||
if(mode==GL_FILL) {
|
||||
for (v = v1, j = j1; j <= j2-1; j++, v += dv) {
|
||||
gl4es_glBegin(renderMode);
|
||||
for (u = u1, i = i1; i <= i2; i++, u += du) {
|
||||
gl4es_glEvalCoord2f(u, v);
|
||||
gl4es_glEvalCoord2f(u, v + dv);
|
||||
}
|
||||
gl4es_glEnd();
|
||||
}
|
||||
} else {
|
||||
for (v = v1, j = j1; j <= j2; j++, v += dv) {
|
||||
gl4es_glBegin(renderMode);
|
||||
for (u = u1, i = i1; i <= i2; i++, u += du) {
|
||||
gl4es_glEvalCoord2f(u, v);
|
||||
}
|
||||
gl4es_glEnd();
|
||||
}
|
||||
if (mode == GL_LINE) {
|
||||
gl4es_glBegin(renderMode);
|
||||
for (u = u1, i = i1; i <= i2; i++, u += du) {
|
||||
for (v = v1, j = j1; j <= j2; j++, v += dv) {
|
||||
gl4es_glEvalCoord2f(u, v);
|
||||
}
|
||||
}
|
||||
gl4es_glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEvalPoint1(GLint i) {
|
||||
gl4es_glEvalCoord1f(glstate->map_grid[0]._1 + glstate->map_grid[0].d*i);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEvalPoint2(GLint i, GLint j) {
|
||||
gl4es_glEvalCoord2f(glstate->map_grid[0]._1 + glstate->map_grid[0].d*i, glstate->map_grid[1]._1 + glstate->map_grid[1].d*j);
|
||||
}
|
||||
|
||||
#define GL_GET_MAP(t, type) \
|
||||
void APIENTRY_GL4ES gl4es_glGetMap##t##v(GLenum target, GLenum query, type *v) { \
|
||||
noerrorShim(); \
|
||||
map_statef_t *map = *(map_statef_t **)get_map_pointer(target); \
|
||||
if (map) { \
|
||||
switch (query) { \
|
||||
case GL_COEFF: { \
|
||||
const GLfloat *points = map->points; \
|
||||
for (int i = 0; i < map->u.order; i++) { \
|
||||
if (map->dims == 2) { \
|
||||
for (int j = 0; j < map->v.order; j++) { \
|
||||
*v++ = *points++; \
|
||||
} \
|
||||
} else { \
|
||||
*v++ = *points++; \
|
||||
} \
|
||||
} \
|
||||
return; \
|
||||
} \
|
||||
case GL_ORDER: \
|
||||
*v++ = map->u.order; \
|
||||
if (map->dims == 2) \
|
||||
*v++ = map->v.order; \
|
||||
return; \
|
||||
case GL_DOMAIN: \
|
||||
*v++ = map->u._1; \
|
||||
*v++ = map->u._2; \
|
||||
if (map->dims == 2) { \
|
||||
*v++ = map->u._1; \
|
||||
*v++ = map->u._2; \
|
||||
} \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
GL_GET_MAP(i, GLint)
|
||||
GL_GET_MAP(f, GLfloat)
|
||||
GL_GET_MAP(d, GLdouble)
|
||||
|
||||
#undef GL_GET_MAP
|
||||
|
||||
//Direct wrapper
|
||||
AliasExport_M(void,glMap1d,,(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points),32);
|
||||
AliasExport(void,glMap1f,,(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points));
|
||||
AliasExport_M(void,glMap2d,,(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points),56);
|
||||
AliasExport(void,glMap2f,,(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points));
|
||||
AliasExport(void,glEvalCoord1f,,(GLfloat u));
|
||||
AliasExport(void,glEvalCoord2f,,(GLfloat u, GLfloat v));
|
||||
AliasExport(void,glEvalMesh1,,(GLenum mode, GLint i1, GLint i2));
|
||||
AliasExport(void,glEvalMesh2,,(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2));
|
||||
AliasExport(void,glEvalPoint1,,(GLint i));
|
||||
AliasExport(void,glEvalPoint2,,(GLint i, GLint j));
|
||||
AliasExport(void,glMapGrid1f,,(GLint un, GLfloat u1, GLfloat u2));
|
||||
AliasExport(void,glMapGrid2f,,(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2));
|
||||
AliasExport(void,glGetMapdv,,(GLenum target, GLenum query, GLdouble *v));
|
||||
AliasExport(void,glGetMapfv,,(GLenum target, GLenum query, GLfloat *v));
|
||||
AliasExport(void,glGetMapiv,,(GLenum target, GLenum query, GLint *v));
|
||||
@@ -0,0 +1,87 @@
|
||||
#ifndef _GL4ES_EVAL_H_
|
||||
#define _GL4ES_EVAL_H_
|
||||
|
||||
#include "const.h"
|
||||
#include "gles.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
|
||||
void APIENTRY_GL4ES gl4es_glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
|
||||
void APIENTRY_GL4ES gl4es_glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
|
||||
void APIENTRY_GL4ES gl4es_glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEvalCoord1d(GLdouble u);
|
||||
void APIENTRY_GL4ES gl4es_glEvalCoord1f(GLfloat u);
|
||||
void APIENTRY_GL4ES gl4es_glEvalCoord2d(GLdouble u, GLdouble v);
|
||||
void APIENTRY_GL4ES gl4es_glEvalCoord2f(GLfloat u, GLfloat v);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glEvalMesh1(GLenum mode, GLint i1, GLint i2);
|
||||
void APIENTRY_GL4ES gl4es_glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
|
||||
void APIENTRY_GL4ES gl4es_glEvalPoint1(GLint i);
|
||||
void APIENTRY_GL4ES gl4es_glEvalPoint2(GLint i, GLint j);
|
||||
void APIENTRY_GL4ES gl4es_glMapGrid1d(GLint un, GLdouble u1, GLdouble u2);
|
||||
void APIENTRY_GL4ES gl4es_glMapGrid1f(GLint un, GLfloat u1, GLfloat u2);
|
||||
void APIENTRY_GL4ES gl4es_glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
|
||||
void APIENTRY_GL4ES gl4es_glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
|
||||
void APIENTRY_GL4ES gl4es_glGetMapdv(GLenum target, GLenum query, GLdouble *v);
|
||||
void APIENTRY_GL4ES gl4es_glGetMapfv(GLenum target, GLenum query, GLfloat *v);
|
||||
void APIENTRY_GL4ES gl4es_glGetMapiv(GLenum target, GLenum query, GLint *v);
|
||||
|
||||
typedef struct {
|
||||
GLenum type;
|
||||
} map_state_t;
|
||||
|
||||
typedef struct {
|
||||
GLdouble _1, _2, d;
|
||||
GLint order;
|
||||
} mapcoordd_t;
|
||||
|
||||
typedef struct {
|
||||
GLfloat _1, _2, d;
|
||||
GLint order;
|
||||
} mapcoordf_t;
|
||||
|
||||
typedef struct {
|
||||
GLenum type;
|
||||
GLint dims, width;
|
||||
mapcoordd_t u, v;
|
||||
const GLdouble *points;
|
||||
} map_stated_t;
|
||||
|
||||
typedef struct {
|
||||
GLenum type;
|
||||
GLint dims, width;
|
||||
mapcoordf_t u, v;
|
||||
const GLfloat *points;
|
||||
} map_statef_t;
|
||||
|
||||
typedef struct {
|
||||
GLfloat _1, _2;
|
||||
GLfloat d;
|
||||
GLint n;
|
||||
} map_grid_t;
|
||||
|
||||
static const GLsizei get_map_width(GLenum target) {
|
||||
switch (target) {
|
||||
case GL_MAP1_COLOR_4: return 4;
|
||||
case GL_MAP1_INDEX: return 3;
|
||||
case GL_MAP1_NORMAL: return 3;
|
||||
case GL_MAP1_TEXTURE_COORD_1: return 1;
|
||||
case GL_MAP1_TEXTURE_COORD_2: return 2;
|
||||
case GL_MAP1_TEXTURE_COORD_3: return 3;
|
||||
case GL_MAP1_TEXTURE_COORD_4: return 4;
|
||||
case GL_MAP1_VERTEX_3: return 3;
|
||||
case GL_MAP1_VERTEX_4: return 4;
|
||||
case GL_MAP2_COLOR_4: return 4;
|
||||
case GL_MAP2_INDEX: return 3;
|
||||
case GL_MAP2_NORMAL: return 3;
|
||||
case GL_MAP2_TEXTURE_COORD_1: return 1;
|
||||
case GL_MAP2_TEXTURE_COORD_2: return 2;
|
||||
case GL_MAP2_TEXTURE_COORD_3: return 3;
|
||||
case GL_MAP2_TEXTURE_COORD_4: return 4;
|
||||
case GL_MAP2_VERTEX_3: return 3;
|
||||
case GL_MAP2_VERTEX_4: return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // _GL4ES_EVAL_H_
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "face.h"
|
||||
|
||||
#include "loader.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glCullFace(GLenum mode) {
|
||||
if(!glstate->list.pending)
|
||||
PUSH_IF_COMPILING(glCullFace);
|
||||
if(mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(glstate->face.cull == mode) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
glstate->face.cull = mode;
|
||||
LOAD_GLES(glCullFace);
|
||||
gles_glCullFace(mode);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glFrontFace(GLenum mode) {
|
||||
if(!glstate->list.pending)
|
||||
PUSH_IF_COMPILING(glFrontFace);
|
||||
if(mode!=GL_CW && mode!=GL_CCW) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(glstate->face.front == mode) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
glstate->face.front = mode;
|
||||
LOAD_GLES(glFrontFace);
|
||||
gles_glFrontFace(mode);
|
||||
}
|
||||
|
||||
|
||||
AliasExport(void,glCullFace,,(GLenum mode));
|
||||
AliasExport(void,glFrontFace,,(GLenum mode));
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef _GL4ES_FACE_H_
|
||||
#define _GL4ES_FACE_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glCullFace(GLenum mode);
|
||||
void APIENTRY_GL4ES gl4es_glFrontFace(GLenum mode);
|
||||
|
||||
#endif // _GL4ES_FACE_H_
|
||||
@@ -0,0 +1,118 @@
|
||||
#include "fog.h"
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "fpe.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "loader.h"
|
||||
#include "matrix.h"
|
||||
#include "matvec.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glFogfv(GLenum pname, const GLfloat* params) {
|
||||
|
||||
if (glstate->list.active)
|
||||
if (glstate->list.compiling) {
|
||||
NewStage(glstate->list.active, STAGE_FOG);
|
||||
rlFogOp(glstate->list.active, pname, params);
|
||||
return;
|
||||
}
|
||||
else gl4es_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);
|
||||
#define GOI(name) if(glstate->fog.name==params[0]) return; else glstate->fog.name=params[0];
|
||||
switch (pname) {
|
||||
case GL_FOG_MODE:
|
||||
GOI(mode)
|
||||
break;
|
||||
case GL_FOG_DENSITY:
|
||||
if(*params<0.f) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
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 for now
|
||||
case GL_FOG_COLOR:
|
||||
#if defined(__GNUC__) && (__GNUC__ > 7)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
#endif
|
||||
// GCC 8.1 warn about reading 16 bytes from a 4 bytes value, but params is not (in that case) a 4 bytes value
|
||||
GO(, color, 4*sizeof(GLfloat))
|
||||
#if defined(__GNUC__) && (__GNUC__ > 7)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
break;
|
||||
case GL_FOG_COORD_SRC:
|
||||
GOI(coord_src)
|
||||
if(hardext.esversion==1)
|
||||
return; // unsupported on GLES1.1
|
||||
break;
|
||||
case GL_FOG_DISTANCE_MODE_NV:
|
||||
GOI(distance)
|
||||
if(hardext.esversion==1)
|
||||
return; // unsupported on GLES1.1
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
#undef GO
|
||||
#undef GOI
|
||||
LOAD_GLES_FPE(glFogfv);
|
||||
gles_glFogfv(pname, params);
|
||||
errorGL();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glFogf(GLenum pname, GLfloat param) {
|
||||
gl4es_glFogfv(pname, ¶m);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glFogCoordd(GLdouble coord) {
|
||||
gl4es_glFogCoordf(coord);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glFogCoorddv(const GLdouble *coord) {
|
||||
gl4es_glFogCoordf(*coord);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glFogCoordfv(const GLfloat *coord) {
|
||||
gl4es_glFogCoordf(*coord);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glFogCoordf(GLfloat coord) {
|
||||
if (glstate->list.active) {
|
||||
if(glstate->list.pending)
|
||||
gl4es_flush();
|
||||
else
|
||||
{
|
||||
rlFogCoordf(glstate->list.active, coord);
|
||||
glstate->list.active->lastFogCoord = coord;
|
||||
}
|
||||
noerrorShim();
|
||||
} else {
|
||||
noerrorShim();
|
||||
}
|
||||
// change the state last thing
|
||||
glstate->fogcoord[0] = coord;
|
||||
}
|
||||
|
||||
|
||||
AliasExport(void,glFogfv,,(GLenum pname, const GLfloat* params));
|
||||
AliasExport(void,glFogf,,(GLenum pname, GLfloat param));
|
||||
AliasExport_D(void,glFogCoordd,,(GLdouble coord));
|
||||
AliasExport(void,glFogCoorddv,,(const GLdouble *coord));
|
||||
AliasExport(void,glFogCoordf,,(GLfloat coord));
|
||||
AliasExport(void,glFogCoordfv,,(const GLfloat *coord));
|
||||
|
||||
AliasExport(void,glFogfv,EXT,(GLenum pname, const GLfloat* params));
|
||||
AliasExport(void,glFogf,EXT,(GLenum pname, GLfloat param));
|
||||
AliasExport_D(void,glFogCoordd,EXT,(GLdouble coord));
|
||||
AliasExport(void,glFogCoorddv,EXT,(const GLdouble *coord));
|
||||
AliasExport(void,glFogCoordf,EXT,(GLfloat coord));
|
||||
AliasExport(void,glFogCoordfv,EXT,(const GLfloat *coord));
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _GL4ES_FOG_H_
|
||||
#define _GL4ES_FOG_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
typedef struct {
|
||||
GLenum mode;
|
||||
GLfloat density;
|
||||
GLenum distance;
|
||||
GLfloat start;
|
||||
GLfloat end;
|
||||
GLfloat index;
|
||||
GLfloat color[4];
|
||||
GLenum coord_src;
|
||||
} fog_t;
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glFogfv(GLenum pname, const GLfloat* params);
|
||||
void APIENTRY_GL4ES gl4es_glFogf(GLenum pname, GLfloat param);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glFogCoordf(GLfloat coord);
|
||||
void APIENTRY_GL4ES gl4es_glFogCoordfv(const GLfloat *coord);
|
||||
|
||||
#endif // _GL4ES_FOG_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,284 @@
|
||||
#ifndef _GL4ES_FPE_H_
|
||||
#define _GL4ES_FPE_H_
|
||||
|
||||
/*
|
||||
This is the FPE : Fixed Pipeline Emulator
|
||||
|
||||
It task is to create a shader that emulate the fixed pipeline.
|
||||
|
||||
So based on the current GL State, it will either take a shader from the cache or create a new one
|
||||
For conveniance, the relevant GL states element are condenced in a bitfield packed fpe_state_t structure
|
||||
|
||||
*/
|
||||
|
||||
#include "gles.h"
|
||||
#include "program.h"
|
||||
|
||||
#define FPE_FOG_EXP 0
|
||||
#define FPE_FOG_EXP2 1
|
||||
#define FPE_FOG_LINEAR 2
|
||||
|
||||
#define FPE_FOG_SRC_DEPTH 0
|
||||
#define FPE_FOG_SRC_COORD 1
|
||||
|
||||
#define FPE_FOG_DIST_PLANE_ABS 0
|
||||
#define FPE_FOG_DIST_PLANE 1
|
||||
#define FPE_FOG_DIST_RADIAL 2
|
||||
|
||||
#define FPE_TEX_OFF 0
|
||||
#define FPE_TEX_2D 1
|
||||
#define FPE_TEX_RECT 2
|
||||
#define FPE_TEX_3D 3
|
||||
#define FPE_TEX_CUBE 4
|
||||
#define FPE_TEX_STRM 5
|
||||
|
||||
#define FPE_ALWAYS 0
|
||||
#define FPE_NEVER 1
|
||||
#define FPE_LESS 2
|
||||
#define FPE_EQUAL 3
|
||||
#define FPE_LEQUAL 4
|
||||
#define FPE_GREATER 5
|
||||
#define FPE_NOTEQUAL 6
|
||||
#define FPE_GEQUAL 7
|
||||
|
||||
#define FPE_CM_AMBIENTDIFFUSE 0
|
||||
#define FPE_CM_EMISSION 1
|
||||
#define FPE_CM_AMBIENT 2
|
||||
#define FPE_CM_DIFFUSE 3
|
||||
#define FPE_CM_SPECULAR 4
|
||||
|
||||
#define FPE_MODULATE 0
|
||||
#define FPE_ADD 1
|
||||
#define FPE_DECAL 2
|
||||
#define FPE_BLEND 3
|
||||
#define FPE_REPLACE 4
|
||||
#define FPE_COMBINE 5
|
||||
#define FPE_COMBINE4 6
|
||||
|
||||
#define FPE_CR_REPLACE 0
|
||||
#define FPE_CR_MODULATE 1
|
||||
#define FPE_CR_ADD 2
|
||||
#define FPE_CR_ADD_SIGNED 3
|
||||
#define FPE_CR_INTERPOLATE 4
|
||||
#define FPE_CR_SUBTRACT 5
|
||||
#define FPE_CR_DOT3_RGB 6
|
||||
#define FPE_CR_DOT3_RGBA 7
|
||||
#define FPE_CR_MOD_ADD 8
|
||||
#define FPE_CR_MOD_ADD_SIGNED 9
|
||||
#define FPE_CR_MOD_SUB 10
|
||||
|
||||
#define FPE_SRC_TEXTURE 0
|
||||
#define FPE_SRC_TEXTURE0 1
|
||||
#define FPE_SRC_TEXTURE1 2
|
||||
#define FPE_SRC_TEXTURE2 3
|
||||
#define FPE_SRC_TEXTURE3 4
|
||||
#define FPE_SRC_TEXTURE4 5
|
||||
#define FPE_SRC_TEXTURE5 6
|
||||
#define FPE_SRC_TEXTURE6 7
|
||||
#define FPE_SRC_TEXTURE7 8
|
||||
#define FPE_SRC_TEXTURE8 9
|
||||
#define FPE_SRC_TEXTURE9 10
|
||||
#define FPE_SRC_TEXTURE10 11
|
||||
#define FPE_SRC_TEXTURE11 12
|
||||
#define FPE_SRC_TEXTURE12 13
|
||||
#define FPE_SRC_TEXTURE13 14
|
||||
#define FPE_SRC_TEXTURE14 15
|
||||
#define FPE_SRC_TEXTURE15 16
|
||||
#define FPE_SRC_CONSTANT 17
|
||||
#define FPE_SRC_PRIMARY_COLOR 18
|
||||
#define FPE_SRC_PREVIOUS 19
|
||||
#define FPE_SRC_ZERO 20
|
||||
#define FPE_SRC_ONE 21
|
||||
#define FPE_SRC_SECONDARY_COLOR 22
|
||||
|
||||
#define FPE_OP_ALPHA 0
|
||||
#define FPE_OP_MINUSALPHA 1
|
||||
#define FPE_OP_SRCCOLOR 2
|
||||
#define FPE_OP_MINUSCOLOR 3
|
||||
|
||||
#define FPE_TEX_RGBA 0
|
||||
#define FPE_TEX_RGB 1
|
||||
#define FPE_TEX_INTENSITY 2
|
||||
#define FPE_TEX_LUM_ALPHA 3
|
||||
#define FPE_TEX_LUM 4
|
||||
#define FPE_TEX_ALPHA 5
|
||||
#define FPE_TEX_DEPTH 6
|
||||
|
||||
#define FPE_TG_EYELINEAR 0
|
||||
#define FPE_TG_OBJLINEAR 1
|
||||
#define FPE_TG_SPHEREMAP 2
|
||||
#define FPE_TG_NORMALMAP 3
|
||||
#define FPE_TG_REFLECMAP 4
|
||||
#define FPE_TG_NONE 5 // dummy, to help fpe
|
||||
|
||||
#define FPE_BLEND_ZERO 0
|
||||
#define FPE_BLEND_ONE 1
|
||||
#define FPE_BLEND_SRC_COLOR 2
|
||||
#define FPE_BLEND_ONE_MINUS_SRC_COLOR 3
|
||||
#define FPE_BLEND_DST_COLOR 4
|
||||
#define FPE_BLEND_ONE_MINUS_DST_COLOR 5
|
||||
#define FPE_BLEND_SRC_ALPHA 6
|
||||
#define FPE_BLEND_ONE_MINUS_SRC_ALPHA 7
|
||||
#define FPE_BLEND_DST_ALPHA 8
|
||||
#define FPE_BLEND_ONE_MINUS_DST_ALPHA 9
|
||||
#define FPE_BLEND_CONSTANT_COLOR 10
|
||||
#define FPE_BLEND_ONE_MINUS_CONSTANT_COLOR 11
|
||||
#define FPE_BLEND_CONSTANT_ALPHA 12
|
||||
#define FPE_BLEND_ONE_MINUS_CONSTANT_ALPHA 13
|
||||
#define FPE_BLEND_SRC_ALPHA_SATURATE 14
|
||||
|
||||
#define FPE_BLENDEQ_FUNC_ADD 0
|
||||
#define FPE_BLENDEQ_FUNC_SUBTRACT 1
|
||||
#define FPE_BLENDEQ_FUNC_REVERSE_SUBTRACT 2
|
||||
#define FPE_BLENDEQ_MIN 3
|
||||
#define FPE_BLENDEQ_MAX 4
|
||||
|
||||
typedef struct fpe_texgen_s {
|
||||
unsigned int texgen_s:1; // texgen S enabled on 1 bit
|
||||
unsigned int texgen_s_mode:3; // texgen S on 3 bits
|
||||
unsigned int texgen_t:1; // texgen T enabled on 1 bit
|
||||
unsigned int texgen_t_mode:3; // texgen T on 3 bits
|
||||
unsigned int texgen_r:1; // texgen R enabled on 1 bit
|
||||
unsigned int texgen_r_mode:3; // texgen R on 3 bits
|
||||
unsigned int texgen_q:1; // texgen Q enabled on 1 bit
|
||||
unsigned int texgen_q_mode:3; // texgen Q on 3 bits
|
||||
} fpe_texgen_t;
|
||||
|
||||
typedef struct fpe_texture_s {
|
||||
unsigned int texmat:1; // flags if texture matrix is not identity
|
||||
unsigned int textype:3; // textures type stored on 3 bits
|
||||
unsigned int texadjust:1; // flags if texture need adjustement
|
||||
unsigned int texformat:3; // textures (simplified) internal format on 3 bits
|
||||
} fpe_texture_t;
|
||||
|
||||
typedef struct fpe_texenv_s {
|
||||
unsigned int texenv:4; // texenv flag
|
||||
unsigned int texoprgb0:2; // texenv src op (OPERATION_n_RGB is 2 bits)
|
||||
unsigned int texoprgb1:2; // texenv src op (OPERATION_n_RGB is 2 bits)
|
||||
unsigned int texoprgb2:2; // texenv src op (OPERATION_n_RGB is 2 bits)
|
||||
unsigned int texoprgb3:2; // texenv src op (OPERATION_n_RGB is 2 bits)
|
||||
unsigned int texopalpha0:1; // texenv src op (OPERATION_n_ALPHA is 1 bits)
|
||||
unsigned int texopalpha1:1; // texenv src op (OPERATION_n_ALPHA is 1 bits)
|
||||
unsigned int texopalpha2:1; // texenv src op (OPERATION_n_ALPHA is 1 bits)
|
||||
unsigned int texopalpha3:1; // texenv src op (OPERATION_n_ALPHA is 1 bits)
|
||||
unsigned int texsrcrgb0:5; // texenv src rgb n
|
||||
unsigned int texsrcrgb1:5; // texenv src rgb n
|
||||
unsigned int texsrcrgb2:5; // texenv src rgb n
|
||||
unsigned int texsrcrgb3:5; // texenv src rgb n
|
||||
unsigned int texsrcalpha0:5; // texenv src alpha n
|
||||
unsigned int texsrcalpha1:5; // texenv src alpha n
|
||||
unsigned int texsrcalpha2:5; // texenv src alpha n
|
||||
unsigned int texsrcalpha3:5; // texenv src alpha n
|
||||
unsigned int texrgbscale:1; // flag if RGB_SCALE for texture is != 1.0
|
||||
unsigned int texalphascale:1; // flag if ALPHA_SCALE for texture is != 1.0
|
||||
unsigned int dummy:6; // align sturture to 64bits...
|
||||
} fpe_texenv_t;
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct fpe_state_s {
|
||||
fpe_texture_t texture[MAX_TEX]; // 16 texture flags
|
||||
fpe_texgen_t texgen[MAX_TEX]; // 16 texgen flags
|
||||
fpe_texenv_t texenv[MAX_TEX]; // 16 texture env flags
|
||||
uint8_t texcombine[MAX_TEX]; // 16 texture combined (RGB as lower 4 bits, A as higher 4 bits)
|
||||
uint8_t light; // 8 lights packed
|
||||
uint8_t light_cutoff180; // 8 lights cutoff!=180 flags
|
||||
uint8_t light_direction; // 8 lights position[3].w==0 flags
|
||||
unsigned int plane:6; // 6 planes packed
|
||||
unsigned int fogmode:2; // fog mode
|
||||
unsigned int fogdist:2; // fog distance mode
|
||||
unsigned int fogsource:1; // fog source
|
||||
unsigned int fog:1; // Fog enabled or not
|
||||
unsigned int colorsum:1; // secondary color enabled
|
||||
unsigned int lighting:1; // global lighting enabled
|
||||
unsigned int normalize:1; // normalization
|
||||
unsigned int rescaling:1; // rescale normal
|
||||
unsigned int alphafunc:3; // alpha functions
|
||||
unsigned int alphatest:1; // alpha test
|
||||
unsigned int twosided:1; // lightmodel: two sided
|
||||
unsigned int color_material:1; // color material enabled
|
||||
unsigned int cm_front_mode:3; // front color material mode
|
||||
unsigned int cm_back_mode:3; // back color material mode
|
||||
unsigned int cm_front_nullexp:1; // front material shininess is 0
|
||||
unsigned int cm_back_nullexp:1; // back material shininess is 0
|
||||
unsigned int light_separate:1; // light separate specular color
|
||||
unsigned int light_localviewer:1; // light local viewer
|
||||
unsigned int point:1; // point rendering
|
||||
unsigned int pointsprite:1; // point sprite rendering
|
||||
unsigned int pointsprite_coord:1; // point sprite coord replace
|
||||
unsigned int pointsprite_upper:1; // if coord is upper left and not lower left
|
||||
unsigned int vertex_prg_enable:1; // if vertex program is enabled
|
||||
unsigned int fragment_prg_enable:1; // if fragment program is enabled
|
||||
unsigned int blend_enable:1;
|
||||
unsigned int blendsrcrgb:4;
|
||||
unsigned int blendsrcalpha:4;
|
||||
unsigned int blenddstrgb:4;
|
||||
unsigned int blenddstalpha:4;
|
||||
unsigned int blendeqrgb:3;
|
||||
unsigned int blendeqalpha:3;
|
||||
uint16_t vertex_prg_id; // Id of vertex program currently binded (0 most of the time), 16bits is more than enough...
|
||||
uint16_t fragment_prg_id; // Id of fragment program currently binded (0 most of the time)
|
||||
} fpe_state_t;
|
||||
#pragma pack()
|
||||
|
||||
typedef struct fpe_fpe_s {
|
||||
GLuint frag, vert, prog; // shader info
|
||||
fpe_state_t state; // state relevant to the current fpe program
|
||||
program_t *glprogram;
|
||||
} fpe_fpe_t;
|
||||
|
||||
typedef struct kh_fpecachelist_s kh_fpecachelist_t;
|
||||
#define fpe_cache_t kh_fpecachelist_t
|
||||
|
||||
typedef struct scratch_s {
|
||||
void* scratch[16];
|
||||
int size;
|
||||
} scratch_t;
|
||||
void free_scratch(scratch_t* scratch);
|
||||
|
||||
|
||||
fpe_fpe_t *fpe_GetCache(fpe_cache_t *cur, fpe_state_t *state, int fixed);
|
||||
void fpe_disposeCache(fpe_cache_t* cache, int freeprog);
|
||||
|
||||
// fpe is gles export replacement, so should use same caling conversion
|
||||
void APIENTRY_GLES fpe_glEnableClientState(GLenum cap);
|
||||
void APIENTRY_GLES fpe_glDisableClientState(GLenum cap);
|
||||
void APIENTRY_GLES fpe_glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
|
||||
void APIENTRY_GLES fpe_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GLES fpe_glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GLES fpe_glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GLES fpe_glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GLES fpe_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GLES fpe_glTexCoordPointerTMU(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer, int TMU);
|
||||
void APIENTRY_GLES fpe_glFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GLES fpe_glEnable(GLenum cap);
|
||||
void APIENTRY_GLES fpe_glDisable(GLenum cap);
|
||||
void APIENTRY_GLES fpe_glDrawArrays(GLenum mode, GLint first, GLsizei count);
|
||||
void APIENTRY_GLES fpe_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
void APIENTRY_GLES fpe_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
void APIENTRY_GLES fpe_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
|
||||
void APIENTRY_GLES fpe_glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
|
||||
void APIENTRY_GLES fpe_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
void APIENTRY_GLES fpe_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz);
|
||||
void APIENTRY_GLES fpe_glClientActiveTexture(GLenum texture);
|
||||
void APIENTRY_GLES fpe_glFogfv(GLenum pname, const GLfloat* params);
|
||||
void APIENTRY_GLES fpe_glAlphaFunc(GLenum func, GLclampf ref);
|
||||
|
||||
void APIENTRY_GLES fpe_glMatrixMode(GLenum mode);
|
||||
|
||||
void APIENTRY_GLES fpe_glLightModelf(GLenum pname, GLfloat param);
|
||||
void APIENTRY_GLES fpe_glLightModelfv(GLenum pname, const GLfloat* params);
|
||||
void APIENTRY_GLES fpe_glLightfv(GLenum light, GLenum pname, const GLfloat* params);
|
||||
void APIENTRY_GLES fpe_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params);
|
||||
void APIENTRY_GLES fpe_glMaterialf(GLenum face, GLenum pname, const GLfloat param);
|
||||
|
||||
void APIENTRY_GLES fpe_glPointParameterfv(GLenum pname, const GLfloat * params);
|
||||
void APIENTRY_GLES fpe_glPointSize(GLfloat size);
|
||||
|
||||
void builtin_Init(program_t *glprogram);
|
||||
int builtin_CheckUniform(program_t *glprogram, char* name, GLint id, int size);
|
||||
int builtin_CheckVertexAttrib(program_t *glprogram, char* name, GLint id);
|
||||
|
||||
void realize_glenv(int ispoint, int first, int count, GLenum type, const void* indices, scratch_t* scratch);
|
||||
void realize_blitenv(int alpha);
|
||||
|
||||
#endif // _GL4ES_FPE_H_
|
||||
@@ -0,0 +1,288 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "init.h"
|
||||
#include "logs.h"
|
||||
#include "debug.h"
|
||||
#include "program.h"
|
||||
#include "fpe_cache.h"
|
||||
#include "fpe.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#pragma GCC optimize 0
|
||||
#define DBG(a) a
|
||||
#else
|
||||
#define DBG(a)
|
||||
#endif
|
||||
|
||||
static const char PSA_SIGN[] = "GL4ES PrecompiledShaderArchive";
|
||||
#define CACHE_VERSION 112
|
||||
|
||||
static kh_inline khint_t _hash_fpe(fpe_state_t *p)
|
||||
{
|
||||
const char* s = (const char*)p;
|
||||
khint_t h = (khint_t)*s;
|
||||
for (int i=1 ; i<sizeof(fpe_state_t); ++i) h = (h << 5) - h + (khint_t)*(++s);
|
||||
return h;
|
||||
}
|
||||
|
||||
#define kh_fpe_hash_func(key) _hash_fpe(key)
|
||||
|
||||
#define kh_fpe_hash_equal(a, b) (memcmp(a, b, sizeof(fpe_state_t)) == 0)
|
||||
|
||||
#define KHASH_MAP_INIT_FPE(name, khval_t) \
|
||||
KHASH_INIT(name, kh_fpe_t, khval_t, 1, kh_fpe_hash_func, kh_fpe_hash_equal)
|
||||
|
||||
KHASH_MAP_INIT_FPE(fpecachelist, fpe_fpe_t *);
|
||||
|
||||
// ********* Cache handling *********
|
||||
|
||||
fpe_cache_t* fpe_NewCache() {
|
||||
khash_t(fpecachelist) *cache = kh_init(fpecachelist);
|
||||
return cache;
|
||||
}
|
||||
|
||||
void fpe_disposeCache(fpe_cache_t* cache, int freeprog) {
|
||||
if(!cache) return;
|
||||
fpe_fpe_t *m;
|
||||
kh_foreach_value(cache, m,
|
||||
if(freeprog) {
|
||||
if(m->glprogram)
|
||||
gl4es_glDeleteProgram(m->glprogram->id);
|
||||
}
|
||||
free(m);
|
||||
)
|
||||
kh_destroy(fpecachelist, cache);
|
||||
}
|
||||
|
||||
fpe_fpe_t *fpe_GetCache(fpe_cache_t *cur, fpe_state_t *state, int fixed) {
|
||||
khint_t k;
|
||||
int r;
|
||||
|
||||
k = kh_get(fpecachelist, cur, state);
|
||||
if(k != kh_end(cur)) {
|
||||
return kh_value(cur, k);
|
||||
} else {
|
||||
fpe_fpe_t *n = (fpe_fpe_t*)calloc(1, sizeof(fpe_fpe_t));
|
||||
memcpy(&n->state, state, sizeof(fpe_state_t));
|
||||
k = kh_put(fpecachelist, cur, &n->state, &r);
|
||||
kh_value(cur, k) = n;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct psa_s {
|
||||
fpe_state_t state;
|
||||
GLenum format;
|
||||
int size;
|
||||
void* prog;
|
||||
} psa_t;
|
||||
|
||||
KHASH_MAP_INIT_FPE(psalist, psa_t *);
|
||||
|
||||
// Precompiled Shader Archive
|
||||
typedef struct gl4es_psa_s {
|
||||
int size;
|
||||
int dirty;
|
||||
kh_psalist_t* cache;
|
||||
} gl4es_psa_t;
|
||||
|
||||
static gl4es_psa_t *psa = NULL;
|
||||
static char *psa_name = NULL;
|
||||
|
||||
void fpe_readPSA()
|
||||
{
|
||||
if(!psa || !psa_name)
|
||||
return;
|
||||
FILE *f = fopen(psa_name, "rb");
|
||||
if(!f)
|
||||
return;
|
||||
char tmp[sizeof(PSA_SIGN)];
|
||||
if(fread(tmp, sizeof(PSA_SIGN), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return; //to short
|
||||
}
|
||||
if(strcmp(tmp, PSA_SIGN)!=0) {
|
||||
fclose(f);
|
||||
return; // bad signature
|
||||
}
|
||||
int version = 0;
|
||||
if(fread(&version, sizeof(version), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
if(version!=CACHE_VERSION) {
|
||||
fclose(f);
|
||||
return; // unsupported version
|
||||
}
|
||||
int sz_fpe = 0;
|
||||
if(fread(&sz_fpe, sizeof(sz_fpe), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
if(sz_fpe!=sizeof(fpe_state_t)) {
|
||||
fclose(f);
|
||||
return; // maybe try to adapt instead?
|
||||
}
|
||||
int n = 0;
|
||||
if(fread(&n, sizeof(n), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
for (int i=0; i<n; ++i) {
|
||||
psa_t *p = (psa_t*)calloc(1, sizeof(psa_t));
|
||||
if(fread(&p->state, sizeof(p->state), 1, f)!=1) {
|
||||
free(p);
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
if(fread(&p->format, sizeof(p->format), 1, f)!=1) {
|
||||
free(p);
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
if(fread(&p->size, sizeof(p->size), 1, f)!=1) {
|
||||
free(p);
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
p->prog = malloc(p->size);
|
||||
if(fread(p->prog, p->size, 1, f)!=1) {
|
||||
free(p->prog);
|
||||
free(p);
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
int ret;
|
||||
khint_t k = kh_put(psalist, psa->cache, &p->state, &ret);
|
||||
kh_value(psa->cache, k) = p;
|
||||
psa->size = kh_size(psa->cache);
|
||||
}
|
||||
fclose(f);
|
||||
SHUT_LOGD("Loaded a PSA with %d Precompiled Programs\n", psa->size);
|
||||
}
|
||||
|
||||
void fpe_writePSA()
|
||||
{
|
||||
if(!psa || !psa_name)
|
||||
return;
|
||||
if(!psa->dirty)
|
||||
return; // no need
|
||||
FILE *f = fopen(psa_name, "wb");
|
||||
if(!f)
|
||||
return;
|
||||
if(fwrite(PSA_SIGN, sizeof(PSA_SIGN), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return; //to short
|
||||
}
|
||||
int version = CACHE_VERSION;
|
||||
if(fwrite(&version, sizeof(version), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
int sz_fpe = sizeof(fpe_state_t);
|
||||
if(fwrite(&sz_fpe, sizeof(sz_fpe), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
if(fwrite(&psa->size, sizeof(psa->size), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
psa_t *p;
|
||||
kh_foreach_value(psa->cache, p,
|
||||
if(fwrite(&p->state, sizeof(p->state), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
if(fwrite(&p->format, sizeof(p->format), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
if(fwrite(&p->size, sizeof(p->size), 1, f)!=1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
if(fwrite(p->prog, p->size, 1, f)!=1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
);
|
||||
fclose(f);
|
||||
SHUT_LOGD("Saved a PSA with %d Precompiled Programs\n", psa->size);
|
||||
}
|
||||
|
||||
void fpe_InitPSA(const char* name)
|
||||
{
|
||||
if(psa)
|
||||
return; // already inited
|
||||
psa = (gl4es_psa_t*)calloc(1, sizeof(gl4es_psa_t));
|
||||
psa->cache = kh_init(psalist);
|
||||
psa_name = strdup(name);
|
||||
}
|
||||
|
||||
void fpe_FreePSA()
|
||||
{
|
||||
if(!psa)
|
||||
return; // nothing to init
|
||||
|
||||
psa_t *m;
|
||||
kh_foreach_value(psa->cache, m,
|
||||
free(m->prog);
|
||||
free(m);
|
||||
)
|
||||
kh_destroy(psalist, psa->cache);
|
||||
|
||||
free(psa);
|
||||
psa = NULL;
|
||||
free(psa_name);
|
||||
psa_name = NULL;
|
||||
}
|
||||
|
||||
int fpe_GetProgramPSA(GLuint program, fpe_state_t* state)
|
||||
{
|
||||
if(!psa)
|
||||
return 0;
|
||||
// if state contains custom vertex of fragment shader, then ignore
|
||||
if(state->vertex_prg_enable || state->fragment_prg_enable)
|
||||
return 0;
|
||||
khint_t k = kh_get(psalist, psa->cache, state);
|
||||
if(k==kh_end(psa->cache))
|
||||
return 0; // not here
|
||||
psa_t *p = kh_value(psa->cache, k);
|
||||
// try to load...
|
||||
return gl4es_useProgramBinary(program, p->size, p->format, p->prog);
|
||||
}
|
||||
|
||||
void fpe_AddProgramPSA(GLuint program, fpe_state_t* state)
|
||||
{
|
||||
if(!psa)
|
||||
return;
|
||||
// if state contains custom vertex of fragment shader, then ignore
|
||||
if(state->vertex_prg_enable || state->fragment_prg_enable)
|
||||
return;
|
||||
psa->dirty = 1;
|
||||
psa_t *p = (psa_t*)calloc(1, sizeof(psa_t));
|
||||
memcpy(&p->state, state, sizeof(p->state));
|
||||
|
||||
int l = gl4es_getProgramBinary(program, &p->size, &p->format, &p->prog);
|
||||
if(l==0) { // there was an error...
|
||||
free(p->prog);
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
// add program
|
||||
int ret;
|
||||
khint_t k = kh_put(psalist, psa->cache, &p->state, &ret);
|
||||
if(!ret) {
|
||||
psa_t *p2 = kh_value(psa->cache, k);
|
||||
free(p2->prog);
|
||||
p2->prog = NULL;
|
||||
free(p2);
|
||||
}
|
||||
kh_value(psa->cache, k) = p;
|
||||
// all done
|
||||
psa->size = kh_size(psa->cache);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef __FPE_CACHE_H__
|
||||
#define __FPE_CACHE_H__
|
||||
|
||||
typedef struct fpe_state_s fpe_state_t;
|
||||
typedef fpe_state_t *kh_fpe_t;
|
||||
typedef struct fpe_fpe_s fpe_fpe_t;
|
||||
typedef struct kh_fpecachelist_s kh_fpecachelist_t;
|
||||
#ifndef fpe_cache_t
|
||||
#define fpe_cache_t kh_fpecachelist_t
|
||||
#endif
|
||||
|
||||
fpe_cache_t* fpe_NewCache();
|
||||
void fpe_disposeCache(fpe_cache_t* cache, int freeprog);
|
||||
fpe_fpe_t *fpe_GetCache(fpe_cache_t *cur, fpe_state_t *state, int fixed);
|
||||
|
||||
void fpe_InitPSA(const char* name);
|
||||
void fpe_FreePSA();
|
||||
void fpe_readPSA();
|
||||
void fpe_writePSA();
|
||||
int fpe_GetProgramPSA(GLuint program, fpe_state_t* state);
|
||||
void fpe_AddProgramPSA(GLuint program, fpe_state_t* state);
|
||||
|
||||
#endif //__FPE_CACHE_H__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
#ifndef _GL4ES_FPE_SHADER_H_
|
||||
#define _GL4ES_FPE_SHADER_H_
|
||||
|
||||
#include "fpe.h"
|
||||
|
||||
extern const char* fpeshader_signature;
|
||||
|
||||
const char* const* fpe_VertexShader(shaderconv_need_t* need, fpe_state_t *state);
|
||||
const char* const* fpe_FragmentShader(shaderconv_need_t* need, fpe_state_t *state);
|
||||
|
||||
const char* const* fpe_CustomVertexShader(const char* initial, fpe_state_t* state, int default_fragment);
|
||||
const char* const* fpe_CustomFragmentShader(const char* initial, fpe_state_t* state);
|
||||
|
||||
#endif // _GL4ES_FPE_SHADER_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,60 @@
|
||||
#ifndef _GL4ES_FRAMEBUFFERS_H_
|
||||
#define _GL4ES_FRAMEBUFFERS_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGenerateMipmap(GLenum target);
|
||||
void APIENTRY_GL4ES gl4es_glGenFramebuffers(GLsizei n, GLuint *ids);
|
||||
void APIENTRY_GL4ES gl4es_glDeleteFramebuffers(GLsizei n, GLuint *framebuffers);
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsFramebuffer(GLuint framebuffer);
|
||||
GLenum APIENTRY_GL4ES gl4es_glCheckFramebufferStatus(GLenum target);
|
||||
void APIENTRY_GL4ES gl4es_glBindFramebuffer(GLenum target, GLuint framebuffer);
|
||||
void APIENTRY_GL4ES gl4es_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
void APIENTRY_GL4ES gl4es_glGenRenderbuffers(GLsizei n, GLuint *renderbuffers);
|
||||
void APIENTRY_GL4ES gl4es_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
|
||||
void APIENTRY_GL4ES gl4es_glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers);
|
||||
void APIENTRY_GL4ES gl4es_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
void APIENTRY_GL4ES gl4es_glBindRenderbuffer(GLenum target, GLuint renderbuffer);
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsRenderbuffer(GLuint renderbuffer);
|
||||
void APIENTRY_GL4ES gl4es_glGenerateMipmap(GLenum target);
|
||||
void APIENTRY_GL4ES gl4es_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint * params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); // naive Wrap
|
||||
void APIENTRY_GL4ES gl4es_glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); // naive Wrap
|
||||
void APIENTRY_GL4ES gl4es_glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); //STUB
|
||||
void APIENTRY_GL4ES gl4es_glFramebufferTextureLayer( GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); // naive Wrap
|
||||
void APIENTRY_GL4ES gl4es_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDrawBuffers(GLsizei n, const GLenum *bufs);
|
||||
void APIENTRY_GL4ES gl4es_glNamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n, const GLenum *bufs);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint * value);
|
||||
void APIENTRY_GL4ES gl4es_glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint * value);
|
||||
void APIENTRY_GL4ES gl4es_glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat * value);
|
||||
void APIENTRY_GL4ES gl4es_glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value);
|
||||
void APIENTRY_GL4ES gl4es_glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value);
|
||||
void APIENTRY_GL4ES gl4es_glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value);
|
||||
void APIENTRY_GL4ES gl4es_glClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glColorMaskIndexed(GLuint framebuffer, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
|
||||
// In case of LIBGL_FB=2, let's create an FBO for everything, that is then blitted just before the SwapBuffer
|
||||
void createMainFBO(int width, int height);
|
||||
void blitMainFBO(int x, int y, int width, int height);
|
||||
void deleteMainFBO(void* state);
|
||||
void bindMainFBO();
|
||||
void unbindMainFBO();
|
||||
|
||||
void readfboBegin();
|
||||
void readfboEnd();
|
||||
|
||||
GLuint gl4es_getCurrentFBO();
|
||||
void gl4es_setCurrentFBO();
|
||||
|
||||
void gl4es_saveCurrentFBO();
|
||||
void gl4es_restoreCurrentFBO();
|
||||
|
||||
#endif // _GL4ES_FRAMEBUFFERS_H_
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,164 @@
|
||||
#ifndef _GL4ES_GL4ES_H_
|
||||
#define _GL4ES_GL4ES_H_
|
||||
|
||||
#include "khash.h"
|
||||
|
||||
#ifdef __ARM_NEON__
|
||||
#include <arm_neon.h>
|
||||
#endif // __ARM_NEON__
|
||||
|
||||
#include "wrap/gles.h"
|
||||
#include "gles.h"
|
||||
#include "glstate.h"
|
||||
|
||||
packed_call_t* APIENTRY_GL4ES glCopyPackedCall(const packed_call_t *packed);
|
||||
|
||||
#define checkError(code) \
|
||||
{int error; while ((error = glGetError())) {} \
|
||||
code \
|
||||
if ((error = glGetError())) \
|
||||
printf(#code " -> %i\n", error);}
|
||||
|
||||
#define printError(file, line) \
|
||||
{int error; if ((error = glGetError())) \
|
||||
printf(file ":%i -> %i\n", line, error);}
|
||||
|
||||
#define FLUSH_BEGINEND if(glstate->list.pending) gl4es_flush()
|
||||
|
||||
#define ERROR_IN_BEGIN if(glstate->list.begin) {errorShim(GL_INVALID_OPERATION); return;}
|
||||
|
||||
const GLubyte* APIENTRY_GL4ES gl4es_glGetString(GLenum name);
|
||||
void APIENTRY_GL4ES gl4es_glGetIntegerv(GLenum pname, GLint *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetFloatv(GLenum pname, GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glEnable(GLenum cap);
|
||||
void APIENTRY_GL4ES gl4es_glDisable(GLenum cap);
|
||||
void APIENTRY_GL4ES gl4es_glEnableClientState(GLenum cap);
|
||||
void APIENTRY_GL4ES gl4es_glDisableClientState(GLenum cap);
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsEnabled(GLenum cap);
|
||||
void APIENTRY_GL4ES gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
void APIENTRY_GL4ES gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count);
|
||||
void APIENTRY_GL4ES gl4es_glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GL4ES gl4es_glBegin(GLenum mode);
|
||||
void APIENTRY_GL4ES gl4es_glEnd(void);
|
||||
void APIENTRY_GL4ES gl4es_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz);
|
||||
void APIENTRY_GL4ES gl4es_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void APIENTRY_GL4ES gl4es_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
void APIENTRY_GL4ES gl4es_glSecondaryColor3f(GLfloat r, GLfloat g, GLfloat b);
|
||||
void APIENTRY_GL4ES gl4es_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glMaterialf(GLenum face, GLenum pname, const GLfloat param);
|
||||
void APIENTRY_GL4ES gl4es_glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q);
|
||||
void APIENTRY_GL4ES gl4es_glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
|
||||
void APIENTRY_GL4ES gl4es_glArrayElement(GLint i);
|
||||
void APIENTRY_GL4ES gl4es_glLockArrays(GLint first, GLsizei count);
|
||||
void APIENTRY_GL4ES gl4es_glUnlockArrays(void);
|
||||
GLuint APIENTRY_GL4ES gl4es_glGenLists(GLsizei range);
|
||||
void APIENTRY_GL4ES gl4es_glNewList(GLuint list, GLenum mode);
|
||||
void APIENTRY_GL4ES gl4es_glEndList(void);
|
||||
void APIENTRY_GL4ES gl4es_glCallList(GLuint list);
|
||||
void APIENTRY_GL4ES gl4es_glCallLists(GLsizei n, GLenum type, const GLvoid *lists);
|
||||
void APIENTRY_GL4ES gl4es_glDeleteLists(GLuint list, GLsizei range);
|
||||
void APIENTRY_GL4ES gl4es_glListBase(GLuint base);
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsList(GLuint list);
|
||||
void APIENTRY_GL4ES gl4es_glPolygonMode(GLenum face, GLenum mode);
|
||||
GLenum APIENTRY_GL4ES gl4es_glGetError(void);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GL4ES gl4es_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer);
|
||||
void APIENTRY_GL4ES gl4es_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer);
|
||||
void APIENTRY_GL4ES gl4es_glGetPointerv(GLenum pname, GLvoid* *params);
|
||||
void APIENTRY_GL4ES gl4es_glFlush(void);
|
||||
void APIENTRY_GL4ES gl4es_glFinish(void);
|
||||
void APIENTRY_GL4ES gl4es_glFogfv(GLenum pname, const GLfloat* params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glStencilMaskSeparate(GLenum face, GLuint mask);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
|
||||
void APIENTRY_GL4ES gl4es_glMultiDrawElements( GLenum mode, GLsizei *count, GLenum type, const void * const *indices, GLsizei primcount);
|
||||
void APIENTRY_GL4ES gl4es_glMultiDrawElementsBaseVertex( GLenum mode, GLsizei *count, GLenum type, const void * const *indices, GLsizei primcount, const GLint * basevertex);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
|
||||
void APIENTRY_GL4ES gl4es_glDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
|
||||
void APIENTRY_GL4ES gl4es_glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
|
||||
void APIENTRY_GL4ES gl4es_glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex);
|
||||
|
||||
const GLubyte* APIENTRY_GL4ES gl4es_glGetStringi(GLenum name, GLuint index);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glClampColor(GLenum target, GLenum clamp);
|
||||
|
||||
void gl4es_flush(void);
|
||||
|
||||
int adjust_vertices(GLenum mode, int nb);
|
||||
|
||||
extern glstate_t *glstate;
|
||||
|
||||
void fpe_Init(glstate_t *glstate); // defined in fpe.c
|
||||
void fpe_Dispose(glstate_t *glstate); // defined in fpe.c
|
||||
|
||||
// glGetError() return last error, but that error is not reset until read
|
||||
// So if 2 operations generate an error,
|
||||
// the 2nd error is lost if glGetError has not been called after 1st op
|
||||
static inline void errorGL() { // next glGetError will be from GL
|
||||
if(glstate->type_error && glstate->shim_error==GL_NO_ERROR)
|
||||
glstate->type_error = 0;
|
||||
else if(glstate->type_error==2)
|
||||
glstate->type_error = 1; // will need to read glGetError...
|
||||
}
|
||||
static inline void errorShim(GLenum error) { // next glGetError will be "error" from gl4es
|
||||
if(glstate->type_error && glstate->shim_error==GL_NO_ERROR)
|
||||
glstate->type_error = 1;
|
||||
if(glstate->shim_error == GL_NO_ERROR)
|
||||
glstate->shim_error = error;
|
||||
}
|
||||
static inline void noerrorShim() {
|
||||
if(glstate->type_error && glstate->shim_error==GL_NO_ERROR)
|
||||
glstate->type_error = 1;
|
||||
}
|
||||
|
||||
static inline void noerrorShimNoPurge() {
|
||||
// doing nothing
|
||||
}
|
||||
|
||||
void gl4es_scratch(int alloc);
|
||||
void gl4es_scratch_vertex(int alloc);
|
||||
void gl4es_scratch_indices(int alloc);
|
||||
void gl4es_use_scratch_vertex(int use);
|
||||
void gl4es_use_scratch_indices(int use);
|
||||
|
||||
void ToBuffer(int first, int count);
|
||||
void UnBuffer();
|
||||
|
||||
GLboolean APIENTRY_GL4ES glIsList(GLuint list);
|
||||
GLuint APIENTRY_GL4ES glGenLists(GLsizei range);
|
||||
void APIENTRY_GL4ES glActiveTextureARB(GLenum texture);
|
||||
void APIENTRY_GL4ES glArrayElement(GLint i);
|
||||
void APIENTRY_GL4ES glBegin(GLenum mode);
|
||||
void APIENTRY_GL4ES glCallList(GLuint list);
|
||||
void APIENTRY_GL4ES glCallLists(GLsizei n, GLenum type, const GLvoid *lists);
|
||||
void APIENTRY_GL4ES glClearDepth(GLdouble depth);
|
||||
void APIENTRY_GL4ES glDeleteList(GLuint list);
|
||||
void APIENTRY_GL4ES glDeleteLists(GLuint list, GLsizei range);
|
||||
void APIENTRY_GL4ES glDrawArrays(GLenum mode, GLint first, GLsizei count);
|
||||
void APIENTRY_GL4ES glEnd(void);
|
||||
void APIENTRY_GL4ES glEndList(void);
|
||||
void APIENTRY_GL4ES glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble Near, GLdouble Far);
|
||||
void APIENTRY_GL4ES glGetDoublev(GLenum pname, GLdouble *params);
|
||||
void APIENTRY_GL4ES glIndexf(GLfloat i);
|
||||
void APIENTRY_GL4ES glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GL4ES glListBase(GLuint base);
|
||||
void APIENTRY_GL4ES glLockArraysEXT(GLint first, GLsizei count);
|
||||
void APIENTRY_GL4ES glNewList(GLuint list, GLenum mode);
|
||||
void APIENTRY_GL4ES glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble Near, GLdouble Far);
|
||||
void APIENTRY_GL4ES glSecondaryColor3f(GLfloat r, GLfloat g, GLfloat b);
|
||||
void APIENTRY_GL4ES glTexCoord2f(GLfloat s, GLfloat t);
|
||||
void APIENTRY_GL4ES glUnlockArraysEXT(void);
|
||||
void APIENTRY_GL4ES glVertex2f(GLfloat x, GLfloat y);
|
||||
void APIENTRY_GL4ES glVertex2i(GLint x, GLint y);
|
||||
void APIENTRY_GL4ES glVertex3f(GLfloat x, GLfloat y, GLfloat z);
|
||||
GLenum APIENTRY_GL4ES glGetError(void);
|
||||
|
||||
// custom functions
|
||||
void APIENTRY_GL4ES glPushCall(void *call);
|
||||
|
||||
#endif // _GL4ES_GL4ES_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
#ifndef _GL_LOOKUP_H_
|
||||
#define _GL_LOOKUP_H_
|
||||
|
||||
#include "attributes.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define MAP(func_name, func) \
|
||||
if (strcmp(name, func_name) == 0) {printf("%p (%s)\n", (void*)func, #func) ;return (void *)func;}
|
||||
#else
|
||||
#define MAP(func_name, func) \
|
||||
if (strcmp(name, func_name) == 0) return (void *)func;
|
||||
#endif
|
||||
|
||||
#define EX(func_name) MAP(#func_name, func_name)
|
||||
|
||||
#define ARB(func_name) MAP(#func_name "ARB", func_name)
|
||||
|
||||
#define EXT(func_name) MAP(#func_name "EXT", func_name)
|
||||
|
||||
#define _EX(func_name) MAP(#func_name, gl4es_ ## func_name)
|
||||
|
||||
#define _ARB(func_name) MAP(#func_name "ARB", gl4es_ ## func_name)
|
||||
|
||||
#define _EXT(func_name) MAP(#func_name "EXT", gl4es_ ## func_name)
|
||||
|
||||
#ifndef STUB_FCT
|
||||
#error STUB_FCT is not defined
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define STUB(func_name) \
|
||||
if (strcmp(name, #func_name) == 0) { \
|
||||
printf("=> STUB\n"); \
|
||||
if(!globals4es.silentstub) LOGD("GL4ES stub: %s\n", #func_name); \
|
||||
return (void *)STUB_FCT; \
|
||||
}
|
||||
#else
|
||||
#define STUB(func_name) \
|
||||
if (strcmp(name, #func_name) == 0) { \
|
||||
if(!globals4es.silentstub) LOGD("GL4ES stub: %s\n", #func_name); \
|
||||
return (void *)STUB_FCT; \
|
||||
}
|
||||
#endif
|
||||
|
||||
NonAliasExportDecl(void*,gl4es_GetProcAddress,(const char *name));
|
||||
|
||||
#endif //_GL_LOOKUP_H_
|
||||
@@ -0,0 +1,88 @@
|
||||
#ifndef _GL4ES_GLCASE_H_
|
||||
#define _GL4ES_GLCASE_H_
|
||||
|
||||
#define GL_TYPE_CASE(name, var, magic, vtype, code)\
|
||||
case magic: { \
|
||||
vtype *name = (vtype *)var; \
|
||||
code \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define GL_TYPE_CASE_ALT(name, var, name2, var2, magic, vtype, code) \
|
||||
case magic: { \
|
||||
vtype *name = (vtype *)var; \
|
||||
vtype *name2= (vtype *)var2; \
|
||||
code \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define GL_TYPE_CASE2(name, var, magic, vtype, code2, code) \
|
||||
case magic: { \
|
||||
code2 { \
|
||||
vtype *name = (vtype *)var; \
|
||||
code \
|
||||
} \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define GL_TYPE_CASE_MAX(name, var, magic, vtype, code, max) \
|
||||
case magic: { \
|
||||
vtype *name = (vtype *)var; \
|
||||
vtype maxv = max; \
|
||||
code \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define GL_TYPE_SWITCH(name, var, type, code, extra) \
|
||||
switch (type) { \
|
||||
GL_TYPE_CASE(name, var, GL_DOUBLE, GLdouble, code) \
|
||||
GL_TYPE_CASE(name, var, GL_FLOAT, GLfloat, code) \
|
||||
GL_TYPE_CASE(name, var, GL_INT, GLint, code) \
|
||||
GL_TYPE_CASE(name, var, GL_SHORT, GLshort, code) \
|
||||
GL_TYPE_CASE(name, var, GL_BYTE, GLbyte, code) \
|
||||
GL_TYPE_CASE(name, var, GL_UNSIGNED_BYTE, GLubyte, code) \
|
||||
GL_TYPE_CASE(name, var, GL_UNSIGNED_INT, GLuint, code) \
|
||||
GL_TYPE_CASE(name, var, GL_UNSIGNED_SHORT, GLushort, code) \
|
||||
extra \
|
||||
}
|
||||
|
||||
#define GL_TYPE_SWITCH_ALT(name, var, name2, var2, type, code, extra) \
|
||||
switch (type) { \
|
||||
GL_TYPE_CASE_ALT(name, var, name2, var2, GL_DOUBLE, GLdouble, code) \
|
||||
GL_TYPE_CASE_ALT(name, var, name2, var2, GL_FLOAT, GLfloat, code) \
|
||||
GL_TYPE_CASE_ALT(name, var, name2, var2, GL_INT, GLint, code) \
|
||||
GL_TYPE_CASE_ALT(name, var, name2, var2, GL_SHORT, GLshort, code) \
|
||||
GL_TYPE_CASE_ALT(name, var, name2, var2, GL_BYTE, GLbyte, code) \
|
||||
GL_TYPE_CASE_ALT(name, var, name2, var2, GL_UNSIGNED_BYTE, GLubyte, code) \
|
||||
GL_TYPE_CASE_ALT(name, var, name2, var2, GL_UNSIGNED_INT, GLuint, code) \
|
||||
GL_TYPE_CASE_ALT(name, var, name2, var2, GL_UNSIGNED_SHORT, GLushort, code) \
|
||||
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.0) \
|
||||
GL_TYPE_CASE_MAX(name, var, GL_FLOAT, GLfloat, code, 1.0f) \
|
||||
GL_TYPE_CASE_MAX(name, var, GL_INT, GLint, code, 2147483647l) \
|
||||
GL_TYPE_CASE_MAX(name, var, GL_SHORT, GLshort, code, 32767) \
|
||||
GL_TYPE_CASE_MAX(name, var, GL_BYTE, GLbyte, code, 127) \
|
||||
GL_TYPE_CASE_MAX(name, var, GL_UNSIGNED_BYTE, GLubyte, code, 255) \
|
||||
GL_TYPE_CASE_MAX(name, var, GL_UNSIGNED_INT, GLuint, code, 4294967295l) \
|
||||
GL_TYPE_CASE_MAX(name, var, GL_UNSIGNED_SHORT, GLushort, code, 65535) \
|
||||
extra \
|
||||
}
|
||||
|
||||
#endif // _GL4ES_GLCASE_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,241 @@
|
||||
_EX(glActiveTexture);
|
||||
_EX(glAlphaFunc);
|
||||
_EX(glAlphaFuncx);
|
||||
_EX(glAttachShader);
|
||||
_EX(glBindAttribLocation);
|
||||
_EX(glBindBuffer);
|
||||
_EX(glBindFramebuffer);
|
||||
_EX(glBindRenderbuffer);
|
||||
_EX(glBindTexture);
|
||||
_EX(glBlendColor);
|
||||
_EX(glBlendEquation);
|
||||
_EX(glBlendEquationSeparate);
|
||||
_EX(glBlendFunc);
|
||||
_EX(glBlendFuncSeparate);
|
||||
_EX(glBufferData);
|
||||
_EX(glBufferSubData);
|
||||
_EX(glCheckFramebufferStatus);
|
||||
_EX(glClear);
|
||||
_EX(glClearColor);
|
||||
_EX(glClearColorx);
|
||||
_EX(glClearDepthf);
|
||||
_EX(glClearDepthx);
|
||||
_EX(glClearStencil);
|
||||
_EX(glClientActiveTexture);
|
||||
_EX(glClipPlanef);
|
||||
_EX(glClipPlanex);
|
||||
_EX(glColor4f);
|
||||
_EX(glColor4ub);
|
||||
_EX(glColor4x);
|
||||
_EX(glColorMask);
|
||||
_EX(glColorPointer);
|
||||
_EX(glCompileShader);
|
||||
_EX(glCompressedTexImage2D);
|
||||
_EX(glCompressedTexSubImage2D);
|
||||
_EX(glCopyTexImage2D);
|
||||
_EX(glCopyTexSubImage2D);
|
||||
_EX(glCreateProgram);
|
||||
_EX(glCreateShader);
|
||||
_EX(glCullFace);
|
||||
_EX(glDeleteBuffers);
|
||||
_EX(glDeleteFramebuffers);
|
||||
_EX(glDeleteProgram);
|
||||
_EX(glDeleteRenderbuffers);
|
||||
_EX(glDeleteShader);
|
||||
_EX(glDeleteTextures);
|
||||
_EX(glDepthFunc);
|
||||
_EX(glDepthMask);
|
||||
_EX(glDepthRangef);
|
||||
_EX(glDepthRangex);
|
||||
_EX(glDetachShader);
|
||||
_EX(glDisable);
|
||||
_EX(glDisableClientState);
|
||||
_EX(glDisableVertexAttribArray);
|
||||
_EX(glDrawArrays);
|
||||
_EX(glDrawElements);
|
||||
_EX(glDrawTexf);
|
||||
_EX(glDrawTexi);
|
||||
_EX(glEnable);
|
||||
_EX(glEnableClientState);
|
||||
_EX(glEnableVertexAttribArray);
|
||||
_EX(glFinish);
|
||||
_EX(glFlush);
|
||||
_EX(glFogCoordPointer);
|
||||
_EX(glFogCoordf);
|
||||
_EX(glFogCoordfv);
|
||||
_EX(glFogf);
|
||||
_EX(glFogfv);
|
||||
_EX(glFogx);
|
||||
_EX(glFogxv);
|
||||
_EX(glFramebufferRenderbuffer);
|
||||
_EX(glFramebufferTexture2D);
|
||||
_EX(glFrontFace);
|
||||
_EX(glFrustumf);
|
||||
_EX(glFrustumx);
|
||||
_EX(glGenBuffers);
|
||||
_EX(glGenFramebuffers);
|
||||
_EX(glGenRenderbuffers);
|
||||
_EX(glGenTextures);
|
||||
_EX(glGenerateMipmap);
|
||||
_EX(glGetActiveAttrib);
|
||||
_EX(glGetActiveUniform);
|
||||
_EX(glGetAttachedShaders);
|
||||
_EX(glGetAttribLocation);
|
||||
_EX(glGetBooleanv);
|
||||
_EX(glGetBufferParameteriv);
|
||||
_EX(glGetClipPlanef);
|
||||
_EX(glGetClipPlanex);
|
||||
_EX(glGetError);
|
||||
_EX(glGetFixedv);
|
||||
_EX(glGetFloatv);
|
||||
_EX(glGetFramebufferAttachmentParameteriv);
|
||||
_EX(glGetIntegerv);
|
||||
_EX(glGetLightfv);
|
||||
_EX(glGetLightxv);
|
||||
_EX(glGetMaterialfv);
|
||||
_EX(glGetMaterialxv);
|
||||
_EX(glGetPointerv);
|
||||
_EX(glGetProgramBinary);
|
||||
_EX(glGetProgramInfoLog);
|
||||
_EX(glGetProgramiv);
|
||||
_EX(glGetRenderbufferParameteriv);
|
||||
_EX(glGetShaderInfoLog);
|
||||
_EX(glGetShaderPrecisionFormat);
|
||||
_EX(glGetShaderSource);
|
||||
_EX(glGetShaderiv);
|
||||
_EX(glGetString);
|
||||
_EX(glGetTexEnvfv);
|
||||
_EX(glGetTexEnviv);
|
||||
_EX(glGetTexEnvxv);
|
||||
_EX(glGetTexParameterfv);
|
||||
_EX(glGetTexParameteriv);
|
||||
_EX(glGetTexParameterxv);
|
||||
_EX(glGetUniformLocation);
|
||||
_EX(glGetUniformfv);
|
||||
_EX(glGetUniformiv);
|
||||
_EX(glGetVertexAttribPointerv);
|
||||
_EX(glGetVertexAttribfv);
|
||||
_EX(glGetVertexAttribiv);
|
||||
_EX(glHint);
|
||||
_EX(glIsBuffer);
|
||||
_EX(glIsEnabled);
|
||||
_EX(glIsFramebuffer);
|
||||
_EX(glIsProgram);
|
||||
_EX(glIsRenderbuffer);
|
||||
_EX(glIsShader);
|
||||
_EX(glIsTexture);
|
||||
_EX(glLightModelf);
|
||||
_EX(glLightModelfv);
|
||||
_EX(glLightModelx);
|
||||
_EX(glLightModelxv);
|
||||
_EX(glLightf);
|
||||
_EX(glLightfv);
|
||||
_EX(glLightx);
|
||||
_EX(glLightxv);
|
||||
_EX(glLineWidth);
|
||||
_EX(glLineWidthx);
|
||||
_EX(glLinkProgram);
|
||||
_EX(glLoadIdentity);
|
||||
_EX(glLoadMatrixf);
|
||||
_EX(glLoadMatrixx);
|
||||
_EX(glLogicOp);
|
||||
_EX(glMaterialf);
|
||||
_EX(glMaterialfv);
|
||||
_EX(glMaterialx);
|
||||
_EX(glMaterialxv);
|
||||
_EX(glMatrixMode);
|
||||
_EX(glMultMatrixf);
|
||||
_EX(glMultMatrixx);
|
||||
_EX(glMultiDrawArrays);
|
||||
_EX(glMultiDrawElements);
|
||||
_EX(glMultiTexCoord4f);
|
||||
_EX(glMultiTexCoord4x);
|
||||
_EX(glNormal3f);
|
||||
_EX(glNormal3x);
|
||||
_EX(glNormalPointer);
|
||||
_EX(glOrthof);
|
||||
_EX(glOrthox);
|
||||
_EX(glPixelStorei);
|
||||
_EX(glPointParameterf);
|
||||
_EX(glPointParameterfv);
|
||||
_EX(glPointParameterx);
|
||||
_EX(glPointParameterxv);
|
||||
_EX(glPointSize);
|
||||
_EX(glPointSizePointerOES);
|
||||
_EX(glPointSizex);
|
||||
_EX(glPolygonOffset);
|
||||
_EX(glPolygonOffsetx);
|
||||
_EX(glPopMatrix);
|
||||
_EX(glProgramBinary);
|
||||
_EX(glPushMatrix);
|
||||
_EX(glReadPixels);
|
||||
_EX(glReleaseShaderCompiler);
|
||||
_EX(glRenderbufferStorage);
|
||||
_EX(glRotatef);
|
||||
_EX(glRotatex);
|
||||
_EX(glSampleCoverage);
|
||||
_EX(glSampleCoveragex);
|
||||
_EX(glScalef);
|
||||
_EX(glScalex);
|
||||
_EX(glScissor);
|
||||
_EX(glShadeModel);
|
||||
_EX(glShaderBinary);
|
||||
_EX(glShaderSource);
|
||||
_EX(glStencilFunc);
|
||||
_EX(glStencilFuncSeparate);
|
||||
_EX(glStencilMask);
|
||||
_EX(glStencilMaskSeparate);
|
||||
_EX(glStencilOp);
|
||||
_EX(glStencilOpSeparate);
|
||||
_EX(glTexCoordPointer);
|
||||
_EX(glTexEnvf);
|
||||
_EX(glTexEnvfv);
|
||||
_EX(glTexEnvi);
|
||||
_EX(glTexEnviv);
|
||||
_EX(glTexEnvx);
|
||||
_EX(glTexEnvxv);
|
||||
_EX(glTexGenfv);
|
||||
_EX(glTexGeni);
|
||||
_EX(glTexImage2D);
|
||||
_EX(glTexParameterf);
|
||||
_EX(glTexParameterfv);
|
||||
_EX(glTexParameteri);
|
||||
_EX(glTexParameteriv);
|
||||
_EX(glTexParameterx);
|
||||
_EX(glTexParameterxv);
|
||||
_EX(glTexSubImage2D);
|
||||
_EX(glTranslatef);
|
||||
_EX(glTranslatex);
|
||||
_EX(glUniform1f);
|
||||
_EX(glUniform1fv);
|
||||
_EX(glUniform1i);
|
||||
_EX(glUniform1iv);
|
||||
_EX(glUniform2f);
|
||||
_EX(glUniform2fv);
|
||||
_EX(glUniform2i);
|
||||
_EX(glUniform2iv);
|
||||
_EX(glUniform3f);
|
||||
_EX(glUniform3fv);
|
||||
_EX(glUniform3i);
|
||||
_EX(glUniform3iv);
|
||||
_EX(glUniform4f);
|
||||
_EX(glUniform4fv);
|
||||
_EX(glUniform4i);
|
||||
_EX(glUniform4iv);
|
||||
_EX(glUniformMatrix2fv);
|
||||
_EX(glUniformMatrix3fv);
|
||||
_EX(glUniformMatrix4fv);
|
||||
_EX(glUseProgram);
|
||||
_EX(glValidateProgram);
|
||||
_EX(glVertexAttrib1f);
|
||||
_EX(glVertexAttrib1fv);
|
||||
_EX(glVertexAttrib2f);
|
||||
_EX(glVertexAttrib2fv);
|
||||
_EX(glVertexAttrib3f);
|
||||
_EX(glVertexAttrib3fv);
|
||||
_EX(glVertexAttrib4f);
|
||||
_EX(glVertexAttrib4fv);
|
||||
_EX(glVertexAttribPointer);
|
||||
_EX(glVertexAttribIPointer);
|
||||
_EX(glVertexPointer);
|
||||
_EX(glViewport);
|
||||
@@ -0,0 +1,632 @@
|
||||
#include "glstate.h"
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "fpe.h"
|
||||
#include "framebuffers.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "init.h"
|
||||
#include "loader.h"
|
||||
#include "oldprogram.h"
|
||||
|
||||
glstate_t *glstate = NULL;
|
||||
|
||||
glstate_t default_glstate = {0};
|
||||
|
||||
#define DEFAULT_STATE (void*)(~(uintptr_t)0)
|
||||
|
||||
void init_matrix(glstate_t* glstate);
|
||||
|
||||
static void free_renderbuffer(glrenderbuffer_t *rend)
|
||||
{
|
||||
LOAD_GLES2_OR_OES(glDeleteRenderbuffers);
|
||||
if(!rend || !gles_glDeleteRenderbuffers)
|
||||
return;
|
||||
if(rend->secondarybuffer)
|
||||
gles_glDeleteRenderbuffers(1, &rend->secondarybuffer);
|
||||
if(rend->renderbuffer)
|
||||
gles_glDeleteRenderbuffers(1, &rend->renderbuffer);
|
||||
// the texture will be free by the free of the texture list, as it's referenced there...
|
||||
free(rend);
|
||||
}
|
||||
|
||||
static void free_framebuffer(glframebuffer_t *fb)
|
||||
{
|
||||
LOAD_GLES2_OR_OES(glDeleteFramebuffers);
|
||||
if(!fb || !gles_glDeleteFramebuffers)
|
||||
return;
|
||||
if(fb->id)
|
||||
gles_glDeleteFramebuffers(1, &fb->id);
|
||||
// the texture will be free by the free of the texture list, as it's referenced there...
|
||||
free(fb);
|
||||
}
|
||||
|
||||
static void free_texture(gltexture_t *tex)
|
||||
{
|
||||
LOAD_GLES(glDeleteTextures);
|
||||
if(!tex || !gles_glDeleteTextures)
|
||||
return;
|
||||
if(tex->glname)
|
||||
gles_glDeleteTextures(1, &tex->glname);
|
||||
if(tex->data)
|
||||
free(tex->data);
|
||||
// renderbuffer linked to this texture will be freed by the free_renderbuffer function.
|
||||
free(tex);
|
||||
}
|
||||
|
||||
void CopyGLEShard(void* dst, const void* src)
|
||||
{
|
||||
if(!dst || !src)
|
||||
return;
|
||||
memcpy(((glstate_t*)dst)->gleshard, ((const glstate_t*)src)->gleshard, sizeof(gleshard_t));
|
||||
}
|
||||
|
||||
void* NewGLState(void* shared_glstate, int es2only) {
|
||||
glstate_t *glstate = (shared_glstate!=DEFAULT_STATE)?((glstate_t*)calloc(1, sizeof(glstate_t))):&default_glstate;
|
||||
#if defined(AMIGAOS4) || defined(__EMSCRIPTEN__)
|
||||
int def = 0;
|
||||
if(shared_glstate==DEFAULT_STATE)
|
||||
def = 1;
|
||||
#endif
|
||||
if(shared_glstate==DEFAULT_STATE)
|
||||
shared_glstate=NULL;
|
||||
if(shared_glstate) {
|
||||
glstate_t* copy_state = (glstate_t*)shared_glstate;
|
||||
if(!copy_state->shared_cnt) {
|
||||
copy_state->shared_cnt = (int*)malloc(sizeof(int));
|
||||
(*copy_state->shared_cnt) = 2;
|
||||
} else
|
||||
(*copy_state->shared_cnt)++;
|
||||
glstate->shared_cnt = copy_state->shared_cnt;
|
||||
glstate->headlists = copy_state->headlists;
|
||||
glstate->actual_tex2d = copy_state->actual_tex2d;
|
||||
glstate->texture.list = copy_state->texture.list;
|
||||
glstate->glsl = copy_state->glsl;
|
||||
//glstate->gleshard = copy_state->gleshard; // Not shared (at least not the VA)
|
||||
glstate->buffers = copy_state->buffers;
|
||||
glstate->fpe_cache = copy_state->fpe_cache;
|
||||
glstate->fbo.renderbufferlist = copy_state->fbo.renderbufferlist;
|
||||
glstate->fbo.default_rb = copy_state->fbo.default_rb;
|
||||
glstate->fbo.framebufferlist = copy_state->fbo.framebufferlist;
|
||||
glstate->fbo.fbo_0 = copy_state->fbo.fbo_0;
|
||||
glstate->fbo.old = copy_state->fbo.old;
|
||||
glstate->samplers.samplerlist = copy_state->samplers.samplerlist;
|
||||
glstate->queries.querylist = copy_state->queries.querylist;
|
||||
|
||||
glstate->defaultvbo = copy_state->defaultvbo;
|
||||
}
|
||||
// set all VAValue to default
|
||||
GLfloat vadefault[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
for (int i=0; i<MAX_VATTRIB; ++i)
|
||||
memcpy(glstate->vavalue[i], vadefault, sizeof(vadefault));
|
||||
// set shortcut
|
||||
glstate->vertex = glstate->vavalue[ATT_VERTEX];
|
||||
glstate->color = glstate->vavalue[ATT_COLOR];
|
||||
glstate->secondary = glstate->vavalue[ATT_SECONDARY];
|
||||
glstate->normal = glstate->vavalue[ATT_NORMAL];
|
||||
glstate->fogcoord = glstate->vavalue[ATT_FOGCOORD];
|
||||
for (int i=0; i<MAX_TEX; ++i)
|
||||
glstate->texcoord[i] = glstate->vavalue[ATT_MULTITEXCOORD0+i];
|
||||
// set specifics default
|
||||
GLfloat white[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
memcpy(glstate->color, white, sizeof(GLfloat)*4);
|
||||
glstate->shim_error = GL_NO_ERROR;
|
||||
glstate->normal[2] = 1.0f; // default normal is 0/0/1
|
||||
glstate->matrix_mode = GL_MODELVIEW;
|
||||
|
||||
// add default VBO
|
||||
if(!shared_glstate) // TODO: check if default VBO is shared?
|
||||
{
|
||||
khint_t k;
|
||||
int ret;
|
||||
khash_t(buff) *list = glstate->buffers = kh_init(buff);
|
||||
k = kh_put(buff, list, 0, &ret);
|
||||
glbuffer_t *buff = kh_value(list, k) = calloc(1, sizeof(glbuffer_t));
|
||||
/*buff->buffer = 0;
|
||||
buff->type = 0;
|
||||
buff->data = NULL;*/
|
||||
buff->usage = GL_STATIC_DRAW;
|
||||
//buff->size = 0;
|
||||
buff->access = GL_READ_WRITE;
|
||||
//buff->mapped = 0;
|
||||
glstate->defaultvbo = buff;
|
||||
}
|
||||
// add default VAO
|
||||
{
|
||||
khint_t k;
|
||||
int ret;
|
||||
khash_t(glvao) *list = glstate->vaos = kh_init(glvao);
|
||||
k = kh_put(glvao, list, 0, &ret);
|
||||
glvao_t *glvao = kh_value(list, k) = malloc(sizeof(glvao_t));
|
||||
// new vao is binded to default vbo
|
||||
VaoInit(glvao);
|
||||
// just put is number
|
||||
glvao->array = 0;
|
||||
glstate->defaultvao = glvao;
|
||||
}
|
||||
// initialize gllists
|
||||
if(!shared_glstate)
|
||||
{
|
||||
khint_t k;
|
||||
int ret;
|
||||
khash_t(gllisthead) *list = glstate->headlists = kh_init(gllisthead);
|
||||
k = kh_put(gllisthead, list, 1, &ret);
|
||||
kh_del(gllisthead, list, k);
|
||||
}
|
||||
// actual_tex2d
|
||||
if(!shared_glstate)
|
||||
{
|
||||
glstate->actual_tex2d = (GLuint*)calloc(MAX_TEX, sizeof(GLuint));
|
||||
}
|
||||
// glsl
|
||||
glstate->gleshard = (gleshard_t*)calloc(1, sizeof(gleshard_t)); // Not shared!
|
||||
if(!shared_glstate)
|
||||
{
|
||||
glstate->glsl = (glsl_t*)malloc(sizeof(glsl_t));
|
||||
memset(glstate->glsl, 0, sizeof(glsl_t));
|
||||
InitOldProgramMap(glstate);
|
||||
}
|
||||
// Bind defaults...
|
||||
glstate->vao = glstate->defaultvao;
|
||||
|
||||
//raster & viewport
|
||||
glstate->raster.raster_zoomx=1.0f;
|
||||
glstate->raster.raster_zoomy=1.0f;
|
||||
glstate->raster.map_i2i_size=1;
|
||||
glstate->raster.map_i2r_size=1;
|
||||
glstate->raster.map_i2g_size=1;
|
||||
glstate->raster.map_i2b_size=1;
|
||||
glstate->raster.map_i2a_size=1;
|
||||
/*
|
||||
glstate->raster.map_s2s_size=1;
|
||||
glstate->raster.map_r2r_size=1;
|
||||
glstate->raster.map_g2g_size=1;
|
||||
glstate->raster.map_b2b_size=1;
|
||||
glstate->raster.map_a2a_size=1;
|
||||
*/
|
||||
|
||||
// pack & unpack alignment
|
||||
glstate->texture.pack_align = 4;
|
||||
glstate->texture.unpack_align = 4;
|
||||
|
||||
// eval
|
||||
glstate->map_grid[0]._2 = 1.0f;
|
||||
glstate->map_grid[0].n = 1;
|
||||
glstate->map_grid[0].d = 1.0f;
|
||||
glstate->map_grid[1]._2 = 1.0f;
|
||||
glstate->map_grid[1].n = 1;
|
||||
glstate->map_grid[1].d = 1.0f;
|
||||
|
||||
// line stipple
|
||||
glstate->linestipple.factor = 1;
|
||||
glstate->linestipple.pattern = 0xFFFF;
|
||||
glstate->linestipple.data = (GLubyte *)malloc(sizeof(GLubyte) * 16);
|
||||
memset(glstate->linestipple.data, 0xff, sizeof(GLubyte) * 16);
|
||||
glstate->linestipple.texture = 0;
|
||||
|
||||
// fpe
|
||||
if(hardext.esversion>1) {
|
||||
glstate->fpe_state = (fpe_state_t*)calloc(1, sizeof(fpe_state_t));
|
||||
glstate->glsl->es2 = es2only;
|
||||
fpe_Init(glstate);
|
||||
}
|
||||
|
||||
// init the matrix tracking
|
||||
init_matrix(glstate);
|
||||
|
||||
// init the textures
|
||||
{
|
||||
gltexture_t* tex;
|
||||
if(!shared_glstate) {
|
||||
int ret;
|
||||
khint_t k;
|
||||
khash_t(tex) *list = glstate->texture.list;
|
||||
list = glstate->texture.list = kh_init(tex);
|
||||
// segfaults if we don't do a single put
|
||||
k = kh_put(tex, list, 1, &ret);
|
||||
kh_del(tex, list, k);
|
||||
}
|
||||
// now add default "0" texture => no, because tex 0 is not shared....
|
||||
/*k = kh_put(tex, list, 0, &ret);
|
||||
glstate->texture.zero = tex = kh_value(list, k) = malloc(sizeof(gltexture_t));*/
|
||||
glstate->texture.zero = tex = calloc(1, sizeof(gltexture_t));
|
||||
tex->adjustxy[0] = tex->adjustxy[1] = 1.f;
|
||||
tex->mipmap_auto = (globals4es.automipmap==1);
|
||||
tex->mipmap_need = (globals4es.automipmap==1)?1:0;
|
||||
tex->streamingID = -1;
|
||||
tex->base_level = -1;
|
||||
tex->max_level = -1;
|
||||
tex->alpha = true;
|
||||
init_sampler(&tex->sampler);
|
||||
tex->fpe_format = FPE_TEX_RGBA;
|
||||
tex->format = GL_RGBA;
|
||||
tex->type = GL_UNSIGNED_BYTE;
|
||||
tex->inter_format = GL_RGBA;
|
||||
tex->inter_type = GL_UNSIGNED_BYTE;
|
||||
// now bind that texture on all unit
|
||||
for (int itarget=0; itarget<ENABLED_TEXTURE_LAST; ++itarget)
|
||||
for (int i=0; i<MAX_TEX; ++i)
|
||||
glstate->texture.bound[i][itarget] = tex;
|
||||
}
|
||||
|
||||
|
||||
// init the light tracking
|
||||
glstate->light.ambient[0]=glstate->light.ambient[1]=glstate->light.ambient[2]=0.2f;
|
||||
glstate->light.ambient[3]=1.0f;
|
||||
glstate->light.lights[0].diffuse[0]=
|
||||
glstate->light.lights[0].diffuse[1]=
|
||||
glstate->light.lights[0].diffuse[2]=
|
||||
glstate->light.lights[0].diffuse[3]=1.0f;
|
||||
memcpy(glstate->light.lights[0].specular, glstate->light.lights[0].diffuse, 4*sizeof(GLfloat));
|
||||
for (int i=0; i<hardext.maxlights; i++) {
|
||||
glstate->light.lights[i].ambient[3] = 1.0f;
|
||||
glstate->light.lights[i].position[2] = 1.0f;
|
||||
glstate->light.lights[i].spotDirection[2] = -1.0f;
|
||||
glstate->light.lights[i].spotCutoff = 180;
|
||||
glstate->light.lights[i].constantAttenuation = 1;
|
||||
}
|
||||
// Materials
|
||||
glstate->material.front.ambient[0] =
|
||||
glstate->material.front.ambient[1] =
|
||||
glstate->material.front.ambient[2] = 0.2f;
|
||||
glstate->material.front.ambient[3] = 1.0f;
|
||||
glstate->material.front.diffuse[0] =
|
||||
glstate->material.front.diffuse[1] =
|
||||
glstate->material.front.diffuse[2] = 0.8f;
|
||||
glstate->material.front.diffuse[3] = 1.0f;
|
||||
glstate->material.front.specular[3] = 1.0f;
|
||||
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;
|
||||
glstate->fog.distance = GL_EYE_PLANE_ABSOLUTE_NV;
|
||||
// Alpha Func
|
||||
glstate->alphafunc = GL_ALWAYS;
|
||||
glstate->alpharef = 0.0f;
|
||||
// Blend
|
||||
glstate->blendsfactorrgb = GL_ONE;
|
||||
glstate->blenddfactorrgb = GL_ZERO;
|
||||
glstate->blendsfactoralpha = GL_ONE;
|
||||
glstate->blenddfactoralpha = GL_ZERO;
|
||||
// Depth
|
||||
glstate->depth.func = GL_LESS;
|
||||
glstate->depth.mask = GL_TRUE;
|
||||
glstate->depth.Far = 1.0f;
|
||||
glstate->depth.clear= 1.0f;
|
||||
// Face
|
||||
glstate->face.cull = GL_BACK;
|
||||
glstate->face.front = GL_CCW;
|
||||
// Point Sprite
|
||||
glstate->pointsprite.size = 1.0f;
|
||||
glstate->pointsprite.sizeMax = 32.0f; // spec indicate 1., but it seems it's set to hardware limit, so puting 32...
|
||||
glstate->pointsprite.fadeThresholdSize = 1.0f;
|
||||
glstate->pointsprite.distance[0] = 1.0f;
|
||||
glstate->pointsprite.coordOrigin = GL_UPPER_LEFT;
|
||||
// Stencil
|
||||
glstate->stencil.func[0] = glstate->stencil.func[1] = GL_ALWAYS;
|
||||
//glstate->stencil.f_ref[0] = glstate->stencil.f_ref[1] = 0;
|
||||
glstate->stencil.f_mask[0] = glstate->stencil.f_mask[1] = ~(GLuint)0;
|
||||
glstate->stencil.mask[0] = glstate->stencil.mask[1] = ~(GLuint)0;
|
||||
glstate->stencil.sfail[0] = glstate->stencil.sfail[1] = GL_KEEP;
|
||||
glstate->stencil.dpfail[0] = glstate->stencil.dpfail[1] = GL_KEEP;
|
||||
glstate->stencil.dppass[0] = glstate->stencil.dppass[1] = GL_KEEP;
|
||||
// Color Mask
|
||||
for(int i=0; i<4; i++)
|
||||
glstate->colormask[i] = 1;
|
||||
// Raster
|
||||
for(int i=0; i<4; i++)
|
||||
glstate->raster.raster_scale[i] = 1.0f;
|
||||
// ShadeModel
|
||||
glstate->shademodel = GL_SMOOTH;
|
||||
// TexEnv
|
||||
for (int i=0; i<hardext.maxtex; i++) {
|
||||
glstate->texenv[i].env.mode = GL_MODULATE;
|
||||
glstate->texenv[i].env.rgb_scale = 1.0f;
|
||||
glstate->texenv[i].env.alpha_scale = 1.0f;
|
||||
glstate->texenv[i].env.src0_rgb = glstate->texenv[i].env.src0_alpha = GL_TEXTURE;
|
||||
glstate->texenv[i].env.src1_rgb = glstate->texenv[i].env.src1_alpha = GL_PREVIOUS;
|
||||
glstate->texenv[i].env.src2_rgb = glstate->texenv[i].env.src2_alpha = GL_CONSTANT;
|
||||
glstate->texenv[i].env.op0_rgb = glstate->texenv[i].env.op1_rgb = GL_SRC_COLOR;
|
||||
glstate->texenv[i].env.op2_rgb = glstate->texenv[i].env.op0_alpha =
|
||||
glstate->texenv[i].env.op1_alpha = glstate->texenv[i].env.op2_alpha = GL_SRC_ALPHA;
|
||||
}
|
||||
// TexGen
|
||||
for (int i=0; i<hardext.maxtex; i++) {
|
||||
glstate->texgen[i].S = GL_EYE_LINEAR;
|
||||
glstate->texgen[i].T = GL_EYE_LINEAR;
|
||||
glstate->texgen[i].R = GL_EYE_LINEAR;
|
||||
glstate->texgen[i].Q = GL_EYE_LINEAR;
|
||||
glstate->texgen[i].S_E[0] = 1.0;
|
||||
glstate->texgen[i].S_O[0] = 1.0;
|
||||
glstate->texgen[i].T_E[1] = 1.0;
|
||||
glstate->texgen[i].T_O[1] = 1.0;
|
||||
}
|
||||
|
||||
// fpe
|
||||
if(hardext.esversion>1) {
|
||||
glstate->fpe_state = (fpe_state_t*)calloc(1, sizeof(fpe_state_t));
|
||||
glstate->glsl->es2 = es2only;
|
||||
if(!shared_glstate)
|
||||
fpe_Init(glstate);
|
||||
// some default are not 0...
|
||||
for (int i=0; i<MAX_TEX; i++) {
|
||||
//TexEnv Combine that are not 0
|
||||
glstate->fpe_state->texenv[i].texsrcrgb0 = FPE_SRC_TEXTURE;
|
||||
glstate->fpe_state->texenv[i].texsrcalpha0 = FPE_SRC_TEXTURE;
|
||||
glstate->fpe_state->texenv[i].texsrcrgb1 = FPE_SRC_PREVIOUS;
|
||||
glstate->fpe_state->texenv[i].texsrcalpha1 = FPE_SRC_PREVIOUS;
|
||||
glstate->fpe_state->texenv[i].texsrcrgb2 = FPE_SRC_CONSTANT;
|
||||
glstate->fpe_state->texenv[i].texsrcalpha2 = FPE_SRC_CONSTANT;
|
||||
glstate->fpe_state->texenv[i].texoprgb0 = FPE_OP_SRCCOLOR;
|
||||
glstate->fpe_state->texenv[i].texoprgb1 = FPE_OP_SRCCOLOR;
|
||||
}
|
||||
if(globals4es.shaderblend) {
|
||||
glstate->fpe_state->blendsrcrgb = FPE_BLEND_ONE;
|
||||
glstate->fpe_state->blendsrcalpha = FPE_BLEND_ONE;
|
||||
}
|
||||
}
|
||||
|
||||
// GLSL stuff
|
||||
if(!shared_glstate)
|
||||
{
|
||||
khint_t k;
|
||||
int ret;
|
||||
khash_t(shaderlist) *shaders = glstate->glsl->shaders = kh_init(shaderlist);
|
||||
k = kh_put(shaderlist, shaders, 1, &ret);
|
||||
kh_del(shaderlist, shaders, k);
|
||||
khash_t(programlist) *programs = glstate->glsl->programs = kh_init(programlist);
|
||||
k = kh_put(programlist, programs, 1, &ret);
|
||||
kh_del(programlist, programs, k);
|
||||
}
|
||||
|
||||
// Grab ViewPort & Scissor
|
||||
#if defined(AMIGAOS4) || defined(__EMSCRIPTEN__)
|
||||
if(!def) {// if it's default_glstate, then there is probably no glcontext...
|
||||
#endif
|
||||
LOAD_GLES(glGetIntegerv);
|
||||
gles_glGetIntegerv(GL_VIEWPORT, (GLint*)&glstate->raster.viewport);
|
||||
gles_glGetIntegerv(GL_SCISSOR_BOX, (GLint*)&glstate->raster.scissor);
|
||||
#if defined(AMIGAOS4) || defined(__EMSCRIPTEN__)
|
||||
}
|
||||
#endif
|
||||
// FBO
|
||||
glstate->fbowidth = glstate->fbo.mainfbo_width = glstate->raster.viewport.width;
|
||||
glstate->fboheight = glstate->fbo.mainfbo_height = glstate->raster.viewport.height;
|
||||
glstate->fbo.mainfbo_nwidth = (hardext.npot)?glstate->fbo.mainfbo_width:npot(glstate->fbo.mainfbo_width);
|
||||
glstate->fbo.mainfbo_nheight = (hardext.npot)?glstate->fbo.mainfbo_height:npot(glstate->fbo.mainfbo_height);
|
||||
// add default Renderbuffer
|
||||
if(!shared_glstate)
|
||||
{
|
||||
khint_t k;
|
||||
int ret;
|
||||
khash_t(renderbufferlist_t) *list = glstate->fbo.renderbufferlist = kh_init(renderbufferlist_t);
|
||||
k = kh_put(renderbufferlist_t, list, 0, &ret);
|
||||
glrenderbuffer_t *rend = kh_value(list, k) = calloc(1, sizeof(glrenderbuffer_t));
|
||||
glstate->fbo.default_rb = rend;
|
||||
}
|
||||
// add default Framebuffer
|
||||
if(!shared_glstate)
|
||||
{
|
||||
khint_t k;
|
||||
int ret;
|
||||
khash_t(framebufferlist_t) *list = glstate->fbo.framebufferlist = kh_init(framebufferlist_t);
|
||||
k = kh_put(framebufferlist_t, list, 0, &ret);
|
||||
glframebuffer_t *fb = kh_value(list, k) = calloc(1, sizeof(glframebuffer_t));
|
||||
fb->width = glstate->fbo.mainfbo_width;
|
||||
fb->height = glstate->fbo.mainfbo_height;
|
||||
glstate->fbo.fbo_0 = fb;
|
||||
if(globals4es.recyclefbo) {
|
||||
glstate->fbo.old = (oldfbos_t*)calloc(1, sizeof(oldfbos_t));
|
||||
}
|
||||
}
|
||||
glstate->fbo.current_fb = glstate->fbo.fbo_0;
|
||||
glstate->fbo.current_rb = glstate->fbo.default_rb;
|
||||
glstate->fbo.fbo_read = glstate->fbo.fbo_0;
|
||||
glstate->fbo.fbo_draw = glstate->fbo.fbo_0;
|
||||
// Samplers & queries
|
||||
if(!shared_glstate)
|
||||
{
|
||||
glstate->samplers.samplerlist = kh_init(samplerlist_t);
|
||||
glstate->queries.querylist = kh_init(queries);
|
||||
}
|
||||
glstate->queries.start = get_clock();
|
||||
// Get the per/context hardware values
|
||||
glstate->readf = GL_RGBA;
|
||||
glstate->readt = GL_UNSIGNED_BYTE;
|
||||
#if defined(AMIGAOS4) || defined(__EMSCRIPTEN__)
|
||||
if(!def) // if it's default_glstate, then there is probably no glcontext...
|
||||
{
|
||||
LOAD_GLES(glGetIntegerv);
|
||||
#endif
|
||||
gles_glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, (GLint *) &glstate->readf);
|
||||
gles_glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, (GLint *) &glstate->readt);
|
||||
#if defined(AMIGAOS4) || defined(__EMSCRIPTEN__)
|
||||
}
|
||||
#endif
|
||||
//printf("LIBGL: Implementation Read is %s/%s\n", PrintEnum(glstate->readf), PrintEnum(glstate->readt));
|
||||
|
||||
// All done
|
||||
return (void*)glstate;
|
||||
}
|
||||
|
||||
|
||||
void DeleteGLState(void* oldstate) {
|
||||
glstate_t* state = (glstate_t*)oldstate;
|
||||
if(!state) return;
|
||||
if(state==&default_glstate) return;
|
||||
if(oldstate==DEFAULT_STATE)
|
||||
state = &default_glstate;
|
||||
|
||||
if(state->shared_cnt) {
|
||||
if(!--(*state->shared_cnt)) {
|
||||
free(state->shared_cnt);
|
||||
state->shared_cnt = 0;
|
||||
}
|
||||
}
|
||||
if(globals4es.noclean)
|
||||
return;
|
||||
|
||||
if(glstate == state)
|
||||
glstate = (oldstate==DEFAULT_STATE)?NULL:&default_glstate;
|
||||
|
||||
if(!state->shared_cnt)
|
||||
free(state->actual_tex2d);
|
||||
|
||||
#define free_hashmap(T, N, K, F) \
|
||||
if(state->N) \
|
||||
{ \
|
||||
T *m; \
|
||||
kh_foreach_value(state->N, m, \
|
||||
F(m); \
|
||||
) \
|
||||
kh_destroy(K, state->N); \
|
||||
}
|
||||
free_hashmap(glvao_t, vaos, glvao, free);
|
||||
if(!state->shared_cnt) {
|
||||
free_hashmap(glbuffer_t, buffers, buff, free);
|
||||
free_hashmap(gltexture_t, texture.list, tex, free_texture);
|
||||
free_hashmap(renderlist_t, headlists, gllisthead, free_renderlist);
|
||||
free_hashmap(glrenderbuffer_t, fbo.renderbufferlist, renderbufferlist_t, free_renderbuffer);
|
||||
free_hashmap(glframebuffer_t, fbo.framebufferlist, framebufferlist_t, free_framebuffer);
|
||||
free_hashmap(glsampler_t, samplers.samplerlist, samplerlist_t, free);
|
||||
free_hashmap(glquery_t, queries.querylist, queries, free);
|
||||
}
|
||||
#undef free_hashmap
|
||||
// free texture zero as it's not in the list anymore
|
||||
free(state->texture.zero);
|
||||
// free eval maps
|
||||
#define freemap(dims, name) \
|
||||
{ map_statef_t *m = (map_statef_t *)state->map##dims.name; \
|
||||
if (m) { \
|
||||
free((void *)m->points); \
|
||||
free(m); \
|
||||
} }
|
||||
freemap(1, vertex3); freemap(1, vertex4); freemap(1, index); freemap(1, color4); freemap(1, normal);
|
||||
freemap(1, texture1); freemap(1, texture2); freemap(1, texture3); freemap(1, texture4);
|
||||
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 active list
|
||||
if(!state->shared_cnt && state->list.active) free_renderlist(state->list.active);
|
||||
|
||||
// free matrix stack
|
||||
#define free_matrix(A) \
|
||||
if (state->A) { \
|
||||
free(state->A->stack); \
|
||||
free(state->A); \
|
||||
}
|
||||
free_matrix(projection_matrix);
|
||||
free_matrix(modelview_matrix);
|
||||
for (int i=0; i<MAX_TEX; i++)
|
||||
free_matrix(texture_matrix[i]);
|
||||
free(state->texture_matrix);
|
||||
for (int i=0; i<MAX_ARB_MATRIX; i++)
|
||||
free_matrix(arb_matrix[i]);
|
||||
#undef free_matrix
|
||||
// states stack
|
||||
if(state->stack)
|
||||
free(state->stack);
|
||||
if(state->clientStack)
|
||||
free(state->clientStack);
|
||||
// linestipple
|
||||
if(state->linestipple.data)
|
||||
free(state->linestipple.data);
|
||||
// raster / bitmap
|
||||
if(state->raster.data)
|
||||
free(state->raster.data);
|
||||
if(state->raster.bitmap)
|
||||
free(state->raster.bitmap);
|
||||
// TODO: delete the "immediate" stuff and bitmap texture?
|
||||
// scratch buffer
|
||||
if(state->scratch)
|
||||
free(state->scratch);
|
||||
// merger buffers
|
||||
if(state->merger_master)
|
||||
free(state->merger_master);
|
||||
if(state->merger_secondary)
|
||||
free(state->merger_secondary);
|
||||
for(int a=0; a<MAX_TEX-2; ++a)
|
||||
if(state->merger_tex[a])
|
||||
free(state->merger_tex[a]);
|
||||
// mainfbo
|
||||
if(!state->shared_cnt) {
|
||||
if(state->fbo.mainfbo_fbo)
|
||||
deleteMainFBO(state);
|
||||
}
|
||||
// oldfbos
|
||||
if(!state->shared_cnt && state->fbo.old) {
|
||||
LOAD_GLES2_OR_OES(glDeleteFramebuffers);
|
||||
gles_glDeleteFramebuffers(state->fbo.old->nbr, state->fbo.old->fbos);
|
||||
free(state->fbo.old->fbos);
|
||||
free(state->fbo.old);
|
||||
}
|
||||
// free blit GLES2 stuff
|
||||
if(state->blit) {
|
||||
//TODO: check if should delete GL object too
|
||||
free(state->blit);
|
||||
}
|
||||
if(!state->shared_cnt) {
|
||||
FreeOldProgramMap(state);
|
||||
free(state->glsl);
|
||||
if(state->fpe_cache) {
|
||||
fpe_Dispose(state);
|
||||
}
|
||||
}
|
||||
free(state->gleshard); // Not shared!
|
||||
// get extensions
|
||||
if(state->extensions)
|
||||
free(state->extensions);
|
||||
if(state->extensions_list) {
|
||||
for(int i=0; i<state->num_extensions; ++i)
|
||||
free(state->extensions_list[i]);
|
||||
free(state->extensions_list);
|
||||
}
|
||||
// helper texture adjust
|
||||
for(int i=0; i<MAX_TEX; ++i) {
|
||||
if(state->helper_tex[i])
|
||||
free(state->helper_tex[i]);
|
||||
if(state->texgened[i])
|
||||
free(state->texgened[i]);
|
||||
|
||||
}
|
||||
//TODO: free sharderlist and programlist...
|
||||
|
||||
// probably missing some things to free here!
|
||||
|
||||
// all done
|
||||
if(oldstate!=DEFAULT_STATE)
|
||||
free(state);
|
||||
return;
|
||||
}
|
||||
|
||||
void ActivateGLState(void* new_glstate) {
|
||||
glstate_t *newstate = (new_glstate)?(glstate_t*)new_glstate:&default_glstate;
|
||||
if(glstate == newstate) return; // same state, nothing to do
|
||||
// check if viewport is correct
|
||||
#if defined(AMIGAOS4) || defined(__EMSCRIPTEN__)
|
||||
if(glstate || newstate!=&default_glstate) // avoid getting gles info with no context
|
||||
#endif
|
||||
if(new_glstate && (newstate->raster.viewport.width==0 || newstate->raster.viewport.height==0)) {
|
||||
LOAD_GLES(glGetIntegerv);
|
||||
gles_glGetIntegerv(GL_VIEWPORT, (GLint*)&newstate->raster.viewport);
|
||||
gles_glGetIntegerv(GL_SCISSOR_BOX, (GLint*)&newstate->raster.scissor);
|
||||
}
|
||||
glstate = newstate;
|
||||
}
|
||||
|
||||
void gl_init() {
|
||||
#ifdef GL4ES_COMPILE_FOR_USE_IN_SHARED_LIB
|
||||
glstate=NULL;
|
||||
memset(&default_glstate,0,sizeof(glstate_t));
|
||||
#endif
|
||||
(void)NewGLState(DEFAULT_STATE, 0); // automaticaly fill default_glstate
|
||||
ActivateGLState(&default_glstate);
|
||||
}
|
||||
|
||||
void gl_close() {
|
||||
DeleteGLState(DEFAULT_STATE);
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
#ifndef _GL4ES_GLSTATE_H_
|
||||
#define _GL4ES_GLSTATE_H_
|
||||
|
||||
#include "fog.h"
|
||||
#include "fpe.h"
|
||||
#include "light.h"
|
||||
#include "pointsprite.h"
|
||||
#include "queries.h"
|
||||
#include "stack.h"
|
||||
#include "stencil.h"
|
||||
|
||||
typedef struct glstate_s {
|
||||
int dummy[16]; // dummy zone, test for memory overwriting...
|
||||
displaylist_state_t list;
|
||||
enable_state_t enable;
|
||||
map_grid_t map_grid[2];
|
||||
map_states_t map1, map2;
|
||||
khash_t(gllisthead) *headlists; // shared
|
||||
texgen_state_t texgen[MAX_TEX];
|
||||
texenv_state_t texenv[MAX_TEX];
|
||||
texture_state_t texture;
|
||||
GLboolean colormask[4];
|
||||
int render_mode;
|
||||
int polygon_mode;
|
||||
int clamp_read_color;
|
||||
namestack_t namestack;
|
||||
GLfloat mvp_matrix[16];
|
||||
int mvp_matrix_dirty;
|
||||
GLfloat inv_mv_matrix[16];
|
||||
int inv_mv_matrix_dirty;
|
||||
GLfloat normal_matrix[9];
|
||||
int normal_matrix_dirty;
|
||||
matrixstack_t *modelview_matrix;
|
||||
matrixstack_t *projection_matrix;
|
||||
matrixstack_t **texture_matrix;
|
||||
matrixstack_t **arb_matrix;
|
||||
int matrix_mode;
|
||||
selectbuf_t selectbuf;
|
||||
khash_t(glvao) *vaos;
|
||||
khash_t(buff) *buffers; //shared
|
||||
glvao_t *vao;
|
||||
glbuffer_t *defaultvbo;
|
||||
glvao_t *defaultvao;
|
||||
GLfloat vavalue[MAX_VATTRIB][4]; // the "static" value of a VA
|
||||
GLfloat *vertex; // shortcut to actual vavalue...
|
||||
GLfloat *color;
|
||||
GLfloat *secondary;
|
||||
GLfloat *texcoord[MAX_TEX];
|
||||
GLfloat *normal;
|
||||
GLfloat *fogcoord; // last shortcut
|
||||
int type_error;
|
||||
GLenum shim_error;
|
||||
GLint vp[4];
|
||||
glstack_t *stack;
|
||||
glclientstack_t *clientStack;
|
||||
raster_state_t raster;
|
||||
GLuint *actual_tex2d; // store the texture actually bounded TEX2D unit, because it's shared... (TODO: all binding and not only TEX2D)
|
||||
int bound_changed; // 0 if not changed or max TMU if changed...
|
||||
int fpe_bound_changed; // same but for fpe
|
||||
#ifdef TEXSTREAM
|
||||
int bound_stream[MAX_TEX]; // should be shared too
|
||||
#endif
|
||||
int emulatedPixmap;
|
||||
int emulatedWin;
|
||||
int *shared_cnt;
|
||||
light_state_t light;
|
||||
fog_t fog;
|
||||
material_state_t material;
|
||||
stencil_t stencil;
|
||||
float planes[MAX_CLIP_PLANES][4];
|
||||
pointsprite_t pointsprite;
|
||||
linestipple_t linestipple;
|
||||
GLenum shademodel;
|
||||
GLenum alphafunc;
|
||||
GLfloat alpharef;
|
||||
GLenum logicop;
|
||||
glsl_t *glsl; //shared
|
||||
fpe_state_t *fpe_state;
|
||||
fpe_fpe_t *fpe;
|
||||
fpestatus_t fpe_client;
|
||||
fpe_cache_t *fpe_cache;
|
||||
gleshard_t *gleshard; //shared
|
||||
glesblit_t *blit;
|
||||
fbo_t fbo;
|
||||
int fbowidth, fboheight; // initial size (usefull only on LIBGL_FB=1 or 2)
|
||||
depth_state_t depth;
|
||||
face_state_t face;
|
||||
GLint instanceID;
|
||||
GLint proxy_width;
|
||||
GLint proxy_height;
|
||||
GLint proxy_intformat;
|
||||
// scratch array
|
||||
int scratch_alloc;
|
||||
void* scratch;
|
||||
// glBegin/glEnd merger
|
||||
int merger_cap;
|
||||
GLfloat* merger_master;
|
||||
GLfloat* merger_secondary;
|
||||
GLfloat* merger_tex[MAX_TEX-2];
|
||||
int merger_indice_cap;
|
||||
GLushort* merger_indices;
|
||||
int merger_used;
|
||||
// scratch VBO
|
||||
GLuint scratch_vertex;
|
||||
GLsizei scratch_vertex_size;
|
||||
GLuint scratch_indices;
|
||||
GLsizei scratch_indices_size;
|
||||
// Implementation read
|
||||
GLenum readf; // implementation Read Format
|
||||
GLenum readt; // implementation Read Type
|
||||
// Get extension
|
||||
GLubyte* extensions;
|
||||
int num_extensions;
|
||||
GLubyte** extensions_list;
|
||||
// Texture adjust helper
|
||||
void* helper_tex[MAX_TEX];
|
||||
int helper_texlen[MAX_TEX];
|
||||
GLfloat* texgened[MAX_TEX];
|
||||
int texgenedsz[MAX_TEX];
|
||||
// Sampler
|
||||
samplers_t samplers;
|
||||
// Queries
|
||||
queries_t queries;
|
||||
// Binded buffer (if used)
|
||||
bind_buffers_t bind_buffer;
|
||||
// Blend status
|
||||
float blend_color[4];
|
||||
GLenum blendsfactorrgb;
|
||||
GLenum blenddfactorrgb;
|
||||
GLenum blendsfactoralpha;
|
||||
GLenum blenddfactoralpha;
|
||||
GLenum blendeqrgb;
|
||||
GLenum blendeqalpha;
|
||||
} glstate_t;
|
||||
|
||||
|
||||
#endif // _GL4ES_GLSTATE_H_
|
||||
@@ -0,0 +1,135 @@
|
||||
#include "hint.h"
|
||||
|
||||
#include <gl4eshint.h>
|
||||
#include "init.h"
|
||||
#include "loader.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
|
||||
#ifdef PANDORA
|
||||
void pandora_set_gamma();
|
||||
#endif
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glHint(GLenum pname, GLenum mode) {
|
||||
|
||||
FLUSH_BEGINEND;
|
||||
|
||||
LOAD_GLES(glHint);
|
||||
noerrorShim();
|
||||
switch(pname) {
|
||||
// some Hint are not supported in GLES2, so just ignoring them
|
||||
case GL_FOG_HINT:
|
||||
if(hardext.esversion>1)
|
||||
return;
|
||||
gles_glHint(pname, mode);
|
||||
break;
|
||||
case GL_PERSPECTIVE_CORRECTION_HINT:
|
||||
if(hardext.esversion>1)
|
||||
return;
|
||||
gles_glHint(pname, mode);
|
||||
break;
|
||||
case GL_LINE_SMOOTH_HINT:
|
||||
if(hardext.esversion>1)
|
||||
return;
|
||||
gles_glHint(pname, mode);
|
||||
break;
|
||||
case GL_POINT_SMOOTH_HINT:
|
||||
if(hardext.esversion>1)
|
||||
return;
|
||||
gles_glHint(pname, mode);
|
||||
break;
|
||||
case GL_TEXTURE_COMPRESSION_HINT: // ignore this one
|
||||
// TODO: track setted value
|
||||
return;
|
||||
// specifics GL4ES Hints
|
||||
case GL_SHRINK_HINT_GL4ES:
|
||||
if (mode<=11)
|
||||
globals4es.texshrink = mode;
|
||||
else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_ALPHAHACK_HINT_GL4ES:
|
||||
if (mode<=1)
|
||||
globals4es.alphahack = mode;
|
||||
else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_RECYCLEFBO_HINT_GL4ES:
|
||||
if (mode<=1)
|
||||
globals4es.recyclefbo = mode;
|
||||
else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_MIPMAP_HINT_GL4ES:
|
||||
if (mode<=4)
|
||||
globals4es.automipmap = mode;
|
||||
else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_TEXDUMP_HINT_GL4ES:
|
||||
if (mode<=1)
|
||||
globals4es.texdump = mode;
|
||||
else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_COPY_HINT_GL4ES:
|
||||
if (mode>1) //removed
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_NOLUMAPHA_HINT_GL4ES:
|
||||
if (mode<=1)
|
||||
globals4es.nolumalpha = mode;
|
||||
else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_BLENDHACK_HINT_GL4ES:
|
||||
if (mode<=1)
|
||||
globals4es.blendhack = mode;
|
||||
else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_BATCH_HINT_GL4ES:
|
||||
globals4es.minbatch = 0;
|
||||
globals4es.maxbatch = mode*100;
|
||||
break;
|
||||
case GL_NOERROR_HINT_GL4ES:
|
||||
if (mode<=1)
|
||||
globals4es.noerror = mode;
|
||||
else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_NODOWNSAMPLING_HINT_GL4ES:
|
||||
if (mode<=1)
|
||||
globals4es.nodownsampling = mode;
|
||||
else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_NOVAOCACHE_HINT_GL4ES:
|
||||
if (mode<=1)
|
||||
globals4es.novaocache = mode;
|
||||
else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
case GL_BEGINEND_HINT_GL4ES:
|
||||
if(mode<=2)
|
||||
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;
|
||||
case GL_GAMMA_HINT_GL4ES:
|
||||
globals4es.gamma = ((float)mode)/10.f;
|
||||
#ifdef PANDORA
|
||||
pandora_set_gamma();
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
errorGL();
|
||||
gles_glHint(pname, mode);
|
||||
}
|
||||
}
|
||||
AliasExport(void,glHint,,(GLenum pname, GLenum mode));
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef _GL4ES_HINT_H_
|
||||
#define _GL4ES_HINT_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glHint(GLenum pname, GLenum mode);
|
||||
|
||||
#endif // _GL4ES_HINT_H_
|
||||
@@ -0,0 +1,756 @@
|
||||
#include <stdio.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <direct.h>
|
||||
#define getcwd(a,b) _getcwd(a,b)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#include "../../version.h"
|
||||
#include "../glx/glx_gbm.h"
|
||||
#include "../glx/streaming.h"
|
||||
#include "build_info.h"
|
||||
#include "debug.h"
|
||||
#include "loader.h"
|
||||
#include "logs.h"
|
||||
#include "fpe_cache.h"
|
||||
#include "init.h"
|
||||
#include "envvars.h"
|
||||
#if defined(__EMSCRIPTEN__) || defined(__APPLE__)
|
||||
#define NO_INIT_CONSTRUCTOR
|
||||
#endif
|
||||
|
||||
void gl_init();
|
||||
void gl_close();
|
||||
|
||||
#ifdef GL4ES_COMPILE_FOR_USE_IN_SHARED_LIB
|
||||
#ifdef AMIGAOS4
|
||||
void agl_reset_internals();
|
||||
#endif
|
||||
void fpe_shader_reset_internals();
|
||||
#endif
|
||||
|
||||
globals4es_t globals4es = {0};
|
||||
|
||||
#if defined(PANDORA) || defined(CHIP) || defined(GOA_CLONE)
|
||||
static void fast_math() {
|
||||
// enable Cortex A8 RunFast
|
||||
int v = 0;
|
||||
__asm__ __volatile__ (
|
||||
"vmrs %0, fpscr\n"
|
||||
"orr %0, #((1<<25)|(1<<24))\n" // default NaN, flush-to-zero
|
||||
"vmsr fpscr, %0\n"
|
||||
//"vmrs %0, fpscr\n"
|
||||
: "=&r"(v));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_ES
|
||||
#if defined(PANDORA) || defined(ANDROID)
|
||||
#define DEFAULT_ES 1
|
||||
#else
|
||||
#define DEFAULT_ES 2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void load_libs();
|
||||
void glx_init();
|
||||
|
||||
static int inited = 0;
|
||||
|
||||
EXPORT
|
||||
void set_getmainfbsize(void (APIENTRY_GL4ES *new_getMainFBSize)(int* w, int* h)) {
|
||||
gl4es_getMainFBSize = (void*)new_getMainFBSize;
|
||||
}
|
||||
|
||||
EXPORT
|
||||
void set_getprocaddress(void *(APIENTRY_GL4ES *new_proc_address)(const char *)) {
|
||||
gles_getProcAddress = new_proc_address;
|
||||
}
|
||||
|
||||
#ifdef NO_INIT_CONSTRUCTOR
|
||||
EXPORT
|
||||
#else
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define BUILD_WINDOWS_DLL
|
||||
// dll can't initialize emulator in startup code :(
|
||||
static unsigned char dll_inited;
|
||||
EXPORT
|
||||
#endif
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
__attribute__((constructor(101)))
|
||||
#endif
|
||||
#endif
|
||||
void initialize_gl4es() {
|
||||
#ifdef BUILD_WINDOWS_DLL
|
||||
if(!dll_inited) {
|
||||
LOGE("Windows ES emulator's can't be initialized from DllMain (directX limitation)\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// only init 1 time
|
||||
if(inited++) return;
|
||||
// default init of globals
|
||||
memset(&globals4es, 0, sizeof(globals4es));
|
||||
globals4es.mergelist = 1;
|
||||
globals4es.queries = 1;
|
||||
globals4es.beginend = 1;
|
||||
#ifdef PYRA
|
||||
GetEnvVarInt("LIBGL_DEEPBIND", &globals4es.deepbind, 0);
|
||||
#else
|
||||
GetEnvVarInt("LIBGL_DEEPBIND", &globals4es.deepbind, 1);
|
||||
#endif
|
||||
// overrides by env. variables
|
||||
#ifdef GL4ES_COMPILE_FOR_USE_IN_SHARED_LIB
|
||||
GetEnvVarInt("LIBGL_NOBANNER",&globals4es.nobanner,1);
|
||||
#else
|
||||
globals4es.nobanner = IsEnvVarTrue("LIBGL_NOBANNER");
|
||||
#endif
|
||||
|
||||
SHUT_LOGD("Initialising gl4es\n");
|
||||
|
||||
if(!globals4es.nobanner) print_build_infos();
|
||||
|
||||
#define env(name, global, message) \
|
||||
if(IsEnvVarTrue(#name)) {\
|
||||
SHUT_LOGD(message "\n"); \
|
||||
global = true; \
|
||||
}
|
||||
|
||||
env(LIBGL_XREFRESH, globals4es.xrefresh, "xrefresh will be called on cleanup");
|
||||
env(LIBGL_STACKTRACE, globals4es.stacktrace, "stacktrace will be printed on crash");
|
||||
|
||||
|
||||
switch(ReturnEnvVarInt("LIBGL_FB")) {
|
||||
case 1:
|
||||
SHUT_LOGD("framebuffer output enabled\n");
|
||||
globals4es.usefb = 1;
|
||||
break;
|
||||
case 2:
|
||||
SHUT_LOGD("using framebuffer + fbo\n");
|
||||
globals4es.usefb = 1;
|
||||
globals4es.usefbo = 1;
|
||||
break;
|
||||
#ifndef NOX11
|
||||
case 3:
|
||||
SHUT_LOGD("using pbuffer\n");
|
||||
globals4es.usefb = 0;
|
||||
globals4es.usepbuffer = 1;
|
||||
break;
|
||||
#endif
|
||||
case 4:
|
||||
#ifdef NO_GBM
|
||||
SHUT_LOGD("GBM support not built, cannot use it\n");
|
||||
#else
|
||||
SHUT_LOGD("using GBM\n");
|
||||
globals4es.usefb = 0;
|
||||
globals4es.usegbm = 1;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
env(LIBGL_BLITFB0, globals4es.blitfb0, "Blit to FB 0 force a SwapBuffer");
|
||||
env(LIBGL_FPS, globals4es.showfps, "fps counter enabled");
|
||||
#if defined(USE_FBIO) || defined(PYRA)
|
||||
env(LIBGL_VSYNC, globals4es.vsync, "vsync enabled");
|
||||
#endif
|
||||
#ifdef PANDORA
|
||||
if(GetEnvVarFloat("LIBGL_GAMMA",&globals4es.gamma,0.0f)) {
|
||||
SHUT_LOGD("Set gamma to %.2f\n", globals4es.gamma);
|
||||
}
|
||||
#endif
|
||||
env(LIBGL_NOBGRA, globals4es.nobgra, "Ignore BGRA texture capability");
|
||||
env(LIBGL_NOTEXRECT, globals4es.notexrect, "Don't export Text Rectangle extension");
|
||||
if(globals4es.usefbo) {
|
||||
env(LIBGL_FBONOALPHA, globals4es.fbo_noalpha, "Main FBO has no alpha channel");
|
||||
}
|
||||
|
||||
globals4es.es=ReturnEnvVarInt("LIBGL_ES");
|
||||
switch(globals4es.es) {
|
||||
case 1:
|
||||
case 2:
|
||||
break;
|
||||
default:
|
||||
// automatic ES backend selection
|
||||
globals4es.es = DEFAULT_ES;
|
||||
break;
|
||||
}
|
||||
|
||||
globals4es.gl=ReturnEnvVarInt("LIBGL_GL");
|
||||
switch(globals4es.gl) {
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 20:
|
||||
case 21:
|
||||
case 30:
|
||||
case 31:
|
||||
case 32:
|
||||
case 33:
|
||||
case 40:
|
||||
case 41:
|
||||
case 42:
|
||||
case 43:
|
||||
case 44:
|
||||
case 45:
|
||||
break;
|
||||
default:
|
||||
// automatic GL version selection
|
||||
globals4es.gl = (globals4es.es==1)?15:21; // forcing GL 1.5 for es1.1 and GL 2.1 for es2.0
|
||||
break;
|
||||
}
|
||||
|
||||
SHUT_LOGD("Using GLES %s backend\n", (globals4es.es==1)?"1.1":"2.0");
|
||||
|
||||
env(LIBGL_NODEPTHTEX, globals4es.nodepthtex, "Disable usage of Depth Textures");
|
||||
|
||||
const char* env_drmcard = GetEnvVar("LIBGL_DRMCARD");
|
||||
if(env_drmcard) {
|
||||
#ifdef NO_GBM
|
||||
SHUT_LOGD("Warning, GBM not compiled in, cannot use LIBGL_DRMCARD\n");
|
||||
#else
|
||||
strncpy(globals4es.drmcard, env_drmcard, 50);
|
||||
} else {
|
||||
strcpy(globals4es.drmcard, "/dev/dri/card0");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(__APPLE__)
|
||||
load_libs();
|
||||
#endif
|
||||
|
||||
#if (defined(NOEGL) && !defined(ANDROID) && !defined(__APPLE__)) || defined(__EMSCRIPTEN__)
|
||||
int gl4es_notest = !gles_getProcAddress;
|
||||
#else
|
||||
int gl4es_notest = IsEnvVarTrue("LIBGL_NOTEST");
|
||||
#endif
|
||||
env(LIBGL_NOHIGHP, globals4es.nohighp, "Do not use HIGHP in fragment shader even if detected");
|
||||
|
||||
globals4es.floattex=ReturnEnvVarIntDef("LIBGL_FLOAT", 1);
|
||||
switch(globals4es.floattex) {
|
||||
case 0:
|
||||
SHUT_LOGD("Float and Half-Float texture support disabled\n");
|
||||
break;
|
||||
case 2:
|
||||
SHUT_LOGD("Float and Half-float texture support forced\n");
|
||||
break;
|
||||
default:
|
||||
globals4es.floattex = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
GetHardwareExtensions(gl4es_notest);
|
||||
|
||||
#if !defined(NO_LOADER) && !defined(NO_GBM)
|
||||
if(globals4es.usegbm)
|
||||
LoadGBMFunctions();
|
||||
if(globals4es.usegbm && !(gbm && drm)) {
|
||||
SHUT_LOGD("cannot use GBM, disabling\n");
|
||||
globals4es.usegbm = 0; // should do some smarter fallback?
|
||||
}
|
||||
#else
|
||||
globals4es.usegbm = 0;
|
||||
#endif
|
||||
#if !defined(NOX11)
|
||||
glx_init();
|
||||
#endif
|
||||
|
||||
gl_init();
|
||||
|
||||
#ifdef GL4ES_COMPILE_FOR_USE_IN_SHARED_LIB
|
||||
fpe_shader_reset_internals();
|
||||
#ifdef AMIGAOS4
|
||||
agl_reset_internals();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
env(LIBGL_RECYCLEFBO, globals4es.recyclefbo, "Recycling of FBO enabled");
|
||||
|
||||
// Texture hacks
|
||||
globals4es.automipmap=ReturnEnvVarInt("LIBGL_MIPMAP");
|
||||
switch(globals4es.automipmap) {
|
||||
case 1:
|
||||
SHUT_LOGD("AutoMipMap forced\n");
|
||||
break;
|
||||
case 2:
|
||||
SHUT_LOGD("guess AutoMipMap\n");
|
||||
break;
|
||||
case 3:
|
||||
SHUT_LOGD("ignore MipMap\n");
|
||||
break;
|
||||
case 4:
|
||||
SHUT_LOGD("ignore AutoMipMap on non-squared textures\n");
|
||||
break;
|
||||
case 5:
|
||||
SHUT_LOGD("Calculate sub-mipmap in case some are missing\n");
|
||||
break;
|
||||
default:
|
||||
globals4es.automipmap = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(IsEnvVarTrue("LIBGL_TEXCOPY")) {
|
||||
globals4es.texcopydata = 1;
|
||||
SHUT_LOGD("Texture copy enabled\n");
|
||||
}
|
||||
|
||||
globals4es.texshrink=ReturnEnvVarInt("LIBGL_SHRINK");
|
||||
switch(globals4es.texshrink) {
|
||||
case 10:
|
||||
SHUT_LOGD("Texture shrink, mode 10 selected (advertise 8192 max texture size, but >2048 are quadshrinked and > 512 are shrinked), but not for empty textures\n");
|
||||
break;
|
||||
case 11:
|
||||
SHUT_LOGD("Texture shrink, mode 11 selected (advertise a max texture size *2, but every texture with one dimension > max texture size will get shrinked to max texture size), but not for empty textures\n");
|
||||
break;
|
||||
case 1:
|
||||
SHUT_LOGD("Texture shrink, mode 1 selected (everything / 2)\n");
|
||||
break;
|
||||
case 2:
|
||||
SHUT_LOGD("Texture shrink, mode 2 selected (only > 512 /2 )\n");
|
||||
break;
|
||||
case 3:
|
||||
SHUT_LOGD("Texture shrink, mode 3 selected (only > 256 /2 )\n");
|
||||
break;
|
||||
case 4:
|
||||
SHUT_LOGD("Texture shrink, mode 4 selected (only > 256 /2, >=1024 /4 )\n");
|
||||
break;
|
||||
case 5:
|
||||
SHUT_LOGD("Texture shrink, mode 5 selected (every > 256 is downscaled to 256 ), but not for empty textures\n");
|
||||
break;
|
||||
case 6:
|
||||
SHUT_LOGD("Texture shrink, mode 6 selected (only > 128 /2, >=512 is downscaled to 256 ), but not for empty textures\n");
|
||||
break;
|
||||
case 7:
|
||||
SHUT_LOGD("Texture shrink, mode 7 selected (only > 512 /2 ), but not for empty textures\n");
|
||||
break;
|
||||
case 8:
|
||||
SHUT_LOGD("Texture shrink, mode 8 selected (advertise 8192 max texture size, but >2048 are shrinked to 2048)\n");
|
||||
break;
|
||||
case 9:
|
||||
SHUT_LOGD("Texture shrink, mode 9 selected (advertise 8192 max texture size, but >4096 are quadshrinked and > 512 are shrinked), but not for empty textures\n");
|
||||
break;
|
||||
default:
|
||||
globals4es.texshrink=0;
|
||||
break;
|
||||
}
|
||||
|
||||
env(LIBGL_TEXDUMP, globals4es.texdump, "Texture dump enabled");
|
||||
env(LIBGL_ALPHAHACK, globals4es.alphahack, "Alpha Hack enabled");
|
||||
|
||||
#ifdef TEXSTREAM
|
||||
switch(ReturnEnvVarInt("LIBGL_STREAM")) {
|
||||
case 1:
|
||||
globals4es.texstream = InitStreamingCache();
|
||||
SHUT_LOGD("Streaming texture %s\n",(globals4es.texstream)?"enabled":"not available");
|
||||
//FreeStreamed(AddStreamed(1024, 512, 0));
|
||||
break;
|
||||
case 2:
|
||||
globals4es.texstream = InitStreamingCache()?2:0;
|
||||
SHUT_LOGD("Streaming texture %s\n",(globals4es.texstream)?"forced":"not available");
|
||||
//FreeStreamed(AddStreamed(1024, 512, 0));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
env(LIBGL_NOLUMALPHA, globals4es.nolumalpha, "GL_LUMINANCE_ALPHA hardware support disabled");
|
||||
env(LIBGL_BLENDHACK, globals4es.blendhack, "Change Blend GL_SRC_ALPHA, GL_ONE to GL_ONE, GL_ONE");
|
||||
env(LIBGL_BLENDCOLOR, globals4es.blendcolor, "Export a (faked) glBlendColor");
|
||||
env(LIBGL_NOERROR, globals4es.noerror, "glGetError() always return GL_NOERROR");
|
||||
|
||||
globals4es.silentstub = 1;
|
||||
if(IsEnvVarInt("LIBGL_SILENTSTUB",0)) {
|
||||
globals4es.silentstub = 0;
|
||||
SHUT_LOGD("Stub/non present functions are printed");
|
||||
}
|
||||
|
||||
env(LIBGL_VABGRA, globals4es.vabgra, "Export GL_ARB_vertex_array_bgra extension");
|
||||
|
||||
const char *env_version = GetEnvVar("LIBGL_VERSION");
|
||||
if (env_version) {
|
||||
SHUT_LOGD("Override version string with \"%s\" (should be in the form of \"1.x\")\n", env_version);
|
||||
}
|
||||
if(env_version) {
|
||||
snprintf(globals4es.version, 49, "%s gl4es wrapper %d.%d.%d", env_version, MAJOR, MINOR, REVISION);
|
||||
SHUT_LOGD("Targeting OpenGL %s\n", env_version);
|
||||
} else {
|
||||
snprintf(globals4es.version, 49, "%d.%d gl4es wrapper %d.%d.%d", globals4es.gl/10, globals4es.gl%10, MAJOR, MINOR, REVISION);
|
||||
SHUT_LOGD("Targeting OpenGL %d.%d\n", globals4es.gl/10, globals4es.gl%10);
|
||||
}
|
||||
|
||||
if(hardext.srgb && IsEnvVarTrue("LIBGL_SRGB")) {
|
||||
globals4es.glx_surface_srgb = 2;
|
||||
SHUT_LOGD("enabling sRGB support\n");
|
||||
}
|
||||
|
||||
if(IsEnvVarTrue("LIBGL_FASTMATH")) {
|
||||
#if defined(PANDORA) || defined(CHIP) || defined(GOA_CLONE)
|
||||
SHUT_LOGD("Enable FastMath for cortex-a8\n");
|
||||
fast_math();
|
||||
#else
|
||||
SHUT_LOGD("No FastMath on this platform\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
switch(hardext.npot) {
|
||||
case 0: globals4es.npot = 0; break;
|
||||
case 1:
|
||||
case 2: globals4es.npot = 1; break;
|
||||
case 3: globals4es.npot = 2; break;
|
||||
}
|
||||
switch(ReturnEnvVarInt("LIBGL_NPOT")) {
|
||||
case 1:
|
||||
if(globals4es.npot<1) {
|
||||
globals4es.npot = 1;
|
||||
SHUT_LOGD("Expose limited NPOT extension\n");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(globals4es.npot<3) {
|
||||
globals4es.npot = 2;
|
||||
SHUT_LOGD("Expose GL_ARB_texture_non_power_of_two extension\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(IsEnvVarFalse("LIBGL_GLQUERIES")) {
|
||||
globals4es.queries = 0;
|
||||
SHUT_LOGD("Don't expose fake glQueries functions\n");
|
||||
}
|
||||
if(IsEnvVarTrue("LIBGL_NODOWNSAMPLING")) {
|
||||
globals4es.nodownsampling = 1;
|
||||
SHUT_LOGD("No downsampling of DXTc textures\n");
|
||||
}
|
||||
env(LIBGL_NOTEXMAT, globals4es.texmat, "Don't handle Texture Matrice internally");
|
||||
env(LIBGL_NOVAOCACHE, globals4es.novaocache, "Don't use VAO cache");
|
||||
if(IsEnvVarTrue("LIBGL_NOINTOVLHACK")) {
|
||||
globals4es.nointovlhack = 1;
|
||||
SHUT_LOGD("No hack in shader converter to define overloaded function with int\n");
|
||||
}
|
||||
if(IsEnvVarTrue("LIBGL_NOSHADERLOD")) {
|
||||
globals4es.noshaderlod = 1;
|
||||
SHUT_LOGD("No GL_EXT_shader_texture_lod used even if present\n");
|
||||
hardext.shaderlod=0;
|
||||
}
|
||||
|
||||
int env_begin_end;
|
||||
if(GetEnvVarInt("LIBGL_BEGINEND",&env_begin_end,0)) {
|
||||
switch(env_begin_end) {
|
||||
case 0:
|
||||
globals4es.beginend = 0;
|
||||
globals4es.mergelist = 0;
|
||||
SHUT_LOGD("Don't try to merge subsequent glBegin/glEnd blocks\n");
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
globals4es.beginend = 1;
|
||||
SHUT_LOGD("Try to merge subsequent glBegin/glEnd blocks, even if there is a glColor / glNormal in between\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(GetEnvVarBool("LIBGL_AVOID16BITS", &globals4es.avoid16bits, (hardext.vendor&VEND_IMGTEC)?0:1)) {
|
||||
if(globals4es.avoid16bits) {
|
||||
SHUT_LOGD("Avoid 16bits textures\n");
|
||||
} else {
|
||||
SHUT_LOGD("Don't avoid 16bits textures\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(GetEnvVarInt("LIBGL_AVOID24BITS",&globals4es.avoid24bits,0)) {
|
||||
switch(globals4es.avoid24bits) {
|
||||
case 0:
|
||||
SHUT_LOGD("Don't try to avoid 24bits textures\n");
|
||||
break;
|
||||
case 1:
|
||||
globals4es.avoid24bits = 2;
|
||||
SHUT_LOGD("Avoid 24bits textures\n");
|
||||
break;
|
||||
default:
|
||||
globals4es.avoid24bits = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
env(LIBGL_FORCE16BITS, globals4es.force16bits, "Force 16bits textures");
|
||||
env(LIBGL_POTFRAMEBUFFER, globals4es.potframebuffer, "Force framebuffers to be on POT size");
|
||||
|
||||
int env_forcenpot=ReturnEnvVarIntDef("LIBGL_FORCENPOT",0);
|
||||
if(env_forcenpot==0 && (hardext.esversion==2 && (hardext.npot==1 || hardext.npot==2))) {
|
||||
SHUT_LOGD("Not forcing NPOT support\n");
|
||||
} else if(env_forcenpot!=0 || (hardext.esversion==2 && (hardext.npot==1 || hardext.npot==2))) {
|
||||
if(hardext.npot==3) {
|
||||
SHUT_LOGD("NPOT texture handled in hardware\n");
|
||||
} else if(hardext.npot==1) {
|
||||
globals4es.forcenpot = 1;
|
||||
SHUT_LOGD("Forcing NPOT support by disabling MIPMAP support for NPOT textures\n");
|
||||
} else {
|
||||
SHUT_LOGD("WARNING, No Limited or Full NPOT support in hardware, Forcing NPOT has no effect!\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(GL4ES_COMPILE_FOR_USE_IN_SHARED_LIB) && defined(AMIGAOS4) // temporary workaround for not-working envs
|
||||
globals4es.maxbatch = 40;
|
||||
#else
|
||||
globals4es.maxbatch = 0;
|
||||
#endif
|
||||
globals4es.minbatch = 0;
|
||||
int tmp = 0, tmp2 = 0;
|
||||
switch(GetEnvVarFmt("LIBGL_BATCH","%d-%d",&tmp,&tmp2)) {
|
||||
case 2:
|
||||
globals4es.maxbatch = tmp2;
|
||||
globals4es.minbatch = tmp;
|
||||
if(globals4es.minbatch>globals4es.maxbatch) {
|
||||
globals4es.maxbatch = tmp;
|
||||
globals4es.minbatch = tmp2;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
globals4es.maxbatch = 10*10*tmp;
|
||||
globals4es.minbatch = 0;
|
||||
break;
|
||||
}
|
||||
if(globals4es.maxbatch==0) {
|
||||
SHUT_LOGD("Not trying to batch small subsequent glDrawXXXX\n");
|
||||
} else {
|
||||
SHUT_LOGD("Trying to batch subsequent glDrawXXXX of size between %d and %d vertices\n", globals4es.minbatch, globals4es.maxbatch);
|
||||
}
|
||||
|
||||
if(hardext.esversion==1) globals4es.usevbo=0; // VBO on ES1.1 backend will be too messy, so disabling
|
||||
else {
|
||||
globals4es.usevbo = ReturnEnvVarIntDef("LIBGL_USEVBO",1);
|
||||
switch(globals4es.usevbo) {
|
||||
case 0:
|
||||
SHUT_LOGD("Use of VBO disabled\n");
|
||||
break;
|
||||
case 1:
|
||||
SHUT_LOGD("Trying to use VBO\n");
|
||||
break;
|
||||
case 2:
|
||||
SHUT_LOGD("Trying to use VBO (also with glLockArrays)\n");
|
||||
break;
|
||||
case 3:
|
||||
SHUT_LOGD("Trying to use VBO (special glLockArrays case for idtech3 engine)\n");
|
||||
break;
|
||||
default:
|
||||
globals4es.usevbo=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
globals4es.fbomakecurrent = 0;
|
||||
if((hardext.vendor & VEND_ARM) || (globals4es.usefb))
|
||||
globals4es.fbomakecurrent = 1;
|
||||
switch(ReturnEnvVarIntDef("LIBGL_FBOMAKECURRENT",-1)) {
|
||||
case 0:
|
||||
if(globals4es.fbomakecurrent) {
|
||||
globals4es.fbomakecurrent = 0;
|
||||
SHUT_LOGD("glXMakeCurrent FBO workaround disabled\n");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
globals4es.fbomakecurrent = 1;
|
||||
break;
|
||||
}
|
||||
if(globals4es.fbomakecurrent) {
|
||||
SHUT_LOGD("glXMakeCurrent FBO workaround enabled\n");
|
||||
}
|
||||
|
||||
|
||||
globals4es.fbounbind = 0;
|
||||
if((hardext.vendor & VEND_ARM) || (hardext.vendor & VEND_IMGTEC))
|
||||
globals4es.fbounbind = 1;
|
||||
switch(ReturnEnvVarIntDef("LIBGL_FBOUNBIND",-1)) {
|
||||
case 0:
|
||||
if(globals4es.fbounbind) {
|
||||
globals4es.fbounbind = 0;
|
||||
SHUT_LOGD("FBO workaround for using binded texture disabled\n");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
globals4es.fbounbind = 1;
|
||||
break;
|
||||
}
|
||||
if(globals4es.fbounbind) {
|
||||
SHUT_LOGD("FBO workaround for using binded texture enabled\n");
|
||||
}
|
||||
|
||||
globals4es.fboforcetex = 1;
|
||||
GetEnvVarInt("LIBGL_FBOFORCETEX", &globals4es.fboforcetex, globals4es.fboforcetex);
|
||||
if(globals4es.fboforcetex)
|
||||
SHUT_LOGD("Force texture for Attachment color0 on FBO\n");
|
||||
globals4es.blitfullscreen = 1;
|
||||
GetEnvVarInt("LIBGL_BLITFULLSCREEN", &globals4es.blitfullscreen, globals4es.blitfullscreen);
|
||||
if(globals4es.blitfullscreen)
|
||||
SHUT_LOGD("Hack to trigger a SwapBuffers when a Full Framebuffer Blit on default FBO is done\n");
|
||||
|
||||
env(LIBGL_COMMENTS, globals4es.comments, "Keep comments in converted Shaders");
|
||||
|
||||
env(LIBGL_NOARBPROGRAM, globals4es.noarbprogram, "Not exposing ARB Program extensions");
|
||||
|
||||
if(hardext.npot==3)
|
||||
globals4es.defaultwrap=0;
|
||||
else
|
||||
globals4es.defaultwrap=1;
|
||||
|
||||
if(GetEnvVarInt("LIBGL_DEFAULTWRAP",&globals4es.defaultwrap,(hardext.npot==3) ? 0 : 1)) {
|
||||
switch(globals4es.defaultwrap) {
|
||||
case 0:
|
||||
SHUT_LOGD("Default wrap mode is GL_REPEAT\n");
|
||||
break;
|
||||
case 1:
|
||||
SHUT_LOGD("Default wrap mode is GL_CLAMP_TO_EDGE\n");
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
globals4es.defaultwrap=2;
|
||||
SHUT_LOGD("Default wrap mode is GL_CLAMP_TO_EDGE, enforced\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GetEnvVarBool("LIBGL_NOTEXARRAY",&globals4es.notexarray,0);
|
||||
if(globals4es.notexarray) {
|
||||
SHUT_LOGD("No Texture Array in Shaders\n");
|
||||
}
|
||||
|
||||
env(LIBGL_LOGSHADERERROR, globals4es.logshader, "Log errors compiling shaders to the console");
|
||||
env(LIBGL_SHADERNOGLES, globals4es.shadernogles, "Remove GLES part in shader");
|
||||
env(LIBGL_NOES2COMPAT, globals4es.noes2, "Don't expose GLX_EXT_create_context_es2_profile extension");
|
||||
env(LIBGL_NORMALIZE, globals4es.normalize, "Force normals to be normalized on FPE shaders");
|
||||
|
||||
globals4es.dbgshaderconv=ReturnEnvVarIntDef("LIBGL_DBGSHADERCONV",0);
|
||||
if(globals4es.dbgshaderconv) {
|
||||
if(globals4es.dbgshaderconv==1)
|
||||
globals4es.dbgshaderconv=15;
|
||||
if(!(globals4es.dbgshaderconv&3)) // neither vertex or fragment
|
||||
globals4es.dbgshaderconv|=3; // select both
|
||||
if(!(globals4es.dbgshaderconv&12)) // neither before or after
|
||||
globals4es.dbgshaderconv|=12; // select both
|
||||
SHUT_LOGD_NOPREFIX("Log all shaders, before and after conversion, to the console: ");
|
||||
if(globals4es.dbgshaderconv&4)
|
||||
SHUT_LOGD_NOPREFIX("Before ");
|
||||
if(globals4es.dbgshaderconv&8)
|
||||
SHUT_LOGD_NOPREFIX("After ");
|
||||
if(globals4es.dbgshaderconv&1)
|
||||
SHUT_LOGD_NOPREFIX("Vertex ");
|
||||
if(globals4es.dbgshaderconv&2)
|
||||
SHUT_LOGD_NOPREFIX("Fragment ");
|
||||
SHUT_LOGD_NOPREFIX("\n");
|
||||
}
|
||||
|
||||
env(LIBGL_NOCLEAN, globals4es.noclean, "Don't clean Context when destroyed");
|
||||
|
||||
globals4es.glxrecycle = 1;
|
||||
#ifndef NOEGL
|
||||
if((globals4es.usepbuffer) || (globals4es.usefb))
|
||||
globals4es.glxrecycle = 0;
|
||||
|
||||
int env_glxrecycle=ReturnEnvVarIntDef("LIBGL_GLXRECYCLE",-1);
|
||||
if(globals4es.glxrecycle && env_glxrecycle==0 && !((globals4es.usepbuffer) || (globals4es.usefb))) {
|
||||
globals4es.glxrecycle = 0;
|
||||
SHUT_LOGD("glX Will NOT try to recycle EGL Surface\n");
|
||||
}
|
||||
if(env_glxrecycle==1)
|
||||
globals4es.glxrecycle = 1;
|
||||
if(globals4es.glxrecycle) {
|
||||
SHUT_LOGD("glX Will try to recycle EGL Surface\n");
|
||||
}
|
||||
env(LIBGL_GLXNATIVE, globals4es.glxnative, "Don't filter GLXConfig with GLX_X_NATIVE_TYPE");
|
||||
#endif
|
||||
char cwd[4096];
|
||||
if (getcwd(cwd, sizeof(cwd))!= NULL)
|
||||
SHUT_LOGD("Current folder is:%s\n", cwd);
|
||||
|
||||
if(hardext.shader_fbfetch) {
|
||||
env(LIBGL_SHADERBLEND, globals4es.shaderblend, "Blend will be handled in shaders");
|
||||
}
|
||||
if(hardext.prgbin_n>0 && !globals4es.notexarray) {
|
||||
env(LIBGL_NOPSA, globals4es.nopsa, "Don't use PrecompiledShaderArchive");
|
||||
if(globals4es.nopsa==0) {
|
||||
cwd[0]='\0';
|
||||
// TODO: What to do on ANDROID and EMSCRIPTEN?
|
||||
const char* custom_psa = GetEnvVar("LIBGL_PSA_FOLDER");
|
||||
#ifdef __linux__
|
||||
const char* home = GetEnvVar("HOME");
|
||||
if(custom_psa)
|
||||
strcpy(cwd, custom_psa);
|
||||
else if(home)
|
||||
strcpy(cwd, home);
|
||||
if(strlen(cwd))
|
||||
if(cwd[strlen(cwd)]!='/')
|
||||
strcat(cwd, "/");
|
||||
#elif defined AMIGAOS4
|
||||
if(custom_psa)
|
||||
strcpy(cwd, custom_psa);
|
||||
else
|
||||
strcpy(cwd, "PROGDIR:");
|
||||
#endif
|
||||
if(strlen(cwd)) {
|
||||
strcat(cwd, ".gl4es.psa");
|
||||
fpe_InitPSA(cwd);
|
||||
fpe_readPSA();
|
||||
}
|
||||
}
|
||||
} else
|
||||
SHUT_LOGD("Not using PSA (prgbin_n=%d, notexarray=%d)\n", hardext.prgbin_n, globals4es.notexarray);
|
||||
|
||||
env(LIBGL_SKIPTEXCOPIES, globals4es.skiptexcopies, "Texture Copies will be skipped");
|
||||
if(GetEnvVarFloat("LIBGL_FB_TEX_SCALE",&globals4es.fbtexscale,0.0f)) {
|
||||
SHUT_LOGD("Framebuffer Textures will be scaled by %.2f\n", globals4es.fbtexscale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef NOX11
|
||||
void FreeFBVisual();
|
||||
#endif
|
||||
#ifdef NO_INIT_CONSTRUCTOR
|
||||
EXPORT
|
||||
#else
|
||||
#ifdef BUILD_WINDOWS_DLL
|
||||
EXPORT // symmetric for init -- trivialize application code
|
||||
#endif
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
__attribute__((destructor))
|
||||
#endif
|
||||
#endif
|
||||
void close_gl4es() {
|
||||
#ifdef GL4ES_COMPILE_FOR_USE_IN_SHARED_LIB
|
||||
SHUT_LOGD("Shutdown requested\n");
|
||||
if(--inited) return;
|
||||
#endif
|
||||
SHUT_LOGD("Shutting down\n");
|
||||
#ifndef NOX11
|
||||
FreeFBVisual();
|
||||
#endif
|
||||
gl_close();
|
||||
fpe_writePSA();
|
||||
fpe_FreePSA();
|
||||
#if defined(GL4ES_COMPILE_FOR_USE_IN_SHARED_LIB) && defined(AMIGAOS4)
|
||||
os4CloseLib();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BUILD_WINDOWS_DLL
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
__attribute__((constructor(103)))
|
||||
#endif
|
||||
void dll_init_done()
|
||||
{ dll_inited = 1; }
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(NO_INIT_CONSTRUCTOR) && !defined(__clang__)
|
||||
#pragma const_seg(".CRT$XCU")
|
||||
void (*const gl4es_ctors[])() = { initialize_gl4es, dll_init_done };
|
||||
#pragma const_seg(".CRT$XTX")
|
||||
void (*const gl4es_dtor)() = close_gl4es;
|
||||
#pragma const_seg()
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
#ifndef _GL4ES_INIT_H_
|
||||
#define _GL4ES_INIT_H_
|
||||
|
||||
#if defined(PANDORA)
|
||||
#define USE_FBIO 1
|
||||
#endif
|
||||
|
||||
typedef struct _globals4es {
|
||||
int nobanner;
|
||||
int mergelist;
|
||||
int xrefresh;
|
||||
int stacktrace;
|
||||
int usefb;
|
||||
int usegbm;
|
||||
int usefbo;
|
||||
int recyclefbo;
|
||||
int usepbuffer;
|
||||
int showfps;
|
||||
int vsync;
|
||||
int automipmap;
|
||||
int texcopydata;
|
||||
int tested_env;
|
||||
int texshrink;
|
||||
int texdump;
|
||||
int alphahack;
|
||||
int texstream;
|
||||
int nolumalpha;
|
||||
int blendhack;
|
||||
int blendcolor;
|
||||
int noerror;
|
||||
int npot;
|
||||
int defaultwrap;
|
||||
int notexrect;
|
||||
int queries;
|
||||
int silentstub;
|
||||
int glx_surface_srgb;
|
||||
int nodownsampling;
|
||||
int vabgra;
|
||||
int nobgra;
|
||||
int potframebuffer;
|
||||
float gamma;
|
||||
int texmat;
|
||||
int novaocache;
|
||||
int beginend;
|
||||
int avoid16bits;
|
||||
int avoid24bits;
|
||||
int force16bits;
|
||||
int nohighp;
|
||||
int minbatch;
|
||||
int maxbatch;
|
||||
int es;
|
||||
int gl;
|
||||
int usevbo;
|
||||
int comments;
|
||||
int forcenpot;
|
||||
int fbomakecurrent; // hack to bind/unbind FBO when doing glXMakeCurrent
|
||||
int fbounbind; // hack to bind/unbind fbo if a bind texture is used for drawing
|
||||
int fboforcetex; // force texture attachment for Color0
|
||||
int blitfullscreen; // a "fullscreen" blit to FB0 means SwapBuffers
|
||||
int notexarray;
|
||||
int nodepthtex;
|
||||
int logshader;
|
||||
int shadernogles;
|
||||
int floattex;
|
||||
int glxrecycle;
|
||||
int noclean;
|
||||
int dbgshaderconv;
|
||||
int nopsa;
|
||||
int noes2;
|
||||
int nointovlhack;
|
||||
int noshaderlod;
|
||||
int fbo_noalpha;
|
||||
int noarbprogram; // to disable ARB Program
|
||||
int glxnative;
|
||||
int normalize; // force normal normalization (workaround a bug)
|
||||
int blitfb0;
|
||||
int skiptexcopies;
|
||||
int shaderblend;
|
||||
int deepbind;
|
||||
float fbtexscale;
|
||||
#ifndef NO_GBM
|
||||
char drmcard[50];
|
||||
#endif
|
||||
char version[50];
|
||||
} globals4es_t;
|
||||
|
||||
extern globals4es_t globals4es;
|
||||
|
||||
#endif // _GL4ES_INIT_H_
|
||||
@@ -0,0 +1,441 @@
|
||||
#include "light.h"
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "fpe.h"
|
||||
#include "loader.h"
|
||||
#include "matrix.h"
|
||||
#include "matvec.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glLightModelf(GLenum pname, GLfloat param) {
|
||||
//printf("%sglLightModelf(%04X, %.2f)\n", (state.list.compiling)?"list":"", pname, param);
|
||||
ERROR_IN_BEGIN
|
||||
if(glstate->list.active)
|
||||
if ((glstate->list.compiling)) {
|
||||
GLfloat dummy[4];
|
||||
dummy[0]=param;
|
||||
gl4es_glLightModelfv(pname, dummy);
|
||||
return;
|
||||
} else gl4es_flush();
|
||||
switch (pname) {
|
||||
case GL_LIGHT_MODEL_TWO_SIDE:
|
||||
errorGL();
|
||||
glstate->light.two_side = param;
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->twosided = param;
|
||||
break;
|
||||
case GL_LIGHT_MODEL_COLOR_CONTROL:
|
||||
if(param!=GL_SINGLE_COLOR && param!=GL_SEPARATE_SPECULAR_COLOR ) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
} else {
|
||||
GLboolean value = (param==GL_SEPARATE_SPECULAR_COLOR);
|
||||
if(glstate->light.separate_specular == value) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
glstate->light.separate_specular=value;
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->light_separate=value;
|
||||
}
|
||||
return; // NOT Supported in GLES 1.1 anyway
|
||||
case GL_LIGHT_MODEL_LOCAL_VIEWER:
|
||||
{
|
||||
GLboolean value = (param!=0.0);
|
||||
if(glstate->light.local_viewer == value) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
glstate->light.local_viewer=value;
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->light_localviewer=value;
|
||||
}
|
||||
return; // NOT Supported in GLES 1.1 anyway
|
||||
case GL_LIGHT_MODEL_AMBIENT:
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
LOAD_GLES_FPE(glLightModelf);
|
||||
gles_glLightModelf(pname, param);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glLightModelfv(GLenum pname, const GLfloat* params) {
|
||||
//printf("%sglLightModelfv(%04X, [%.2f, %.2f, %.2f, %.2f])\n", (state.list.compiling)?"list":"", pname, params[0], params[1], params[2], params[3]);
|
||||
ERROR_IN_BEGIN
|
||||
if(glstate->list.active)
|
||||
if ((glstate->list.compiling)) {
|
||||
NewStage(glstate->list.active, STAGE_LIGHTMODEL);
|
||||
/* if (glstate->list.active->lightmodel)
|
||||
glstate->list.active = extend_renderlist(glstate->list.active);*/
|
||||
glstate->list.active->lightmodelparam = pname;
|
||||
glstate->list.active->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat));
|
||||
int sz = 4;
|
||||
if(pname==GL_LIGHT_MODEL_TWO_SIDE || pname==GL_LIGHT_MODEL_COLOR_CONTROL || pname==GL_LIGHT_MODEL_LOCAL_VIEWER)
|
||||
sz=1;
|
||||
memcpy(glstate->list.active->lightmodel, params, sz*sizeof(GLfloat));
|
||||
noerrorShim();
|
||||
return;
|
||||
} else gl4es_flush();
|
||||
switch (pname) {
|
||||
case GL_LIGHT_MODEL_AMBIENT:
|
||||
if(memcmp(glstate->light.ambient, params, 4*sizeof(GLfloat))==0) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
errorGL();
|
||||
memcpy(glstate->light.ambient, params, 4*sizeof(GLfloat));
|
||||
break;
|
||||
case GL_LIGHT_MODEL_TWO_SIDE:
|
||||
if(glstate->light.two_side == params[0]) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
errorGL();
|
||||
glstate->light.two_side = params[0];
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->twosided = params[0];
|
||||
break;
|
||||
case GL_LIGHT_MODEL_COLOR_CONTROL:
|
||||
if(params[0]!=GL_SINGLE_COLOR && params[0]!=GL_SEPARATE_SPECULAR_COLOR ) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
} else {
|
||||
GLboolean value = (params[0]==GL_SEPARATE_SPECULAR_COLOR);
|
||||
if(glstate->light.separate_specular == value) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
glstate->light.separate_specular=value;
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->light_separate=value;
|
||||
}
|
||||
return; // NOT Supported in GLES 1.1 anyway
|
||||
case GL_LIGHT_MODEL_LOCAL_VIEWER:
|
||||
{
|
||||
GLboolean value = (params[0]!=0.0);
|
||||
if(glstate->light.local_viewer == value) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
glstate->light.local_viewer=value;
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->light_localviewer=value;
|
||||
}
|
||||
return; // NOT Supported in GLES 1.1 anyway
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
LOAD_GLES_FPE(glLightModelfv);
|
||||
gles_glLightModelfv(pname, params);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glLightfv(GLenum light, GLenum pname, const GLfloat* params) {
|
||||
//printf("%sglLightfv(%s, %s, %p=[%.2f, %.2f, %.2f, %.2f])\n", (glstate->list.compiling)?"list":"", PrintEnum(light), PrintEnum(pname), params, (params)?params[0]:0.0f, (params)?params[1]:0.0f, (params)?params[2]:0.0f, (params)?params[3]:0.0f);
|
||||
const int nl = light-GL_LIGHT0;
|
||||
if(nl<0 || nl>=hardext.maxlights) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
ERROR_IN_BEGIN
|
||||
if(glstate->list.active)
|
||||
if (glstate->list.compiling) {
|
||||
NewStage(glstate->list.active, STAGE_LIGHT);
|
||||
rlLightfv(glstate->list.active, light, pname, params);
|
||||
noerrorShim();
|
||||
return;
|
||||
} else gl4es_flush();
|
||||
|
||||
GLfloat tmp[4];
|
||||
noerrorShim();
|
||||
switch(pname) {
|
||||
case GL_AMBIENT:
|
||||
if(memcmp(glstate->light.lights[nl].ambient, params, 4*sizeof(GLfloat))==0)
|
||||
return;
|
||||
memcpy(glstate->light.lights[nl].ambient, params, 4*sizeof(GLfloat));
|
||||
break;
|
||||
case GL_DIFFUSE:
|
||||
if(memcmp(glstate->light.lights[nl].diffuse, params, 4*sizeof(GLfloat))==0)
|
||||
return;
|
||||
memcpy(glstate->light.lights[nl].diffuse, params, 4*sizeof(GLfloat));
|
||||
break;
|
||||
case GL_SPECULAR:
|
||||
if(memcmp(glstate->light.lights[nl].specular, params, 4*sizeof(GLfloat))==0)
|
||||
return;
|
||||
memcpy(glstate->light.lights[nl].specular, params, 4*sizeof(GLfloat));
|
||||
break;
|
||||
case GL_POSITION:
|
||||
vector_matrix(params, getMVMat(), tmp);
|
||||
if(memcmp(glstate->light.lights[nl].position, tmp, 4*sizeof(GLfloat))==0)
|
||||
return;
|
||||
memcpy(glstate->light.lights[nl].position, tmp, 4*sizeof(GLfloat));
|
||||
if(glstate->fpe_state) {
|
||||
int dir = (tmp[3]!=0.f);
|
||||
if (dir) {
|
||||
glstate->fpe_state->light_direction |= (1<<nl);
|
||||
} else {
|
||||
glstate->fpe_state->light_direction &= ~(1<<nl);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_SPOT_DIRECTION:
|
||||
vector3_matrix4(params,getMVMat(), tmp);
|
||||
if(memcmp(glstate->light.lights[nl].spotDirection, tmp, 3*sizeof(GLfloat))==0)
|
||||
return;
|
||||
memcpy(glstate->light.lights[nl].spotDirection, tmp, 3*sizeof(GLfloat));
|
||||
break;
|
||||
case GL_SPOT_EXPONENT:
|
||||
if(params[0]<0 || params[0]>128) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->light.lights[nl].spotExponent == params[0])
|
||||
return;
|
||||
glstate->light.lights[nl].spotExponent = params[0];
|
||||
break;
|
||||
case GL_SPOT_CUTOFF:
|
||||
if(params[0]<0.f || (params[0]>90.0f && params[0]!=180.f)) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->light.lights[nl].spotCutoff == params[0])
|
||||
return;
|
||||
glstate->light.lights[nl].spotCutoff = params[0];
|
||||
if(glstate->fpe_state) {
|
||||
int dir = (params[0]!=180.f);
|
||||
if (dir) {
|
||||
glstate->fpe_state->light_cutoff180 |= (1<<nl);
|
||||
} else {
|
||||
glstate->fpe_state->light_cutoff180 &= ~(1<<nl);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_CONSTANT_ATTENUATION:
|
||||
if(params[0]<0) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->light.lights[nl].constantAttenuation == params[0])
|
||||
return;
|
||||
glstate->light.lights[nl].constantAttenuation = params[0];
|
||||
break;
|
||||
case GL_LINEAR_ATTENUATION:
|
||||
if(params[0]<0) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->light.lights[nl].linearAttenuation == params[0])
|
||||
return;
|
||||
glstate->light.lights[nl].linearAttenuation = params[0];
|
||||
break;
|
||||
case GL_QUADRATIC_ATTENUATION:
|
||||
if(params[0]<0) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->light.lights[nl].quadraticAttenuation == params[0])
|
||||
return;
|
||||
glstate->light.lights[nl].quadraticAttenuation = params[0];
|
||||
break;
|
||||
}
|
||||
LOAD_GLES_FPE(glLightfv);
|
||||
gles_glLightfv(light, pname, params);
|
||||
errorGL();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glLightf(GLenum light, GLenum pname, GLfloat param) {
|
||||
GLfloat dummy[4];
|
||||
dummy[0]=param;
|
||||
gl4es_glLightfv(light, pname, dummy);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
|
||||
if(glstate->list.active)
|
||||
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) {
|
||||
NewStage(glstate->list.active, STAGE_MATERIAL);
|
||||
rlMaterialfv(glstate->list.active, face, pname, params);
|
||||
noerrorShim();
|
||||
return;
|
||||
} else gl4es_flush();
|
||||
}
|
||||
if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
switch(pname) {
|
||||
case GL_AMBIENT:
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
||||
memcpy(glstate->material.front.ambient, params, 4*sizeof(GLfloat));
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
||||
memcpy(glstate->material.back.ambient, params, 4*sizeof(GLfloat));
|
||||
break;
|
||||
case GL_DIFFUSE:
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
||||
memcpy(glstate->material.front.diffuse, params, 4*sizeof(GLfloat));
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
||||
memcpy(glstate->material.back.diffuse, params, 4*sizeof(GLfloat));
|
||||
break;
|
||||
case GL_SPECULAR:
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
||||
memcpy(glstate->material.front.specular, params, 4*sizeof(GLfloat));
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
||||
memcpy(glstate->material.back.specular, params, 4*sizeof(GLfloat));
|
||||
break;
|
||||
case GL_EMISSION:
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
||||
memcpy(glstate->material.front.emission, params, 4*sizeof(GLfloat));
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
||||
memcpy(glstate->material.back.emission, params, 4*sizeof(GLfloat));
|
||||
break;
|
||||
case GL_AMBIENT_AND_DIFFUSE:
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_FRONT) {
|
||||
memcpy(glstate->material.front.ambient, params, 4*sizeof(GLfloat));
|
||||
memcpy(glstate->material.front.diffuse, params, 4*sizeof(GLfloat));
|
||||
}
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_BACK) {
|
||||
memcpy(glstate->material.back.ambient, params, 4*sizeof(GLfloat));
|
||||
memcpy(glstate->material.back.diffuse, params, 4*sizeof(GLfloat));
|
||||
}
|
||||
break;
|
||||
case GL_SHININESS:
|
||||
if(*params<0.0f || *params>128.0f) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_FRONT) {
|
||||
glstate->material.front.shininess = *params;
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->cm_front_nullexp=(*params<=0.0)?0:1;
|
||||
}
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_BACK) {
|
||||
glstate->material.back.shininess = *params;
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->cm_back_nullexp=(*params<=0.0)?0:1;
|
||||
}
|
||||
break;
|
||||
case GL_COLOR_INDEXES:
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_FRONT) {
|
||||
glstate->material.front.indexes[0] = params[0];
|
||||
glstate->material.front.indexes[1] = params[1];
|
||||
glstate->material.front.indexes[2] = params[2];
|
||||
}
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_BACK) {
|
||||
glstate->material.back.indexes[0] = params[0];
|
||||
glstate->material.back.indexes[1] = params[1];
|
||||
glstate->material.back.indexes[2] = params[2];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(face==GL_BACK && hardext.esversion==1) { // lets ignore GL_BACK in GLES 1.1
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
LOAD_GLES_FPE(glMaterialfv);
|
||||
gles_glMaterialfv(GL_FRONT_AND_BACK, pname, params);
|
||||
errorGL();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMaterialf(GLenum face, GLenum pname, GLfloat param) {
|
||||
ERROR_IN_BEGIN
|
||||
if(glstate->list.active)
|
||||
if (glstate->list.compiling) {
|
||||
GLfloat params[4];
|
||||
memset(params, 0, 4*sizeof(GLfloat));
|
||||
params[0] = param;
|
||||
NewStage(glstate->list.active, STAGE_MATERIAL);
|
||||
rlMaterialfv(glstate->list.active, face, pname, params);
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
|
||||
if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(pname!=GL_SHININESS) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(param<0.0f || param>128.0f) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_FRONT) {
|
||||
if(glstate->material.front.shininess == param)
|
||||
return;
|
||||
glstate->material.front.shininess = param;
|
||||
}
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_BACK) {
|
||||
if(glstate->material.back.shininess == param)
|
||||
return;
|
||||
glstate->material.back.shininess = param;
|
||||
}
|
||||
|
||||
if(face==GL_BACK && hardext.esversion==1) { // lets ignore GL_BACK in GLES 1.1
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
FLUSH_BEGINEND;
|
||||
LOAD_GLES_FPE(glMaterialf);
|
||||
gles_glMaterialf(GL_FRONT_AND_BACK, pname, param);
|
||||
errorGL();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glColorMaterial(GLenum face, GLenum mode) {
|
||||
ERROR_IN_BEGIN
|
||||
if(glstate->list.active)
|
||||
if (glstate->list.compiling) {
|
||||
NewStage(glstate->list.active, STAGE_COLOR_MATERIAL);
|
||||
glstate->list.active->colormat_face = face;
|
||||
glstate->list.active->colormat_mode = mode;
|
||||
noerrorShim();
|
||||
return;
|
||||
} else gl4es_flush();
|
||||
|
||||
if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(mode!=GL_EMISSION && mode!=GL_AMBIENT && mode!=GL_DIFFUSE && mode!=GL_SPECULAR && mode!=GL_AMBIENT_AND_DIFFUSE) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
||||
glstate->material.front.colormat = mode;
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
||||
glstate->material.back.colormat = mode;
|
||||
if(glstate->fpe_state) {
|
||||
int value = FPE_CM_AMBIENTDIFFUSE;
|
||||
switch(mode) {
|
||||
case GL_EMISSION: value = FPE_CM_EMISSION; break;
|
||||
case GL_AMBIENT: value=FPE_CM_AMBIENT; break;
|
||||
case GL_DIFFUSE: value=FPE_CM_DIFFUSE; break;
|
||||
case GL_SPECULAR: value=FPE_CM_SPECULAR; break;
|
||||
}
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_FRONT) {
|
||||
glstate->fpe_state->cm_front_mode = value;
|
||||
}
|
||||
if(face==GL_FRONT_AND_BACK || face==GL_BACK) {
|
||||
glstate->fpe_state->cm_back_mode = value;
|
||||
}
|
||||
}
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
AliasExport(void,glLightModelf,,(GLenum pname, GLfloat param));
|
||||
AliasExport(void,glLightModelfv,,(GLenum pname, const GLfloat* params));
|
||||
AliasExport(void,glLightfv,,(GLenum light, GLenum pname, const GLfloat* params));
|
||||
AliasExport(void,glLightf,,(GLenum light, GLenum pname, GLfloat param));
|
||||
AliasExport(void,glMaterialfv,,(GLenum face, GLenum pname, const GLfloat *params));
|
||||
AliasExport(void,glMaterialf,,(GLenum face, GLenum pname, GLfloat param));
|
||||
AliasExport(void,glColorMaterial,,(GLenum face, GLenum mode));
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef _GL4ES_LIGHT_H_
|
||||
#define _GL4ES_LIGHT_H_
|
||||
|
||||
#include "gles.h"
|
||||
#include "../config.h"
|
||||
|
||||
typedef struct {
|
||||
GLfloat ambient[4];
|
||||
GLfloat diffuse[4];
|
||||
GLfloat specular[4];
|
||||
GLfloat constantAttenuation, linearAttenuation, quadraticAttenuation;
|
||||
GLfloat position[4];
|
||||
GLfloat spotDirection[3]; // It's only 3 in fact, because it's a direction
|
||||
GLfloat spotExponent;
|
||||
GLfloat spotCutoff;
|
||||
} light_t;
|
||||
|
||||
typedef struct {
|
||||
light_t lights[MAX_LIGHT];
|
||||
GLfloat ambient[4];
|
||||
GLboolean two_side;
|
||||
GLboolean separate_specular;
|
||||
GLboolean local_viewer;
|
||||
} light_state_t;
|
||||
|
||||
typedef struct {
|
||||
GLfloat ambient[4];
|
||||
GLfloat diffuse[4];
|
||||
GLfloat specular[4];
|
||||
GLfloat emission[4];
|
||||
GLfloat shininess;
|
||||
int indexes[3];
|
||||
GLenum colormat;
|
||||
} material_t;
|
||||
|
||||
typedef struct {
|
||||
material_t front;
|
||||
material_t back;
|
||||
} material_state_t;
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glLightModelf(GLenum pname, GLfloat param);
|
||||
void APIENTRY_GL4ES gl4es_glLightModelfv(GLenum pname, const GLfloat* params);
|
||||
void APIENTRY_GL4ES gl4es_glLightfv(GLenum light, GLenum pname, const GLfloat* params);
|
||||
void APIENTRY_GL4ES gl4es_glLightf(GLenum light, GLenum pname, GLfloat params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetLightfv(GLenum light, GLenum pname, GLfloat * params);
|
||||
void APIENTRY_GL4ES gl4es_glGetLightiv(GLenum light, GLenum pname, GLint * params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) ;
|
||||
void APIENTRY_GL4ES gl4es_glMaterialf(GLenum face, GLenum pname, GLfloat param);
|
||||
void APIENTRY_GL4ES gl4es_glColorMaterial(GLenum face, GLenum mode);
|
||||
|
||||
#endif // _GL4ES_LIGHT_H_
|
||||
@@ -0,0 +1,166 @@
|
||||
#include "line.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "list.h"
|
||||
#include "matrix.h"
|
||||
#include "matvec.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DBG(a) a
|
||||
#else
|
||||
#define DBG(a)
|
||||
#endif
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glLineStipple(GLuint factor, GLushort pattern) {
|
||||
DBG(printf("glLineStipple(%d, 0x%04X)\n", factor, pattern);)
|
||||
if(glstate->list.active) {
|
||||
if (glstate->list.compiling) {
|
||||
NewStage(glstate->list.active, STAGE_LINESTIPPLE);
|
||||
glstate->list.active->linestipple_op = 1;
|
||||
glstate->list.active->linestipple_factor = factor;
|
||||
glstate->list.active->linestipple_pattern = pattern;
|
||||
return;
|
||||
} else gl4es_flush();
|
||||
}
|
||||
if(factor<1) factor = 1;
|
||||
if(factor>256) factor = 256;
|
||||
if(pattern!=glstate->linestipple.pattern || factor!=glstate->linestipple.factor || !glstate->linestipple.texture) {
|
||||
glstate->linestipple.factor = factor;
|
||||
glstate->linestipple.pattern = pattern;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
glstate->linestipple.data[i] = ((pattern >> i) & 1) ? 255 : 0;
|
||||
}
|
||||
|
||||
// "Push" current Texture0 binding
|
||||
GLuint old_act = glstate->texture.active;
|
||||
if(old_act)
|
||||
gl4es_glActiveTexture(GL_TEXTURE0);
|
||||
GLuint old_tex = glstate->texture.bound[0][ENABLED_TEX2D]->texture;
|
||||
// create / update stipple texture
|
||||
if (! glstate->linestipple.texture) {
|
||||
gl4es_glGenTextures(1, &glstate->linestipple.texture);
|
||||
gl4es_glBindTexture(GL_TEXTURE_2D, glstate->linestipple.texture);
|
||||
gl4es_glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
gl4es_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
gl4es_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
gl4es_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
gl4es_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
gl4es_glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
|
||||
16, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, glstate->linestipple.data);
|
||||
} else {
|
||||
gl4es_glBindTexture(GL_TEXTURE_2D, glstate->linestipple.texture);
|
||||
gl4es_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 1,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, glstate->linestipple.data);
|
||||
}
|
||||
// "Pop" texture 0 binding
|
||||
gl4es_glBindTexture(GL_TEXTURE_2D, old_tex);
|
||||
if(old_act)
|
||||
gl4es_glActiveTexture(GL_TEXTURE0+old_act);
|
||||
// all done
|
||||
noerrorShim();
|
||||
}
|
||||
}
|
||||
AliasExport(void,glLineStipple,,(GLuint factor, GLushort pattern));
|
||||
|
||||
void bind_stipple_tex() {
|
||||
gl4es_glBindTexture(GL_TEXTURE_2D, glstate->linestipple.texture);
|
||||
}
|
||||
|
||||
GLfloat *gen_stipple_tex_coords(GLfloat *vert, GLushort *sindices, modeinit_t *modes, int stride, int length, GLfloat* noalloctex) {
|
||||
DBG(printf("Generate stripple tex (stride=%d, noalloctex=%p) length=%d:", stride, noalloctex, length);)
|
||||
// generate our texture coords
|
||||
GLfloat *tex = noalloctex?noalloctex:(GLfloat *)malloc(modes[length-1].ilen * 4 * sizeof(GLfloat));
|
||||
GLfloat *texPos = tex;
|
||||
GLfloat *vertPos = vert;
|
||||
|
||||
GLfloat x1, x2, y1, y2;
|
||||
GLfloat oldlen, len;
|
||||
const GLfloat* mvp = getMVPMat();
|
||||
GLfloat v[4];
|
||||
GLfloat w = (GLfloat)glstate->raster.viewport.width;
|
||||
GLfloat h = (GLfloat)glstate->raster.viewport.height;
|
||||
if(stride==0) stride = 4; else stride/=sizeof(GLfloat);
|
||||
int texstride = noalloctex?stride:4;
|
||||
// projected coordinates here, and transform to screen pixel using viewport
|
||||
// because projected coordinates are from -1. to +1., w and h are to be divided by 2...
|
||||
w*=0.5f; h*=0.5f;
|
||||
int i=0;
|
||||
for (int k=0; k<length; k++) {
|
||||
GLenum mode = modes[k].mode_init;
|
||||
DBG(printf("[%s->%d] ", PrintEnum(mode), modes[k].ilen);)
|
||||
oldlen = len = 0.f;
|
||||
if(modes[k].ilen<2)
|
||||
continue;
|
||||
if(mode==GL_LINES || length>1) // always line when multiple lines were merged
|
||||
for (; i < modes[k].ilen; i+=2) {
|
||||
if(sindices)
|
||||
vertPos = vert+stride*sindices[i];
|
||||
vector_matrix(vertPos, mvp, v);
|
||||
if(sindices)
|
||||
vertPos = vert+stride*sindices[i+1];
|
||||
else
|
||||
vertPos+=stride;
|
||||
// need to take "w" componant into acount...
|
||||
if(v[3]==0.0f) {
|
||||
x1=v[0]*w; y1=v[1]*h;
|
||||
} else {
|
||||
x1=(v[0]/v[3])*w; y1=(v[1]/v[3])*h;
|
||||
}
|
||||
vector_matrix(vertPos, mvp, v);
|
||||
vertPos+=stride;
|
||||
if(v[3]==0.0f) {
|
||||
x2=v[0]*w; y2=v[1]*h;
|
||||
} else {
|
||||
x2=(v[0]/v[3])*w; y2=(v[1]/v[3])*h;
|
||||
}
|
||||
oldlen = len;
|
||||
len += sqrtf((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) / (glstate->linestipple.factor * 16.f);
|
||||
DBG(printf("%f->%f (%f,%f -> %f,%f)\t", oldlen, len, x1, y1, x2, y2);)
|
||||
if(sindices)
|
||||
texPos = tex+texstride*sindices[i+0]; // it get writen 2*, but that should be ok, it's the same value
|
||||
memset(texPos, 0, 4*sizeof(GLfloat));
|
||||
texPos[0] = oldlen; texPos[3] = 1.0f;
|
||||
if(sindices)
|
||||
texPos = tex+texstride*sindices[i+1];
|
||||
else
|
||||
texPos+=texstride;
|
||||
memset(texPos, 0, 4*sizeof(GLfloat));
|
||||
texPos[0] = len; texPos[3] = 1.0f;
|
||||
texPos+=texstride;
|
||||
}
|
||||
else { // GL_LINE_STRIP and GL_LINE_LOOPS works the same here
|
||||
// (well, last segment, the "loop" one, will look strange, but I will not add a vertex for that)
|
||||
if(sindices)
|
||||
vertPos = vert+stride*sindices[i];
|
||||
vector_matrix(vertPos, mvp, v);
|
||||
x2=(v[0]/v[3])*w; y2=(v[1]/v[3])*h;
|
||||
vertPos+=stride;
|
||||
DBG(printf("%f\t", len);)
|
||||
memset(texPos, 0, 4*sizeof(GLfloat));
|
||||
texPos[0] = len; texPos[3] = 1.0f;
|
||||
texPos+=texstride;
|
||||
++i;
|
||||
for (; i < modes[k].ilen; i++) {
|
||||
x1 = x2; y1 = y2;
|
||||
if(sindices)
|
||||
vertPos = vert+stride*sindices[i];
|
||||
vector_matrix(vertPos, mvp, v);
|
||||
vertPos+=stride;
|
||||
x2=(v[0]/v[3])*w; y2=(v[1]/v[3])*h;
|
||||
len += sqrtf((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) / (glstate->linestipple.factor * 16.f);
|
||||
DBG(printf("->%f\t", len);)
|
||||
if(sindices)
|
||||
texPos = tex+texstride*sindices[i];
|
||||
memset(texPos, 0, 4*sizeof(GLfloat));
|
||||
texPos[0] = len; texPos[3] = 1.0f;
|
||||
texPos+=texstride;
|
||||
}
|
||||
}
|
||||
}
|
||||
DBG(printf("\n");)
|
||||
return tex;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef _GL4ES_LINE_H
|
||||
#define _GL4ES_LINE_H
|
||||
|
||||
#include "gles.h"
|
||||
#include "list.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glLineStipple(GLuint factor, GLushort pattern);
|
||||
GLfloat *gen_stipple_tex_coords(GLfloat *vert, GLushort *sindices, modeinit_t *modes, int stride, int length, GLfloat* noalloctex);
|
||||
void bind_stipple_tex();
|
||||
|
||||
#endif // _GL4ES_LINE_H
|
||||
@@ -0,0 +1,971 @@
|
||||
#include "list.h"
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "const.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "init.h"
|
||||
#include "loader.h"
|
||||
#include "buffers.h"
|
||||
|
||||
// KH Map implementation
|
||||
KHASH_MAP_IMPL_INT(material, rendermaterial_t *);
|
||||
KHASH_MAP_IMPL_INT(light, renderlight_t *);
|
||||
KHASH_MAP_IMPL_INT(texgen, rendertexgen_t *);
|
||||
KHASH_MAP_IMPL_INT(texenv, rendertexenv_t *);
|
||||
KHASH_MAP_IMPL_INT(gllisthead, renderlist_t*);
|
||||
|
||||
renderlist_t *alloc_renderlist() {
|
||||
|
||||
renderlist_t *list = (renderlist_t *)malloc(sizeof(renderlist_t));
|
||||
memset(list, 0, sizeof(renderlist_t));
|
||||
list->cap = DEFAULT_RENDER_LIST_CAPACITY;
|
||||
list->matrix_val[0] = list->matrix_val[5] = list->matrix_val[10] =
|
||||
list->matrix_val[15] = 1.0f;
|
||||
list->lightmodelparam = GL_LIGHT_MODEL_AMBIENT;
|
||||
list->target_texture = GL_TEXTURE_2D;
|
||||
list->tmu = glstate->texture.active;
|
||||
|
||||
memcpy(list->lastNormal, glstate->normal, 3*sizeof(GLfloat));
|
||||
memcpy(list->lastSecondaryColors, glstate->secondary, 3*sizeof(GLfloat));
|
||||
memcpy(list->lastColors, glstate->color, 4*sizeof(GLfloat));
|
||||
memcpy(&list->lastFogCoord, glstate->fogcoord, 1*sizeof(GLfloat));
|
||||
|
||||
list->instanceCount = 1;
|
||||
|
||||
list->open = true;
|
||||
return list;
|
||||
}
|
||||
|
||||
bool ispurerender_renderlist(renderlist_t *list) {
|
||||
// return true if renderlist contains only rendering command, no state changes
|
||||
if (list->calls.len)
|
||||
return false;
|
||||
if (list->matrix_op)
|
||||
return false;
|
||||
if (list->raster_op)
|
||||
return false;
|
||||
if (list->raster)
|
||||
return false;
|
||||
if (list->bitmaps)
|
||||
return false;
|
||||
if (list->pushattribute)
|
||||
return false;
|
||||
if (list->popattribute)
|
||||
return false;
|
||||
if (list->material || list->colormat_face || list->light || list->lightmodel || list->texgen || list->texenv)
|
||||
return false;
|
||||
if (list->fog_op)
|
||||
return false;
|
||||
if (list->instanceCount!=1)
|
||||
return false;
|
||||
if (list->pointparam_op)
|
||||
return false;
|
||||
if (list->mode_init == 0)
|
||||
return false;
|
||||
if (list->ind_lines || list->final_colors)
|
||||
return false;
|
||||
if (list->set_texture || list->set_tmu)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isempty_renderlist(renderlist_t *list) {
|
||||
return (list->stage == STAGE_NONE);
|
||||
}
|
||||
|
||||
int rendermode_dimensions(GLenum mode) {
|
||||
// return 1 for points, 2 for any lines, 3 for any triangles, 4 for any Quad and 5 for polygon
|
||||
switch (mode) {
|
||||
case GL_POINTS:
|
||||
return 1;
|
||||
case GL_LINES:
|
||||
case GL_LINE_LOOP:
|
||||
case GL_LINE_STRIP:
|
||||
return 2;
|
||||
case GL_TRIANGLES:
|
||||
case GL_TRIANGLE_FAN:
|
||||
case GL_TRIANGLE_STRIP:
|
||||
return 3;
|
||||
case GL_QUADS:
|
||||
case GL_QUAD_STRIP:
|
||||
return 3; // It's 4, but we use only triangles...
|
||||
case GL_POLYGON:
|
||||
return 3; // It's 5, but we use only triangles too.
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool islistscompatible_renderlist(renderlist_t *a, renderlist_t *b) {
|
||||
if (!globals4es.mergelist || !a)
|
||||
return false;
|
||||
|
||||
// check if 2 "pure rendering" list are compatible for merge
|
||||
if (a->mode_init != b->mode_init) {
|
||||
int a_mode = a->mode_dimension;
|
||||
int b_mode = b->mode_dimension;
|
||||
if ((a_mode == 0) || (b_mode == 0))
|
||||
return false; // undetermined is not good
|
||||
if (a_mode == 4) a_mode = 3; // quads are handled as triangles
|
||||
if (b_mode == 4) b_mode = 3;
|
||||
if (a_mode != b_mode)
|
||||
return false;
|
||||
}
|
||||
if(a->use_vbo_array==2 || b->use_vbo_array==2)
|
||||
return false;
|
||||
if(a->use_vbo_indices==2 || b->use_vbo_indices==2)
|
||||
return false;
|
||||
if(!a->open || !b->open)
|
||||
return false;
|
||||
if(a->use_glstate)
|
||||
return false; //TODO: Handle this case
|
||||
/* if ((a->indices==NULL) != (b->indices==NULL))
|
||||
return false;*/
|
||||
if (a->polygon_mode != b->polygon_mode)
|
||||
return false;
|
||||
if ((a->vert==NULL) != (b->vert==NULL))
|
||||
return false;
|
||||
if ((a->normal==NULL) != (b->normal==NULL))
|
||||
return false;
|
||||
if ((a->color==NULL) != (b->color==NULL))
|
||||
return false;
|
||||
if ((a->secondary==NULL) != (b->secondary==NULL))
|
||||
return false;
|
||||
if ((a->fogcoord==NULL) != (b->fogcoord==NULL))
|
||||
return false;
|
||||
// check the textures
|
||||
if(a->maxtex!=b->maxtex)
|
||||
return false;
|
||||
for (int i=0; i<a->maxtex; i++)
|
||||
if ((a->tex[i]==NULL) != (b->tex[i]==NULL))
|
||||
return false;
|
||||
if ((a->set_texture==b->set_texture) && ((a->texture != b->texture) || (a->target_texture != b->target_texture)))
|
||||
return false;
|
||||
if (!a->set_texture && b->set_texture)
|
||||
return false;
|
||||
// post color is only important if b as no color pointer...
|
||||
if(a->post_color && b->color==NULL)
|
||||
return false;
|
||||
// same for post_normal
|
||||
if(a->post_normal && b->normal==NULL)
|
||||
return false;
|
||||
// check instanceCount (maybe it would be better to just check if both are == 1)
|
||||
if(a->instanceCount != b->instanceCount)
|
||||
return false;
|
||||
|
||||
// Check the size of a list, if it"s too big, don't merge...
|
||||
if ((a->len+b->len)>60000)
|
||||
return false;
|
||||
if ((a->ilen+b->ilen)>60000)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void renderlist_createindices(int ilen, GLushort *indices, int count) {
|
||||
for (int i = 0; i<ilen; i++) {
|
||||
indices[i] = i+count;
|
||||
}
|
||||
}
|
||||
|
||||
#define vind(a) (((ind)?ind[(a)]:(a))+count)
|
||||
|
||||
void renderlist_lineloop_lines(GLushort *ind, int len, GLushort *indices, int count) {
|
||||
int ilen = len*2; // new size is 2* + return
|
||||
|
||||
if(len>1) {
|
||||
int k=0;
|
||||
indices[k++] = vind(0);
|
||||
indices[k++] = vind(1);
|
||||
for (int i = 2; i<len; i++) {
|
||||
indices[k++] = vind(i-1);
|
||||
indices[k++] = vind(i);
|
||||
}
|
||||
// go back to initial point
|
||||
indices[k++] = indices[(len-1)*2-1];
|
||||
indices[k++] = indices[0];
|
||||
}
|
||||
}
|
||||
|
||||
void renderlist_linestrip_lines(GLushort *ind, int len, GLushort *indices, int count) {
|
||||
int ilen = len*2-2; // new size is 2*
|
||||
if (ilen<1) ilen=0;
|
||||
if(len>1) {
|
||||
int k=0;
|
||||
indices[k++] = vind(0);
|
||||
indices[k++] = vind(1);
|
||||
for (int i = 2; i<len; i++) {
|
||||
indices[k++] = vind(i-1);
|
||||
indices[k++] = vind(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void renderlist_trianglestrip_triangles(GLushort *ind, int len, GLushort *indices, int count) {
|
||||
int ilen = (len-2)*3;
|
||||
if (ilen<0) ilen=0;
|
||||
for (int i = 2; i<len; i++) {
|
||||
indices[(i-2)*3+(i%2)] = vind(i-2);
|
||||
indices[(i-2)*3+1-(i%2)] = vind(i-1);
|
||||
indices[(i-2)*3+2] = vind(i);
|
||||
}
|
||||
}
|
||||
|
||||
void renderlist_trianglefan_triangles(GLushort *ind, int len, GLushort *indices, int count) {
|
||||
int ilen = (len-2)*3;
|
||||
if (ilen<0) ilen=0;
|
||||
for (int i = 2; i<len; i++) {
|
||||
indices[(i-2)*3+0] = vind(0);
|
||||
indices[(i-2)*3+1] = vind(i-1);
|
||||
indices[(i-2)*3+2] = vind(i);
|
||||
}
|
||||
}
|
||||
|
||||
void renderlist_quads_triangles(GLushort *ind, int len, GLushort *indices, int count) {
|
||||
// len must be a multiple of 4 !
|
||||
len &= ~3; // discard extra vertex...
|
||||
int ilen = len*3/2;
|
||||
for (int i=0, j=0; i+3<len; i+=4, j+=6) {
|
||||
indices[j+0] = vind(i+0);
|
||||
indices[j+1] = vind(i+1);
|
||||
indices[j+2] = vind(i+2);
|
||||
|
||||
indices[j+3] = vind(i+0);
|
||||
indices[j+4] = vind(i+2);
|
||||
indices[j+5] = vind(i+3);
|
||||
}
|
||||
}
|
||||
#undef vind
|
||||
#define vind(a) ((ind)?ind[(a)]:(a))
|
||||
void renderlist_quads2triangles(renderlist_t *a) {
|
||||
GLushort *ind = a->indices;
|
||||
int len = (ind)? a->ilen:a->len;
|
||||
// len must be a multiple of 4 !
|
||||
len &= ~3; // discard extra vertex...
|
||||
int ilen = len*3/2;
|
||||
if(a->use_glstate) {
|
||||
if(ind) {//need to copy first...
|
||||
ind = (GLushort*)malloc(len*sizeof(GLushort));
|
||||
memcpy(ind, glstate->merger_indices, len*sizeof(GLushort));
|
||||
a->shared_indices = NULL; // should not be needed
|
||||
}
|
||||
resize_merger_indices(ilen);
|
||||
a->indices = glstate->merger_indices;
|
||||
} else
|
||||
a->indices = (GLushort*)malloc(ilen*sizeof(GLushort));
|
||||
|
||||
for (int i=0, j=0; i+3<len; i+=4, j+=6) {
|
||||
a->indices[j+0] = vind(i+0);
|
||||
a->indices[j+1] = vind(i+1);
|
||||
a->indices[j+2] = vind(i+2);
|
||||
|
||||
a->indices[j+3] = vind(i+0);
|
||||
a->indices[j+4] = vind(i+2);
|
||||
a->indices[j+5] = vind(i+3);
|
||||
}
|
||||
a->ilen = ilen;
|
||||
if (ind) {
|
||||
if (!a->shared_indices || ((*a->shared_indices)--)==0) {
|
||||
free(ind);
|
||||
free(a->shared_indices);
|
||||
}
|
||||
a->shared_indices = NULL; // unshared list
|
||||
}
|
||||
a->mode = GL_TRIANGLES;
|
||||
}
|
||||
#undef vind
|
||||
|
||||
int indices_getindicesize(GLenum mode, int len) {
|
||||
int ilen_a;
|
||||
switch (mode) {
|
||||
case GL_LINE_LOOP:
|
||||
ilen_a = len*2;
|
||||
if (ilen_a<0) ilen_a=1; // special borked case...
|
||||
break;
|
||||
case GL_LINE_STRIP:
|
||||
ilen_a = (len*2)-2;
|
||||
if (ilen_a<0) ilen_a=1; // special borked case...
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
case GL_TRIANGLE_STRIP:
|
||||
case GL_TRIANGLE_FAN:
|
||||
case GL_POLYGON:
|
||||
ilen_a = (len-2)*3;
|
||||
if (ilen_a<0) ilen_a=1; // special borked case...
|
||||
break;
|
||||
case GL_QUADS:
|
||||
ilen_a = ((len&~3)*3)/2;
|
||||
break;
|
||||
default:
|
||||
ilen_a = len;
|
||||
break;
|
||||
}
|
||||
return ilen_a;
|
||||
}
|
||||
int renderlist_getindicesize(renderlist_t *a) {
|
||||
int ilen_a = indices_getindicesize(a->mode, ((a->indices)? a->ilen:a->len));
|
||||
return ilen_a;
|
||||
}
|
||||
int mode_needindices(GLenum m) {
|
||||
switch(m) {
|
||||
case GL_LINE_LOOP:
|
||||
case GL_LINE_STRIP:
|
||||
case GL_TRIANGLE_FAN:
|
||||
case GL_TRIANGLE_STRIP:
|
||||
case GL_QUAD_STRIP:
|
||||
case GL_POLYGON:
|
||||
//case GL_QUADS: // not needed, but will appens anyway
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void list_add_modeinit(renderlist_t* list, GLenum mode) {
|
||||
if (list->mode_init_len+1 >= list->mode_init_cap) {
|
||||
list->mode_init_cap+=128;
|
||||
list->mode_inits = (modeinit_t*)realloc(list->mode_inits, list->mode_init_cap*sizeof(modeinit_t));
|
||||
}
|
||||
list->mode_inits[list->mode_init_len].mode_init = mode;
|
||||
list->mode_inits[list->mode_init_len++].ilen = list->indices?list->ilen:(list->cur_istart?list->cur_istart:list->len);
|
||||
}
|
||||
|
||||
void unshared_renderlist(renderlist_t *a, int cap) {
|
||||
if(a->shared_arrays && ((*a->shared_arrays)--)>0) {
|
||||
a->cap = cap;
|
||||
GLfloat *tmp;
|
||||
tmp = a->vert;
|
||||
if (tmp) {
|
||||
a->vert = alloc_sublist(4, cap);
|
||||
memcpy(a->vert, tmp, 4*a->len*sizeof(GLfloat));
|
||||
}
|
||||
tmp = a->normal;
|
||||
if (tmp) {
|
||||
a->normal = alloc_sublist(3, cap);
|
||||
memcpy(a->normal, tmp, 3*a->len*sizeof(GLfloat));
|
||||
}
|
||||
tmp = a->color;
|
||||
if (tmp) {
|
||||
a->color = alloc_sublist(4, cap);
|
||||
memcpy(a->color, tmp, 4*a->len*sizeof(GLfloat));
|
||||
}
|
||||
tmp = a->secondary;
|
||||
if (tmp) {
|
||||
a->secondary = alloc_sublist(4, cap);
|
||||
memcpy(a->secondary, tmp, 4*a->len*sizeof(GLfloat));
|
||||
}
|
||||
tmp = a->fogcoord;
|
||||
if (tmp) {
|
||||
a->fogcoord = alloc_sublist(1, cap);
|
||||
memcpy(a->fogcoord, tmp, 1*a->len*sizeof(GLfloat));
|
||||
}
|
||||
for (int i=0; i<a->maxtex; i++) {
|
||||
tmp = a->tex[i];
|
||||
if (tmp) {
|
||||
a->tex[i] = alloc_sublist(4, cap);
|
||||
memcpy(a->tex[i], tmp, 4*a->len*sizeof(GLfloat));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(a->shared_arrays && (*a->shared_arrays)==0) {
|
||||
free(a->shared_arrays);
|
||||
a->shared_arrays=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void unsharedindices_renderlist(renderlist_t* a, int cap)
|
||||
{
|
||||
if (a->shared_indices && ((*a->shared_indices)--)>0) {
|
||||
if (a->indices) {
|
||||
GLushort* tmpi = a->indices;
|
||||
a->indice_cap = cap;
|
||||
if (a->indice_cap > 48) a->indice_cap = ((a->indice_cap+512)>>9)<<9;
|
||||
a->indices = (GLushort*)malloc(a->indice_cap*sizeof(GLushort));
|
||||
memcpy(a->indices, tmpi, a->ilen*sizeof(GLushort));
|
||||
}
|
||||
}
|
||||
if(a->shared_indices && (*a->shared_indices)==0) {
|
||||
free(a->shared_indices);
|
||||
a->shared_indices=0;
|
||||
}
|
||||
}
|
||||
|
||||
void redim_renderlist(renderlist_t *a, int cap) {
|
||||
if (a->cap < cap) {
|
||||
a->cap = cap;
|
||||
realloc_sublist(a->vert, 4, cap);
|
||||
realloc_sublist(a->normal, 3, cap);
|
||||
realloc_sublist(a->color, 4, cap);
|
||||
realloc_sublist(a->secondary, 4, cap);
|
||||
realloc_sublist(a->fogcoord, 1, cap);
|
||||
for (int i=0; i<a->maxtex; i++)
|
||||
realloc_sublist(a->tex[i], 4, cap);
|
||||
}
|
||||
}
|
||||
|
||||
void prepareadd_renderlist(renderlist_t* a, int size_to_add)
|
||||
{
|
||||
// alloc or realloc a->indices first...
|
||||
int capindices = renderlist_getindicesize(a)+size_to_add;
|
||||
if (capindices > 48) capindices = ((capindices+512)>>9)<<9;
|
||||
#define alloc_a_indices \
|
||||
newind=(GLushort*)malloc(capindices*sizeof(GLushort))
|
||||
#define copy_a_indices \
|
||||
if (a->indices) free(a->indices); \
|
||||
a->indices = newind; \
|
||||
a->indice_cap = capindices
|
||||
// check if "a" needs to be converted
|
||||
int ilen_a = renderlist_getindicesize(a);
|
||||
GLushort *newind=NULL;
|
||||
switch (a->mode) {
|
||||
case GL_LINE_LOOP:
|
||||
alloc_a_indices;
|
||||
renderlist_lineloop_lines(a->indices, a->indices?a->ilen:a->len, newind, 0);
|
||||
a->mode = GL_LINES;
|
||||
copy_a_indices;
|
||||
break;
|
||||
case GL_LINE_STRIP:
|
||||
alloc_a_indices;
|
||||
renderlist_linestrip_lines(a->indices, a->indices?a->ilen:a->len, newind, 0);
|
||||
a->mode = GL_LINES;
|
||||
copy_a_indices;
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
case GL_TRIANGLE_STRIP:
|
||||
alloc_a_indices;
|
||||
renderlist_trianglestrip_triangles(a->indices, a->indices?a->ilen:a->len, newind, 0);
|
||||
a->mode = GL_TRIANGLES;
|
||||
copy_a_indices;
|
||||
break;
|
||||
case GL_TRIANGLE_FAN:
|
||||
case GL_POLYGON:
|
||||
alloc_a_indices;
|
||||
renderlist_trianglefan_triangles(a->indices, a->indices?a->ilen:a->len, newind, 0);
|
||||
a->mode = GL_TRIANGLES;
|
||||
copy_a_indices;
|
||||
break;
|
||||
case GL_QUADS:
|
||||
alloc_a_indices;
|
||||
renderlist_quads_triangles(a->indices, a->indices?a->ilen:a->len, newind, 0);
|
||||
a->mode = GL_TRIANGLES;
|
||||
copy_a_indices;
|
||||
break;
|
||||
default:
|
||||
if (!a->indices) {
|
||||
// no a->indices, must alloc and fill one
|
||||
alloc_a_indices;
|
||||
renderlist_createindices(a->len, newind, 0);
|
||||
copy_a_indices;
|
||||
} else {
|
||||
// a->indices already exist, just check if need to adjust its size
|
||||
if (a->indice_cap < capindices) {
|
||||
a->indices = (GLushort*)realloc(a->indices, capindices*sizeof(GLushort));
|
||||
a->indice_cap = capindices;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#undef copy_a_indices
|
||||
#undef alloc_a_indices
|
||||
|
||||
a->ilen = ilen_a;
|
||||
}
|
||||
|
||||
void doadd_renderlist(renderlist_t* a, GLenum mode, GLushort* indices, int count, int size_to_add)
|
||||
{
|
||||
// then append b
|
||||
switch (mode) {
|
||||
case GL_LINE_LOOP:
|
||||
renderlist_lineloop_lines(indices, count, a->indices + a->ilen, a->len);
|
||||
break;
|
||||
case GL_LINE_STRIP:
|
||||
renderlist_linestrip_lines(indices, count, a->indices + a->ilen, a->len);
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
case GL_TRIANGLE_STRIP:
|
||||
renderlist_trianglestrip_triangles(indices, count, a->indices + a->ilen, a->len);
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
case GL_TRIANGLE_FAN:
|
||||
renderlist_trianglefan_triangles(indices, count, a->indices + a->ilen, a->len);
|
||||
break;
|
||||
case GL_QUADS:
|
||||
renderlist_quads_triangles(indices, count, a->indices + a->ilen, a->len);
|
||||
break;
|
||||
default:
|
||||
// no transform here, just take (or create) the indice list as-is
|
||||
if (!indices) {
|
||||
// append a newly created indice list
|
||||
renderlist_createindices(count, a->indices + a->ilen, a->len);
|
||||
} else {
|
||||
// append existing one
|
||||
GLushort* newind = a->indices+a->ilen;
|
||||
for(int i=0; i<count; i++)
|
||||
newind[i] = indices[i]+a->len;
|
||||
}
|
||||
break;
|
||||
}
|
||||
a->ilen += size_to_add;
|
||||
}
|
||||
|
||||
void append_renderlist(renderlist_t *a, renderlist_t *b) {
|
||||
// append all draw elements of b in a
|
||||
// check the final indice size of a and b
|
||||
int ilen_a = a->ilen;
|
||||
int ilen_b = b->ilen;
|
||||
// lets append all the arrays
|
||||
unsigned long cap = a->cap;
|
||||
if (a->len + b->len >= cap) cap += b->cap + DEFAULT_RENDER_LIST_CAPACITY;
|
||||
// Unshare if shared (shared array are not used for now)
|
||||
unshared_renderlist(a, cap);
|
||||
redim_renderlist(a, cap);
|
||||
unsharedindices_renderlist(a, ((ilen_a)?ilen_a:a->len) + ((ilen_b)?ilen_b:b->len));
|
||||
// append arrays
|
||||
if (a->vert) memcpy(a->vert+a->len*4, b->vert, b->len*4*sizeof(GLfloat));
|
||||
if (a->normal) memcpy(a->normal+a->len*3, b->normal, b->len*3*sizeof(GLfloat));
|
||||
if (a->color) memcpy(a->color+a->len*4, b->color, b->len*4*sizeof(GLfloat));
|
||||
if (a->secondary) memcpy(a->secondary+a->len*4, b->secondary, b->len*4*sizeof(GLfloat));
|
||||
if (a->fogcoord) memcpy(a->fogcoord+a->len*1, b->fogcoord, b->len*1*sizeof(GLfloat));
|
||||
for (int i=0; i<a->maxtex; i++)
|
||||
if (a->tex[i]) memcpy(a->tex[i]+a->len*4, b->tex[i], b->len*4*sizeof(GLfloat));
|
||||
// indices
|
||||
if(!a->mode_inits) list_add_modeinit(a, a->mode_init);
|
||||
if (ilen_a || ilen_b || mode_needindices(a->mode) || mode_needindices(b->mode)
|
||||
|| (a->mode!=b->mode && (a->mode==GL_QUADS || b->mode==GL_QUADS)) )
|
||||
{
|
||||
// alloc or realloc a->indices first...
|
||||
ilen_b = renderlist_getindicesize(b);
|
||||
prepareadd_renderlist(a, ilen_b);
|
||||
// then append b
|
||||
doadd_renderlist(a, b->mode, b->indices, b->indices?b->ilen:b->len, ilen_b);
|
||||
}
|
||||
// lenghts
|
||||
a->len += b->len;
|
||||
if(a->mode_inits) list_add_modeinit(a, b->mode);
|
||||
// copy the lastColors if needed
|
||||
if(b->lastColorsSet) {
|
||||
a->lastColorsSet = 1;
|
||||
memcpy(a->lastColors, b->lastColors, 4*sizeof(GLfloat));
|
||||
}
|
||||
if(b->post_color) {
|
||||
a->post_color = 1;
|
||||
memcpy(a->post_colors, b->post_colors, 4*sizeof(GLfloat));
|
||||
}
|
||||
if(b->post_normal) {
|
||||
a->post_normal = 1;
|
||||
memcpy(a->post_normals, b->post_normals, 3*sizeof(GLfloat));
|
||||
}
|
||||
//all done
|
||||
a->stage = STAGE_DRAW; // just in case
|
||||
return;
|
||||
}
|
||||
void adjust_renderlist(renderlist_t *list);
|
||||
|
||||
renderlist_t *extend_renderlist(renderlist_t *list) {
|
||||
if ((list->prev!=NULL) && ispurerender_renderlist(list) && islistscompatible_renderlist(list->prev, list)) {
|
||||
// append list!
|
||||
append_renderlist(list->prev, list);
|
||||
renderlist_t *new = alloc_renderlist();
|
||||
new->prev = list->prev;
|
||||
list->prev->next = new;
|
||||
// just in case
|
||||
memcpy(new->lastNormal, list->lastNormal, 3*sizeof(GLfloat));
|
||||
memcpy(new->lastSecondaryColors, list->lastSecondaryColors, 3*sizeof(GLfloat));
|
||||
memcpy(new->lastColors, list->lastColors, 4*sizeof(GLfloat));
|
||||
new->lastColorsSet = list->lastColorsSet;
|
||||
// detach
|
||||
list->prev = NULL;
|
||||
// free list now
|
||||
free_renderlist(list);
|
||||
return new;
|
||||
} else {
|
||||
renderlist_t *new = alloc_renderlist();
|
||||
list->next = new;
|
||||
new->prev = list;
|
||||
new->tmu = list->tmu;
|
||||
// copy local state
|
||||
memcpy(new->lastNormal, list->lastNormal, 3*sizeof(GLfloat));
|
||||
memcpy(new->lastSecondaryColors, list->lastSecondaryColors, 3*sizeof(GLfloat));
|
||||
memcpy(new->lastColors, (list->post_color)?list->post_colors:list->lastColors, 4*sizeof(GLfloat));
|
||||
new->lastColorsSet = (list->post_color || list->lastColorsSet)?1:0;
|
||||
return new;
|
||||
}
|
||||
}
|
||||
|
||||
renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a)
|
||||
{
|
||||
// go to end of list
|
||||
while(list->next) list = list->next;
|
||||
while(a) {
|
||||
if(ispurerender_renderlist(a) && islistscompatible_renderlist(list, a)) {
|
||||
// append list!
|
||||
append_renderlist(list, a);
|
||||
} else {
|
||||
// create a new appended list
|
||||
renderlist_t *new = alloc_renderlist();
|
||||
// prepared shared stuff...
|
||||
if(a->len && !a->shared_arrays) {
|
||||
a->shared_arrays = (int*)malloc(sizeof(int));
|
||||
*a->shared_arrays = 0;
|
||||
}
|
||||
if(a->ilen && !a->shared_indices) {
|
||||
a->shared_indices = (int*)malloc(sizeof(int));
|
||||
*a->shared_indices = 0;
|
||||
}
|
||||
if(a->calls.len && !a->shared_calls) {
|
||||
a->shared_calls = (int*)malloc(sizeof(int));
|
||||
*a->shared_calls = 0;
|
||||
}
|
||||
// batch copy first
|
||||
memcpy(new, a, sizeof(renderlist_t));
|
||||
list->next = new;
|
||||
new->prev = list;
|
||||
// ok, now on new list
|
||||
list = new;
|
||||
// copy the many list arrays
|
||||
if (list->calls.len > 0) {
|
||||
++(*list->shared_calls);
|
||||
/*
|
||||
list->calls.calls = (packed_call_t**)malloc(sizeof(packed_call_t*)*a->calls.cap);
|
||||
for (int i = 0; i < list->calls.len; i++) {
|
||||
list->calls.calls[i] = glCopyPackedCall(a->calls.calls[i]);
|
||||
}*/
|
||||
}
|
||||
if(list->len) {
|
||||
++(*list->shared_arrays);
|
||||
}
|
||||
if(list->ilen) {
|
||||
++(*list->shared_indices);
|
||||
}
|
||||
#define PROCESS(W, T, C) if(list->W) { \
|
||||
list->W = kh_init(W); \
|
||||
T *m, *m2; \
|
||||
khint_t k; \
|
||||
int ret; \
|
||||
kh_foreach_value(a->W, m, \
|
||||
k = kh_put(W, list->W, C, &ret); \
|
||||
m2= kh_value(list->W, k) = malloc(sizeof(T)); \
|
||||
memcpy(m2, m, sizeof(T)); \
|
||||
); \
|
||||
}
|
||||
PROCESS(material, rendermaterial_t, m->pname);
|
||||
PROCESS(light, renderlight_t, m->pname | ((m->which-GL_LIGHT0)<<16));
|
||||
PROCESS(texgen, rendertexgen_t, m->pname | ((m->coord-GL_S)<<16));
|
||||
PROCESS(texenv, rendertexenv_t, m->pname | ((m->target)<<16));
|
||||
#undef PROCESS
|
||||
if (list->lightmodel) {
|
||||
list->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat));
|
||||
memcpy(list->lightmodel, a->lightmodel, 4*sizeof(GLfloat));
|
||||
}
|
||||
if (list->raster) {
|
||||
(*list->raster->shared)++;
|
||||
}
|
||||
if (list->bitmaps) {
|
||||
(*list->bitmaps->shared)++;
|
||||
}
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void free_renderlist(renderlist_t *list) {
|
||||
// test if list is NULL
|
||||
if (list == NULL)
|
||||
return;
|
||||
// we want the first list in the chain
|
||||
while (list->prev)
|
||||
list = list->prev;
|
||||
|
||||
renderlist_t *next;
|
||||
do {
|
||||
if(list->mode_inits)
|
||||
free(list->mode_inits);
|
||||
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]);
|
||||
}
|
||||
free(list->calls.calls);
|
||||
}
|
||||
int a;
|
||||
if(!list->use_glstate) {
|
||||
if (!list->shared_arrays || ((*list->shared_arrays)--)==0) {
|
||||
if (list->shared_arrays) free(list->shared_arrays);
|
||||
if (list->vert) free(list->vert);
|
||||
if (list->normal) free(list->normal);
|
||||
if (list->color) free(list->color);
|
||||
if (list->secondary) free(list->secondary);
|
||||
if (list->fogcoord) free(list->fogcoord);
|
||||
for (a=0; a<list->maxtex; a++)
|
||||
if (list->tex[a]) free(list->tex[a]);
|
||||
}
|
||||
if (!list->shared_indices || ((*list->shared_indices)--)==0) {
|
||||
if (list->shared_indices) free(list->shared_indices);
|
||||
if (list->indices)
|
||||
free(list->indices);
|
||||
}
|
||||
} else
|
||||
glstate->merger_used = 0;
|
||||
|
||||
if (list->material) {
|
||||
rendermaterial_t *m;
|
||||
kh_foreach_value(list->material, m,
|
||||
free(m);
|
||||
)
|
||||
kh_destroy(material, list->material);
|
||||
}
|
||||
if (list->light) {
|
||||
renderlight_t *m;
|
||||
kh_foreach_value(list->light, m,
|
||||
free(m);
|
||||
)
|
||||
kh_destroy(light, list->light);
|
||||
}
|
||||
if (list->texgen) {
|
||||
rendertexgen_t *m;
|
||||
kh_foreach_value(list->texgen, m,
|
||||
free(m);
|
||||
)
|
||||
kh_destroy(texgen, list->texgen);
|
||||
}
|
||||
if (list->texenv) {
|
||||
rendertexenv_t *m;
|
||||
kh_foreach_value(list->texenv, m,
|
||||
free(m);
|
||||
)
|
||||
kh_destroy(texenv, list->texenv);
|
||||
}
|
||||
if (list->lightmodel)
|
||||
free(list->lightmodel);
|
||||
|
||||
if (list->raster && !((*list->raster->shared)--)) {
|
||||
if (list->raster->texture)
|
||||
gl4es_glDeleteTextures(1, &list->raster->texture);
|
||||
free(list->raster->shared);
|
||||
free(list->raster);
|
||||
}
|
||||
|
||||
if(list->bitmaps && !((*list->bitmaps->shared)--)) {
|
||||
for(int i=0; i<list->bitmaps->count; i++)
|
||||
if(list->bitmaps->list[i].bitmap)
|
||||
free(list->bitmaps->list[i].bitmap);
|
||||
free(list->bitmaps->list);
|
||||
free(list->bitmaps->shared);
|
||||
free(list->bitmaps);
|
||||
}
|
||||
|
||||
if(list->ind_lines)
|
||||
free(list->ind_lines);
|
||||
if(list->final_colors)
|
||||
free(list->final_colors);
|
||||
if(list->vbo_array)
|
||||
deleteSingleBuffer(list->vbo_array);
|
||||
if(list->vbo_indices)
|
||||
deleteSingleBuffer(list->vbo_indices);
|
||||
|
||||
next = list->next;
|
||||
free(list);
|
||||
} while ((list = next));
|
||||
}
|
||||
|
||||
void resize_renderlist(renderlist_t *list) {
|
||||
if (list->use_glstate) {
|
||||
if (list->len >= glstate->merger_cap) {
|
||||
glstate->merger_cap += DEFAULT_RENDER_LIST_CAPACITY*8;
|
||||
realloc_merger_sublist(glstate->merger_master, 4*5, glstate->merger_cap);
|
||||
realloc_sublist(glstate->merger_secondary, 4, glstate->merger_cap);
|
||||
for (int a=2; a<list->maxtex; a++)
|
||||
realloc_sublist(glstate->merger_tex[a-2], 4, glstate->merger_cap);
|
||||
if(list->vert) list->vert = glstate->merger_master;
|
||||
if(list->normal) list->normal = glstate->merger_master+4+4+2*4;
|
||||
if(list->color) list->color = glstate->merger_master+4;
|
||||
if(list->tex[0]) list->tex[0] = glstate->merger_master+4+4;
|
||||
if(list->tex[1]) list->tex[1] = glstate->merger_master+4+4+4;
|
||||
if(list->fogcoord) list->fogcoord = glstate->merger_master+4+4+2*4+3;
|
||||
if(list->secondary) list->secondary = glstate->merger_secondary;
|
||||
for (int a=2; a<list->maxtex; a++)
|
||||
if(list->tex[a]) list->tex[a] = glstate->merger_tex[a-2];
|
||||
}
|
||||
} else {
|
||||
if (list->len >= list->cap) {
|
||||
list->cap += DEFAULT_RENDER_LIST_CAPACITY*8;
|
||||
realloc_sublist(list->vert, 4, list->cap);
|
||||
realloc_sublist(list->normal, 3, list->cap);
|
||||
realloc_sublist(list->color, 4, list->cap);
|
||||
realloc_sublist(list->secondary, 4, list->cap);
|
||||
realloc_sublist(list->fogcoord, 1, list->cap);
|
||||
for (int a=0; a<list->maxtex; a++)
|
||||
realloc_sublist(list->tex[a], 4, list->cap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resize_merger_indices(int cap) {
|
||||
if(cap<glstate->merger_indice_cap)
|
||||
return;
|
||||
glstate->merger_indice_cap = ((glstate->merger_indice_cap+cap+512)>>9)<<9;
|
||||
glstate->merger_indices = (GLushort*)realloc(glstate->merger_indices, glstate->merger_indice_cap*sizeof(GLushort));
|
||||
}
|
||||
|
||||
void resize_indices_renderlist(renderlist_t *list, int n) {
|
||||
if (!list->indices || list->shared_indices)
|
||||
return;
|
||||
if (list->use_glstate) {
|
||||
resize_merger_indices(list->ilen+n);
|
||||
list->indices = glstate->merger_indices;
|
||||
} else {
|
||||
if(list->ilen+n<list->indice_cap)
|
||||
return;
|
||||
list->indice_cap = ((list->indice_cap+n+511)>>9)<<9;
|
||||
list->indices = (GLushort*)realloc(list->indices, list->indice_cap*sizeof(GLushort));
|
||||
}
|
||||
}
|
||||
|
||||
void adjust_renderlist(renderlist_t *list) {
|
||||
if (! list->open)
|
||||
return;
|
||||
|
||||
list->stage = STAGE_LAST;
|
||||
list->open = false;
|
||||
if(hardext.esversion==1) // no more adjustment needed for ES2
|
||||
for (int a=0; a<list->maxtex; a++) {
|
||||
const GLint itarget = get_target(glstate->enable.texture[a]);
|
||||
gltexture_t *bound = (itarget>=0)?glstate->texture.bound[a][itarget]:NULL;
|
||||
// in case of Texture bounding inside a list
|
||||
if (list->set_texture && (list->tmu == a))
|
||||
bound = gl4es_getTexture(list->target_texture, list->texture);
|
||||
// GL_ARB_texture_rectangle
|
||||
if ((list->tex[a]) && (itarget == ENABLED_TEXTURE_RECTANGLE) && (bound)) {
|
||||
tex_coord_rect_arb(list->tex[a], list->tex_stride[a]>>2, list->len, bound->width, bound->height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderlist_t* end_renderlist(renderlist_t *list) {
|
||||
if (!list || ! list->open)
|
||||
return list;
|
||||
|
||||
adjust_renderlist(list);
|
||||
|
||||
switch (list->mode) {
|
||||
case GL_QUADS:
|
||||
if (((list->indices) && (list->ilen==4)) || ((list->indices==NULL) && (list->len==4))) {
|
||||
list->mode = GL_TRIANGLE_FAN;
|
||||
} else {
|
||||
renderlist_quads2triangles(list);
|
||||
}
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
list->mode = GL_TRIANGLE_FAN;
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
list->mode = GL_TRIANGLE_STRIP;
|
||||
break;
|
||||
}
|
||||
if(list->prev && isempty_renderlist(list)) {
|
||||
renderlist_t *p = list;
|
||||
list = list->prev;
|
||||
list->next = NULL;
|
||||
p->prev = NULL;
|
||||
free_renderlist(p);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
renderlist_t* recycle_renderlist(renderlist_t *list, GLenum mode) {
|
||||
if(isempty_renderlist(list) || (ispurerender_renderlist(list) && list->len==0)) {
|
||||
list->mode_init = mode;
|
||||
list->mode = mode;
|
||||
list->stage=STAGE_DRAW;
|
||||
if (list->post_color) {
|
||||
list->post_color = 0;
|
||||
rlColor4f(list, list->post_colors[0], list->post_colors[1], list->post_colors[2], list->post_colors[3]);
|
||||
}
|
||||
if (list->post_normal) {
|
||||
list->post_normal = 0;
|
||||
rlNormal3f(list, list->post_normals[0], list->post_normals[1], list->post_normals[2]);
|
||||
}
|
||||
return list; // recycling...
|
||||
}
|
||||
// check if pending color...
|
||||
if (list->post_color) {
|
||||
list->post_color = 0;
|
||||
rlColor4f(list, list->post_colors[0], list->post_colors[1], list->post_colors[2], list->post_colors[3]);
|
||||
}
|
||||
if (list->post_normal) {
|
||||
list->post_normal = 0;
|
||||
rlNormal3f(list, list->post_normals[0], list->post_normals[1], list->post_normals[2]);
|
||||
}
|
||||
// check if list needs to be converted to triangles / lines...
|
||||
GLushort *indices = NULL;
|
||||
#define pre_expand \
|
||||
if(list->use_glstate) {\
|
||||
resize_merger_indices(renderlist_getindicesize(list)); indices = glstate->merger_indices;\
|
||||
} else {\
|
||||
list->indice_cap = renderlist_getindicesize(list);\
|
||||
indices = (GLushort*)malloc(sizeof(GLushort)*list->indice_cap);\
|
||||
}
|
||||
#define post_expand \
|
||||
list->ilen = renderlist_getindicesize(list);\
|
||||
list->indices = indices
|
||||
|
||||
list->merger_mode = mode;
|
||||
switch(list->mode) {
|
||||
case GL_LINES:
|
||||
if(mode!=GL_LINES && !list->indices) {
|
||||
pre_expand;
|
||||
renderlist_createindices(list->len, indices, 0);
|
||||
post_expand;
|
||||
}
|
||||
break;
|
||||
case GL_LINE_LOOP:
|
||||
pre_expand;
|
||||
renderlist_lineloop_lines(list->indices, list->indices?list->ilen:list->len, indices, 0);
|
||||
post_expand;
|
||||
list->mode=GL_LINES;
|
||||
break;
|
||||
case GL_LINE_STRIP:
|
||||
pre_expand;
|
||||
renderlist_linestrip_lines(list->indices, list->indices?list->ilen:list->len, indices, 0);
|
||||
post_expand;
|
||||
list->mode=GL_LINES;
|
||||
break;
|
||||
case GL_TRIANGLES:
|
||||
if(mode!=GL_TRIANGLES && !list->indices) {
|
||||
pre_expand;
|
||||
renderlist_createindices(list->len, indices, 0);
|
||||
post_expand;
|
||||
}
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
case GL_TRIANGLE_FAN:
|
||||
pre_expand;
|
||||
renderlist_trianglefan_triangles(list->indices, list->indices?list->ilen:list->len, indices, 0);
|
||||
post_expand;
|
||||
list->mode=GL_TRIANGLES;
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
case GL_TRIANGLE_STRIP:
|
||||
pre_expand;
|
||||
renderlist_trianglestrip_triangles(list->indices, list->indices?list->ilen:list->len, indices, 0);
|
||||
post_expand;
|
||||
list->mode=GL_TRIANGLES;
|
||||
break;
|
||||
case GL_QUADS:
|
||||
pre_expand;
|
||||
renderlist_quads_triangles(list->indices, list->indices?list->ilen:list->len, indices, 0);
|
||||
post_expand;
|
||||
list->mode=GL_TRIANGLES;
|
||||
break;
|
||||
}
|
||||
#undef pre_expand
|
||||
#undef post_expand
|
||||
list->cur_istart = list->len;
|
||||
// All done
|
||||
list->stage=STAGE_DRAW;
|
||||
|
||||
return list;
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
#ifndef _GL4ES_LIST_H_
|
||||
#define _GL4ES_LIST_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "khash.h"
|
||||
#include "../config.h"
|
||||
#include "wrap/gles.h"
|
||||
#include "attributes.h"
|
||||
#include "gles.h"
|
||||
|
||||
typedef enum {
|
||||
STAGE_NONE = 0,
|
||||
STAGE_PUSH,
|
||||
STAGE_POP,
|
||||
STAGE_GLCALL,
|
||||
STAGE_RENDER,
|
||||
STAGE_FOG,
|
||||
STAGE_POINTPARAM,
|
||||
STAGE_MATRIX,
|
||||
STAGE_ACTIVETEX,
|
||||
STAGE_BINDTEX,
|
||||
STAGE_RASTER,
|
||||
STAGE_BITMAP,
|
||||
STAGE_MATERIAL,
|
||||
STAGE_COLOR_MATERIAL,
|
||||
STAGE_LIGHT,
|
||||
STAGE_LIGHTMODEL,
|
||||
STAGE_LINESTIPPLE,
|
||||
STAGE_TEXENV,
|
||||
STAGE_TEXGEN,
|
||||
STAGE_POLYGON,
|
||||
STAGE_DRAW,
|
||||
STAGE_POSTDRAW,
|
||||
STAGE_LAST
|
||||
} liststage_t;
|
||||
|
||||
static int StageExclusive[] = {
|
||||
0, // STAGE_NONE
|
||||
1, // STAGE_PUSH
|
||||
1, // STAGE_POP
|
||||
0, // STAGE_GLCALL
|
||||
1, // STAGE_RENDER
|
||||
1, // STAGE_FOG
|
||||
1, // STAGE_POINTPARAM
|
||||
1, // STAGE_MATRIX
|
||||
1, // STAGE_ACTIVETEX
|
||||
1, // STAGE_BINDTEX
|
||||
1, // STAGE_RASTER
|
||||
0, // STAGE_BITMAP
|
||||
0, // STAGE_MATERIAL
|
||||
1, // STAGE_COLOR_MATERIAL
|
||||
0, // STAGE_LIGHT
|
||||
1, // STAGE_LIGTMODEL
|
||||
1, // STAGE_LINESTIPPLE
|
||||
0, // STAGE_TEXENV
|
||||
0, // STAGE_TEXGEN
|
||||
1, // STAGE_POLYGON
|
||||
1, // STAGE_DRAW
|
||||
1, // STAGE_POSTDRAW (used for "pending", i.e. post glEnd(), in case a similar glBegin occurs)
|
||||
0 // STAGE_LAST
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int face;
|
||||
int pname;
|
||||
GLfloat color[4];
|
||||
int count;
|
||||
} rendermaterial_t;
|
||||
|
||||
typedef struct {
|
||||
int which;
|
||||
int pname;
|
||||
GLfloat color[4];
|
||||
int count;
|
||||
} renderlight_t;
|
||||
|
||||
typedef struct {
|
||||
int coord;
|
||||
int pname;
|
||||
GLfloat color[4];
|
||||
int count;
|
||||
} rendertexgen_t;
|
||||
|
||||
typedef struct {
|
||||
int target;
|
||||
int pname;
|
||||
GLfloat params[4];
|
||||
int count;
|
||||
} rendertexenv_t;
|
||||
|
||||
typedef struct {
|
||||
GLfloat xmove;
|
||||
GLfloat ymove;
|
||||
GLsizei width;
|
||||
GLsizei height;
|
||||
GLsizei nwidth;
|
||||
GLsizei nheight;
|
||||
GLfloat xorig;
|
||||
GLfloat yorig;
|
||||
GLfloat zoomx;
|
||||
GLfloat zoomy;
|
||||
GLboolean bitmap;
|
||||
GLuint texture;
|
||||
int *shared;
|
||||
} rasterlist_t;
|
||||
|
||||
KHASH_MAP_DECLARE_INT(material, rendermaterial_t *);
|
||||
KHASH_MAP_DECLARE_INT(light, renderlight_t *);
|
||||
KHASH_MAP_DECLARE_INT(texgen, rendertexgen_t *);
|
||||
KHASH_MAP_DECLARE_INT(texenv, rendertexenv_t *);
|
||||
|
||||
typedef struct _call_list_t {
|
||||
unsigned long len;
|
||||
unsigned long cap;
|
||||
packed_call_t **calls;
|
||||
} call_list_t;
|
||||
|
||||
typedef struct {
|
||||
GLsizei width;
|
||||
GLsizei height;
|
||||
GLfloat xorig;
|
||||
GLfloat yorig;
|
||||
GLfloat xmove;
|
||||
GLfloat ymove;
|
||||
GLubyte *bitmap;
|
||||
} bitmap_list_t;
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
int cap;
|
||||
bitmap_list_t *list;
|
||||
int *shared;
|
||||
} bitmaps_t;
|
||||
|
||||
typedef struct {
|
||||
GLenum mode_init;
|
||||
int ilen;
|
||||
} modeinit_t;
|
||||
|
||||
typedef struct _renderlist_t {
|
||||
unsigned long len;
|
||||
unsigned long ilen;
|
||||
unsigned long cap;
|
||||
GLenum mode;
|
||||
GLenum mode_init; // initial requested mode
|
||||
GLuint name;
|
||||
modeinit_t* mode_inits; // array of requested/len, for the merger
|
||||
int mode_init_cap;
|
||||
int mode_init_len;
|
||||
int mode_dimension;
|
||||
GLfloat lastNormal[3];
|
||||
GLfloat lastColors[4];
|
||||
GLfloat lastSecondaryColors[4];
|
||||
GLfloat lastFogCoord;
|
||||
int use_glstate;
|
||||
|
||||
int lastColorsSet;
|
||||
|
||||
int* shared_calls;
|
||||
call_list_t calls;
|
||||
|
||||
int *shared_arrays;
|
||||
GLfloat *vert;
|
||||
GLfloat *normal;
|
||||
GLfloat *color;
|
||||
GLfloat *secondary;
|
||||
GLfloat *fogcoord;
|
||||
GLfloat *tex[MAX_TEX];
|
||||
int vert_stride;
|
||||
int normal_stride;
|
||||
int color_stride;
|
||||
int secondary_stride;
|
||||
int fogcoord_stride;
|
||||
int tex_stride[MAX_TEX];
|
||||
GLuint vbo_array;
|
||||
GLuint vbo_indices;
|
||||
int use_vbo_array; // 0=Not evaluated, 1=No, 2=Yes
|
||||
int use_vbo_indices; // same
|
||||
GLfloat *vbo_vert;
|
||||
GLfloat *vbo_normal;
|
||||
GLfloat *vbo_color;
|
||||
GLfloat *vbo_secondary;
|
||||
GLfloat *vbo_fogcoord;
|
||||
GLfloat *vbo_tex[MAX_TEX];
|
||||
int *shared_indices;
|
||||
GLushort *indices;
|
||||
unsigned int indice_cap;
|
||||
int maxtex;
|
||||
GLenum merger_mode;
|
||||
int cur_istart; // used by glBegin/glEnd merger.
|
||||
|
||||
rasterlist_t *raster;
|
||||
|
||||
bitmaps_t *bitmaps;
|
||||
|
||||
liststage_t stage;
|
||||
|
||||
GLbitfield pushattribute;
|
||||
GLboolean popattribute;
|
||||
|
||||
int render_op;
|
||||
GLuint render_arg;
|
||||
|
||||
int raster_op;
|
||||
GLfloat raster_xyz[3];
|
||||
|
||||
int matrix_op;
|
||||
GLfloat matrix_val[16];
|
||||
|
||||
int fog_op;
|
||||
GLfloat fog_val[4];
|
||||
|
||||
int pointparam_op;
|
||||
GLfloat pointparam_val[4];
|
||||
|
||||
int linestipple_op;
|
||||
GLuint linestipple_factor, linestipple_pattern;
|
||||
|
||||
int post_color;
|
||||
GLfloat post_colors[4];
|
||||
int post_normal;
|
||||
GLfloat post_normals[3];
|
||||
|
||||
GLushort *ind_lines;
|
||||
int ind_line;
|
||||
GLfloat *final_colors;
|
||||
|
||||
int instanceCount;
|
||||
|
||||
khash_t(material) *material;
|
||||
GLenum colormat_face;
|
||||
GLenum colormat_mode;
|
||||
khash_t(light) *light;
|
||||
khash_t(texgen) *texgen;
|
||||
khash_t(texenv) *texenv;
|
||||
GLfloat *lightmodel;
|
||||
GLenum lightmodelparam;
|
||||
GLenum polygon_mode;
|
||||
GLboolean set_tmu; // TRUE is glActiveTexture called
|
||||
int tmu; // the current TMU...
|
||||
GLuint texture;
|
||||
GLenum target_texture;
|
||||
GLboolean set_texture;
|
||||
struct _renderlist_t *prev;
|
||||
struct _renderlist_t *next;
|
||||
GLboolean open;
|
||||
} renderlist_t;
|
||||
|
||||
KHASH_MAP_DECLARE_INT(gllisthead, renderlist_t*);
|
||||
|
||||
#define DEFAULT_CALL_LIST_CAPACITY 20
|
||||
#define DEFAULT_RENDER_LIST_CAPACITY 64
|
||||
|
||||
int rendermode_dimensions(GLenum mode);
|
||||
renderlist_t* recycle_renderlist(renderlist_t* list, GLenum mode);
|
||||
renderlist_t* NewDrawStage(renderlist_t* l, GLenum m);
|
||||
|
||||
#define NewStage(l, s) if (l->stage+StageExclusive[l->stage] > s) {l = extend_renderlist(l);} l->stage = s
|
||||
|
||||
renderlist_t* GetFirst(renderlist_t* list);
|
||||
|
||||
#define alloc_sublist(n, cap) \
|
||||
(GLfloat *)malloc(n * sizeof(GLfloat) * cap)
|
||||
|
||||
#define realloc_sublist(ref, n, cap) \
|
||||
if (ref) \
|
||||
ref = (GLfloat *)realloc(ref, n * sizeof(GLfloat) * cap)
|
||||
|
||||
#define realloc_merger_sublist(ref, n, cap) \
|
||||
ref = (GLfloat *)realloc(ref, n * sizeof(GLfloat) * cap)
|
||||
|
||||
renderlist_t *alloc_renderlist();
|
||||
renderlist_t *extend_renderlist(renderlist_t *list);
|
||||
void free_renderlist(renderlist_t *list);
|
||||
void draw_renderlist(renderlist_t *list);
|
||||
renderlist_t* end_renderlist(renderlist_t *list);
|
||||
bool isempty_renderlist(renderlist_t *list);
|
||||
void resize_renderlist(renderlist_t *list);
|
||||
renderlist_t *alloc_renderlist();
|
||||
int mode_needindices(GLenum m);
|
||||
void resize_indices_renderlist(renderlist_t *list, int n);
|
||||
void resize_merger_indices(int cap);
|
||||
int indices_getindicesize(GLenum mode, int len);
|
||||
void list_add_modeinit(renderlist_t* list, GLenum mode);
|
||||
void unshared_renderlist(renderlist_t *a, int cap);
|
||||
void unsharedindices_renderlist(renderlist_t* a, int cap);
|
||||
void redim_renderlist(renderlist_t *a, int cap);
|
||||
void prepareadd_renderlist(renderlist_t* a, int size_to_add);
|
||||
void doadd_renderlist(renderlist_t* a, GLenum mode, GLushort* indices, int count, int size_to_add);
|
||||
|
||||
void renderlist_createindices(int ilen, GLushort *indices, int count);
|
||||
void renderlist_lineloop_lines(GLushort *ind, int len, GLushort *indices, int count);
|
||||
void renderlist_linestrip_lines(GLushort *ind, int len, GLushort *indices, int count);
|
||||
void renderlist_trianglestrip_triangles(GLushort *ind, int len, GLushort *indices, int count);
|
||||
void renderlist_trianglefan_triangles(GLushort *ind, int len, GLushort *indices, int count);
|
||||
void renderlist_quads_triangles(GLushort *ind, int len, GLushort *indices, int count);
|
||||
|
||||
void rlActiveTexture(renderlist_t *list, GLenum texture );
|
||||
void rlBindTexture(renderlist_t *list, GLenum target, GLuint texture);
|
||||
void rlColor4f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b, GLfloat a) FASTMATH;
|
||||
void rlColor4fv(renderlist_t *list, GLfloat* v) FASTMATH;
|
||||
void rlMaterialfv(renderlist_t *list, GLenum face, GLenum pname, const GLfloat * params);
|
||||
void rlLightfv(renderlist_t *list, GLenum which, GLenum pname, const GLfloat * params);
|
||||
void rlTexGenfv(renderlist_t *list, GLenum coord, GLenum pname, const GLfloat * params);
|
||||
void rlTexEnvfv(renderlist_t *list, GLenum target, GLenum pname, const GLfloat * params);
|
||||
void rlTexEnviv(renderlist_t *list, GLenum target, GLenum pname, const GLint * params);
|
||||
void rlNormal3f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z) FASTMATH;
|
||||
void rlNormal3fv(renderlist_t *list, GLfloat* v) FASTMATH;
|
||||
void rlPushCall(renderlist_t *list, packed_call_t *data);
|
||||
void rlMultiTexCoord4f(renderlist_t *list, GLenum texture, GLfloat s, GLfloat t, GLfloat r, GLfloat q) FASTMATH;
|
||||
void rlMultiTexCoord2fv(renderlist_t *list, GLenum texture, GLfloat* v) FASTMATH;
|
||||
void rlMultiTexCoord4fv(renderlist_t *list, GLenum texture, GLfloat* v) FASTMATH;
|
||||
void rlVertex4f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z, GLfloat w) FASTMATH;
|
||||
void rlVertex3fv(renderlist_t *list, GLfloat* v) FASTMATH;
|
||||
void rlVertex4fv(renderlist_t *list, GLfloat* v) FASTMATH;
|
||||
void rlSecondary3f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b) FASTMATH;
|
||||
void rlRasterOp(renderlist_t *list, int op, GLfloat x, GLfloat y, GLfloat z) FASTMATH;
|
||||
void rlFogOp(renderlist_t *list, int op, const GLfloat* v);
|
||||
void rlPointParamOp(renderlist_t *list, int op, const GLfloat* v);
|
||||
void rlFogCoordf(renderlist_t *list, GLfloat coord);
|
||||
void rlEnd(renderlist_t *list);
|
||||
|
||||
#endif // _GL4ES_LIST_H_
|
||||
@@ -0,0 +1,864 @@
|
||||
#include "list.h"
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "wrap/gl4es.h"
|
||||
#include "fpe.h"
|
||||
#include "init.h"
|
||||
#include "line.h"
|
||||
#include "loader.h"
|
||||
#include "matrix.h"
|
||||
#include "texgen.h"
|
||||
#include "render.h"
|
||||
#include "fpe.h"
|
||||
|
||||
/* return 1 if failed, 2 if succeed */
|
||||
typedef struct array2vbo_s {
|
||||
uintptr_t real_base;
|
||||
uint32_t real_size;
|
||||
uint32_t stride;
|
||||
uintptr_t vbo_base;
|
||||
uintptr_t vbo_basebase;
|
||||
} array2vbo_t;
|
||||
|
||||
int list2VBO(renderlist_t* list)
|
||||
{
|
||||
LOAD_GLES2(glGenBuffers);
|
||||
LOAD_GLES2(glBufferData);
|
||||
LOAD_GLES2(glBufferSubData);
|
||||
array2vbo_t work[ATT_MAX] = {0};
|
||||
// list -> work
|
||||
int imax = 0;
|
||||
int len = list->len;
|
||||
if(list->vert) {
|
||||
work[imax].real_base = (uintptr_t)list->vert;
|
||||
work[imax].stride = list->vert_stride;
|
||||
if(!work[imax].stride) work[imax].stride = 4*4; // 4*GL_FLOAT
|
||||
work[imax].real_size = work[imax].stride*len;
|
||||
imax++;
|
||||
}
|
||||
if(list->color) {
|
||||
work[imax].real_base = (uintptr_t)list->color;
|
||||
work[imax].stride = list->color_stride;
|
||||
if(!work[imax].stride) work[imax].stride = 4*4; // 4*GL_FLOAT
|
||||
work[imax].real_size = work[imax].stride*len;
|
||||
imax++;
|
||||
}
|
||||
if(list->secondary) {
|
||||
work[imax].real_base = (uintptr_t)list->secondary;
|
||||
work[imax].stride = list->secondary_stride;
|
||||
if(!work[imax].stride) work[imax].stride = 4*4; // 4*GL_FLOAT
|
||||
work[imax].real_size = work[imax].stride*len;
|
||||
imax++;
|
||||
}
|
||||
if(list->fogcoord) {
|
||||
work[imax].real_base = (uintptr_t)list->fogcoord;
|
||||
work[imax].stride = list->fogcoord_stride;
|
||||
if(!work[imax].stride) work[imax].stride = 1*4; // 1*GL_FLOAT
|
||||
work[imax].real_size = work[imax].stride*len;
|
||||
imax++;
|
||||
}
|
||||
if(list->normal) {
|
||||
work[imax].real_base = (uintptr_t)list->normal;
|
||||
work[imax].stride = list->normal_stride;
|
||||
if(!work[imax].stride) work[imax].stride = 3*4; // 3*GL_FLOAT
|
||||
work[imax].real_size = work[imax].stride*len;
|
||||
imax++;
|
||||
}
|
||||
for (int a=0; a<list->maxtex; ++a) {
|
||||
if(list->tex[a]) {
|
||||
work[imax].real_base = (uintptr_t)list->tex[a];
|
||||
work[imax].stride = list->tex_stride[a];
|
||||
if(!work[imax].stride) work[imax].stride = 4*4; // 4*GL_FLOAT
|
||||
work[imax].real_size = work[imax].stride*len;
|
||||
imax++;
|
||||
}
|
||||
}
|
||||
// sort the real address...
|
||||
int sorted[ATT_MAX];
|
||||
for (int i=0; i<imax; ++i)
|
||||
sorted[i] = i;
|
||||
// bubble sort, array is small enough, and probably almost sorted
|
||||
for (int i=0; i<imax-1; ++i)
|
||||
for (int j=i+1; j<imax; ++j)
|
||||
if(work[sorted[i]].real_base > work[sorted[j]].real_base) {
|
||||
int tmp = sorted[i];
|
||||
sorted[i] = sorted[j];
|
||||
sorted[j] = tmp;
|
||||
}
|
||||
// get a base vbo offset
|
||||
uintptr_t vbo_base = 0;
|
||||
for (int i=0; i<imax; ++i) {
|
||||
uintptr_t base = vbo_base;
|
||||
uintptr_t basebase = vbo_base;
|
||||
array2vbo_t *r = work+sorted[i];
|
||||
if(i) for(int j=i-1; j<i; ++j) {
|
||||
array2vbo_t *t = work+sorted[j];
|
||||
if(r->real_base<t->real_base+t->real_size) {
|
||||
base = r->vbo_base + (r->real_base - t->real_base);
|
||||
basebase = r->vbo_basebase;
|
||||
break;
|
||||
}
|
||||
}
|
||||
r->vbo_base = base;
|
||||
r->vbo_basebase = basebase;
|
||||
if(base == basebase)
|
||||
vbo_base += r->real_size;
|
||||
}
|
||||
if(!vbo_base) // no data?!
|
||||
return 1;
|
||||
// Create the VBO and fill the data
|
||||
gles_glGenBuffers(1, &list->vbo_array);
|
||||
bindBuffer(GL_ARRAY_BUFFER, list->vbo_array);
|
||||
gles_glBufferData(GL_ARRAY_BUFFER, vbo_base, NULL, GL_STATIC_DRAW);
|
||||
for(int i=0; i<imax; ++i) {
|
||||
array2vbo_t *r = work+sorted[i];
|
||||
if(r->vbo_base==r->vbo_basebase)
|
||||
gles_glBufferSubData(GL_ARRAY_BUFFER, r->vbo_basebase, r->real_size, (void*)r->real_base);
|
||||
}
|
||||
// work -> list
|
||||
imax = 0;
|
||||
if(list->vert) {
|
||||
list->vbo_vert = (GLfloat*)work[imax].vbo_base;
|
||||
imax++;
|
||||
}
|
||||
if(list->color) {
|
||||
list->vbo_color = (GLfloat*)work[imax].vbo_base;
|
||||
imax++;
|
||||
}
|
||||
if(list->secondary) {
|
||||
list->vbo_secondary = (GLfloat*)work[imax].vbo_base;
|
||||
imax++;
|
||||
}
|
||||
if(list->fogcoord) {
|
||||
list->vbo_fogcoord = (GLfloat*)work[imax].vbo_base;
|
||||
imax++;
|
||||
}
|
||||
if(list->normal) {
|
||||
list->vbo_normal = (GLfloat*)work[imax].vbo_base;
|
||||
imax++;
|
||||
}
|
||||
for (int a=0; a<list->maxtex; ++a) {
|
||||
if(list->tex[a]) {
|
||||
list->vbo_tex[a] = (GLfloat*)work[imax].vbo_base;
|
||||
imax++;
|
||||
}
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
typedef struct save_vbo_s {
|
||||
GLuint real_buffer;
|
||||
const GLvoid* real_pointer;
|
||||
glbuffer_t* buffer;
|
||||
} save_vbo_t;
|
||||
|
||||
void listActiveVBO(renderlist_t* list, save_vbo_t* saved) {
|
||||
if(list->vert) {
|
||||
saved[ATT_VERTEX].real_buffer = glstate->vao->vertexattrib[ATT_VERTEX].real_buffer;
|
||||
saved[ATT_VERTEX].real_pointer = glstate->vao->vertexattrib[ATT_VERTEX].real_pointer;
|
||||
saved[ATT_VERTEX].buffer = glstate->vao->vertexattrib[ATT_VERTEX].buffer;
|
||||
glstate->vao->vertexattrib[ATT_VERTEX].real_buffer = list->vbo_array;
|
||||
glstate->vao->vertexattrib[ATT_VERTEX].real_pointer = list->vbo_vert;
|
||||
glstate->vao->vertexattrib[ATT_VERTEX].buffer = NULL;
|
||||
}
|
||||
if(list->color) {
|
||||
saved[ATT_COLOR].real_buffer = glstate->vao->vertexattrib[ATT_COLOR].real_buffer;
|
||||
saved[ATT_COLOR].real_pointer = glstate->vao->vertexattrib[ATT_COLOR].real_pointer;
|
||||
saved[ATT_COLOR].buffer = glstate->vao->vertexattrib[ATT_COLOR].buffer;
|
||||
glstate->vao->vertexattrib[ATT_COLOR].real_buffer = list->vbo_array;
|
||||
glstate->vao->vertexattrib[ATT_COLOR].real_pointer = list->vbo_color;
|
||||
glstate->vao->vertexattrib[ATT_COLOR].buffer = NULL;
|
||||
}
|
||||
if(list->secondary) {
|
||||
saved[ATT_SECONDARY].real_buffer = glstate->vao->vertexattrib[ATT_SECONDARY].real_buffer;
|
||||
saved[ATT_SECONDARY].real_pointer = glstate->vao->vertexattrib[ATT_SECONDARY].real_pointer;
|
||||
saved[ATT_SECONDARY].buffer = glstate->vao->vertexattrib[ATT_SECONDARY].buffer;
|
||||
glstate->vao->vertexattrib[ATT_SECONDARY].real_buffer = list->vbo_array;
|
||||
glstate->vao->vertexattrib[ATT_SECONDARY].real_pointer = list->vbo_secondary;
|
||||
glstate->vao->vertexattrib[ATT_SECONDARY].buffer = NULL;
|
||||
}
|
||||
if(list->fogcoord) {
|
||||
saved[ATT_FOGCOORD].real_buffer = glstate->vao->vertexattrib[ATT_FOGCOORD].real_buffer;
|
||||
saved[ATT_FOGCOORD].real_pointer = glstate->vao->vertexattrib[ATT_FOGCOORD].real_pointer;
|
||||
saved[ATT_FOGCOORD].buffer = glstate->vao->vertexattrib[ATT_FOGCOORD].buffer;
|
||||
glstate->vao->vertexattrib[ATT_FOGCOORD].real_buffer = list->vbo_array;
|
||||
glstate->vao->vertexattrib[ATT_FOGCOORD].real_pointer = list->vbo_fogcoord;
|
||||
glstate->vao->vertexattrib[ATT_FOGCOORD].buffer = NULL;
|
||||
}
|
||||
if(list->normal) {
|
||||
saved[ATT_NORMAL].real_buffer = glstate->vao->vertexattrib[ATT_NORMAL].real_buffer;
|
||||
saved[ATT_NORMAL].real_pointer = glstate->vao->vertexattrib[ATT_NORMAL].real_pointer;
|
||||
saved[ATT_NORMAL].buffer = glstate->vao->vertexattrib[ATT_NORMAL].buffer;
|
||||
glstate->vao->vertexattrib[ATT_NORMAL].real_buffer = list->vbo_array;
|
||||
glstate->vao->vertexattrib[ATT_NORMAL].real_pointer = list->vbo_normal;
|
||||
glstate->vao->vertexattrib[ATT_NORMAL].buffer = NULL;
|
||||
}
|
||||
for (int a=0; a<list->maxtex; ++a) {
|
||||
if(list->tex[a]) {
|
||||
saved[ATT_MULTITEXCOORD0+a].real_buffer = glstate->vao->vertexattrib[ATT_MULTITEXCOORD0+a].real_buffer;
|
||||
saved[ATT_MULTITEXCOORD0+a].real_pointer = glstate->vao->vertexattrib[ATT_MULTITEXCOORD0+a].real_pointer;
|
||||
saved[ATT_MULTITEXCOORD0+a].buffer = glstate->vao->vertexattrib[ATT_MULTITEXCOORD0+a].buffer;
|
||||
glstate->vao->vertexattrib[ATT_MULTITEXCOORD0+a].real_buffer = list->vbo_array;
|
||||
glstate->vao->vertexattrib[ATT_MULTITEXCOORD0+a].real_pointer = list->vbo_tex[a];
|
||||
glstate->vao->vertexattrib[ATT_MULTITEXCOORD0+a].buffer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
void listInactiveVBO(renderlist_t* list, save_vbo_t* saved) {
|
||||
if(list->vert) {
|
||||
glstate->vao->vertexattrib[ATT_VERTEX].real_buffer = saved[ATT_VERTEX].real_buffer;
|
||||
glstate->vao->vertexattrib[ATT_VERTEX].real_pointer = saved[ATT_VERTEX].real_pointer;
|
||||
glstate->vao->vertexattrib[ATT_VERTEX].buffer = saved[ATT_VERTEX].buffer;
|
||||
}
|
||||
if(list->color) {
|
||||
glstate->vao->vertexattrib[ATT_COLOR].real_buffer = saved[ATT_COLOR].real_buffer;
|
||||
glstate->vao->vertexattrib[ATT_COLOR].real_pointer = saved[ATT_COLOR].real_pointer;
|
||||
glstate->vao->vertexattrib[ATT_COLOR].buffer = saved[ATT_COLOR].buffer;
|
||||
}
|
||||
if(list->secondary) {
|
||||
glstate->vao->vertexattrib[ATT_SECONDARY].real_buffer = saved[ATT_SECONDARY].real_buffer;
|
||||
glstate->vao->vertexattrib[ATT_SECONDARY].real_pointer = saved[ATT_SECONDARY].real_pointer;
|
||||
glstate->vao->vertexattrib[ATT_SECONDARY].buffer = saved[ATT_SECONDARY].buffer;
|
||||
}
|
||||
if(list->fogcoord) {
|
||||
glstate->vao->vertexattrib[ATT_FOGCOORD].real_buffer = saved[ATT_FOGCOORD].real_buffer;
|
||||
glstate->vao->vertexattrib[ATT_FOGCOORD].real_pointer = saved[ATT_FOGCOORD].real_pointer;
|
||||
glstate->vao->vertexattrib[ATT_FOGCOORD].buffer = saved[ATT_FOGCOORD].buffer;
|
||||
}
|
||||
if(list->normal) {
|
||||
glstate->vao->vertexattrib[ATT_NORMAL].real_buffer = saved[ATT_NORMAL].real_buffer;
|
||||
glstate->vao->vertexattrib[ATT_NORMAL].real_pointer = saved[ATT_NORMAL].real_pointer;
|
||||
glstate->vao->vertexattrib[ATT_NORMAL].buffer = saved[ATT_NORMAL].buffer;
|
||||
}
|
||||
for (int a=0; a<list->maxtex; ++a) {
|
||||
if(list->tex[a]) {
|
||||
glstate->vao->vertexattrib[ATT_MULTITEXCOORD0+a].real_buffer = saved[ATT_MULTITEXCOORD0+a].real_buffer;
|
||||
glstate->vao->vertexattrib[ATT_MULTITEXCOORD0+a].real_pointer = saved[ATT_MULTITEXCOORD0+a].real_pointer;
|
||||
glstate->vao->vertexattrib[ATT_MULTITEXCOORD0+a].buffer = saved[ATT_MULTITEXCOORD0+a].buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fill_lineIndices(modeinit_t *modes, int length, GLenum mode, GLushort* indices, GLushort *ind_line)
|
||||
{
|
||||
#define ind(a) indices?indices[a]:(a)
|
||||
int k=0;
|
||||
int i=0;
|
||||
for (int m=0; m<length; m++) {
|
||||
GLenum mode_init = modes[k].mode_init;
|
||||
int len = modes[k].ilen;
|
||||
switch (mode) {
|
||||
case GL_TRIANGLE_STRIP:
|
||||
// first 3 points a triangle, then a 2 lines per new point
|
||||
if (len>2) {
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind(i+1);
|
||||
i+=2;
|
||||
for (; i<len; i++) {
|
||||
ind_line[k++] = ind(i-2); ind_line[k++] = ind(i);
|
||||
ind_line[k++] = ind(i-1); ind_line[k++] = ind(i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_TRIANGLE_FAN:
|
||||
if(mode_init==GL_QUAD_STRIP) {
|
||||
// first 4 points is a quad, then 2 points per new quad
|
||||
if (len>3) {
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind(i+1);
|
||||
i+=2;
|
||||
for (; i<len-1; i+=2) {
|
||||
ind_line[k++] = ind(i-1); ind_line[k++] = ind(i);
|
||||
ind_line[k++] = ind(i-2); ind_line[k++] = ind(i+1);
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind(i+1);
|
||||
}
|
||||
}
|
||||
} else if(mode_init==GL_POLYGON) {
|
||||
if (len) {
|
||||
int z = i;
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind(i+1);
|
||||
++i;
|
||||
for (; i<len; i++) {
|
||||
ind_line[k++] = ind(i-1); ind_line[k++] = ind(i);
|
||||
}
|
||||
ind_line[k++] = ind(len-1); ind_line[k++] = ind(z);
|
||||
}
|
||||
} else {
|
||||
// first 3 points a triangle, then a 2 lines per new point too
|
||||
if (len>2) {
|
||||
int z = i;
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind(i+1);
|
||||
i+=2;
|
||||
for (; i<len; i++) {
|
||||
ind_line[k++] = ind(z); ind_line[k++] = ind(i);
|
||||
ind_line[k++] = ind(i-1); ind_line[k++] = ind(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_TRIANGLES:
|
||||
switch (mode_init) {
|
||||
case GL_TRIANGLE_STRIP:
|
||||
case GL_TRIANGLE_FAN:
|
||||
case GL_TRIANGLES:
|
||||
if(len>2) {
|
||||
// 1 triangle -> 3 lines => 6 half-lines !
|
||||
for (; i<len-2; i+=3) {
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind(i+1);
|
||||
ind_line[k++] = ind(i+1); ind_line[k++] = ind(i+2);
|
||||
ind_line[k++] = ind(i+2); ind_line[k++] = ind(i+0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_QUADS:
|
||||
if (len>3) {
|
||||
// 4 lines per quads, but dest may already be a triangles list...
|
||||
if (len==4) {
|
||||
// just 1 Quad
|
||||
for (; i<4; i++) {
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind((i+1)%4);
|
||||
}
|
||||
} else {
|
||||
// list of triangles, 2 per quads...
|
||||
for (; i<len-5; i+=6) {
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind(i+1);
|
||||
ind_line[k++] = ind(i+1); ind_line[k++] = ind(i+2);
|
||||
ind_line[k++] = ind(i+2); ind_line[k++] = ind(i+5);
|
||||
ind_line[k++] = ind(i+5); ind_line[k++] = ind(i+0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
// first 4 points is a quad, then 2 points per new quad
|
||||
if (len>3) {
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind(i+1);
|
||||
i+=2;
|
||||
for (; i<len-1; i+=2) {
|
||||
ind_line[k++] = ind(i-1); ind_line[k++] = ind(i);
|
||||
ind_line[k++] = ind(i-2); ind_line[k++] = ind(i+1);
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind(i+1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
// if polygons have been merged, then info is lost...
|
||||
if (len) {
|
||||
int z = i;
|
||||
ind_line[k++] = ind(i+0); ind_line[k++] = ind(i+1);
|
||||
++i;
|
||||
for (; i<len; i++) {
|
||||
ind_line[k++] = ind(i-1); ind_line[k++] = ind(i);
|
||||
}
|
||||
ind_line[k++] = ind(len-1); ind_line[k++] = ind(z);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef ind
|
||||
return k;
|
||||
}
|
||||
|
||||
void draw_renderlist(renderlist_t *list) {
|
||||
if (!list) return;
|
||||
// go to 1st...
|
||||
while (list->prev) list = list->prev;
|
||||
// ok, go on now, draw everything
|
||||
//printf("draw_renderlist %p, size=%i, mode=%s(%s), ilen=%d, next=%p, color=%p, secondarycolor=%p fogcoord=%p\n", list, list->len, PrintEnum(list->mode), PrintEnum(list->mode_init), list->ilen, list->next, list->color, list->secondary, list->fogcoord);
|
||||
LOAD_GLES_FPE(glDrawArrays);
|
||||
LOAD_GLES_FPE(glDrawElements);
|
||||
LOAD_GLES_FPE(glVertexPointer);
|
||||
LOAD_GLES_FPE(glNormalPointer);
|
||||
LOAD_GLES_FPE(glColorPointer);
|
||||
LOAD_GLES_FPE(glTexCoordPointer);
|
||||
LOAD_GLES_FPE(glEnable);
|
||||
LOAD_GLES_FPE(glDisable);
|
||||
gl4es_glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
|
||||
|
||||
int old_tex;
|
||||
GLushort *indices;
|
||||
int use_texgen[MAX_TEX] = {0};
|
||||
old_tex = glstate->texture.client;
|
||||
GLuint cur_tex = old_tex;
|
||||
GLint needclean[MAX_TEX] = {0};
|
||||
bool stipple;
|
||||
int stipple_tmu;
|
||||
GLenum stipple_env;
|
||||
GLenum stipple_afunc;
|
||||
GLfloat stipple_aref;
|
||||
int stipple_tex2d;
|
||||
int stipple_alpha;
|
||||
int stipple_old;
|
||||
int stipple_texgen[4];
|
||||
|
||||
do {
|
||||
// close if needed!
|
||||
if (list->open)
|
||||
list = end_renderlist(list);
|
||||
// push/pop attributes
|
||||
if (list->pushattribute)
|
||||
gl4es_glPushAttrib(list->pushattribute);
|
||||
if (list->popattribute)
|
||||
gl4es_glPopAttrib();
|
||||
call_list_t *cl = &list->calls;
|
||||
if (cl->len > 0) {
|
||||
for (int i = 0; i < cl->len; i++) {
|
||||
glPackedCall(cl->calls[i]);
|
||||
}
|
||||
}
|
||||
if(list->render_op) {
|
||||
switch(list->render_op) {
|
||||
case 1: gl4es_glInitNames(); break;
|
||||
case 2: gl4es_glPopName(); break;
|
||||
case 3: gl4es_glPushName(list->render_arg); break;
|
||||
case 4: gl4es_glLoadName(list->render_arg); break;
|
||||
}
|
||||
}
|
||||
if (list->fog_op) {
|
||||
gl4es_glFogfv(GL_FOG_COLOR, list->fog_val);
|
||||
}
|
||||
if (list->pointparam_op) {
|
||||
switch (list->pointparam_op) {
|
||||
case 1: // GL_POINT_DISTANCE_ATTENUATION
|
||||
gl4es_glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION , list->pointparam_val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (list->matrix_op) {
|
||||
switch (list->matrix_op) {
|
||||
case 1: // load
|
||||
gl4es_glLoadMatrixf(list->matrix_val);
|
||||
break;
|
||||
case 2: // mult
|
||||
gl4es_glMultMatrixf(list->matrix_val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (list->set_tmu) {
|
||||
gl4es_glActiveTexture(GL_TEXTURE0+list->tmu);
|
||||
}
|
||||
if (list->set_texture) {
|
||||
gl4es_glBindTexture(list->target_texture, list->texture);
|
||||
}
|
||||
// raster
|
||||
if (list->raster_op) {
|
||||
if (list->raster_op==1) {
|
||||
gl4es_glRasterPos3f(list->raster_xyz[0], list->raster_xyz[1], list->raster_xyz[2]);
|
||||
} else if (list->raster_op==2) {
|
||||
gl4es_glWindowPos3f(list->raster_xyz[0], list->raster_xyz[1], list->raster_xyz[2]);
|
||||
} else if (list->raster_op==3) {
|
||||
gl4es_glPixelZoom(list->raster_xyz[0], list->raster_xyz[1]);
|
||||
} else if ((list->raster_op&0x10000) == 0x10000) {
|
||||
gl4es_glPixelTransferf(list->raster_op&0xFFFF, list->raster_xyz[0]);
|
||||
}
|
||||
}
|
||||
if (list->raster) {
|
||||
rasterlist_t * r = list->raster;
|
||||
//glBitmap(r->width, r->height, r->xorig, r->yorig, r->xmove, r->ymove, r->raster);
|
||||
render_raster_list(list->raster);
|
||||
}
|
||||
// bitmaps
|
||||
if (list->bitmaps) {
|
||||
for (int i=0; i<list->bitmaps->count; i++) {
|
||||
bitmap_list_t *l = &list->bitmaps->list[i];
|
||||
gl4es_glBitmap(l->width, l->height, l->xorig, l->yorig, l->xmove, l->ymove, l->bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
if (list->material) {
|
||||
khash_t(material) *map = list->material;
|
||||
rendermaterial_t *m;
|
||||
kh_foreach_value(map, m,
|
||||
switch (m->pname) {
|
||||
case GL_SHININESS:
|
||||
gl4es_glMaterialf(m->face, m->pname, m->color[0]);
|
||||
break;
|
||||
default:
|
||||
gl4es_glMaterialfv(m->face, m->pname, m->color);
|
||||
}
|
||||
)
|
||||
}
|
||||
if (list->colormat_face)
|
||||
gl4es_glColorMaterial(list->colormat_face, list->colormat_mode);
|
||||
if (list->light) {
|
||||
khash_t(light) *lig = list->light;
|
||||
renderlight_t *m;
|
||||
kh_foreach_value(lig, m,
|
||||
switch (m->pname) {
|
||||
default:
|
||||
gl4es_glLightfv(m->which, m->pname, m->color);
|
||||
}
|
||||
)
|
||||
}
|
||||
if (list->lightmodel) {
|
||||
gl4es_glLightModelfv(list->lightmodelparam, list->lightmodel);
|
||||
}
|
||||
|
||||
if (list->linestipple_op) {
|
||||
gl4es_glLineStipple(list->linestipple_factor, list->linestipple_pattern);
|
||||
}
|
||||
|
||||
if (list->texenv) {
|
||||
khash_t(texenv) *tgn = list->texenv;
|
||||
rendertexenv_t *m;
|
||||
kh_foreach_value(tgn, m,
|
||||
gl4es_glTexEnvfv(m->target, m->pname, m->params);
|
||||
)
|
||||
}
|
||||
|
||||
if (list->texgen) {
|
||||
khash_t(texgen) *tgn = list->texgen;
|
||||
rendertexgen_t *m;
|
||||
kh_foreach_value(tgn, m,
|
||||
gl4es_glTexGenfv(m->coord, m->pname, m->color);
|
||||
)
|
||||
}
|
||||
|
||||
if (list->polygon_mode) {
|
||||
gl4es_glPolygonMode(GL_FRONT_AND_BACK, list->polygon_mode);
|
||||
}
|
||||
|
||||
if (! list->len)
|
||||
continue;
|
||||
|
||||
int use_vbo_array = list->use_vbo_array;
|
||||
if(!use_vbo_array && (hardext.esversion==1 || globals4es.usevbo==0 || !list->name)) {
|
||||
use_vbo_array = 1;
|
||||
}
|
||||
int use_vbo_indices = list->use_vbo_indices;
|
||||
if(!use_vbo_indices && (hardext.esversion==1 || globals4es.usevbo==0 || !list->name)) {
|
||||
use_vbo_indices = 1;
|
||||
}
|
||||
if (list->vert) {
|
||||
fpe_glEnableClientState(GL_VERTEX_ARRAY);
|
||||
gles_glVertexPointer(4, GL_FLOAT, list->vert_stride, list->vert);
|
||||
} else {
|
||||
fpe_glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
if (list->normal) {
|
||||
fpe_glEnableClientState(GL_NORMAL_ARRAY);
|
||||
gles_glNormalPointer(GL_FLOAT, list->normal_stride, list->normal);
|
||||
} else {
|
||||
fpe_glDisableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
indices = list->indices;
|
||||
|
||||
if(glstate->raster.bm_drawing)
|
||||
bitmap_flush();
|
||||
if (list->color) {
|
||||
fpe_glEnableClientState(GL_COLOR_ARRAY);
|
||||
if (glstate->enable.color_sum && (list->secondary) && hardext.esversion==1 && !list->use_glstate) {
|
||||
if(!list->final_colors) {
|
||||
list->final_colors=(GLfloat*)malloc(list->len * 4 * sizeof(GLfloat));
|
||||
if (indices) {
|
||||
for (int i=0; i<list->ilen; i++)
|
||||
for (int j=0; j<4; j++) {
|
||||
const int k=indices[i]*4+j;
|
||||
list->final_colors[k]=list->color[k] + list->secondary[k];
|
||||
}
|
||||
} else {
|
||||
for (int i=0; i<list->len*4; i++)
|
||||
list->final_colors[i]=list->color[i] + list->secondary[i];
|
||||
}
|
||||
}
|
||||
gles_glColorPointer(4, GL_FLOAT, 0, list->final_colors);
|
||||
} else {
|
||||
//printf("colors=%f, %f, %f, %f / %f, %f, %f, %f\n", list->color[0],list->color[1],list->color[2],list->color[3], list->color[4],list->color[5],list->color[6],list->color[7]);
|
||||
gles_glColorPointer(4, GL_FLOAT, list->color_stride, list->color);
|
||||
}
|
||||
} else {
|
||||
fpe_glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
if(hardext.esversion > 1) {
|
||||
// secondary color only on ES2+
|
||||
if (glstate->enable.color_sum && (list->secondary)) {
|
||||
fpe_glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
|
||||
fpe_glSecondaryColorPointer(4, GL_FLOAT, list->secondary_stride, list->secondary);
|
||||
} else {
|
||||
fpe_glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
|
||||
}
|
||||
// fog coord only on ES2+
|
||||
if ((glstate->fog.coord_src==GL_FOG_COORD) && (list->fogcoord)) {
|
||||
fpe_glEnableClientState(GL_FOG_COORD_ARRAY);
|
||||
fpe_glFogCoordPointer(GL_FLOAT, list->fogcoord_stride, list->fogcoord);
|
||||
} else {
|
||||
fpe_glDisableClientState(GL_FOG_COORD_ARRAY);
|
||||
}
|
||||
}
|
||||
#define TEXTURE(A) if (cur_tex!=A) {gl4es_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;}
|
||||
stipple = false;
|
||||
if ((list->mode == GL_LINES || list->mode == GL_LINE_STRIP || list->mode == GL_LINE_LOOP)
|
||||
&& glstate->enable.line_stipple) {
|
||||
stipple = true;
|
||||
if(get_target(glstate->enable.texture[0])!=-1)
|
||||
stipple_tmu = 1;
|
||||
else
|
||||
stipple_tmu = 0;
|
||||
}
|
||||
if (stipple) {
|
||||
if(!use_vbo_array) use_vbo_array = 1;
|
||||
stipple_old = glstate->gleshard->active;
|
||||
if(glstate->gleshard->active!=stipple_tmu) {
|
||||
LOAD_GLES(glActiveTexture);
|
||||
gl4es_glActiveTexture(GL_TEXTURE0+stipple_tmu);
|
||||
}
|
||||
TEXTURE(stipple_tmu);
|
||||
GLenum matmode;
|
||||
gl4es_glGetIntegerv(GL_MATRIX_MODE, (GLint *) &matmode);
|
||||
gl4es_glMatrixMode(GL_TEXTURE);
|
||||
gl4es_glPushMatrix();
|
||||
gl4es_glLoadIdentity();
|
||||
gl4es_glMatrixMode(matmode);
|
||||
stipple_env = glstate->texenv[stipple_tmu].env.mode;
|
||||
gl4es_glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
stipple_tex2d = gl4es_glIsEnabled(GL_TEXTURE_2D);
|
||||
stipple_alpha = gl4es_glIsEnabled(GL_ALPHA_TEST);
|
||||
gl4es_glEnable(GL_TEXTURE_2D);
|
||||
gl4es_glEnable(GL_ALPHA_TEST);
|
||||
for (int k=0; k<4; k++) {
|
||||
stipple_texgen[k] = gl4es_glIsEnabled(GL_TEXTURE_GEN_S+k);
|
||||
if(stipple_texgen[k])
|
||||
gl4es_glDisable(GL_TEXTURE_GEN_S+k);
|
||||
}
|
||||
stipple_afunc = glstate->alphafunc;
|
||||
stipple_aref = glstate->alpharef;
|
||||
gl4es_glAlphaFunc(GL_GREATER, 0.0f);
|
||||
bind_stipple_tex();
|
||||
modeinit_t tmp; tmp.mode_init = list->mode_init; tmp.ilen=list->ilen?list->ilen:list->len;
|
||||
list->tex[stipple_tmu] = gen_stipple_tex_coords(list->vert, list->indices, list->mode_inits?list->mode_inits:&tmp, list->vert_stride, list->mode_inits?list->mode_init_len:1, (list->use_glstate)?(list->vert+8+stipple_tmu*4):NULL);
|
||||
}
|
||||
#define RS(A, len) if(glstate->texgenedsz[A]<len) {free(glstate->texgened[A]); glstate->texgened[A]=malloc(4*sizeof(GLfloat)*len); glstate->texgenedsz[A]=len; } use_texgen[A]=1
|
||||
// cannot use list->maxtex because some TMU can be using TexGen or point sprites...
|
||||
if(hardext.esversion==1) {
|
||||
for (int a=0; a<hardext.maxtex; a++) {
|
||||
if(glstate->enable.texture[a] || (stipple && a==stipple_tmu)) {
|
||||
const GLint itarget = (stipple && a==stipple_tmu)?ENABLED_TEX2D:get_target(glstate->enable.texture[a]);
|
||||
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])) {
|
||||
TEXTURE(a);
|
||||
RS(a, list->len);
|
||||
gen_tex_coords(list->vert, list->normal, &glstate->texgened[a], list->len, &needclean[a], a, (list->ilen<list->len)?indices:NULL, (list->ilen<list->len)?list->ilen:0);
|
||||
} else if ((list->tex[a]==NULL) && !(list->mode==GL_POINT && glstate->texture.pscoordreplace[a])) {
|
||||
RS(a, list->len);
|
||||
gen_tex_coords(list->vert, list->normal, &glstate->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][itarget];
|
||||
if((list->tex[a] || (use_texgen[a] && !needclean[a])) && ((!(globals4es.texmat || glstate->texture_matrix[a]->identity)) || (bound->adjust))) {
|
||||
if(!use_texgen[a]) {
|
||||
RS(a, list->len);
|
||||
if(list->tex_stride[a]) {
|
||||
GLfloat *src = list->tex[a];
|
||||
GLfloat *dst = glstate->texgened[a];
|
||||
int stride = list->tex_stride[a]>>2; // stride need to be a multiple of 4 (i.e. sizeof(GLfloat))
|
||||
for (int ii=0; ii<list->len; ii++) {
|
||||
memcpy(dst, src, 4*sizeof(GLfloat));
|
||||
src+=stride;
|
||||
dst+=4;
|
||||
}
|
||||
} else
|
||||
memcpy(glstate->texgened[a], list->tex[a], 4*sizeof(GLfloat)*list->len);
|
||||
}
|
||||
if (!(globals4es.texmat || glstate->texture_matrix[a]->identity))
|
||||
tex_coord_matrix(glstate->texgened[a], list->len, getTexMat(a));
|
||||
if (bound->adjust) {
|
||||
tex_coord_npot(glstate->texgened[a], list->len, bound->width, bound->height, bound->nwidth, bound->nheight);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((list->tex[a] || (use_texgen[a] && !needclean[a]))/* && glstate->enable.texture[a]*/) {
|
||||
TEXTURE(a);
|
||||
fpe_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
gles_glTexCoordPointer(4, GL_FLOAT, (use_texgen[a])?0:list->tex_stride[a], (use_texgen[a])?glstate->texgened[a]:list->tex[a]);
|
||||
} else {
|
||||
if (glstate->gleshard->vertexattrib[ATT_MULTITEXCOORD0+a].enabled || (hardext.esversion!=1)) { // optim for ES1.1 to avoid useless texture switch
|
||||
TEXTURE(a);
|
||||
fpe_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
//else if (!glstate->enable.texgen_s[a] && glstate->enable.texture[a]) printf("LIBGL: texture[%i] without TexCoord, mode=0x%04X (init=0x%04X), listlen=%i\n", a, list->mode, list->mode_init, list->len);
|
||||
|
||||
}
|
||||
if (!IS_TEX2D(glstate->enable.texture[a]) && (IS_ANYTEX(glstate->enable.texture[a]))) {
|
||||
TEXTURE(a);
|
||||
gl4es_glActiveTexture(GL_TEXTURE0+a);
|
||||
realize_active();
|
||||
gles_glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// texture loop for ES2+ version
|
||||
for (int a=0; a<hardext.maxtex; a++) {
|
||||
if(list->tex[a]) {
|
||||
TEXTURE(a);
|
||||
fpe_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
gles_glTexCoordPointer(4, GL_FLOAT, list->tex_stride[a], list->tex[a]);
|
||||
} else {
|
||||
TEXTURE(a);
|
||||
fpe_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (glstate->texture.client != old_tex) TEXTURE(old_tex);
|
||||
#undef RS
|
||||
#undef TEXTURE
|
||||
|
||||
realize_textures(1);
|
||||
|
||||
if(use_vbo_array==0) {
|
||||
if((glstate->render_mode == GL_SELECT) || (glstate->polygon_mode == GL_LINE) || (glstate->polygon_mode == GL_POINT))
|
||||
use_vbo_array = 1;
|
||||
else
|
||||
// evaluated, seems good to go !
|
||||
use_vbo_array = list2VBO(list);
|
||||
}
|
||||
save_vbo_t saved[NB_VA];
|
||||
if(use_vbo_array==2)
|
||||
listActiveVBO(list, saved);
|
||||
if(list->use_vbo_array != use_vbo_array)
|
||||
list->use_vbo_array = use_vbo_array;
|
||||
|
||||
GLenum mode;
|
||||
mode = list->mode;
|
||||
if ((glstate->polygon_mode == GL_LINE) && (mode>=GL_TRIANGLES))
|
||||
mode = GL_LINES;
|
||||
if ((glstate->polygon_mode == GL_POINT) && (mode>=GL_TRIANGLES))
|
||||
mode = GL_POINTS;
|
||||
|
||||
if (indices) {
|
||||
if (glstate->render_mode == GL_SELECT) {
|
||||
vertexattrib_t vtx = {0};
|
||||
vtx.pointer = list->vert;
|
||||
vtx.type = GL_FLOAT;
|
||||
vtx.normalized = GL_FALSE;
|
||||
vtx.size = 4;
|
||||
vtx.stride = 0;
|
||||
select_glDrawElements(&vtx, list->mode, list->ilen, GL_UNSIGNED_SHORT, indices);
|
||||
use_vbo_indices = 1;
|
||||
} else {
|
||||
GLuint old_index = wantBufferIndex(0);
|
||||
if (glstate->polygon_mode == GL_LINE && list->mode_init>=GL_TRIANGLES) {
|
||||
int ilen = list->ilen;
|
||||
if(!list->ind_lines) {
|
||||
GLushort *ind_line = list->ind_lines = (GLushort*)malloc(sizeof(GLushort)*ilen*4+2);
|
||||
modeinit_t tmp; tmp.mode_init = list->mode_init; tmp.ilen=list->ilen;
|
||||
int k = fill_lineIndices(list->mode_inits?list->mode_inits:&tmp, list->mode_inits?list->mode_init_len:1, list->mode, indices, list->ind_lines);
|
||||
list->ind_line = k;
|
||||
}
|
||||
bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
gles_glDrawElements(mode, list->ind_line, GL_UNSIGNED_SHORT, list->ind_lines);
|
||||
use_vbo_indices = 1;
|
||||
} else {
|
||||
int vbo_indices = 0;
|
||||
if(!use_vbo_indices) {
|
||||
// create VBO for indices
|
||||
LOAD_GLES2(glGenBuffers);
|
||||
LOAD_GLES2(glBufferData);
|
||||
gles_glGenBuffers(1, &list->vbo_indices);
|
||||
bindBuffer(GL_ELEMENT_ARRAY_BUFFER, list->vbo_indices);
|
||||
gles_glBufferData(GL_ELEMENT_ARRAY_BUFFER, list->ilen*sizeof(GLushort), indices, GL_STATIC_DRAW);
|
||||
use_vbo_indices = 2;
|
||||
vbo_indices = 1;
|
||||
} else if(use_vbo_indices==2) {
|
||||
bindBuffer(GL_ELEMENT_ARRAY_BUFFER, list->vbo_indices);
|
||||
vbo_indices = 1;
|
||||
} else
|
||||
realize_bufferIndex();
|
||||
if(list->instanceCount==1)
|
||||
gles_glDrawElements(mode, list->ilen, GL_UNSIGNED_SHORT, vbo_indices?NULL:indices);
|
||||
else {
|
||||
for (glstate->instanceID=0; glstate->instanceID<list->instanceCount; ++glstate->instanceID)
|
||||
gles_glDrawElements(mode, list->ilen, GL_UNSIGNED_SHORT, vbo_indices?NULL:indices);
|
||||
glstate->instanceID = 0;
|
||||
}
|
||||
}
|
||||
wantBufferIndex(old_index);
|
||||
}
|
||||
} else {
|
||||
if (glstate->render_mode == GL_SELECT) {
|
||||
vertexattrib_t vtx = {0};
|
||||
vtx.pointer = list->vert;
|
||||
vtx.type = GL_FLOAT;
|
||||
vtx.size = 4;
|
||||
vtx.normalized = GL_FALSE;
|
||||
vtx.stride = 0;
|
||||
select_glDrawArrays(&vtx, list->mode, 0, list->len);
|
||||
} else {
|
||||
int len = list->len;
|
||||
if ((glstate->polygon_mode == GL_LINE) && (list->mode_init>=GL_TRIANGLES)) {
|
||||
if(!list->ind_lines) {
|
||||
GLushort *ind_line = list->ind_lines = (GLushort*)malloc(sizeof(GLushort)*len*4+2);
|
||||
modeinit_t tmp; tmp.mode_init = list->mode_init; tmp.ilen=len;
|
||||
int k = fill_lineIndices(list->mode_inits?list->mode_inits:&tmp, list->mode_inits?list->mode_init_len:1, list->mode, NULL, list->ind_lines);
|
||||
list->ind_line = k;
|
||||
}
|
||||
bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
gles_glDrawElements(mode, list->ind_line, GL_UNSIGNED_SHORT, list->ind_lines);
|
||||
} else {
|
||||
if(list->instanceCount==1)
|
||||
gles_glDrawArrays(mode, 0, len);
|
||||
else {
|
||||
for (glstate->instanceID=0; glstate->instanceID<list->instanceCount; ++glstate->instanceID)
|
||||
gles_glDrawArrays(mode, 0, len);
|
||||
glstate->instanceID = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(list->use_vbo_indices != use_vbo_indices)
|
||||
list->use_vbo_indices = use_vbo_indices;
|
||||
if(use_vbo_array==2)
|
||||
listInactiveVBO(list, saved);
|
||||
|
||||
#define TEXTURE(A) if (cur_tex!=A) {gl4es_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;}
|
||||
if(hardext.esversion==1)
|
||||
for (int a=0; a<hardext.maxtex; a++) {
|
||||
if (needclean[a]) {
|
||||
TEXTURE(a);
|
||||
gen_tex_clean(needclean[a], a);
|
||||
}
|
||||
if (!IS_TEX2D(glstate->enable.texture[a]) && (IS_ANYTEX(glstate->enable.texture[a]))) {
|
||||
TEXTURE(a);
|
||||
gles_glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
if (glstate->texture.client!=old_tex)
|
||||
TEXTURE(old_tex);
|
||||
#undef TEXTURE
|
||||
|
||||
if (stipple) {
|
||||
if(!list->use_glstate) //TODO: avoid that malloc/free...
|
||||
free(list->tex[stipple_tmu]);
|
||||
list->tex[stipple_tmu]=NULL;
|
||||
LOAD_GLES(glActiveTexture);
|
||||
if(glstate->gleshard->active!=stipple_tmu)
|
||||
gl4es_glActiveTexture(GL_TEXTURE0+stipple_tmu);
|
||||
GLenum matmode;
|
||||
gl4es_glGetIntegerv(GL_MATRIX_MODE, (GLint *) &matmode);
|
||||
gl4es_glMatrixMode(GL_TEXTURE);
|
||||
gl4es_glPopMatrix();
|
||||
gl4es_glMatrixMode(matmode);
|
||||
gl4es_glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, stipple_env);
|
||||
gl4es_glAlphaFunc(stipple_afunc, stipple_aref);
|
||||
if(stipple_tex2d)
|
||||
gl4es_glEnable(GL_TEXTURE_2D);
|
||||
else
|
||||
gl4es_glDisable(GL_TEXTURE_2D);
|
||||
if(stipple_alpha)
|
||||
gl4es_glEnable(GL_ALPHA_TEST);
|
||||
else
|
||||
gl4es_glDisable(GL_ALPHA_TEST);
|
||||
for (int k=0; k<4; k++) {
|
||||
if(stipple_texgen[k])
|
||||
gl4es_glEnable(GL_TEXTURE_GEN_S+k);
|
||||
}
|
||||
if(glstate->gleshard->active!=stipple_old)
|
||||
gl4es_glActiveTexture(GL_TEXTURE0+stipple_old);
|
||||
}
|
||||
if(list->post_color) gl4es_glColor4fv(list->post_colors);
|
||||
if(list->post_normal) gl4es_glNormal3fv(list->post_normals);
|
||||
} while ((list = list->next));
|
||||
gl4es_glPopClientAttrib();
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
#include "list.h"
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "init.h"
|
||||
#include "matrix.h"
|
||||
|
||||
static inline void rlVertexCommon(renderlist_t *list, int idx, int l) {
|
||||
if(list->use_glstate) {
|
||||
resize_renderlist(list);
|
||||
if (!list->vert) list->vert = glstate->merger_master;
|
||||
if (list->normal) memcpy(list->normal + idx, list->lastNormal, sizeof(GLfloat) * 3);
|
||||
if (list->fogcoord) memcpy(list->fogcoord + idx, glstate->fogcoord, sizeof(GLfloat) * 1);
|
||||
} else {
|
||||
if (!list->vert) list->vert = alloc_sublist(4, list->cap);
|
||||
else resize_renderlist(list);
|
||||
if (list->normal) memcpy(list->normal + (l * 3), list->lastNormal, sizeof(GLfloat) * 3);
|
||||
if (list->fogcoord) memcpy(list->fogcoord + (l * 1), glstate->fogcoord, sizeof(GLfloat) * 1);
|
||||
}
|
||||
// common part
|
||||
if (list->color) memcpy(list->color + idx, list->lastColors, sizeof(GLfloat) * 4);
|
||||
if (list->secondary) memcpy(list->secondary + (l * 4), glstate->secondary, sizeof(GLfloat) * 4);
|
||||
if (list->tex[0]) memcpy(list->tex[0] + idx, glstate->texcoord[0], sizeof(GLfloat) * 4);
|
||||
if (list->tex[1]) memcpy(list->tex[1] + idx, glstate->texcoord[1], sizeof(GLfloat) * 4);
|
||||
for (int a=2; a<list->maxtex; a++)
|
||||
if (list->tex[a]) memcpy(list->tex[a] + (l * 4), glstate->texcoord[a], sizeof(GLfloat) * 4);
|
||||
}
|
||||
|
||||
void FASTMATH rlVertex4f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
|
||||
const int idx = (list->use_glstate)?(list->len * 5*4):(list->len * 4);
|
||||
rlVertexCommon(list, idx, list->len);
|
||||
++list->len;
|
||||
|
||||
GLfloat * const vert = list->vert + idx;
|
||||
vert[0] = x; vert[1] = y; vert[2] = z; vert[3] = w;
|
||||
}
|
||||
void FASTMATH rlVertex3fv(renderlist_t *list, GLfloat* v) {
|
||||
const int idx = (list->use_glstate)?(list->len * 5*4):(list->len * 4);
|
||||
rlVertexCommon(list, idx, list->len);
|
||||
|
||||
GLfloat * const vert = list->vert + idx;
|
||||
++list->len;
|
||||
memcpy(vert, v, 3*sizeof(GLfloat));
|
||||
vert[3] = 1.f;
|
||||
}
|
||||
void FASTMATH rlVertex4fv(renderlist_t *list, GLfloat* v) {
|
||||
const int idx = (list->use_glstate)?(list->len * 5*4):(list->len * 4);
|
||||
rlVertexCommon(list, idx, list->len);
|
||||
|
||||
GLfloat * const vert = list->vert + idx;
|
||||
++list->len;
|
||||
memcpy(vert, v, 4*sizeof(GLfloat));
|
||||
}
|
||||
|
||||
void rlEnd(renderlist_t *list) {
|
||||
// adjust number of vertex, to remove extra vertex
|
||||
int adj = list->len - list->cur_istart;
|
||||
adj -= adjust_vertices(list->merger_mode?list->merger_mode:list->mode_init, adj);
|
||||
//printf("rlEnd(%d), indices=%p, mode_init_len=%d, len/cur_istart(adj)/ilen=%d/%d(%d)/%d, mode/mode_init=%s/%s, merger_mode=%s\n", list, list->indices, list->mode_init_len, list->len, list->cur_istart, adj, list->ilen, PrintEnum(list->mode), PrintEnum(list->mode_init), list->merger_mode?PrintEnum(list->merger_mode):"none");
|
||||
list->len -= adj;
|
||||
if(!list->mode_inits && list->cur_istart) list_add_modeinit(list, list->mode_init);
|
||||
if(list->indices && list->merger_mode && list->len-list->cur_istart) {
|
||||
// also feed the indices...
|
||||
int istart = list->cur_istart;
|
||||
int ivert = 0;
|
||||
int len = list->len-istart;
|
||||
resize_indices_renderlist(list, indices_getindicesize(list->merger_mode, len));
|
||||
switch (list->merger_mode) {
|
||||
case GL_LINE_STRIP:
|
||||
if(len>1) {
|
||||
list->indices[list->ilen++]=istart+(ivert);
|
||||
list->indices[list->ilen++]=istart+(++ivert);
|
||||
for (int i=2; i<len; i++) {
|
||||
list->indices[list->ilen++]=istart+(ivert);
|
||||
list->indices[list->ilen++]=istart+(++ivert);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_LINE_LOOP:
|
||||
if(len>1) {
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
for (int i=istart+2; i<list->len; i++) {
|
||||
list->indices[list->ilen++]=istart+(ivert-1);
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
}
|
||||
list->indices[list->ilen++]=istart+(ivert-1);
|
||||
list->indices[list->ilen++]=istart;
|
||||
}
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
case GL_TRIANGLE_FAN:
|
||||
if(len>2) {
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
}
|
||||
for (int i=istart+3; i<list->len; i++) {
|
||||
// add a new triangle for each new point
|
||||
list->indices[list->ilen++]=istart;
|
||||
list->indices[list->ilen++]=istart+(ivert-1);
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
}
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
case GL_TRIANGLE_STRIP:
|
||||
if(len>2) {
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
}
|
||||
for (int i=istart+3; i<list->len; i++) {
|
||||
// add a new triangle for each new point
|
||||
list->indices[list->ilen++]=istart+(ivert-((ivert%2)?1:2));
|
||||
list->indices[list->ilen++]=istart+(ivert-((ivert%2)?2:1));
|
||||
list->indices[list->ilen++]=istart+(ivert++);
|
||||
}
|
||||
break;
|
||||
case GL_QUADS:
|
||||
if(len>3)
|
||||
for (int i=istart; i+3<list->len; i+=4) {
|
||||
list->indices[list->ilen++]=i+0;
|
||||
list->indices[list->ilen++]=i+1;
|
||||
list->indices[list->ilen++]=i+2;
|
||||
|
||||
list->indices[list->ilen++]=i+0;
|
||||
list->indices[list->ilen++]=i+2;
|
||||
list->indices[list->ilen++]=i+3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (int i=istart; i<list->len; i++)
|
||||
list->indices[list->ilen++]=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
list->cur_istart = 0;
|
||||
if(list->mode_inits) list_add_modeinit(list, list->merger_mode?list->merger_mode:list->mode_init);
|
||||
if(list->color)
|
||||
memcpy(glstate->color, list->lastColors, 4*sizeof(GLfloat));
|
||||
if(list->normal)
|
||||
memcpy(glstate->normal, list->lastNormal, 3*sizeof(GLfloat));
|
||||
}
|
||||
|
||||
static inline void rlNormalCommon(renderlist_t *list) {
|
||||
if (list->normal == NULL) {
|
||||
const int stride = (list->use_glstate)?(5*4):3;
|
||||
if(list->use_glstate) {
|
||||
list->normal = glstate->merger_master+4+4+2*4;
|
||||
} else {
|
||||
list->normal = alloc_sublist(3, list->cap);
|
||||
}
|
||||
// catch up
|
||||
for (int i = 0; i < list->len; i++) {
|
||||
GLfloat *normal = (list->normal + (i * stride));
|
||||
memcpy(normal, list->lastNormal, sizeof(GLfloat) * 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
void FASTMATH rlNormal3f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z) {
|
||||
rlNormalCommon(list);
|
||||
|
||||
GLfloat *normal = list->lastNormal;
|
||||
normal[0] = x; normal[1] = y; normal[2] = z;
|
||||
}
|
||||
void FASTMATH rlNormal3fv(renderlist_t *list, GLfloat*v) {
|
||||
rlNormalCommon(list);
|
||||
|
||||
memcpy(list->lastNormal, v, 3*sizeof(GLfloat));
|
||||
}
|
||||
|
||||
static inline void rlColorCommon(renderlist_t *list) {
|
||||
if (list->color == NULL) {
|
||||
list->lastColorsSet = 1;
|
||||
const int stride = (list->use_glstate)?(5*4):4;
|
||||
if(list->use_glstate) {
|
||||
list->color = glstate->merger_master+4;
|
||||
} else {
|
||||
list->color = alloc_sublist(4, list->cap);
|
||||
}
|
||||
// catch up
|
||||
for (int i = 0; i < list->len; i++) {
|
||||
GLfloat *color = (list->color + (i * stride));
|
||||
memcpy(color,list->lastColors, sizeof(GLfloat) * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
void FASTMATH rlColor4f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
||||
rlColorCommon(list);
|
||||
|
||||
GLfloat *color = list->lastColors;
|
||||
color[0] = r; color[1] = g; color[2] = b; color[3] = a;
|
||||
}
|
||||
void FASTMATH rlColor4fv(renderlist_t *list, GLfloat* v) {
|
||||
rlColorCommon(list);
|
||||
|
||||
memcpy(list->lastColors, v, 4*sizeof(GLfloat));
|
||||
}
|
||||
|
||||
void FASTMATH rlSecondary3f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b) {
|
||||
if (list->secondary == NULL) {
|
||||
if(list->use_glstate) {
|
||||
if(!glstate->merger_secondary)
|
||||
glstate->merger_secondary = (GLfloat*)malloc(sizeof(GLfloat)*4*glstate->merger_cap);
|
||||
list->secondary = glstate->merger_secondary;
|
||||
} else {
|
||||
list->secondary = alloc_sublist(4, list->cap);
|
||||
}
|
||||
// catch up
|
||||
GLfloat *secondary = list->secondary;
|
||||
for (int i = 0; i < list->len; i++) {
|
||||
memcpy(secondary, list->lastSecondaryColors, sizeof(GLfloat) * 4);
|
||||
secondary += 4;
|
||||
}
|
||||
}
|
||||
|
||||
GLfloat *color = glstate->secondary;
|
||||
color[0] = r; color[1] = g; color[2] = b; color[3] = 0.0f;
|
||||
}
|
||||
|
||||
void rlMaterialfv(renderlist_t *list, GLenum face, GLenum pname, const GLfloat * params) {
|
||||
rendermaterial_t *m;
|
||||
khash_t(material) *map;
|
||||
khint_t k;
|
||||
int ret;
|
||||
if (! list->material) {
|
||||
list->material = map = kh_init(material);
|
||||
// segfaults if we don't do a single put
|
||||
kh_put(material, map, 1, &ret);
|
||||
kh_del(material, map, 1);
|
||||
} else {
|
||||
map = list->material;
|
||||
}
|
||||
|
||||
int iface = (face==GL_FRONT)?0:((face==GL_BACK)?1:2);
|
||||
int key = pname | (iface<<16);
|
||||
k = kh_get(material, map, key);
|
||||
if (k == kh_end(map)) {
|
||||
k = kh_put(material, map, key, &ret);
|
||||
m = kh_value(map, k) = malloc(sizeof(rendermaterial_t));
|
||||
} else {
|
||||
m = kh_value(map, k);
|
||||
}
|
||||
|
||||
m->face = face;
|
||||
m->pname = pname;
|
||||
int sz=4;
|
||||
if(pname==GL_SHININESS || pname==GL_COLOR_INDEXES) sz=1;
|
||||
memcpy(m->color, params, sz*sizeof(GLfloat));
|
||||
}
|
||||
|
||||
void rlLightfv(renderlist_t *list, GLenum which, GLenum pname, const GLfloat * params) {
|
||||
renderlight_t *m;
|
||||
khash_t(light) *map;
|
||||
khint_t k;
|
||||
int ret;
|
||||
if (! list->light) {
|
||||
list->light = map = kh_init(light);
|
||||
// segfaults if we don't do a single put
|
||||
kh_put(light, map, 1, &ret);
|
||||
kh_del(light, map, 1);
|
||||
} else {
|
||||
map = list->light;
|
||||
}
|
||||
|
||||
int key = pname | ((which-GL_LIGHT0)<<16);
|
||||
k = kh_get(light, map, key);
|
||||
if (k == kh_end(map)) {
|
||||
k = kh_put(light, map, key, &ret);
|
||||
m = kh_value(map, k) = malloc(sizeof(renderlight_t));
|
||||
} else {
|
||||
m = kh_value(map, k);
|
||||
}
|
||||
|
||||
m->which = which;
|
||||
m->pname = pname;
|
||||
int sz=4;
|
||||
if(pname==GL_SPOT_DIRECTION) sz=3;
|
||||
if(pname==GL_SPOT_EXPONENT || pname==GL_SPOT_CUTOFF
|
||||
|| pname==GL_CONSTANT_ATTENUATION || pname==GL_LINEAR_ATTENUATION
|
||||
|| pname==GL_QUADRATIC_ATTENUATION) sz=1;
|
||||
memcpy(m->color, params, sz*sizeof(GLfloat));
|
||||
}
|
||||
|
||||
void rlTexGenfv(renderlist_t *list, GLenum coord, GLenum pname, const GLfloat * params) {
|
||||
rendertexgen_t *m;
|
||||
khash_t(texgen) *map;
|
||||
khint_t k;
|
||||
int ret;
|
||||
if (! list->texgen) {
|
||||
list->texgen = map = kh_init(texgen);
|
||||
// segfaults if we don't do a single put
|
||||
kh_put(texgen, map, 1, &ret);
|
||||
kh_del(texgen, map, 1);
|
||||
} else {
|
||||
map = list->texgen;
|
||||
}
|
||||
|
||||
int key = pname | ((coord-GL_S)<<16);
|
||||
k = kh_get(texgen, map, key);
|
||||
if (k == kh_end(map)) {
|
||||
k = kh_put(texgen, map, key, &ret);
|
||||
m = kh_value(map, k) = malloc(sizeof(rendertexgen_t));
|
||||
} else {
|
||||
m = kh_value(map, k);
|
||||
}
|
||||
|
||||
m->coord = coord;
|
||||
m->pname = pname;
|
||||
memcpy(m->color, params, 4*sizeof(GLfloat));
|
||||
}
|
||||
|
||||
void rlMultiTexCoordCommon(renderlist_t* list, int tmu) {
|
||||
if (list->tex[tmu] == NULL) {
|
||||
if (list->maxtex<tmu+1) list->maxtex = tmu+1;
|
||||
const int stride = (list->use_glstate && tmu<2)?(5*4):4;
|
||||
if(list->use_glstate) {
|
||||
if(tmu<2)
|
||||
list->tex[tmu] = glstate->merger_master+4+4+tmu*4;
|
||||
else {
|
||||
if(!glstate->merger_tex[tmu-2])
|
||||
glstate->merger_tex[tmu-2] = (GLfloat*)malloc(sizeof(GLfloat)*4*glstate->merger_cap);
|
||||
list->tex[tmu] = glstate->merger_tex[tmu-2];
|
||||
}
|
||||
} else {
|
||||
list->tex[tmu] = alloc_sublist(4, list->cap);
|
||||
}
|
||||
// catch up
|
||||
GLfloat *tex = list->tex[tmu];
|
||||
for (int i = 0; i < list->len; i++) {
|
||||
memcpy(tex, glstate->texcoord[tmu], sizeof(GLfloat) * 4);
|
||||
tex += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
void FASTMATH rlMultiTexCoord4f(renderlist_t *list, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
|
||||
const int tmu = target - GL_TEXTURE0;
|
||||
rlMultiTexCoordCommon(list, tmu);
|
||||
|
||||
GLfloat *tex = glstate->texcoord[tmu];
|
||||
tex[0] = s; tex[1] = t;
|
||||
tex[2] = r; tex[3] = q;
|
||||
}
|
||||
void FASTMATH rlMultiTexCoord2fv(renderlist_t *list, GLenum target, GLfloat* v) {
|
||||
const int tmu = target - GL_TEXTURE0;
|
||||
rlMultiTexCoordCommon(list, tmu);
|
||||
|
||||
GLfloat *tex = glstate->texcoord[tmu];
|
||||
memcpy(tex, v, 2*sizeof(GLfloat));
|
||||
tex[2] = 0.f; tex[3] = 1.f;
|
||||
}
|
||||
void FASTMATH rlMultiTexCoord4fv(renderlist_t *list, GLenum target, GLfloat* v) {
|
||||
const int tmu = target - GL_TEXTURE0;
|
||||
rlMultiTexCoordCommon(list, tmu);
|
||||
|
||||
GLfloat *tex = glstate->texcoord[tmu];
|
||||
memcpy(tex, v, 4*sizeof(GLfloat));
|
||||
}
|
||||
|
||||
void FASTMATH rlFogCoordf(renderlist_t *list, GLfloat coord) {
|
||||
if (list->fogcoord == NULL) {
|
||||
const int stride = (list->use_glstate)?(5*4):1;
|
||||
if(list->use_glstate) {
|
||||
list->fogcoord = glstate->merger_master+4+4+2*4+3;
|
||||
} else {
|
||||
list->fogcoord = alloc_sublist(1, list->cap);
|
||||
}
|
||||
// catch up
|
||||
GLfloat *fog = list->fogcoord;
|
||||
for (int i = 0; i < list->len; i++) {
|
||||
memcpy(fog, glstate->fogcoord, sizeof(GLfloat) * 1);
|
||||
fog+=stride;
|
||||
}
|
||||
}
|
||||
glstate->fogcoord[0] = coord;
|
||||
}
|
||||
|
||||
void rlActiveTexture(renderlist_t *list, GLenum texture ) {
|
||||
list->set_tmu = true;
|
||||
list->tmu = texture - GL_TEXTURE0;
|
||||
if(list->maxtex < list->tmu+1) list->maxtex = list->tmu+1;
|
||||
}
|
||||
|
||||
void rlBindTexture(renderlist_t *list, GLenum target, GLuint texture) {
|
||||
list->texture = texture;
|
||||
list->target_texture = target;
|
||||
list->set_texture = true;
|
||||
}
|
||||
|
||||
void rlRasterOp(renderlist_t *list, int op, GLfloat x, GLfloat y, GLfloat z) {
|
||||
list->raster_op = op;
|
||||
list->raster_xyz[0] = x;
|
||||
list->raster_xyz[1] = y;
|
||||
list->raster_xyz[2] = z;
|
||||
}
|
||||
|
||||
void rlFogOp(renderlist_t *list, int op, const GLfloat* v) {
|
||||
int n = 1;
|
||||
if (op==GL_FOG_COLOR) n = 4;
|
||||
list->fog_op = op;
|
||||
list->fog_val[0] = v[0];
|
||||
if (n>1) list->fog_val[1] = v[1];
|
||||
if (n>2) list->fog_val[2] = v[2];
|
||||
if (n>3) list->fog_val[3] = v[3];
|
||||
}
|
||||
|
||||
void rlPointParamOp(renderlist_t *list, int op, const GLfloat* v) {
|
||||
list->pointparam_op = op;
|
||||
list->pointparam_val[0] = v[0];
|
||||
list->pointparam_val[1] = v[1];
|
||||
list->pointparam_val[2] = v[2];
|
||||
list->pointparam_val[3] = v[3];
|
||||
}
|
||||
|
||||
void rlPushCall(renderlist_t *list, packed_call_t *data) {
|
||||
call_list_t *cl = &list->calls;
|
||||
if (!cl->calls) {
|
||||
cl->cap = DEFAULT_CALL_LIST_CAPACITY;
|
||||
cl->calls = malloc(DEFAULT_CALL_LIST_CAPACITY * sizeof(void*));
|
||||
} else if (list->calls.len == list->calls.cap) {
|
||||
cl->cap += DEFAULT_CALL_LIST_CAPACITY;
|
||||
cl->calls = realloc(cl->calls, cl->cap * sizeof(void*));
|
||||
}
|
||||
cl->calls[cl->len++] = data;
|
||||
}
|
||||
|
||||
renderlist_t* GetFirst(renderlist_t* list) {
|
||||
while(list->prev)
|
||||
list = list->prev;
|
||||
return list;
|
||||
}
|
||||
|
||||
void rlTexEnvfv(renderlist_t *list, GLenum target, GLenum pname, const GLfloat * params) {
|
||||
int n = 1;
|
||||
switch(target) {
|
||||
case GL_POINT_SPRITE: n = 1; break;
|
||||
default:
|
||||
switch(pname) {
|
||||
case GL_TEXTURE_ENV_MODE: n=1; break;
|
||||
case GL_TEXTURE_ENV_COLOR: n=4; break;
|
||||
case GL_TEXTURE_LOD_BIAS: n=1; break;
|
||||
}
|
||||
}
|
||||
rendertexenv_t *m;
|
||||
khash_t(texenv) *map;
|
||||
khint_t k;
|
||||
int ret;
|
||||
if (! list->texenv) {
|
||||
list->texenv = map = kh_init(texenv);
|
||||
// segfaults if we don't do a single put
|
||||
kh_put(texenv, map, 1, &ret);
|
||||
kh_del(texenv, map, 1);
|
||||
} else {
|
||||
map = list->texenv;
|
||||
}
|
||||
|
||||
int key = pname | ((target)<<16);
|
||||
k = kh_get(texenv, map, key);
|
||||
if (k == kh_end(map)) {
|
||||
k = kh_put(texenv, map, key, &ret);
|
||||
m = kh_value(map, k) = malloc(sizeof(rendertexenv_t));
|
||||
} else {
|
||||
m = kh_value(map, k);
|
||||
}
|
||||
|
||||
m->target = target;
|
||||
m->pname = pname;
|
||||
memcpy(m->params, params, n*sizeof(GLfloat));
|
||||
}
|
||||
void rlTexEnviv(renderlist_t *list, GLenum target, GLenum pname, const GLint * params) {
|
||||
GLfloat fparams[4];
|
||||
int n = 1;
|
||||
switch(target) {
|
||||
case GL_POINT_SPRITE: n = 1; break;
|
||||
default:
|
||||
switch(pname) {
|
||||
case GL_TEXTURE_ENV_MODE: n=1; break;
|
||||
case GL_TEXTURE_ENV_COLOR: n=4; break;
|
||||
case GL_TEXTURE_LOD_BIAS: n=1; break;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<n; i++) fparams[i] = params[i];
|
||||
rlTexEnvfv(list, target, pname, fparams);
|
||||
}
|
||||
|
||||
#undef alloc_sublist
|
||||
#undef realloc_sublist
|
||||
|
||||
renderlist_t* NewDrawStage(renderlist_t* l, GLenum m) {
|
||||
if(globals4es.mergelist && !glstate->polygon_mode
|
||||
&& ((isempty_renderlist(l) && l->prev && l->prev->open && l->prev->mode==m && l->prev->mode_init==m)
|
||||
|| (l->stage==STAGE_POSTDRAW && l->open))
|
||||
&& ((l->mode_dimension==rendermode_dimensions(m) && l->mode_dimension>0)))
|
||||
{
|
||||
return recycle_renderlist(l, m);
|
||||
} else {
|
||||
// if we are just in glBegin/glEnd merger, then purge the list...
|
||||
if(!glstate->list.compiling && glstate->list.pending) {
|
||||
glstate->list.active = NULL;
|
||||
l = end_renderlist(l);
|
||||
draw_renderlist(l);
|
||||
free_renderlist(l);
|
||||
l = alloc_renderlist();
|
||||
NewStage(l, STAGE_DRAW);
|
||||
} else {
|
||||
NewStage(l, STAGE_DRAW);
|
||||
}
|
||||
l->mode=m;
|
||||
l->mode_init=m;
|
||||
l->mode_dimension = rendermode_dimensions(m);
|
||||
if(!glstate->merger_used && !glstate->list.compiling
|
||||
&& !(glstate->render_mode==GL_SELECT || glstate->polygon_mode==GL_LINE || glstate->polygon_mode == GL_POINT))
|
||||
{
|
||||
l->vert_stride=sizeof(GLfloat)*4*5;
|
||||
l->color_stride=sizeof(GLfloat)*4*5;
|
||||
l->tex_stride[0]=sizeof(GLfloat)*4*5;
|
||||
l->tex_stride[1]=sizeof(GLfloat)*4*5;
|
||||
l->normal_stride=sizeof(GLfloat)*4*5;
|
||||
l->fogcoord_stride=sizeof(GLfloat)*4*5;
|
||||
l->use_glstate=1;
|
||||
glstate->merger_used=1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
#include "loader.h"
|
||||
|
||||
void (APIENTRY_GL4ES *gl4es_getMainFBSize)(GLint* width, GLint* height);
|
||||
|
||||
#if defined NO_LOADER
|
||||
|
||||
void *gles = (void*)(~(uintptr_t)0);
|
||||
void *egl = (void*)(~(uintptr_t)0);
|
||||
void *open_lib(const char **names, const char *override) {
|
||||
return (void*)(~(uintptr_t)0);
|
||||
}
|
||||
void load_libs() {
|
||||
}
|
||||
|
||||
#elif defined AMIGAOS4
|
||||
#include "../agl/amigaos.h"
|
||||
void *gles;
|
||||
void load_libs() {
|
||||
os4OpenLib(&gles);
|
||||
}
|
||||
|
||||
void *open_lib(const char **names, const char *override) {
|
||||
return (void*)(~(uintptr_t)0);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
#ifndef _WIN32
|
||||
// PATH_MAX
|
||||
#ifdef __linux__
|
||||
#include <linux/limits.h>
|
||||
#else
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#else
|
||||
__declspec(dllimport)
|
||||
struct HINSTANCE__* __stdcall LoadLibraryW(const wchar_t*);
|
||||
#endif
|
||||
#include "logs.h"
|
||||
#include "init.h"
|
||||
#include "envvars.h"
|
||||
|
||||
void *gles = NULL, *egl = NULL, *bcm_host = NULL, *vcos = NULL, *gbm = NULL, *drm = NULL;
|
||||
#ifndef _WIN32
|
||||
#ifndef NO_GBM
|
||||
static const char *drm_lib[] = {
|
||||
"libdrm",
|
||||
NULL
|
||||
};
|
||||
static const char *gbm_lib[] = {
|
||||
"libgbm",
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
static const char *path_prefix[] = {
|
||||
"",
|
||||
"/opt/vc/lib/",
|
||||
"/usr/local/lib/",
|
||||
"/usr/lib/",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char *lib_ext[] = {
|
||||
#ifndef NO_GBM
|
||||
"so.19",
|
||||
#endif
|
||||
"so",
|
||||
"so.1",
|
||||
"so.2",
|
||||
"dylib",
|
||||
"dll",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char *gles2_lib[] = {
|
||||
#if defined(BCMHOST)
|
||||
"libbrcmGLESv2",
|
||||
#endif
|
||||
"libGLESv2_CM",
|
||||
"libGLESv2",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *gles_lib[] = {
|
||||
#if defined(BCMHOST)
|
||||
"libbrcmGLESv1_CM",
|
||||
#endif
|
||||
#if !defined(PYRA)
|
||||
"libGLESv1_CM",
|
||||
#endif
|
||||
"libGLES_CM",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *egl_lib[] = {
|
||||
#if defined(BCMHOST)
|
||||
"libbrcmEGL",
|
||||
#endif
|
||||
"libEGL",
|
||||
NULL
|
||||
};
|
||||
|
||||
void *open_lib(const char **names, const char *override) {
|
||||
void *lib = NULL;
|
||||
|
||||
char path_name[PATH_MAX + 1];
|
||||
int flags = RTLD_LOCAL | RTLD_NOW;
|
||||
#if defined(RTLD_DEEPBIND)
|
||||
static int totest = 1;
|
||||
static int sanitizer = 0;
|
||||
if(totest) {
|
||||
totest = 0;
|
||||
char *p = getenv("LD_PRELOAD");
|
||||
if(p && strstr(p, "libasan.so"))
|
||||
sanitizer = 1;
|
||||
}
|
||||
// note: breaks address sanitizer
|
||||
if(!sanitizer && globals4es.deepbind)
|
||||
flags |= RTLD_DEEPBIND;
|
||||
#endif
|
||||
if (override) {
|
||||
if ((lib = dlopen(override, flags))) {
|
||||
strncpy(path_name, override, PATH_MAX);
|
||||
if(!globals4es.nobanner) LOGD("LIBGL:loaded: %s\n", path_name);
|
||||
return lib;
|
||||
} else {
|
||||
LOGE("LIBGL_GLES override failed: %s\n", dlerror());
|
||||
}
|
||||
}
|
||||
for (int p = 0; path_prefix[p]; p++) {
|
||||
for (int i = 0; names[i]; i++) {
|
||||
for (int e = 0; lib_ext[e]; e++) {
|
||||
snprintf(path_name, PATH_MAX, "%s%s.%s", path_prefix[p], names[i], lib_ext[e]);
|
||||
if ((lib = dlopen(path_name, flags))) {
|
||||
if(!globals4es.nobanner) LOGD("loaded: %s\n", path_name);
|
||||
return lib;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return lib;
|
||||
}
|
||||
#else // _WIN32
|
||||
void* open_lib(const wchar_t* envvar, const wchar_t* dll)
|
||||
{
|
||||
const wchar_t* name = _wgetenv(envvar);
|
||||
return LoadLibraryW(name?name:dll);
|
||||
}
|
||||
#endif
|
||||
|
||||
void load_libs() {
|
||||
static int first = 1;
|
||||
if (! first) return;
|
||||
first = 0;
|
||||
#ifndef _WIN32
|
||||
const char *gles_override = GetEnvVar("LIBGL_GLES");
|
||||
#if defined(BCMHOST) && !defined(ANDROID)
|
||||
// optimistically try to load the raspberry pi libs
|
||||
if (! gles_override) {
|
||||
const char *bcm_host_name[] = {"libbcm_host", NULL};
|
||||
const char *vcos_name[] = {"libvcos", NULL};
|
||||
bcm_host = open_lib(bcm_host_name, NULL);
|
||||
vcos = open_lib(vcos_name, NULL);
|
||||
}
|
||||
#endif
|
||||
gles = open_lib((globals4es.es==1)?gles_lib:gles2_lib, gles_override);
|
||||
#else
|
||||
gles = open_lib(L"LIBGL_GLES", L"libGLESv2.dll");
|
||||
#endif
|
||||
WARN_NULL(gles);
|
||||
|
||||
#ifdef NOEGL
|
||||
egl = gles;
|
||||
#elif !defined(_WIN32)
|
||||
const char *egl_override = GetEnvVar("LIBGL_EGL");
|
||||
egl = open_lib(egl_lib, egl_override);
|
||||
#else
|
||||
egl = open_lib(L"LIBGL_EGL", L"libEGL.dll");
|
||||
#endif
|
||||
WARN_NULL(egl);
|
||||
|
||||
#ifndef NO_GBM
|
||||
const char *gbm_override = GetEnvVar("LIBGL_GBM");
|
||||
gbm = open_lib(gbm_lib, gbm_override);
|
||||
const char *drm_override = GetEnvVar("LIBGL_DRM");
|
||||
drm = open_lib(drm_lib, drm_override);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// user-defined getProcAddress
|
||||
void* (APIENTRY_GL4ES *gles_getProcAddress)(const char *name);
|
||||
|
||||
void* APIENTRY_GL4ES proc_address(void *lib, const char *name) {
|
||||
if (gles_getProcAddress)
|
||||
return gles_getProcAddress(name);
|
||||
#ifdef AMIGAOS4
|
||||
return os4GetProcAddress(name);
|
||||
#elif defined __EMSCRIPTEN__
|
||||
void *emscripten_GetProcAddress(const char *name);
|
||||
return emscripten_GetProcAddress(name);
|
||||
#elif defined __APPLE__
|
||||
// apple code seems to use RTLD_NEXT which is usually ((void*)-1)
|
||||
// remove if it not needed
|
||||
return dlsym((void*)(~(uintptr_t)0), name);
|
||||
#elif !defined NO_LOADER
|
||||
return dlsym(lib, name);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
#ifndef _GL4ES_LOADER_H_
|
||||
#define _GL4ES_LOADER_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "gl4es.h"
|
||||
#include "gles.h"
|
||||
#include "logs.h"
|
||||
|
||||
#ifndef NOEGL
|
||||
//Typedef for egl to be able to call LOAD_EGL...
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
typedef EGLBoolean (*eglBindAPI_PTR)(EGLenum api);
|
||||
typedef EGLBoolean (*eglBindTexImage_PTR)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
typedef EGLBoolean (*eglChooseConfig_PTR)(EGLDisplay dpy, const EGLint * attrib_list, EGLConfig * configs, EGLint config_size, EGLint * num_config);
|
||||
typedef EGLBoolean (*eglCopyBuffers_PTR)(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
|
||||
typedef EGLContext (*eglCreateContext_PTR)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint * attrib_list);
|
||||
typedef EGLSurface (*eglCreatePbufferFromClientBuffer_PTR)(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint * attrib_list);
|
||||
typedef EGLSurface (*eglCreatePbufferSurface_PTR)(EGLDisplay dpy, EGLConfig config, const EGLint * attrib_list);
|
||||
typedef EGLSurface (*eglCreatePixmapSurface_PTR)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint * attrib_list);
|
||||
typedef EGLSurface (*eglCreatePlatformWindowSurface_PTR)(EGLDisplay display, EGLConfig config, void * native_window, const EGLint * attrib_list);
|
||||
typedef EGLSurface (*eglCreateWindowSurface_PTR)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint * attrib_list);
|
||||
typedef EGLBoolean (*eglDestroyContext_PTR)(EGLDisplay dpy, EGLContext ctx);
|
||||
typedef EGLBoolean (*eglDestroySurface_PTR)(EGLDisplay dpy, EGLSurface surface);
|
||||
typedef EGLBoolean (*eglGetConfigAttrib_PTR)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint * value);
|
||||
typedef EGLBoolean (*eglGetConfigs_PTR)(EGLDisplay dpy, EGLConfig * configs, EGLint config_size, EGLint * num_config);
|
||||
typedef EGLContext (*eglGetCurrentContext_PTR)();
|
||||
typedef EGLDisplay (*eglGetCurrentDisplay_PTR)();
|
||||
typedef EGLSurface (*eglGetCurrentSurface_PTR)(EGLint readdraw);
|
||||
typedef EGLDisplay (*eglGetDisplay_PTR)(EGLNativeDisplayType display_id);
|
||||
typedef EGLDisplay (*eglGetPlatformDisplay_PTR)(EGLenum platform, void * native_display, const EGLint * attrib_list);
|
||||
typedef EGLint (*eglGetError_PTR)();
|
||||
typedef __eglMustCastToProperFunctionPointerType (*eglGetProcAddress_PTR)(const char * procname);
|
||||
typedef EGLBoolean (*eglInitialize_PTR)(EGLDisplay dpy, EGLint * major, EGLint * minor);
|
||||
typedef EGLBoolean (*eglMakeCurrent_PTR)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
|
||||
typedef EGLenum (*eglQueryAPI_PTR)();
|
||||
typedef EGLBoolean (*eglQueryContext_PTR)(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint * value);
|
||||
typedef const char * (*eglQueryString_PTR)(EGLDisplay dpy, EGLint name);
|
||||
typedef EGLBoolean (*eglQuerySurface_PTR)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint * value);
|
||||
typedef EGLBoolean (*eglReleaseTexImage_PTR)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
typedef EGLBoolean (*eglReleaseThread_PTR)();
|
||||
typedef EGLBoolean (*eglSurfaceAttrib_PTR)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
|
||||
typedef EGLBoolean (*eglSwapBuffers_PTR)(EGLDisplay dpy, EGLSurface surface);
|
||||
typedef EGLBoolean (*eglSwapBuffersWithDamageEXT_PTR)(EGLDisplay dpy, EGLSurface surface, EGLint * rects, EGLint n_rects);
|
||||
typedef EGLBoolean (*eglSwapInterval_PTR)(EGLDisplay dpy, EGLint interval);
|
||||
typedef EGLBoolean (*eglTerminate_PTR)(EGLDisplay dpy);
|
||||
typedef EGLBoolean (*eglUnlockSurfaceKHR_PTR)(EGLDisplay display, EGLSurface surface);
|
||||
typedef EGLBoolean (*eglWaitClient_PTR)();
|
||||
typedef EGLBoolean (*eglWaitGL_PTR)();
|
||||
typedef EGLBoolean (*eglWaitNative_PTR)(EGLint engine);
|
||||
typedef EGLSyncKHR (*eglCreateSyncKHR_PTR)(EGLDisplay dpy, EGLenum type, const EGLint * attrib_list);
|
||||
typedef EGLint (*eglClientWaitSyncKHR_PTR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
|
||||
|
||||
typedef NativePixmapType (*egl_create_pixmap_ID_mapping_PTR)(void *pixmap);
|
||||
typedef NativePixmapType (*egl_destroy_pixmap_ID_mapping_PTR)(int id);
|
||||
#ifdef TEXSTREAM
|
||||
typedef EGLSurface (*eglCreatePixmapSurfaceHI_PTR)(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI * pixmap);
|
||||
typedef EGLBoolean (*eglDestroyImageKHR_PTR)(EGLDisplay dpy, EGLImageKHR image);
|
||||
typedef EGLBoolean (*eglDestroyStreamKHR_PTR)(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
typedef EGLImageKHR (*eglCreateImageKHR_PTR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint * attrib_list);
|
||||
typedef EGLStreamKHR (*eglCreateStreamFromFileDescriptorKHR_PTR)(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
|
||||
typedef EGLStreamKHR (*eglCreateStreamKHR_PTR)(EGLDisplay dpy, const EGLint * attrib_list);
|
||||
typedef EGLBoolean (*eglDestroySyncKHR_PTR)(EGLDisplay dpy, EGLSyncKHR sync);
|
||||
typedef EGLBoolean (*eglSignalSyncKHR_PTR)(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
|
||||
typedef EGLBoolean (*eglGetSyncAttribKHR_PTR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint * value);
|
||||
typedef EGLBoolean (*eglStreamAttribKHR_PTR)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
|
||||
typedef EGLBoolean (*eglStreamConsumerAcquireKHR_PTR)(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
typedef EGLBoolean (*eglStreamConsumerGLTextureExternalKHR_PTR)(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
typedef EGLBoolean (*eglStreamConsumerReleaseKHR_PTR)(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
typedef EGLBoolean (*eglLockSurfaceKHR_PTR)(EGLDisplay display, EGLSurface surface, const EGLint * attrib_list);
|
||||
typedef EGLNativeFileDescriptorKHR (*eglGetStreamFileDescriptorKHR_PTR)(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
typedef EGLBoolean (*eglQueryStreamKHR_PTR)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint * value);
|
||||
typedef EGLBoolean (*eglQueryStreamTimeKHR_PTR)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR * value);
|
||||
typedef EGLint (*eglWaitSyncKHR_PTR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
|
||||
typedef EGLSurface (*eglCreateStreamProducerSurfaceKHR_PTR)(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint * attrib_list);
|
||||
#endif // TEXSTREAM
|
||||
#endif // NOEGL
|
||||
|
||||
#ifdef AMIGAOS4
|
||||
#include "../agl/amigaos.h"
|
||||
#elif !defined(_WIN32)
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#ifndef _WINBASE_
|
||||
typedef struct HISTANCE__* HISTANCE;
|
||||
typedef intptr_t (__stdcall* FPROC)();
|
||||
__declspec(dllimport)
|
||||
FPROC __stdcall GetProcAddress(HISTANCE, const char*);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
__forceinline
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline)) __inline
|
||||
#endif
|
||||
static void* dlsym(void* __restrict handle, const char* __restrict symbol)
|
||||
{ return (void*)GetProcAddress(handle, symbol); }
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
extern void* (APIENTRY_GL4ES *gles_getProcAddress)(const char *name);
|
||||
extern void (APIENTRY_GL4ES *gl4es_getMainFBSize)(GLint* width, GLint* height);
|
||||
NonAliasExportDecl(void*,proc_address,(void *lib, const char *name));
|
||||
// will become references to dlopen'd gles and egl
|
||||
extern void *gles, *bcm_host, *vcos, *gbm, *drm;
|
||||
EXPORT extern void *egl;
|
||||
#if defined __APPLE__ || defined __EMSCRIPTEN__
|
||||
#define NO_LOADER
|
||||
#endif
|
||||
|
||||
#define WARN_NULL(name) if (name == NULL) LOGD("warning, %s line %d function %s: " #name " is NULL\n", __FILE__, __LINE__, __func__);
|
||||
|
||||
#define MSVC_SPC(MACRO, ARGS) MACRO ARGS
|
||||
|
||||
#define PUSH_IF_COMPILING_EXT(nam, ...) \
|
||||
if (glstate->list.active) { \
|
||||
if (!glstate->list.pending) { \
|
||||
NewStage(glstate->list.active, STAGE_GLCALL); \
|
||||
MSVC_SPC(push_##nam, (__VA_ARGS__)); \
|
||||
noerrorShim(); \
|
||||
return (nam##_RETURN)0; \
|
||||
} \
|
||||
else gl4es_flush(); \
|
||||
}
|
||||
|
||||
#define PUSH_IF_COMPILING(name) PUSH_IF_COMPILING_EXT(name, name##_ARG_NAMES)
|
||||
|
||||
#define DEFINE_RAW(lib, name) static name##_PTR lib##_##name = NULL
|
||||
#define LOAD_RAW(lib, name, ...) \
|
||||
{ \
|
||||
static bool first = true; \
|
||||
if (first) { \
|
||||
first = false; \
|
||||
if (lib != NULL) { \
|
||||
lib##_##name = (name##_PTR)__VA_ARGS__; \
|
||||
} \
|
||||
WARN_NULL(lib##_##name); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LOAD_RAW_3(lib, name, fnc1, fnc2, ...) \
|
||||
{ \
|
||||
static bool first = true; \
|
||||
if (first) { \
|
||||
first = false; \
|
||||
if (lib != NULL) { \
|
||||
lib##_##name = (name##_PTR)fnc1; \
|
||||
if(! lib##_##name) \
|
||||
lib##_##name = (name##_PTR)fnc2; \
|
||||
if(! lib##_##name) { \
|
||||
__VA_ARGS__ \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LOAD_RAW_SILENT(lib, name, ...) \
|
||||
{ \
|
||||
static bool first = true; \
|
||||
if (first) { \
|
||||
first = false; \
|
||||
if (lib != NULL) { \
|
||||
lib##_##name = (name##_PTR)__VA_ARGS__; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LOAD_RAW_ALT(lib, alt, name, ...) \
|
||||
{ \
|
||||
static bool first = true; \
|
||||
if (first) { \
|
||||
first = false; \
|
||||
if (lib != NULL) { \
|
||||
lib##_##name = (name##_PTR)__VA_ARGS__; \
|
||||
} \
|
||||
if(lib##_##name == NULL) \
|
||||
lib##_##name = alt##_##name; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LOAD_LIB(lib, name) DEFINE_RAW(lib, name); LOAD_RAW(lib, name, proc_address(lib, #name))
|
||||
#define LOAD_LIB_SILENT(lib, name) DEFINE_RAW(lib, name); LOAD_RAW_SILENT(lib, name, proc_address(lib, #name))
|
||||
#define LOAD_LIB_ALT(lib, alt, name) DEFINE_RAW(lib, name); LOAD_RAW_ALT(lib, alt, name, proc_address(lib, #name))
|
||||
|
||||
#define LOAD_GLES(name) LOAD_LIB(gles, name)
|
||||
#define LOAD_GLES2(name) LOAD_LIB_SILENT(gles, name)
|
||||
#define LOAD_GLES_OR_FPE(name) LOAD_LIB_ALT(gles, fpe, name)
|
||||
|
||||
#define LOAD_GLES_FPE(name) \
|
||||
DEFINE_RAW(gles, name); \
|
||||
if(hardext.esversion==1) { \
|
||||
LOAD_RAW(gles, name, proc_address(gles, #name)); \
|
||||
} else { \
|
||||
gles_##name = fpe_##name; \
|
||||
}
|
||||
|
||||
#define LOAD_EGL(name) LOAD_LIB(egl, name)
|
||||
|
||||
#define LOAD_GBM(name) LOAD_LIB(gbm, name)
|
||||
|
||||
#if defined(AMIGAOS4) || defined(NOEGL) || defined(__EMSCRIPTEN__)
|
||||
#define LOAD_GLES_OES(name) \
|
||||
DEFINE_RAW(gles, name); \
|
||||
{ \
|
||||
LOAD_RAW(gles, name, proc_address(gles, #name"OES")); \
|
||||
}
|
||||
|
||||
#define LOAD_GLES_EXT(name) \
|
||||
DEFINE_RAW(gles, name); \
|
||||
{ \
|
||||
LOAD_RAW(gles, name, proc_address(gles, #name"EXT")); \
|
||||
}
|
||||
|
||||
#define LOAD_GLES2_OR_OES(name) \
|
||||
DEFINE_RAW(gles, name); \
|
||||
{ \
|
||||
LOAD_RAW_SILENT(gles, name, proc_address(gles, #name)); \
|
||||
}
|
||||
|
||||
#else // defined(AMIGAOS4) || defined(NOEGL)
|
||||
|
||||
#define LOAD_EGL_EXT(name) \
|
||||
DEFINE_RAW(egl, name); \
|
||||
LOAD_RAW_3(egl, name, proc_address(egl, #name), proc_address(egl, #name "EXT"), LOAD_EGL(eglGetProcAddress); LOAD_RAW(egl, name, egl_eglGetProcAddress(#name "EXT")); )
|
||||
|
||||
#define LOAD_GLES_OES(name) \
|
||||
DEFINE_RAW(gles, name); \
|
||||
{ \
|
||||
LOAD_EGL(eglGetProcAddress); \
|
||||
LOAD_RAW(gles, name, egl_eglGetProcAddress(#name"OES")); \
|
||||
}
|
||||
|
||||
#define LOAD_GLES_EXT(name) \
|
||||
DEFINE_RAW(gles, name); \
|
||||
{ \
|
||||
LOAD_EGL(eglGetProcAddress); \
|
||||
LOAD_RAW(gles, name, egl_eglGetProcAddress(#name"EXT")); \
|
||||
}
|
||||
|
||||
#define LOAD_GLES2_OR_OES(name) \
|
||||
DEFINE_RAW(gles, name); \
|
||||
{ \
|
||||
LOAD_EGL(eglGetProcAddress); \
|
||||
LOAD_RAW_SILENT(gles, name, ((hardext.esversion==1)?((void*)egl_eglGetProcAddress(#name"OES")):((void*)dlsym(gles, #name)))); \
|
||||
}
|
||||
#endif // defined(AMIGAOS4) || defined(NOEGL)
|
||||
|
||||
#endif // _GL4ES_LOADER_H_
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "logs.h"
|
||||
#include "init.h"
|
||||
#include <stdarg.h>
|
||||
#if defined(ANDROID) && defined(USE_ANDROID_LOG)
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
//----------------------------------------------------------------------------
|
||||
static const char * const log_prefix="LIBGL: ";
|
||||
//----------------------------------------------------------------------------
|
||||
void LogPrintf_NoPrefix(const char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args,fmt);
|
||||
#if defined(ANDROID) && defined(USE_ANDROID_LOG)
|
||||
__android_log_vprint(ANDROID_LOG_INFO, "LIBGL", fmt, args);
|
||||
#else
|
||||
vprintf(fmt,args);
|
||||
#endif
|
||||
va_end(args);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void LogFPrintf(FILE *fp,const char *fmt,...)
|
||||
{
|
||||
#ifndef ANDROID
|
||||
fprintf(fp,log_prefix);
|
||||
#endif
|
||||
va_list args;
|
||||
va_start(args,fmt);
|
||||
#if defined(ANDROID) && defined(USE_ANDROID_LOG)
|
||||
// also on logcat
|
||||
__android_log_vprint(ANDROID_LOG_INFO, "LIBGL", fmt, args);
|
||||
#endif
|
||||
vfprintf(fp,fmt,args);
|
||||
va_end(args);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void LogPrintf(const char *fmt,...)
|
||||
{
|
||||
#ifndef ANDROID
|
||||
printf(log_prefix);
|
||||
#endif
|
||||
va_list args;
|
||||
va_start(args,fmt);
|
||||
#if defined(ANDROID) && defined(USE_ANDROID_LOG)
|
||||
__android_log_vprint(ANDROID_LOG_INFO, "LIBGL", fmt, args);
|
||||
#else
|
||||
vprintf(fmt,args);
|
||||
#endif
|
||||
va_end(args);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef _GL4ES_LOGS_H_
|
||||
#define _GL4ES_LOGS_H_
|
||||
//----------------------------------------------------------------------------
|
||||
#include <stdio.h>
|
||||
#include "init.h"
|
||||
#include "attributes.h"
|
||||
//----------------------------------------------------------------------------
|
||||
void LogPrintf_NoPrefix(const char *fmt,...);
|
||||
void LogFPrintf(FILE *fp,const char *fmt,...);
|
||||
EXPORT void LogPrintf(const char *fmt,...);
|
||||
//----------------------------------------------------------------------------
|
||||
#ifdef GL4ES_SILENCE_MESSAGES
|
||||
#define SHUT_LOGD(...)
|
||||
#define SHUT_LOGD_NOPREFIX(...)
|
||||
#define SHUT_LOGE(...)
|
||||
#else
|
||||
#define SHUT_LOGD(...) if(!globals4es.nobanner) LogPrintf(__VA_ARGS__)
|
||||
#define SHUT_LOGD_NOPREFIX(...) if(!globals4es.nobanner) LogPrintf_NoPrefix(__VA_ARGS__)
|
||||
#define SHUT_LOGE(...) if(!globals4es.nobanner) LogFPrintf(stderr,__VA_ARGS__)
|
||||
#endif
|
||||
//----------------------------------------------------------------------------
|
||||
#define LOGD(...) LogPrintf(__VA_ARGS__)
|
||||
#define LOGE(...) LogFPrintf(stderr,__VA_ARGS__)
|
||||
//----------------------------------------------------------------------------
|
||||
#endif // _GL4ES_LOGS_H_
|
||||
@@ -0,0 +1,103 @@
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.5
|
||||
*
|
||||
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _M_EVAL_H
|
||||
#define _M_EVAL_H
|
||||
|
||||
#include "../gl4es.h"
|
||||
|
||||
void _math_init_eval( void );
|
||||
|
||||
|
||||
/*
|
||||
* Horner scheme for Bezier curves
|
||||
*
|
||||
* Bezier curves can be computed via a Horner scheme.
|
||||
* Horner is numerically less stable than the de Casteljau
|
||||
* algorithm, but it is faster. For curves of degree n
|
||||
* the complexity of Horner is O(n) and de Casteljau is O(n^2).
|
||||
* Since stability is not important for displaying curve
|
||||
* points I decided to use the Horner scheme.
|
||||
*
|
||||
* A cubic Bezier curve with control points b0, b1, b2, b3 can be
|
||||
* written as
|
||||
*
|
||||
* (([3] [3] ) [3] ) [3]
|
||||
* c(t) = (([0]*s*b0 + [1]*t*b1)*s + [2]*t^2*b2)*s + [3]*t^2*b3
|
||||
*
|
||||
* [n]
|
||||
* where s=1-t and the binomial coefficients [i]. These can
|
||||
* be computed iteratively using the identity:
|
||||
*
|
||||
* [n] [n ] [n]
|
||||
* [i] = (n-i+1)/i * [i-1] and [0] = 1
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
_math_horner_bezier_curve(const GLfloat *cp, GLfloat *out, GLfloat t,
|
||||
GLuint dim, GLuint order);
|
||||
|
||||
|
||||
/*
|
||||
* Tensor product Bezier surfaces
|
||||
*
|
||||
* Again the Horner scheme is used to compute a point on a
|
||||
* TP Bezier surface. First a control polygon for a curve
|
||||
* on the surface in one parameter direction is computed,
|
||||
* then the point on the curve for the other parameter
|
||||
* direction is evaluated.
|
||||
*
|
||||
* To store the curve control polygon additional storage
|
||||
* for max(uorder,vorder) points is needed in the
|
||||
* control net cn.
|
||||
*/
|
||||
|
||||
void
|
||||
_math_horner_bezier_surf(GLfloat *cn, GLfloat *out, GLfloat u, GLfloat v,
|
||||
GLuint dim, GLuint uorder, GLuint vorder);
|
||||
|
||||
|
||||
/*
|
||||
* The direct de Casteljau algorithm is used when a point on the
|
||||
* surface and the tangent directions spanning the tangent plane
|
||||
* should be computed (this is needed to compute normals to the
|
||||
* surface). In this case the de Casteljau algorithm approach is
|
||||
* nicer because a point and the partial derivatives can be computed
|
||||
* at the same time. To get the correct tangent length du and dv
|
||||
* must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1.
|
||||
* Since only the directions are needed, this scaling step is omitted.
|
||||
*
|
||||
* De Casteljau needs additional storage for uorder*vorder
|
||||
* values in the control net cn.
|
||||
*/
|
||||
|
||||
void
|
||||
_math_de_casteljau_surf(GLfloat *cn, GLfloat *out, GLfloat *du, GLfloat *dv,
|
||||
GLfloat u, GLfloat v, GLuint dim,
|
||||
GLuint uorder, GLuint vorder);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,452 @@
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.5
|
||||
*
|
||||
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* eval.c was written by
|
||||
* Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and
|
||||
* Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de).
|
||||
*
|
||||
* My original implementation of evaluators was simplistic and didn't
|
||||
* compute surface normal vectors properly. Bernd and Volker applied
|
||||
* used more sophisticated methods to get better results.
|
||||
*
|
||||
* Thanks guys!
|
||||
*/
|
||||
|
||||
#include "eval.h"
|
||||
|
||||
static GLboolean init_done = false;
|
||||
static GLfloat inv_tab[MAX_EVAL_ORDER];
|
||||
|
||||
/*
|
||||
* Horner scheme for Bezier curves
|
||||
*
|
||||
* Bezier curves can be computed via a Horner scheme.
|
||||
* Horner is numerically less stable than the de Casteljau
|
||||
* algorithm, but it is faster. For curves of degree n
|
||||
* the complexity of Horner is O(n) and de Casteljau is O(n^2).
|
||||
* Since stability is not important for displaying curve
|
||||
* points I decided to use the Horner scheme.
|
||||
*
|
||||
* A cubic Bezier curve with control points b0, b1, b2, b3 can be
|
||||
* written as
|
||||
*
|
||||
* (([3] [3] ) [3] ) [3]
|
||||
* c(t) = (([0]*s*b0 + [1]*t*b1)*s + [2]*t^2*b2)*s + [3]*t^2*b3
|
||||
*
|
||||
* [n]
|
||||
* where s=1-t and the binomial coefficients [i]. These can
|
||||
* be computed iteratively using the identity:
|
||||
*
|
||||
* [n] [n ] [n]
|
||||
* [i] = (n-i+1)/i * [i-1] and [0] = 1
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
_math_horner_bezier_curve(const GLfloat * cp, GLfloat * out, GLfloat t,
|
||||
GLuint dim, GLuint order) {
|
||||
if (! init_done)
|
||||
_math_init_eval();
|
||||
|
||||
GLfloat s, powert, bincoeff;
|
||||
GLuint i, k;
|
||||
|
||||
if (order >= 2) {
|
||||
bincoeff = (GLfloat) (order - 1);
|
||||
s = 1.0F - t;
|
||||
for (k = 0; k < dim; k++)
|
||||
out[k] = s * cp[k] + bincoeff * t * cp[dim + k];
|
||||
|
||||
for (i = 2, cp += 2 * dim, powert = t * t; i < order;
|
||||
i++, powert *= t, cp += dim) {
|
||||
bincoeff *= (GLfloat) (order - i);
|
||||
bincoeff *= inv_tab[i];
|
||||
|
||||
for (k = 0; k < dim; k++)
|
||||
out[k] = s * out[k] + bincoeff * powert * cp[k];
|
||||
}
|
||||
} else { /* order=1 -> constant curve */
|
||||
for (k = 0; k < dim; k++)
|
||||
out[k] = cp[k];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Tensor product Bezier surfaces
|
||||
*
|
||||
* Again the Horner scheme is used to compute a point on a
|
||||
* TP Bezier surface. First a control polygon for a curve
|
||||
* on the surface in one parameter direction is computed,
|
||||
* then the point on the curve for the other parameter
|
||||
* direction is evaluated.
|
||||
*
|
||||
* To store the curve control polygon additional storage
|
||||
* for max(uorder,vorder) points is needed in the
|
||||
* control net cn.
|
||||
*/
|
||||
|
||||
void
|
||||
_math_horner_bezier_surf(GLfloat * cn, GLfloat * out, GLfloat u, GLfloat v,
|
||||
GLuint dim, GLuint uorder, GLuint vorder) {
|
||||
if (! init_done)
|
||||
_math_init_eval();
|
||||
|
||||
GLfloat *cp = cn + uorder * vorder * dim;
|
||||
GLuint i, uinc = vorder * dim;
|
||||
|
||||
if (vorder > uorder) {
|
||||
if (uorder >= 2) {
|
||||
GLfloat s, poweru, bincoeff;
|
||||
GLuint j, k;
|
||||
|
||||
/* Compute the control polygon for the surface-curve in u-direction */
|
||||
for (j = 0; j < vorder; j++) {
|
||||
GLfloat *ucp = &cn[j * dim];
|
||||
|
||||
/* Each control point is the point for parameter u on a */
|
||||
/* curve defined by the control polygons in u-direction */
|
||||
bincoeff = (GLfloat) (uorder - 1);
|
||||
s = 1.0F - u;
|
||||
|
||||
for (k = 0; k < dim; k++)
|
||||
cp[j * dim + k] = s * ucp[k] + bincoeff * u * ucp[uinc + k];
|
||||
|
||||
for (i = 2, ucp += 2 * uinc, poweru = u * u; i < uorder;
|
||||
i++, poweru *= u, ucp += uinc) {
|
||||
bincoeff *= (GLfloat) (uorder - i);
|
||||
bincoeff *= inv_tab[i];
|
||||
|
||||
for (k = 0; k < dim; k++)
|
||||
cp[j * dim + k] =
|
||||
s * cp[j * dim + k] + bincoeff * poweru * ucp[k];
|
||||
}
|
||||
}
|
||||
|
||||
/* Evaluate curve point in v */
|
||||
_math_horner_bezier_curve(cp, out, v, dim, vorder);
|
||||
} else /* uorder=1 -> cn defines a curve in v */
|
||||
_math_horner_bezier_curve(cn, out, v, dim, vorder);
|
||||
} else { /* vorder <= uorder */
|
||||
|
||||
if (vorder > 1) {
|
||||
GLuint i;
|
||||
|
||||
/* Compute the control polygon for the surface-curve in u-direction */
|
||||
for (i = 0; i < uorder; i++, cn += uinc) {
|
||||
/* For constant i all cn[i][j] (j=0..vorder) are located */
|
||||
/* on consecutive memory locations, so we can use */
|
||||
/* horner_bezier_curve to compute the control points */
|
||||
|
||||
_math_horner_bezier_curve(cn, &cp[i * dim], v, dim, vorder);
|
||||
}
|
||||
|
||||
/* Evaluate curve point in u */
|
||||
_math_horner_bezier_curve(cp, out, u, dim, uorder);
|
||||
} else /* vorder=1 -> cn defines a curve in u */
|
||||
_math_horner_bezier_curve(cn, out, u, dim, uorder);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The direct de Casteljau algorithm is used when a point on the
|
||||
* surface and the tangent directions spanning the tangent plane
|
||||
* should be computed (this is needed to compute normals to the
|
||||
* surface). In this case the de Casteljau algorithm approach is
|
||||
* nicer because a point and the partial derivatives can be computed
|
||||
* at the same time. To get the correct tangent length du and dv
|
||||
* must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1.
|
||||
* Since only the directions are needed, this scaling step is omitted.
|
||||
*
|
||||
* De Casteljau needs additional storage for uorder*vorder
|
||||
* values in the control net cn.
|
||||
*/
|
||||
|
||||
void
|
||||
_math_de_casteljau_surf(GLfloat * cn, GLfloat * out, GLfloat * du,
|
||||
GLfloat * dv, GLfloat u, GLfloat v, GLuint dim,
|
||||
GLuint uorder, GLuint vorder) {
|
||||
GLfloat *dcn = cn + uorder * vorder * dim;
|
||||
GLfloat us = 1.0F - u, vs = 1.0F - v;
|
||||
GLuint h, i, j, k;
|
||||
GLuint minorder = uorder < vorder ? uorder : vorder;
|
||||
GLuint uinc = vorder * dim;
|
||||
GLuint dcuinc = vorder;
|
||||
|
||||
/* Each component is evaluated separately to save buffer space */
|
||||
/* This does not drasticaly decrease the performance of the */
|
||||
/* algorithm. If additional storage for (uorder-1)*(vorder-1) */
|
||||
/* points would be available, the components could be accessed */
|
||||
/* in the innermost loop which could lead to less cache misses. */
|
||||
|
||||
#define CN(I,J,K) cn[(I)*uinc+(J)*dim+(K)]
|
||||
#define DCN(I, J) dcn[(I)*dcuinc+(J)]
|
||||
if (minorder < 3) {
|
||||
if (uorder == vorder) {
|
||||
for (k = 0; k < dim; k++) {
|
||||
/* Derivative direction in u */
|
||||
du[k] = vs * (CN(1, 0, k) - CN(0, 0, k)) +
|
||||
v * (CN(1, 1, k) - CN(0, 1, k));
|
||||
|
||||
/* Derivative direction in v */
|
||||
dv[k] = us * (CN(0, 1, k) - CN(0, 0, k)) +
|
||||
u * (CN(1, 1, k) - CN(1, 0, k));
|
||||
|
||||
/* bilinear de Casteljau step */
|
||||
out[k] = us * (vs * CN(0, 0, k) + v * CN(0, 1, k)) +
|
||||
u * (vs * CN(1, 0, k) + v * CN(1, 1, k));
|
||||
}
|
||||
} else if (minorder == uorder) {
|
||||
for (k = 0; k < dim; k++) {
|
||||
/* bilinear de Casteljau step */
|
||||
DCN(1, 0) = CN(1, 0, k) - CN(0, 0, k);
|
||||
DCN(0, 0) = us * CN(0, 0, k) + u * CN(1, 0, k);
|
||||
|
||||
for (j = 0; j < vorder - 1; j++) {
|
||||
/* for the derivative in u */
|
||||
DCN(1, j + 1) = CN(1, j + 1, k) - CN(0, j + 1, k);
|
||||
DCN(1, j) = vs * DCN(1, j) + v * DCN(1, j + 1);
|
||||
|
||||
/* for the `point' */
|
||||
DCN(0, j + 1) = us * CN(0, j + 1, k) + u * CN(1, j + 1, k);
|
||||
DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1);
|
||||
}
|
||||
|
||||
/* remaining linear de Casteljau steps until the second last step */
|
||||
for (h = minorder; h < vorder - 1; h++)
|
||||
for (j = 0; j < vorder - h; j++) {
|
||||
/* for the derivative in u */
|
||||
DCN(1, j) = vs * DCN(1, j) + v * DCN(1, j + 1);
|
||||
|
||||
/* for the `point' */
|
||||
DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1);
|
||||
}
|
||||
|
||||
/* derivative direction in v */
|
||||
dv[k] = DCN(0, 1) - DCN(0, 0);
|
||||
|
||||
/* derivative direction in u */
|
||||
du[k] = vs * DCN(1, 0) + v * DCN(1, 1);
|
||||
|
||||
/* last linear de Casteljau step */
|
||||
out[k] = vs * DCN(0, 0) + v * DCN(0, 1);
|
||||
}
|
||||
} else { /* minorder == vorder */
|
||||
for (k = 0; k < dim; k++) {
|
||||
/* bilinear de Casteljau step */
|
||||
DCN(0, 1) = CN(0, 1, k) - CN(0, 0, k);
|
||||
DCN(0, 0) = vs * CN(0, 0, k) + v * CN(0, 1, k);
|
||||
for (i = 0; i < uorder - 1; i++) {
|
||||
/* for the derivative in v */
|
||||
DCN(i + 1, 1) = CN(i + 1, 1, k) - CN(i + 1, 0, k);
|
||||
DCN(i, 1) = us * DCN(i, 1) + u * DCN(i + 1, 1);
|
||||
|
||||
/* for the `point' */
|
||||
DCN(i + 1, 0) = vs * CN(i + 1, 0, k) + v * CN(i + 1, 1, k);
|
||||
DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0);
|
||||
}
|
||||
|
||||
/* remaining linear de Casteljau steps until the second last step */
|
||||
for (h = minorder; h < uorder - 1; h++)
|
||||
for (i = 0; i < uorder - h; i++) {
|
||||
/* for the derivative in v */
|
||||
DCN(i, 1) = us * DCN(i, 1) + u * DCN(i + 1, 1);
|
||||
|
||||
/* for the `point' */
|
||||
DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0);
|
||||
}
|
||||
|
||||
/* derivative direction in u */
|
||||
du[k] = DCN(1, 0) - DCN(0, 0);
|
||||
|
||||
/* derivative direction in v */
|
||||
dv[k] = us * DCN(0, 1) + u * DCN(1, 1);
|
||||
|
||||
/* last linear de Casteljau step */
|
||||
out[k] = us * DCN(0, 0) + u * DCN(1, 0);
|
||||
}
|
||||
}
|
||||
} else if (uorder == vorder) {
|
||||
for (k = 0; k < dim; k++) {
|
||||
/* first bilinear de Casteljau step */
|
||||
for (i = 0; i < uorder - 1; i++) {
|
||||
DCN(i, 0) = us * CN(i, 0, k) + u * CN(i + 1, 0, k);
|
||||
for (j = 0; j < vorder - 1; j++) {
|
||||
DCN(i, j + 1) = us * CN(i, j + 1, k) + u * CN(i + 1, j + 1, k);
|
||||
DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* remaining bilinear de Casteljau steps until the second last step */
|
||||
for (h = 2; h < minorder - 1; h++) {
|
||||
for (i = 0; i < uorder - h; i++) {
|
||||
DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0);
|
||||
for (j = 0; j < vorder - h; j++) {
|
||||
DCN(i, j + 1) = us * DCN(i, j + 1) + u * DCN(i + 1, j + 1);
|
||||
DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* derivative direction in u */
|
||||
du[k] = vs * (DCN(1, 0) - DCN(0, 0)) + v * (DCN(1, 1) - DCN(0, 1));
|
||||
|
||||
/* derivative direction in v */
|
||||
dv[k] = us * (DCN(0, 1) - DCN(0, 0)) + u * (DCN(1, 1) - DCN(1, 0));
|
||||
|
||||
/* last bilinear de Casteljau step */
|
||||
out[k] = us * (vs * DCN(0, 0) + v * DCN(0, 1)) +
|
||||
u * (vs * DCN(1, 0) + v * DCN(1, 1));
|
||||
}
|
||||
} else if (minorder == uorder) {
|
||||
for (k = 0; k < dim; k++) {
|
||||
/* first bilinear de Casteljau step */
|
||||
for (i = 0; i < uorder - 1; i++) {
|
||||
DCN(i, 0) = us * CN(i, 0, k) + u * CN(i + 1, 0, k);
|
||||
for (j = 0; j < vorder - 1; j++) {
|
||||
DCN(i, j + 1) = us * CN(i, j + 1, k) + u * CN(i + 1, j + 1, k);
|
||||
DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* remaining bilinear de Casteljau steps until the second last step */
|
||||
for (h = 2; h < minorder - 1; h++) {
|
||||
for (i = 0; i < uorder - h; i++) {
|
||||
DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0);
|
||||
for (j = 0; j < vorder - h; j++) {
|
||||
DCN(i, j + 1) = us * DCN(i, j + 1) + u * DCN(i + 1, j + 1);
|
||||
DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* last bilinear de Casteljau step */
|
||||
DCN(2, 0) = DCN(1, 0) - DCN(0, 0);
|
||||
DCN(0, 0) = us * DCN(0, 0) + u * DCN(1, 0);
|
||||
for (j = 0; j < vorder - 1; j++) {
|
||||
/* for the derivative in u */
|
||||
DCN(2, j + 1) = DCN(1, j + 1) - DCN(0, j + 1);
|
||||
DCN(2, j) = vs * DCN(2, j) + v * DCN(2, j + 1);
|
||||
|
||||
/* for the `point' */
|
||||
DCN(0, j + 1) = us * DCN(0, j + 1) + u * DCN(1, j + 1);
|
||||
DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1);
|
||||
}
|
||||
|
||||
/* remaining linear de Casteljau steps until the second last step */
|
||||
for (h = minorder; h < vorder - 1; h++) {
|
||||
for (j = 0; j < vorder - h; j++) {
|
||||
/* for the derivative in u */
|
||||
DCN(2, j) = vs * DCN(2, j) + v * DCN(2, j + 1);
|
||||
|
||||
/* for the `point' */
|
||||
DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* derivative direction in v */
|
||||
dv[k] = DCN(0, 1) - DCN(0, 0);
|
||||
|
||||
/* derivative direction in u */
|
||||
du[k] = vs * DCN(2, 0) + v * DCN(2, 1);
|
||||
|
||||
/* last linear de Casteljau step */
|
||||
out[k] = vs * DCN(0, 0) + v * DCN(0, 1);
|
||||
}
|
||||
} else { /* minorder == vorder */
|
||||
|
||||
for (k = 0; k < dim; k++) {
|
||||
/* first bilinear de Casteljau step */
|
||||
for (i = 0; i < uorder - 1; i++) {
|
||||
DCN(i, 0) = us * CN(i, 0, k) + u * CN(i + 1, 0, k);
|
||||
for (j = 0; j < vorder - 1; j++) {
|
||||
DCN(i, j + 1) = us * CN(i, j + 1, k) + u * CN(i + 1, j + 1, k);
|
||||
DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* remaining bilinear de Casteljau steps until the second last step */
|
||||
for (h = 2; h < minorder - 1; h++) {
|
||||
for (i = 0; i < uorder - h; i++) {
|
||||
DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0);
|
||||
for (j = 0; j < vorder - h; j++) {
|
||||
DCN(i, j + 1) = us * DCN(i, j + 1) + u * DCN(i + 1, j + 1);
|
||||
DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* last bilinear de Casteljau step */
|
||||
DCN(0, 2) = DCN(0, 1) - DCN(0, 0);
|
||||
DCN(0, 0) = vs * DCN(0, 0) + v * DCN(0, 1);
|
||||
for (i = 0; i < uorder - 1; i++) {
|
||||
/* for the derivative in v */
|
||||
DCN(i + 1, 2) = DCN(i + 1, 1) - DCN(i + 1, 0);
|
||||
DCN(i, 2) = us * DCN(i, 2) + u * DCN(i + 1, 2);
|
||||
|
||||
/* for the `point' */
|
||||
DCN(i + 1, 0) = vs * DCN(i + 1, 0) + v * DCN(i + 1, 1);
|
||||
DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0);
|
||||
}
|
||||
|
||||
/* remaining linear de Casteljau steps until the second last step */
|
||||
for (h = minorder; h < uorder - 1; h++) {
|
||||
for (i = 0; i < uorder - h; i++) {
|
||||
/* for the derivative in v */
|
||||
DCN(i, 2) = us * DCN(i, 2) + u * DCN(i + 1, 2);
|
||||
|
||||
/* for the `point' */
|
||||
DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* derivative direction in u */
|
||||
du[k] = DCN(1, 0) - DCN(0, 0);
|
||||
|
||||
/* derivative direction in v */
|
||||
dv[k] = us * DCN(0, 2) + u * DCN(1, 2);
|
||||
|
||||
/* last linear de Casteljau step */
|
||||
out[k] = us * DCN(0, 0) + u * DCN(1, 0);
|
||||
}
|
||||
}
|
||||
#undef DCN
|
||||
#undef CN
|
||||
}
|
||||
|
||||
/*
|
||||
* Do one-time initialization for evaluators.
|
||||
*/
|
||||
void _math_init_eval() {
|
||||
GLuint i;
|
||||
|
||||
/* KW: precompute 1/x for useful x.
|
||||
*/
|
||||
for (i = 1; i < MAX_EVAL_ORDER; i++)
|
||||
inv_tab[i] = 1.0F / i;
|
||||
|
||||
init_done = true;
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
#include "matrix.h"
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "debug.h"
|
||||
#include "fpe.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "init.h"
|
||||
#include "loader.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DBG(a) a
|
||||
#else
|
||||
#define DBG(a)
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#define TOP(A) (glstate->A->stack+(glstate->A->top*16))
|
||||
|
||||
static GLfloat* update_current_mat() {
|
||||
switch(glstate->matrix_mode) {
|
||||
case GL_MODELVIEW:
|
||||
return TOP(modelview_matrix);
|
||||
case GL_PROJECTION:
|
||||
return TOP(projection_matrix);
|
||||
case GL_TEXTURE:
|
||||
return TOP(texture_matrix[glstate->texture.active]);
|
||||
default:
|
||||
if(glstate->matrix_mode>=GL_MATRIX0_ARB && glstate->matrix_mode<GL_MATRIX0_ARB+MAX_ARB_MATRIX)
|
||||
return TOP(arb_matrix[glstate->matrix_mode-GL_MATRIX0_ARB]);
|
||||
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]));
|
||||
default:
|
||||
if(glstate->matrix_mode>=GL_MATRIX0_ARB && glstate->matrix_mode<GL_MATRIX0_ARB+MAX_ARB_MATRIX)
|
||||
return glstate->arb_matrix[glstate->matrix_mode-GL_MATRIX0_ARB]->identity = (I)?1:is_identity(TOP(arb_matrix[glstate->matrix_mode-GL_MATRIX0_ARB]));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int send_to_hardware() {
|
||||
if(hardext.esversion>1)
|
||||
return 0;
|
||||
switch(glstate->matrix_mode) {
|
||||
case GL_PROJECTION:
|
||||
return 1;
|
||||
case GL_MODELVIEW:
|
||||
return 1;
|
||||
case GL_TEXTURE:
|
||||
return (globals4es.texmat)?1:0;
|
||||
/*default:
|
||||
if(glstate->matrix_mode>=GL_MATRIX0_ARB && glstate->matrix_mode<GL_MATRIX0_ARB+MAX_ARB_MATRIX)
|
||||
return 0;*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_matrix(glstate_t* glstate) {
|
||||
DBG(printf("init_matrix(%p)\n", 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);
|
||||
glstate->arb_matrix = (matrixstack_t**)malloc(sizeof(matrixstack_t*)*MAX_ARB_MATRIX);
|
||||
set_identity(glstate->mvp_matrix);
|
||||
glstate->mvp_matrix_dirty = 0;
|
||||
set_identity(glstate->inv_mv_matrix);
|
||||
glstate->inv_mv_matrix_dirty = 0;
|
||||
// no identity function for 3x3 matrix
|
||||
memset(glstate->normal_matrix, 0, 9*sizeof(GLfloat));
|
||||
glstate->normal_matrix[0] = glstate->normal_matrix[4] = glstate->normal_matrix[8] = 1.0f;
|
||||
glstate->normal_matrix_dirty = 1;
|
||||
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;
|
||||
}
|
||||
for (int i=0; i<MAX_ARB_MATRIX; i++) {
|
||||
alloc_matrix(&glstate->arb_matrix[i], MAX_STACK_ARB_MATRIX);
|
||||
set_identity(TOP(arb_matrix[i]));
|
||||
glstate->arb_matrix[i]->identity = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void set_fpe_textureidentity() {
|
||||
if(glstate->texture_matrix[glstate->texture.active]->identity) // inverted in fpe flags
|
||||
glstate->fpe_state->texture[glstate->texture.active].texmat = 0;
|
||||
else
|
||||
glstate->fpe_state->texture[glstate->texture.active].texmat = 1;
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMatrixMode(GLenum mode) {
|
||||
DBG(printf("glMatrixMode(%s), list=%p\n", PrintEnum(mode), glstate->list.active);)
|
||||
noerrorShim();
|
||||
if (glstate->list.active && glstate->list.pending && glstate->matrix_mode==GL_MODELVIEW && mode==GL_MODELVIEW) {
|
||||
return; // nothing to do...
|
||||
}
|
||||
PUSH_IF_COMPILING(glMatrixMode);
|
||||
|
||||
if(!((mode==GL_MODELVIEW) || (mode==GL_PROJECTION) || (mode==GL_TEXTURE) || (mode>=GL_MATRIX0_ARB && mode<(GL_MATRIX0_ARB+MAX_ARB_MATRIX)))) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(glstate->matrix_mode != mode) {
|
||||
glstate->matrix_mode = mode;
|
||||
LOAD_GLES_FPE(glMatrixMode);
|
||||
gles_glMatrixMode(mode);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glPushMatrix(void) {
|
||||
DBG(printf("glPushMatrix(), list=%p\n", glstate->list.active);)
|
||||
if (glstate->list.active && !glstate->list.pending) {
|
||||
PUSH_IF_COMPILING(glPushMatrix);
|
||||
}
|
||||
// get matrix mode
|
||||
GLint matrix_mode = glstate->matrix_mode;
|
||||
noerrorShim();
|
||||
// go...
|
||||
switch(matrix_mode) {
|
||||
#define P(A, B) if(glstate->A->top+1<MAX_STACK_##B) { \
|
||||
memcpy(TOP(A)+16, TOP(A), 16*sizeof(GLfloat)); \
|
||||
glstate->A->top++; \
|
||||
} else errorShim(GL_STACK_OVERFLOW)
|
||||
case GL_PROJECTION:
|
||||
P(projection_matrix, PROJECTION);
|
||||
break;
|
||||
case GL_MODELVIEW:
|
||||
P(modelview_matrix, MODELVIEW);
|
||||
break;
|
||||
case GL_TEXTURE:
|
||||
P(texture_matrix[glstate->texture.active], TEXTURE);
|
||||
break;
|
||||
default:
|
||||
if(glstate->matrix_mode>=GL_MATRIX0_ARB && glstate->matrix_mode<GL_MATRIX0_ARB+MAX_ARB_MATRIX) {
|
||||
P(arb_matrix[glstate->matrix_mode-GL_MATRIX0_ARB], ARB_MATRIX);
|
||||
} else {
|
||||
//Warning?
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
//LOGE("PushMatrix with Unrecognise matrix mode (0x%04X)\n", matrix_mode);
|
||||
//gles_glPushMatrix();
|
||||
}
|
||||
#undef P
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glPopMatrix(void) {
|
||||
DBG(printf("glPopMatrix(), list=%p\n", glstate->list.active);)
|
||||
if (glstate->list.active
|
||||
&& !(glstate->list.compiling)
|
||||
&& (globals4es.beginend)
|
||||
&& glstate->matrix_mode==GL_MODELVIEW
|
||||
&& !(glstate->polygon_mode==GL_LINE)
|
||||
&& glstate->list.pending) {
|
||||
// check if pop'd matrix is the same as actual...
|
||||
if(memcmp(TOP(modelview_matrix)-16, TOP(modelview_matrix), 16*sizeof(GLfloat))==0) {
|
||||
--glstate->modelview_matrix->top;
|
||||
return;
|
||||
}
|
||||
}
|
||||
PUSH_IF_COMPILING(glPopMatrix);
|
||||
// get matrix mode
|
||||
GLint matrix_mode = glstate->matrix_mode;
|
||||
// go...
|
||||
noerrorShim();
|
||||
switch(matrix_mode) {
|
||||
#define P(A) if(glstate->A->top) { \
|
||||
--glstate->A->top; \
|
||||
glstate->A->identity = is_identity(update_current_mat()); \
|
||||
if (send_to_hardware()) {LOAD_GLES(glLoadMatrixf); gles_glLoadMatrixf(update_current_mat()); } \
|
||||
} else errorShim(GL_STACK_UNDERFLOW)
|
||||
case GL_PROJECTION:
|
||||
P(projection_matrix);
|
||||
glstate->mvp_matrix_dirty = 1;
|
||||
break;
|
||||
case GL_MODELVIEW:
|
||||
P(modelview_matrix);
|
||||
glstate->mvp_matrix_dirty = 1;
|
||||
glstate->inv_mv_matrix_dirty = 1;
|
||||
glstate->normal_matrix_dirty = 1;
|
||||
break;
|
||||
case GL_TEXTURE:
|
||||
P(texture_matrix[glstate->texture.active]);
|
||||
if(glstate->fpe_state)
|
||||
set_fpe_textureidentity();
|
||||
break;
|
||||
default:
|
||||
if(glstate->matrix_mode>=GL_MATRIX0_ARB && glstate->matrix_mode<GL_MATRIX0_ARB+MAX_ARB_MATRIX) {
|
||||
P(arb_matrix[glstate->matrix_mode-GL_MATRIX0_ARB]);
|
||||
} else {
|
||||
//Warning?
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
//LOGE("PopMatrix with Unrecognise matrix mode (0x%04X)\n", matrix_mode);
|
||||
//gles_glPopMatrix();
|
||||
}
|
||||
#undef P
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES 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);)
|
||||
if (glstate->list.active) {
|
||||
if(glstate->list.pending) gl4es_flush();
|
||||
else {
|
||||
NewStage(glstate->list.active, STAGE_MATRIX);
|
||||
glstate->list.active->matrix_op = 1;
|
||||
memcpy(glstate->list.active->matrix_val, m, 16*sizeof(GLfloat));
|
||||
return;
|
||||
}
|
||||
}
|
||||
memcpy(update_current_mat(), m, 16*sizeof(GLfloat));
|
||||
const int id = update_current_identity(0);
|
||||
if(glstate->matrix_mode==GL_MODELVIEW)
|
||||
glstate->normal_matrix_dirty = glstate->inv_mv_matrix_dirty = 1;
|
||||
if(glstate->matrix_mode==GL_MODELVIEW || glstate->matrix_mode==GL_PROJECTION)
|
||||
glstate->mvp_matrix_dirty = 1;
|
||||
else if((glstate->matrix_mode==GL_TEXTURE) && glstate->fpe_state)
|
||||
set_fpe_textureidentity();
|
||||
if(send_to_hardware()) {
|
||||
LOAD_GLES(glLoadMatrixf);
|
||||
LOAD_GLES(glLoadIdentity);
|
||||
if(id) gles_glLoadIdentity(); // in case the driver as some special optimisations
|
||||
else gles_glLoadMatrixf(m);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES 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);)
|
||||
if (glstate->list.active) {
|
||||
if(glstate->list.pending) gl4es_flush();
|
||||
else {
|
||||
if(glstate->list.active->stage == STAGE_MATRIX) {
|
||||
// multiply the matrix mith the current one....
|
||||
matrix_mul(glstate->list.active->matrix_val, m, glstate->list.active->matrix_val);
|
||||
return;
|
||||
}
|
||||
NewStage(glstate->list.active, STAGE_MATRIX);
|
||||
glstate->list.active->matrix_op = 2;
|
||||
memcpy(glstate->list.active->matrix_val, m, 16*sizeof(GLfloat));
|
||||
return;
|
||||
}
|
||||
}
|
||||
GLfloat *current_mat = update_current_mat();
|
||||
matrix_mul(current_mat, m, current_mat);
|
||||
const int id = update_current_identity(0);
|
||||
if(glstate->matrix_mode==GL_MODELVIEW)
|
||||
glstate->normal_matrix_dirty = glstate->inv_mv_matrix_dirty = 1;
|
||||
if(glstate->matrix_mode==GL_MODELVIEW || glstate->matrix_mode==GL_PROJECTION)
|
||||
glstate->mvp_matrix_dirty = 1;
|
||||
else if((glstate->matrix_mode==GL_TEXTURE) && glstate->fpe_state)
|
||||
set_fpe_textureidentity();
|
||||
DBG(printf(" => (%f, %f, %f, %f, %f, %f, %f...)\n", current_mat[0], current_mat[1], current_mat[2], current_mat[3], current_mat[4], current_mat[5], current_mat[6]);)
|
||||
if(send_to_hardware()) {
|
||||
LOAD_GLES(glLoadMatrixf);
|
||||
LOAD_GLES(glLoadIdentity);
|
||||
if(id) gles_glLoadIdentity(); // in case the driver as some special optimisations
|
||||
else gles_glLoadMatrixf(current_mat);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glLoadIdentity(void) {
|
||||
DBG(printf("glLoadIdentity(), list=%p\n", glstate->list.active);)
|
||||
if (glstate->list.active) {
|
||||
if(glstate->list.pending) gl4es_flush();
|
||||
else {
|
||||
NewStage(glstate->list.active, STAGE_MATRIX);
|
||||
glstate->list.active->matrix_op = 1;
|
||||
set_identity(glstate->list.active->matrix_val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
set_identity(update_current_mat());
|
||||
update_current_identity(1);
|
||||
if(glstate->matrix_mode==GL_MODELVIEW)
|
||||
glstate->normal_matrix_dirty = glstate->inv_mv_matrix_dirty = 1;
|
||||
if(glstate->matrix_mode==GL_MODELVIEW || glstate->matrix_mode==GL_PROJECTION)
|
||||
glstate->mvp_matrix_dirty = 1;
|
||||
else if((glstate->matrix_mode==GL_TEXTURE) && glstate->fpe_state)
|
||||
set_fpe_textureidentity();
|
||||
if(send_to_hardware()) {
|
||||
LOAD_GLES(glLoadIdentity);
|
||||
gles_glLoadIdentity();
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
|
||||
DBG(printf("glTranslatef(%f, %f, %f), list=%p\n", x, y, z, glstate->list.active);)
|
||||
// create a translation matrix than multiply it...
|
||||
GLfloat tmp[16];
|
||||
set_identity(tmp);
|
||||
tmp[12+0] = x;
|
||||
tmp[12+1] = y;
|
||||
tmp[12+2] = z;
|
||||
gl4es_glMultMatrixf(tmp);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glScalef(GLfloat x, GLfloat y, GLfloat z) {
|
||||
DBG(printf("glScalef(%f, %f, %f), list=%p\n", x, y, z, glstate->list.active);)
|
||||
// create a scale matrix than multiply it...
|
||||
GLfloat tmp[16];
|
||||
memset(tmp, 0, 16*sizeof(GLfloat));
|
||||
tmp[0+0] = x;
|
||||
tmp[1+4] = y;
|
||||
tmp[2+8] = z;
|
||||
tmp[3+12] = 1.0f;
|
||||
gl4es_glMultMatrixf(tmp);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
|
||||
DBG(printf("glRotatef(%f, %f, %f, %f), list=%p\n", angle, x, y, z, glstate->list.active);)
|
||||
// create a rotation matrix than multiply it...
|
||||
GLfloat tmp[16];
|
||||
memset(tmp, 0, 16*sizeof(GLfloat));
|
||||
if((x==0 && y==0 && z==0) || angle==0)
|
||||
return; // nothing to do
|
||||
// normalize x y z
|
||||
GLfloat l = 1.0f/sqrtf(x*x+y*y+z*z);
|
||||
x=x*l; y=y*l; z=z*l;
|
||||
// calculate sin/cos
|
||||
angle*=3.1415926535f/180.f;
|
||||
const GLfloat s=sinf(angle);
|
||||
const GLfloat c=cosf(angle);
|
||||
const GLfloat c1 = 1-c;
|
||||
//build the matrix
|
||||
tmp[0+0] = x*x*c1+c; tmp[0+4] = x*y*c1-z*s; tmp[0+8] = x*z*c1+y*s;
|
||||
tmp[1+0] = y*x*c1+z*s; tmp[1+4] = y*y*c1+c; tmp[1+8] = y*z*c1-x*s;
|
||||
tmp[2+0] = x*z*c1-y*s; tmp[2+4] = y*z*c1+x*s; tmp[2+8] = z*z*c1+c;
|
||||
|
||||
tmp[3+12] = 1.0f;
|
||||
// done...
|
||||
gl4es_glMultMatrixf(tmp);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal) {
|
||||
DBG(printf("glOrthof(%f, %f, %f, %f, %f, %f), list=%p\n", left, right, top, bottom, nearVal, farVal, glstate->list.active);)
|
||||
GLfloat tmp[16];
|
||||
memset(tmp, 0, 16*sizeof(GLfloat));
|
||||
|
||||
tmp[0+0] = 2.0f/(right-left); tmp[0+12] = -(right+left)/(right-left);
|
||||
tmp[1+4] = 2.0f/(top-bottom); tmp[1+12] = -(top+bottom)/(top-bottom);
|
||||
tmp[2+8] =-2.0f/(farVal-nearVal); tmp[2+12] = -(farVal+nearVal)/(farVal-nearVal);
|
||||
tmp[3+12] = 1.0f;
|
||||
|
||||
gl4es_glMultMatrixf(tmp);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal) {
|
||||
DBG(printf("glFrustumf(%f, %f, %f, %f, %f, %f) list=%p\n", left, right, top, bottom, nearVal, farVal, glstate->list.active);)
|
||||
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[3+8] = -1.0f;
|
||||
|
||||
gl4es_glMultMatrixf(tmp);
|
||||
}
|
||||
|
||||
AliasExport(void,glMatrixMode,,(GLenum mode));
|
||||
AliasExport_V(void,glPushMatrix);
|
||||
AliasExport_V(void,glPopMatrix);
|
||||
AliasExport(void,glLoadMatrixf,,(const GLfloat * m));
|
||||
AliasExport(void,glMultMatrixf,,(const GLfloat * m));
|
||||
AliasExport_V(void,glLoadIdentity);
|
||||
AliasExport(void,glTranslatef,,(GLfloat x, GLfloat y, GLfloat z));
|
||||
AliasExport(void,glScalef,,(GLfloat x, GLfloat y, GLfloat z));
|
||||
AliasExport(void,glRotatef,,(GLfloat angle, GLfloat x, GLfloat y, GLfloat z));
|
||||
AliasExport(void,glOrthof,,(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal));
|
||||
AliasExport(void,glFrustumf,,(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal));
|
||||
@@ -0,0 +1,59 @@
|
||||
#ifndef _GL4ES_MATRIX_H_
|
||||
#define _GL4ES_MATRIX_H_
|
||||
|
||||
#include "gl4es.h"
|
||||
#include "gles.h"
|
||||
#include "glstate.h"
|
||||
#include "list.h"
|
||||
#include "matvec.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glMatrixMode(GLenum mode);
|
||||
void APIENTRY_GL4ES gl4es_glPushMatrix(void);
|
||||
void APIENTRY_GL4ES gl4es_glPopMatrix(void);
|
||||
void APIENTRY_GL4ES gl4es_glLoadMatrixf(const GLfloat * m);
|
||||
void APIENTRY_GL4ES gl4es_glMultMatrixf(const GLfloat * m);
|
||||
void APIENTRY_GL4ES gl4es_glLoadIdentity(void);
|
||||
void APIENTRY_GL4ES gl4es_glTranslatef(GLfloat x, GLfloat y, GLfloat z);
|
||||
void APIENTRY_GL4ES gl4es_glScalef(GLfloat x, GLfloat y, GLfloat z);
|
||||
void APIENTRY_GL4ES gl4es_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
||||
void APIENTRY_GL4ES gl4es_glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearVal, GLfloat farVal);
|
||||
void APIENTRY_GL4ES 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;
|
||||
}
|
||||
|
||||
static inline GLfloat* getMVMat() {
|
||||
return glstate->modelview_matrix->stack+glstate->modelview_matrix->top*16;
|
||||
}
|
||||
|
||||
static inline GLfloat* getInvMVMat() {
|
||||
if(glstate->inv_mv_matrix_dirty) {
|
||||
matrix_inverse(glstate->modelview_matrix->stack+glstate->modelview_matrix->top*16, glstate->inv_mv_matrix);
|
||||
glstate->inv_mv_matrix_dirty = 0;
|
||||
}
|
||||
return glstate->inv_mv_matrix;
|
||||
}
|
||||
static inline GLfloat* getNormalMat() {
|
||||
if(glstate->normal_matrix_dirty) {
|
||||
matrix_inverse3_transpose(glstate->modelview_matrix->stack+glstate->modelview_matrix->top*16, glstate->normal_matrix);
|
||||
glstate->normal_matrix_dirty = 0;
|
||||
}
|
||||
return glstate->normal_matrix;
|
||||
}
|
||||
|
||||
static inline GLfloat* getPMat() {
|
||||
return glstate->projection_matrix->stack+glstate->projection_matrix->top*16;
|
||||
}
|
||||
|
||||
static inline GLfloat* getMVPMat()
|
||||
{
|
||||
if(glstate->mvp_matrix_dirty) {
|
||||
matrix_mul(getPMat(), getMVMat(), glstate->mvp_matrix);
|
||||
glstate->mvp_matrix_dirty = 0;
|
||||
}
|
||||
return glstate->mvp_matrix;
|
||||
}
|
||||
|
||||
|
||||
#endif // _GL4ES_MATRIX_H_
|
||||
@@ -0,0 +1,353 @@
|
||||
#include "matvec.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
float FASTMATH dot(const float *a, const float *b) {
|
||||
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
|
||||
}
|
||||
|
||||
float FASTMATH dot4(const float *a, const float *b) {
|
||||
#if defined(__ARM_NEON__) && !defined(__APPLE__)
|
||||
register float ret;
|
||||
asm volatile (
|
||||
"vld1.f32 {d0-d1}, [%1] \n" //q0 = a(0..3)
|
||||
"vld1.f32 {d2-d3}, [%2] \n" //q1 = b(0..3)
|
||||
"vmul.f32 q0, q0, q1 \n" //q0 = a(0)*b(0),a(1)*b(1),a(2)*b(2),a(3)*b(3)
|
||||
"vadd.f32 d0, d0, d1 \n" //d0 = a(0)*b(0)+a(2)*b(2),a(1)*b(1)+a(3)*b(3)
|
||||
"vpadd.f32 d0,d0 \n" //d0 = a(0)*b(0)+a(2)*b(2)+a(1)*b(1)+a(3)*b(3),a(0)*b(0)+a(2)*b(2)+a(1)*b(1)+a(3)*b(3)
|
||||
"vmov.f32 %0, s0 \n"
|
||||
:"=w"(ret): "r"(a), "r"(b)
|
||||
: "q0", "q1"
|
||||
);
|
||||
return ret;
|
||||
#else
|
||||
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
void cross3(const float *a, const float *b, float* c) {
|
||||
//TODO Neonize? Cross product doesn't seems NEON friendly, and this is not much used.
|
||||
c[0] = a[1]*b[2] - a[2]*b[1];
|
||||
c[1] = a[3]*b[0] - a[0]*b[3];
|
||||
c[2] = a[0]*b[1] - a[1]*b[0];
|
||||
}
|
||||
|
||||
void matrix_vector(const float *a, const float *b, float *c) {
|
||||
#if defined(__ARM_NEON__) && !defined(__APPLE__)
|
||||
const float* a1 = a+8;
|
||||
asm volatile (
|
||||
"vld4.f32 {d0,d2,d4,d6}, [%1] \n"
|
||||
"vld4.f32 {d1,d3,d5,d7}, [%2] \n" // q0-q3 = a(0,4,8,12/1,5,9,13/2,6,10,14/3,7,11,15)
|
||||
"vld1.f32 {q4}, [%3] \n" // q4 = b
|
||||
"vmul.f32 q0, q0, d8[0] \n" // q0 = a(0,4,8,12)*b[0]
|
||||
"vmla.f32 q0, q1, d8[1] \n" // q0 = q0 + a(1,5,9,13)*b[1]
|
||||
"vmla.f32 q0, q2, d9[0] \n" // q0 = q0 + a(2,6,10,14)*b[2]
|
||||
"vmla.f32 q0, q3, d9[1] \n" // q0 = q0 + a(3,7,11,15)*b[3]
|
||||
"vst1.f32 {q0}, [%0] \n"
|
||||
::"r"(c), "r"(a), "r"(a1), "r"(b)
|
||||
: "q0", "q1", "q2", "q3", "q4", "memory"
|
||||
);
|
||||
#else
|
||||
c[0] = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
|
||||
c[1] = a[4] * b[0] + a[5] * b[1] + a[6] * b[2] + a[7] * b[3];
|
||||
c[2] = a[8] * b[0] + a[9] * b[1] + a[10] * b[2] + a[11] * b[3];
|
||||
c[3] = a[12] * b[0] + a[13] * b[1] + a[14] * b[2] + a[15] * b[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
void vector_matrix(const float *a, const float *b, float *c) {
|
||||
#if defined(__ARM_NEON__) && !defined(__APPLE__)
|
||||
const float* b2=b+4;
|
||||
const float* b3=b+8;
|
||||
const float* b4=b+12;
|
||||
asm volatile (
|
||||
"vld1.f32 {q0}, [%1] \n" // %q0 = a(0..3)
|
||||
"vld1.f32 {q1}, [%2] \n" // %q1 = b(0..3)
|
||||
"vmul.f32 q1, q1, d0[0] \n" // %q1 = b(0..3)*a[0]
|
||||
"vld1.f32 {q2}, [%3] \n" // %q2 = b(4..7)
|
||||
"vmla.f32 q1, q2, d0[1] \n" // %q1 = %q1 + b(4..7)*a[1]
|
||||
"vld1.f32 {q2}, [%4] \n" // %q2 = b(8..11)
|
||||
"vmla.f32 q1, q2, d1[0] \n" // %q1 = %q1 + b(8..11)*a[2]
|
||||
"vld1.f32 {q2}, [%5] \n" // %q2 = b(12..15)
|
||||
"vmla.f32 q1, q2, d1[1] \n" // %q1 = %q1 + b(12..15)*a[3]
|
||||
"vst1.f32 {q1}, [%0] \n"
|
||||
::"r"(c), "r"(a), "r"(b), "r"(b2), "r"(b3), "r"(b4)
|
||||
: "%2", "q0", "q1", "q2", "memory"
|
||||
);
|
||||
#else
|
||||
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
|
||||
}
|
||||
|
||||
void vector3_matrix(const float *a, const float *b, float *c) {
|
||||
#if defined(__ARM_NEON__) && !defined(__APPLE__)
|
||||
const float* b2=b+4;
|
||||
const float* b3=b+8;
|
||||
const float* b4=b+12;
|
||||
asm volatile (
|
||||
//"vld1.f32 {q0}, [%1] \n" // %q0 = a(0..2)
|
||||
"vld1.32 {d0}, [%1] \n"
|
||||
"flds s2, [%1, #8] \n"
|
||||
"vsub.f32 s3, s3, s3 \n"
|
||||
"vld1.f32 {q1}, [%2] \n" // %q1 = b(0..3)
|
||||
"vmul.f32 q1, q1, d0[0] \n" // %q1 = b(0..3)*a[0]
|
||||
"vld1.f32 {q2}, [%3] \n" // %q2 = b(4..7)
|
||||
"vmla.f32 q1, q2, d0[1] \n" // %q1 = %q1 + b(4..7)*a[1]
|
||||
"vld1.f32 {q2}, [%4] \n" // %q2 = b(8..11)
|
||||
"vmla.f32 q1, q2, d1[0] \n" // %q1 = %q1 + b(8..11)*a[2]
|
||||
"vld1.f32 {q2}, [%5] \n" // %q2 = b(12..15)
|
||||
"vadd.f32 q1, q1, q2 \n" // %q1 = %q1 + b(12..15)
|
||||
"vst1.f32 {q1}, [%0] \n"
|
||||
::"r"(c), "r"(a), "r"(b), "r"(b2), "r"(b3), "r"(b4)
|
||||
: "q0", "q1", "q2", "memory"
|
||||
);
|
||||
#else
|
||||
c[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + b[12];
|
||||
c[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + b[13];
|
||||
c[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + b[14];
|
||||
c[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + b[15];
|
||||
#endif
|
||||
}
|
||||
|
||||
void vector3_matrix4(const float *a, const float *b, float *c) {
|
||||
c[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8];
|
||||
c[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9];
|
||||
c[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10];
|
||||
}
|
||||
|
||||
void vector3_matrix3(const float *a, const float *b, float *c) {
|
||||
c[0] = a[0] * b[0] + a[1] * b[3] + a[2] * b[6];
|
||||
c[1] = a[0] * b[1] + a[1] * b[4] + a[2] * b[7];
|
||||
c[2] = a[0] * b[2] + a[1] * b[5] + a[2] * b[8];
|
||||
}
|
||||
|
||||
void vector_normalize(float *a) {
|
||||
#if defined(__ARM_NEON__) && !defined(__APPLE__)
|
||||
asm volatile (
|
||||
"vld1.32 {d4}, [%0] \n\t" //d4={x0,y0}
|
||||
"flds s10, [%0, #8] \n\t" //d5[0]={z0}
|
||||
"vsub.f32 s11, s11, s11 \n\t"
|
||||
|
||||
"vmul.f32 d0, d4, d4 \n\t" //d0= d4*d4
|
||||
"vpadd.f32 d0, d0 \n\t" //d0 = d[0] + d[1]
|
||||
"vmla.f32 d0, d5, d5 \n\t" //d0 = d0 + d5*d5
|
||||
|
||||
"vmov.f32 d1, d0 \n\t" //d1 = d0
|
||||
"vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0)
|
||||
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
|
||||
"vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2
|
||||
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3
|
||||
/* "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
|
||||
"vrsqrts.f32 d3, d2, d0 \n\t" //d4 = (3 - d0 * d3) / 2
|
||||
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4 */ // 1 iteration should be enough
|
||||
|
||||
"vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4
|
||||
"vst1.32 {d4}, [%0] \n\t" //
|
||||
"fsts s10, [%0, #8] \n\t" //
|
||||
|
||||
:"+&r"(a):
|
||||
: "d0", "d1", "d2", "d3", "d4", "d5", "memory"
|
||||
);
|
||||
#else
|
||||
float det=1.0f/sqrtf(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
|
||||
a[0]*=det;
|
||||
a[1]*=det;
|
||||
a[2]*=det;
|
||||
#endif
|
||||
}
|
||||
|
||||
void vector4_normalize(float *a) {
|
||||
#if defined(__ARM_NEON__) && !defined(__APPLE__)
|
||||
asm volatile (
|
||||
"vld1.32 {q2}, [%0] \n\t" //q2={x0,y0,z0,00}
|
||||
|
||||
"vmul.f32 d0, d4, d4 \n\t" //d0= d4*d4
|
||||
"vpadd.f32 d0, d0 \n\t" //d0 = d[0] + d[1]
|
||||
"vmla.f32 d0, d5, d5 \n\t" //d0 = d0 + d5*d5
|
||||
|
||||
"vmov.f32 d1, d0 \n\t" //d1 = d0
|
||||
"vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0)
|
||||
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
|
||||
"vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2
|
||||
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3
|
||||
/* "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
|
||||
"vrsqrts.f32 d3, d2, d0 \n\t" //d4 = (3 - d0 * d3) / 2
|
||||
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4 */ // 1 iteration should be enough
|
||||
|
||||
"vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4
|
||||
"vst1.32 {q2}, [%0] \n\t" //
|
||||
|
||||
:"+&r"(a):
|
||||
: "d0", "d1", "d2", "d3", "d4", "d5", "memory"
|
||||
);
|
||||
#else
|
||||
float det=1.0f/sqrtf(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
|
||||
a[0]*=det;
|
||||
a[1]*=det;
|
||||
a[2]*=det;
|
||||
// a[3] is ignored and left as 0.0f
|
||||
#endif
|
||||
}
|
||||
|
||||
void FASTMATH matrix_transpose(const float *a, float *b) {
|
||||
// column major -> row major
|
||||
// a(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) -> b(0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15)
|
||||
#if defined(__ARM_NEON__) && !defined(__APPLE__)
|
||||
const float* a1 = a+8;
|
||||
float* b1=b+8;
|
||||
asm volatile (
|
||||
"vld4.f32 {d0,d2,d4,d6}, [%1] \n"
|
||||
"vld4.f32 {d1,d3,d5,d7}, [%2] \n" // %q0-%q3 = a(0,4,8,12/1,5,9,13/2,6,10,14/3,7,11,15)
|
||||
"vst1.f32 {d0-d3}, [%0] \n"
|
||||
"vst1.f32 {d4-d7}, [%3] \n"
|
||||
::"r"(b), "r"(a), "r"(a1), "r"(b1)
|
||||
: "q0", "q1", "q2", "q3", "memory"
|
||||
);
|
||||
#else
|
||||
for (int i=0; i<4; i++)
|
||||
for (int j=0; j<4; j++)
|
||||
b[i*4+j]=a[i+j*4];
|
||||
#endif
|
||||
}
|
||||
|
||||
void matrix_inverse(const float *m, float *r) {
|
||||
|
||||
r[0] = m[5]*m[10]*m[15] - m[5]*m[14]*m[11] - m[6]*m[9]*m[15] + m[6]*m[13]*m[11] + m[7]*m[9]*m[14] - m[7]*m[13]*m[10];
|
||||
r[1] = -m[1]*m[10]*m[15] + m[1]*m[14]*m[11] + m[2]*m[9]*m[15] - m[2]*m[13]*m[11] - m[3]*m[9]*m[14] + m[3]*m[13]*m[10];
|
||||
r[2] = m[1]*m[6]*m[15] - m[1]*m[14]*m[7] - m[2]*m[5]*m[15] + m[2]*m[13]*m[7] + m[3]*m[5]*m[14] - m[3]*m[13]*m[6];
|
||||
r[3] = -m[1]*m[6]*m[11] + m[1]*m[10]*m[7] + m[2]*m[5]*m[11] - m[2]*m[9]*m[7] - m[3]*m[5]*m[10] + m[3]*m[9]*m[6];
|
||||
|
||||
r[4] = -m[4]*m[10]*m[15] + m[4]*m[14]*m[11] + m[6]*m[8]*m[15] - m[6]*m[12]*m[11] - m[7]*m[8]*m[14] + m[7]*m[12]*m[10];
|
||||
r[5] = m[0]*m[10]*m[15] - m[0]*m[14]*m[11] - m[2]*m[8]*m[15] + m[2]*m[12]*m[11] + m[3]*m[8]*m[14] - m[3]*m[12]*m[10];
|
||||
r[6] = -m[0]*m[6]*m[15] + m[0]*m[14]*m[7] + m[2]*m[4]*m[15] - m[2]*m[12]*m[7] - m[3]*m[4]*m[14] + m[3]*m[12]*m[6];
|
||||
r[7] = m[0]*m[6]*m[11] - m[0]*m[10]*m[7] - m[2]*m[4]*m[11] + m[2]*m[8]*m[7] + m[3]*m[4]*m[10] - m[3]*m[8]*m[6];
|
||||
|
||||
r[8] = m[4]*m[9]*m[15] - m[4]*m[13]*m[11] - m[5]*m[8]*m[15] + m[5]*m[12]*m[11] + m[7]*m[8]*m[13] - m[7]*m[12]*m[9];
|
||||
r[9] = -m[0]*m[9]*m[15] + m[0]*m[13]*m[11] + m[1]*m[8]*m[15] - m[1]*m[12]*m[11] - m[3]*m[8]*m[13] + m[3]*m[12]*m[9];
|
||||
r[10] = m[0]*m[5]*m[15] - m[0]*m[13]*m[7] - m[1]*m[4]*m[15] + m[1]*m[12]*m[7] + m[3]*m[4]*m[13] - m[3]*m[12]*m[5];
|
||||
r[11] = -m[0]*m[5]*m[11] + m[0]*m[9]*m[7] + m[1]*m[4]*m[11] - m[1]*m[8]*m[7] - m[3]*m[4]*m[9] + m[3]*m[8]*m[5];
|
||||
|
||||
r[12] = -m[4]*m[9]*m[14] + m[4]*m[13]*m[10] + m[5]*m[8]*m[14] - m[5]*m[12]*m[10] - m[6]*m[8]*m[13] + m[6]*m[12]*m[9];
|
||||
r[13] = m[0]*m[9]*m[14] - m[0]*m[13]*m[10] - m[1]*m[8]*m[14] + m[1]*m[12]*m[10] + m[2]*m[8]*m[13] - m[2]*m[12]*m[9];
|
||||
r[14] = -m[0]*m[5]*m[14] + m[0]*m[13]*m[6] + m[1]*m[4]*m[14] - m[1]*m[12]*m[6] - m[2]*m[4]*m[13] + m[2]*m[12]*m[5];
|
||||
r[15] = m[0]*m[5]*m[10] - m[0]*m[9]*m[6] - m[1]*m[4]*m[10] + m[1]*m[8]*m[6] + m[2]*m[4]*m[9] - m[2]*m[8]*m[5];
|
||||
|
||||
float det = 1.0f/(m[0]*r[0] + m[1]*r[4] + m[2]*r[8] + m[3]*r[12]);
|
||||
for (int i = 0; i < 16; i++) r[i] *= det;
|
||||
}
|
||||
|
||||
void matrix_inverse3_transpose(const float *m, float *r) {
|
||||
|
||||
r[0] = m[4+1]*m[8+2] - m[4+2]*m[8+1];
|
||||
r[1] = m[4+2]*m[8+0] - m[4+0]*m[8+2];
|
||||
r[2] = m[4+0]*m[8+1] - m[4+1]*m[8+0];
|
||||
|
||||
r[3] = m[0+2]*m[8+1] - m[0+1]*m[8+2];
|
||||
r[4] = m[0+0]*m[8+2] - m[0+2]*m[8+0];
|
||||
r[5] = m[0+1]*m[8+0] - m[0+0]*m[8+1];
|
||||
|
||||
r[6] = m[0+1]*m[4+2] - m[0+2]*m[4+1];
|
||||
r[7] = m[0+2]*m[4+0] - m[0+0]*m[4+2];
|
||||
r[8] = m[0+0]*m[4+1] - m[0+1]*m[4+0];
|
||||
|
||||
float det = 1.0f/(m[0]*r[0] + m[4+0]*r[3] + m[8+0]*r[6]);
|
||||
for (int i = 0; i < 9; i++) r[i] *= det;
|
||||
}
|
||||
|
||||
void matrix_mul(const float *a, const float *b, float *c) {
|
||||
#if defined(__ARM_NEON__) && !defined(__APPLE__)
|
||||
const float* a1 = a+8;
|
||||
const float* b1=b+8;
|
||||
float* c1=c+8;
|
||||
asm volatile (
|
||||
"vld1.32 {d16-d19}, [%2] \n"
|
||||
"vld1.32 {d20-d23}, [%3] \n"
|
||||
"vld1.32 {d0-d3}, [%4] \n"
|
||||
"vld1.32 {d4-d7}, [%5] \n"
|
||||
"vmul.f32 q12, q8, d0[0] \n"
|
||||
"vmul.f32 q13, q8, d2[0] \n"
|
||||
"vmul.f32 q14, q8, d4[0] \n"
|
||||
"vmul.f32 q15, q8, d6[0] \n"
|
||||
"vmla.f32 q12, q9, d0[1] \n"
|
||||
"vmla.f32 q13, q9, d2[1] \n"
|
||||
"vmla.f32 q14, q9, d4[1] \n"
|
||||
"vmla.f32 q15, q9, d6[1] \n"
|
||||
"vmla.f32 q12, q10, d1[0] \n"
|
||||
"vmla.f32 q13, q10, d3[0] \n"
|
||||
"vmla.f32 q14, q10, d5[0] \n"
|
||||
"vmla.f32 q15, q10, d7[0] \n"
|
||||
"vmla.f32 q12, q11, d1[1] \n"
|
||||
"vmla.f32 q13, q11, d3[1] \n"
|
||||
"vmla.f32 q14, q11, d5[1] \n"
|
||||
"vmla.f32 q15, q11, d7[1] \n"
|
||||
"vst1.32 {d24-d27}, [%0] \n"
|
||||
"vst1.32 {d28-d31}, [%1] \n"
|
||||
::"r"(c), "r"(c1), "r"(a), "r"(a1), "r"(b), "r"(b1)
|
||||
: "q0", "q1", "q2", "q3",
|
||||
"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory"
|
||||
);
|
||||
#else
|
||||
float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
|
||||
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
|
||||
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
|
||||
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
|
||||
|
||||
float b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
|
||||
c[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
||||
c[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
||||
c[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
||||
c[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
||||
|
||||
b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
|
||||
c[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
||||
c[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
||||
c[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
||||
c[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
||||
|
||||
b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
|
||||
c[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
||||
c[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
||||
c[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
||||
c[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
||||
|
||||
b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
|
||||
c[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
||||
c[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
||||
c[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
||||
c[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
||||
#endif
|
||||
}
|
||||
|
||||
void vector4_mult(const float *a, const float *b, float *c) {
|
||||
//TODO: NEON version of this
|
||||
for (int i=0; i<4; i++)
|
||||
c[i] = a[i]*b[i];
|
||||
}
|
||||
|
||||
void vector4_add(const float *a, const float *b, float *c) {
|
||||
//TODO: NEON version of this
|
||||
for (int i=0; i<4; i++)
|
||||
c[i] = a[i]+b[i];
|
||||
}
|
||||
|
||||
void vector4_sub(const float *a, const float *b, float *c) {
|
||||
//TODO: NEON version of this
|
||||
for (int i=0; i<4; i++)
|
||||
c[i] = a[i]-b[i];
|
||||
}
|
||||
|
||||
void set_identity(float* mat) {
|
||||
memset(mat, 0, 16*sizeof(float));
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef _GL4ES_MATVEC_H_
|
||||
#define _GL4ES_MATVEC_H_
|
||||
|
||||
#include <math.h>
|
||||
#include "attributes.h"
|
||||
|
||||
float dot(const float *a, const float *b) FASTMATH;
|
||||
float dot4(const float *a, const float *b) FASTMATH;
|
||||
void cross3(const float *a, const float *b, float* c) FASTMATH;
|
||||
void matrix_vector(const float *a, const float *b, float *c);
|
||||
void vector_matrix(const float *a, const float *b, float *c);
|
||||
void vector3_matrix(const float *a, const float *b, float *c);
|
||||
void vector3_matrix3(const float *a, const float *b, float *c);
|
||||
void vector3_matrix4(const float *a, const float *b, float *c);
|
||||
void vector_normalize(float *a);
|
||||
void vector4_normalize(float *a);
|
||||
void vector4_mult(const float *a, const float *b, float *c);
|
||||
void vector4_add(const float *a, const float *b, float *c);
|
||||
void matrix_transpose(const float *a, float *b);
|
||||
void matrix_inverse(const float *m, float *r);
|
||||
void matrix_inverse3_transpose(const float *m, float *r); // upper3x3 of matrix4 -> inverse -> transposed mat3
|
||||
void matrix_mul(const float *a, const float *b, float *c);
|
||||
void set_identity(float* mat);
|
||||
int is_identity(const float* mat);
|
||||
|
||||
#endif // _GL4ES_MATVEC_H_
|
||||
@@ -0,0 +1,855 @@
|
||||
#include "debug.h"
|
||||
#include "fpe.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "loader.h"
|
||||
#include "oldprogram.h"
|
||||
#include "shaderconv.h"
|
||||
#include "vertexattrib.h"
|
||||
#include "arbconverter.h"
|
||||
#include "debug.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DBG(a) a
|
||||
#else
|
||||
#define DBG(a)
|
||||
#endif
|
||||
|
||||
// Implement "Old program" handling: so ARB_vertex_program and ARB_fragment_program extensions
|
||||
// the core of this is a conversion between ARB ASM-like syntax to GLSL, then using regular functions
|
||||
// Note that a program in this context is in fact a shader in ARB_vertex_shader (and GLSL) extension
|
||||
|
||||
KHASH_MAP_INIT_INT(oldprograms, oldprogram_t *);
|
||||
|
||||
void freeOldProgram(oldprogram_t* old)
|
||||
{
|
||||
if(!old)
|
||||
return;
|
||||
if(old->string)
|
||||
free(old->string);
|
||||
if(old->shader)
|
||||
gl4es_glDeleteShader(old->shader->id);
|
||||
if(old->prog_local_params)
|
||||
free(old->prog_local_params);
|
||||
free(old);
|
||||
}
|
||||
|
||||
void InitOldProgramMap(glstate_t* glstate)
|
||||
{
|
||||
if(glstate->glsl) {
|
||||
glstate->glsl->oldprograms = kh_init(oldprograms);
|
||||
glstate->glsl->error_msg = NULL;
|
||||
glstate->glsl->error_ptr = -1;
|
||||
}
|
||||
}
|
||||
void FreeOldProgramMap(glstate_t* glstate)
|
||||
{
|
||||
if(!glstate->glsl)
|
||||
return;
|
||||
if(glstate->glsl->error_msg)
|
||||
free(glstate->glsl->error_msg);
|
||||
oldprogram_t* old;
|
||||
kh_foreach_value(glstate->glsl->oldprograms, old, freeOldProgram(old));
|
||||
kh_destroy(oldprograms, glstate->glsl->oldprograms);
|
||||
}
|
||||
|
||||
GLuint getUniqueProgramID(GLuint last) {
|
||||
// avoid recycling prog id (that may messup FPE Cache)
|
||||
static GLuint upper = 0;
|
||||
if(last>upper) last = upper;
|
||||
khint_t k;
|
||||
do {
|
||||
++last;
|
||||
k = kh_get(oldprograms, glstate->glsl->oldprograms, last);
|
||||
} while(k!=kh_end(glstate->glsl->oldprograms));
|
||||
upper = last;
|
||||
return last;
|
||||
}
|
||||
|
||||
oldprogram_t* getOldProgram(GLuint program)
|
||||
{
|
||||
kh_oldprograms_t * oldprograms = glstate->glsl->oldprograms;
|
||||
if(program) {
|
||||
khint_t k = kh_get(oldprograms, oldprograms, program);
|
||||
if(k != kh_end(oldprograms))
|
||||
return kh_value(oldprograms, k);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Vertex function are also defined with ARB_vertex_shader
|
||||
/*
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib1sARB(GLuint index, GLshort x)
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib1fARB(GLuint index, GLfloat x);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib1dARB(GLuint index, GLdouble x);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib2sARB(GLuint index, GLshort x, GLshort y);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib1svARB(GLuint index, const GLshort *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib1fvARB(GLuint index, const GLfloat *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib1dvARB(GLuint index, const GLdouble *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib2svARB(GLuint index, const GLshort *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib2fvARB(GLuint index, const GLfloat *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib2dvARB(GLuint index, const GLdouble *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib3svARB(GLuint index, const GLshort *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib3fvARB(GLuint index, const GLfloat *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib3dvARB(GLuint index, const GLdouble *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4bvARB(GLuint index, const GLbyte *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4svARB(GLuint index, const GLshort *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4ivARB(GLuint index, const GLint *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4ubvARB(GLuint index, const GLubyte *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4usvARB(GLuint index, const GLushort *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4uivARB(GLuint index, const GLuint *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4fvARB(GLuint index, const GLfloat *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4dvARB(GLuint index, const GLdouble *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4NbvARB(GLuint index, const GLbyte *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4NsvARB(GLuint index, const GLshort *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4NivARB(GLuint index, const GLint *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4NubvARB(GLuint index, const GLubyte *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4NusvARB(GLuint index, const GLushort *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttrib4NuivARB(GLuint index, const GLuint *v);
|
||||
void APIENTRY_GL4ES gl4es_glVertexAttribPointerARB(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
|
||||
void APIENTRY_GL4ES gl4es_glEnableVertexAttribArrayARB(GLuint index);
|
||||
void APIENTRY_GL4ES gl4es_glDisableVertexAttribArrayARB(GLuint index);
|
||||
*/
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid *string) {
|
||||
DBG(printf("glProgramStringARB(%s, %s, %d, %p), source is\n%s\n=======\n", PrintEnum(target), PrintEnum(format), len, string, (const char*)string);)
|
||||
oldprogram_t* old = NULL;
|
||||
int vertex;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
old = glstate->glsl->vtx_prog;
|
||||
vertex = 1;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
old = glstate->glsl->frg_prog;
|
||||
vertex = 0;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(format!=GL_PROGRAM_FORMAT_ASCII_ARB) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(old->string)
|
||||
free(old->string);
|
||||
// grab the new program
|
||||
old->string = calloc(1, len + 1);
|
||||
memcpy(old->string, string, len);
|
||||
// check if a shader is actually attached
|
||||
if(!old->shader) {
|
||||
DBG(printf("Error, no shader attached but glProgramStringARB(...) called\n");)
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
// Convert to GLSL
|
||||
const GLchar * p[1] = {0};
|
||||
p[0] = gl4es_convertARB(old->string, vertex, &glstate->glsl->error_msg, &glstate->glsl->error_ptr);
|
||||
if((!p[0]) || (glstate->glsl->error_ptr!=-1)) {
|
||||
DBG(printf("Error with ARB->GLSL conversion\nsource is:\n%s\n======\n", old->shader->source);)
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
gl4es_glShaderSource(old->shader->id, 1, p , NULL);
|
||||
DBG(printf("converted source is:\n%s\n======\n", old->shader->source?old->shader->source:"**error**");)
|
||||
if (!old->shader->source) {
|
||||
DBG(printf("Error with ARB->GLSL conversion\n");)
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
if (glstate->glsl->error_msg) free(glstate->glsl->error_msg);
|
||||
glstate->glsl->error_msg = strdup("Error with ARB->GLSL conversion");
|
||||
glstate->glsl->error_ptr = 0;
|
||||
return;
|
||||
}
|
||||
if (!old->shader->converted) {
|
||||
DBG(printf("Error with GLSL->GLSL:ES conversion\n");)
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
if (glstate->glsl->error_msg) free(glstate->glsl->error_msg);
|
||||
glstate->glsl->error_msg = strdup("Error with GLSL->GLSL:ES conversion");
|
||||
glstate->glsl->error_ptr = 0;
|
||||
return;
|
||||
}
|
||||
gl4es_glCompileShader(old->shader->id);
|
||||
GLint res = 0;
|
||||
gl4es_glGetShaderiv(old->shader->id, GL_COMPILE_STATUS, &res);
|
||||
if(res!=GL_TRUE) {
|
||||
DBG(printf("Error with Compile shader\n");)
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
if (glstate->glsl->error_msg) free(glstate->glsl->error_msg);
|
||||
glstate->glsl->error_msg = strdup("Error with Compile shader");
|
||||
glstate->glsl->error_ptr = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBindProgramARB(GLenum target, GLuint program) {
|
||||
DBG(printf("glBindProgramARB(%s, %d)\n", PrintEnum(target), program);)
|
||||
khint_t k;
|
||||
oldprogram_t* old = NULL;
|
||||
kh_oldprograms_t * oldprograms = glstate->glsl->oldprograms;
|
||||
if(program) {
|
||||
k = kh_get(oldprograms, oldprograms, program);
|
||||
if(k == kh_end(oldprograms)) {
|
||||
// if program as not be generated it's fine, create a new one on-the-fly
|
||||
int ret;
|
||||
k = kh_put(oldprograms, oldprograms, program, &ret);
|
||||
old = kh_value(oldprograms, k) =(oldprogram_t*)calloc(1, sizeof(oldprogram_t));
|
||||
old->id = program;
|
||||
} else {
|
||||
old = kh_value(oldprograms, k);
|
||||
if(old->type!=0 && old->type!=target) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
if(program) {
|
||||
noerrorShimNoPurge();
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->vertex_prg_id = program;
|
||||
glstate->glsl->vtx_prog = old;
|
||||
if(!old->type) {
|
||||
// create an empty shader
|
||||
old->type = target;
|
||||
GLuint shader = gl4es_glCreateShader(GL_VERTEX_SHADER);
|
||||
shader_t *glshader = NULL;
|
||||
khash_t(shaderlist) *shaders = glstate->glsl->shaders;
|
||||
k = kh_get(shaderlist, shaders, shader);
|
||||
glshader = kh_value(shaders, k);
|
||||
old->shader = glshader;
|
||||
// alloc memory for locals
|
||||
old->max_local_params = MAX_VTX_PROG_LOC_PARAMS;
|
||||
old->prog_local_params = (float*)calloc(MAX_VTX_PROG_LOC_PARAMS*4, sizeof(float));
|
||||
old->max_env_params = MAX_VTX_PROG_ENV_PARAMS;
|
||||
old->prog_env_params = glstate->glsl->vtx_env_params;
|
||||
old->max_loc = -1;
|
||||
old->max_env = -1;
|
||||
old->min_loc = MAX_VTX_PROG_LOC_PARAMS;
|
||||
old->min_env = MAX_VTX_PROG_ENV_PARAMS;
|
||||
}
|
||||
} else {
|
||||
noerrorShimNoPurge();
|
||||
glstate->glsl->vtx_prog = NULL;
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->vertex_prg_id = 0;
|
||||
}
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
if(program) {
|
||||
noerrorShimNoPurge();
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->fragment_prg_id = program;
|
||||
glstate->glsl->frg_prog = old;
|
||||
if(!old->type) {
|
||||
// create an empty shader
|
||||
old->type = target;
|
||||
GLuint shader = gl4es_glCreateShader(GL_FRAGMENT_SHADER);
|
||||
shader_t *glshader = NULL;
|
||||
khash_t(shaderlist) *shaders = glstate->glsl->shaders;
|
||||
k = kh_get(shaderlist, shaders, shader);
|
||||
glshader = kh_value(shaders, k);
|
||||
old->shader = glshader;
|
||||
// alloc memory for locals
|
||||
old->max_local_params = MAX_FRG_PROG_LOC_PARAMS;
|
||||
old->prog_local_params = (float*)calloc(MAX_FRG_PROG_LOC_PARAMS*4, sizeof(float));
|
||||
old->max_env_params = MAX_FRG_PROG_ENV_PARAMS;
|
||||
old->prog_env_params = glstate->glsl->frg_env_params;
|
||||
old->max_loc = -1;
|
||||
old->max_env = -1;
|
||||
old->min_loc = MAX_FRG_PROG_LOC_PARAMS;
|
||||
old->min_env = MAX_FRG_PROG_ENV_PARAMS;
|
||||
}
|
||||
} else {
|
||||
noerrorShimNoPurge();
|
||||
glstate->glsl->frg_prog = NULL;
|
||||
if(glstate->fpe_state)
|
||||
glstate->fpe_state->fragment_prg_id = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDeleteProgramsARB(GLsizei n, const GLuint *programs) {
|
||||
DBG(printf("glDeleteProgramsARB(%d, %p)\n", n, programs);)
|
||||
//TODO, unbind if binded?
|
||||
khint_t k;
|
||||
kh_oldprograms_t * oldprograms = glstate->glsl->oldprograms;
|
||||
for (int i=0; i<n; ++i) {
|
||||
GLuint id = programs[i];
|
||||
k = kh_get(oldprograms, oldprograms, id);
|
||||
if(k!=kh_end(oldprograms)) {
|
||||
freeOldProgram(kh_value(oldprograms, k));
|
||||
kh_del(oldprograms, oldprograms, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGenProgramsARB(GLsizei n, GLuint *programs) {
|
||||
DBG(printf("glGenProgramsARB(%d, %p)\n", n, programs);)
|
||||
GLuint last = 0;
|
||||
khint_t k;
|
||||
kh_oldprograms_t * oldprograms = glstate->glsl->oldprograms;
|
||||
for (int i=0; i<n; ++i) {
|
||||
programs[i] = last = getUniqueProgramID(last);
|
||||
int ret;
|
||||
k = kh_put(oldprograms, oldprograms, last, &ret);
|
||||
oldprogram_t *old = kh_value(oldprograms, k) =(oldprogram_t*)calloc(1, sizeof(oldprogram_t));
|
||||
old->id = last;
|
||||
}
|
||||
noerrorShimNoPurge();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {
|
||||
DBG(printf("glProgramEnvParameter4dARB(%s, %u, %f, %f, %f, %f)\n", PrintEnum(target), index, x, y, z, w);)
|
||||
float *f = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
if(index<MAX_VTX_PROG_ENV_PARAMS) {
|
||||
noerrorShimNoPurge();
|
||||
f = glstate->glsl->vtx_env_params+index*4;
|
||||
}
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
if(index<MAX_FRG_PROG_ENV_PARAMS) {
|
||||
noerrorShimNoPurge();
|
||||
f = glstate->glsl->frg_env_params+index*4;
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(f) {
|
||||
f[0] = x;
|
||||
f[1] = y;
|
||||
f[2] = z;
|
||||
f[3] = w;
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble *params) {
|
||||
DBG(printf("glProgramEnvParameter4dvARB(%s, %u, %p[%f/%f/%f/%f])\n", PrintEnum(target), index, params, params[0], params[1], params[2], params[3]);)
|
||||
float *f = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
if(index<MAX_VTX_PROG_ENV_PARAMS) {
|
||||
noerrorShimNoPurge();
|
||||
f = glstate->glsl->vtx_env_params+index*4;
|
||||
}
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
if(index<MAX_FRG_PROG_ENV_PARAMS) {
|
||||
noerrorShimNoPurge();
|
||||
f = glstate->glsl->frg_env_params+index*4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(f) {
|
||||
f[0] = params[0];
|
||||
f[1] = params[1];
|
||||
f[2] = params[2];
|
||||
f[3] = params[3];
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
|
||||
DBG(printf("glProgramEnvParameter4fARB(%s, %u, %f, %f, %f, %f)\n", PrintEnum(target), index, x, y, z, w);)
|
||||
float *f = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
if(index<MAX_VTX_PROG_ENV_PARAMS) {
|
||||
noerrorShimNoPurge();
|
||||
f = glstate->glsl->vtx_env_params+index*4;
|
||||
}
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
if(index<MAX_FRG_PROG_ENV_PARAMS) {
|
||||
noerrorShimNoPurge();
|
||||
f = glstate->glsl->frg_env_params+index*4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
}
|
||||
if(f) {
|
||||
f[0] = x;
|
||||
f[1] = y;
|
||||
f[2] = z;
|
||||
f[3] = w;
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat *params) {
|
||||
DBG(printf("glProgramEnvParameter4fvARB(%s, %u, %p[%f/%f/%f/%f])\n", PrintEnum(target), index, params, params[0], params[1], params[2], params[3]);)
|
||||
float *f = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
if(index<MAX_VTX_PROG_ENV_PARAMS) {
|
||||
f = glstate->glsl->vtx_env_params+index*4;
|
||||
}
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
if(index<MAX_FRG_PROG_ENV_PARAMS) {
|
||||
f = glstate->glsl->frg_env_params+index*4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
}
|
||||
if(f) {
|
||||
noerrorShimNoPurge();
|
||||
memcpy(f, params, 4*sizeof(float));
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glProgramLocalParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {
|
||||
DBG(printf("glProgramLocalParameter4dARB(%s, %u, %f, %f, %f, %f)\n", PrintEnum(target), index, x, y, z, w);)
|
||||
oldprogram_t *old = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
old = glstate->glsl->vtx_prog;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
old = glstate->glsl->frg_prog;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(!old) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
if(index<old->max_local_params) {
|
||||
noerrorShimNoPurge();
|
||||
float* f = old->prog_local_params+index*4;
|
||||
f[0] = x;
|
||||
f[1] = y;
|
||||
f[2] = z;
|
||||
f[3] = w;
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glProgramLocalParameter4dvARB(GLenum target, GLuint index, const GLdouble *params) {
|
||||
DBG(printf("glProgramLocalParameter4dvARB(%s, %u, %p[%f/%f/%f/%f])\n", PrintEnum(target), index, params, params[0], params[1], params[2], params[3]);)
|
||||
oldprogram_t *old = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
old = glstate->glsl->vtx_prog;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
old = glstate->glsl->frg_prog;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(!old) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
if(index<old->max_local_params) {
|
||||
noerrorShimNoPurge();
|
||||
float* f = old->prog_local_params+index*4;
|
||||
f[0] = params[0];
|
||||
f[1] = params[1];
|
||||
f[2] = params[2];
|
||||
f[3] = params[3];
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glProgramLocalParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
|
||||
DBG(printf("glProgramLocalParameter4fARB(%s, %u, %f, %f, %f, %f)\n", PrintEnum(target), index, x, y, z, w);)
|
||||
oldprogram_t *old = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
old = glstate->glsl->vtx_prog;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
old = glstate->glsl->frg_prog;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(!old) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
if(index<old->max_local_params) {
|
||||
noerrorShimNoPurge();
|
||||
float* f = old->prog_local_params+index*4;
|
||||
f[0] = x;
|
||||
f[1] = y;
|
||||
f[2] = z;
|
||||
f[3] = w;
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glProgramLocalParameter4fvARB(GLenum target, GLuint index, const GLfloat *params) {
|
||||
DBG(printf("glProgramLocalParameter4fvARB(%s, %u, %p[%f/%f/%f/%f])\n", PrintEnum(target), index, params, params[0], params[1], params[2], params[3]);)
|
||||
oldprogram_t *old = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
old = glstate->glsl->vtx_prog;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
old = glstate->glsl->frg_prog;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(!old) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
if(index<old->max_local_params) {
|
||||
noerrorShimNoPurge();
|
||||
memcpy(old->prog_local_params+index*4, params, 4*sizeof(float));
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramEnvParameterdvARB(GLenum target, GLuint index, GLdouble *params) {
|
||||
DBG(printf("glGetProgramEnvParameterdvARB(%s, %u, %p)\n", PrintEnum(target), index, params);)
|
||||
float * f = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
if(index<MAX_VTX_PROG_ENV_PARAMS) {
|
||||
noerrorShimNoPurge();
|
||||
f = glstate->glsl->vtx_env_params+index*4;
|
||||
}
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
if(index<MAX_FRG_PROG_ENV_PARAMS) {
|
||||
noerrorShimNoPurge();
|
||||
f = glstate->glsl->frg_env_params+index*4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(f) {
|
||||
params[0] = f[0];
|
||||
params[1] = f[1];
|
||||
params[2] = f[2];
|
||||
params[3] = f[3];
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramEnvParameterfvARB(GLenum target, GLuint index, GLfloat *params) {
|
||||
DBG(printf("glGetProgramEnvParameterfvARB(%s, %u, %p)\n", PrintEnum(target), index, params);)
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
if(index<MAX_VTX_PROG_ENV_PARAMS) {
|
||||
noerrorShimNoPurge();
|
||||
memcpy(params, glstate->glsl->vtx_env_params+index*4, 4*sizeof(float));
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
if(index<MAX_FRG_PROG_ENV_PARAMS) {
|
||||
noerrorShimNoPurge();
|
||||
memcpy(params, glstate->glsl->frg_env_params+index*4, 4*sizeof(float));
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramLocalParameterdvARB(GLenum target, GLuint index, GLdouble *params) {
|
||||
DBG(printf("glGetProgramLocalParameterdvARB(%s, %u, %p)\n", PrintEnum(target), index, params);)
|
||||
oldprogram_t *old = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
old = glstate->glsl->vtx_prog;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
old = glstate->glsl->frg_prog;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(!old) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
if(index<old->max_local_params) {
|
||||
noerrorShimNoPurge();
|
||||
float* f = old->prog_local_params+index*4;
|
||||
params[0] = f[0];
|
||||
params[1] = f[1];
|
||||
params[2] = f[2];
|
||||
params[3] = f[3];
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramLocalParameterfvARB(GLenum target, GLuint index, GLfloat *params) {
|
||||
DBG(printf("glGetProgramLocalParameterfvARB(%s, %u, %p)\n", PrintEnum(target), index, params);)
|
||||
oldprogram_t *old = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
old = glstate->glsl->vtx_prog;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
old = glstate->glsl->frg_prog;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(!old) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
if(index<old->max_local_params) {
|
||||
noerrorShimNoPurge();
|
||||
memcpy(params, old->prog_local_params+index*4, 4*sizeof(float));
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramivARB(GLenum target, GLenum pname, GLint *params) {
|
||||
DBG(printf("glGetProgramivARB(%s, %s, %p)\n", PrintEnum(target), PrintEnum(pname), params);)
|
||||
oldprogram_t* old = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
old = glstate->glsl->vtx_prog;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
old = glstate->glsl->frg_prog;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
switch(pname) {
|
||||
case GL_PROGRAM_LENGTH_ARB:
|
||||
if(old) {
|
||||
noerrorShimNoPurge();
|
||||
*params = old->string?(strlen(old->string)+1):0;
|
||||
} else
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
break;
|
||||
case GL_PROGRAM_FORMAT_ARB:
|
||||
if(old) {
|
||||
noerrorShimNoPurge();
|
||||
*params = GL_PROGRAM_FORMAT_ASCII_ARB;
|
||||
} else
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
break;
|
||||
case GL_PROGRAM_BINDING_ARB:
|
||||
if(old) {
|
||||
noerrorShimNoPurge();
|
||||
*params = old->id;
|
||||
} else
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
break;
|
||||
case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
|
||||
*params = (target==GL_VERTEX_PROGRAM_ARB)?MAX_VTX_PROG_LOC_PARAMS:MAX_FRG_PROG_LOC_PARAMS;
|
||||
break;
|
||||
case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
|
||||
*params = (target==GL_VERTEX_PROGRAM_ARB)?MAX_VTX_PROG_ENV_PARAMS:MAX_FRG_PROG_ENV_PARAMS;
|
||||
break;
|
||||
case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
|
||||
case GL_MAX_PROGRAM_ATTRIBS_ARB:
|
||||
*params = hardext.maxvattrib;
|
||||
break;
|
||||
// arbritrary settings...
|
||||
case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
|
||||
case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
|
||||
*params = 4096;
|
||||
break;
|
||||
case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
|
||||
case GL_MAX_PROGRAM_TEMPORARIES_ARB:
|
||||
*params = 64;
|
||||
break;
|
||||
case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
|
||||
case GL_MAX_PROGRAM_PARAMETERS_ARB:
|
||||
*params = 64;
|
||||
break;
|
||||
case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
|
||||
case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
|
||||
*params = 4;
|
||||
break;
|
||||
case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
|
||||
case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
|
||||
*params = 1024;
|
||||
break;
|
||||
case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
|
||||
case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
|
||||
*params = 32;
|
||||
break;
|
||||
case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
|
||||
case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
|
||||
*params = 8;
|
||||
break;
|
||||
/*
|
||||
// bounded program stats...
|
||||
case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
|
||||
case GL_PROGRAM_INSTRUCTIONS_ARB:
|
||||
case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
|
||||
case GL_PROGRAM_TEMPORARIES_ARB:
|
||||
case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
|
||||
case GL_PROGRAM_PARAMETERS_ARB:
|
||||
case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
|
||||
case GL_PROGRAM_ATTRIBS_ARB:
|
||||
case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
|
||||
case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
|
||||
case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
|
||||
case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
|
||||
case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
|
||||
case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
|
||||
case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
|
||||
case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
|
||||
*/
|
||||
case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
|
||||
*params = 1; // always return OK for now
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) {
|
||||
DBG(printf("glGetProgramStringARB(%s, %u, %p)\n", PrintEnum(target), pname, string);)
|
||||
oldprogram_t* old = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
old = glstate->glsl->vtx_prog;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
old = glstate->glsl->frg_prog;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(pname!=GL_PROGRAM_STRING_ARB) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(!old) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
if(old->string)
|
||||
strcpy(string, old->string);
|
||||
noerrorShimNoPurge();
|
||||
}
|
||||
|
||||
/*
|
||||
// same as GLSL version
|
||||
void APIENTRY_GL4ES gl4es_glGetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetVertexAttribivARB(GLuint index, GLenum pname, GLint *params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer);
|
||||
*/
|
||||
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsProgramARB(GLuint program) {
|
||||
DBG(printf("glIsProgramARB(%u)\n", program);)
|
||||
khint_t k = kh_get(oldprograms, glstate->glsl->oldprograms, program);
|
||||
return (k==kh_end(glstate->glsl->oldprograms))?GL_FALSE:GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat *params)
|
||||
{
|
||||
DBG(printf("glProgramEnvParameters4fvEXT(%s, %u, %i, %p)\n", PrintEnum(target), index, count, params);)
|
||||
float *f = NULL;
|
||||
int nmax = 0;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
f = glstate->glsl->vtx_env_params+index*4;
|
||||
nmax = MAX_VTX_PROG_ENV_PARAMS;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
f = glstate->glsl->frg_env_params+index*4;
|
||||
nmax = MAX_FRG_PROG_ENV_PARAMS;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
}
|
||||
if(f && index+count<=nmax && count>=0) {
|
||||
noerrorShimNoPurge();
|
||||
memcpy(f, params, count*4*sizeof(float));
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat *params)
|
||||
{
|
||||
DBG(printf("glProgramLocalParameters4fvEXT(%s, %u, %i, %p)\n", PrintEnum(target), index, count, params);)
|
||||
float *f = NULL;
|
||||
oldprogram_t *old = NULL;
|
||||
switch(target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
old = glstate->glsl->vtx_prog;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
old = glstate->glsl->frg_prog;
|
||||
break;
|
||||
default:
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(!old) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
if(index+count<old->max_local_params && count>=0) {
|
||||
noerrorShimNoPurge();
|
||||
memcpy(old->prog_local_params+index*4, params, count*4*sizeof(float));
|
||||
} else
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
// Mappers for ARB_vertex_program
|
||||
AliasExport(void,glProgramStringARB,,(GLenum target, GLenum format, GLsizei len, const GLvoid *string));
|
||||
AliasExport(void,glBindProgramARB,,(GLenum target, GLuint program));
|
||||
AliasExport(void,glDeleteProgramsARB,,(GLsizei n, const GLuint *programs));
|
||||
AliasExport(void,glGenProgramsARB,,(GLsizei n, GLuint *programs));
|
||||
AliasExport_M(void,glProgramEnvParameter4dARB,,(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w),40);
|
||||
AliasExport(void,glProgramEnvParameter4dvARB,,(GLenum target, GLuint index, const GLdouble *params));
|
||||
AliasExport(void,glProgramEnvParameter4fARB,,(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
|
||||
AliasExport(void,glProgramEnvParameter4fvARB,,(GLenum target, GLuint index, const GLfloat *params));
|
||||
AliasExport_M(void,glProgramLocalParameter4dARB,,(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w),40);
|
||||
AliasExport(void,glProgramLocalParameter4dvARB,,(GLenum target, GLuint index, const GLdouble *params));
|
||||
AliasExport(void,glProgramLocalParameter4fARB,,(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
|
||||
AliasExport(void,glProgramLocalParameter4fvARB,,(GLenum target, GLuint index, const GLfloat *params));
|
||||
AliasExport(void,glGetProgramEnvParameterdvARB,,(GLenum target, GLuint index, GLdouble *params));
|
||||
AliasExport(void,glGetProgramEnvParameterfvARB,,(GLenum target, GLuint index, GLfloat *params));
|
||||
AliasExport(void,glGetProgramLocalParameterdvARB,,(GLenum target, GLuint index, GLdouble *params));
|
||||
AliasExport(void,glGetProgramLocalParameterfvARB,,(GLenum target, GLuint index, GLfloat *params));
|
||||
AliasExport(void,glGetProgramivARB,,(GLenum target, GLenum pname, GLint *params));
|
||||
AliasExport(void,glGetProgramStringARB,,(GLenum target, GLenum pname, GLvoid *string));
|
||||
AliasExport(GLboolean,glIsProgramARB,,(GLuint program));
|
||||
|
||||
AliasExport(void,glProgramEnvParameters4fvEXT,,(GLenum target, GLuint index, GLsizei count, const GLfloat *params));
|
||||
AliasExport(void,glProgramLocalParameters4fvEXT,,(GLenum target, GLuint index, GLsizei count, const GLfloat *params));
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef _GL4ES_OLD_PROGRAM_H_
|
||||
#define _GL4ES_OLD_PROGRAM_H_
|
||||
|
||||
#include "gles.h"
|
||||
#include "buffers.h"
|
||||
#include "shader.h"
|
||||
#include "uniform.h"
|
||||
#include "program.h"
|
||||
|
||||
typedef struct kh_oldprograms_s kh_oldprograms_t;
|
||||
typedef struct glstate_s glstate_t;
|
||||
typedef struct shader_s shader_t;
|
||||
|
||||
typedef struct oldprogram_s {
|
||||
GLuint id;
|
||||
GLenum type;
|
||||
char* string;
|
||||
shader_t* shader;
|
||||
int max_local_params;
|
||||
float* prog_local_params;
|
||||
int max_env_params;
|
||||
float* prog_env_params; // link to global array
|
||||
// tracking of the shader uniforms
|
||||
int min_loc;
|
||||
int max_loc;
|
||||
int* locals;
|
||||
int min_env;
|
||||
int max_env;
|
||||
int* envs;
|
||||
} oldprogram_t;
|
||||
|
||||
void InitOldProgramMap(glstate_t* glstate);
|
||||
void FreeOldProgramMap(glstate_t* glstate);
|
||||
|
||||
oldprogram_t* getOldProgram(GLuint id);
|
||||
|
||||
// ARB_vertex_program
|
||||
// VertexAttrib are the same as ARB_vertex_shader
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid *string);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBindProgramARB(GLenum target, GLuint program);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDeleteProgramsARB(GLsizei n, const GLuint *programs);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGenProgramsARB(GLsizei n, GLuint *programs);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
void APIENTRY_GL4ES gl4es_glProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble *params);
|
||||
void APIENTRY_GL4ES gl4es_glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void APIENTRY_GL4ES gl4es_glProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat *params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glProgramLocalParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
void APIENTRY_GL4ES gl4es_glProgramLocalParameter4dvARB(GLenum target, GLuint index, const GLdouble *params);
|
||||
void APIENTRY_GL4ES gl4es_glProgramLocalParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void APIENTRY_GL4ES gl4es_glProgramLocalParameter4fvARB(GLenum target, GLuint index, const GLfloat *params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramEnvParameterdvARB(GLenum target, GLuint index, GLdouble *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramEnvParameterfvARB(GLenum target, GLuint index, GLfloat *params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramLocalParameterdvARB(GLenum target, GLuint index, GLdouble *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramLocalParameterfvARB(GLenum target, GLuint index, GLfloat *params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramivARB(GLenum target, GLenum pname, GLint *params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramStringARB(GLenum target, GLenum pname, GLvoid *string);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glGetVertexAttribivARB(GLuint index, GLenum pname, GLint *params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer);
|
||||
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsProgramARB(GLuint program);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat *params);
|
||||
void APIENTRY_GL4ES gl4es_glProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat *params);
|
||||
|
||||
#endif //_GL4ES_OLD_PROGRAM_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
||||
#ifndef _GL4ES_PIXEL_H_
|
||||
#define _GL4ES_PIXEL_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "gles.h"
|
||||
|
||||
typedef struct {
|
||||
GLenum type;
|
||||
GLint red, green, blue, alpha;
|
||||
int maxv;
|
||||
} colorlayout_t;
|
||||
|
||||
typedef struct {
|
||||
GLfloat r, g, b, a;
|
||||
} pixel_t;
|
||||
|
||||
#define widthalign(width, align) ((((uintptr_t)(width))+((uintptr_t)(align)-1))&(~((uintptr_t)(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, GLuint align);
|
||||
|
||||
bool pixel_transform(const GLvoid *src, GLvoid **dst,
|
||||
GLuint width, GLuint height,
|
||||
GLenum src_format, GLenum src_type,
|
||||
const GLfloat *scale, const GLfloat *bias);
|
||||
|
||||
bool pixel_scale(const GLvoid *src, GLvoid **dst,
|
||||
GLuint width, GLuint height,
|
||||
GLuint new_width, GLuint new_height,
|
||||
GLenum format, GLenum type);
|
||||
|
||||
bool pixel_halfscale(const GLvoid *src, GLvoid **dst,
|
||||
GLuint width, GLuint height,
|
||||
GLenum format, GLenum type);
|
||||
|
||||
bool pixel_thirdscale(const GLvoid *src, GLvoid **dst,
|
||||
GLuint width, GLuint height,
|
||||
GLenum format, GLenum type);
|
||||
|
||||
bool pixel_quarterscale(const GLvoid *src, GLvoid **dst,
|
||||
GLuint width, GLuint height,
|
||||
GLenum format, GLenum type);
|
||||
|
||||
bool pixel_doublescale(const GLvoid *src, GLvoid **dst,
|
||||
GLuint width, GLuint height,
|
||||
GLenum format, GLenum type);
|
||||
|
||||
bool pixel_to_ppm(const GLvoid *pixels,
|
||||
GLuint width, GLuint height,
|
||||
GLenum format, GLenum type, GLuint name, GLuint align);
|
||||
|
||||
// sRGB ->RGB colorspace conversion, for RGBA data...
|
||||
void pixel_srgb_inplace(GLvoid* pixels, GLuint width, GLuint height);
|
||||
|
||||
#endif // _GL4ES_PIXEL_H_
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "planes.h"
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "loader.h"
|
||||
#include "matrix.h"
|
||||
#include "matvec.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glClipPlanef(GLenum plane, const GLfloat *equation)
|
||||
{
|
||||
/*
|
||||
When glClipPlane is called,
|
||||
equation is transformed by the inverse of the modelview matrix and stored in the resulting eye coordinates.
|
||||
Subsequent changes to the modelview matrix have no effect on the stored plane-equation components.
|
||||
If the dot product of the eye coordinates of a vertex with the stored plane equation components is positive or zero,
|
||||
the vertex is in with respect to that clipping plane. Otherwise, it is out.
|
||||
*/
|
||||
PUSH_IF_COMPILING(glClipPlanef); //TODO: fix that, equation is an array and should be copied before beeing put in the stack
|
||||
if((plane<GL_CLIP_PLANE0) || (plane>=GL_CLIP_PLANE0+hardext.maxplanes)) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
if(hardext.esversion==1) {
|
||||
LOAD_GLES2(glClipPlanef);
|
||||
errorGL();
|
||||
gles_glClipPlanef(plane, equation);
|
||||
} else { // TODO: should fist compute the clipplane and compare to stored one before sending to hardware
|
||||
int p = plane-GL_CLIP_PLANE0;
|
||||
matrix_vector(getInvMVMat(), equation, glstate->planes[p]); //Tested, seems ok
|
||||
noerrorShim();
|
||||
}
|
||||
}
|
||||
|
||||
AliasExport(void,glClipPlanef,,(GLenum pname, const GLfloat* params));
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef _GL4ES_PLANES_H_
|
||||
#define _GL4ES_PLANES_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glClipPlanef(GLenum plane, const GLfloat *equation);
|
||||
|
||||
#endif // _GL4ES_PLANES_H_
|
||||
@@ -0,0 +1,129 @@
|
||||
#include "pointsprite.h"
|
||||
|
||||
#include "../glx/hardext.h"
|
||||
#include "debug.h"
|
||||
#include "fpe.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "loader.h"
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glPointParameteri(GLenum pname, GLint param)
|
||||
{
|
||||
gl4es_glPointParameterf(pname, param);
|
||||
}
|
||||
AliasExport(void,glPointParameteri,,(GLenum pname, GLint param));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glPointParameteriv(GLenum pname, const GLint * params)
|
||||
{
|
||||
GLfloat tmp[3];
|
||||
int v=(pname==GL_POINT_DISTANCE_ATTENUATION)?3:1;
|
||||
for (int i=0; i<v; i++) tmp[i] = params[i];
|
||||
gl4es_glPointParameterfv(pname, tmp);
|
||||
}
|
||||
AliasExport(void,glPointParameteriv,,(GLenum pname, const GLint * params));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glPointParameterf(GLenum pname, GLfloat param) {
|
||||
PUSH_IF_COMPILING(glPointParameterf);
|
||||
gl4es_glPointParameterfv(pname, ¶m);
|
||||
}
|
||||
AliasExport(void,glPointParameterf,,(GLenum pname, GLfloat param));
|
||||
AliasExport(void,glPointParameterf,ARB,(GLenum pname, GLfloat param));
|
||||
AliasExport(void,glPointParameterf,EXT,(GLenum pname, GLfloat param));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glPointParameterfv(GLenum pname, const GLfloat * params)
|
||||
{
|
||||
if (glstate->list.active)
|
||||
if (glstate->list.compiling) {
|
||||
if (pname == GL_POINT_DISTANCE_ATTENUATION) {
|
||||
NewStage(glstate->list.active, STAGE_POINTPARAM);
|
||||
rlPointParamOp(glstate->list.active, 1, params);
|
||||
return;
|
||||
} else {
|
||||
gl4es_glPointParameterf(pname, params[0]);
|
||||
return;
|
||||
}
|
||||
} else gl4es_flush();
|
||||
|
||||
switch(pname) {
|
||||
case GL_POINT_SIZE_MIN:
|
||||
if(*params<0.0f) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->pointsprite.sizeMin == *params) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
glstate->pointsprite.sizeMin = *params;
|
||||
break;
|
||||
case GL_POINT_SIZE_MAX:
|
||||
if(*params<0.0f) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->pointsprite.sizeMax == *params) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
glstate->pointsprite.sizeMax = *params;
|
||||
break;
|
||||
case GL_POINT_FADE_THRESHOLD_SIZE:
|
||||
if(*params<0.0f) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->pointsprite.fadeThresholdSize == *params) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
glstate->pointsprite.fadeThresholdSize = *params;
|
||||
break;
|
||||
case GL_POINT_DISTANCE_ATTENUATION:
|
||||
if(*params<0.0f) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(memcmp(glstate->pointsprite.distance, params, 3*sizeof(GLfloat))==0) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
memcpy(glstate->pointsprite.distance, params, 3*sizeof(GLfloat));
|
||||
break;
|
||||
case GL_POINT_SPRITE_COORD_ORIGIN:
|
||||
if(*params!=GL_UPPER_LEFT && *params!=GL_LOWER_LEFT) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(glstate->pointsprite.coordOrigin == *params) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
if(glstate->fpe_state) {
|
||||
if(*params==GL_LOWER_LEFT)
|
||||
glstate->fpe_state->pointsprite_upper = 0;
|
||||
else
|
||||
glstate->fpe_state->pointsprite_upper = 1;
|
||||
}
|
||||
glstate->pointsprite.coordOrigin = *params;
|
||||
break;
|
||||
}
|
||||
|
||||
LOAD_GLES_FPE(glPointParameterfv);
|
||||
errorGL();
|
||||
gles_glPointParameterfv(pname, params);
|
||||
}
|
||||
AliasExport(void,glPointParameterfv,,(GLenum pname, const GLfloat * params));
|
||||
AliasExport(void,glPointParameterfv,ARB,(GLenum pname, const GLfloat * params));
|
||||
AliasExport(void,glPointParameterfv,EXT,(GLenum pname, const GLfloat * params));
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glPointSize(GLfloat size) {
|
||||
if(size<=0.0f) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glstate->pointsprite.size = size;
|
||||
errorGL();
|
||||
LOAD_GLES_FPE(glPointSize);
|
||||
gles_glPointSize(size);
|
||||
}
|
||||
AliasExport(void,glPointSize,,(GLfloat size));
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef _GL4ES_POINTSPRITE_H_
|
||||
#define _GL4ES_POINTSPRITE_H_
|
||||
|
||||
#include "gles.h"
|
||||
|
||||
typedef struct {
|
||||
GLfloat size;
|
||||
GLfloat sizeMin;
|
||||
GLfloat sizeMax;
|
||||
GLfloat fadeThresholdSize;
|
||||
GLfloat distance[3];
|
||||
GLenum coordOrigin;
|
||||
} pointsprite_t;
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glPointParameteri(GLenum pname, GLint param);
|
||||
void APIENTRY_GL4ES gl4es_glPointParameteriv(GLenum pname, const GLint * params);
|
||||
void APIENTRY_GL4ES gl4es_glPointParameterf(GLenum pname, GLfloat param);
|
||||
void APIENTRY_GL4ES gl4es_glPointParameterfv(GLenum pname, const GLfloat * params);
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glPointSize(GLfloat size);
|
||||
|
||||
#endif // _GL4ES_POINTSPRITE_H_
|
||||
@@ -0,0 +1,825 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <locale.h>
|
||||
#include "khash.h"
|
||||
|
||||
#include "preproc.h"
|
||||
#include "string_utils.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DBG(a) a
|
||||
#pragma GCC optimize 0
|
||||
#else
|
||||
#define DBG(a)
|
||||
#endif
|
||||
|
||||
typedef enum _eTokenType {
|
||||
TK_NULL = 0,
|
||||
TK_SPACE,
|
||||
TK_SHARP,
|
||||
TK_NEWLINE,
|
||||
TK_INT,
|
||||
TK_FLOAT,
|
||||
TK_PLUS,
|
||||
TK_MINUS,
|
||||
TK_EQUAL,
|
||||
TK_SLASH,
|
||||
TK_DOUBLESLASH, //10
|
||||
TK_MULTIPLY,
|
||||
TK_BACKSLASH,
|
||||
TK_OPENBRACE,
|
||||
TK_CLOSEBRACE,
|
||||
TK_OPENCURLY,
|
||||
TK_CLOSECURLY,
|
||||
TK_OPENBRAKET,
|
||||
TK_CLOSEBRAKET,
|
||||
TK_OPENCOMMENT,
|
||||
TK_CLOSECOMMENT, //20
|
||||
TK_COLUMN,
|
||||
TK_SEMICOLUMN,
|
||||
TK_COMMA,
|
||||
TK_DOT,
|
||||
TK_AMP,
|
||||
TK_POW,
|
||||
TK_PIPE,
|
||||
TK_EXCLAM,
|
||||
TK_POINT, //30
|
||||
TK_GREATER,
|
||||
TK_LESS,
|
||||
TK_DOUBLEEQUAL,
|
||||
TK_TILDE,
|
||||
TK_TEXT,
|
||||
TK_TEXTCOMMENT
|
||||
} eTokenType;
|
||||
|
||||
#define MAXSTR 500
|
||||
|
||||
typedef struct _uToken {
|
||||
eTokenType type;
|
||||
char str[MAXSTR];
|
||||
int integer;
|
||||
float real;
|
||||
} uToken;
|
||||
|
||||
eTokenType NextTokenComment(char **p, uToken *tok) {
|
||||
tok->type = TK_NULL;
|
||||
tok->str[0] = 0;
|
||||
if(!**p) return tok->type;
|
||||
|
||||
char c = **p;
|
||||
(*p)++;
|
||||
char nextc = **p;
|
||||
int nb = 0;
|
||||
int isfloat = 0;
|
||||
int isneg = 1; // multiply by it...
|
||||
float fnb = 0.f;
|
||||
int cnt = 0;
|
||||
float fcnt = 0.f;
|
||||
|
||||
tok->str[0]=c; tok->str[1]=0;
|
||||
|
||||
switch (c) {
|
||||
case 10:
|
||||
if(nextc==13)
|
||||
(*p)++;
|
||||
strcpy(tok->str, "\n");
|
||||
tok->type = TK_NEWLINE;
|
||||
break;
|
||||
case 13:
|
||||
if(nextc==10)
|
||||
(*p)++;
|
||||
strcpy(tok->str, "\n");
|
||||
tok->type = TK_NEWLINE;
|
||||
break;
|
||||
case ' ':
|
||||
case '\t':
|
||||
while(nextc==' ' || nextc=='\t') { int l=strlen(tok->str); tok->str[l]=nextc; tok->str[l+1]=0; (*p)++; nextc=**p; }
|
||||
tok->type = TK_SPACE;
|
||||
break;
|
||||
case '/':
|
||||
if(nextc=='/') {
|
||||
(*p)++;
|
||||
tok->type=TK_DOUBLESLASH;
|
||||
strcpy(tok->str, "//");
|
||||
} else if(nextc=='*') {
|
||||
(*p)++;
|
||||
tok->type=TK_OPENCOMMENT;
|
||||
strcpy(tok->str, "/*");
|
||||
} else {
|
||||
tok->type=TK_SLASH;
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
if(nextc=='/') {
|
||||
(*p)++;
|
||||
tok->type=TK_CLOSECOMMENT;
|
||||
strcpy(tok->str, "*/");
|
||||
} else {
|
||||
tok->type=TK_MULTIPLY;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// all other are plain Ids...
|
||||
cnt=1;
|
||||
tok->type=TK_TEXTCOMMENT;
|
||||
while(cnt!=(MAXSTR-1) && (nextc=='_' || (nextc>='0' && nextc<='9') || (nextc>='A' && nextc<='Z') || (nextc>='a' && nextc<='z'))) {
|
||||
tok->str[cnt]=nextc;
|
||||
(*p)++; nextc=**p;
|
||||
++cnt;
|
||||
}
|
||||
tok->str[cnt]=0;
|
||||
}
|
||||
|
||||
return tok->type;
|
||||
}
|
||||
|
||||
eTokenType NextToken(char **p, uToken *tok) {
|
||||
tok->type = TK_NULL;
|
||||
tok->str[0] = 0;
|
||||
if(!**p) return tok->type;
|
||||
|
||||
char c = **p;
|
||||
(*p)++;
|
||||
char nextc = **p;
|
||||
int nb = 0;
|
||||
int isfloat = 0;
|
||||
int isneg = 1; // multiply by it...
|
||||
float fnb = 0.f;
|
||||
int cnt = 0;
|
||||
float fcnt = 0.f;
|
||||
|
||||
tok->str[0]=c; tok->str[1]=0;
|
||||
|
||||
switch (c) {
|
||||
case 10:
|
||||
if(nextc==13)
|
||||
(*p)++;
|
||||
tok->type = TK_NEWLINE;
|
||||
strcpy(tok->str, "\n");
|
||||
break;
|
||||
case 13:
|
||||
if(nextc==10)
|
||||
(*p)++;
|
||||
tok->type = TK_NEWLINE;
|
||||
strcpy(tok->str, "\n");
|
||||
break;
|
||||
case ' ':
|
||||
case '\t':
|
||||
while(nextc==' ' || nextc=='\t') { int l=strlen(tok->str); tok->str[l]=nextc; tok->str[l+1]=0; (*p)++; nextc=**p; }
|
||||
tok->type = TK_SPACE;
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
nb=c-'0';
|
||||
// we don't know if it's an int or a float at first...
|
||||
if(nextc=='x' && nb==0) {
|
||||
// hex number, so int...
|
||||
(*p)++; nextc=**p;
|
||||
while((nextc>='0' && nextc<='9') || (nextc>='a' && nextc<='f') || (nextc>='A' && nextc<='F')) {
|
||||
nb=nb*16;
|
||||
if(nextc>='0' && nextc<='9')
|
||||
nb+=nextc-'0';
|
||||
else if(nextc>='a' && nextc<='f')
|
||||
nb+=nextc-'a'+10;
|
||||
else if(nextc>='A' && nextc<='F')
|
||||
nb+=nextc-'A'+10;
|
||||
(*p)++; nextc=**p;
|
||||
}
|
||||
tok->type = TK_INT;
|
||||
tok->integer = nb;
|
||||
sprintf(tok->str, "0x%x", nb);
|
||||
} else {
|
||||
while(nextc>='0' && nextc<='9') { nb=nb*10+nextc-'0'; (*p)++; nextc=**p;}
|
||||
if(nextc=='.' || nextc=='f' || nextc=='e') {
|
||||
isfloat = 1;
|
||||
fnb=nb;
|
||||
if(nextc=='.') {
|
||||
(*p)++; nextc=**p;
|
||||
fcnt = 0.1f;
|
||||
while(nextc>='0' && nextc<='9') {
|
||||
fnb+=(nextc-'0')*fcnt;
|
||||
fcnt/=10.f;
|
||||
(*p)++; nextc=**p;
|
||||
}
|
||||
}
|
||||
if(nextc=='e') {
|
||||
// exponent
|
||||
(*p)++; nextc=**p;
|
||||
nb=0;
|
||||
int expsign = 1;
|
||||
if(nextc=='-' || nextc=='+') {
|
||||
if(nextc=='-') expsign = -1;
|
||||
(*p)++; nextc=**p;
|
||||
}
|
||||
while(nextc>='0' && nextc<='9') { nb=nb*10+nextc-'0'; (*p)++; nextc=**p;}
|
||||
fnb *= powf(10, nb*expsign); // exp10f is a GNU extension
|
||||
}
|
||||
if(nextc=='f') {
|
||||
(*p)++; nextc=**p;
|
||||
}
|
||||
fnb*=isneg;
|
||||
tok->type = TK_FLOAT;
|
||||
tok->real = fnb;
|
||||
sprintf(tok->str, "%#g", fnb);
|
||||
} else {
|
||||
tok->type = TK_INT;
|
||||
tok->integer = nb;
|
||||
sprintf(tok->str, "%d", nb);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
if(nextc=='/') {
|
||||
(*p)++;
|
||||
tok->type=TK_DOUBLESLASH;
|
||||
strcpy(tok->str, "//");
|
||||
} else if(nextc=='*') {
|
||||
(*p)++;
|
||||
tok->type=TK_OPENCOMMENT;
|
||||
strcpy(tok->str, "/*");
|
||||
} else {
|
||||
tok->type=TK_SLASH;
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
if(nextc=='/') {
|
||||
(*p)++;
|
||||
tok->type=TK_CLOSECOMMENT;
|
||||
strcpy(tok->str, "*/");
|
||||
} else {
|
||||
tok->type=TK_MULTIPLY;
|
||||
}
|
||||
break;
|
||||
case '=': tok->type=TK_EQUAL; break;
|
||||
case '~': tok->type=TK_TILDE; break;
|
||||
case '#': tok->type=TK_SHARP; break;
|
||||
case '(': tok->type=TK_OPENBRACE; break;
|
||||
case ')': tok->type=TK_CLOSEBRACE; break;
|
||||
case '{': tok->type=TK_OPENCURLY; break;
|
||||
case '}': tok->type=TK_CLOSECURLY; break;
|
||||
case '[': tok->type=TK_OPENBRAKET; break;
|
||||
case ']': tok->type=TK_CLOSEBRAKET; break;
|
||||
case '&': tok->type=TK_AMP; break;
|
||||
case '^': tok->type=TK_POW; break;
|
||||
case '|': tok->type=TK_PIPE; break;
|
||||
case '\\': tok->type=TK_BACKSLASH; break;
|
||||
case '<': tok->type=TK_LESS; break;
|
||||
case '>': tok->type=TK_GREATER; break;
|
||||
case '+': tok->type=TK_PLUS; break;
|
||||
case '-': tok->type=TK_MINUS; break;
|
||||
case ':': tok->type=TK_COLUMN; break;
|
||||
case ';': tok->type=TK_SEMICOLUMN; break;
|
||||
case ',': tok->type=TK_COMMA; break;
|
||||
case '.': tok->type=TK_DOT; break;
|
||||
case '!': tok->type=TK_EXCLAM; break;
|
||||
// todo: char and string?
|
||||
default:
|
||||
// all other are plain Ids...
|
||||
cnt=1;
|
||||
tok->type=TK_TEXT;
|
||||
while(cnt!=(MAXSTR-1) && (nextc=='_' || (nextc>='0' && nextc<='9') || (nextc>='A' && nextc<='Z') || (nextc>='a' && nextc<='z'))) {
|
||||
tok->str[cnt]=nextc;
|
||||
(*p)++; nextc=**p;
|
||||
++cnt;
|
||||
}
|
||||
tok->str[cnt]=0;
|
||||
}
|
||||
|
||||
return tok->type;
|
||||
}
|
||||
|
||||
eTokenType GetToken(char **p, uToken *tok, int incomment) {
|
||||
eTokenType ret;
|
||||
if (incomment)
|
||||
ret = NextTokenComment(p, tok);
|
||||
else
|
||||
ret = NextToken(p, tok);
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int cap;
|
||||
int sz;
|
||||
int *ifs;
|
||||
} stackif_t;
|
||||
|
||||
static void push_if(stackif_t *st, int v) {
|
||||
if(st->sz == st->cap) {
|
||||
st->cap += 16;
|
||||
st->ifs = (int*)realloc(st->ifs, sizeof(int)*st->cap);
|
||||
}
|
||||
st->ifs[st->sz++] = v;
|
||||
}
|
||||
|
||||
static int pop_if(stackif_t *st) {
|
||||
if(st->sz)
|
||||
return st->ifs[--st->sz];
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int top_if(stackif_t *st) {
|
||||
if(st->sz)
|
||||
return st->ifs[st->sz-1];
|
||||
return -1;
|
||||
}
|
||||
static void not_top_if(stackif_t *st) {
|
||||
if(st->sz && st->ifs[st->sz-1]!=-1)
|
||||
st->ifs[st->sz-1] = 1 - st->ifs[st->sz-1];
|
||||
}
|
||||
|
||||
static int result_if(stackif_t *st) {
|
||||
for (int i=0; i<st->sz; ++i) {
|
||||
if(st->ifs[i] == 1) return 1;
|
||||
else if(st->ifs[i] == -1) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
KHASH_MAP_INIT_STR(define, int);
|
||||
KHASH_MAP_INIT_STR(alldefine, char*);
|
||||
|
||||
char* preproc(const char* code, int keepcomments, int gl_es, extensions_t* exts, char** versionString) {
|
||||
DBG(printf("Preproc on: =========\n%s\n=================\n", code);)
|
||||
|
||||
uToken tok;
|
||||
char* p = (char*)code;
|
||||
char* oldp = NULL;
|
||||
int cap=1000;
|
||||
char* ncode = (char*)malloc(1000);
|
||||
ncode[0]=0;
|
||||
int sz=1;
|
||||
int status=0;
|
||||
int write=1;
|
||||
int incomment=0;
|
||||
int indefined=0;
|
||||
int newline=0;
|
||||
int gettok=0;
|
||||
int notok = 0;
|
||||
char extname[50];
|
||||
khint_t k;
|
||||
int ret;
|
||||
char *defname; //used for #define or #if
|
||||
int defval;
|
||||
stackif_t stackif = {0};
|
||||
int nowrite_ifs = 0;
|
||||
int current_if = 0;
|
||||
int need_pop = 0;
|
||||
|
||||
char* old_locale = setlocale(LC_ALL, "C");
|
||||
|
||||
khash_t(alldefine) *alldefines = kh_init(alldefine); // will conatin all defines, even the one without int inside
|
||||
|
||||
khash_t(define) *defines = kh_init(define);
|
||||
if(gl_es) {
|
||||
k = kh_put(define, defines, "GL_ES", &ret);
|
||||
kh_value(defines, k) = 0;
|
||||
}
|
||||
push_if(&stackif, 0); // default to OK
|
||||
GetToken(&p, &tok, incomment);
|
||||
while(tok.type!=TK_NULL) {
|
||||
// pop #if / #endif status
|
||||
if(need_pop) {
|
||||
pop_if(&stackif);
|
||||
nowrite_ifs = result_if(&stackif);
|
||||
need_pop = 0;
|
||||
|
||||
}
|
||||
// pre get token switch
|
||||
switch(status) {
|
||||
case 110: // line comment done...
|
||||
case 210: // block comment done
|
||||
if(!write && newline) {
|
||||
gettok=0;
|
||||
tok.type=TK_NEWLINE;
|
||||
strcpy(tok.str, "\n");
|
||||
}
|
||||
write = 1;
|
||||
status = (status==210)?1:0;
|
||||
incomment=0;
|
||||
newline=0;
|
||||
break;
|
||||
}
|
||||
// get token (if needed)
|
||||
if (gettok) GetToken(&p, &tok, incomment);
|
||||
gettok=1;
|
||||
// post get token switch
|
||||
if(tok.type!=TK_NULL) {
|
||||
switch(status) {
|
||||
case 0: // regular...
|
||||
case 1:
|
||||
if(tok.type==TK_DOUBLESLASH) {
|
||||
status = 100; // line comment
|
||||
incomment = 1;
|
||||
newline = 1;
|
||||
if(!keepcomments) write=0;
|
||||
} else if(tok.type==TK_OPENCOMMENT) {
|
||||
status = 200; // multi-line comment
|
||||
incomment = 1;
|
||||
if(!keepcomments) write=0;
|
||||
} else if(tok.type==TK_SHARP && !incomment && status==0) {
|
||||
oldp = p-1; // lets buffer the line
|
||||
status = 300;
|
||||
} else if(tok.type==TK_NEWLINE)
|
||||
status = 0;
|
||||
else if(tok.type!=TK_SPACE)
|
||||
status = 1; // everything else but space set status to 1...
|
||||
break;
|
||||
|
||||
// line comment...
|
||||
case 100:
|
||||
if(tok.type==TK_BACKSLASH) {
|
||||
status = 120; // is it backslash+endline for multiline?
|
||||
} else if(tok.type==TK_NEWLINE) {
|
||||
status = 110;
|
||||
}
|
||||
break;
|
||||
case 120:
|
||||
status = 100; // continue comment, what ever follow (NewLine or anything else)
|
||||
break;
|
||||
|
||||
// block comment...
|
||||
case 200:
|
||||
if(tok.type==TK_NEWLINE)
|
||||
newline=1;
|
||||
if(tok.type==TK_CLOSECOMMENT) {
|
||||
status=210;
|
||||
}
|
||||
break;
|
||||
|
||||
// # (of ifdef or extension)
|
||||
case 300:
|
||||
if(tok.type!=TK_SPACE)
|
||||
if(tok.type==TK_TEXT) {
|
||||
if(!strcmp(tok.str, "ifdef"))
|
||||
status=310;
|
||||
else if(!strcmp(tok.str, "ifndef"))
|
||||
status=320;
|
||||
else if(!strcmp(tok.str, "if")) {
|
||||
// #if defined(GL_ES) not supported for now
|
||||
push_if(&stackif, -1);
|
||||
if(nowrite_ifs==1) {
|
||||
status = 398; notok = 1;
|
||||
} else {
|
||||
status = 390;
|
||||
{
|
||||
int l = p - oldp;
|
||||
memcpy(tok.str, oldp, l);
|
||||
tok.str[l]='\0';
|
||||
oldp = 0;
|
||||
}
|
||||
}
|
||||
nowrite_ifs = result_if(&stackif);
|
||||
} else if(!strcmp(tok.str, "else")) {
|
||||
status = 399;
|
||||
// ifs handling
|
||||
{
|
||||
not_top_if(&stackif);
|
||||
int v = result_if(&stackif);
|
||||
if(v!=-1) {
|
||||
notok = 1;
|
||||
status = 398;
|
||||
}
|
||||
nowrite_ifs = v;
|
||||
}
|
||||
} else if(!strcmp(tok.str, "endif")) {
|
||||
status = 399;
|
||||
{
|
||||
need_pop = 1;
|
||||
if(nowrite_ifs!=-1) {
|
||||
notok = 1;
|
||||
status = 398;
|
||||
}
|
||||
}
|
||||
} else if(!strcmp(tok.str, "extension")) {
|
||||
status = 410;
|
||||
} else if(!strcmp(tok.str, "pragma")) {
|
||||
status = 510;
|
||||
} else if(!strcmp(tok.str, "define")) {
|
||||
status = 610;
|
||||
} else if(!strcmp(tok.str, "version")) {
|
||||
status = 810;
|
||||
if(!*versionString)
|
||||
*versionString = (char*)calloc(1, 51);
|
||||
} else status=399;
|
||||
} else status = 399; // meh?
|
||||
break;
|
||||
|
||||
// ifdef
|
||||
case 310:
|
||||
if(tok.type==TK_SPACE)
|
||||
status = 310;
|
||||
else if(tok.type==TK_TEXT) {
|
||||
int v = -1;
|
||||
if(gl_es && (strcmp(tok.str, "GL_ES")==0))
|
||||
v = 1;
|
||||
else if(kh_get(alldefine, alldefines, tok.str)!=kh_end(alldefines)) {
|
||||
v = 0;
|
||||
} else if (strncmp(tok.str, "GL_", 3)==0)
|
||||
v = -1;
|
||||
push_if(&stackif, v);
|
||||
nowrite_ifs = result_if(&stackif);
|
||||
if(nowrite_ifs!=-1) {
|
||||
status = 398; notok = 1;
|
||||
} else
|
||||
status = 399;
|
||||
} else {push_if(&stackif, -1); nowrite_ifs = result_if(&stackif);status = 399;}
|
||||
break;
|
||||
|
||||
// ifndef
|
||||
case 320:
|
||||
if(tok.type==TK_SPACE)
|
||||
status = 320;
|
||||
else if(tok.type==TK_TEXT) {
|
||||
int v = -1;
|
||||
if(gl_es && strcmp(tok.str, "GL_ES")==0)
|
||||
v = 0;
|
||||
else if(kh_get(alldefine, alldefines, tok.str)!=kh_end(alldefines)) {
|
||||
v = 1;
|
||||
} else if (strncmp(tok.str, "GL_", 3)==0)
|
||||
v = -1;
|
||||
push_if(&stackif, v);
|
||||
nowrite_ifs = result_if(&stackif);
|
||||
if(nowrite_ifs!=-1) {
|
||||
status = 398; notok = 1;
|
||||
} else
|
||||
status = 399;
|
||||
} else {push_if(&stackif, -1); nowrite_ifs = result_if(&stackif); status = 399;}
|
||||
break;
|
||||
|
||||
// #if ...
|
||||
case 390:
|
||||
if (tok.type == TK_NEWLINE) {
|
||||
status = 0;
|
||||
} else if (tok.type == TK_TEXT) {
|
||||
if(!strcmp(tok.str, "defined"))
|
||||
status = 710;
|
||||
}
|
||||
break;
|
||||
|
||||
// end of #ifdef GL_ES and variant..
|
||||
case 398:
|
||||
if(tok.type==TK_NEWLINE) {
|
||||
oldp = NULL;
|
||||
status = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
// fallback for #ifdef GL_ES, write the line back...
|
||||
case 399:
|
||||
if(oldp)
|
||||
{
|
||||
int l = p - oldp;
|
||||
memcpy(tok.str, oldp, l);
|
||||
tok.str[l]='\0';
|
||||
oldp = NULL;
|
||||
}
|
||||
status = (tok.type==TK_NEWLINE)?0:1;
|
||||
break;
|
||||
// #extension
|
||||
case 410:
|
||||
if(tok.type==TK_SPACE) {
|
||||
// nothing...
|
||||
} else if(tok.type==TK_TEXT && strlen(tok.str)<50) {
|
||||
strcpy(extname, tok.str);
|
||||
status = 420;
|
||||
} else {
|
||||
status = 399; // fallback, syntax error...
|
||||
}
|
||||
break;
|
||||
// after the name and before the ':' of #extension
|
||||
case 420:
|
||||
if(tok.type==TK_SPACE) {
|
||||
// nothing...
|
||||
} else if (tok.type==TK_COLUMN) {
|
||||
status=430;
|
||||
} else {
|
||||
status = 399; // fallback, syntax error...
|
||||
}
|
||||
break;
|
||||
// after the ':' of #extension
|
||||
case 430:
|
||||
if(tok.type==TK_SPACE) {
|
||||
// nothing...
|
||||
} else if(tok.type==TK_TEXT) {
|
||||
int state = -1;
|
||||
if(!strcmp(tok.str, "disable"))
|
||||
state = 0;
|
||||
else if(!strcmp(tok.str, "warn"))
|
||||
state = 1;
|
||||
else if(!strcmp(tok.str, "enable"))
|
||||
state = 1;
|
||||
else if(!strcmp(tok.str, "require"))
|
||||
state = 1;
|
||||
if(state!=-1) {
|
||||
if(exts->size==exts->cap) {
|
||||
exts->cap += 4;
|
||||
exts->ext = (extension_t*)realloc(exts->ext, sizeof(extension_t)*exts->cap);
|
||||
}
|
||||
strcpy(exts->ext[exts->size].name, extname);
|
||||
exts->ext[exts->size].state = state;
|
||||
++exts->size;
|
||||
status = 398; // all done
|
||||
} else
|
||||
status = 399; // error, unknown keyword
|
||||
} else {
|
||||
status = 399; // fallback, syntax error...
|
||||
}
|
||||
break;
|
||||
// #pragma
|
||||
case 510:
|
||||
if(tok.type==TK_SPACE) {
|
||||
// nothing...
|
||||
} else if(tok.type==TK_TEXT && strlen(tok.str)<50) {
|
||||
if(strcmp(tok.str, "message")==0)
|
||||
status = 398; //pragma message are removed
|
||||
else if(strcmp(tok.str, "parameter")==0)
|
||||
status = 398; //pragma message are removed
|
||||
else
|
||||
status = 399; // other pragma as left as-is
|
||||
} else {
|
||||
status = 399; // fallback, syntax error...
|
||||
}
|
||||
break;
|
||||
// #define
|
||||
case 610:
|
||||
if(tok.type==TK_SPACE) {
|
||||
// nothing...
|
||||
} else if(tok.type==TK_TEXT && strlen(tok.str)<50) {
|
||||
defname = strdup(tok.str);
|
||||
k = kh_put(alldefine, alldefines, defname, &ret);
|
||||
kh_value(alldefines, k) = defname;
|
||||
status = 620; // and now get the value
|
||||
} else {
|
||||
status = 399; // fallback, define name too long...
|
||||
}
|
||||
break;
|
||||
case 620:
|
||||
if(tok.type==TK_SPACE) {
|
||||
// nothing...
|
||||
} else if(tok.type==TK_INT) {
|
||||
defval = tok.integer;
|
||||
status = 630; // check if end of line (so it's a simple define)
|
||||
} else if(tok.type==TK_NEWLINE) {
|
||||
{
|
||||
int l = p - oldp;
|
||||
memcpy(tok.str, oldp, l);
|
||||
tok.str[l]='\0';
|
||||
oldp = 0;
|
||||
}
|
||||
status = 0;
|
||||
} else {
|
||||
status = 399; // fallback
|
||||
}
|
||||
break;
|
||||
case 630:
|
||||
if(tok.type==TK_SPACE) {
|
||||
// nothing...
|
||||
} else if(tok.type==TK_NEWLINE) {
|
||||
k = kh_put(define, defines, defname, &ret);
|
||||
kh_value(defines, k) = defval;
|
||||
{
|
||||
int l = p - oldp;
|
||||
memcpy(tok.str, oldp, l);
|
||||
tok.str[l]='\0';
|
||||
oldp = 0;
|
||||
}
|
||||
status = 0; // ok, define added to collection, left the line as-is anyway
|
||||
} else {
|
||||
status = 399; // fallback
|
||||
}
|
||||
break;
|
||||
// #defined
|
||||
case 710:
|
||||
if(tok.type==TK_SPACE) {
|
||||
// nothing...
|
||||
} else if(tok.type==TK_OPENBRACE) {
|
||||
status = 720; // and now get the value
|
||||
++indefined;
|
||||
} else if(tok.type==TK_NEWLINE) {
|
||||
if(!indefined) status = 0; // ok... no handling of #defined for now, so just write through the line
|
||||
}/* else {
|
||||
status = 399; // No fallback...
|
||||
}*/
|
||||
break;
|
||||
case 720:
|
||||
if(tok.type==TK_SPACE || tok.type==TK_TEXT) {
|
||||
// nothing...
|
||||
} else if (tok.type==TK_CLOSEBRACE) {
|
||||
--indefined;
|
||||
status = 710;
|
||||
} else {
|
||||
indefined = 0;
|
||||
status = 399;
|
||||
}
|
||||
break;
|
||||
// #version
|
||||
case 810:
|
||||
if(tok.type==TK_SPACE) {
|
||||
// nothing...
|
||||
} else if(tok.type==TK_TEXT) {
|
||||
strncat(*versionString, tok.str, 50);
|
||||
status = 820;
|
||||
} else if(tok.type==TK_INT) {
|
||||
char buff[20] = {0};
|
||||
sprintf(buff, "%d", tok.integer);
|
||||
strncat(*versionString, buff, 50);
|
||||
status = 820;
|
||||
} else if(tok.type==TK_FLOAT) {
|
||||
char buff[20] = {0};
|
||||
sprintf(buff, "%g", tok.real);
|
||||
strncat(*versionString, buff, 50);
|
||||
status = 820;
|
||||
} else {
|
||||
status = 399; // fallback, syntax error...
|
||||
}
|
||||
break;
|
||||
case 820:
|
||||
if(tok.type==TK_SPACE) {
|
||||
strncat(*versionString, " ", 50);
|
||||
status = 830;
|
||||
} else if(tok.type==TK_TEXT) {
|
||||
strncat(*versionString, tok.str, 50);
|
||||
} else if(tok.type==TK_INT) {
|
||||
char buff[20] = {0};
|
||||
sprintf(buff, "%d", tok.integer);
|
||||
strncat(*versionString, buff, 50);
|
||||
} else if(tok.type==TK_FLOAT) {
|
||||
char buff[20] = {0};
|
||||
sprintf(buff, "%g", tok.real);
|
||||
strncat(*versionString, buff, 50);
|
||||
} else if(tok.type==TK_NEWLINE) {
|
||||
oldp = NULL;
|
||||
status = 0;
|
||||
} else {
|
||||
status = 399; // fallback, syntax error...
|
||||
}
|
||||
break;
|
||||
case 830:
|
||||
if(tok.type==TK_SPACE) {
|
||||
status = 830;
|
||||
} else if(tok.type==TK_TEXT) {
|
||||
strncat(*versionString, tok.str, 50);
|
||||
status = 820;
|
||||
} else if(tok.type==TK_INT) {
|
||||
char buff[20] = {0};
|
||||
sprintf(buff, "%d", tok.integer);
|
||||
strncat(*versionString, buff, 50);
|
||||
status = 820;
|
||||
} else if(tok.type==TK_FLOAT) {
|
||||
char buff[20] = {0};
|
||||
sprintf(buff, "%g", tok.real);
|
||||
strncat(*versionString, buff, 50);
|
||||
status = 820;
|
||||
} else if(tok.type==TK_NEWLINE) {
|
||||
oldp = NULL;
|
||||
status = 0;
|
||||
} else {
|
||||
status = 399; // fallback, syntax error...
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(notok)
|
||||
notok=0;
|
||||
else
|
||||
if(write && !oldp && nowrite_ifs!=1) {
|
||||
if(!incomment && !indefined && tok.type == TK_TEXT) {
|
||||
k = kh_get(define, defines, tok.str);
|
||||
if(k!=kh_end(defines)) {
|
||||
int v = kh_val(defines, k);
|
||||
sprintf(tok.str, "%d", v); // overide define with defined value
|
||||
}
|
||||
}
|
||||
int l = strlen(tok.str);
|
||||
if(sz+l>=cap) {
|
||||
cap+=2000;
|
||||
ncode = (char*)realloc(ncode, cap);
|
||||
}
|
||||
strcat(ncode, tok.str);
|
||||
sz+=l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DBG(printf("New code is: ------------\n%s\n------------------\n", ncode);)
|
||||
kh_destroy(define, defines);
|
||||
kh_foreach_value(alldefines, defname,
|
||||
free(defname);
|
||||
)
|
||||
kh_destroy(alldefine, alldefines);
|
||||
if(stackif.ifs)
|
||||
free(stackif.ifs);
|
||||
|
||||
setlocale(LC_ALL, old_locale);
|
||||
return ncode;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef _GL4ES_PREPROC_H_
|
||||
#define _GL4ES_PREPROC_H_
|
||||
|
||||
typedef struct {
|
||||
char name[50];
|
||||
int state; //0:disable, 1:warn, 1:enable, 2:require
|
||||
} extension_t;
|
||||
|
||||
typedef struct {
|
||||
extension_t *ext;
|
||||
int size;
|
||||
int cap;
|
||||
} extensions_t;
|
||||
|
||||
char* preproc(const char* code, int keepcomments, int gl_es, extensions_t* exts, char** versionString);
|
||||
|
||||
#endif // _GL4ES_PREPROC_H_
|
||||
@@ -0,0 +1,999 @@
|
||||
#include "program.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../glx/hardext.h"
|
||||
#include "debug.h"
|
||||
#include "fpe.h"
|
||||
#include "gl4es.h"
|
||||
#include "glstate.h"
|
||||
#include "loader.h"
|
||||
#include "shaderconv.h"
|
||||
#include "fpe_shader.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DBG(a) a
|
||||
#else
|
||||
#define DBG(a)
|
||||
#endif
|
||||
|
||||
//KH Map implementations
|
||||
KHASH_MAP_IMPL_INT(attribloclist, attribloc_t *);
|
||||
KHASH_MAP_IMPL_INT(uniformlist, uniform_t *);
|
||||
KHASH_MAP_IMPL_INT(programlist, program_t *);
|
||||
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glAttachShader(GLuint program, GLuint shader) {
|
||||
DBG(printf("glAttachShader(%d, %d)\n", program, shader);)
|
||||
FLUSH_BEGINEND;
|
||||
// sanity tests
|
||||
CHECK_PROGRAM(void, program)
|
||||
CHECK_SHADER(void, shader)
|
||||
|
||||
// add shader reference to program
|
||||
if(glprogram->attach_cap == glprogram->attach_size) {
|
||||
glprogram->attach_cap += 4;
|
||||
glprogram->attach = (GLuint*)realloc(glprogram->attach, sizeof(GLuint)*glprogram->attach_cap);
|
||||
}
|
||||
glprogram->attach[glprogram->attach_size++] = glshader->id;
|
||||
glshader->attached++;
|
||||
// save last vertex or fragment attached
|
||||
if(glshader->type==GL_VERTEX_SHADER && !glprogram->last_vert)
|
||||
glprogram->last_vert = glshader;
|
||||
else if(glshader->type==GL_FRAGMENT_SHADER && !glprogram->last_frag)
|
||||
glprogram->last_frag = glshader;
|
||||
// send to hadware
|
||||
LOAD_GLES2(glAttachShader);
|
||||
if(gles_glAttachShader) {
|
||||
gles_glAttachShader(glprogram->id, glshader->id);
|
||||
errorGL();
|
||||
} else
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glBindAttribLocation(GLuint program, GLuint index, const GLchar *name) {
|
||||
DBG(printf("glBindAttribLocation(%d, %d, \"%s\")\n", program, index, name);)
|
||||
FLUSH_BEGINEND;
|
||||
// sanity tests
|
||||
CHECK_PROGRAM(void, program)
|
||||
// look / create attribloc at index
|
||||
attribloc_t *attribloc = NULL;
|
||||
{
|
||||
khint_t k;
|
||||
int ret;
|
||||
khash_t(attribloclist) *attribloclist = glprogram->attribloc;
|
||||
k = kh_get(attribloclist, attribloclist, index);
|
||||
if (k != kh_end(attribloclist)) {
|
||||
attribloc = kh_value(attribloclist, k);
|
||||
} else {
|
||||
k = kh_put(attribloclist, attribloclist, index, &ret);
|
||||
attribloc = kh_value(attribloclist, k) = malloc(sizeof(attribloc_t));
|
||||
memset(attribloc, 0, sizeof(attribloc_t));
|
||||
attribloc->real_index = -1;
|
||||
attribloc->index = index;
|
||||
}
|
||||
}
|
||||
// update name
|
||||
if(attribloc->name) free(attribloc->name);
|
||||
attribloc->name = strdup(name);
|
||||
attribloc->glname = attribloc->name;
|
||||
// send to hardware
|
||||
LOAD_GLES2(glBindAttribLocation);
|
||||
if(gles_glBindAttribLocation) {
|
||||
gles_glBindAttribLocation(glprogram->id, index, attribloc->name);
|
||||
errorGL();
|
||||
} else
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
GLuint APIENTRY_GL4ES gl4es_glCreateProgram(void) {
|
||||
DBG(printf("glCreateProgram()\n");)
|
||||
FLUSH_BEGINEND;
|
||||
static GLuint lastprogram = 0;
|
||||
GLuint program;
|
||||
// create the program
|
||||
LOAD_GLES2(glCreateProgram);
|
||||
if(gles_glCreateProgram) {
|
||||
program = gles_glCreateProgram();
|
||||
if(!program) {
|
||||
errorGL();
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
program = ++lastprogram;
|
||||
noerrorShim();
|
||||
}
|
||||
// store the new empty shader in the list for later use
|
||||
khint_t k;
|
||||
int ret;
|
||||
khash_t(programlist) *programs = glstate->glsl->programs;
|
||||
k = kh_get(programlist, programs, program);
|
||||
program_t *glprogram = NULL;
|
||||
if (k == kh_end(programs)){
|
||||
k = kh_put(programlist, programs, program, &ret);
|
||||
glprogram = kh_value(programs, k) = (program_t*)calloc(1, sizeof(program_t));
|
||||
} else {
|
||||
glprogram = kh_value(programs, k);
|
||||
if(glprogram->attribloc) {
|
||||
attribloc_t *m;
|
||||
kh_foreach_value(glprogram->attribloc, m,
|
||||
free(m->name); free(m);
|
||||
)
|
||||
kh_destroy(attribloclist, glprogram->attribloc);
|
||||
glprogram->attribloc = NULL;
|
||||
}
|
||||
memset(glprogram, 0, sizeof(program_t));
|
||||
}
|
||||
glprogram->id = program;
|
||||
// initialize attribloc hashmap
|
||||
khash_t(attribloclist) *attribloc = glprogram->attribloc = kh_init(attribloclist);
|
||||
// initialize uniform hashmap
|
||||
khash_t(uniformlist) *uniform = glprogram->uniform = kh_init(uniformlist);
|
||||
// all done
|
||||
return program;
|
||||
}
|
||||
|
||||
void actualy_deleteshader(GLuint shader);
|
||||
void actualy_detachshader(GLuint shader);
|
||||
|
||||
void deleteProgram(program_t *glprogram, khint_t k_program) {
|
||||
free(glprogram->attach);
|
||||
// clean attribloc
|
||||
if(glprogram->attribloc) {
|
||||
attribloc_t *m;
|
||||
kh_foreach_value(glprogram->attribloc, m,
|
||||
free(m->name); free(m);
|
||||
)
|
||||
kh_destroy(attribloclist, glprogram->attribloc);
|
||||
glprogram->attribloc = NULL;
|
||||
}
|
||||
// clean uniform list
|
||||
if(glprogram->uniform) {
|
||||
uniform_t *m;
|
||||
kh_foreach_value(glprogram->uniform, m,
|
||||
free(m->name); free(m);
|
||||
)
|
||||
kh_destroy(uniformlist, glprogram->uniform);
|
||||
glprogram->uniform = NULL;
|
||||
}
|
||||
// clean cache
|
||||
if(glprogram->cache.cache)
|
||||
free(glprogram->cache.cache);
|
||||
// clean fpe cache if it exist
|
||||
if(glprogram->fpe_cache)
|
||||
fpe_disposeCache((fpe_cache_t*)glprogram->fpe_cache, 1);
|
||||
// delete program
|
||||
kh_del(programlist, glstate->glsl->programs, k_program);
|
||||
free(glprogram);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDeleteProgram(GLuint program) {
|
||||
DBG(printf("glDeleteProgram(%d)\n", program);)
|
||||
if(!glstate) return; // in case a program delete shaders after deleteing all context
|
||||
FLUSH_BEGINEND;
|
||||
CHECK_PROGRAM(void, program)
|
||||
// send to hardware
|
||||
LOAD_GLES2(glDeleteProgram);
|
||||
if(gles_glDeleteProgram) {
|
||||
gles_glDeleteProgram(glprogram->id);
|
||||
errorGL();
|
||||
} else
|
||||
noerrorShim();
|
||||
// TODO: check GL ERROR to not clean in case of error?
|
||||
// clean attached shaders
|
||||
for (int i=0; i<glprogram->attach_size; i++) {
|
||||
actualy_detachshader(glprogram->attach[i]); // auto delete if marqued as delete!
|
||||
}
|
||||
deleteProgram(glprogram, k_program);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glDetachShader(GLuint program, GLuint shader) {
|
||||
DBG(printf("glDetachShader(%d, %d)\n", program, shader);)
|
||||
FLUSH_BEGINEND;
|
||||
CHECK_PROGRAM(void, program)
|
||||
CHECK_SHADER(void, shader)
|
||||
// is shader attached?
|
||||
int f = 0;
|
||||
while(f<glprogram->attach_size && glprogram->attach[f]!=shader)
|
||||
f++;
|
||||
// if program is linked, don't try anything....
|
||||
if(glprogram->linked) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
// send to hardware
|
||||
LOAD_GLES2(glDetachShader);
|
||||
if(gles_glDetachShader) {
|
||||
gles_glDetachShader(glprogram->id, glshader->id);
|
||||
errorGL();
|
||||
} else
|
||||
noerrorShim();
|
||||
// marked as detached
|
||||
actualy_detachshader(shader);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {
|
||||
DBG(printf("glGetActiveAttrib(%d, %d, %d, %p, %p, %p, %p)\n", program, index, bufSize, length, size, type, name);)
|
||||
FLUSH_BEGINEND;
|
||||
CHECK_PROGRAM(void, program)
|
||||
|
||||
if(glprogram->attribloc) {
|
||||
attribloc_t *attribloc;
|
||||
kh_foreach_value(glprogram->attribloc, attribloc,
|
||||
if(attribloc->real_index == index) {
|
||||
if(type) *type = attribloc->type;
|
||||
if(size) *size = attribloc->size;
|
||||
if(length) *length = strlen(attribloc->glname);
|
||||
if(bufSize && name) {
|
||||
strncpy(name, attribloc->glname, bufSize-1);
|
||||
name[bufSize-1] = '\0';
|
||||
}
|
||||
DBG(printf("found, type=%s, size=%d, name=%s/%s\n", PrintEnum(attribloc->type), attribloc->size, attribloc->name, attribloc->glname);)
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
);
|
||||
}
|
||||
DBG(printf("not found\n");)
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders) {
|
||||
DBG(printf("glGetAttachedShaders(%d, %d, %p, %p)\n", program, maxCount, count, shaders);)
|
||||
FLUSH_BEGINEND;
|
||||
CHECK_PROGRAM(void, program)
|
||||
|
||||
int n = glprogram->attach_size;
|
||||
if(n>maxCount) n = maxCount;
|
||||
|
||||
if (count) *count=n;
|
||||
if (shaders)
|
||||
for (int i=0; i<n; i++)
|
||||
shaders[i] = glprogram->attach[i];
|
||||
|
||||
noerrorShim();
|
||||
}
|
||||
|
||||
GLint APIENTRY_GL4ES gl4es_glGetAttribLocation(GLuint program, const GLchar *name) {
|
||||
DBG(printf("glGetAttribLocation(%d, %s)\n", program, name));
|
||||
FLUSH_BEGINEND;
|
||||
CHECK_PROGRAM(GLint, program);
|
||||
|
||||
if(!glprogram->linked) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
DBG(printf(" program unlinked: -1\n"));
|
||||
return -1;
|
||||
}
|
||||
noerrorShim();
|
||||
if(strncmp(name, "gl_", 3)==0) {
|
||||
DBG(printf(" internal attrib: -1\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rloc = -1;
|
||||
int loc = -1;
|
||||
// look in already created attribloc
|
||||
if(glprogram->attribloc) {
|
||||
attribloc_t *m;
|
||||
kh_foreach_value(glprogram->attribloc, m,
|
||||
if(strcmp(m->glname, name)==0) {
|
||||
loc = m->index;
|
||||
rloc = m->real_index;
|
||||
}
|
||||
)
|
||||
}
|
||||
// if found, just return the value, it's done...
|
||||
if(loc!=-1) {
|
||||
DBG(printf(" found in cache: %d\n", loc);)
|
||||
return loc;
|
||||
}
|
||||
// end
|
||||
DBG(printf(" asked hardware: %d\n", loc);)
|
||||
return loc;
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {
|
||||
DBG(printf("glGetActiveUniform(%d, %d, %d, %p, %p, %p, %p)\n", program, index, bufSize, length, size, type, name);)
|
||||
FLUSH_BEGINEND;
|
||||
CHECK_PROGRAM(GLvoid, program);
|
||||
|
||||
if(!glprogram->linked) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
DBG(printf(" not linked\n");)
|
||||
return;
|
||||
}
|
||||
noerrorShim();
|
||||
if(strncmp(name, "gl_", 3)==0) {
|
||||
DBG(printf(" internal uniform\n");)
|
||||
return;
|
||||
}
|
||||
|
||||
// look in uniform cache, that is filled when program is linked
|
||||
if(glprogram->uniform) {
|
||||
uniform_t *m;
|
||||
kh_foreach_value(glprogram->uniform, m,
|
||||
if(m->internal_id == index) {
|
||||
if(type) *type = m->type;
|
||||
if(size) *size = m->size;
|
||||
if(length) *length = strlen(m->name);
|
||||
if(bufSize && name) {
|
||||
strncpy(name, m->name, bufSize-1);
|
||||
name[bufSize-1] = '\0';
|
||||
}
|
||||
DBG(printf(" found %s (%zd), type=%s, size=%d\n", m->name, strlen(m->name), PrintEnum(m->type), m->size);)
|
||||
return;
|
||||
}
|
||||
);
|
||||
}
|
||||
// end
|
||||
DBG(printf(" not found\n");)
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
static const char* notlinked = "Program not linked";
|
||||
static const char* linked = "Program linked, but no shader support";
|
||||
static const char* validated = "Program validated, but no shader support";
|
||||
const char* getFakeProgramInfo(program_t* glprogram) {
|
||||
return (glprogram->linked)?((glprogram->validated)?validated:linked):notlinked;
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramInfoLog(GLuint program, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {
|
||||
DBG(printf("glGetProgramInfoLog(%d, %d, %p, %p)\n", program, maxLength, length, infoLog);)
|
||||
FLUSH_BEGINEND;
|
||||
CHECK_PROGRAM(void, program)
|
||||
|
||||
if(maxLength<0) {
|
||||
errorShim(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if(!maxLength) {
|
||||
noerrorShim();
|
||||
return;
|
||||
}
|
||||
|
||||
LOAD_GLES2(glGetProgramInfoLog);
|
||||
if(gles_glGetProgramInfoLog) {
|
||||
gles_glGetProgramInfoLog(glprogram->id, maxLength, length, infoLog);
|
||||
errorGL();
|
||||
} else {
|
||||
const char* res = getFakeProgramInfo(glprogram);
|
||||
int l = strlen(res)+1;
|
||||
if (l>maxLength) l = maxLength;
|
||||
if(length) *length = l-1;
|
||||
if(infoLog) strncpy(infoLog, res, l);
|
||||
noerrorShim();
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramiv(GLuint program, GLenum pname, GLint *params) {
|
||||
DBG(printf("glGetProgramiv(%d, %s, %p)\n", program, PrintEnum(pname), params);)
|
||||
FLUSH_BEGINEND;
|
||||
CHECK_PROGRAM(void, program)
|
||||
|
||||
LOAD_GLES2(glGetProgramiv);
|
||||
noerrorShim();
|
||||
switch(pname) {
|
||||
case GL_DELETE_STATUS:
|
||||
if(gles_glGetProgramiv) {
|
||||
gles_glGetProgramiv(glprogram->id, pname, params);
|
||||
errorGL();
|
||||
} else
|
||||
*params = GL_FALSE;
|
||||
break;
|
||||
case GL_LINK_STATUS:
|
||||
*params = glprogram->linked?GL_TRUE:GL_FALSE;
|
||||
break;
|
||||
case GL_VALIDATE_STATUS:
|
||||
*params = glprogram->valid_result;
|
||||
break;
|
||||
case GL_INFO_LOG_LENGTH:
|
||||
if(gles_glGetProgramiv) {
|
||||
gles_glGetProgramiv(glprogram->id, pname, params);
|
||||
errorGL();
|
||||
} else
|
||||
*params = strlen(getFakeProgramInfo(glprogram));
|
||||
break;
|
||||
case GL_ATTACHED_SHADERS:
|
||||
*params = glprogram->attach_size;
|
||||
break;
|
||||
case GL_ACTIVE_ATTRIBUTES:
|
||||
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
|
||||
if(gles_glGetProgramiv) {
|
||||
gles_glGetProgramiv(glprogram->id, pname, params);
|
||||
errorGL();
|
||||
} else
|
||||
*params = 0;
|
||||
break;
|
||||
case GL_ACTIVE_UNIFORMS:
|
||||
*params = (glprogram->uniform)?glprogram->num_uniform:0;
|
||||
break;
|
||||
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
|
||||
{
|
||||
int l = 0;
|
||||
uniform_t *m;
|
||||
kh_foreach_value(glprogram->uniform, m,
|
||||
if(l<strlen(m->name)+1)
|
||||
l = strlen(m->name)+1;
|
||||
)
|
||||
*params = l;
|
||||
}
|
||||
break;
|
||||
case GL_PROGRAM_BINARY_LENGTH:
|
||||
// TODO: check if extension is present
|
||||
if(gles_glGetProgramiv) {
|
||||
gles_glGetProgramiv(glprogram->id, pname, params);
|
||||
errorGL();
|
||||
} else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
|
||||
default:
|
||||
if(gles_glGetProgramiv) {
|
||||
gles_glGetProgramiv(glprogram->id, pname, params);
|
||||
errorGL();
|
||||
} else
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GLint APIENTRY_GL4ES gl4es_glGetUniformLocation(GLuint program, const GLchar *name) {
|
||||
DBG(printf("glGetUniformLocation(%d, %s)\n", program, name);)
|
||||
FLUSH_BEGINEND;
|
||||
CHECK_PROGRAM(GLint, program)
|
||||
|
||||
noerrorShim();
|
||||
int res = -1;
|
||||
if(strncmp(name, "gl_", 3)==0) {
|
||||
DBG(printf(" internal uniform: -1\n");)
|
||||
return res;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
int l = strlen(name);
|
||||
// get array (only if end with ])
|
||||
if(name[l-1]==']') {
|
||||
char * p = strrchr(name, '[');
|
||||
l = p-name;
|
||||
p++;
|
||||
while(p && *p>='0' && *p<='9') {
|
||||
index = index*10 + *(p++)-'0';
|
||||
}
|
||||
}
|
||||
if(glprogram->uniform) {
|
||||
uniform_t *m;
|
||||
kh_foreach_value(glprogram->uniform, m,
|
||||
if(strlen(m->name)==l && strncmp(m->name, name, l)==0) {
|
||||
res = m->id;
|
||||
if(index>m->size) {
|
||||
res = -1; // too big !
|
||||
} else
|
||||
res += index;
|
||||
break;
|
||||
}
|
||||
)
|
||||
}
|
||||
DBG(printf(" location: %d\n", res);)
|
||||
return res;
|
||||
}
|
||||
|
||||
GLboolean APIENTRY_GL4ES gl4es_glIsProgram(GLuint program) {
|
||||
DBG(printf("glIsProgram(%d)\n", program);)
|
||||
FLUSH_BEGINEND;
|
||||
noerrorShim();
|
||||
if(!program) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
program_t *glprogram = NULL;
|
||||
khint_t k;
|
||||
khash_t(programlist) *programs = glstate->glsl->programs;
|
||||
k = kh_get(programlist, programs, program);
|
||||
if (k != kh_end(programs))
|
||||
return GL_TRUE;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
static void clear_program(program_t *glprogram)
|
||||
{
|
||||
// clear all Attrib location cache
|
||||
if(glprogram->attribloc) {
|
||||
attribloc_t *m;
|
||||
khint_t k;
|
||||
int ret;
|
||||
//attribloc->glname must not be freed
|
||||
kh_foreach(glprogram->attribloc, k, m,
|
||||
free(m->name); free(m);
|
||||
kh_del(attribloclist, glprogram->attribloc, k);
|
||||
)
|
||||
kh_destroy(attribloclist, glprogram->attribloc);
|
||||
khash_t(attribloclist) *attribloc = glprogram->attribloc = kh_init(attribloclist);
|
||||
kh_put(attribloclist, attribloc, 1, &ret);
|
||||
kh_del(attribloclist, attribloc, 1);
|
||||
}
|
||||
// clear all Uniform cache
|
||||
glprogram->num_uniform = 0;
|
||||
if(glprogram->uniform) {
|
||||
uniform_t *m;
|
||||
khint_t k;
|
||||
kh_foreach(glprogram->uniform, k, m,
|
||||
free(m->name); free(m);
|
||||
kh_del(uniformlist, glprogram->uniform, k);
|
||||
)
|
||||
}
|
||||
glprogram->cache.size = 0; // reset cache buffer
|
||||
}
|
||||
|
||||
static void fill_program(program_t *glprogram)
|
||||
{
|
||||
LOAD_GLES(glGetError);
|
||||
LOAD_GLES2(glGetProgramiv);
|
||||
LOAD_GLES2(glGetActiveUniform);
|
||||
LOAD_GLES2(glGetUniformLocation);
|
||||
LOAD_GLES2(glGetActiveAttrib);
|
||||
LOAD_GLES2(glGetAttribLocation);
|
||||
int n=0;
|
||||
int maxsize=0;
|
||||
khint_t k;
|
||||
int ret;
|
||||
DBG(GLenum e2;)
|
||||
|
||||
// init bluitin emulation first
|
||||
builtin_Init(glprogram);
|
||||
// Grab all Uniform
|
||||
gles_glGetProgramiv(glprogram->id, GL_ACTIVE_UNIFORMS, &n);
|
||||
gles_glGetProgramiv(glprogram->id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxsize);
|
||||
khash_t(uniformlist) *uniforms = glprogram->uniform;
|
||||
uniform_t *gluniform = NULL;
|
||||
int uniform_cache = 0;
|
||||
GLint size = 0;
|
||||
GLenum type = 0;
|
||||
GLchar *name = (char*)malloc(maxsize);
|
||||
int tu_idx = 0;
|
||||
for (int i=0; i<n; i++) {
|
||||
gles_glGetActiveUniform(glprogram->id, i, maxsize, NULL, &size, &type, name);
|
||||
DBG(e2=gles_glGetError();)
|
||||
DBG(if(e2==GL_NO_ERROR))
|
||||
{
|
||||
// remove any ending "[]" that could be present
|
||||
if(name[strlen(name)-1]==']' && strrchr(name, '[')) (*strrchr(name, '['))='\0';
|
||||
GLint id = gles_glGetUniformLocation(glprogram->id, name);
|
||||
if(id!=-1) {
|
||||
for (int j = 0; j<size; j++) {
|
||||
k = kh_put(uniformlist, uniforms, id, &ret);
|
||||
gluniform = kh_value(uniforms, k) = malloc(sizeof(uniform_t));
|
||||
memset(gluniform, 0, sizeof(uniform_t));
|
||||
if(j) {
|
||||
gluniform->name = malloc(strlen(name)+1+5);
|
||||
sprintf(gluniform->name, "%s[%d]", name, j);
|
||||
} else
|
||||
gluniform->name = strdup(name);
|
||||
gluniform->id = id;
|
||||
gluniform->internal_id = i;
|
||||
gluniform->size = size-j;
|
||||
gluniform->type = type;
|
||||
gluniform->cache_offs = uniform_cache+j*uniformsize(type);
|
||||
gluniform->cache_size = uniformsize(type)*(size-j);
|
||||
gluniform->builtin = builtin_CheckUniform(glprogram, name, id, size-j);
|
||||
// TextureUnit grabbing...
|
||||
if(type==GL_SAMPLER_CUBE) {
|
||||
glprogram->texunits[tu_idx].id = id;
|
||||
glprogram->texunits[tu_idx].type=TU_CUBE;
|
||||
glprogram->texunits[tu_idx].req_tu = glprogram->texunits[tu_idx].act_tu = 0;
|
||||
++tu_idx;
|
||||
} else if (type==GL_SAMPLER_2D) {
|
||||
glprogram->texunits[tu_idx].id = id;
|
||||
glprogram->texunits[tu_idx].type=TU_TEX2D;
|
||||
glprogram->texunits[tu_idx].req_tu = glprogram->texunits[tu_idx].act_tu = 0;
|
||||
++tu_idx;
|
||||
}
|
||||
DBG(printf(" uniform #%d : \"%s\"%s type=%s size=%d\n", id, gluniform->name, gluniform->builtin?" (builtin) ":"", PrintEnum(gluniform->type), gluniform->size);)
|
||||
if(gluniform->size==1) ++glprogram->num_uniform;
|
||||
id++;
|
||||
}
|
||||
uniform_cache += uniformsize(type)*size;
|
||||
}
|
||||
}
|
||||
DBG(else printf("LIBGL: Warning, getting Uniform #%d info failed with %s\n", i, PrintEnum(e2));)
|
||||
}
|
||||
free(name);
|
||||
// reset uniform cache
|
||||
if(glprogram->cache.cap < uniform_cache) {
|
||||
glprogram->cache.cap=uniform_cache;
|
||||
glprogram->cache.cache = malloc(glprogram->cache.cap);
|
||||
}
|
||||
memset(glprogram->cache.cache, 0, glprogram->cache.cap);
|
||||
//Maybe Sampler uniform should not be initialized to 0, but to -1, to be sure the value is initialized?
|
||||
if(glprogram->uniform) {
|
||||
uniform_t *m;
|
||||
khint_t k;
|
||||
kh_foreach(glprogram->uniform, k, m,
|
||||
if(m->type == GL_SAMPLER_2D || m->type == GL_SAMPLER_CUBE)
|
||||
memset((char*)glprogram->cache.cache+m->cache_offs, 0xff, m->cache_size);
|
||||
)
|
||||
}
|
||||
|
||||
// Grab all Attrib
|
||||
gles_glGetProgramiv(glprogram->id, GL_ACTIVE_ATTRIBUTES, &n);
|
||||
gles_glGetProgramiv(glprogram->id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxsize);
|
||||
name = (char*)malloc(maxsize);
|
||||
for (int i=0; i<n; i++) {
|
||||
DBG(e2=gles_glGetError();)
|
||||
DBG(if(e2==GL_NO_ERROR))
|
||||
{
|
||||
gles_glGetActiveAttrib(glprogram->id, i, maxsize, NULL, &size, &type, name);
|
||||
GLint id = gles_glGetAttribLocation(glprogram->id, name);
|
||||
if(id!=-1) {
|
||||
attribloc_t *glattribloc = NULL;
|
||||
k = kh_put(attribloclist, glprogram->attribloc, id, &ret);
|
||||
if(ret==0) {
|
||||
// already there
|
||||
glattribloc = kh_value(glprogram->attribloc, k);
|
||||
if(glattribloc->name)
|
||||
free(glattribloc->name);
|
||||
} else {
|
||||
glattribloc = kh_value(glprogram->attribloc, k) = malloc(sizeof(attribloc_t));
|
||||
}
|
||||
memset(glattribloc, 0, sizeof(attribloc_t));
|
||||
glattribloc->name = strdup(name);
|
||||
glattribloc->glname = builtinAttribGLName(glattribloc->name);
|
||||
glattribloc->size = size;
|
||||
glattribloc->type = type;
|
||||
glattribloc->index = id;
|
||||
glattribloc->real_index = i;
|
||||
int builtin = builtin_CheckVertexAttrib(glprogram, name, id);
|
||||
glprogram->va_size[id] = n_uniform(type); // same as uniform
|
||||
DBG(printf(" attrib #%d : \"%s\"%s type=%s size=%d\n", id, glattribloc->name, builtin?" (builtin) ":"", PrintEnum(glattribloc->type), glattribloc->size);)
|
||||
}
|
||||
}
|
||||
DBG(else printf("LIBGL: Warning, getting Attrib #%d info failed with %s\n", i, PrintEnum(e2));)
|
||||
}
|
||||
free(name);
|
||||
}
|
||||
|
||||
int gl4es_useProgramBinary(GLuint program, int length, GLenum format, const void* binary)
|
||||
{
|
||||
if(hardext.prgbin_n==0)
|
||||
return 0;
|
||||
DBG(printf("useProgramBinary(%d, %d, %d, %p)\n", program, length, format, binary);)
|
||||
CHECK_PROGRAM(int, program)
|
||||
noerrorShim();
|
||||
|
||||
clear_program(glprogram);
|
||||
|
||||
LOAD_GLES_OES(glProgramBinary);
|
||||
LOAD_GLES2(glGetProgramiv);
|
||||
|
||||
gles_glProgramBinary(glprogram->id, format, binary, length);
|
||||
|
||||
gles_glGetProgramiv(glprogram->id, GL_LINK_STATUS, &glprogram->linked);
|
||||
DBG(printf(" link status = %d\n", glprogram->linked);)
|
||||
if(glprogram->linked) {
|
||||
fill_program(glprogram);
|
||||
} else {
|
||||
// should DBG the linker error?
|
||||
DBG(printf(" Load failed!\n");)
|
||||
glprogram->linked = 0;
|
||||
errorGL();
|
||||
}
|
||||
return glprogram->linked;
|
||||
}
|
||||
|
||||
int gl4es_getProgramBinary(GLuint program, int *length, GLenum *format, void** binary)
|
||||
{
|
||||
if(hardext.prgbin_n==0)
|
||||
return 0;
|
||||
DBG(printf("getProgramBinary(%d, %p, %p, %p)\n", program, length, format, binary);)
|
||||
CHECK_PROGRAM(int, program)
|
||||
noerrorShim();
|
||||
|
||||
LOAD_GLES_OES(glGetProgramBinary);
|
||||
LOAD_GLES2(glGetProgramiv);
|
||||
|
||||
int l;
|
||||
gles_glGetProgramiv(glprogram->id, GL_PROGRAM_BINARY_LENGTH_OES, &l);
|
||||
if(!l)
|
||||
return 0;
|
||||
|
||||
*binary = malloc(l);
|
||||
gles_glGetProgramBinary(glprogram->id, l, length, format, *binary);
|
||||
|
||||
return (*length);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)
|
||||
{
|
||||
if(hardext.prgbin_n==0) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
DBG(printf("glGetProgramBinary(%d, %d, %p, %p, %p)\n", program, bufSize, length, binaryFormat, binary);)
|
||||
CHECK_PROGRAM(void, program)
|
||||
LOAD_GLES_OES(glGetProgramBinary);
|
||||
gles_glGetProgramBinary(glprogram->id, bufSize, length, binaryFormat, binary);
|
||||
errorGL();
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
|
||||
{
|
||||
if(hardext.prgbin_n==0) {
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
DBG(printf("glProgramBinary(%d, %d, %p, %d)\n", program, binaryFormat, binary, length);)
|
||||
if(gl4es_useProgramBinary(program, length, binaryFormat, binary))
|
||||
noerrorShim();
|
||||
else
|
||||
errorShim(GL_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glLinkProgram(GLuint program) {
|
||||
DBG(printf("glLinkProgram(%d)\n", program);)
|
||||
FLUSH_BEGINEND;
|
||||
CHECK_PROGRAM(void, program)
|
||||
noerrorShim();
|
||||
|
||||
clear_program(glprogram);
|
||||
|
||||
// check if attached shaders are compatible in term of varying...
|
||||
shaderconv_need_t needs = {0};
|
||||
needs.need_texcoord = -1;
|
||||
// first get the compatible need
|
||||
for (int i=0; i<glprogram->attach_size; i++) {
|
||||
accumShaderNeeds(glprogram->attach[i], &needs);
|
||||
}
|
||||
// create one vertex shader if needed!
|
||||
if(!glprogram->last_vert) {
|
||||
glprogram->default_need = (shaderconv_need_t*)malloc(sizeof(shaderconv_need_t));
|
||||
memcpy(glprogram->default_need, &needs, sizeof(shaderconv_need_t));
|
||||
glprogram->default_vertex = 1;
|
||||
GLenum vtx = gl4es_glCreateShader(GL_VERTEX_SHADER);
|
||||
gl4es_glShaderSource(vtx, 1, fpe_VertexShader(&needs, NULL), NULL);
|
||||
gl4es_glCompileShader(vtx);
|
||||
gl4es_glAttachShader(glprogram->id, vtx);
|
||||
}
|
||||
// create one fragment shader if needed!
|
||||
if(!glprogram->last_frag) {
|
||||
glprogram->default_need = (shaderconv_need_t*)malloc(sizeof(shaderconv_need_t));
|
||||
memcpy(glprogram->default_need, &needs, sizeof(shaderconv_need_t));
|
||||
glprogram->default_fragment = 1;
|
||||
GLenum vtx = gl4es_glCreateShader(GL_FRAGMENT_SHADER);
|
||||
gl4es_glShaderSource(vtx, 1, fpe_FragmentShader(&needs, NULL), NULL);
|
||||
gl4es_glCompileShader(vtx);
|
||||
gl4es_glAttachShader(glprogram->id, vtx);
|
||||
}
|
||||
int compatible = 1;
|
||||
// now is everyone ok?
|
||||
for (int i=0; i<glprogram->attach_size && compatible; i++) {
|
||||
compatible = isShaderCompatible(glprogram->attach[i], &needs);
|
||||
}
|
||||
// someone is not compatible, redoing shaders...
|
||||
if(!compatible) {
|
||||
DBG(printf("Need to redo some shaders...\n");)
|
||||
for (int i=0; i<glprogram->attach_size; i++) {
|
||||
redoShader(glprogram->attach[i], &needs);
|
||||
}
|
||||
}
|
||||
// check if Built-in VA are used, and if so, bind them to their proper location
|
||||
if(glprogram->last_vert)
|
||||
for (int i=0; i<ATT_MAX; ++i) {
|
||||
const char* attribute = hasBuiltinAttrib(glprogram->last_vert->converted, i);
|
||||
if(attribute)
|
||||
gl4es_glBindAttribLocation(glprogram->id, i, attribute);
|
||||
}
|
||||
// ok, continue with linking
|
||||
LOAD_GLES2(glLinkProgram);
|
||||
if(gles_glLinkProgram) {
|
||||
LOAD_GLES(glGetError);
|
||||
LOAD_GLES2(glGetProgramiv);
|
||||
gles_glLinkProgram(glprogram->id);
|
||||
GLenum err = gles_glGetError();
|
||||
// Get Link Status
|
||||
gles_glGetProgramiv(glprogram->id, GL_LINK_STATUS, &glprogram->linked);
|
||||
DBG(printf(" link status = %d\n", glprogram->linked);)
|
||||
if(glprogram->linked) {
|
||||
fill_program(glprogram);
|
||||
noerrorShimNoPurge();
|
||||
} else {
|
||||
// should DBG the linker error?
|
||||
DBG(printf(" Link failled!\n");)
|
||||
glprogram->linked = 0;
|
||||
errorShim(err);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
noerrorShim();
|
||||
}
|
||||
glprogram->linked = 1;
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glUseProgram(GLuint program) {
|
||||
DBG(printf("glUseProgram(%d) old=%d\n", program, glstate->glsl->program);)
|
||||
PUSH_IF_COMPILING(glUseProgram);
|
||||
if(program==0) {
|
||||
glstate->glsl->program=0;
|
||||
glstate->glsl->glprogram=NULL;
|
||||
return;
|
||||
}
|
||||
CHECK_PROGRAM(void, program)
|
||||
noerrorShim();
|
||||
DBG(printf("program id=%d\n", glprogram->id);)
|
||||
|
||||
glstate->glsl->program=glprogram->id;
|
||||
glstate->glsl->glprogram=glprogram;
|
||||
}
|
||||
|
||||
void APIENTRY_GL4ES gl4es_glValidateProgram(GLuint program) {
|
||||
CHECK_PROGRAM(void, program)
|
||||
FLUSH_BEGINEND;
|
||||
noerrorShim();
|
||||
|
||||
LOAD_GLES2(glValidateProgram);
|
||||
if(gles_glValidateProgram) {
|
||||
LOAD_GLES(glGetError);
|
||||
LOAD_GLES2(glGetProgramiv);
|
||||
gles_glValidateProgram(glprogram->id);
|
||||
GLenum err = gles_glGetError();
|
||||
gles_glGetProgramiv(glprogram->id, GL_VALIDATE_STATUS, (GLint *) &glprogram->valid_result);
|
||||
errorShim(err);
|
||||
// TODO: grab all Uniform and Attrib of the program
|
||||
} else {
|
||||
noerrorShim();
|
||||
}
|
||||
glprogram->validated = 1;
|
||||
}
|
||||
|
||||
|
||||
AliasExport(void,glAttachShader,,(GLuint program, GLuint shader));
|
||||
AliasExport(void,glBindAttribLocation,,(GLuint program, GLuint index, const GLchar *name));
|
||||
AliasExport_V(GLuint,glCreateProgram);
|
||||
AliasExport(void,glDeleteProgram,,(GLuint program));
|
||||
AliasExport(void,glDetachShader,,(GLuint program, GLuint shader));
|
||||
AliasExport(void,glGetActiveAttrib,,(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name));
|
||||
AliasExport(void,glGetAttachedShaders,,(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders));
|
||||
AliasExport(GLint,glGetAttribLocation,,(GLuint program, const GLchar *name));
|
||||
AliasExport(void,glGetActiveUniform,,(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name));
|
||||
AliasExport(void,glGetProgramiv,,(GLuint program, GLenum pname, GLint *params));
|
||||
AliasExport(GLint,glGetUniformLocation,,(GLuint program, const GLchar *name));
|
||||
AliasExport(GLboolean,glIsProgram,,(GLuint program));
|
||||
AliasExport(void,glLinkProgram,,(GLuint program));
|
||||
AliasExport(void,glUseProgram,,(GLuint program));
|
||||
AliasExport(void,glValidateProgram,,(GLuint program));
|
||||
AliasExport(void,glGetProgramInfoLog,,(GLuint program, GLsizei maxLength, GLsizei *length, GLchar *infoLog));
|
||||
|
||||
AliasExport(void,glGetProgramBinary,,(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary));
|
||||
AliasExport(void,glProgramBinary,,(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length));
|
||||
|
||||
|
||||
// ================ GL_ARB_vertex_shader =================
|
||||
AliasExport(GLvoid,glBindAttribLocation,ARB,(GLhandleARB programObj, GLuint index, const GLcharARB *name));
|
||||
|
||||
AliasExport(GLvoid,glGetActiveAttrib,ARB,(GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name));
|
||||
|
||||
AliasExport(GLint,glGetAttribLocation,ARB,(GLhandleARB programObj, const GLcharARB *name));
|
||||
|
||||
// ============== GL_ARB_shader_objects ==================
|
||||
// some are not simple alias but wrappers
|
||||
GLvoid APIENTRY_GL4ES gl4es_glDeleteObject(GLhandleARB obj) {
|
||||
if(!obj)
|
||||
return;
|
||||
// find type of obj (shader or program)
|
||||
program_t *glprogram = NULL;
|
||||
khint_t k_program;
|
||||
{
|
||||
khash_t(programlist) *programs = glstate->glsl->programs;
|
||||
k_program = kh_get(programlist, programs, obj);
|
||||
if (k_program != kh_end(programs))
|
||||
glprogram = kh_value(programs, k_program);
|
||||
}
|
||||
if(glprogram)
|
||||
gl4es_glDeleteProgram(obj);
|
||||
else
|
||||
gl4es_glDeleteShader(obj);
|
||||
}
|
||||
|
||||
GLhandleARB APIENTRY_GL4ES gl4es_glGetHandle(GLenum pname) {
|
||||
FLUSH_BEGINEND;
|
||||
if(pname!=GL_PROGRAM_OBJECT_ARB) {
|
||||
errorShim(GL_INVALID_ENUM);
|
||||
return 0;
|
||||
}
|
||||
return glstate->glsl->program;
|
||||
}
|
||||
|
||||
GLvoid APIENTRY_GL4ES gl4es_glDetachObject(GLhandleARB containerObj, GLhandleARB attachedObj) {
|
||||
gl4es_glDetachShader(containerObj, attachedObj);
|
||||
}
|
||||
|
||||
GLhandleARB APIENTRY_GL4ES gl4es_glCreateProgramObject(GLvoid) {
|
||||
return gl4es_glCreateProgram();
|
||||
}
|
||||
|
||||
GLvoid APIENTRY_GL4ES gl4es_glAttachObject(GLhandleARB containerObj, GLhandleARB obj) {
|
||||
gl4es_glAttachShader(containerObj, obj);
|
||||
}
|
||||
|
||||
GLvoid APIENTRY_GL4ES gl4es_glUseProgramObject(GLhandleARB programObj) {
|
||||
gl4es_glUseProgram(programObj);
|
||||
}
|
||||
|
||||
GLvoid APIENTRY_GL4ES gl4es_glGetObjectParameterfv(GLhandleARB obj, GLenum pname, GLfloat *params) {
|
||||
if(!obj)
|
||||
return;
|
||||
// find type of obj (shader or program)
|
||||
program_t *glprogram = NULL;
|
||||
khint_t k_program;
|
||||
{
|
||||
khash_t(programlist) *programs = glstate->glsl->programs;
|
||||
k_program = kh_get(programlist, programs, obj);
|
||||
if (k_program != kh_end(programs))
|
||||
glprogram = kh_value(programs, k_program);
|
||||
}
|
||||
// float, really?
|
||||
GLint p[4];
|
||||
if(glprogram)
|
||||
gl4es_glGetProgramiv(obj, pname, p);
|
||||
else
|
||||
gl4es_glGetShaderiv(obj, pname, p);
|
||||
|
||||
params[0] = p[0]; // only 1-sized array here, right?
|
||||
}
|
||||
GLvoid APIENTRY_GL4ES gl4es_glGetObjectParameteriv(GLhandleARB obj, GLenum pname, GLint *params) {
|
||||
if(!obj)
|
||||
return;
|
||||
// find type of obj (shader or program)
|
||||
program_t *glprogram = NULL;
|
||||
khint_t k_program;
|
||||
{
|
||||
khash_t(programlist) *programs = glstate->glsl->programs;
|
||||
k_program = kh_get(programlist, programs, obj);
|
||||
if (k_program != kh_end(programs))
|
||||
glprogram = kh_value(programs, k_program);
|
||||
}
|
||||
if(glprogram)
|
||||
gl4es_glGetProgramiv(obj, pname, params);
|
||||
else
|
||||
gl4es_glGetShaderiv(obj, pname, params);
|
||||
// hack, some program don't take into account that the lenght return by GL_OBJECT_INFO_LOG_LENGTH_ARB exclude the '\0'.. so adding it here
|
||||
if(pname==GL_INFO_LOG_LENGTH)
|
||||
(*params)++;
|
||||
}
|
||||
|
||||
GLvoid APIENTRY_GL4ES gl4es_glGetInfoLog(GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog) {
|
||||
if(!obj)
|
||||
return;
|
||||
// find type of obj (shader or program)
|
||||
program_t *glprogram = NULL;
|
||||
khint_t k_program;
|
||||
{
|
||||
khash_t(programlist) *programs = glstate->glsl->programs;
|
||||
k_program = kh_get(programlist, programs, obj);
|
||||
if (k_program != kh_end(programs))
|
||||
glprogram = kh_value(programs, k_program);
|
||||
}
|
||||
|
||||
if(glprogram)
|
||||
gl4es_glGetProgramInfoLog(obj, maxLength, length, infoLog);
|
||||
else
|
||||
gl4es_glGetShaderInfoLog(obj, maxLength, length, infoLog);
|
||||
}
|
||||
|
||||
GLvoid APIENTRY_GL4ES gl4es_glGetAttachedObjects(GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj) {
|
||||
gl4es_glGetAttachedShaders(containerObj, maxCount, count, obj);
|
||||
}
|
||||
|
||||
AliasExport(GLvoid,glDeleteObject,ARB,(GLhandleARB obj));
|
||||
AliasExport(GLhandleARB,glGetHandle,ARB,(GLenum pname));
|
||||
AliasExport(GLvoid,glDetachObject,ARB,(GLhandleARB containerObj, GLhandleARB attachedObj));
|
||||
AliasExport(GLhandleARB,glCreateProgramObject,ARB,());
|
||||
AliasExport(GLvoid,glAttachObject,ARB,(GLhandleARB containerObj, GLhandleARB obj));
|
||||
AliasExport(GLvoid,glLinkProgram,ARB,(GLhandleARB programObj));
|
||||
AliasExport(GLvoid,glUseProgramObject,ARB,(GLhandleARB programObj));
|
||||
AliasExport(GLvoid,glValidateProgram,ARB,(GLhandleARB programObj));
|
||||
AliasExport(GLvoid,glGetObjectParameterfv,ARB,(GLhandleARB obj, GLenum pname, GLfloat *params));
|
||||
AliasExport(GLvoid,glGetObjectParameteriv,ARB,(GLhandleARB obj, GLenum pname, GLint *params));
|
||||
AliasExport(GLvoid,glGetInfoLog,ARB,(GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog));
|
||||
AliasExport(GLvoid,glGetAttachedObjects,ARB,(GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj));
|
||||
AliasExport(GLint,glGetUniformLocation,ARB,(GLhandleARB programObj, const GLcharARB *name));
|
||||
AliasExport(GLvoid,glGetActiveUniform,ARB,(GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name));
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user