Initial commit of libAgl2 using Pixelflinger2 in external/mesa3d
Somewhat functional, refer to README for details. Need to enable Android.mk to build. It builds libGLES_android.so, which needs to replace the one in system/lib/egl built by libagl. Change-Id: Iec3aaa8f3963a4185d81955cd24019eb0c4a5850 Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
parent
b8759993d0
commit
aa1f54d78f
58
opengl/libagl2/Android.mk
Normal file
58
opengl/libagl2/Android.mk
Normal file
@ -0,0 +1,58 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
#
|
||||
# Build the software OpenGL ES library
|
||||
#
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
src/api.cpp \
|
||||
src/egl.cpp \
|
||||
src/get.cpp \
|
||||
src/shader.cpp \
|
||||
src/state.cpp \
|
||||
src/texture.cpp \
|
||||
src/vertex.cpp
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(LOCAL_PATH) \
|
||||
external/mesa3d/include \
|
||||
external/mesa3d/src \
|
||||
external/stlport/stlport \
|
||||
bionic
|
||||
|
||||
#LOCAL_CFLAGS += -DLOG_TAG=\"libagl2\"
|
||||
#LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
|
||||
#LOCAL_CFLAGS += -fvisibility=hidden
|
||||
#LOCAL_CFLAGS += -O0 -g -DDEBUG -UNDEBUG
|
||||
LOCAL_CFLAGS += -O3
|
||||
LOCAL_STATIC_LIBRARIES := libMesa
|
||||
LOCAL_SHARED_LIBRARIES := libstlport libcutils libhardware libutils libbcc libdl
|
||||
LOCAL_LDLIBS := -lpthread
|
||||
|
||||
ifeq ($(TARGET_ARCH),arm)
|
||||
LOCAL_CFLAGS += -fstrict-aliasing
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
|
||||
LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
|
||||
endif
|
||||
|
||||
ifneq ($(TARGET_SIMULATOR),true)
|
||||
# we need to access the private Bionic header <bionic_tls.h>
|
||||
# on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER
|
||||
# behavior from the bionic Android.mk file
|
||||
ifeq ($(TARGET_ARCH)-$(ARCH_ARM_HAVE_TLS_REGISTER),arm-true)
|
||||
LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
|
||||
endif
|
||||
LOCAL_C_INCLUDES += bionic/libc/private
|
||||
endif
|
||||
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
|
||||
#replace libagl for now
|
||||
LOCAL_MODULE:= libGLES_android
|
||||
LOCAL_MODULE_TAGS := eng
|
||||
|
||||
## Disable this makefile for now
|
||||
## include $(BUILD_SHARED_LIBRARY)
|
26
opengl/libagl2/README
Normal file
26
opengl/libagl2/README
Normal file
@ -0,0 +1,26 @@
|
||||
libAgl2 provides software GL ES 2.0 implementation using Pixelflinger2 in external/mesa3d
|
||||
|
||||
To build, enable Android.mk, which builds libGLES_android.so, then replace the one built from libAgl in system/lib/egl.
|
||||
ES 1.0 functions are not implemented and will cause exit, so do not setprop debug.egl.hw 0 until launcher is loaded.
|
||||
|
||||
All functions have little to none error checking.
|
||||
Not thread safe, Pixelflinger2 uses some static data.
|
||||
|
||||
Most shader functions are implemented, however, most Get* functions for shaders/programs/uniforms/attribs are not.
|
||||
No name system for shaders/programs, just using the pointers as names.
|
||||
|
||||
Basic glTexImage2D, glTexSubImage2D, glCopyImage2D and glCopySubImage2D are implemented, with a range of 8/16/24/32bpp formats.
|
||||
Cube map support is minimal. No mipmapping.
|
||||
TexParameter is mostly implemented, supports texcoord wrap modes, and only linear for both min and mag, or nearest for both min and mag filtering.
|
||||
Texture names are implemented, but bad.
|
||||
|
||||
Frame buffer and render buffers are not implemented.
|
||||
|
||||
Depth and stencil are implemented, but not tested.
|
||||
Blending seems to work.
|
||||
Colorbuffer supports RGBA_8888 and RGB_565.
|
||||
|
||||
Vertex buffer objects are implemented.
|
||||
Some GL_TRIANGLES and GL_TRIANGLE_STRIPS modes for glDrawArrays and glDrawElements are implemented, but vertex order is probably wrong so culling is disabled.
|
||||
|
||||
Basic apps should work, and some libhwui should work, except for frame buffer operations, which will cause exit.
|
108
opengl/libagl2/libagl2.project
Normal file
108
opengl/libagl2/libagl2.project
Normal file
@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<CodeLite_Project Name="libagl2" InternalType="Console">
|
||||
<Plugins>
|
||||
<Plugin Name="qmake">
|
||||
<![CDATA[00010001N0005Debug000000000000]]>
|
||||
</Plugin>
|
||||
</Plugins>
|
||||
<Description/>
|
||||
<Dependencies/>
|
||||
<Dependencies Name="Release"/>
|
||||
<VirtualDirectory Name="src">
|
||||
<File Name="src/egl.cpp"/>
|
||||
<File Name="src/api.cpp"/>
|
||||
<File Name="src/gles2context.h"/>
|
||||
<File Name="src/shader.cpp"/>
|
||||
<File Name="src/vertex.cpp"/>
|
||||
<File Name="src/state.cpp"/>
|
||||
<File Name="src/texture.cpp"/>
|
||||
<File Name="src/get.cpp"/>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="include"/>
|
||||
<Settings Type="Executable">
|
||||
<Configuration Name="Debug" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="Executable" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
|
||||
<Compiler Options="-g;-m32" Required="yes" PreCompiledHeader="">
|
||||
<IncludePath Value="/usr/include/c++/4.4"/>
|
||||
<IncludePath Value="/usr/include/c++/4.4/ext"/>
|
||||
<IncludePath Value="."/>
|
||||
<IncludePath Value="include"/>
|
||||
<IncludePath Value="../../../../external/mesa3d/include"/>
|
||||
<IncludePath Value="../../../../external/mesa3d/src"/>
|
||||
<IncludePath Value="../../../../hardware/libhardware/include"/>
|
||||
<IncludePath Value="../../../../system/core/include"/>
|
||||
<IncludePath Value="../include"/>
|
||||
<IncludePath Value="../../include"/>
|
||||
<IncludePath Value="../../../../development/ndk/platforms/android-9/include"/>
|
||||
<IncludePath Value="../../../../bionic/libc/include/"/>
|
||||
<IncludePath Value="/../../../../development/ndk/platforms/android-5/arch-x86/include"/>
|
||||
<IncludePath Value="../../../../bionic/libc/arch-x86/include"/>
|
||||
<IncludePath Value="../../../../bionic/libc/kernel/arch-x86"/>
|
||||
<IncludePath Value="/../../../../external/kernel-headers/original"/>
|
||||
<IncludePath Value="../../../../prebuilt/ndk/android-ndk-r4/platforms/android-8/arch-x86/usr/include"/>
|
||||
</Compiler>
|
||||
<Linker Options="-m32;-lstdc++" Required="yes"/>
|
||||
<ResourceCompiler Options="" Required="no"/>
|
||||
<General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Debug" Command="./$(ProjectName)" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
|
||||
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
|
||||
<PostConnectCommands/>
|
||||
<StartupCommands/>
|
||||
</Debugger>
|
||||
<PreBuild/>
|
||||
<PostBuild/>
|
||||
<CustomBuild Enabled="no">
|
||||
<RebuildCommand/>
|
||||
<CleanCommand/>
|
||||
<BuildCommand/>
|
||||
<PreprocessFileCommand/>
|
||||
<SingleFileCommand/>
|
||||
<MakefileGenerationCommand/>
|
||||
<ThirdPartyToolName>None</ThirdPartyToolName>
|
||||
<WorkingDirectory/>
|
||||
</CustomBuild>
|
||||
<AdditionalRules>
|
||||
<CustomPostBuild/>
|
||||
<CustomPreBuild/>
|
||||
</AdditionalRules>
|
||||
</Configuration>
|
||||
<Configuration Name="Release" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
|
||||
<Compiler Options="" Required="yes" PreCompiledHeader="">
|
||||
<IncludePath Value="."/>
|
||||
</Compiler>
|
||||
<Linker Options="-O2" Required="yes"/>
|
||||
<ResourceCompiler Options="" Required="no"/>
|
||||
<General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Release" Command="./$(ProjectName)" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
|
||||
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
|
||||
<PostConnectCommands/>
|
||||
<StartupCommands/>
|
||||
</Debugger>
|
||||
<PreBuild/>
|
||||
<PostBuild/>
|
||||
<CustomBuild Enabled="no">
|
||||
<RebuildCommand/>
|
||||
<CleanCommand/>
|
||||
<BuildCommand/>
|
||||
<PreprocessFileCommand/>
|
||||
<SingleFileCommand/>
|
||||
<MakefileGenerationCommand/>
|
||||
<ThirdPartyToolName>None</ThirdPartyToolName>
|
||||
<WorkingDirectory/>
|
||||
</CustomBuild>
|
||||
<AdditionalRules>
|
||||
<CustomPostBuild/>
|
||||
<CustomPreBuild/>
|
||||
</AdditionalRules>
|
||||
</Configuration>
|
||||
<GlobalSettings>
|
||||
<Compiler Options="">
|
||||
<IncludePath Value="."/>
|
||||
</Compiler>
|
||||
<Linker Options="">
|
||||
<LibraryPath Value="."/>
|
||||
</Linker>
|
||||
<ResourceCompiler Options=""/>
|
||||
</GlobalSettings>
|
||||
</Settings>
|
||||
<Dependencies Name="Debug">
|
||||
<Project Name="libMesa"/>
|
||||
</Dependencies>
|
||||
</CodeLite_Project>
|
266
opengl/libagl2/src/api.cpp
Normal file
266
opengl/libagl2/src/api.cpp
Normal file
@ -0,0 +1,266 @@
|
||||
#include "gles2context.h"
|
||||
|
||||
#define API_ENTRY
|
||||
#define CALL_GL_API(NAME,...) LOGD("?"#NAME); assert(0);
|
||||
#define CALL_GL_API_RETURN(NAME,...) LOGD("?"#NAME); assert(0); return 0;
|
||||
|
||||
|
||||
void API_ENTRY(glBindFramebuffer)(GLenum target, GLuint framebuffer)
|
||||
{
|
||||
CALL_GL_API(glBindFramebuffer, target, framebuffer);
|
||||
}
|
||||
void API_ENTRY(glBindRenderbuffer)(GLenum target, GLuint renderbuffer)
|
||||
{
|
||||
CALL_GL_API(glBindRenderbuffer, target, renderbuffer);
|
||||
}
|
||||
GLenum API_ENTRY(glCheckFramebufferStatus)(GLenum target)
|
||||
{
|
||||
CALL_GL_API_RETURN(glCheckFramebufferStatus, target);
|
||||
}
|
||||
void API_ENTRY(glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
|
||||
{
|
||||
CALL_GL_API(glColorMask, red, green, blue, alpha);
|
||||
}
|
||||
void API_ENTRY(glDeleteFramebuffers)(GLsizei n, const GLuint* framebuffers)
|
||||
{
|
||||
CALL_GL_API(glDeleteFramebuffers, n, framebuffers);
|
||||
}
|
||||
void API_ENTRY(glDeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers)
|
||||
{
|
||||
CALL_GL_API(glDeleteRenderbuffers, n, renderbuffers);
|
||||
}
|
||||
void API_ENTRY(glDepthFunc)(GLenum func)
|
||||
{
|
||||
CALL_GL_API(glDepthFunc, func);
|
||||
}
|
||||
void API_ENTRY(glDepthMask)(GLboolean flag)
|
||||
{
|
||||
CALL_GL_API(glDepthMask, flag);
|
||||
}
|
||||
void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar)
|
||||
{
|
||||
CALL_GL_API(glDepthRangef, zNear, zFar);
|
||||
}
|
||||
void API_ENTRY(glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
|
||||
{
|
||||
CALL_GL_API(glFramebufferRenderbuffer, target, attachment, renderbuffertarget, renderbuffer);
|
||||
}
|
||||
void API_ENTRY(glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
|
||||
{
|
||||
CALL_GL_API(glFramebufferTexture2D, target, attachment, textarget, texture, level);
|
||||
}
|
||||
void glGenerateMipmap(GLenum target)
|
||||
{
|
||||
//CALL_GL_API(glGenerateMipmap, target);
|
||||
LOGD("agl2: glGenerateMipmap not implemented");
|
||||
}
|
||||
void API_ENTRY(glGenFramebuffers)(GLsizei n, GLuint* framebuffers)
|
||||
{
|
||||
CALL_GL_API(glGenFramebuffers, n, framebuffers);
|
||||
}
|
||||
void API_ENTRY(glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers)
|
||||
{
|
||||
CALL_GL_API(glGenRenderbuffers, n, renderbuffers);
|
||||
}
|
||||
void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
|
||||
{
|
||||
CALL_GL_API(glGetActiveAttrib, program, index, bufsize, length, size, type, name);
|
||||
}
|
||||
void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
|
||||
{
|
||||
CALL_GL_API(glGetActiveUniform, program, index, bufsize, length, size, type, name);
|
||||
}
|
||||
void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
|
||||
{
|
||||
CALL_GL_API(glGetAttachedShaders, program, maxcount, count, shaders);
|
||||
}
|
||||
void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean* params)
|
||||
{
|
||||
CALL_GL_API(glGetBooleanv, pname, params);
|
||||
}
|
||||
void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params)
|
||||
{
|
||||
CALL_GL_API(glGetBufferParameteriv, target, pname, params);
|
||||
}
|
||||
GLenum glGetError(void)
|
||||
{
|
||||
puts("agl2: glGetError");
|
||||
return GL_NO_ERROR;
|
||||
//CALL_GL_API_RETURN(glGetError);
|
||||
}
|
||||
void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat* params)
|
||||
{
|
||||
CALL_GL_API(glGetFloatv, pname, params);
|
||||
}
|
||||
void API_ENTRY(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params)
|
||||
{
|
||||
CALL_GL_API(glGetFramebufferAttachmentParameteriv, target, attachment, pname, params);
|
||||
}
|
||||
void API_ENTRY(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params)
|
||||
{
|
||||
CALL_GL_API(glGetRenderbufferParameteriv, target, pname, params);
|
||||
}
|
||||
void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
|
||||
{
|
||||
CALL_GL_API(glGetShaderPrecisionFormat, shadertype, precisiontype, range, precision);
|
||||
}
|
||||
void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
|
||||
{
|
||||
CALL_GL_API(glGetShaderSource, shader, bufsize, length, source);
|
||||
}
|
||||
void API_ENTRY(glGetUniformfv)(GLuint program, GLint location, GLfloat* params)
|
||||
{
|
||||
CALL_GL_API(glGetUniformfv, program, location, params);
|
||||
}
|
||||
void API_ENTRY(glGetUniformiv)(GLuint program, GLint location, GLint* params)
|
||||
{
|
||||
CALL_GL_API(glGetUniformiv, program, location, params);
|
||||
}
|
||||
void API_ENTRY(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params)
|
||||
{
|
||||
CALL_GL_API(glGetVertexAttribfv, index, pname, params);
|
||||
}
|
||||
void API_ENTRY(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params)
|
||||
{
|
||||
CALL_GL_API(glGetVertexAttribiv, index, pname, params);
|
||||
}
|
||||
void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid** pointer)
|
||||
{
|
||||
CALL_GL_API(glGetVertexAttribPointerv, index, pname, pointer);
|
||||
}
|
||||
GLboolean API_ENTRY(glIsBuffer)(GLuint buffer)
|
||||
{
|
||||
CALL_GL_API_RETURN(glIsBuffer, buffer);
|
||||
}
|
||||
GLboolean API_ENTRY(glIsEnabled)(GLenum cap)
|
||||
{
|
||||
CALL_GL_API_RETURN(glIsEnabled, cap);
|
||||
}
|
||||
GLboolean API_ENTRY(glIsFramebuffer)(GLuint framebuffer)
|
||||
{
|
||||
CALL_GL_API_RETURN(glIsFramebuffer, framebuffer);
|
||||
}
|
||||
GLboolean API_ENTRY(glIsProgram)(GLuint program)
|
||||
{
|
||||
CALL_GL_API_RETURN(glIsProgram, program);
|
||||
}
|
||||
GLboolean API_ENTRY(glIsRenderbuffer)(GLuint renderbuffer)
|
||||
{
|
||||
CALL_GL_API_RETURN(glIsRenderbuffer, renderbuffer);
|
||||
}
|
||||
GLboolean API_ENTRY(glIsShader)(GLuint shader)
|
||||
{
|
||||
CALL_GL_API_RETURN(glIsShader, shader);
|
||||
}
|
||||
void API_ENTRY(glLineWidth)(GLfloat width)
|
||||
{
|
||||
CALL_GL_API(glLineWidth, width);
|
||||
}
|
||||
void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units)
|
||||
{
|
||||
CALL_GL_API(glPolygonOffset, factor, units);
|
||||
}
|
||||
void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
|
||||
{
|
||||
CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
|
||||
}
|
||||
void API_ENTRY(glReleaseShaderCompiler)(void)
|
||||
{
|
||||
CALL_GL_API(glReleaseShaderCompiler);
|
||||
}
|
||||
void API_ENTRY(glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
|
||||
{
|
||||
CALL_GL_API(glRenderbufferStorage, target, internalformat, width, height);
|
||||
}
|
||||
void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert)
|
||||
{
|
||||
CALL_GL_API(glSampleCoverage, value, invert);
|
||||
}
|
||||
void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
|
||||
{
|
||||
CALL_GL_API(glShaderBinary, n, shaders, binaryformat, binary, length);
|
||||
}
|
||||
void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask)
|
||||
{
|
||||
CALL_GL_API(glStencilFunc, func, ref, mask);
|
||||
}
|
||||
void API_ENTRY(glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask)
|
||||
{
|
||||
CALL_GL_API(glStencilFuncSeparate, face, func, ref, mask);
|
||||
}
|
||||
void API_ENTRY(glStencilMask)(GLuint mask)
|
||||
{
|
||||
CALL_GL_API(glStencilMask, mask);
|
||||
}
|
||||
void API_ENTRY(glStencilMaskSeparate)(GLenum face, GLuint mask)
|
||||
{
|
||||
CALL_GL_API(glStencilMaskSeparate, face, mask);
|
||||
}
|
||||
void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass)
|
||||
{
|
||||
CALL_GL_API(glStencilOp, fail, zfail, zpass);
|
||||
}
|
||||
void API_ENTRY(glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
|
||||
{
|
||||
CALL_GL_API(glStencilOpSeparate, face, fail, zfail, zpass);
|
||||
}
|
||||
void API_ENTRY(glUniform1fv)(GLint location, GLsizei count, const GLfloat* v)
|
||||
{
|
||||
CALL_GL_API(glUniform1fv, location, count, v);
|
||||
}
|
||||
void API_ENTRY(glUniform1iv)(GLint location, GLsizei count, const GLint* v)
|
||||
{
|
||||
CALL_GL_API(glUniform1iv, location, count, v);
|
||||
}
|
||||
void API_ENTRY(glUniform2fv)(GLint location, GLsizei count, const GLfloat* v)
|
||||
{
|
||||
CALL_GL_API(glUniform2fv, location, count, v);
|
||||
}
|
||||
void API_ENTRY(glUniform2i)(GLint location, GLint x, GLint y)
|
||||
{
|
||||
CALL_GL_API(glUniform2i, location, x, y);
|
||||
}
|
||||
void API_ENTRY(glUniform2iv)(GLint location, GLsizei count, const GLint* v)
|
||||
{
|
||||
CALL_GL_API(glUniform2iv, location, count, v);
|
||||
}
|
||||
void API_ENTRY(glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z)
|
||||
{
|
||||
CALL_GL_API(glUniform3f, location, x, y, z);
|
||||
}
|
||||
void API_ENTRY(glUniform3fv)(GLint location, GLsizei count, const GLfloat* v)
|
||||
{
|
||||
CALL_GL_API(glUniform3fv, location, count, v);
|
||||
}
|
||||
void API_ENTRY(glUniform3i)(GLint location, GLint x, GLint y, GLint z)
|
||||
{
|
||||
CALL_GL_API(glUniform3i, location, x, y, z);
|
||||
}
|
||||
void API_ENTRY(glUniform3iv)(GLint location, GLsizei count, const GLint* v)
|
||||
{
|
||||
CALL_GL_API(glUniform3iv, location, count, v);
|
||||
}
|
||||
void API_ENTRY(glUniform4fv)(GLint location, GLsizei count, const GLfloat* v)
|
||||
{
|
||||
CALL_GL_API(glUniform4fv, location, count, v);
|
||||
}
|
||||
void API_ENTRY(glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w)
|
||||
{
|
||||
CALL_GL_API(glUniform4i, location, x, y, z, w);
|
||||
}
|
||||
void API_ENTRY(glUniform4iv)(GLint location, GLsizei count, const GLint* v)
|
||||
{
|
||||
CALL_GL_API(glUniform4iv, location, count, v);
|
||||
}
|
||||
void API_ENTRY(glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
|
||||
{
|
||||
CALL_GL_API(glUniformMatrix2fv, location, count, transpose, value);
|
||||
}
|
||||
void API_ENTRY(glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
|
||||
{
|
||||
CALL_GL_API(glUniformMatrix3fv, location, count, transpose, value);
|
||||
}
|
||||
void API_ENTRY(glValidateProgram)(GLuint program)
|
||||
{
|
||||
CALL_GL_API(glValidateProgram, program);
|
||||
}
|
2232
opengl/libagl2/src/egl.cpp
Normal file
2232
opengl/libagl2/src/egl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
79
opengl/libagl2/src/get.cpp
Normal file
79
opengl/libagl2/src/get.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include "gles2context.h"
|
||||
|
||||
static char const * const gVendorString = "Android";
|
||||
static char const * const gRendererString = "Android PixelFlinger2 0.0";
|
||||
static char const * const gVersionString = "OpenGL ES 2.0";
|
||||
static char const * const gExtensionsString =
|
||||
// "GL_OES_byte_coordinates " // OK
|
||||
// "GL_OES_fixed_point " // OK
|
||||
// "GL_OES_single_precision " // OK
|
||||
// "GL_OES_read_format " // OK
|
||||
// "GL_OES_compressed_paletted_texture " // OK
|
||||
// "GL_OES_draw_texture " // OK
|
||||
// "GL_OES_matrix_get " // OK
|
||||
// "GL_OES_query_matrix " // OK
|
||||
// // "GL_OES_point_size_array " // TODO
|
||||
// // "GL_OES_point_sprite " // TODO
|
||||
// "GL_OES_EGL_image " // OK
|
||||
//#ifdef GL_OES_compressed_ETC1_RGB8_texture
|
||||
// "GL_OES_compressed_ETC1_RGB8_texture " // OK
|
||||
//#endif
|
||||
// "GL_ARB_texture_compression " // OK
|
||||
// "GL_ARB_texture_non_power_of_two " // OK
|
||||
// "GL_ANDROID_user_clip_plane " // OK
|
||||
// "GL_ANDROID_vertex_buffer_object " // OK
|
||||
// "GL_ANDROID_generate_mipmap " // OK
|
||||
""
|
||||
;
|
||||
|
||||
void glGetIntegerv(GLenum pname, GLint* params)
|
||||
{
|
||||
switch (pname) {
|
||||
case GL_MAX_TEXTURE_SIZE :
|
||||
*params = 4096; // limit is in precision of texcoord calculation, which uses 16.16
|
||||
break;
|
||||
case GL_MAX_VERTEX_ATTRIBS:
|
||||
*params = GGL_MAXVERTEXATTRIBS;
|
||||
break;
|
||||
case GL_MAX_VERTEX_UNIFORM_VECTORS:
|
||||
*params = GGL_MAXVERTEXUNIFORMVECTORS;
|
||||
break;
|
||||
case GL_MAX_VARYING_VECTORS:
|
||||
*params = GGL_MAXVARYINGVECTORS;
|
||||
break;
|
||||
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
|
||||
*params = GGL_MAXCOMBINEDTEXTUREIMAGEUNITS;
|
||||
break;
|
||||
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
|
||||
*params = GGL_MAXVERTEXTEXTUREIMAGEUNITS;
|
||||
break;
|
||||
case GL_MAX_TEXTURE_IMAGE_UNITS:
|
||||
*params = GGL_MAXTEXTUREIMAGEUNITS;
|
||||
break;
|
||||
case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
|
||||
*params = GGL_MAXFRAGMENTUNIFORMVECTORS;
|
||||
break;
|
||||
case GL_ALIASED_LINE_WIDTH_RANGE:
|
||||
*params = 1; // TODO: not implemented
|
||||
break;
|
||||
default:
|
||||
LOGD("agl2: glGetIntegerv 0x%.4X", pname);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
const GLubyte* glGetString(GLenum name)
|
||||
{
|
||||
switch (name) {
|
||||
case GL_VENDOR:
|
||||
return (const GLubyte*)gVendorString;
|
||||
case GL_RENDERER:
|
||||
return (const GLubyte*)gRendererString;
|
||||
case GL_VERSION:
|
||||
return (const GLubyte*)gVersionString;
|
||||
case GL_EXTENSIONS:
|
||||
return (const GLubyte*)gExtensionsString;
|
||||
}
|
||||
assert(0); //(c, GL_INVALID_ENUM);
|
||||
return 0;
|
||||
}
|
166
opengl/libagl2/src/gles2context.h
Normal file
166
opengl/libagl2/src/gles2context.h
Normal file
@ -0,0 +1,166 @@
|
||||
#define _SIZE_T_DEFINED_
|
||||
typedef unsigned int size_t;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES/gl.h>
|
||||
#include <GLES/glext.h>
|
||||
|
||||
#include <utils/threads.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __arm__
|
||||
#ifndef __location__
|
||||
#define __HIERALLOC_STRING_0__(s) #s
|
||||
#define __HIERALLOC_STRING_1__(s) __HIERALLOC_STRING_0__(s)
|
||||
#define __HIERALLOC_STRING_2__ __HIERALLOC_STRING_1__(__LINE__)
|
||||
#define __location__ __FILE__ ":" __HIERALLOC_STRING_2__
|
||||
#endif
|
||||
#undef assert
|
||||
#define assert(EXPR) { do { if (!(EXPR)) {LOGD("\n*\n*\n*\n* assert fail: '"#EXPR"' at "__location__"\n*\n*\n*\n*"); exit(EXIT_FAILURE); } } while (false); }
|
||||
//#define printf LOGD
|
||||
#else // #ifdef __arm__
|
||||
//#define LOGD printf
|
||||
#endif // #ifdef __arm__
|
||||
|
||||
|
||||
#include <pixelflinger2/pixelflinger2_format.h>
|
||||
#include <pixelflinger2/pixelflinger2.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
typedef uint8_t GGLubyte; // ub
|
||||
|
||||
#define ggl_likely(x) __builtin_expect(!!(x), 1)
|
||||
#define ggl_unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#undef NELEM
|
||||
#define NELEM(x) (sizeof(x)/sizeof(*(x)))
|
||||
|
||||
template<typename T>
|
||||
inline T max(T a, T b)
|
||||
{
|
||||
return a<b ? b : a;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T min(T a, T b)
|
||||
{
|
||||
return a<b ? a : b;
|
||||
}
|
||||
|
||||
struct egl_context_t {
|
||||
enum {
|
||||
IS_CURRENT = 0x00010000,
|
||||
NEVER_CURRENT = 0x00020000
|
||||
};
|
||||
uint32_t flags;
|
||||
EGLDisplay dpy;
|
||||
EGLConfig config;
|
||||
EGLSurface read;
|
||||
EGLSurface draw;
|
||||
|
||||
unsigned frame;
|
||||
clock_t lastSwapTime;
|
||||
float accumulateSeconds;
|
||||
|
||||
static inline egl_context_t* context(EGLContext ctx);
|
||||
};
|
||||
|
||||
struct GLES2Context;
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
#include <bionic_tls.h>
|
||||
// We have a dedicated TLS slot in bionic
|
||||
inline void setGlThreadSpecific(GLES2Context *value)
|
||||
{
|
||||
((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
|
||||
}
|
||||
inline GLES2Context* getGlThreadSpecific()
|
||||
{
|
||||
return (GLES2Context *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
|
||||
}
|
||||
#else
|
||||
extern pthread_key_t gGLKey;
|
||||
inline void setGlThreadSpecific(GLES2Context *value)
|
||||
{
|
||||
pthread_setspecific(gGLKey, value);
|
||||
}
|
||||
inline GLES2Context* getGlThreadSpecific()
|
||||
{
|
||||
return static_cast<GLES2Context*>(pthread_getspecific(gGLKey));
|
||||
}
|
||||
#endif
|
||||
|
||||
struct VBO {
|
||||
unsigned size;
|
||||
GLenum usage;
|
||||
void * data;
|
||||
};
|
||||
|
||||
struct GLES2Context {
|
||||
GGLContext rasterizer;
|
||||
egl_context_t egl;
|
||||
GGLInterface * iface; // shortcut to &rasterizer.interface
|
||||
|
||||
struct VertexState {
|
||||
struct VertAttribPointer {
|
||||
unsigned size; // number of values per vertex
|
||||
GLenum type; // data type
|
||||
unsigned stride; // bytes
|
||||
const void * ptr;
|
||||
bool normalized :
|
||||
1;
|
||||
bool enabled :
|
||||
1;
|
||||
} attribs [GGL_MAXVERTEXATTRIBS];
|
||||
|
||||
VBO * vbo, * indices;
|
||||
std::map<GLuint, VBO *> vbos;
|
||||
GLuint free;
|
||||
|
||||
Vector4 defaultAttribs [GGL_MAXVERTEXATTRIBS];
|
||||
} vert;
|
||||
|
||||
struct TextureState {
|
||||
GGLTexture * tmus[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS];
|
||||
int sampler2tmu[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS]; // sampler2tmu[sampler] is index of tmu, -1 means not used
|
||||
unsigned active;
|
||||
std::map<GLuint, GGLTexture *> textures;
|
||||
GLuint free; // first possible free name
|
||||
GGLTexture * tex2D, * texCube; // default textures
|
||||
unsigned unpack;
|
||||
|
||||
void UpdateSampler(GGLInterface * iface, unsigned tmu);
|
||||
} tex;
|
||||
|
||||
GLES2Context();
|
||||
void InitializeTextures();
|
||||
void InitializeVertices();
|
||||
|
||||
~GLES2Context();
|
||||
void UninitializeTextures();
|
||||
void UninitializeVertices();
|
||||
|
||||
static inline GLES2Context* get() {
|
||||
return getGlThreadSpecific();
|
||||
}
|
||||
};
|
||||
|
||||
inline egl_context_t* egl_context_t::context(EGLContext ctx)
|
||||
{
|
||||
GLES2Context* const gl = static_cast<GLES2Context*>(ctx);
|
||||
return static_cast<egl_context_t*>(&gl->egl);
|
||||
}
|
||||
|
||||
#define GLES2_GET_CONTEXT(ctx) GLES2Context * ctx = GLES2Context::get(); \
|
||||
/*puts(__FUNCTION__);*/
|
||||
#define GLES2_GET_CONST_CONTEXT(ctx) GLES2Context * ctx = GLES2Context::get(); \
|
||||
/*puts(__FUNCTION__);*/
|
191
opengl/libagl2/src/shader.cpp
Normal file
191
opengl/libagl2/src/shader.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
#include "gles2context.h"
|
||||
|
||||
//#undef LOGD
|
||||
//#define LOGD(...)
|
||||
|
||||
static inline GLuint s2n(gl_shader * s)
|
||||
{
|
||||
return (GLuint)s ^ 0xaf3c532d;
|
||||
}
|
||||
|
||||
static inline gl_shader * n2s(GLuint n)
|
||||
{
|
||||
return (gl_shader *)(n ^ 0xaf3c532d);
|
||||
}
|
||||
|
||||
static inline GLuint p2n(gl_shader_program * p)
|
||||
{
|
||||
return (GLuint)p ^ 0x04dc18f9;
|
||||
}
|
||||
|
||||
static inline gl_shader_program * n2p(GLuint n)
|
||||
{
|
||||
return (gl_shader_program *)(n ^ 0x04dc18f9);
|
||||
}
|
||||
|
||||
void glAttachShader(GLuint program, GLuint shader)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderAttach(ctx->iface, n2p(program), n2s(shader));
|
||||
}
|
||||
|
||||
void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderAttributeBind(n2p(program), index, name);
|
||||
// assert(0);
|
||||
}
|
||||
|
||||
GLuint glCreateShader(GLenum type)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
return s2n(ctx->iface->ShaderCreate(ctx->iface, type));
|
||||
}
|
||||
|
||||
GLuint glCreateProgram(void)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
return p2n(ctx->iface->ShaderProgramCreate(ctx->iface));
|
||||
}
|
||||
|
||||
void glCompileShader(GLuint shader)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderCompile(ctx->iface, n2s(shader), NULL, NULL);
|
||||
}
|
||||
|
||||
void glDeleteProgram(GLuint program)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderProgramDelete(ctx->iface, n2p(program));
|
||||
}
|
||||
|
||||
void glDeleteShader(GLuint shader)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderDelete(ctx->iface, n2s(shader));
|
||||
}
|
||||
|
||||
void glDetachShader(GLuint program, GLuint shader)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderDetach(ctx->iface, n2p(program), n2s(shader));
|
||||
}
|
||||
|
||||
GLint glGetAttribLocation(GLuint program, const GLchar* name)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
GLint location = ctx->iface->ShaderAttributeLocation(n2p(program), name);
|
||||
// LOGD("\n*\n*\n* agl2: glGetAttribLocation program=%u name=%s location=%d \n*\n*",
|
||||
// program, name, location);
|
||||
return location;
|
||||
}
|
||||
|
||||
void glGetProgramiv(GLuint program, GLenum pname, GLint* params)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderProgramGetiv(n2p(program), pname, params);
|
||||
LOGD("agl2: glGetProgramiv 0x%.4X=%d \n", pname, *params);
|
||||
}
|
||||
|
||||
void glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderProgramGetInfoLog(n2p(program), bufsize, length, infolog);
|
||||
}
|
||||
|
||||
void glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderGetiv(n2s(shader), pname, params);
|
||||
LOGD("agl2: glGetShaderiv 0x%.4X=%d \n", pname, *params);
|
||||
}
|
||||
|
||||
void glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderGetInfoLog(n2s(shader), bufsize, length, infolog);
|
||||
}
|
||||
|
||||
int glGetUniformLocation(GLuint program, const GLchar* name)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
return ctx->iface->ShaderUniformLocation(n2p(program), name);
|
||||
}
|
||||
|
||||
void glLinkProgram(GLuint program)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
GLboolean linked = ctx->iface->ShaderProgramLink(n2p(program), NULL);
|
||||
assert(linked);
|
||||
}
|
||||
|
||||
void glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ShaderSource(n2s(shader), count, string, length);
|
||||
}
|
||||
|
||||
void glUniform1f(GLint location, GLfloat x)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
int sampler = ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, &x, GL_FLOAT);
|
||||
assert(0 > sampler); // should be assigning to sampler
|
||||
}
|
||||
|
||||
void glUniform1i(GLint location, GLint x)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
const float params[1] = {x};
|
||||
int sampler = ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, params, GL_INT);
|
||||
if (0 <= sampler) {
|
||||
// LOGD("\n*\n* agl2: glUniform1i updated sampler=%d tmu=%d location=%d\n*", sampler, x, location);
|
||||
assert(0 <= x && GGL_MAXCOMBINEDTEXTUREIMAGEUNITS > x);
|
||||
// LOGD("tmu%u: format=0x%.2X w=%u h=%u levels=%p", x, ctx->tex.tmus[x]->format,
|
||||
// ctx->tex.tmus[x]->width, ctx->tex.tmus[x]->height, ctx->tex.tmus[x]->format);
|
||||
ctx->tex.sampler2tmu[sampler] = x;
|
||||
ctx->tex.UpdateSampler(ctx->iface, x);
|
||||
}
|
||||
}
|
||||
|
||||
void glUniform2f(GLint location, GLfloat x, GLfloat y)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
const float params[4] = {x, y};
|
||||
ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, params, GL_FLOAT_VEC2);
|
||||
}
|
||||
|
||||
void glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
const float params[4] = {x, y, z, w};
|
||||
// LOGD("agl2: glUniform4f location=%d %f,%f,%f,%f", location, x, y, z, w);
|
||||
ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, params, GL_FLOAT_VEC4);
|
||||
}
|
||||
|
||||
void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// const gl_shader_program * program = ctx->rasterizer.CurrentProgram;
|
||||
// if (strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source, ").a;")) {
|
||||
// LOGD("agl2: glUniformMatrix4fv location=%d count=%d transpose=%d", location, count, transpose);
|
||||
// for (unsigned i = 0; i < 4; i++)
|
||||
// LOGD("agl2: glUniformMatrix4fv %.2f \t %.2f \t %.2f \t %.2f", value[i * 4 + 0],
|
||||
// value[i * 4 + 1], value[i * 4 + 2], value[i * 4 + 3]);
|
||||
// }
|
||||
ctx->iface->ShaderUniformMatrix(ctx->rasterizer.CurrentProgram, 4, 4, location, count, transpose, value);
|
||||
// while (true)
|
||||
// ;
|
||||
// assert(0);
|
||||
}
|
||||
|
||||
void glUseProgram(GLuint program)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("\n*\n*\n* agl2: glUseProgram %d \n*\n*\n*", program);
|
||||
ctx->iface->ShaderUse(ctx->iface, n2p(program));
|
||||
ctx->iface->ShaderUniformGetSamplers(n2p(program), ctx->tex.sampler2tmu);
|
||||
for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
|
||||
if (0 <= ctx->tex.sampler2tmu[i])
|
||||
ctx->iface->SetSampler(ctx->iface, i, ctx->tex.tmus[ctx->tex.sampler2tmu[i]]);
|
||||
}
|
129
opengl/libagl2/src/state.cpp
Normal file
129
opengl/libagl2/src/state.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
#include "gles2context.h"
|
||||
|
||||
GLES2Context::GLES2Context()
|
||||
{
|
||||
memset(this, 0, sizeof *this);
|
||||
|
||||
assert((void *)&rasterizer == &rasterizer.interface);
|
||||
InitializeGGLState(&rasterizer.interface);
|
||||
iface = &rasterizer.interface;
|
||||
printf("gl->rasterizer.PickScanLine(%p) = %p \n", &rasterizer.PickScanLine, rasterizer.PickScanLine);
|
||||
assert(rasterizer.PickRaster);
|
||||
assert(rasterizer.PickScanLine);
|
||||
|
||||
InitializeTextures();
|
||||
InitializeVertices();
|
||||
}
|
||||
|
||||
GLES2Context::~GLES2Context()
|
||||
{
|
||||
UninitializeTextures();
|
||||
UninitializeVertices();
|
||||
UninitializeGGLState(&rasterizer.interface);
|
||||
}
|
||||
|
||||
void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->BlendColor(ctx->iface, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
void glBlendEquation( GLenum mode )
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->BlendEquationSeparate(ctx->iface, mode, mode);
|
||||
}
|
||||
|
||||
void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->BlendEquationSeparate(ctx->iface, modeRGB, modeAlpha);
|
||||
}
|
||||
|
||||
void glBlendFunc(GLenum sfactor, GLenum dfactor)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->BlendFuncSeparate(ctx->iface, sfactor, dfactor, sfactor, dfactor);
|
||||
}
|
||||
|
||||
void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->BlendFuncSeparate(ctx->iface, srcRGB, dstRGB, srcAlpha, dstAlpha);
|
||||
}
|
||||
|
||||
void glClear(GLbitfield mask)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->Clear(ctx->iface, mask);
|
||||
}
|
||||
|
||||
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ClearColor(ctx->iface, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
void glClearDepthf(GLclampf depth)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ClearDepthf(ctx->iface, depth);
|
||||
}
|
||||
|
||||
void glClearStencil(GLint s)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->ClearStencil(ctx->iface, s);
|
||||
}
|
||||
|
||||
void glCullFace(GLenum mode)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->CullFace(ctx->iface, mode);
|
||||
}
|
||||
|
||||
void glDisable(GLenum cap)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->EnableDisable(ctx->iface, cap, false);
|
||||
}
|
||||
|
||||
void glEnable(GLenum cap)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->EnableDisable(ctx->iface, cap, true);
|
||||
}
|
||||
|
||||
void glFinish(void)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void glFrontFace(GLenum mode)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->iface->FrontFace(ctx->iface, mode);
|
||||
}
|
||||
|
||||
void glFlush(void)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void glHint(GLenum target, GLenum mode)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
|
||||
{
|
||||
// LOGD("agl2: glScissor not implemented x=%d y=%d width=%d height=%d", x, y, width, height);
|
||||
//CALL_GL_API(glScissor, x, y, width, height);
|
||||
}
|
||||
|
||||
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("agl2: glViewport x=%d y=%d width=%d height=%d", x, y, width, height);
|
||||
ctx->iface->Viewport(ctx->iface, x, y, width, height);
|
||||
}
|
534
opengl/libagl2/src/texture.cpp
Normal file
534
opengl/libagl2/src/texture.cpp
Normal file
@ -0,0 +1,534 @@
|
||||
#include "gles2context.h"
|
||||
|
||||
//#undef LOGD
|
||||
//#define LOGD(...)
|
||||
|
||||
#define API_ENTRY
|
||||
#define CALL_GL_API(NAME,...) LOGD("?"#NAME); assert(0);
|
||||
#define CALL_GL_API_RETURN(NAME,...) LOGD("?"#NAME); assert(0); return 0;
|
||||
|
||||
static inline GGLTexture * AllocTexture()
|
||||
{
|
||||
GGLTexture * tex = (GGLTexture *)calloc(1, sizeof(GGLTexture));
|
||||
tex->minFilter = GGLTexture::GGL_LINEAR; // should be NEAREST_ MIPMAP_LINEAR
|
||||
tex->magFilter = GGLTexture::GGL_LINEAR;
|
||||
return tex;
|
||||
}
|
||||
|
||||
void GLES2Context::InitializeTextures()
|
||||
{
|
||||
tex.textures = std::map<GLuint, GGLTexture *>(); // the entire struct has been zeroed in constructor
|
||||
tex.tex2D = AllocTexture();
|
||||
tex.textures[GL_TEXTURE_2D] = tex.tex2D;
|
||||
tex.texCube = AllocTexture();
|
||||
tex.textures[GL_TEXTURE_CUBE_MAP] = tex.texCube;
|
||||
for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++) {
|
||||
tex.tmus[i] = NULL;
|
||||
tex.sampler2tmu[i] = NULL;
|
||||
}
|
||||
|
||||
tex.active = 0;
|
||||
|
||||
tex.free = max(GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP) + 1;
|
||||
|
||||
tex.tex2D->format = GGL_PIXEL_FORMAT_RGBA_8888;
|
||||
tex.tex2D->type = GL_TEXTURE_2D;
|
||||
tex.tex2D->levelCount = 1;
|
||||
tex.tex2D->wrapS = tex.tex2D->wrapT = GGLTexture::GGL_REPEAT;
|
||||
tex.tex2D->minFilter = tex.tex2D->magFilter = GGLTexture::GGL_NEAREST;
|
||||
tex.tex2D->width = tex.tex2D->height = 1;
|
||||
tex.tex2D->levels = malloc(4);
|
||||
*(unsigned *)tex.tex2D->levels = 0xff000000;
|
||||
|
||||
|
||||
tex.texCube->format = GGL_PIXEL_FORMAT_RGBA_8888;
|
||||
tex.texCube->type = GL_TEXTURE_CUBE_MAP;
|
||||
tex.texCube->levelCount = 1;
|
||||
tex.texCube->wrapS = tex.texCube->wrapT = GGLTexture::GGL_REPEAT;
|
||||
tex.texCube->minFilter = tex.texCube->magFilter = GGLTexture::GGL_NEAREST;
|
||||
tex.texCube->width = tex.texCube->height = 1;
|
||||
tex.texCube->levels = malloc(4 * 6);
|
||||
static unsigned texels [6] = {0xff0000ff, 0xff00ff00, 0xffff0000,
|
||||
0xff00ffff, 0xffffff00, 0xffff00ff
|
||||
};
|
||||
memcpy(tex.texCube->levels, texels, sizeof texels);
|
||||
|
||||
//texture.levelCount = GenerateMipmaps(texture.levels, texture.width, texture.height);
|
||||
|
||||
// static unsigned texels [6] = {0xff0000ff, 0xff00ff00, 0xffff0000,
|
||||
// 0xff00ffff, 0xffffff00, 0xffff00ff};
|
||||
// memcpy(texture.levels[0], texels, sizeof texels);
|
||||
// texture.format = GGL_PIXEL_FORMAT_RGBA_8888;
|
||||
// texture.width = texture.height = 1;
|
||||
//texture.height /= 6;
|
||||
//texture.type = GL_TEXTURE_CUBE_MAP;
|
||||
|
||||
tex.unpack = 4;
|
||||
}
|
||||
|
||||
void GLES2Context::TextureState::UpdateSampler(GGLInterface * iface, unsigned tmu)
|
||||
{
|
||||
for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
|
||||
if (tmu == sampler2tmu[i])
|
||||
iface->SetSampler(iface, i, tmus[tmu]);
|
||||
}
|
||||
|
||||
void GLES2Context::UninitializeTextures()
|
||||
{
|
||||
for (std::map<GLuint, GGLTexture *>::iterator it = tex.textures.begin(); it != tex.textures.end(); it++) {
|
||||
if (!it->second)
|
||||
continue;
|
||||
free(it->second->levels);
|
||||
free(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void GetFormatAndBytesPerPixel(const GLenum format, unsigned * bytesPerPixel,
|
||||
GGLPixelFormat * texFormat)
|
||||
{
|
||||
switch (format) {
|
||||
case GL_ALPHA:
|
||||
*texFormat = GGL_PIXEL_FORMAT_A_8;
|
||||
*bytesPerPixel = 1;
|
||||
break;
|
||||
case GL_LUMINANCE:
|
||||
*texFormat = GGL_PIXEL_FORMAT_L_8;
|
||||
*bytesPerPixel = 1;
|
||||
break;
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
*texFormat = GGL_PIXEL_FORMAT_LA_88;
|
||||
*bytesPerPixel = 2;
|
||||
break;
|
||||
case GL_RGB:
|
||||
*texFormat = GGL_PIXEL_FORMAT_RGB_888;
|
||||
*bytesPerPixel = 3;
|
||||
break;
|
||||
case GL_RGBA:
|
||||
*texFormat = GGL_PIXEL_FORMAT_RGBA_8888;
|
||||
*bytesPerPixel = 4;
|
||||
break;
|
||||
|
||||
// internal formats to avoid conversion
|
||||
case GL_UNSIGNED_SHORT_5_6_5:
|
||||
*texFormat = GGL_PIXEL_FORMAT_RGB_565;
|
||||
*bytesPerPixel = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void CopyTexture(char * dst, const char * src, const unsigned bytesPerPixel,
|
||||
const unsigned sx, const unsigned sy, const unsigned sw,
|
||||
const unsigned dx, const unsigned dy, const unsigned dw,
|
||||
const unsigned w, const unsigned h)
|
||||
{
|
||||
const unsigned bpp = bytesPerPixel;
|
||||
if (dw == sw && dw == w && sx == 0 && dx == 0)
|
||||
memcpy(dst + dy * dw * bpp, src + sy * sw * bpp, w * h * bpp);
|
||||
else
|
||||
for (unsigned y = 0; y < h; y++)
|
||||
memcpy(dst + ((dy + y) * dw + dx) * bpp, src + ((sy + y) * sw + sx) * bpp, w * bpp);
|
||||
}
|
||||
|
||||
void glActiveTexture(GLenum texture)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
unsigned index = texture - GL_TEXTURE0;
|
||||
assert(NELEM(ctx->tex.tmus) > index);
|
||||
// LOGD("agl2: glActiveTexture %u", index);
|
||||
ctx->tex.active = index;
|
||||
}
|
||||
|
||||
void glBindTexture(GLenum target, GLuint texture)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("agl2: glBindTexture target=0x%.4X texture=%u active=%u", target, texture, ctx->tex.active);
|
||||
std::map<GLuint, GGLTexture *>::iterator it = ctx->tex.textures.find(texture);
|
||||
GGLTexture * tex = NULL;
|
||||
if (it != ctx->tex.textures.end()) {
|
||||
tex = it->second;
|
||||
if (!tex) {
|
||||
tex = AllocTexture();
|
||||
tex->type = target;
|
||||
it->second = tex;
|
||||
// LOGD("agl2: glBindTexture allocTexture");
|
||||
}
|
||||
// else
|
||||
// LOGD("agl2: glBindTexture bind existing texture");
|
||||
assert(target == tex->type);
|
||||
} else if (0 == texture) {
|
||||
if (GL_TEXTURE_2D == target)
|
||||
{
|
||||
tex = ctx->tex.tex2D;
|
||||
// LOGD("agl2: glBindTexture bind default tex2D");
|
||||
}
|
||||
else if (GL_TEXTURE_CUBE_MAP == target)
|
||||
{
|
||||
tex = ctx->tex.texCube;
|
||||
// LOGD("agl2: glBindTexture bind default texCube");
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
} else {
|
||||
if (texture <= ctx->tex.free)
|
||||
ctx->tex.free = texture + 1;
|
||||
tex = AllocTexture();
|
||||
tex->type = target;
|
||||
ctx->tex.textures[texture] = tex;
|
||||
// LOGD("agl2: glBindTexture new texture=%u", texture);
|
||||
}
|
||||
ctx->tex.tmus[ctx->tex.active] = tex;
|
||||
// LOGD("agl2: glBindTexture format=0x%.2X w=%u h=%u levels=%p", tex->format,
|
||||
// tex->width, tex->height, tex->levels);
|
||||
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
|
||||
}
|
||||
|
||||
void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
|
||||
{
|
||||
CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data);
|
||||
}
|
||||
|
||||
void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
|
||||
{
|
||||
CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data);
|
||||
}
|
||||
|
||||
void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("agl2: glCopyTexImage2D target=0x%.4X internalformat=0x%.4X", target, internalformat);
|
||||
// LOGD("x=%d y=%d width=%d height=%d border=%d level=%d ", x, y, width, height, border, level);
|
||||
assert(0 == border);
|
||||
assert(0 == level);
|
||||
unsigned bytesPerPixel = 0;
|
||||
GGLPixelFormat texFormat = GGL_PIXEL_FORMAT_UNKNOWN;
|
||||
GetFormatAndBytesPerPixel(internalformat, &bytesPerPixel, &texFormat);
|
||||
|
||||
assert(texFormat == ctx->rasterizer.frameSurface.format);
|
||||
// LOGD("texFormat=0x%.2X bytesPerPixel=%d \n", texFormat, bytesPerPixel);
|
||||
unsigned offset = 0, size = width * height * bytesPerPixel, totalSize = size;
|
||||
|
||||
assert(ctx->tex.tmus[ctx->tex.active]);
|
||||
assert(y + height <= ctx->rasterizer.frameSurface.height);
|
||||
assert(x + width <= ctx->rasterizer.frameSurface.width);
|
||||
GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
|
||||
tex.width = width;
|
||||
tex.height = height;
|
||||
tex.levelCount = 1;
|
||||
tex.format = texFormat;
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
tex.levels = realloc(tex.levels, totalSize);
|
||||
CopyTexture((char *)tex.levels, (const char *)ctx->rasterizer.frameSurface.data, bytesPerPixel,
|
||||
x, y, ctx->rasterizer.frameSurface.width, 0, 0, width, width, height);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
|
||||
}
|
||||
|
||||
void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
|
||||
{
|
||||
// x, y are src offset
|
||||
// xoffset and yoffset are dst offset
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("agl2: glCopyTexSubImage2D target=0x%.4X level=%d", target, level);
|
||||
// LOGD("xoffset=%d yoffset=%d x=%d y=%d width=%d height=%d", xoffset, yoffset, x, y, width, height);
|
||||
assert(0 == level);
|
||||
|
||||
unsigned bytesPerPixel = 4;
|
||||
unsigned offset = 0, size = width * height * bytesPerPixel, totalSize = size;
|
||||
|
||||
assert(ctx->tex.tmus[ctx->tex.active]);
|
||||
GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
|
||||
|
||||
assert(tex.format == ctx->rasterizer.frameSurface.format);
|
||||
assert(GGL_PIXEL_FORMAT_RGBA_8888 == tex.format);
|
||||
|
||||
const unsigned srcWidth = ctx->rasterizer.frameSurface.width;
|
||||
const unsigned srcHeight = ctx->rasterizer.frameSurface.height;
|
||||
|
||||
assert(x >= 0 && y >= 0);
|
||||
assert(xoffset >= 0 && yoffset >= 0);
|
||||
assert(x + width <= srcWidth);
|
||||
assert(y + height <= srcHeight);
|
||||
assert(xoffset + width <= tex.width);
|
||||
assert(yoffset + height <= tex.height);
|
||||
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
CopyTexture((char *)tex.levels, (const char *)ctx->rasterizer.frameSurface.data, bytesPerPixel,
|
||||
x, y, srcWidth, xoffset, yoffset, tex.width, width, height);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
|
||||
}
|
||||
|
||||
void glDeleteTextures(GLsizei n, const GLuint* textures)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
std::map<GLuint, GGLTexture *>::iterator it = ctx->tex.textures.find(textures[i]);
|
||||
if (it == ctx->tex.textures.end())
|
||||
continue;
|
||||
ctx->tex.free = min(ctx->tex.free, textures[i]);
|
||||
for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
|
||||
if (ctx->tex.tmus[i] == it->second) {
|
||||
if (GL_TEXTURE_2D == it->second->type)
|
||||
ctx->tex.tmus[i] = ctx->tex.tex2D;
|
||||
else if (GL_TEXTURE_CUBE_MAP == it->second->type)
|
||||
ctx->tex.tmus[i] = ctx->tex.texCube;
|
||||
else
|
||||
assert(0);
|
||||
ctx->tex.UpdateSampler(ctx->iface, i);
|
||||
}
|
||||
if (it->second) {
|
||||
free(it->second->levels);
|
||||
free(it->second);
|
||||
}
|
||||
ctx->tex.textures.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void glGenTextures(GLsizei n, GLuint* textures)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
textures[i] = 0;
|
||||
for (ctx->tex.free; ctx->tex.free < 0xffffffffu; ctx->tex.free++)
|
||||
if (ctx->tex.textures.find(ctx->tex.free) == ctx->tex.textures.end()) {
|
||||
ctx->tex.textures[ctx->tex.free] = NULL;
|
||||
textures[i] = ctx->tex.free;
|
||||
ctx->tex.free++;
|
||||
break;
|
||||
}
|
||||
assert(textures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params)
|
||||
{
|
||||
CALL_GL_API(glGetTexParameterfv, target, pname, params);
|
||||
}
|
||||
void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint* params)
|
||||
{
|
||||
CALL_GL_API(glGetTexParameteriv, target, pname, params);
|
||||
}
|
||||
|
||||
GLboolean glIsTexture(GLuint texture)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
if (ctx->tex.textures.find(texture) == ctx->tex.textures.end())
|
||||
return GL_FALSE;
|
||||
else
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void glPixelStorei(GLenum pname, GLint param)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
assert(GL_UNPACK_ALIGNMENT == pname);
|
||||
assert(1 == param || 2 == param || 4 == param || 8 == param);
|
||||
// LOGD("\n*\n* agl2: glPixelStorei not implemented pname=0x%.4X param=%d \n*", pname, param);
|
||||
ctx->tex.unpack = param;
|
||||
// CALL_GL_API(glPixelStorei, pname, param);
|
||||
}
|
||||
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
|
||||
GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("agl2: glTexImage2D internalformat=0x%.4X format=0x%.4X type=0x%.4X \n", internalformat, format, type);
|
||||
// LOGD("width=%d height=%d border=%d level=%d pixels=%p \n", width, height, border, level, pixels);
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
break;
|
||||
case GL_UNSIGNED_SHORT_5_6_5:
|
||||
internalformat = format = GL_UNSIGNED_SHORT_5_6_5;
|
||||
assert(4 == ctx->tex.unpack);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
assert(internalformat == format);
|
||||
assert(0 == border);
|
||||
if (0 != level) {
|
||||
LOGD("agl2: glTexImage2D level=%d", level);
|
||||
return;
|
||||
}
|
||||
unsigned bytesPerPixel = 0;
|
||||
GGLPixelFormat texFormat = GGL_PIXEL_FORMAT_UNKNOWN;
|
||||
GetFormatAndBytesPerPixel(format, &bytesPerPixel, &texFormat);
|
||||
|
||||
assert(texFormat && bytesPerPixel);
|
||||
// LOGD("texFormat=0x%.2X bytesPerPixel=%d active=%u", texFormat, bytesPerPixel, ctx->tex.active);
|
||||
unsigned offset = 0, size = width * height * bytesPerPixel, totalSize = size;
|
||||
|
||||
assert(ctx->tex.tmus[ctx->tex.active]);
|
||||
|
||||
GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
|
||||
tex.width = width;
|
||||
tex.height = height;
|
||||
tex.levelCount = 1;
|
||||
tex.format = texFormat;
|
||||
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
assert(GL_TEXTURE_2D == ctx->tex.tmus[ctx->tex.active]->type);
|
||||
offset = 0;
|
||||
break;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
assert(GL_TEXTURE_CUBE_MAP == ctx->tex.tmus[ctx->tex.active]->type);
|
||||
assert(width == height);
|
||||
offset = (target - GL_TEXTURE_CUBE_MAP_POSITIVE_X) * size;
|
||||
totalSize = 6 * size;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
tex.levels = realloc(tex.levels, totalSize);
|
||||
if (pixels)
|
||||
CopyTexture((char *)tex.levels, (const char *)pixels, bytesPerPixel, 0, 0, width, 0, 0, width, width, height);
|
||||
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
|
||||
}
|
||||
|
||||
void glTexParameterf(GLenum target, GLenum pname, GLfloat param)
|
||||
{
|
||||
// LOGD("agl2: glTexParameterf target=0x%.4X pname=0x%.4X param=%f", target, pname, param);
|
||||
glTexParameteri(target, pname, param);
|
||||
}
|
||||
void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat* params)
|
||||
{
|
||||
CALL_GL_API(glTexParameterfv, target, pname, params);
|
||||
}
|
||||
void glTexParameteri(GLenum target, GLenum pname, GLint param)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("alg2: glTexParameteri target=0x%.0X pname=0x%.4X param=0x%.4X",
|
||||
// target, pname, param);
|
||||
assert(ctx->tex.tmus[ctx->tex.active]);
|
||||
assert(target == ctx->tex.tmus[ctx->tex.active]->type);
|
||||
GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
|
||||
switch (pname) {
|
||||
case GL_TEXTURE_WRAP_S:
|
||||
case GL_TEXTURE_WRAP_T:
|
||||
GGLTexture::GGLTextureWrap wrap;
|
||||
switch (param) {
|
||||
case GL_REPEAT:
|
||||
wrap = GGLTexture::GGL_REPEAT;
|
||||
break;
|
||||
case GL_CLAMP_TO_EDGE:
|
||||
wrap = GGLTexture::GGL_CLAMP_TO_EDGE;
|
||||
break;
|
||||
case GL_MIRRORED_REPEAT:
|
||||
wrap = GGLTexture::GGL_MIRRORED_REPEAT;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
if (GL_TEXTURE_WRAP_S == pname)
|
||||
tex.wrapS = wrap;
|
||||
else
|
||||
tex.wrapT = wrap;
|
||||
break;
|
||||
case GL_TEXTURE_MIN_FILTER:
|
||||
switch (param) {
|
||||
case GL_NEAREST:
|
||||
tex.minFilter = GGLTexture::GGL_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
tex.minFilter = GGLTexture::GGL_LINEAR;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
// tex.minFilter = GGLTexture::GGL_NEAREST_MIPMAP_NEAREST;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
// tex.minFilter = GGLTexture::GGL_NEAREST_MIPMAP_LINEAR;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
// tex.minFilter = GGLTexture::GGL_LINEAR_MIPMAP_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
// tex.minFilter = GGLTexture::GGL_LINEAR_MIPMAP_LINEAR;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_MAG_FILTER:
|
||||
switch (param) {
|
||||
case GL_NEAREST:
|
||||
tex.minFilter = GGLTexture::GGL_NEAREST;
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
tex.minFilter = GGLTexture::GGL_LINEAR;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
// implementation restriction
|
||||
if (tex.magFilter != tex.minFilter)
|
||||
tex.magFilter = tex.minFilter = GGLTexture::GGL_LINEAR;
|
||||
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
|
||||
}
|
||||
void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint* params)
|
||||
{
|
||||
CALL_GL_API(glTexParameteriv, target, pname, params);
|
||||
}
|
||||
void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("agl2: glTexSubImage2D target=0x%.4X level=%d xoffset=%d yoffset=%d width=%d height=%d format=0x%.4X type=0x%.4X pixels=%p",
|
||||
// target, level, xoffset, yoffset, width, height, format, type, pixels);
|
||||
assert(0 == level);
|
||||
assert(target == ctx->tex.tmus[ctx->tex.active]->type);
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
break;
|
||||
case GL_UNSIGNED_SHORT_5_6_5:
|
||||
format = GL_UNSIGNED_SHORT_5_6_5;
|
||||
assert(4 == ctx->tex.unpack);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
|
||||
GGLPixelFormat texFormat = GGL_PIXEL_FORMAT_UNKNOWN;
|
||||
unsigned bytesPerPixel = 0;
|
||||
GetFormatAndBytesPerPixel(format, &bytesPerPixel, &texFormat);
|
||||
assert(texFormat == tex.format);
|
||||
assert(GL_UNSIGNED_BYTE == type);
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
CopyTexture((char *)tex.levels, (const char *)pixels, bytesPerPixel, 0, 0, width, xoffset,
|
||||
yoffset, tex.width, width, height);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
|
||||
}
|
373
opengl/libagl2/src/vertex.cpp
Normal file
373
opengl/libagl2/src/vertex.cpp
Normal file
@ -0,0 +1,373 @@
|
||||
#include "gles2context.h"
|
||||
|
||||
//#undef LOGD
|
||||
//#define LOGD(...)
|
||||
|
||||
void GLES2Context::InitializeVertices()
|
||||
{
|
||||
vert.vbos = std::map<GLuint, VBO *>(); // the entire struct has been zeroed in constructor
|
||||
vert.free = 1;
|
||||
vert.vbo = NULL;
|
||||
vert.indices = NULL;
|
||||
for (unsigned i = 0; i < GGL_MAXVERTEXATTRIBS; i++)
|
||||
vert.defaultAttribs[i] = Vector4(0,0,0,1);
|
||||
}
|
||||
|
||||
void GLES2Context::UninitializeVertices()
|
||||
{
|
||||
for (std::map<GLuint, VBO *>::iterator it = vert.vbos.begin(); it != vert.vbos.end(); it++) {
|
||||
if (!it->second)
|
||||
continue;
|
||||
free(it->second->data);
|
||||
free(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void FetchElement(const GLES2Context * ctx, const unsigned index,
|
||||
const unsigned maxAttrib, VertexInput * elem)
|
||||
{
|
||||
for (unsigned i = 0; i < maxAttrib; i++) {
|
||||
{
|
||||
unsigned size = 0;
|
||||
if (ctx->vert.attribs[i].enabled) {
|
||||
const char * ptr = (const char *)ctx->vert.attribs[i].ptr;
|
||||
ptr += ctx->vert.attribs[i].stride * index;
|
||||
memcpy(elem->attributes + i, ptr, ctx->vert.attribs[i].size * sizeof(float));
|
||||
size = ctx->vert.attribs[i].size;
|
||||
// LOGD("agl2: FetchElement %d attribs size=%d %.2f,%.2f,%.2f,%.2f", i, size, elem->attributes[i].x,
|
||||
// elem->attributes[i].y, elem->attributes[i].z, elem->attributes[i].w);
|
||||
} else {
|
||||
// LOGD("agl2: FetchElement %d default %.2f,%.2f,%.2f,%.2f", i, ctx->vert.defaultAttribs[i].x,
|
||||
// ctx->vert.defaultAttribs[i].y, ctx->vert.defaultAttribs[i].z, ctx->vert.defaultAttribs[i].w);
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 0: // fall through
|
||||
elem->attributes[i].x = ctx->vert.defaultAttribs[i].x;
|
||||
case 1: // fall through
|
||||
elem->attributes[i].y = ctx->vert.defaultAttribs[i].y;
|
||||
case 2: // fall through
|
||||
elem->attributes[i].z = ctx->vert.defaultAttribs[i].z;
|
||||
case 3: // fall through
|
||||
elem->attributes[i].w = ctx->vert.defaultAttribs[i].w;
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
// LOGD("agl2: FetchElement %d size=%d %.2f,%.2f,%.2f,%.2f", i, size, elem->attributes[i].x,
|
||||
// elem->attributes[i].y, elem->attributes[i].z, elem->attributes[i].w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IndexT> static void DrawElementsTriangles(const GLES2Context * ctx,
|
||||
const unsigned count, const IndexT * indices, const unsigned maxAttrib)
|
||||
{
|
||||
VertexInput v[3];
|
||||
if (ctx->vert.indices)
|
||||
indices = (IndexT *)((char *)ctx->vert.indices->data + (long)indices);
|
||||
for (unsigned i = 0; i < count; i += 3) {
|
||||
for (unsigned j = 0; j < 3; j++)
|
||||
FetchElement(ctx, indices[i + j], maxAttrib, v + j);
|
||||
ctx->iface->DrawTriangle(ctx->iface, v, v + 1, v + 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawArraysTriangles(const GLES2Context * ctx, const unsigned first,
|
||||
const unsigned count, const unsigned maxAttrib)
|
||||
{
|
||||
// LOGD("agl: DrawArraysTriangles=%p", DrawArraysTriangles);
|
||||
VertexInput v[3];
|
||||
for (unsigned i = 2; i < count; i+=3) {
|
||||
// TODO: fix order
|
||||
FetchElement(ctx, first + i - 2, maxAttrib, v + 0);
|
||||
FetchElement(ctx, first + i - 1, maxAttrib, v + 1);
|
||||
FetchElement(ctx, first + i - 0, maxAttrib, v + 2);
|
||||
ctx->iface->DrawTriangle(ctx->iface, v + 0, v + 1, v + 2);
|
||||
}
|
||||
// LOGD("agl: DrawArraysTriangles end");
|
||||
}
|
||||
|
||||
template<typename IndexT> static void DrawElementsTriangleStrip(const GLES2Context * ctx,
|
||||
const unsigned count, const IndexT * indices, const unsigned maxAttrib)
|
||||
{
|
||||
VertexInput v[3];
|
||||
if (ctx->vert.indices)
|
||||
indices = (IndexT *)((char *)ctx->vert.indices->data + (long)indices);
|
||||
|
||||
// LOGD("agl2: DrawElementsTriangleStrip");
|
||||
// for (unsigned i = 0; i < count; i++)
|
||||
// LOGD("indices[%d] = %d", i, indices[i]);
|
||||
|
||||
FetchElement(ctx, indices[0], maxAttrib, v + 0);
|
||||
FetchElement(ctx, indices[1], maxAttrib, v + 1);
|
||||
for (unsigned i = 2; i < count; i ++) {
|
||||
FetchElement(ctx, indices[i], maxAttrib, v + i % 3);
|
||||
ctx->iface->DrawTriangle(ctx->iface, v + (i - 2) % 3, v + (i - 1) % 3 , v + (i + 0) % 3);
|
||||
}
|
||||
|
||||
// for (unsigned i = 2; i < count; i++) {
|
||||
// FetchElement(ctx, indices[i - 2], maxAttrib, v + 0);
|
||||
// FetchElement(ctx, indices[i - 1], maxAttrib, v + 1);
|
||||
// FetchElement(ctx, indices[i - 0], maxAttrib, v + 2);
|
||||
// ctx->iface->DrawTriangle(ctx->iface, v + 0, v + 1, v + 2);
|
||||
// }
|
||||
}
|
||||
|
||||
static void DrawArraysTriangleStrip(const GLES2Context * ctx, const unsigned first,
|
||||
const unsigned count, const unsigned maxAttrib)
|
||||
{
|
||||
VertexInput v[3];
|
||||
FetchElement(ctx, first, maxAttrib, v + 0);
|
||||
FetchElement(ctx, first + 1, maxAttrib, v + 1);
|
||||
for (unsigned i = 2; i < count; i++) {
|
||||
// TODO: fix order
|
||||
FetchElement(ctx, first + i, maxAttrib, v + i % 3);
|
||||
ctx->iface->DrawTriangle(ctx->iface, v + (i - 2) % 3, v + (i - 1) % 3 , v + (i + 0) % 3);
|
||||
}
|
||||
}
|
||||
|
||||
void glBindBuffer(GLenum target, GLuint buffer)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
VBO * vbo = NULL;
|
||||
if (0 != buffer) {
|
||||
std::map<GLuint, VBO *>::iterator it = ctx->vert.vbos.find(buffer);
|
||||
if (it != ctx->vert.vbos.end()) {
|
||||
vbo = it->second;
|
||||
if (!vbo)
|
||||
vbo = (VBO *)calloc(1, sizeof(VBO));
|
||||
it->second = vbo;
|
||||
} else
|
||||
assert(0);
|
||||
}
|
||||
if (GL_ARRAY_BUFFER == target)
|
||||
ctx->vert.vbo = vbo;
|
||||
else if (GL_ELEMENT_ARRAY_BUFFER == target)
|
||||
ctx->vert.indices = vbo;
|
||||
else
|
||||
assert(0);
|
||||
assert(vbo || buffer == 0);
|
||||
// LOGD("\n*\n glBindBuffer 0x%.4X=%d ", target, buffer);
|
||||
}
|
||||
|
||||
void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
if (GL_ARRAY_BUFFER == target) {
|
||||
assert(ctx->vert.vbo);
|
||||
ctx->vert.vbo->data = realloc(ctx->vert.vbo->data, size);
|
||||
ctx->vert.vbo->size = size;
|
||||
ctx->vert.vbo->usage = usage;
|
||||
if (data)
|
||||
memcpy(ctx->vert.vbo->data, data, size);
|
||||
} else if (GL_ELEMENT_ARRAY_BUFFER == target) {
|
||||
assert(ctx->vert.indices);
|
||||
ctx->vert.indices->data = realloc(ctx->vert.indices->data, size);
|
||||
ctx->vert.indices->size = size;
|
||||
ctx->vert.indices->usage = usage;
|
||||
if (data)
|
||||
memcpy(ctx->vert.indices->data, data, size);
|
||||
} else
|
||||
assert(0);
|
||||
// LOGD("\n*\n glBufferData target=0x%.4X size=%u data=%p usage=0x%.4X \n",
|
||||
// target, size, data, usage);
|
||||
}
|
||||
|
||||
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
if (GL_ARRAY_BUFFER == target)
|
||||
{
|
||||
assert(ctx->vert.vbo);
|
||||
assert(0 <= offset);
|
||||
assert(0 <= size);
|
||||
assert(offset + size <= ctx->vert.vbo->size);
|
||||
memcpy((char *)ctx->vert.vbo->data + offset, data, size);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void glDeleteBuffers(GLsizei n, const GLuint* buffers)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
std::map<GLuint, VBO*>::iterator it = ctx->vert.vbos.find(buffers[i]);
|
||||
if (it == ctx->vert.vbos.end())
|
||||
continue;
|
||||
ctx->vert.free = min(ctx->vert.free, buffers[i]);
|
||||
if (it->second == ctx->vert.vbo)
|
||||
ctx->vert.vbo = NULL;
|
||||
else if (it->second == ctx->vert.indices)
|
||||
ctx->vert.indices = NULL;
|
||||
if (it->second) {
|
||||
free(it->second->data);
|
||||
free(it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void glDisableVertexAttribArray(GLuint index)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
assert(GGL_MAXVERTEXATTRIBS > index);
|
||||
ctx->vert.attribs[index].enabled = false;
|
||||
}
|
||||
|
||||
void glDrawArrays(GLenum mode, GLint first, GLsizei count)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("agl2: glDrawArrays=%p", glDrawArrays);
|
||||
assert(ctx->rasterizer.CurrentProgram);
|
||||
assert(0 <= first);
|
||||
int maxAttrib = -1;
|
||||
ctx->iface->ShaderProgramGetiv(ctx->rasterizer.CurrentProgram, GL_ACTIVE_ATTRIBUTES, &maxAttrib);
|
||||
assert(0 <= maxAttrib && GGL_MAXVERTEXATTRIBS >= maxAttrib);
|
||||
switch (mode) {
|
||||
case GL_TRIANGLE_STRIP:
|
||||
DrawArraysTriangleStrip(ctx, first, count, maxAttrib);
|
||||
break;
|
||||
case GL_TRIANGLES:
|
||||
DrawArraysTriangles(ctx, first, count, maxAttrib);
|
||||
break;
|
||||
default:
|
||||
LOGE("agl2: glDrawArrays unsupported mode: 0x%.4X \n", mode);
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
// LOGD("agl2: glDrawArrays end");
|
||||
}
|
||||
|
||||
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("agl2: glDrawElements=%p mode=0x%.4X count=%d type=0x%.4X indices=%p",
|
||||
// glDrawElements, mode, count, type, indices);
|
||||
if (!ctx->rasterizer.CurrentProgram)
|
||||
return;
|
||||
|
||||
int maxAttrib = -1;
|
||||
ctx->iface->ShaderProgramGetiv(ctx->rasterizer.CurrentProgram, GL_ACTIVE_ATTRIBUTES, &maxAttrib);
|
||||
assert(0 <= maxAttrib && GGL_MAXVERTEXATTRIBS >= maxAttrib);
|
||||
// LOGD("agl2: glDrawElements mode=0x%.4X type=0x%.4X count=%d program=%p indices=%p \n",
|
||||
// mode, type, count, ctx->rasterizer.CurrentProgram, indices);
|
||||
switch (mode) {
|
||||
case GL_TRIANGLES:
|
||||
if (GL_UNSIGNED_SHORT == type)
|
||||
DrawElementsTriangles<unsigned short>(ctx, count, (unsigned short *)indices, maxAttrib);
|
||||
else
|
||||
assert(0);
|
||||
break;
|
||||
case GL_TRIANGLE_STRIP:
|
||||
if (GL_UNSIGNED_SHORT == type)
|
||||
DrawElementsTriangleStrip<unsigned short>(ctx, count, (unsigned short *)indices, maxAttrib);
|
||||
else
|
||||
assert(0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
// LOGD("agl2: glDrawElements end");
|
||||
}
|
||||
|
||||
void glEnableVertexAttribArray(GLuint index)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
ctx->vert.attribs[index].enabled = true;
|
||||
// LOGD("agl2: glEnableVertexAttribArray %d \n", index);
|
||||
}
|
||||
|
||||
void glGenBuffers(GLsizei n, GLuint* buffers)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
buffers[i] = 0;
|
||||
for (ctx->vert.free; ctx->vert.free < 0xffffffffu; ctx->vert.free++) {
|
||||
if (ctx->vert.vbos.find(ctx->vert.free) == ctx->vert.vbos.end()) {
|
||||
ctx->vert.vbos[ctx->vert.free] = NULL;
|
||||
buffers[i] = ctx->vert.free;
|
||||
// LOGD("glGenBuffers %d \n", buffers[i]);
|
||||
ctx->vert.free++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(buffers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
|
||||
GLsizei stride, const GLvoid* ptr)
|
||||
{
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
assert(GL_FLOAT == type);
|
||||
assert(0 < size && 4 >= size);
|
||||
ctx->vert.attribs[index].size = size;
|
||||
ctx->vert.attribs[index].type = type;
|
||||
ctx->vert.attribs[index].normalized = normalized;
|
||||
if (0 == stride)
|
||||
ctx->vert.attribs[index].stride = size * sizeof(float);
|
||||
else if (stride > 0)
|
||||
ctx->vert.attribs[index].stride = stride;
|
||||
else
|
||||
assert(0);
|
||||
// LOGD("\n*\n*\n* agl2: glVertexAttribPointer program=%u index=%d size=%d stride=%d ptr=%p \n*\n*",
|
||||
// unsigned(ctx->rasterizer.CurrentProgram) ^ 0x04dc18f9, index, size, stride, ptr);
|
||||
if (ctx->vert.vbo)
|
||||
ctx->vert.attribs[index].ptr = (char *)ctx->vert.vbo->data + (long)ptr;
|
||||
else
|
||||
ctx->vert.attribs[index].ptr = ptr;
|
||||
// const float * attrib = (const float *)ctx->vert.attribs[index].ptr;
|
||||
// for (unsigned i = 0; i < 3; i++)
|
||||
// if (3 == size)
|
||||
// LOGD("%.2f %.2f %.2f", attrib[i * 3 + 0], attrib[i * 3 + 1], attrib[i * 3 + 2]);
|
||||
// else if (2 == size)
|
||||
// LOGD("%.2f %.2f", attrib[i * 3 + 0], attrib[i * 3 + 1]);
|
||||
|
||||
}
|
||||
|
||||
void glVertexAttrib1f(GLuint indx, GLfloat x)
|
||||
{
|
||||
glVertexAttrib4f(indx, x,0,0,1);
|
||||
}
|
||||
|
||||
void glVertexAttrib1fv(GLuint indx, const GLfloat* values)
|
||||
{
|
||||
glVertexAttrib4f(indx, values[0],0,0,1);
|
||||
}
|
||||
|
||||
void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
|
||||
{
|
||||
glVertexAttrib4f(indx, x,y,0,1);
|
||||
}
|
||||
|
||||
void glVertexAttrib2fv(GLuint indx, const GLfloat* values)
|
||||
{
|
||||
glVertexAttrib4f(indx, values[0],values[1],0,1);
|
||||
}
|
||||
|
||||
void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
|
||||
{
|
||||
glVertexAttrib4f(indx, x,y,z,1);
|
||||
}
|
||||
|
||||
void glVertexAttrib3fv(GLuint indx, const GLfloat* values)
|
||||
{
|
||||
glVertexAttrib4f(indx, values[0],values[1],values[2],1);
|
||||
}
|
||||
|
||||
void glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
|
||||
{
|
||||
assert(GGL_MAXVERTEXATTRIBS > indx);
|
||||
GLES2_GET_CONST_CONTEXT(ctx);
|
||||
// LOGD("\n*\n*\n agl2: glVertexAttrib4f %d %.2f,%.2f,%.2f,%.2f \n*\n*", indx, x, y, z, w);
|
||||
ctx->vert.defaultAttribs[indx] = Vector4(x,y,z,w);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void glVertexAttrib4fv(GLuint indx, const GLfloat* values)
|
||||
{
|
||||
glVertexAttrib4f(indx, values[0], values[1], values[2], values[3]);
|
||||
}
|
Loading…
Reference in New Issue
Block a user