summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorpiman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-08 20:32:40 +0000
committerpiman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-08 20:32:40 +0000
commit177002925b7152b6eafe92912fe922eb823d21c6 (patch)
treeeb6d9268a6d0cddb49d9fba6c707f0f157275878 /o3d
parenta669d57df371e525d2ca93f129c0fdec7f7e76ed (diff)
downloadchromium_src-177002925b7152b6eafe92912fe922eb823d21c6.zip
chromium_src-177002925b7152b6eafe92912fe922eb823d21c6.tar.gz
chromium_src-177002925b7152b6eafe92912fe922eb823d21c6.tar.bz2
linux: native OpenGL ES support
This includes Gregg's CL 548023 There are still a few hard-coded paths, and issues to solve, but hellocube-textures-glsl is running on an actual device. Review URL: http://codereview.chromium.org/572029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38385 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/build/common.gypi93
-rw-r--r--o3d/build/libs.gyp90
-rw-r--r--o3d/core/cross/gles2/buffer_gles2.cc71
-rw-r--r--o3d/core/cross/gles2/buffer_gles2.h16
-rw-r--r--o3d/core/cross/gles2/effect_gles2.cc13
-rw-r--r--o3d/core/cross/gles2/gles2_headers.h50
-rw-r--r--o3d/core/cross/gles2/render_surface_gles2.cc51
-rw-r--r--o3d/core/cross/gles2/renderer_gles2.cc295
-rw-r--r--o3d/core/cross/gles2/renderer_gles2.h15
-rw-r--r--o3d/core/cross/gles2/sampler_gles2.cc30
-rw-r--r--o3d/core/cross/gles2/stream_bank_gles2.cc3
-rw-r--r--o3d/core/cross/gles2/texture_gles2.cc74
-rw-r--r--o3d/plugin/cross/o3d_glue.h2
-rw-r--r--o3d/plugin/plugin.gyp5
14 files changed, 619 insertions, 189 deletions
diff --git a/o3d/build/common.gypi b/o3d/build/common.gypi
index 492bd54..ee2324f 100644
--- a/o3d/build/common.gypi
+++ b/o3d/build/common.gypi
@@ -27,6 +27,7 @@
'variables': {
# If the DEPS file exists two levels up, then we're in a Chrome tree.
'o3d_in_chrome%': '<!(python <(DEPTH)/o3d/build/file_exists.py <(DEPTH)/DEPS)',
+ 'gles2_backend%': 'desktop_gl',
'conditions' : [
# These have to come first because GYP doesn't like it when
# they're part of the same conditional as a conditions clause that
@@ -57,6 +58,7 @@
'o3d_in_chrome%': '<(o3d_in_chrome)',
'renderer%': '<(renderer)',
'cgdir%': '<(cgdir)',
+ 'gles2_backend%': '<(gles2_backend)',
'swiftshaderdir%': '<(swiftshaderdir)',
# We default to building everything only if the assets exist.
@@ -88,44 +90,67 @@
},
}],
],
- },
- 'conditions' : [
- ['OS == "win"',
- {
- 'target_defaults': {
+ 'conditions' : [
+ ['renderer == "d3d9"',
+ {
'defines': [
- '_CRT_SECURE_NO_WARNINGS',
- 'OS_WIN',
- 'UNICODE',
- 'NACL_WINDOWS',
- '_X86_',
+ 'RENDERER_D3D9',
+ ],
+ },
+ ],
+ ['renderer == "gl"',
+ {
+ 'defines': [
+ 'RENDERER_GL',
+ ],
+ },
+ ],
+ ['renderer == "gles2"',
+ {
+ 'defines': [
+ 'RENDERER_GLES2',
],
- # Disable warning: "'this' : used in base member initialization list."
- 'msvs_disabled_warnings': [4355],
'conditions': [
- ['renderer == "d3d9"',
+ ['gles2_backend == "desktop_gl"',
{
'defines': [
- 'RENDERER_D3D9',
+ 'GLES2_BACKEND_DESKTOP_GL',
],
},
],
- ['renderer == "gl"',
+ ['gles2_backend == "native_gles2"',
{
'defines': [
- 'RENDERER_GL',
+ 'GLES2_BACKEND_NATIVE_GLES2',
],
},
],
- ['renderer == "gles2"',
+ ['gles2_backend == "gles2_command_buffers"',
{
'defines': [
- 'RENDERER_GLES2',
+ 'GLES2_BACKEND_GLES2_COMMAND_BUFFERS',
],
},
],
],
},
+ ],
+ ],
+ },
+ 'conditions' : [
+ ['OS == "win"',
+ {
+ 'target_defaults': {
+ 'defines': [
+ '_CRT_SECURE_NO_WARNINGS',
+ 'OS_WIN',
+ 'UNICODE',
+ 'NACL_WINDOWS',
+ '_X86_',
+ ],
+ # Disable warning: "'this' : used in base member initialization list."
+ 'msvs_disabled_warnings': [4355],
+ },
},
],
['OS == "mac"',
@@ -155,22 +180,6 @@
'WARNING_CXXFLAGS': ['-Wstrict-aliasing',
'-Wno-deprecated',],
},
- 'conditions': [
- ['renderer == "gl"',
- {
- 'defines': [
- 'RENDERER_GL',
- ],
- },
- ],
- ['renderer == "gles2"',
- {
- 'defines': [
- 'RENDERER_GLES2',
- ],
- },
- ],
- ],
},
},
],
@@ -190,22 +199,6 @@
'-fvisibility=hidden',
'-Wstrict-aliasing',
],
- 'conditions': [
- ['renderer == "gl"',
- {
- 'defines': [
- 'RENDERER_GL',
- ],
- },
- ],
- ['renderer == "gles2"',
- {
- 'defines': [
- 'RENDERER_GLES2',
- ],
- },
- ],
- ],
},
},
],
diff --git a/o3d/build/libs.gyp b/o3d/build/libs.gyp
index fdb1ccf..94f624b 100644
--- a/o3d/build/libs.gyp
+++ b/o3d/build/libs.gyp
@@ -75,54 +75,74 @@
{
'target_name': 'gles2_libs',
'type': 'none',
- 'all_dependent_settings': {
- 'include_dirs': [
- '../../<(glewdir)/include',
- ],
- },
'conditions': [
- [ 'OS=="linux"',
+ ['gles2_backend=="desktop_gl"',
{
'all_dependent_settings': {
- 'defines': [
- 'GL_GLEXT_PROTOTYPES',
+ 'include_dirs': [
+ '../../<(glewdir)/include',
],
- 'ldflags': [
- '-L<(PRODUCT_DIR)',
+ },
+ 'conditions': [
+ [ 'OS=="linux"',
+ {
+ 'all_dependent_settings': {
+ 'defines': [
+ 'GL_GLEXT_PROTOTYPES',
+ ],
+ 'ldflags': [
+ '-L<(PRODUCT_DIR)',
+ ],
+ 'libraries': [
+ '-lGL',
+ '-lGLEW',
+ '-lX11',
+ ],
+ },
+ },
],
- 'libraries': [
- '-lGL',
- '-lGLEW',
- '-lX11',
+ [ 'OS=="mac"',
+ {
+ 'direct_dependent_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
+ ],
+ },
+ },
],
- },
- },
- ],
- [ 'OS=="mac"',
- {
- 'direct_dependent_settings': {
- 'libraries': [
- '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
+ [ 'OS=="win"',
+ {
+ 'all_dependent_settings': {
+ 'libraries': [
+ '-lOpenGL32.lib',
+ '../../<(glewdir)/lib/glew32.lib',
+ ],
+ },
+ 'copies': [
+ {
+ 'destination': '<(PRODUCT_DIR)',
+ 'files': [
+ "../../<(glewdir)/bin/glew32.dll",
+ ]
+ },
+ ],
+ },
],
- },
+ ],
},
],
- [ 'OS=="win"',
+ #['gles2_backend=="gles2_command_buffers"',
+ # {
+ # },
+ #],
+ ['gles2_backend=="native_gles2"',
{
'all_dependent_settings': {
'libraries': [
- '-lOpenGL32.lib',
- '../../<(glewdir)/lib/glew32.lib',
+ '-lEGL',
+ '-lGLESv2',
],
- },
- 'copies': [
- {
- 'destination': '<(PRODUCT_DIR)',
- 'files': [
- "../../<(glewdir)/bin/glew32.dll",
- ]
- },
- ],
+ }
},
],
],
diff --git a/o3d/core/cross/gles2/buffer_gles2.cc b/o3d/core/cross/gles2/buffer_gles2.cc
index d8f4bc4..8cd7838 100644
--- a/o3d/core/cross/gles2/buffer_gles2.cc
+++ b/o3d/core/cross/gles2/buffer_gles2.cc
@@ -48,6 +48,7 @@ namespace o3d {
namespace {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
GLenum BufferAccessModeToGLenum(Buffer::AccessMode access_mode) {
switch (access_mode) {
case Buffer::READ_ONLY:
@@ -62,6 +63,7 @@ GLenum BufferAccessModeToGLenum(Buffer::AccessMode access_mode) {
DCHECK(false);
return GL_READ_WRITE_ARB;
}
+#endif
} // anonymous namespace
@@ -73,6 +75,10 @@ VertexBufferGLES2::VertexBufferGLES2(ServiceLocator* service_locator)
: VertexBuffer(service_locator),
renderer_(static_cast<RendererGLES2*>(
service_locator->GetService<Renderer>())),
+#if !defined(GLES2_BACKEND_DESKTOP_GL)
+ shadow_(NULL),
+ read_only_(true),
+#endif
gl_buffer_(0) {
DLOG(INFO) << "VertexBufferGLES2 Construct";
}
@@ -95,11 +101,15 @@ bool VertexBufferGLES2::ConcreteAllocate(size_t size_in_bytes) {
// Give the VBO a size, but no data, and set the hint to "STATIC_DRAW"
// to mark the buffer as set up once then used often.
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_buffer_);
- glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ glBindBufferARB(GL_ARRAY_BUFFER, gl_buffer_);
+ glBufferDataARB(GL_ARRAY_BUFFER,
size_in_bytes,
NULL,
- GL_STATIC_DRAW_ARB);
+ GL_STATIC_DRAW);
+
+#if !defined(GLES2_BACKEND_DESKTOP_GL)
+ shadow_.reset(new char[size_in_bytes]);
+#endif
CHECK_GL_ERROR();
return true;
}
@@ -111,6 +121,9 @@ void VertexBufferGLES2::ConcreteFree() {
gl_buffer_ = 0;
CHECK_GL_ERROR();
}
+#if !defined(GLES2_BACKEND_DESKTOP_GL)
+ shadow_.reset(NULL);
+#endif
}
// Calls Lock on the OpenGLES2 buffer to get the address in memory of where the
@@ -119,8 +132,9 @@ bool VertexBufferGLES2::ConcreteLock(Buffer::AccessMode access_mode,
void **buffer_data) {
DLOG(INFO) << "VertexBufferGLES2 Lock \"" << name() << "\"";
renderer_->MakeCurrentLazy();
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_buffer_);
- *buffer_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB,
+ glBindBufferARB(GL_ARRAY_BUFFER, gl_buffer_);
+#if defined(GLES2_BACKEND_DESKTOP_GL)
+ *buffer_data = glMapBufferARB(GL_ARRAY_BUFFER,
BufferAccessModeToGLenum(access_mode));
if (*buffer_data == NULL) {
GLenum error = glGetError();
@@ -131,6 +145,10 @@ bool VertexBufferGLES2::ConcreteLock(Buffer::AccessMode access_mode,
}
return false;
}
+#else
+ *buffer_data = shadow_.get();
+ read_only_ = (access_mode == READ_ONLY);
+#endif
CHECK_GL_ERROR();
return true;
}
@@ -140,7 +158,8 @@ bool VertexBufferGLES2::ConcreteLock(Buffer::AccessMode access_mode,
bool VertexBufferGLES2::ConcreteUnlock() {
DLOG(INFO) << "VertexBufferGLES2 Unlock \"" << name() << "\"";
renderer_->MakeCurrentLazy();
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_buffer_);
+ glBindBufferARB(GL_ARRAY_BUFFER, gl_buffer_);
+#if defined(GLES2_BACKEND_DESKTOP_GL)
if (!glUnmapBufferARB(GL_ARRAY_BUFFER)) {
GLenum error = glGetError();
if (error == GL_INVALID_OPERATION) {
@@ -152,6 +171,11 @@ bool VertexBufferGLES2::ConcreteUnlock() {
}
return false;
}
+#else
+ if (!read_only_) {
+ glBufferSubData(GL_ARRAY_BUFFER, 0, GetSizeInBytes(), shadow_.get());
+ }
+#endif
CHECK_GL_ERROR();
return true;
}
@@ -166,6 +190,10 @@ IndexBufferGLES2::IndexBufferGLES2(ServiceLocator* service_locator)
: IndexBuffer(service_locator),
renderer_(static_cast<RendererGLES2*>(
service_locator->GetService<Renderer>())),
+#if !defined(GLES2_BACKEND_DESKTOP_GL)
+ shadow_(NULL),
+ read_only_(true),
+#endif
gl_buffer_(0) {
DLOG(INFO) << "IndexBufferGLES2 Construct";
}
@@ -186,11 +214,14 @@ bool IndexBufferGLES2::ConcreteAllocate(size_t size_in_bytes) {
if (!gl_buffer_) return false;
// Give the VBO a size, but no data, and set the hint to "STATIC_DRAW"
// to mark the buffer as set up once then used often.
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, gl_buffer_);
- glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, gl_buffer_);
+ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER,
size_in_bytes,
NULL,
- GL_STATIC_DRAW_ARB);
+ GL_STATIC_DRAW);
+#if !defined(GLES2_BACKEND_DESKTOP_GL)
+ shadow_.reset(new char[size_in_bytes]);
+#endif
CHECK_GL_ERROR();
return true;
}
@@ -202,6 +233,9 @@ void IndexBufferGLES2::ConcreteFree() {
gl_buffer_ = 0;
CHECK_GL_ERROR();
}
+#if !defined(GLES2_BACKEND_DESKTOP_GL)
+ shadow_.reset(NULL);
+#endif
}
// Maps the OpenGLES2 buffer to get the address in memory of the buffer data.
@@ -209,10 +243,11 @@ bool IndexBufferGLES2::ConcreteLock(Buffer::AccessMode access_mode,
void **buffer_data) {
DLOG(INFO) << "IndexBufferGLES2 Lock \"" << name() << "\"";
renderer_->MakeCurrentLazy();
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, gl_buffer_);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, gl_buffer_);
if (!num_elements())
return true;
- *buffer_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+#if defined(GLES2_BACKEND_DESKTOP_GL)
+ *buffer_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER,
BufferAccessModeToGLenum(access_mode));
if (*buffer_data == NULL) {
GLenum error = glGetError();
@@ -224,6 +259,10 @@ bool IndexBufferGLES2::ConcreteLock(Buffer::AccessMode access_mode,
}
return false;
}
+#else
+ *buffer_data = shadow_.get();
+ read_only_ = (access_mode == READ_ONLY);
+#endif
CHECK_GL_ERROR();
return true;
}
@@ -235,7 +274,8 @@ bool IndexBufferGLES2::ConcreteUnlock() {
renderer_->MakeCurrentLazy();
if (!num_elements())
return true;
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, gl_buffer_);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, gl_buffer_);
+#if defined(GLES2_BACKEND_DESKTOP_GL)
if (!glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER)) {
GLenum error = glGetError();
if (error == GL_INVALID_OPERATION) {
@@ -247,8 +287,13 @@ bool IndexBufferGLES2::ConcreteUnlock() {
}
return false;
}
+#else
+ if (!read_only_) {
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, GetSizeInBytes(),
+ shadow_.get());
+ }
+#endif
CHECK_GL_ERROR();
return true;
}
} // namespace o3d
-
diff --git a/o3d/core/cross/gles2/buffer_gles2.h b/o3d/core/cross/gles2/buffer_gles2.h
index 7dda7e1..b1956f8 100644
--- a/o3d/core/cross/gles2/buffer_gles2.h
+++ b/o3d/core/cross/gles2/buffer_gles2.h
@@ -36,6 +36,7 @@
#ifndef O3D_CORE_CROSS_GLES2_BUFFER_GLES2_H_
#define O3D_CORE_CROSS_GLES2_BUFFER_GLES2_H_
+#include "base/scoped_ptr.h"
#include "core/cross/buffer.h"
#include "core/cross/gles2/gles2_headers.h"
@@ -80,6 +81,13 @@ class VertexBufferGLES2 : public VertexBuffer {
private:
RendererGLES2* renderer_;
+#if !defined(GLES2_BACKEND_DESKTOP_GL)
+ // GLES doesn't support glMapBuffers (only WRITE_ONLY if an extension is
+ // present), or even glGetBufferSubData, so we need to keep a shadow of the
+ // data.
+ scoped_array<char> shadow_;
+ bool read_only_;
+#endif
GLuint gl_buffer_;
};
@@ -112,6 +120,13 @@ class IndexBufferGLES2 : public IndexBuffer {
private:
RendererGLES2* renderer_;
+#if !defined(GLES2_BACKEND_DESKTOP_GL)
+ // GLES doesn't support glMapBuffers (only WRITE_ONLY if an extension is
+ // present), or even glGetBufferSubData, so we need to keep a shadow of the
+ // data.
+ scoped_array<char> shadow_;
+ bool read_only_;
+#endif
GLuint gl_buffer_;
};
@@ -119,4 +134,3 @@ class IndexBufferGLES2 : public IndexBuffer {
#endif // O3D_CORE_CROSS_GLES2_BUFFER_GLES2_H_
-
diff --git a/o3d/core/cross/gles2/effect_gles2.cc b/o3d/core/cross/gles2/effect_gles2.cc
index 1e24e5b..060f46b 100644
--- a/o3d/core/cross/gles2/effect_gles2.cc
+++ b/o3d/core/cross/gles2/effect_gles2.cc
@@ -203,6 +203,15 @@ bool GetIdentifierAfterString(const String& original,
return false;
}
+#ifdef GLES2_BACKEND_DESKTOP_GL
+const char kVertexHeader[] = "";
+const char kFragmentHeader[] = "// ";
+#else
+const char kVertexHeader[] = "precision highp float; precision highp int;\n";
+const char kFragmentHeader[] =
+ "precision mediump float; precision mediump int;\n// ";
+#endif
+
} // anonymous namespace
// Initializes the Effect object using the shaders found in an FX formatted
@@ -235,8 +244,8 @@ bool EffectGLES2::LoadFromFXString(const String& effect) {
return false;
}
- String vertex_shader(effect.substr(0, split_pos));
- String fragment_shader("// " + effect.substr(split_pos));
+ String vertex_shader(kVertexHeader + effect.substr(0, split_pos));
+ String fragment_shader(kFragmentHeader + effect.substr(split_pos));
set_matrix_load_order(matrix_load_order);
diff --git a/o3d/core/cross/gles2/gles2_headers.h b/o3d/core/cross/gles2/gles2_headers.h
index e31de99..545a9d7 100644
--- a/o3d/core/cross/gles2/gles2_headers.h
+++ b/o3d/core/cross/gles2/gles2_headers.h
@@ -32,6 +32,8 @@
#ifndef O3D_CORE_CROSS_GLES2_GL_HEADERS_H_
#define O3D_CORE_CROSS_GLES2_GL_HEADERS_H_
+#if defined(GLES2_BACKEND_DESKTOP_GL)
+
#include <GL/glew.h>
#if defined(OS_WIN)
#include <GL/wglew.h>
@@ -39,4 +41,52 @@
#include <GL/glx.h>
#endif
+#elif defined(GLES2_BACKEND_NATIVE_GLES2)
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#define glClearDepth glClearDepthf
+#define glDepthRange glDepthRangef
+
+// Buffer Objects
+#define glBindBufferARB glBindBuffer
+#define glBufferDataARB glBufferData
+#define glBufferSubDataARB glBufferSubData
+#define glDeleteBuffersARB glDeleteBuffers
+#define glGenBuffersARB glGenBuffers
+
+// Framebuffer Objects
+#define glBindFramebufferEXT glBindFramebuffer
+#define glBindRenderbufferEXT glBindRenderbuffer
+#define glCheckFramebufferStatusEXT glCheckFramebufferStatus
+#define glDeleteRenderbuffersEXT glDeleteRenderbuffers
+#define glDeleteFramebuffersEXT glDeleteFramebuffers
+#define glFramebufferRenderbufferEXT glFramebufferRenderbuffer
+#define glFramebufferTexture2DEXT glFramebufferTexture2D
+#define glGenFramebuffersEXT glGenFramebuffers
+#define glGenRenderbuffersEXT glGenRenderbuffers
+#define glRenderbufferStorageEXT glRenderbufferStorage
+
+#define GLEW_VERSION_2_0 true
+#define GLEW_VERSION_1_4 true
+
+// TODO(piman): handle gracefully the case where GL_EXT_bgra isn't present.
+#define GL_BGRA 0x80E1
+
+// TODO(piman): handle gracefully the case where GL_OES_half_float isn't
+// present.
+#define GL_HALF_FLOAT_ARB GL_HALF_FLOAT_OES
+
+#elif defined(GLES2_BACKEND_GLES2_COMMAND_BUFFERS)
+
+#include <GLES2/gl2.h>
+
+#else // GLES2_BACKEND_xxx not defined
+
+#error "GLES2_BACKEND_xxx not defined"
+
+#endif // GLES2_BACKEND_xxx
+
#endif // O3D_CORE_CROSS_GLES2_GL_HEADERS_H_
diff --git a/o3d/core/cross/gles2/render_surface_gles2.cc b/o3d/core/cross/gles2/render_surface_gles2.cc
index ee0aff9..6d21dc8 100644
--- a/o3d/core/cross/gles2/render_surface_gles2.cc
+++ b/o3d/core/cross/gles2/render_surface_gles2.cc
@@ -86,44 +86,57 @@ RenderDepthStencilSurfaceGLES2::RenderDepthStencilSurfaceGLES2(
: RenderDepthStencilSurface(service_locator, width, height) {
#ifndef DISABLE_FBO
+#if defined(GLES2_BACKEND_DESKTOP_GL)
// If packed depth stencil is supported, create only one buffer for both
// depth and stencil.
+ // TODO(piman): on GLES, test GL_OES_packed_depth_stencil
if (GLEW_EXT_packed_depth_stencil) {
glGenRenderbuffersEXT(1, render_buffers_);
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[0]);
- glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
+ glBindRenderbufferEXT(GL_RENDERBUFFER, render_buffers_[0]);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER,
GL_DEPTH24_STENCIL8_EXT,
width,
height);
CHECK_GL_ERROR();
render_buffers_[1] = render_buffers_[0];
- } else {
- glGenRenderbuffersEXT(2, render_buffers_);
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[0]);
- glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
- GL_DEPTH_COMPONENT24,
- width,
- height);
- CHECK_GL_ERROR();
-
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[1]);
- glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
- GL_STENCIL_INDEX8_EXT,
- width,
- height);
- CHECK_GL_ERROR();
+ return;
}
#endif
+ glGenRenderbuffersEXT(2, render_buffers_);
+ glBindRenderbufferEXT(GL_RENDERBUFFER, render_buffers_[0]);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER,
+#if defined(GLES2_BACKEND_DESKTOP_GL)
+ GL_DEPTH_COMPONENT24,
+#else
+ // On GLES, only 16bit depth is available by default.
+ // TODO(piman): test for GL_OES_depth24 or 32 and
+ // use those.
+ GL_DEPTH_COMPONENT16,
+#endif
+ width,
+ height);
+ CHECK_GL_ERROR();
+
+ glBindRenderbufferEXT(GL_RENDERBUFFER, render_buffers_[1]);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER,
+ GL_STENCIL_INDEX8,
+ width,
+ height);
+ CHECK_GL_ERROR();
+#endif
}
RenderDepthStencilSurfaceGLES2::~RenderDepthStencilSurfaceGLES2() {
#ifndef DISABLE_FBO
+#if defined(GLES2_BACKEND_DESKTOP_GL)
+ // TODO(piman): on GLES, test GL_OES_packed_depth_stencil
if (GLEW_EXT_packed_depth_stencil) {
glDeleteRenderbuffersEXT(1, render_buffers_);
- } else {
- glDeleteRenderbuffersEXT(2, render_buffers_);
+ return;
}
#endif
+ glDeleteRenderbuffersEXT(2, render_buffers_);
+#endif
}
} // end namespace o3d
diff --git a/o3d/core/cross/gles2/renderer_gles2.cc b/o3d/core/cross/gles2/renderer_gles2.cc
index 7a0d3b7..e6012f4 100644
--- a/o3d/core/cross/gles2/renderer_gles2.cc
+++ b/o3d/core/cross/gles2/renderer_gles2.cc
@@ -81,6 +81,7 @@ GLenum ConvertCmpFunc(State::Comparison cmp) {
return GL_ALWAYS;
}
+#if defined(GLES2_BACKEND_DESKTOP_GL)
GLenum ConvertFillMode(State::Fill mode) {
switch (mode) {
case State::POINT:
@@ -94,6 +95,7 @@ GLenum ConvertFillMode(State::Fill mode) {
}
return GL_FILL;
}
+#endif
GLenum ConvertBlendFunc(State::BlendingFunction blend_func) {
switch (blend_func) {
@@ -133,10 +135,17 @@ GLenum ConvertBlendEquation(State::BlendingEquation blend_equation) {
return GL_FUNC_SUBTRACT;
case State::BLEND_REVERSE_SUBTRACT:
return GL_FUNC_REVERSE_SUBTRACT;
+#if defined(GLES2_BACKEND_DESKTOP_GL)
case State::BLEND_MIN:
return GL_MIN;
case State::BLEND_MAX:
return GL_MAX;
+#else
+ case State::BLEND_MIN:
+ case State::BLEND_MAX:
+ NOTIMPLEMENTED() << "MIN/MAX blend equation";
+ break;
+#endif
default:
break;
}
@@ -177,24 +186,24 @@ bool InstallFramebufferObjects(const RenderSurface* surface,
const RenderDepthStencilSurface* surface_depth) {
#ifdef _DEBUG
GLint bound_framebuffer;
- ::glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_framebuffer);
+ ::glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_framebuffer);
DCHECK(bound_framebuffer != 0);
#endif
// Reset the bound attachments to the current framebuffer object.
- ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- GL_RENDERBUFFER_EXT,
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
0);
- ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
- GL_DEPTH_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT,
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER,
0);
- ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
- GL_STENCIL_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT,
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER,
0);
if (surface) {
@@ -205,15 +214,15 @@ bool InstallFramebufferObjects(const RenderSurface* surface,
texture->GetTextureHandle()));
if (texture->IsA(Texture2D::GetApparentClass())) {
::glFramebufferTexture2DEXT(
- GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
+ GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
handle,
gl_surface->mip_level());
} else if (texture->IsA(TextureCUBE::GetApparentClass())) {
::glFramebufferTexture2DEXT(
- GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
+ GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
gl_surface->cube_face(),
handle,
gl_surface->mip_level());
@@ -224,17 +233,17 @@ bool InstallFramebufferObjects(const RenderSurface* surface,
// Bind both the depth and stencil attachments.
const RenderDepthStencilSurfaceGLES2* gl_surface =
down_cast<const RenderDepthStencilSurfaceGLES2*>(surface_depth);
- ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
- GL_DEPTH_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT,
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER,
gl_surface->depth_buffer());
- ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
- GL_STENCIL_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT,
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER,
gl_surface->stencil_buffer());
}
- GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
- if (GL_FRAMEBUFFER_COMPLETE_EXT != framebuffer_status) {
+ GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
+ if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status) {
return false;
}
@@ -285,6 +294,15 @@ class TypedStateHandler : public RendererGLES2::StateHandler {
}
};
+template <class T>
+class NoOpHandler : public TypedStateHandler<T> {
+ public:
+ virtual void SetStateFromTypedParam(RendererGLES2* renderer,
+ T* param) const {
+ }
+};
+
+
// A template the generates a handler for enable/disable states.
// Parameters:
// state_constant: GLenum of state we want to enable/disable
@@ -385,8 +403,12 @@ class FillModeHandler : public TypedStateHandler<ParamInteger> {
public:
virtual void SetStateFromTypedParam(RendererGLES2* renderer,
ParamInteger* param) const {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
::glPolygonMode(GL_FRONT_AND_BACK,
ConvertFillMode(static_cast<State::Fill>(param->value())));
+#else
+ NOTIMPLEMENTED() << "Fill mode";
+#endif
}
};
@@ -503,6 +525,7 @@ class PointSpriteEnableHandler : public TypedStateHandler<ParamBoolean> {
public:
virtual void SetStateFromTypedParam(RendererGLES2* renderer,
ParamBoolean* param) const {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
if (param->value()) {
::glEnable(GL_POINT_SPRITE);
// TODO(o3d): It's not clear from D3D docs that point sprites affect
@@ -514,6 +537,9 @@ class PointSpriteEnableHandler : public TypedStateHandler<ParamBoolean> {
::glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE);
::glDisable(GL_POINT_SPRITE);
}
+#else
+ NOTIMPLEMENTED() << "Point Sprites";
+#endif
}
};
@@ -521,7 +547,11 @@ class PointSizeHandler : public TypedStateHandler<ParamFloat> {
public:
virtual void SetStateFromTypedParam(RendererGLES2* renderer,
ParamFloat* param) const {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
::glPointSize(param->value());
+#else
+ NOTIMPLEMENTED() << "Point Size";
+#endif
}
};
@@ -539,8 +569,14 @@ RendererGLES2::RendererGLES2(ServiceLocator* service_locator)
#ifdef OS_LINUX
display_(NULL),
window_(0),
+#if defined(GLES2_BACKEND_DESKTOP_GL)
context_(0),
-#endif
+#elif defined(GLES2_BACKEND_NATIVE_GLES2)
+ egl_display_(NULL),
+ egl_surface_(NULL),
+ egl_context_(NULL),
+#endif // GLES_BACKEND_xxx
+#endif // OS_LINUX
#ifdef OS_MACOSX
mac_agl_context_(0),
mac_cgl_context_(0),
@@ -572,8 +608,15 @@ RendererGLES2::RendererGLES2(ServiceLocator* service_locator)
}
// Setup state handlers
+#if defined(GLES2_BACKEND_DESKTOP_GL)
AddStateHandler(State::kAlphaTestEnableParamName,
new StateEnableHandler<GL_ALPHA_TEST>);
+#else
+ // TODO(piman): Alpha test isn't supported in GLES2, because it can be done
+ // in a shader. Solution here would be to add instructions to the shader...
+ AddStateHandler(State::kAlphaTestEnableParamName,
+ new NoOpHandler<ParamBoolean>);
+#endif
AddStateHandler(State::kAlphaReferenceParamName,
new AlphaReferenceHandler);
AddStateHandler(State::kAlphaComparisonFunctionParamName,
@@ -583,8 +626,13 @@ RendererGLES2::RendererGLES2(ServiceLocator* service_locator)
new CullModeHandler);
AddStateHandler(State::kDitherEnableParamName,
new StateEnableHandler<GL_DITHER>);
+#if defined(GLES2_BACKEND_DESKTOP_GL)
AddStateHandler(State::kLineSmoothEnableParamName,
new StateEnableHandler<GL_LINE_SMOOTH>);
+#else
+ AddStateHandler(State::kLineSmoothEnableParamName,
+ new NoOpHandler<ParamBoolean>);
+#endif
AddStateHandler(State::kPointSpriteEnableParamName,
new PointSpriteEnableHandler);
AddStateHandler(State::kPointSizeParamName,
@@ -660,6 +708,7 @@ RendererGLES2::~RendererGLES2() {
// platform neutral initialization code
//
Renderer::InitStatus RendererGLES2::InitCommonGLES2() {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
GLenum glew_error = glewInit();
if (glew_error != GLEW_OK) {
DLOG(ERROR) << "Unable to initialise GLEW : "
@@ -715,9 +764,13 @@ Renderer::InitStatus RendererGLES2::InitCommonGLES2() {
if (!GLEW_VERSION_2_0 && !GLEW_EXT_blend_equation_separate) {
DLOG(ERROR) << "Separate blend function extension missing.";
}
+#elif defined(GLES2_BACKEND_NATIVE_GLES2)
+ // GLES specific initialization ?
+#endif // GLES2_BACKEND
DLOG(INFO) << "OpenGLES2 Vendor: " << ::glGetString(GL_VENDOR);
DLOG(INFO) << "OpenGLES2 Renderer: " << ::glGetString(GL_RENDERER);
DLOG(INFO) << "OpenGLES2 Version: " << ::glGetString(GL_VERSION);
+ DLOG(INFO) << "OpenGLES2 Extensions: " << ::glGetString(GL_EXTENSIONS);
// get some limits for this profile.
GLint max_vertex_attribs = 0;
::glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);
@@ -726,9 +779,14 @@ Renderer::InitStatus RendererGLES2::InitCommonGLES2() {
// Tell GLES2 that texture buffers can be single-byte aligned.
::glPixelStorei(GL_PACK_ALIGNMENT, 1);
::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+#if defined(GLES2_BACKEND_DESKTOP_GL)
::glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
::glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+#endif
CHECK_GL_ERROR();
+ // TODO(piman): by default, GLES2 has some minimal support for NPOT. Is it
+ // enough for what we use ?
+ SetSupportsNPOT(true);
GLint viewport[4];
::glGetIntegerv(GL_VIEWPORT, &viewport[0]);
@@ -1032,6 +1090,7 @@ Renderer::InitStatus RendererGLES2::InitPlatformSpecific(
static_cast<const DisplayWindowLinux&>(display_window);
Display *display = display_platform.display();
Window window = display_platform.window();
+#if defined(GLES2_BACKEND_DESKTOP_GL)
XWindowAttributes attributes;
::XGetWindowAttributes(display, window, &attributes);
XVisualInfo visual_info_template;
@@ -1072,16 +1131,148 @@ Renderer::InitStatus RendererGLES2::InitPlatformSpecific(
window_ = 0;
}
return init_status;
+#elif defined(GLES2_BACKEND_NATIVE_GLES2)
+ EGLDisplay egl_display = eglGetDisplay(display);
+ if (eglGetError() != EGL_SUCCESS) {
+ DLOG(ERROR) << "eglGetDisplay failed.";
+ return INITIALIZATION_ERROR;
+ }
+
+ EGLint major;
+ EGLint minor;
+ // TODO(piman): is it ok to do this several times ?
+ if (!eglInitialize(egl_display, &major, &minor)) {
+ DLOG(ERROR) << "eglInitialize failed.";
+ return INITIALIZATION_ERROR;
+ }
+ DLOG(INFO) << "EGL vendor:" << eglQueryString(egl_display, EGL_VENDOR);
+ DLOG(INFO) << "EGL version:" << eglQueryString(egl_display, EGL_VERSION);
+ DLOG(INFO) << "EGL extensions:"
+ << eglQueryString(egl_display, EGL_EXTENSIONS);
+ DLOG(INFO) << "EGL client apis:"
+ << eglQueryString(egl_display, EGL_CLIENT_APIS);
+
+ EGLint attribs[] = {
+#if 0
+ // On some platforms X is started in 16-bit mode, and making a 32-bit
+ // framebuffer causes tons of problems.
+ // TODO(piman): fix this.
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_DEPTH_SIZE, 24,
+ EGL_STENCIL_SIZE, 8,
+#else
+ EGL_RED_SIZE, 5,
+ EGL_GREEN_SIZE, 6,
+ EGL_BLUE_SIZE, 5,
+ EGL_DEPTH_SIZE, 16,
+ EGL_STENCIL_SIZE, 0,
+#endif
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_NONE
+ };
+
+ EGLint num_configs = -1;
+ if (!eglGetConfigs(egl_display, NULL, 0, &num_configs)) {
+ DLOG(ERROR) << "eglGetConfigs failed.";
+ return INITIALIZATION_ERROR;
+ }
+
+ EGLConfig config;
+ if (!eglChooseConfig(egl_display, attribs, &config, 1, &num_configs)) {
+ DLOG(ERROR) << "eglChooseConfig failed.";
+ return INITIALIZATION_ERROR;
+ }
+
+ EGLint red_size, green_size, blue_size, alpha_size, depth_size, stencil_size;
+ eglGetConfigAttrib(egl_display, config, EGL_RED_SIZE, &red_size);
+ eglGetConfigAttrib(egl_display, config, EGL_GREEN_SIZE, &green_size);
+ eglGetConfigAttrib(egl_display, config, EGL_BLUE_SIZE, &blue_size);
+ eglGetConfigAttrib(egl_display, config, EGL_ALPHA_SIZE, &alpha_size);
+ eglGetConfigAttrib(egl_display, config, EGL_DEPTH_SIZE, &depth_size);
+ eglGetConfigAttrib(egl_display, config, EGL_STENCIL_SIZE, &stencil_size);
+ DLOG(INFO) << "R,G,B,A: " << red_size << "," << green_size
+ << "," << blue_size << "," << alpha_size << " bits";
+ DLOG(INFO) << "Depth: " << depth_size << " bits, Stencil:" << stencil_size
+ << "bits";
+
+ EGLSurface egl_surface = eglCreateWindowSurface(egl_display, config,
+ window, NULL);
+ if (!egl_surface) {
+ DLOG(ERROR) << "eglCreateWindowSurface failed.";
+ return INITIALIZATION_ERROR;
+ }
+
+ EGLContext egl_context = eglCreateContext(egl_display, config, NULL, NULL);
+ if (!egl_context) {
+ DLOG(ERROR) << "eglCreateContext failed.";
+ eglDestroySurface(egl_display, egl_surface);
+ return INITIALIZATION_ERROR;
+ }
+
+ display_ = display;
+ window_ = window;
+ egl_display_ = egl_display;
+ egl_surface_ = egl_surface;
+ egl_context_ = egl_context;
+ if (!MakeCurrent()) {
+ eglDestroyContext(egl_display, egl_context);
+ eglDestroySurface(egl_display, egl_surface);
+ display_ = NULL;
+ window_ = 0;
+ egl_display_ = NULL;
+ egl_surface_ = NULL;
+ egl_context_ = NULL;
+ return INITIALIZATION_ERROR;
+ }
+
+ EGLint width;
+ EGLint height;
+ eglQuerySurface(egl_display, egl_surface, EGL_WIDTH, &width);
+ eglQuerySurface(egl_display, egl_surface, EGL_HEIGHT, &height);
+ glViewport(0, 0, width, height);
+
+ InitStatus init_status = InitCommonGLES2();
+ if (init_status != SUCCESS) {
+ Destroy();
+ return INITIALIZATION_ERROR;
+ }
+ return init_status;
+#else
+#error Not Implemented
+#endif
}
void RendererGLES2::Destroy() {
DestroyCommonGLES2();
if (display_) {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
::glXMakeCurrent(display_, 0, 0);
if (context_) {
::glXDestroyContext(display_, context_);
context_ = 0;
}
+#elif defined(GLES2_BACKEND_NATIVE_GLES2)
+ if (egl_display_) {
+ eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ if (egl_context_) {
+ eglDestroyContext(egl_display_, egl_context_);
+ egl_context_ = NULL;
+ }
+ if (egl_surface_) {
+ eglDestroySurface(egl_display_, egl_surface_);
+ egl_surface_ = NULL;
+ }
+ // TODO(piman): is it ok to do this if we have multiple clients ?
+ eglTerminate(egl_display_);
+ egl_display_ = NULL;
+ }
+#else
+#error Not Implemented
+#endif
display_ = NULL;
window_ = 0;
}
@@ -1107,12 +1298,24 @@ bool RendererGLES2::MakeCurrent() {
}
#endif
#ifdef OS_LINUX
+#if defined(GLES2_BACKEND_DESKTOP_GL)
if (context_ != NULL) {
bool result = ::glXMakeCurrent(display_, window_, context_) == True;
return result;
} else {
return false;
}
+#elif defined(GLES2_BACKEND_NATIVE_GLES2)
+ if (egl_context_ != NULL) {
+ EGLBoolean result = eglMakeCurrent(egl_display_, egl_surface_,
+ egl_surface_, egl_context_);
+ return result == EGL_TRUE;
+ } else {
+ return false;
+ }
+#else
+#error Not Implemented
+#endif
#endif
}
@@ -1140,22 +1343,7 @@ void RendererGLES2::UpdateHelperConstant(float width, float height) {
// If render-targets are active, pass -1 to invert the Y axis. OpenGLES2 uses
// a different viewport orientation than DX. Without the inversion, the
// output of render-target rendering will be upside down.
- if (RenderSurfaceActive()) {
- ::glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,
- 0,
- 1.0f / width,
- -1.0f / height,
- 2.0f,
- -1.0f);
- } else {
- // Only apply the origin offset when rendering to the client area.
- ::glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,
- 0,
- (1.0f + (2.0f * -dest_x_offset())) / width,
- (-1.0f + (2.0f * dest_y_offset())) / height,
- 2.0f,
- 1.0f);
- }
+ // TODO(piman): actually implement this.
CHECK_GL_ERROR();
}
@@ -1341,7 +1529,13 @@ void RendererGLES2::PlatformSpecificPresent() {
#endif
#endif
#ifdef OS_LINUX
+#if defined(GLES2_BACKEND_DESKTOP_GL)
::glXSwapBuffers(display_, window_);
+#elif defined(GLES2_BACKEND_NATIVE_GLES2)
+ eglSwapBuffers(egl_display_, egl_surface_);
+#else
+#error Not Implemented
+#endif // GLES2_BACKEND_xxx
#endif
}
@@ -1379,7 +1573,9 @@ void RendererGLES2::SetStencilStates(GLenum face,
stencil_state.op_[StencilStates::PASS_OP]);
::glStencilMaskSeparate(face,
stencil_mask_[WRITE_MASK]);
- } else if (GLEW_EXT_stencil_two_side) {
+ }
+#if defined(GLES2_BACKEND_DESKTOP_GL)
+ else if (GLEW_EXT_stencil_two_side) {
::glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
::glActiveStencilFaceEXT(face);
::glStencilFunc(stencil_state.func_,
@@ -1391,6 +1587,7 @@ void RendererGLES2::SetStencilStates(GLenum face,
::glStencilMask(stencil_mask_[WRITE_MASK]);
::glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
}
+#endif
CHECK_GL_ERROR();
}
@@ -1405,33 +1602,43 @@ void RendererGLES2::ApplyDirtyStates() {
blend_function_[DST][RGB],
blend_function_[SRC][ALPHA],
blend_function_[DST][ALPHA]);
- } else if (GLEW_EXT_blend_func_separate) {
+ }
+#if defined(GLES2_BACKEND_DESKTOP_GL)
+ else if (GLEW_EXT_blend_func_separate) {
::glBlendFuncSeparateEXT(blend_function_[SRC][RGB],
blend_function_[DST][RGB],
blend_function_[SRC][ALPHA],
blend_function_[DST][ALPHA]);
}
+#endif
if (GLEW_VERSION_2_0) {
::glBlendEquationSeparate(blend_equation_[RGB],
blend_equation_[ALPHA]);
- } else if (GLEW_EXT_blend_equation_separate) {
+ }
+#if defined(GLES2_BACKEND_DESKTOP_GL)
+ else if (GLEW_EXT_blend_equation_separate) {
::glBlendEquationSeparateEXT(blend_equation_[RGB],
blend_equation_[ALPHA]);
}
+#endif
} else {
::glBlendFunc(blend_function_[SRC][RGB],
blend_function_[DST][RGB]);
+#if defined(GLES2_BACKEND_DESKTOP_GL)
if (::glBlendEquation != NULL)
+#endif
::glBlendEquation(blend_equation_[RGB]);
}
alpha_blend_settings_changed_ = false;
}
+#if defined(GLES2_BACKEND_DESKTOP_GL)
// Set alpha settings.
if (alpha_function_ref_changed_) {
::glAlphaFunc(alpha_function_, alpha_ref_);
alpha_function_ref_changed_ = false;
}
+#endif
// Set stencil settings.
if (stencil_settings_changed_) {
@@ -1448,13 +1655,17 @@ void RendererGLES2::ApplyDirtyStates() {
bool enable = (polygon_offset_factor_ != 0.f) ||
(polygon_offset_bias_ != 0.f);
if (enable) {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
::glEnable(GL_POLYGON_OFFSET_POINT);
::glEnable(GL_POLYGON_OFFSET_LINE);
+#endif
::glEnable(GL_POLYGON_OFFSET_FILL);
::glPolygonOffset(polygon_offset_factor_, polygon_offset_bias_);
} else {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
::glDisable(GL_POLYGON_OFFSET_POINT);
::glDisable(GL_POLYGON_OFFSET_LINE);
+#endif
::glDisable(GL_POLYGON_OFFSET_FILL);
}
polygon_offset_changed_ = false;
diff --git a/o3d/core/cross/gles2/renderer_gles2.h b/o3d/core/cross/gles2/renderer_gles2.h
index eeb7260..289101c 100644
--- a/o3d/core/cross/gles2/renderer_gles2.h
+++ b/o3d/core/cross/gles2/renderer_gles2.h
@@ -143,10 +143,18 @@ class RendererGLES2 : public Renderer {
return true;
}
#elif defined(OS_LINUX)
+#if defined(GLES2_BACKEND_DESKTOP_GL)
if ((context_ != NULL) &&
(context_ == glXGetCurrentContext())) {
return true;
}
+#elif defined(GLES2_BACKEND_NATIVE_GLES2)
+ if (egl_context_ && egl_context_ == eglGetCurrentContext()) {
+ return true;
+ }
+#elif defined(GLES2_BACKEND_GLES2_COMMAND_BUFFERS)
+#error RendererGLES2::IsCurrent() Not implemented.
+#endif
#else
Error: must port RendererGLES2::IsCurrent() to your platform.
#endif
@@ -267,7 +275,13 @@ class RendererGLES2 : public Renderer {
#ifdef OS_LINUX
Display *display_;
Window window_;
+#if defined(GLES2_BACKEND_DESKTOP_GL)
GLXContext context_;
+#elif defined(GLES2_BACKEND_NATIVE_GLES2)
+ EGLDisplay egl_display_;
+ EGLSurface egl_surface_;
+ EGLContext egl_context_;
+#endif
#endif
// Handle to the framebuffer-object used while rendering to off-screen
@@ -345,4 +359,3 @@ class RendererGLES2 : public Renderer {
} // namespace o3d
#endif // O3D_CORE_CROSS_GLES2_RENDERER_GLES2_H_
-
diff --git a/o3d/core/cross/gles2/sampler_gles2.cc b/o3d/core/cross/gles2/sampler_gles2.cc
index a52affa..6f4769b 100644
--- a/o3d/core/cross/gles2/sampler_gles2.cc
+++ b/o3d/core/cross/gles2/sampler_gles2.cc
@@ -66,7 +66,12 @@ unsigned int GLAddressMode(Sampler::AddressMode o3d_mode,
gl_mode = GL_CLAMP_TO_EDGE;
break;
case Sampler::BORDER:
+#if defined(GLES2_BACKEND_DESKTOP_GL)
gl_mode = GL_CLAMP_TO_BORDER;
+#else
+ NOTIMPLEMENTED() << "Sampler::BORDER";
+ gl_mode = GL_CLAMP_TO_EDGE;
+#endif
break;
default:
DLOG(ERROR) << "Unknown Address mode " << static_cast<int>(o3d_mode);
@@ -167,7 +172,7 @@ GLint SamplerGLES2::SetTextureAndStates(GLES2Parameter gl_param) {
texture_unit_group_set_count_ = renderer_texture_unit_group_set_count;
texture_unit_ = renderer_->GetNextTextureUnit();
}
- ::glActiveTextureARB(GL_TEXTURE0 + texture_unit_);
+ ::glActiveTexture(GL_TEXTURE0 + texture_unit_);
glBindTexture(target, handle);
glTexParameteri(target,
GL_TEXTURE_WRAP_S,
@@ -175,22 +180,26 @@ GLint SamplerGLES2::SetTextureAndStates(GLES2Parameter gl_param) {
glTexParameteri(target,
GL_TEXTURE_WRAP_T,
GLAddressMode(address_mode_v(), GL_REPEAT));
- if (texture_object->IsA(TextureCUBE::GetApparentClass())) {
- glTexParameteri(target,
- GL_TEXTURE_WRAP_R,
- GLAddressMode(address_mode_w(), GL_REPEAT));
- }
+ // disable mipmapping if we have only one level.
+ FilterType clamped_mip_filter =
+ texture_object->levels() == 1 ? NONE : mip_filter();
glTexParameteri(target,
GL_TEXTURE_MIN_FILTER,
- GLMinFilter(min_filter(), mip_filter()));
+ GLMinFilter(min_filter(), clamped_mip_filter));
glTexParameteri(target,
GL_TEXTURE_MAG_FILTER,
GLMagFilter(mag_filter()));
+#if defined(GLES2_BACKEND_DESKTOP_GL)
Float4 color = border_color();
GLfloat gl_color[4] = {color[0], color[1], color[2], color[3]};
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, gl_color);
+#else
+ // Not implemented
+#endif
+
+#if defined(GLES2_BACKEND_DESKTOP_GL)
// Check for anisotropic texture filtering.
if (GLEW_EXT_texture_filter_anisotropic) {
int gl_max_anisotropy =
@@ -198,6 +207,10 @@ GLint SamplerGLES2::SetTextureAndStates(GLES2Parameter gl_param) {
glTexParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
gl_max_anisotropy);
}
+#else
+ // TODO(piman): test for GL_EXT_texture_filter_anisotropic and implement
+ // as above.
+#endif
}
}
@@ -211,10 +224,9 @@ void SamplerGLES2::ResetTexture(GLES2Parameter gl_param) {
// time.
GLenum target = GLTextureTarget(the_texture);
if (target) {
- glActiveTextureARB(GL_TEXTURE0 + texture_unit_);
+ glActiveTexture(GL_TEXTURE0 + texture_unit_);
glBindTexture(target, 0);
}
}
}
} // namespace o3d
-
diff --git a/o3d/core/cross/gles2/stream_bank_gles2.cc b/o3d/core/cross/gles2/stream_bank_gles2.cc
index 1501f35..1657a0a 100644
--- a/o3d/core/cross/gles2/stream_bank_gles2.cc
+++ b/o3d/core/cross/gles2/stream_bank_gles2.cc
@@ -67,7 +67,7 @@ GLenum GLDataType(const Field& field) {
}
String GetAttribName(GLuint gl_program, GLES2Parameter gl_param) {
- GLchar buffer[1024];
+ char buffer[1024];
GLsizei name_len;
GLint size;
GLenum type;
@@ -223,4 +223,3 @@ int StreamBankGLES2::FindVertexStream(Stream::Semantic semantic, int index) {
}
} // namespace o3d
-
diff --git a/o3d/core/cross/gles2/texture_gles2.cc b/o3d/core/cross/gles2/texture_gles2.cc
index f03340e..ef37c2e 100644
--- a/o3d/core/cross/gles2/texture_gles2.cc
+++ b/o3d/core/cross/gles2/texture_gles2.cc
@@ -67,30 +67,52 @@ static GLenum GLFormatFromO3DFormat(Texture::Format format,
GLenum *data_type) {
switch (format) {
case Texture::XRGB8: {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
*internal_format = GL_RGB;
+#else
+ // On GLES, the internal_format must match format.
+ *internal_format = GL_BGRA;
+#endif
*data_type = GL_UNSIGNED_BYTE;
return GL_BGRA;
}
case Texture::ARGB8: {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
*internal_format = GL_RGBA;
+#else
+ *internal_format = GL_BGRA;
+#endif
*data_type = GL_UNSIGNED_BYTE;
return GL_BGRA;
}
case Texture::ABGR16F: {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
*internal_format = GL_RGBA16F_ARB;
+#else
+ *internal_format = GL_RGBA;
+#endif
*data_type = GL_HALF_FLOAT_ARB;
return GL_RGBA;
}
case Texture::R32F: {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
*internal_format = GL_LUMINANCE32F_ARB;
+#else
+ *internal_format = GL_LUMINANCE;
+#endif
*data_type = GL_FLOAT;
return GL_LUMINANCE;
}
case Texture::ABGR32F: {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
*internal_format = GL_RGBA32F_ARB;
+#else
+ *internal_format = GL_BGRA;
+#endif
*data_type = GL_FLOAT;
return GL_BGRA;
}
+#if defined(GLES2_BACKEND_DESKTOP_GL)
case Texture::DXT1: {
if (GL_EXT_texture_compression_s3tc) {
*internal_format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
@@ -136,6 +158,15 @@ static GLenum GLFormatFromO3DFormat(Texture::Format format,
return 0;
}
}
+#else
+ case Texture::DXT1:
+ case Texture::DXT3:
+ case Texture::DXT5:
+ NOTIMPLEMENTED() << "DXT textures";
+ *internal_format = 0;
+ *data_type = GL_BYTE;
+ return 0;
+#endif
case Texture::UNKNOWN_FORMAT:
break;
}
@@ -184,8 +215,12 @@ static bool UpdateGLImageFromBitmap(GLenum target,
glTexSubImage2D(target, level, 0, 0, mip_width, mip_height,
gl_format, gl_data_type, mip_data);
} else {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
glCompressedTexSubImage2D(target, level, 0, 0, mip_width, mip_height,
gl_internal_format, mip_size, mip_data);
+#else
+ NOTIMPLEMENTED() << "DXT textures";
+#endif
}
return glGetError() == GL_NO_ERROR;
}
@@ -226,6 +261,7 @@ static bool CreateGLImages(GLenum target,
return false;
}
} else {
+#if defined(GLES2_BACKEND_DESKTOP_GL)
size_t mip_size = image::ComputeBufferSize(mip_width, mip_height, format);
glCompressedTexImage2DARB(target, i, internal_format, mip_width,
mip_height, 0, mip_size, temp_data.get());
@@ -233,6 +269,10 @@ static bool CreateGLImages(GLenum target,
DLOG(ERROR) << "glCompressedTexImage2D failed";
return false;
}
+#else
+ NOTIMPLEMENTED() << "DXT textures";
+ return false;
+#endif
}
mip_width = std::max(1U, mip_width >> 1);
mip_height = std::max(1U, mip_height >> 1);
@@ -299,8 +339,16 @@ Texture2DGLES2* Texture2DGLES2::Create(ServiceLocator* service_locator,
GLuint gl_texture = 0;
glGenTextures(1, &gl_texture);
glBindTexture(GL_TEXTURE_2D, gl_texture);
+#if defined(GLES2_BACKEND_DESKTOP_GL)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,
levels - 1);
+#else
+ // On GLES2, we can't specify GL_TEXTURE_MAX_LEVEL, so we either allocate
+ // only the base image, and clamp the min filter, or we allocate all of them.
+ if (levels > 1) {
+ levels = image::ComputeMipMapCount(width, height);
+ }
+#endif
if (!CreateGLImages(GL_TEXTURE_2D, gl_internal_format, gl_format,
gl_data_type, TextureCUBE::FACE_POSITIVE_X,
@@ -316,13 +364,6 @@ Texture2DGLES2* Texture2DGLES2::Create(ServiceLocator* service_locator,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- GLint gl_width;
- GLint gl_height;
- glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &gl_width);
- glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &gl_height);
-
- DLOG(INFO) << "Created 2D texture (size=" << gl_width << "x" << gl_height
- << ", GLuint=" << gl_texture << ")";
Texture2DGLES2 *texture = new Texture2DGLES2(service_locator,
gl_texture,
format,
@@ -478,6 +519,7 @@ bool Texture2DGLES2::PlatformSpecificLock(
}
if (mode != kWriteOnly && !HasLevel(level)) {
DCHECK(!resize_to_pot_);
+#if defined(GLES2_BACKEND_DESKTOP_GL)
GLenum gl_internal_format = 0;
GLenum gl_data_type = 0;
GLenum gl_format = GLFormatFromO3DFormat(format(),
@@ -485,6 +527,9 @@ bool Texture2DGLES2::PlatformSpecificLock(
&gl_data_type);
glBindTexture(GL_TEXTURE_2D, gl_texture_);
glGetTexImage(GL_TEXTURE_2D, level, gl_format, gl_data_type, *data);
+#else
+ NOTIMPLEMENTED() << "Texture read back";
+#endif
has_levels_ |= 1 << level;
}
locked_levels_ |= 1 << level;
@@ -617,8 +662,16 @@ TextureCUBEGLES2* TextureCUBEGLES2::Create(ServiceLocator* service_locator,
GLuint gl_texture = 0;
glGenTextures(1, &gl_texture);
glBindTexture(GL_TEXTURE_CUBE_MAP, gl_texture);
+#if defined(GLES2_BACKEND_DESKTOP_GL)
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL,
levels - 1);
+#else
+ // On GLES2, we can't specify GL_TEXTURE_MAX_LEVEL, so we either allocate
+ // only the base image, and clamp the min filter, or we allocate all of them.
+ if (levels > 1) {
+ levels = image::ComputeMipMapCount(edge_length, edge_length);
+ }
+#endif
for (int face = 0; face < static_cast<int>(NUMBER_OF_FACES); ++face) {
CreateGLImages(kCubemapFaceList[face], gl_internal_format,
@@ -816,18 +869,22 @@ bool TextureCUBEGLES2::PlatformSpecificLock(
unsigned bytes_per_row = bytes_per_block * blocks_across;
*pitch = bytes_per_row;
}
- GLenum gl_target = kCubemapFaceList[face];
if (mode != kWriteOnly && !HasLevel(face, level)) {
// TODO(o3d): add some API so we don't have to copy back the data if we
// will rewrite it all.
DCHECK(!resize_to_pot_);
+#if defined(GLES2_BACKEND_DESKTOP_GL)
GLenum gl_internal_format = 0;
GLenum gl_data_type = 0;
GLenum gl_format = GLFormatFromO3DFormat(format(),
&gl_internal_format,
&gl_data_type);
glBindTexture(GL_TEXTURE_CUBE_MAP, gl_texture_);
+ GLenum gl_target = kCubemapFaceList[face];
glGetTexImage(gl_target, level, gl_format, gl_data_type, *data);
+#else
+ NOTIMPLEMENTED() << "Texture read back";
+#endif
has_levels_[face] |= 1 << level;
}
CHECK_GL_ERROR();
@@ -875,4 +932,3 @@ const Texture::RGBASwizzleIndices&
}
} // namespace o3d
-
diff --git a/o3d/plugin/cross/o3d_glue.h b/o3d/plugin/cross/o3d_glue.h
index d732c13..3e7f8a7 100644
--- a/o3d/plugin/cross/o3d_glue.h
+++ b/o3d/plugin/cross/o3d_glue.h
@@ -41,7 +41,7 @@
#endif
#ifdef OS_LINUX
-#include <GL/glx.h>
+#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <gtk/gtk.h>
#endif
diff --git a/o3d/plugin/plugin.gyp b/o3d/plugin/plugin.gyp
index 9fca8f9..1e18f0b 100644
--- a/o3d/plugin/plugin.gyp
+++ b/o3d/plugin/plugin.gyp
@@ -212,11 +212,6 @@
'-Wl,-znodelete',
'-Wl,--gc-sections',
],
- 'link_settings': {
- 'libraries': [
- '-lGL',
- ],
- },
'conditions' : [
['plugin_rpath != ""',
{