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