1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "GLEScmContext.h"
18 #include "GLEScmUtils.h"
19 #include <GLcommon/GLutils.h>
20 #include <GLcommon/GLconversion_macros.h>
21 #include <string.h>
22 #include <GLES/gl.h>
23 #include <GLES/glext.h>
24
25 #include "base/Lock.h"
26 #include "base/StreamSerializing.h"
27 #include "host-common/crash_reporter.h"
28 #include "GLEScmValidate.h"
29
30 #include <glm/vec3.hpp>
31 #include <glm/vec4.hpp>
32 #include <glm/gtc/matrix_transform.hpp>
33 #include <glm/gtc/type_ptr.hpp>
34
35 static GLESVersion s_maxGlesVersion = GLES_1_1;
36
setMaxGlesVersion(GLESVersion version)37 void GLEScmContext::setMaxGlesVersion(GLESVersion version) {
38 s_maxGlesVersion = version;
39 }
40
init()41 void GLEScmContext::init() {
42 android::base::AutoLock mutex(s_lock);
43 if(!m_initialized) {
44 GLEScontext::init();
45
46 addVertexArrayObject(0);
47 setVertexArrayObject(0);
48
49 m_currVaoState[GL_COLOR_ARRAY] = new GLESpointer();
50 m_currVaoState[GL_NORMAL_ARRAY] = new GLESpointer();
51 m_currVaoState[GL_VERTEX_ARRAY] = new GLESpointer();
52 m_currVaoState[GL_POINT_SIZE_ARRAY_OES] = new GLESpointer();
53
54 m_texCoords = new GLESpointer[kMaxTextureUnits];
55 m_currVaoState[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_clientActiveTexture];
56
57 if (isCoreProfile()) {
58 m_coreProfileEngine = new CoreProfileEngine(this);
59 } else if (isGles2Gles()) {
60 m_coreProfileEngine = new CoreProfileEngine(this, true /* gles2gles */);
61 }
62 mColor.type = GL_UNSIGNED_BYTE;
63 mColor.val.ubyteVal[0] = 255;
64 mColor.val.ubyteVal[1] = 255;
65 mColor.val.ubyteVal[2] = 255;
66 mColor.val.ubyteVal[3] = 255;
67 mNormal.type = GL_FLOAT;
68 mNormal.val.floatVal[0] = 0.0f;
69 mNormal.val.floatVal[1] = 0.0f;
70 mNormal.val.floatVal[2] = 1.0f;
71 }
72 m_initialized = true;
73 }
74
initGlobal(EGLiface * eglIface)75 void GLEScmContext::initGlobal(EGLiface* eglIface) {
76 s_glDispatch.dispatchFuncs(s_maxGlesVersion, eglIface->eglGetGlLibrary(), eglIface->getProcAddress);
77 GLEScontext::initGlobal(eglIface);
78 buildStrings(true /* is gles1 */,
79 (const char*)dispatcher().glGetString(GL_VENDOR),
80 (const char*)dispatcher().glGetString(GL_RENDERER),
81 (const char*)dispatcher().glGetString(GL_VERSION),
82 "OpenGL ES-CM 1.1");
83 }
84
initDefaultFBO(GLint width,GLint height,GLint colorFormat,GLint depthstencilFormat,GLint multisamples,GLuint * eglSurfaceRBColorId,GLuint * eglSurfaceRBDepthId,GLuint readWidth,GLint readHeight,GLint readColorFormat,GLint readDepthstencilFormat,GLint readMultisamples,GLuint * eglReadSurfaceRBColorId,GLuint * eglReadSurfaceRBDepthId)85 void GLEScmContext::initDefaultFBO(
86 GLint width, GLint height, GLint colorFormat, GLint depthstencilFormat, GLint multisamples,
87 GLuint* eglSurfaceRBColorId, GLuint* eglSurfaceRBDepthId,
88 GLuint readWidth, GLint readHeight, GLint readColorFormat, GLint readDepthstencilFormat, GLint readMultisamples,
89 GLuint* eglReadSurfaceRBColorId, GLuint* eglReadSurfaceRBDepthId) {
90 GLEScontext::initDefaultFBO(
91 width, height, colorFormat, depthstencilFormat, multisamples,
92 eglSurfaceRBColorId, eglSurfaceRBDepthId,
93 readWidth, readHeight, readColorFormat, readDepthstencilFormat, readMultisamples,
94 eglReadSurfaceRBColorId, eglReadSurfaceRBDepthId
95 );
96 }
97
GLEScmContext(int maj,int min,GlobalNameSpace * globalNameSpace,android::base::Stream * stream)98 GLEScmContext::GLEScmContext(int maj, int min,
99 GlobalNameSpace* globalNameSpace, android::base::Stream* stream)
100 : GLEScontext(globalNameSpace, stream, nullptr) {
101 if (stream) {
102 assert(maj == m_glesMajorVersion);
103 assert(min == m_glesMinorVersion);
104 android::base::loadBuffer(stream, &mProjMatrices);
105 android::base::loadBuffer(stream, &mModelviewMatrices);
106 android::base::loadBuffer(stream, &mTextureMatrices,
107 [](android::base::Stream* stream) {
108 MatrixStack matrices;
109 android::base::loadBuffer(stream, &matrices);
110 return matrices;
111 });
112 android::base::loadBuffer(stream, &mTexUnitEnvs,
113 [](android::base::Stream* stream) {
114 TexEnv texEnv;
115 android::base::loadCollection(stream, &texEnv,
116 [] (android::base::Stream* stream) {
117 GLenum idx = stream->getBe32();
118 GLValTyped val;
119 stream->read(&val, sizeof(GLValTyped));
120 return std::make_pair(idx, val);
121 });
122 return texEnv;
123 });
124 android::base::loadBuffer(stream, &mTexGens,
125 [](android::base::Stream* stream) {
126 TexEnv texEnv;
127 android::base::loadCollection(stream, &texEnv,
128 [] (android::base::Stream* stream) {
129 GLenum idx = stream->getBe32();
130 GLValTyped val;
131 stream->read(&val, sizeof(GLValTyped));
132 return std::make_pair(idx, val);
133 });
134 return texEnv;
135 });
136 m_clientActiveTexture = stream->getBe32();
137 if (m_initialized) {
138 mShadeModel = stream->getBe32();
139 stream->read((void*)&mColor, sizeof(mColor));
140 stream->read((void*)&mNormal, sizeof(mNormal));
141 uint32_t size = stream->getBe32();
142 m_texCoords = new GLESpointer[size];
143 for (uint32_t i = 0; i < size; i++) {
144 m_texCoords[i].onLoad(stream);
145 }
146 m_currVaoState[GL_TEXTURE_COORD_ARRAY] =
147 &m_texCoords[m_clientActiveTexture];
148 }
149
150 android::base::loadBufferPtr<GLVal>(stream, mMultiTexCoord);
151 android::base::loadBufferPtr<Material>(stream, &mMaterial);
152 android::base::loadBufferPtr<LightModel>(stream, &mLightModel);
153 android::base::loadBufferPtr<Light>(stream, mLights);
154 android::base::loadBufferPtr<Fog>(stream, &mFog);
155
156 } else {
157 m_glesMajorVersion = maj;
158 m_glesMinorVersion = min;
159
160 mProjMatrices.resize(1, glm::mat4());
161 mModelviewMatrices.resize(1, glm::mat4());
162 mTextureMatrices.resize(kMaxTextureUnits, { glm::mat4() });
163 mTexUnitEnvs.resize(kMaxTextureUnits, TexEnv());
164 mTexGens.resize(kMaxTextureUnits, TexEnv());
165
166 for (int i = 0; i < kMaxTextureUnits; i++) {
167 mTexUnitEnvs[i][GL_TEXTURE_ENV_MODE].val.intVal[0] = GL_MODULATE;
168 mTexUnitEnvs[i][GL_TEXTURE_ENV_MODE].type = GL_INT;
169 mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[0] = 0.2f;
170 mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[1] = 0.4f;
171 mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[2] = 0.8f;
172 mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[3] = 0.7f;
173 mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].type = GL_FLOAT;
174 mTexUnitEnvs[i][GL_COMBINE_RGB].val.intVal[0] = GL_REPLACE;
175 mTexUnitEnvs[i][GL_COMBINE_RGB].type = GL_INT;
176 mTexUnitEnvs[i][GL_COMBINE_ALPHA].val.intVal[0] = GL_REPLACE;
177 mTexUnitEnvs[i][GL_COMBINE_ALPHA].type = GL_INT;
178 }
179
180 // GL_LIGHT0 starts off as white
181 mLights[0].diffuse[0] = 1.0f;
182 mLights[0].diffuse[1] = 1.0f;
183 mLights[0].diffuse[2] = 1.0f;
184 mLights[0].diffuse[3] = 1.0f;
185 mLights[0].specular[0] = 1.0f;
186 mLights[0].specular[1] = 1.0f;
187 mLights[0].specular[2] = 1.0f;
188 mLights[0].specular[3] = 1.0f;
189 }
190 }
191
192
setActiveTexture(GLenum tex)193 void GLEScmContext::setActiveTexture(GLenum tex) {
194 m_activeTexture = tex - GL_TEXTURE0;
195 }
196
setClientActiveTexture(GLenum tex)197 void GLEScmContext::setClientActiveTexture(GLenum tex) {
198 m_clientActiveTexture = tex - GL_TEXTURE0;
199 m_currVaoState[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_clientActiveTexture];
200 }
201
setBindedTexture(GLenum target,unsigned int texture,unsigned int globalTexName)202 void GLEScmContext::setBindedTexture(GLenum target, unsigned int texture, unsigned int globalTexName) {
203 GLEScontext::setBindedTexture(target, texture);
204 }
205
~GLEScmContext()206 GLEScmContext::~GLEScmContext(){
207 if(m_texCoords){
208 delete[] m_texCoords;
209 m_texCoords = NULL;
210 }
211 if (m_vaoStateMap.size()) {
212 m_currVaoState[GL_TEXTURE_COORD_ARRAY] = NULL;
213 }
214
215 if (m_coreProfileEngine) {
216 delete m_coreProfileEngine;
217 m_coreProfileEngine = NULL;
218 }
219 }
220
getMaterialInfo()221 const GLEScmContext::Material& GLEScmContext::getMaterialInfo() {
222 return mMaterial;
223 }
224
getLightModelInfo()225 const GLEScmContext::LightModel& GLEScmContext::getLightModelInfo() {
226 return mLightModel;
227 }
228
getLightInfo(uint32_t lightIndex)229 const GLEScmContext::Light& GLEScmContext::getLightInfo(uint32_t lightIndex) {
230 return mLights[lightIndex];
231 }
232
getFogInfo()233 const GLEScmContext::Fog& GLEScmContext::getFogInfo() {
234 return mFog;
235 }
236
onSave(android::base::Stream * stream) const237 void GLEScmContext::onSave(android::base::Stream* stream) const {
238 GLEScontext::onSave(stream);
239 android::base::saveBuffer(stream, mProjMatrices);
240 android::base::saveBuffer(stream, mModelviewMatrices);
241 android::base::saveBuffer(stream, mTextureMatrices,
242 [](android::base::Stream* stream, const MatrixStack& matrices) {
243 android::base::saveBuffer(stream, matrices);
244 });
245 android::base::saveBuffer(stream, mTexUnitEnvs,
246 [](android::base::Stream* stream, const TexEnv& texEnv) {
247 android::base::saveCollection(stream, texEnv,
248 [] (android::base::Stream* stream,
249 const std::pair<GLenum, GLValTyped>& it) {
250 stream->putBe32(it.first);
251 stream->write(&it.second, sizeof(GLValTyped));
252 });
253 });
254 android::base::saveBuffer(stream, mTexGens,
255 [](android::base::Stream* stream, const TexEnv& texEnv) {
256 android::base::saveCollection(stream, texEnv,
257 [] (android::base::Stream* stream,
258 const std::pair<GLenum, GLValTyped>& it) {
259 stream->putBe32(it.first);
260 stream->write(&it.second, sizeof(GLValTyped));
261 });
262 });
263 stream->putBe32(m_clientActiveTexture);
264 if (m_initialized) {
265 stream->putBe32(mShadeModel);
266 stream->write((void*)&mColor, sizeof(mColor));
267 stream->write((void*)&mNormal, sizeof(mNormal));
268 stream->putBe32(kMaxTextureUnits);
269 for (uint32_t i = 0; i < kMaxTextureUnits; i++) {
270 m_texCoords[i].onSave(stream);
271 }
272 }
273
274 android::base::saveBuffer<GLVal>(stream, mMultiTexCoord, kMaxTextureUnits);
275 android::base::saveBuffer<Material>(stream, &mMaterial, 1);
276 android::base::saveBuffer<LightModel>(stream, &mLightModel, 1);
277 android::base::saveBuffer<Light>(stream, mLights, kMaxLights);
278 android::base::saveBuffer<Fog>(stream, &mFog, 1);
279 }
280
restoreMatrixStack(const MatrixStack & matrices)281 void GLEScmContext::restoreMatrixStack(const MatrixStack& matrices) {
282 for (size_t i = 0; i < matrices.size(); i++) {
283 if (i > 0) {
284 dispatcher().glPushMatrix();
285 }
286 dispatcher().glLoadMatrixf(&matrices[i][0][0]);
287 }
288 }
289
postLoadRestoreCtx()290 void GLEScmContext::postLoadRestoreCtx() {
291 if (isInitialized()) {
292 if (isCoreProfile()) {
293 m_coreProfileEngine = new CoreProfileEngine(this);
294 } else if (isGles2Gles()) {
295 m_coreProfileEngine = new CoreProfileEngine(this, true);
296 }
297 if (!m_coreProfileEngine) {
298 GLDispatch& dispatcher = GLEScontext::dispatcher();
299 dispatcher.glMatrixMode(GL_PROJECTION);
300 restoreMatrixStack(mProjMatrices);
301 dispatcher.glMatrixMode(GL_MODELVIEW);
302 restoreMatrixStack(mModelviewMatrices);
303 dispatcher.glMatrixMode(GL_TEXTURE);
304 for (size_t i = 0; i < mTextureMatrices.size(); i++) {
305 if (mTextureMatrices[i].size() == 0) {
306 continue;
307 }
308 dispatcher.glActiveTexture(GL_TEXTURE0 + i);
309 restoreMatrixStack(mTextureMatrices[i]);
310 }
311 for (const auto& array : m_currVaoState) {
312 if (array.first == GL_TEXTURE_COORD_ARRAY) continue;
313 array.second->restoreBufferObj(getBufferObj);
314 }
315 for (uint32_t i = 0; i < kMaxTextureUnits; i++) {
316 m_texCoords[i].restoreBufferObj(getBufferObj);
317 }
318 dispatcher.glMatrixMode(mCurrMatrixMode);
319 dispatcher.glActiveTexture(GL_TEXTURE0 + m_activeTexture);
320 for (const auto& it : *m_currVaoState.it->second.arraysMap) {
321 if (GLEScmValidate::supportedArrays(it.first) &&
322 it.first != GL_TEXTURE_COORD_ARRAY) {
323 if (it.second->isEnable()) {
324 dispatcher.glEnableClientState(it.first);
325 } else {
326 dispatcher.glDisableClientState(it.first);
327 }
328 }
329 }
330
331 for (int i = 0; i < kMaxTextureUnits; i++) {
332 GLESpointer* texcoord = m_texCoords + i;
333 dispatcher.glClientActiveTexture(i + GL_TEXTURE0);
334 if (texcoord->isEnable()) {
335 dispatcher.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
336 } else {
337 dispatcher.glDisableClientState(GL_TEXTURE_COORD_ARRAY);
338 }
339 dispatcher.glActiveTexture(i + GL_TEXTURE0);
340 for (const auto& texEnv : mTexUnitEnvs[i]) {
341 GLenum target = texEnv.first == GL_POINT_SPRITE_OES ?
342 GL_COORD_REPLACE_OES : GL_TEXTURE_ENV;
343 if (texEnv.second.type == GL_INT) {
344 dispatcher.glTexEnviv(target, texEnv.first,
345 texEnv.second.val.intVal);
346 } else {
347 assert(texEnv.second.type == GL_FLOAT);
348 dispatcher.glTexEnvfv(target, texEnv.first,
349 texEnv.second.val.floatVal);
350 }
351 }
352 }
353 dispatcher.glClientActiveTexture(
354 m_clientActiveTexture + GL_TEXTURE0);
355 dispatcher.glActiveTexture(m_activeTexture + GL_TEXTURE0);
356 dispatcher.glShadeModel(mShadeModel);
357 switch (mColor.type) {
358 case GL_FLOAT:
359 dispatcher.glColor4f(mColor.val.floatVal[0],
360 mColor.val.floatVal[1],
361 mColor.val.floatVal[2],
362 mColor.val.floatVal[3]);
363 break;
364 case GL_UNSIGNED_BYTE:
365 dispatcher.glColor4ub(mColor.val.ubyteVal[0],
366 mColor.val.ubyteVal[1],
367 mColor.val.ubyteVal[2],
368 mColor.val.ubyteVal[3]);
369 break;
370 default:
371 fprintf(stderr, "WARNING: glColor with unknown type 0x%x\n",
372 mColor.type);
373 break;
374 }
375 switch (mNormal.type) {
376 case GL_FLOAT:
377 dispatcher.glNormal3f(mNormal.val.floatVal[0],
378 mNormal.val.floatVal[1],
379 mNormal.val.floatVal[2]);
380 break;
381 default:
382 fprintf(stderr, "WARNING: glNormal with unknown type 0x%x\n",
383 mNormal.type);
384 break;
385 }
386
387 dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mMaterial.ambient);
388 dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mMaterial.diffuse);
389 dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mMaterial.specular);
390 dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mMaterial.emissive);
391 dispatcher.glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mMaterial.specularExponent);
392
393 dispatcher.glLightModelfv(GL_LIGHT_MODEL_AMBIENT, mLightModel.color);
394 dispatcher.glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, mLightModel.twoSided);
395
396 for (int i = 0; i < kMaxLights; i++) {
397 dispatcher.glLightfv(GL_LIGHT0 + i, GL_AMBIENT, mLights[i].ambient);
398 dispatcher.glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, mLights[i].diffuse);
399 dispatcher.glLightfv(GL_LIGHT0 + i, GL_SPECULAR, mLights[i].specular);
400 dispatcher.glLightfv(GL_LIGHT0 + i, GL_POSITION, mLights[i].position);
401 dispatcher.glLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, mLights[i].direction);
402 dispatcher.glLightf(GL_LIGHT0 + i, GL_SPOT_EXPONENT, mLights[i].spotlightExponent);
403 dispatcher.glLightf(GL_LIGHT0 + i, GL_SPOT_CUTOFF, mLights[i].spotlightCutoffAngle);
404 dispatcher.glLightf(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, mLights[i].attenuationConst);
405 dispatcher.glLightf(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, mLights[i].attenuationLinear);
406 dispatcher.glLightf(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, mLights[i].attenuationQuadratic);
407 }
408
409 dispatcher.glFogf(GL_FOG_MODE, (GLfloat)mFog.mode);
410 dispatcher.glFogf(GL_FOG_DENSITY, mFog.density);
411 dispatcher.glFogf(GL_FOG_START, mFog.start);
412 dispatcher.glFogf(GL_FOG_END, mFog.end);
413 dispatcher.glFogfv(GL_FOG_COLOR, mFog.color);
414 }
415 }
416 GLEScontext::postLoadRestoreCtx();
417 }
418
419 //setting client side arr
setupArr(const GLvoid * arr,GLenum arrayType,GLenum dataType,GLint size,GLsizei stride,GLboolean normalized,int index,bool isInt)420 void GLEScmContext::setupArr(const GLvoid* arr,GLenum arrayType,GLenum dataType,GLint size,GLsizei stride,GLboolean normalized, int index, bool isInt){
421 if( arr == NULL) return;
422 switch(arrayType) {
423 case GL_VERTEX_ARRAY:
424 s_glDispatch.glVertexPointer(size,dataType,stride,arr);
425 break;
426 case GL_NORMAL_ARRAY:
427 s_glDispatch.glNormalPointer(dataType,stride,arr);
428 break;
429 case GL_TEXTURE_COORD_ARRAY:
430 s_glDispatch.glTexCoordPointer(size,dataType,stride,arr);
431 break;
432 case GL_COLOR_ARRAY:
433 s_glDispatch.glColorPointer(size,dataType,stride,arr);
434 break;
435 case GL_POINT_SIZE_ARRAY_OES:
436 m_pointsIndex = index;
437 break;
438 }
439 }
440
441
setupArrayPointerHelper(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLenum array_id,GLESpointer * p)442 void GLEScmContext::setupArrayPointerHelper(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLenum array_id,GLESpointer* p){
443 unsigned int size = p->getSize();
444 GLenum dataType = p->getType();
445
446 if(needConvert(cArrs,first,count,type,indices,direct,p,array_id)){
447 //conversion has occured
448 ArrayData currentArr = cArrs.getCurrentArray();
449 setupArr(currentArr.data,array_id,currentArr.type,size,currentArr.stride,GL_FALSE, cArrs.getCurrentIndex());
450 ++cArrs;
451 } else {
452 setupArr(p->getData(),array_id,dataType,size,p->getStride(), GL_FALSE);
453 }
454 }
455
setupArraysPointers(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct)456 void GLEScmContext::setupArraysPointers(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct) {
457 ArraysMap::iterator it;
458 m_pointsIndex = -1;
459
460 //going over all clients arrays Pointers
461 for ( it=m_currVaoState.begin() ; it != m_currVaoState.end(); ++it) {
462
463 GLenum array_id = (*it).first;
464 GLESpointer* p = (*it).second;
465 if(!p->isEnable()) continue;
466 if(array_id == GL_TEXTURE_COORD_ARRAY) continue; //handling textures later
467 setupArrayPointerHelper(cArrs,first,count,type,indices,direct,array_id,p);
468 }
469
470 unsigned int activeTexture = m_clientActiveTexture + GL_TEXTURE0;
471
472 //converting all texture coords arrays
473 for(int i=0; i< kMaxTextureUnits;i++) {
474
475 unsigned int tex = GL_TEXTURE0+i;
476 setClientActiveTexture(tex);
477 s_glDispatch.glClientActiveTexture(tex);
478
479 GLenum array_id = GL_TEXTURE_COORD_ARRAY;
480 GLESpointer* p = m_currVaoState[array_id];
481 if(!p->isEnable()) continue;
482 setupArrayPointerHelper(cArrs,first,count,type,indices,direct,array_id,p);
483 }
484
485 setClientActiveTexture(activeTexture);
486 s_glDispatch.glClientActiveTexture(activeTexture);
487 }
488
drawPointsData(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices_in,bool isElemsDraw)489 void GLEScmContext::drawPointsData(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices_in,bool isElemsDraw) {
490 const char *pointsArr = NULL;
491 int stride = 0;
492 GLESpointer* p = m_currVaoState[GL_POINT_SIZE_ARRAY_OES];
493
494 //choosing the right points sizes array source
495 if(m_pointsIndex >= 0) { //point size array was converted
496 pointsArr = (const char*)(cArrs[m_pointsIndex].data);
497 stride = cArrs[m_pointsIndex].stride;
498 } else {
499 pointsArr = static_cast<const char*>(p->getData());
500 stride = p->getStride();
501 }
502
503 if(stride == 0){
504 stride = sizeof(GLfloat);
505 }
506
507
508 if(isElemsDraw) {
509 int tSize = 0;
510 switch (type) {
511 case GL_UNSIGNED_BYTE:
512 tSize = 1;
513 break;
514 case GL_UNSIGNED_SHORT:
515 tSize = 2;
516 break;
517 case GL_UNSIGNED_INT:
518 tSize = 4;
519 break;
520 };
521
522 int i = 0;
523 while(i<count)
524 {
525 int sStart = i;
526 int sCount = 1;
527
528 #define INDEX \
529 (type == GL_UNSIGNED_INT ? \
530 static_cast<const GLuint*>(indices_in)[i]: \
531 type == GL_UNSIGNED_SHORT ? \
532 static_cast<const GLushort*>(indices_in)[i]: \
533 static_cast<const GLubyte*>(indices_in)[i])
534
535 GLfloat pSize = *((GLfloat*)(pointsArr+(INDEX*stride)));
536 i++;
537
538 while(i < count && pSize == *((GLfloat*)(pointsArr+(INDEX*stride))))
539 {
540 sCount++;
541 i++;
542 }
543
544 s_glDispatch.glPointSize(pSize);
545 s_glDispatch.glDrawElements(GL_POINTS, sCount, type, (char*)indices_in+sStart*tSize);
546 }
547 } else {
548 int i = 0;
549 while(i<count)
550 {
551 int sStart = i;
552 int sCount = 1;
553 GLfloat pSize = *((GLfloat*)(pointsArr+((first+i)*stride)));
554 i++;
555
556 while(i < count && pSize == *((GLfloat*)(pointsArr+((first+i)*stride))))
557 {
558 sCount++;
559 i++;
560 }
561
562 s_glDispatch.glPointSize(pSize);
563 s_glDispatch.glDrawArrays(GL_POINTS, first+sStart, sCount);
564 }
565 }
566 }
567
drawPointsArrs(GLESConversionArrays & arrs,GLint first,GLsizei count)568 void GLEScmContext::drawPointsArrs(GLESConversionArrays& arrs,GLint first,GLsizei count) {
569 drawPointsData(arrs,first,count,0,NULL,false);
570 }
571
drawPointsElems(GLESConversionArrays & arrs,GLsizei count,GLenum type,const GLvoid * indices_in)572 void GLEScmContext::drawPointsElems(GLESConversionArrays& arrs,GLsizei count,GLenum type,const GLvoid* indices_in) {
573 drawPointsData(arrs,0,count,type,indices_in,true);
574 }
575
doConvert(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLESpointer * p,GLenum array_id)576 bool GLEScmContext::doConvert(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id) {
577 return needConvert(cArrs, first, count, type, indices, direct, p, array_id);
578 }
579
getColor() const580 std::vector<float> GLEScmContext::getColor() const {
581 switch (mColor.type) {
582 case GL_UNSIGNED_BYTE:
583 return
584 { mColor.val.ubyteVal[0] / 255.0f,
585 mColor.val.ubyteVal[1] / 255.0f,
586 mColor.val.ubyteVal[2] / 255.0f,
587 mColor.val.ubyteVal[3] / 255.0f, };
588 default:
589 case GL_FLOAT:
590 return { mColor.val.floatVal[0],
591 mColor.val.floatVal[1],
592 mColor.val.floatVal[2],
593 mColor.val.floatVal[3], };
594 }
595 }
596
getNormal() const597 std::vector<float> GLEScmContext::getNormal() const {
598 return
599 { mNormal.val.floatVal[0],
600 mNormal.val.floatVal[1],
601 mNormal.val.floatVal[2] };
602 }
603
getMultiTexCoord(uint32_t index) const604 std::vector<float> GLEScmContext::getMultiTexCoord(uint32_t index) const {
605 return // s, t, r, qcomponents
606 { mMultiTexCoord[index].floatVal[0],
607 mMultiTexCoord[index].floatVal[1],
608 mMultiTexCoord[index].floatVal[2],
609 mMultiTexCoord[index].floatVal[3] };
610 }
611
getTextureEnvMode()612 GLenum GLEScmContext::getTextureEnvMode() {
613 return mTexUnitEnvs[m_activeTexture][GL_TEXTURE_ENV_MODE].val.intVal[0];
614 }
615
getTextureGenMode()616 GLenum GLEScmContext::getTextureGenMode() {
617 return mTexGens[m_activeTexture][GL_TEXTURE_GEN_MODE_OES].val.intVal[0];
618 }
619
getProjMatrix()620 glm::mat4 GLEScmContext::getProjMatrix() {
621 return mProjMatrices.back();
622 }
623
getModelviewMatrix()624 glm::mat4 GLEScmContext::getModelviewMatrix() {
625 return mModelviewMatrices.back();
626 }
627
getTextureMatrix()628 glm::mat4 GLEScmContext::getTextureMatrix() {
629 return mTextureMatrices[m_activeTexture].back();
630 }
631
currMatrix()632 glm::mat4& GLEScmContext::currMatrix() {
633 return currMatrixStack().back();
634 }
635
currMatrixStack()636 GLEScmContext::MatrixStack& GLEScmContext::currMatrixStack() {
637 switch (mCurrMatrixMode) {
638 case GL_TEXTURE:
639 return mTextureMatrices[m_activeTexture];
640 case GL_PROJECTION:
641 return mProjMatrices;
642 case GL_MODELVIEW:
643 return mModelviewMatrices;
644 default:
645 break;
646 // emugl_crash_reporter("error: matrix mode set to 0x%x!", mCurrMatrixMode);
647 }
648 // Make compiler happy
649 return mModelviewMatrices;
650 }
651
needConvert(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLESpointer * p,GLenum array_id)652 bool GLEScmContext::needConvert(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id) {
653
654 bool usingVBO = p->getAttribType() == GLESpointer::BUFFER;
655 GLenum arrType = p->getType();
656 /*
657 conversion is not necessary in the following cases:
658 (*) array type is byte but it is not vertex or texture array
659 (*) array type is not fixed
660 */
661 if((arrType != GL_FIXED) && (arrType != GL_BYTE)) return false;
662 if((arrType == GL_BYTE && (array_id != GL_VERTEX_ARRAY)) &&
663 (arrType == GL_BYTE && (array_id != GL_TEXTURE_COORD_ARRAY)) ) return false;
664
665
666 bool byteVBO = (arrType == GL_BYTE) && usingVBO;
667 if(byteVBO){
668 p->redirectPointerData();
669 }
670
671 if(!usingVBO || byteVBO) {
672 if (direct) {
673 convertDirect(cArrs,first,count,array_id,p);
674 } else {
675 convertIndirect(cArrs,count,type,indices,array_id,p);
676 }
677 } else {
678 if (direct) {
679 convertDirectVBO(cArrs,first,count,array_id,p) ;
680 } else {
681 convertIndirectVBO(cArrs,count,type,indices,array_id,p);
682 }
683 }
684 return true;
685 }
686
getPointer(GLenum arrType)687 const GLESpointer* GLEScmContext::getPointer(GLenum arrType) {
688 GLenum type =
689 arrType == GL_VERTEX_ARRAY_POINTER ? GL_VERTEX_ARRAY :
690 arrType == GL_NORMAL_ARRAY_POINTER ? GL_NORMAL_ARRAY :
691 arrType == GL_TEXTURE_COORD_ARRAY_POINTER ? GL_TEXTURE_COORD_ARRAY :
692 arrType == GL_COLOR_ARRAY_POINTER ? GL_COLOR_ARRAY :
693 arrType == GL_POINT_SIZE_ARRAY_POINTER_OES ? GL_POINT_SIZE_ARRAY_OES :
694 0;
695 if(type != 0)
696 {
697 return GLEScontext::getPointer(type);
698 }
699 return NULL;
700 }
701
initExtensionString()702 void GLEScmContext::initExtensionString() {
703 if (s_glExtensionsGles1Initialized) return;
704
705 *s_glExtensionsGles1 = "GL_OES_blend_func_separate GL_OES_blend_equation_separate GL_OES_blend_subtract "
706 "GL_OES_byte_coordinates GL_OES_compressed_paletted_texture GL_OES_point_size_array "
707 "GL_OES_point_sprite GL_OES_single_precision GL_OES_stencil_wrap GL_OES_texture_env_crossbar "
708 "GL_OES_texture_mirored_repeat GL_OES_EGL_image GL_OES_element_index_uint GL_OES_draw_texture "
709 "GL_OES_texture_cube_map GL_OES_draw_texture ";
710 if (s_glSupport.GL_OES_READ_FORMAT)
711 *s_glExtensionsGles1+="GL_OES_read_format ";
712 if (s_glSupport.GL_EXT_FRAMEBUFFER_OBJECT) {
713 *s_glExtensionsGles1+="GL_OES_framebuffer_object GL_OES_depth24 GL_OES_depth32 GL_OES_fbo_render_mipmap "
714 "GL_OES_rgb8_rgba8 GL_OES_stencil1 GL_OES_stencil4 GL_OES_stencil8 ";
715 }
716 if (s_glSupport.GL_EXT_PACKED_DEPTH_STENCIL)
717 *s_glExtensionsGles1+="GL_OES_packed_depth_stencil ";
718 if (s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888)
719 *s_glExtensionsGles1+="GL_EXT_texture_format_BGRA8888 GL_APPLE_texture_format_BGRA8888 ";
720 if (s_glSupport.GL_ARB_MATRIX_PALETTE && s_glSupport.GL_ARB_VERTEX_BLEND) {
721 *s_glExtensionsGles1+="GL_OES_matrix_palette ";
722 GLint max_palette_matrices=0;
723 GLint max_vertex_units=0;
724 dispatcher().glGetIntegerv(GL_MAX_PALETTE_MATRICES_OES,&max_palette_matrices);
725 dispatcher().glGetIntegerv(GL_MAX_VERTEX_UNITS_OES,&max_vertex_units);
726 if (max_palette_matrices>=32 && max_vertex_units>=4)
727 *s_glExtensionsGles1+="GL_OES_extended_matrix_palette ";
728 }
729 *s_glExtensionsGles1+="GL_OES_compressed_ETC1_RGB8_texture ";
730
731 s_glExtensionsGles1Initialized = true;
732 }
733
getMaxTexUnits()734 int GLEScmContext::getMaxTexUnits() {
735 return kMaxTextureUnits;
736 }
737
glGetBooleanv(GLenum pname,GLboolean * params)738 bool GLEScmContext::glGetBooleanv(GLenum pname, GLboolean *params)
739 {
740 GLint iParam;
741
742 if(glGetIntegerv(pname, &iParam))
743 {
744 *params = (iParam != 0);
745 return true;
746 }
747
748 return false;
749 }
750
glGetFixedv(GLenum pname,GLfixed * params)751 bool GLEScmContext::glGetFixedv(GLenum pname, GLfixed *params)
752 {
753 GLint iParam;
754
755 if(glGetIntegerv(pname, &iParam))
756 {
757 *params = I2X(iParam);
758 return true;
759 }
760
761 return false;
762 }
763
glGetFloatv(GLenum pname,GLfloat * params)764 bool GLEScmContext::glGetFloatv(GLenum pname, GLfloat *params)
765 {
766 GLint iParam;
767
768 if(glGetIntegerv(pname, &iParam))
769 {
770 *params = (GLfloat)iParam;
771 return true;
772 }
773
774 return false;
775 }
776
glGetIntegerv(GLenum pname,GLint * params)777 bool GLEScmContext::glGetIntegerv(GLenum pname, GLint *params)
778 {
779 if(GLEScontext::glGetIntegerv(pname, params))
780 return true;
781
782 const GLESpointer* ptr = NULL;
783
784 switch(pname){
785 case GL_VERTEX_ARRAY_BUFFER_BINDING:
786 case GL_VERTEX_ARRAY_SIZE:
787 case GL_VERTEX_ARRAY_STRIDE:
788 case GL_VERTEX_ARRAY_TYPE:
789 ptr = getPointer(GL_VERTEX_ARRAY_POINTER);
790 break;
791
792 case GL_NORMAL_ARRAY_BUFFER_BINDING:
793 case GL_NORMAL_ARRAY_STRIDE:
794 case GL_NORMAL_ARRAY_TYPE:
795 ptr = getPointer(GL_NORMAL_ARRAY_POINTER);
796 break;
797
798 case GL_COLOR_ARRAY_BUFFER_BINDING:
799 case GL_COLOR_ARRAY_SIZE:
800 case GL_COLOR_ARRAY_STRIDE:
801 case GL_COLOR_ARRAY_TYPE:
802 ptr = getPointer(GL_COLOR_ARRAY_POINTER);
803 break;
804
805 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
806 case GL_TEXTURE_COORD_ARRAY_SIZE:
807 case GL_TEXTURE_COORD_ARRAY_STRIDE:
808 case GL_TEXTURE_COORD_ARRAY_TYPE:
809 ptr = getPointer(GL_TEXTURE_COORD_ARRAY_POINTER);
810 break;
811
812 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
813 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
814 case GL_POINT_SIZE_ARRAY_TYPE_OES:
815 ptr = getPointer(GL_POINT_SIZE_ARRAY_POINTER_OES);
816 break;
817
818 default:
819 return false;
820 }
821
822 switch(pname)
823 {
824 case GL_VERTEX_ARRAY_BUFFER_BINDING:
825 case GL_NORMAL_ARRAY_BUFFER_BINDING:
826 case GL_COLOR_ARRAY_BUFFER_BINDING:
827 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
828 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
829 *params = ptr ? ptr->getBufferName() : 0;
830 break;
831
832 case GL_VERTEX_ARRAY_STRIDE:
833 case GL_NORMAL_ARRAY_STRIDE:
834 case GL_COLOR_ARRAY_STRIDE:
835 case GL_TEXTURE_COORD_ARRAY_STRIDE:
836 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
837 *params = ptr ? ptr->getStride() : 0;
838 break;
839
840 case GL_VERTEX_ARRAY_SIZE:
841 case GL_COLOR_ARRAY_SIZE:
842 case GL_TEXTURE_COORD_ARRAY_SIZE:
843 *params = ptr ? ptr->getSize() : 0;
844 break;
845
846 case GL_VERTEX_ARRAY_TYPE:
847 case GL_NORMAL_ARRAY_TYPE:
848 case GL_COLOR_ARRAY_TYPE:
849 case GL_TEXTURE_COORD_ARRAY_TYPE:
850 case GL_POINT_SIZE_ARRAY_TYPE_OES:
851 *params = ptr ? ptr->getType() : 0;
852 break;
853 }
854
855 return true;
856 }
857
getErrorCoreProfile()858 GLint GLEScmContext::getErrorCoreProfile() {
859 return core().getAndClearLastError();
860 }
861
enable(GLenum cap)862 void GLEScmContext::enable(GLenum cap) {
863 setEnable(cap, true);
864
865 if (m_coreProfileEngine) {
866 core().enable(cap);
867 } else {
868 if (cap==GL_TEXTURE_GEN_STR_OES) {
869 dispatcher().glEnable(GL_TEXTURE_GEN_S);
870 dispatcher().glEnable(GL_TEXTURE_GEN_T);
871 dispatcher().glEnable(GL_TEXTURE_GEN_R);
872 } else {
873 dispatcher().glEnable(cap);
874 }
875 }
876 }
877
disable(GLenum cap)878 void GLEScmContext::disable(GLenum cap) {
879 setEnable(cap, false);
880
881 if (m_coreProfileEngine) {
882 core().disable(cap);
883 } else {
884 if (cap==GL_TEXTURE_GEN_STR_OES) {
885 dispatcher().glDisable(GL_TEXTURE_GEN_S);
886 dispatcher().glDisable(GL_TEXTURE_GEN_T);
887 dispatcher().glDisable(GL_TEXTURE_GEN_R);
888 } else {
889 dispatcher().glDisable(cap);
890 }
891 }
892 }
893
shadeModel(GLenum mode)894 void GLEScmContext::shadeModel(GLenum mode) {
895 mShadeModel = mode;
896
897 if (m_coreProfileEngine) {
898 core().shadeModel(mode);
899 } else {
900 dispatcher().glShadeModel(mode);
901 }
902 }
903
matrixMode(GLenum mode)904 void GLEScmContext::matrixMode(GLenum mode) {
905 mCurrMatrixMode = mode;
906
907 if (m_coreProfileEngine) {
908 core().matrixMode(mode);
909 } else {
910 dispatcher().glMatrixMode(mode);
911 }
912 }
913
loadIdentity()914 void GLEScmContext::loadIdentity() {
915 currMatrix() = glm::mat4();
916
917 if (m_coreProfileEngine) {
918 core().loadIdentity();
919 } else {
920 dispatcher().glLoadIdentity();
921 }
922 }
923
loadMatrixf(const GLfloat * m)924 void GLEScmContext::loadMatrixf(const GLfloat* m) {
925 currMatrix() = glm::make_mat4(m);
926
927 if (m_coreProfileEngine) {
928 core().loadMatrixf(m);
929 } else {
930 dispatcher().glLoadMatrixf(m);
931 }
932 }
933
pushMatrix()934 void GLEScmContext::pushMatrix() {
935 if (currMatrixStack().size() >= kMaxMatrixStackSize) {
936 setGLerror(GL_STACK_OVERFLOW);
937 return;
938 }
939 currMatrixStack().emplace_back(currMatrixStack().back());
940
941 if (m_coreProfileEngine) {
942 core().pushMatrix();
943 } else {
944 dispatcher().glPushMatrix();
945 }
946 }
947
popMatrix()948 void GLEScmContext::popMatrix() {
949 if (currMatrixStack().size() == 1) {
950 setGLerror(GL_STACK_UNDERFLOW);
951 return;
952 }
953 currMatrixStack().pop_back();
954
955 if (m_coreProfileEngine) {
956 core().popMatrix();
957 } else {
958 dispatcher().glPopMatrix();
959 }
960 }
961
multMatrixf(const GLfloat * m)962 void GLEScmContext::multMatrixf(const GLfloat* m) {
963 currMatrix() *= glm::make_mat4(m);
964
965 if (m_coreProfileEngine) {
966 core().multMatrixf(m);
967 } else {
968 dispatcher().glMultMatrixf(m);
969 }
970 }
971
orthof(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)972 void GLEScmContext::orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
973 currMatrix() *= glm::ortho(left, right, bottom, top, zNear, zFar);
974
975 if (m_coreProfileEngine) {
976 core().orthof(left, right, bottom, top, zNear, zFar);
977 } else {
978 dispatcher().glOrtho(left,right,bottom,top,zNear,zFar);
979 }
980 }
981
frustumf(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)982 void GLEScmContext::frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
983 currMatrix() *= glm::frustum(left, right, bottom, top, zNear, zFar);
984
985 if (m_coreProfileEngine) {
986 core().frustumf(left, right, bottom, top, zNear, zFar);
987 } else {
988 dispatcher().glFrustum(left,right,bottom,top,zNear,zFar);
989 }
990 }
991
texEnvf(GLenum target,GLenum pname,GLfloat param)992 void GLEScmContext::texEnvf(GLenum target, GLenum pname, GLfloat param) {
993 // Assume |target| is GL_TEXTURE_ENV
994 if (pname == GL_TEXTURE_ENV_MODE) {
995 texEnvi(target, pname, (GLint)param);
996 } else {
997 mTexUnitEnvs[m_activeTexture][pname].val.floatVal[0] = param;
998 mTexUnitEnvs[m_activeTexture][pname].type = GL_FLOAT;
999 }
1000
1001 if (m_coreProfileEngine) {
1002 core().texEnvf(target, pname, param);
1003 } else {
1004 dispatcher().glTexEnvf(target, pname, param);
1005 }
1006 }
1007
texEnvfv(GLenum target,GLenum pname,const GLfloat * params)1008 void GLEScmContext::texEnvfv(GLenum target, GLenum pname, const GLfloat* params) {
1009 if (pname == GL_TEXTURE_ENV_COLOR) {
1010 for (int i = 0; i < 4; i++) {
1011 mTexUnitEnvs[m_activeTexture][pname].val.floatVal[i] = params[i];
1012 mTexUnitEnvs[m_activeTexture][pname].type = GL_FLOAT;
1013 }
1014 } else {
1015 texEnvf(target, pname, params[0]);
1016 }
1017
1018 if (m_coreProfileEngine) {
1019 core().texEnvfv(target, pname, params);
1020 } else {
1021 dispatcher().glTexEnvfv(target, pname, params);
1022 }
1023 }
1024
texEnvi(GLenum target,GLenum pname,GLint param)1025 void GLEScmContext::texEnvi(GLenum target, GLenum pname, GLint param) {
1026 mTexUnitEnvs[m_activeTexture][pname].val.intVal[0] = param;
1027 mTexUnitEnvs[m_activeTexture][pname].type = GL_INT;
1028
1029 if (m_coreProfileEngine) {
1030 core().texEnvi(target, pname, param);
1031 } else {
1032 dispatcher().glTexEnvi(target, pname, param);
1033 }
1034 }
1035
texEnviv(GLenum target,GLenum pname,const GLint * params)1036 void GLEScmContext::texEnviv(GLenum target, GLenum pname, const GLint* params) {
1037 mTexUnitEnvs[m_activeTexture][pname].val.intVal[0] = params[0];
1038 mTexUnitEnvs[m_activeTexture][pname].type = GL_INT;
1039
1040 if (m_coreProfileEngine) {
1041 core().texEnviv(target, pname, params);
1042 } else {
1043 dispatcher().glTexEnviv(target, pname, params);
1044 }
1045 }
1046
getTexEnvfv(GLenum env,GLenum pname,GLfloat * params)1047 void GLEScmContext::getTexEnvfv(GLenum env, GLenum pname, GLfloat* params) {
1048 *params = mTexUnitEnvs[m_activeTexture][pname].val.floatVal[0];
1049
1050 if (m_coreProfileEngine) {
1051 core().getTexEnvfv(env, pname, params);
1052 } else {
1053 dispatcher().glGetTexEnvfv(env, pname, params);
1054 }
1055 }
1056
getTexEnviv(GLenum env,GLenum pname,GLint * params)1057 void GLEScmContext::getTexEnviv(GLenum env, GLenum pname, GLint* params) {
1058 *params = mTexUnitEnvs[m_activeTexture][pname].val.intVal[0];
1059
1060 if (m_coreProfileEngine) {
1061 core().getTexEnviv(env, pname, params);
1062 } else {
1063 dispatcher().glGetTexEnviv(env, pname, params);
1064 }
1065 }
1066
texGenf(GLenum coord,GLenum pname,GLfloat param)1067 void GLEScmContext::texGenf(GLenum coord, GLenum pname, GLfloat param) {
1068 mTexGens[m_activeTexture][pname].val.floatVal[0] = param;
1069 mTexGens[m_activeTexture][pname].type = GL_FLOAT;
1070
1071 if (m_coreProfileEngine) {
1072 core().texGenf(coord, pname, param);
1073 } else {
1074 if (coord == GL_TEXTURE_GEN_STR_OES) {
1075 dispatcher().glTexGenf(GL_S,pname,param);
1076 dispatcher().glTexGenf(GL_T,pname,param);
1077 dispatcher().glTexGenf(GL_R,pname,param);
1078 } else {
1079 dispatcher().glTexGenf(coord,pname,param);
1080 }
1081 }
1082 }
1083
texGenfv(GLenum coord,GLenum pname,const GLfloat * params)1084 void GLEScmContext::texGenfv(GLenum coord, GLenum pname, const GLfloat* params) {
1085 mTexGens[m_activeTexture][pname].val.floatVal[0] = params[0];
1086 mTexGens[m_activeTexture][pname].type = GL_FLOAT;
1087
1088 if (m_coreProfileEngine) {
1089 core().texGenfv(coord, pname, params);
1090 } else {
1091 if (coord == GL_TEXTURE_GEN_STR_OES) {
1092 dispatcher().glTexGenfv(GL_S,pname,params);
1093 dispatcher().glTexGenfv(GL_T,pname,params);
1094 dispatcher().glTexGenfv(GL_R,pname,params);
1095 } else {
1096 dispatcher().glTexGenfv(coord,pname,params);
1097 }
1098 }
1099 }
1100
texGeni(GLenum coord,GLenum pname,GLint param)1101 void GLEScmContext::texGeni(GLenum coord, GLenum pname, GLint param) {
1102 mTexGens[m_activeTexture][pname].val.intVal[0] = param;
1103 mTexGens[m_activeTexture][pname].type = GL_INT;
1104
1105 if (m_coreProfileEngine) {
1106 core().texGeni(coord, pname, param);
1107 } else {
1108 if (coord == GL_TEXTURE_GEN_STR_OES) {
1109 dispatcher().glTexGeni(GL_S,pname,param);
1110 dispatcher().glTexGeni(GL_T,pname,param);
1111 dispatcher().glTexGeni(GL_R,pname,param);
1112 } else {
1113 dispatcher().glTexGeni(coord,pname,param);
1114 }
1115 }
1116 }
1117
texGeniv(GLenum coord,GLenum pname,const GLint * params)1118 void GLEScmContext::texGeniv(GLenum coord, GLenum pname, const GLint* params) {
1119 mTexGens[m_activeTexture][pname].val.intVal[0] = params[0];
1120 mTexGens[m_activeTexture][pname].type = GL_INT;
1121
1122 if (m_coreProfileEngine) {
1123 core().texGeniv(coord, pname, params);
1124 } else {
1125 if (coord == GL_TEXTURE_GEN_STR_OES) {
1126 dispatcher().glTexGeniv(GL_S,pname,params);
1127 dispatcher().glTexGeniv(GL_T,pname,params);
1128 dispatcher().glTexGeniv(GL_R,pname,params);
1129 } else {
1130 dispatcher().glTexGeniv(coord,pname,params);
1131 }
1132 }
1133 }
1134
getTexGeniv(GLenum coord,GLenum pname,GLint * params)1135 void GLEScmContext::getTexGeniv(GLenum coord, GLenum pname, GLint* params) {
1136 *params = mTexGens[m_activeTexture][pname].val.intVal[0];
1137
1138 if (m_coreProfileEngine) {
1139 core().getTexGeniv(coord, pname, params);
1140 } else {
1141 if (coord == GL_TEXTURE_GEN_STR_OES) {
1142 GLint state_s = GL_FALSE;
1143 GLint state_t = GL_FALSE;
1144 GLint state_r = GL_FALSE;
1145 dispatcher().glGetTexGeniv(GL_S,pname,&state_s);
1146 dispatcher().glGetTexGeniv(GL_T,pname,&state_t);
1147 dispatcher().glGetTexGeniv(GL_R,pname,&state_r);
1148 *params = state_s && state_t && state_r ? GL_TRUE: GL_FALSE;
1149 } else {
1150 dispatcher().glGetTexGeniv(coord,pname,params);
1151 }
1152 }
1153 }
1154
getTexGenfv(GLenum coord,GLenum pname,GLfloat * params)1155 void GLEScmContext::getTexGenfv(GLenum coord, GLenum pname, GLfloat* params) {
1156 params[0] = mTexGens[m_activeTexture][pname].val.floatVal[0];
1157 params[1] = mTexGens[m_activeTexture][pname].val.floatVal[1];
1158 params[2] = mTexGens[m_activeTexture][pname].val.floatVal[2];
1159 params[3] = mTexGens[m_activeTexture][pname].val.floatVal[3];
1160
1161 if (m_coreProfileEngine) {
1162 core().getTexGenfv(coord, pname, params);
1163 } else {
1164 if (coord == GL_TEXTURE_GEN_STR_OES) {
1165 GLfloat state_s = GL_FALSE;
1166 GLfloat state_t = GL_FALSE;
1167 GLfloat state_r = GL_FALSE;
1168 dispatcher().glGetTexGenfv(GL_S,pname,&state_s);
1169 dispatcher().glGetTexGenfv(GL_T,pname,&state_t);
1170 dispatcher().glGetTexGenfv(GL_R,pname,&state_r);
1171 *params = state_s && state_t && state_r ? GL_TRUE: GL_FALSE;
1172 } else {
1173 dispatcher().glGetTexGenfv(coord,pname,params);
1174 }
1175 }
1176 }
1177
materialf(GLenum face,GLenum pname,GLfloat param)1178 void GLEScmContext::materialf(GLenum face, GLenum pname, GLfloat param) {
1179 if (face != GL_FRONT_AND_BACK) {
1180 fprintf(stderr, "GL_INVALID_ENUM: GLES1's glMaterial(f/x) "
1181 "only supports GL_FRONT_AND_BACK for materials.\n");
1182 setGLerror(GL_INVALID_ENUM);
1183 return;
1184 }
1185 switch (pname) {
1186 case GL_AMBIENT:
1187 case GL_DIFFUSE:
1188 case GL_AMBIENT_AND_DIFFUSE:
1189 case GL_SPECULAR:
1190 case GL_EMISSION:
1191 fprintf(stderr, "GL_INVALID_ENUM: glMaterial(f/x) only supports "
1192 "GL_SHININESS for single parameter setting.\n");
1193 setGLerror(GL_INVALID_ENUM);
1194 return;
1195 case GL_SHININESS:
1196 if (param < 0.0f || param > 128.0f) {
1197 fprintf(stderr, "GL_INVALID_VALUE: Invalid specular exponent value %f. "
1198 "Only range [0.0, 128.0] supported.\n", param);
1199 setGLerror(GL_INVALID_VALUE);
1200 return;
1201 }
1202 mMaterial.specularExponent = param;
1203 break;
1204 default:
1205 fprintf(stderr, "Unknown parameter name 0x%x for glMaterial(f/x)\n", pname);
1206 setGLerror(GL_INVALID_ENUM);
1207 return;
1208 }
1209
1210 if (!m_coreProfileEngine) {
1211 dispatcher().glMaterialf(face, pname, param);
1212 }
1213 }
1214
materialfv(GLenum face,GLenum pname,const GLfloat * params)1215 void GLEScmContext::materialfv(GLenum face, GLenum pname, const GLfloat* params) {
1216 if (face != GL_FRONT_AND_BACK) {
1217 fprintf(stderr, "GL_INVALID_ENUM: GLES1's glMaterial(f/x)v "
1218 "only supports GL_FRONT_AND_BACK for materials.\n");
1219 setGLerror(GL_INVALID_ENUM);
1220 return;
1221 }
1222
1223 switch (pname) {
1224 case GL_AMBIENT:
1225 memcpy(&mMaterial.ambient, params, 4 * sizeof(GLfloat));
1226 break;
1227 case GL_DIFFUSE:
1228 memcpy(&mMaterial.diffuse, params, 4 * sizeof(GLfloat));
1229 break;
1230 case GL_AMBIENT_AND_DIFFUSE:
1231 memcpy(&mMaterial.ambient, params, 4 * sizeof(GLfloat));
1232 memcpy(&mMaterial.diffuse, params, 4 * sizeof(GLfloat));
1233 break;
1234 case GL_SPECULAR:
1235 memcpy(&mMaterial.specular, params, 4 * sizeof(GLfloat));
1236 break;
1237 case GL_EMISSION:
1238 memcpy(&mMaterial.emissive, params, 4 * sizeof(GLfloat));
1239 break;
1240 case GL_SHININESS:
1241 if (*params < 0.0f || *params > 128.0f) {
1242 fprintf(stderr, "GL_INVALID_VALUE: Invalid specular exponent value %f. "
1243 "Only range [0.0, 128.0] supported.\n", *params);
1244 setGLerror(GL_INVALID_VALUE);
1245 return;
1246 }
1247 mMaterial.specularExponent = *params;
1248 break;
1249 default:
1250 fprintf(stderr, "Unknown parameter name 0x%x for glMaterial(f/x)v.\n", pname);
1251 setGLerror(GL_INVALID_ENUM);
1252 return;
1253 }
1254
1255 if (!m_coreProfileEngine) {
1256 dispatcher().glMaterialfv(face, pname, params);
1257 }
1258 }
1259
getMaterialfv(GLenum face,GLenum pname,GLfloat * params)1260 void GLEScmContext::getMaterialfv(GLenum face, GLenum pname, GLfloat* params) {
1261 if (face != GL_FRONT && face != GL_BACK) {
1262 fprintf(stderr, "GL_INVALID_ENUM: glGetMaterial(f/x)v "
1263 "must take GL_FRONT or GL_BACK as face argument\n");
1264 setGLerror(GL_INVALID_ENUM);
1265 return;
1266 }
1267
1268 switch (pname) {
1269 case GL_AMBIENT:
1270 memcpy(params, &mMaterial.ambient, 4 * sizeof(GLfloat));
1271 break;
1272 case GL_DIFFUSE:
1273 memcpy(params, &mMaterial.diffuse, 4 * sizeof(GLfloat));
1274 break;
1275 case GL_SPECULAR:
1276 memcpy(params, &mMaterial.specular, 4 * sizeof(GLfloat));
1277 break;
1278 case GL_EMISSION:
1279 memcpy(params, &mMaterial.emissive, 4 * sizeof(GLfloat));
1280 break;
1281 case GL_SHININESS:
1282 *params = mMaterial.specularExponent;
1283 break;
1284 default:
1285 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glGetMaterial(f/x)v.\n", pname);
1286 setGLerror(GL_INVALID_ENUM);
1287 return;
1288 }
1289
1290 if (!m_coreProfileEngine) {
1291 dispatcher().glGetMaterialfv(face, pname, params);
1292 }
1293 }
1294
lightModelf(GLenum pname,GLfloat param)1295 void GLEScmContext::lightModelf(GLenum pname, GLfloat param) {
1296 switch (pname) {
1297 case GL_LIGHT_MODEL_AMBIENT:
1298 fprintf(stderr, "GL_INVALID_ENUM: glLightModelf only supports GL_LIGHT_MODEL_TWO_SIDE.\n");
1299 setGLerror(GL_INVALID_ENUM);
1300 return;
1301 case GL_LIGHT_MODEL_TWO_SIDE:
1302 if (param != 1.0f && param != 0.0f) {
1303 fprintf(stderr, "GL_INVALID_VALUE: glLightModelf only takes 0 or 1 "
1304 "for GL_LIGHT_MODEL_TWO_SIDE, but got %f\n", param);
1305 setGLerror(GL_INVALID_VALUE);
1306 }
1307 mLightModel.twoSided = param == 1.0f ? true : false;
1308 break;
1309 default:
1310 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glLightModel(f/x)v.\n", pname);
1311 setGLerror(GL_INVALID_ENUM);
1312 return;
1313 }
1314
1315 if (!m_coreProfileEngine) {
1316 dispatcher().glLightModelf(pname, param);
1317 }
1318 }
1319
lightModelfv(GLenum pname,const GLfloat * params)1320 void GLEScmContext::lightModelfv(GLenum pname, const GLfloat* params) {
1321 switch (pname) {
1322 case GL_LIGHT_MODEL_AMBIENT:
1323 memcpy(&mLightModel.color, params, 4 * sizeof(GLfloat));
1324 break;
1325 case GL_LIGHT_MODEL_TWO_SIDE:
1326 if (*params != 1.0f && *params != 0.0f) {
1327 fprintf(stderr, "GL_INVALID_VALUE: glLightModelf only takes 0 or 1 "
1328 "for GL_LIGHT_MODEL_TWO_SIDE, but got %f\n", *params);
1329 setGLerror(GL_INVALID_VALUE);
1330 }
1331 mLightModel.twoSided = *params == 1.0f ? true : false;
1332 break;
1333 default:
1334 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glLightModel(f/x)v.\n", pname);
1335 setGLerror(GL_INVALID_ENUM);
1336 return;
1337 }
1338
1339 if (!m_coreProfileEngine) {
1340 dispatcher().glLightModelfv(pname, params);
1341 }
1342 }
1343
lightf(GLenum light,GLenum pname,GLfloat param)1344 void GLEScmContext::lightf(GLenum light, GLenum pname, GLfloat param) {
1345 uint32_t lightIndex = light - GL_LIGHT0;
1346
1347 if (lightIndex >= kMaxLights) {
1348 fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for glLight(f/x) (wanted %u)\n",
1349 lightIndex);
1350 setGLerror(GL_INVALID_ENUM);
1351 return;
1352 }
1353
1354 switch (pname) {
1355 case GL_AMBIENT:
1356 case GL_DIFFUSE:
1357 case GL_SPECULAR:
1358 case GL_POSITION:
1359 case GL_SPOT_DIRECTION:
1360 fprintf(stderr, "GL_INVALID_ENUM: Invalid parameter name 0x%x "
1361 "for glLight(f/x). Needs glLight(f/x)v.\n", pname);
1362 setGLerror(GL_INVALID_ENUM);
1363 return;
1364 case GL_SPOT_EXPONENT:
1365 mLights[lightIndex].spotlightExponent = param;
1366 break;
1367 case GL_SPOT_CUTOFF:
1368 mLights[lightIndex].spotlightCutoffAngle = param;
1369 break;
1370 case GL_CONSTANT_ATTENUATION:
1371 mLights[lightIndex].attenuationConst = param;
1372 break;
1373 case GL_LINEAR_ATTENUATION:
1374 mLights[lightIndex].attenuationLinear = param;
1375 break;
1376 case GL_QUADRATIC_ATTENUATION:
1377 mLights[lightIndex].attenuationQuadratic = param;
1378 break;
1379 default:
1380 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1381 "for glLight(f/x).\n", pname);
1382 setGLerror(GL_INVALID_ENUM);
1383 return;
1384 }
1385
1386 if (!m_coreProfileEngine) {
1387 dispatcher().glLightf(light, pname, param);
1388 }
1389 }
1390
lightfv(GLenum light,GLenum pname,const GLfloat * params)1391 void GLEScmContext::lightfv(GLenum light, GLenum pname, const GLfloat* params) {
1392 uint32_t lightIndex = light - GL_LIGHT0;
1393
1394 if (lightIndex >= kMaxLights) {
1395 fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for "
1396 "glLight(f/x)v (wanted %u)\n",
1397 lightIndex);
1398 setGLerror(GL_INVALID_ENUM);
1399 return;
1400 }
1401
1402 switch (pname) {
1403 case GL_AMBIENT:
1404 memcpy(&mLights[lightIndex].ambient, params, 4 * sizeof(GLfloat));
1405 break;
1406 case GL_DIFFUSE:
1407 memcpy(&mLights[lightIndex].diffuse, params, 4 * sizeof(GLfloat));
1408 break;
1409 case GL_SPECULAR:
1410 memcpy(&mLights[lightIndex].specular, params, 4 * sizeof(GLfloat));
1411 break;
1412 case GL_POSITION:
1413 memcpy(&mLights[lightIndex].position, params, 4 * sizeof(GLfloat));
1414 break;
1415 case GL_SPOT_DIRECTION:
1416 memcpy(&mLights[lightIndex].direction, params, 3 * sizeof(GLfloat));
1417 break;
1418 case GL_SPOT_EXPONENT:
1419 mLights[lightIndex].spotlightExponent = *params;
1420 break;
1421 case GL_SPOT_CUTOFF:
1422 mLights[lightIndex].spotlightCutoffAngle = *params;
1423 break;
1424 case GL_CONSTANT_ATTENUATION:
1425 mLights[lightIndex].attenuationConst = *params;
1426 break;
1427 case GL_LINEAR_ATTENUATION:
1428 mLights[lightIndex].attenuationLinear = *params;
1429 break;
1430 case GL_QUADRATIC_ATTENUATION:
1431 mLights[lightIndex].attenuationQuadratic = *params;
1432 break;
1433 default:
1434 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1435 "for glLight(f/x).\n", pname);
1436 setGLerror(GL_INVALID_ENUM);
1437 return;
1438 }
1439
1440 if (!m_coreProfileEngine) {
1441 dispatcher().glLightfv(light, pname, params);
1442 }
1443 }
1444
getLightfv(GLenum light,GLenum pname,GLfloat * params)1445 void GLEScmContext::getLightfv(GLenum light, GLenum pname, GLfloat* params) {
1446 uint32_t lightIndex = light - GL_LIGHT0;
1447
1448 if (lightIndex >= kMaxLights) {
1449 fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for "
1450 "glGetLight(f/x)v (wanted %u)\n",
1451 lightIndex);
1452 setGLerror(GL_INVALID_ENUM);
1453 return;
1454 }
1455
1456 switch (pname) {
1457 case GL_AMBIENT:
1458 memcpy(params, &mLights[lightIndex].ambient, 4 * sizeof(GLfloat));
1459 break;
1460 case GL_DIFFUSE:
1461 memcpy(params, &mLights[lightIndex].diffuse, 4 * sizeof(GLfloat));
1462 break;
1463 case GL_SPECULAR:
1464 memcpy(params, &mLights[lightIndex].specular, 4 * sizeof(GLfloat));
1465 break;
1466 case GL_POSITION:
1467 memcpy(params, &mLights[lightIndex].position, 4 * sizeof(GLfloat));
1468 break;
1469 case GL_SPOT_DIRECTION:
1470 memcpy(params, &mLights[lightIndex].direction, 3 * sizeof(GLfloat));
1471 break;
1472 case GL_SPOT_EXPONENT:
1473 *params = mLights[lightIndex].spotlightExponent;
1474 break;
1475 case GL_SPOT_CUTOFF:
1476 *params = mLights[lightIndex].spotlightCutoffAngle;
1477 break;
1478 case GL_CONSTANT_ATTENUATION:
1479 *params = mLights[lightIndex].attenuationConst;
1480 break;
1481 case GL_LINEAR_ATTENUATION:
1482 *params = mLights[lightIndex].attenuationLinear;
1483 break;
1484 case GL_QUADRATIC_ATTENUATION:
1485 *params = mLights[lightIndex].attenuationQuadratic;
1486 break;
1487 default:
1488 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1489 "for glGetLight(f/x).\n", pname);
1490 setGLerror(GL_INVALID_ENUM);
1491 return;
1492 }
1493
1494 if (!m_coreProfileEngine) {
1495 dispatcher().glGetLightfv(light, pname, params);
1496 }
1497 }
1498
multiTexCoord4f(GLenum target,GLfloat s,GLfloat t,GLfloat r,GLfloat q)1499 void GLEScmContext::multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
1500
1501 mMultiTexCoord[target - GL_TEXTURE0].floatVal[0] = s;
1502 mMultiTexCoord[target - GL_TEXTURE0].floatVal[1] = t;
1503 mMultiTexCoord[target - GL_TEXTURE0].floatVal[2] = q;
1504 mMultiTexCoord[target - GL_TEXTURE0].floatVal[3] = r;
1505
1506 if (!m_coreProfileEngine) {
1507 dispatcher().glMultiTexCoord4f(target, s, t, r, q);
1508 }
1509 }
1510
normal3f(GLfloat nx,GLfloat ny,GLfloat nz)1511 void GLEScmContext::normal3f(GLfloat nx, GLfloat ny, GLfloat nz) {
1512 mNormal.type = GL_FLOAT;
1513 mNormal.val.floatVal[0] = nx;
1514 mNormal.val.floatVal[1] = ny;
1515 mNormal.val.floatVal[2] = nz;
1516
1517 if (!m_coreProfileEngine) {
1518 dispatcher().glNormal3f(nx, ny, nz);
1519 }
1520 }
1521
fogf(GLenum pname,GLfloat param)1522 void GLEScmContext::fogf(GLenum pname, GLfloat param) {
1523 switch (pname) {
1524 case GL_FOG_MODE: {
1525 GLenum mode = (GLenum)param;
1526 switch (mode) {
1527 case GL_EXP:
1528 case GL_EXP2:
1529 case GL_LINEAR:
1530 mFog.mode = mode;
1531 break;
1532 default:
1533 fprintf(stderr, "GL_INVALID_ENUM: Unknown GL_FOG_MODE 0x%x "
1534 "for glFog(f/x).\n", mode);
1535 setGLerror(GL_INVALID_ENUM);
1536 break;
1537 }
1538 break;
1539 }
1540 case GL_FOG_DENSITY:
1541 if (param < 0.0f) {
1542 fprintf(stderr, "GL_INVALID_VALUE: glFog(f/x): GL_FOG_DENSITY "
1543 "needs to be nonnegative, but got %f\n", param);
1544 setGLerror(GL_INVALID_VALUE);
1545 return;
1546 }
1547 mFog.density = param;
1548 break;
1549 case GL_FOG_START:
1550 mFog.start = param;
1551 break;
1552 case GL_FOG_END:
1553 mFog.end = param;
1554 break;
1555 case GL_FOG_COLOR:
1556 fprintf(stderr, "GL_INVALID_ENUM: GL_FOG_COLOR not allowed for glFog(f/x).\n");
1557 setGLerror(GL_INVALID_ENUM);
1558 break;
1559 default:
1560 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1561 "for glFog(f/x).\n", pname);
1562 setGLerror(GL_INVALID_ENUM);
1563 return;
1564 }
1565
1566 if (!m_coreProfileEngine) {
1567 dispatcher().glFogf(pname, param);
1568 }
1569 }
1570
fogfv(GLenum pname,const GLfloat * params)1571 void GLEScmContext::fogfv(GLenum pname, const GLfloat* params) {
1572 switch (pname) {
1573 case GL_FOG_MODE: {
1574 GLenum mode = (GLenum)params[0];
1575 switch (mode) {
1576 case GL_EXP:
1577 case GL_EXP2:
1578 case GL_LINEAR:
1579 mFog.mode = mode;
1580 break;
1581 default:
1582 fprintf(stderr, "GL_INVALID_ENUM: Unknown GL_FOG_MODE 0x%x "
1583 "for glFog(f/x)v.\n", mode);
1584 setGLerror(GL_INVALID_ENUM);
1585 break;
1586 }
1587 break;
1588 }
1589 case GL_FOG_DENSITY:
1590 if (params[0] < 0.0f) {
1591 fprintf(stderr, "GL_INVALID_VALUE: glFog(f/x)v: GL_FOG_DENSITY "
1592 "needs to be nonnegative, but got %f\n", params[0]);
1593 setGLerror(GL_INVALID_VALUE);
1594 return;
1595 }
1596 mFog.density = params[0];
1597 break;
1598 case GL_FOG_START:
1599 mFog.start = params[0];
1600 break;
1601 case GL_FOG_END:
1602 mFog.end = params[0];
1603 break;
1604 case GL_FOG_COLOR:
1605 memcpy(&mFog.color, params, 4 * sizeof(GLfloat));
1606 break;
1607 default:
1608 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1609 "for glFog(f/x)v.\n", pname);
1610 setGLerror(GL_INVALID_ENUM);
1611 return;
1612 }
1613
1614 if (!m_coreProfileEngine) {
1615 dispatcher().glFogfv(pname, params);
1616 }
1617 }
1618
enableClientState(GLenum clientState)1619 void GLEScmContext::enableClientState(GLenum clientState) {
1620 if (m_coreProfileEngine) {
1621 core().enableClientState(clientState);
1622 } else {
1623 dispatcher().glEnableClientState(clientState);
1624 }
1625 }
1626
disableClientState(GLenum clientState)1627 void GLEScmContext::disableClientState(GLenum clientState) {
1628 if (m_coreProfileEngine) {
1629 core().disableClientState(clientState);
1630 } else {
1631 dispatcher().glDisableClientState(clientState);
1632 }
1633 }
1634
drawTexOES(float x,float y,float z,float width,float height)1635 void GLEScmContext::drawTexOES(float x, float y, float z, float width, float height) {
1636 if (m_coreProfileEngine) {
1637 core().drawTexOES(x, y, z, width, height);
1638 } else {
1639 auto& gl = dispatcher();
1640
1641 int numClipPlanes;
1642
1643 GLint viewport[4] = {};
1644 z = (z>1 ? 1 : (z<0 ? 0 : z));
1645
1646 float vertices[4*3] = {
1647 x , y, z,
1648 x , static_cast<float>(y+height), z,
1649 static_cast<float>(x+width), static_cast<float>(y+height), z,
1650 static_cast<float>(x+width), y, z
1651 };
1652 GLfloat texels[getMaxTexUnits()][4*2];
1653 memset((void*)texels, 0, getMaxTexUnits()*4*2*sizeof(GLfloat));
1654
1655 gl.glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
1656 gl.glPushAttrib(GL_TRANSFORM_BIT);
1657
1658 //setup projection matrix to draw in viewport aligned coordinates
1659 gl.glMatrixMode(GL_PROJECTION);
1660 gl.glPushMatrix();
1661 gl.glLoadIdentity();
1662 gl.glGetIntegerv(GL_VIEWPORT,viewport);
1663 gl.glOrtho(viewport[0],viewport[0] + viewport[2],viewport[1],viewport[1]+viewport[3],0,-1);
1664 //setup texture matrix
1665 gl.glMatrixMode(GL_TEXTURE);
1666 gl.glPushMatrix();
1667 gl.glLoadIdentity();
1668 //setup modelview matrix
1669 gl.glMatrixMode(GL_MODELVIEW);
1670 gl.glPushMatrix();
1671 gl.glLoadIdentity();
1672 //backup vbo's
1673 int array_buffer,element_array_buffer;
1674 gl.glGetIntegerv(GL_ARRAY_BUFFER_BINDING,&array_buffer);
1675 gl.glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,&element_array_buffer);
1676 gl.glBindBuffer(GL_ARRAY_BUFFER,0);
1677 gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
1678
1679 //disable clip planes
1680 gl.glGetIntegerv(GL_MAX_CLIP_PLANES,&numClipPlanes);
1681 for (int i=0;i<numClipPlanes;++i)
1682 gl.glDisable(GL_CLIP_PLANE0+i);
1683
1684 int nTexPtrs = 0;
1685 for (int i=0;i<getMaxTexUnits();++i) {
1686 if (isTextureUnitEnabled(GL_TEXTURE0+i)) {
1687 TextureData * texData = NULL;
1688 unsigned int texname = getBindedTexture(GL_TEXTURE0+i,GL_TEXTURE_2D);
1689 ObjectLocalName tex = getTextureLocalName(GL_TEXTURE_2D,texname);
1690 gl.glClientActiveTexture(GL_TEXTURE0+i);
1691 auto objData = shareGroup()->getObjectData(
1692 NamedObjectType::TEXTURE, tex);
1693 if (objData) {
1694 texData = (TextureData*)objData;
1695 //calculate texels
1696 texels[i][0] = (float)(texData->crop_rect[0])/(float)(texData->width);
1697 texels[i][1] = (float)(texData->crop_rect[1])/(float)(texData->height);
1698
1699 texels[i][2] = (float)(texData->crop_rect[0])/(float)(texData->width);
1700 texels[i][3] = (float)(texData->crop_rect[3]+texData->crop_rect[1])/(float)(texData->height);
1701
1702 texels[i][4] = (float)(texData->crop_rect[2]+texData->crop_rect[0])/(float)(texData->width);
1703 texels[i][5] = (float)(texData->crop_rect[3]+texData->crop_rect[1])/(float)(texData->height);
1704
1705 texels[i][6] = (float)(texData->crop_rect[2]+texData->crop_rect[0])/(float)(texData->width);
1706 texels[i][7] = (float)(texData->crop_rect[1])/(float)(texData->height);
1707
1708 gl.glTexCoordPointer(2,GL_FLOAT,0,texels[i]);
1709 nTexPtrs++;
1710 }
1711 }
1712 }
1713
1714 if (nTexPtrs>0) {
1715 //draw rectangle - only if we have some textures enabled & ready
1716 gl.glEnableClientState(GL_VERTEX_ARRAY);
1717 gl.glVertexPointer(3,GL_FLOAT,0,vertices);
1718 gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1719 gl.glDrawArrays(GL_TRIANGLE_FAN,0,4);
1720 }
1721
1722 //restore vbo's
1723 gl.glBindBuffer(GL_ARRAY_BUFFER,array_buffer);
1724 gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,element_array_buffer);
1725
1726 //restore matrix state
1727
1728 gl.glMatrixMode(GL_MODELVIEW);
1729 gl.glPopMatrix();
1730 gl.glMatrixMode(GL_TEXTURE);
1731 gl.glPopMatrix();
1732 gl.glMatrixMode(GL_PROJECTION);
1733 gl.glPopMatrix();
1734
1735 gl.glPopAttrib();
1736 gl.glPopClientAttrib();
1737 }
1738 }
1739
rotatef(float angle,float x,float y,float z)1740 void GLEScmContext::rotatef(float angle, float x, float y, float z) {
1741 glm::mat4 rot = glm::rotate(glm::mat4(), 3.14159265358979f / 180.0f * angle, glm::vec3(x, y, z));
1742 currMatrix() *= rot;
1743
1744 if (m_coreProfileEngine) {
1745 core().rotatef(angle, x, y, z);
1746 } else {
1747 dispatcher().glRotatef(angle, x, y, z);
1748 }
1749 }
1750
scalef(float x,float y,float z)1751 void GLEScmContext::scalef(float x, float y, float z) {
1752 glm::mat4 scale = glm::scale(glm::mat4(), glm::vec3(x, y, z));
1753 currMatrix() *= scale;
1754
1755 if (m_coreProfileEngine) {
1756 core().scalef(x, y, z);
1757 } else {
1758 dispatcher().glScalef(x, y, z);
1759 }
1760 }
1761
translatef(float x,float y,float z)1762 void GLEScmContext::translatef(float x, float y, float z) {
1763 glm::mat4 tr = glm::translate(glm::mat4(), glm::vec3(x, y, z));
1764 currMatrix() *= tr;
1765
1766 if (m_coreProfileEngine) {
1767 core().translatef(x, y, z);
1768 } else {
1769 dispatcher().glTranslatef(x, y, z);
1770 }
1771 }
1772
color4f(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)1773 void GLEScmContext::color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
1774
1775 mColor.type = GL_FLOAT;
1776 mColor.val.floatVal[0] = red;
1777 mColor.val.floatVal[1] = green;
1778 mColor.val.floatVal[2] = blue;
1779 mColor.val.floatVal[3] = alpha;
1780
1781 if (m_coreProfileEngine) {
1782 core().color4f(red,green,blue,alpha);
1783 } else{
1784 dispatcher().glColor4f(red,green,blue,alpha);
1785 }
1786 }
1787
color4ub(GLubyte red,GLubyte green,GLubyte blue,GLubyte alpha)1788 void GLEScmContext::color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
1789
1790 mColor.type = GL_UNSIGNED_BYTE;
1791 mColor.val.ubyteVal[0] = red;
1792 mColor.val.ubyteVal[1] = green;
1793 mColor.val.ubyteVal[2] = blue;
1794 mColor.val.ubyteVal[3] = alpha;
1795
1796 if (m_coreProfileEngine) {
1797 core().color4ub(red,green,blue,alpha);
1798 } else{
1799 dispatcher().glColor4ub(red,green,blue,alpha);
1800 }
1801 }
1802
drawArrays(GLenum mode,GLint first,GLsizei count)1803 void GLEScmContext::drawArrays(GLenum mode, GLint first, GLsizei count) {
1804 if (!isArrEnabled(GL_VERTEX_ARRAY)) return;
1805
1806 drawValidate();
1807
1808 GLuint prev_vbo;
1809 GLuint prev_ibo;
1810 dispatcher().glGetIntegerv(GL_ARRAY_BUFFER_BINDING,
1811 (GLint*)&prev_vbo);
1812 dispatcher().glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
1813 (GLint*)&prev_ibo);
1814 dispatcher().glBindBuffer(GL_ARRAY_BUFFER, 0);
1815 dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1816
1817 if (m_coreProfileEngine) {
1818 ArraysMap::iterator it;
1819 m_pointsIndex = -1;
1820
1821 // going over all clients arrays Pointers
1822 for (it = m_currVaoState.begin();
1823 it != m_currVaoState.end(); ++it) {
1824 GLenum array_id = (*it).first;
1825 GLESpointer* p = (*it).second;
1826 if (array_id == GL_VERTEX_ARRAY ||
1827 array_id == GL_NORMAL_ARRAY ||
1828 array_id == GL_COLOR_ARRAY ||
1829 array_id == GL_POINT_SIZE_ARRAY_OES ||
1830 array_id == GL_TEXTURE_COORD_ARRAY) {
1831 core().setupArrayForDraw(array_id, p, first, count, false, 0, nullptr);
1832 }
1833 }
1834
1835 GLenum activeTexture = m_clientActiveTexture + GL_TEXTURE0;
1836 setClientActiveTexture(activeTexture);
1837 core().clientActiveTexture(activeTexture);
1838 core().drawArrays(mode, first, count);
1839 } else {
1840 GLESConversionArrays tmpArrs;
1841
1842 setupArraysPointers(tmpArrs,first,count,0,NULL,true);
1843
1844 if (mode == GL_POINTS && isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){
1845 drawPointsArrs(tmpArrs,first,count);
1846 } else {
1847 dispatcher().glDrawArrays(mode,first,count);
1848 }
1849 }
1850 dispatcher().glBindBuffer(GL_ARRAY_BUFFER, prev_vbo);
1851 dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_ibo);
1852 }
1853
drawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1854 void GLEScmContext::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
1855 if (!isArrEnabled(GL_VERTEX_ARRAY)) return;
1856
1857 drawValidate();
1858
1859 if(isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
1860 const unsigned char* buf = static_cast<unsigned char *>(getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));
1861 indices = buf + SafeUIntFromPointer(indices);
1862 }
1863
1864 GLuint prev_vbo;
1865 GLuint prev_ibo;
1866 dispatcher().glGetIntegerv(GL_ARRAY_BUFFER_BINDING,
1867 (GLint*)&prev_vbo);
1868 dispatcher().glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
1869 (GLint*)&prev_ibo);
1870 dispatcher().glBindBuffer(GL_ARRAY_BUFFER, 0);
1871 dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1872
1873 if (m_coreProfileEngine) {
1874 ArraysMap::iterator it;
1875 m_pointsIndex = -1;
1876
1877 // going over all clients arrays Pointers
1878 for (it = m_currVaoState.begin();
1879 it != m_currVaoState.end(); ++it) {
1880 GLenum array_id = (*it).first;
1881 GLESpointer* p = (*it).second;
1882 if (array_id == GL_VERTEX_ARRAY ||
1883 array_id == GL_NORMAL_ARRAY ||
1884 array_id == GL_COLOR_ARRAY ||
1885 array_id == GL_POINT_SIZE_ARRAY_OES ||
1886 array_id == GL_TEXTURE_COORD_ARRAY) {
1887 core().setupArrayForDraw(array_id, p, 0, count, true, type, indices);
1888 }
1889 }
1890
1891 GLenum activeTexture = m_clientActiveTexture + GL_TEXTURE0;
1892 setClientActiveTexture(activeTexture);
1893 core().clientActiveTexture(activeTexture);
1894 core().drawElements(mode, count, type, indices);
1895 } else {
1896 GLESConversionArrays tmpArrs;
1897
1898 setupArraysPointers(tmpArrs,0,count,type,indices,false);
1899 if(mode == GL_POINTS && isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){
1900 drawPointsElems(tmpArrs,count,type,indices);
1901 }
1902 else{
1903 dispatcher().glDrawElements(mode,count,type,indices);
1904 }
1905 }
1906 dispatcher().glBindBuffer(GL_ARRAY_BUFFER, prev_vbo);
1907 dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_ibo);
1908 }
1909
clientActiveTexture(GLenum texture)1910 void GLEScmContext::clientActiveTexture(GLenum texture) {
1911 if (m_coreProfileEngine) {
1912 core().clientActiveTexture(texture);
1913 } else {
1914 dispatcher().glClientActiveTexture(texture);
1915 }
1916 }
1917