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