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()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( 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 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 initCapsLocked((const GLubyte*)getHostExtensionsString(&s_glDispatch).c_str(),
721 s_glSupportGles1);
722 *s_glExtensionsGles1 = "GL_OES_blend_func_separate GL_OES_blend_equation_separate GL_OES_blend_subtract "
723 "GL_OES_byte_coordinates GL_OES_compressed_paletted_texture GL_OES_point_size_array "
724 "GL_OES_point_sprite GL_OES_single_precision GL_OES_stencil_wrap GL_OES_texture_env_crossbar "
725 "GL_OES_texture_mirored_repeat GL_OES_EGL_image GL_OES_element_index_uint GL_OES_draw_texture "
726 "GL_OES_texture_cube_map GL_OES_draw_texture ";
727 if (s_glSupportGles1.GL_OES_READ_FORMAT)
728 *s_glExtensionsGles1+="GL_OES_read_format ";
729 if (s_glSupportGles1.GL_EXT_FRAMEBUFFER_OBJECT) {
730 *s_glExtensionsGles1+="GL_OES_framebuffer_object GL_OES_depth24 GL_OES_depth32 GL_OES_fbo_render_mipmap "
731 "GL_OES_rgb8_rgba8 GL_OES_stencil1 GL_OES_stencil4 GL_OES_stencil8 ";
732 }
733 if (s_glSupportGles1.GL_EXT_PACKED_DEPTH_STENCIL)
734 *s_glExtensionsGles1+="GL_OES_packed_depth_stencil ";
735 if (s_glSupportGles1.GL_EXT_TEXTURE_FORMAT_BGRA8888)
736 *s_glExtensionsGles1+="GL_EXT_texture_format_BGRA8888 GL_APPLE_texture_format_BGRA8888 ";
737 if (s_glSupportGles1.GL_ARB_MATRIX_PALETTE && s_glSupportGles1.GL_ARB_VERTEX_BLEND) {
738 *s_glExtensionsGles1+="GL_OES_matrix_palette ";
739 GLint max_palette_matrices=0;
740 GLint max_vertex_units=0;
741 dispatcher().glGetIntegerv(GL_MAX_PALETTE_MATRICES_OES,&max_palette_matrices);
742 dispatcher().glGetIntegerv(GL_MAX_VERTEX_UNITS_OES,&max_vertex_units);
743 if (max_palette_matrices>=32 && max_vertex_units>=4)
744 *s_glExtensionsGles1+="GL_OES_extended_matrix_palette ";
745 }
746 *s_glExtensionsGles1+="GL_OES_compressed_ETC1_RGB8_texture ";
747
748 s_glExtensionsGles1Initialized = true;
749 }
750
getMaxTexUnits()751 int GLEScmContext::getMaxTexUnits() {
752 return kMaxTextureUnits;
753 }
754
glGetBooleanv(GLenum pname,GLboolean * params)755 bool GLEScmContext::glGetBooleanv(GLenum pname, GLboolean *params)
756 {
757 GLint iParam;
758
759 if(glGetIntegerv(pname, &iParam))
760 {
761 *params = (iParam != 0);
762 return true;
763 }
764
765 return false;
766 }
767
glGetFixedv(GLenum pname,GLfixed * params)768 bool GLEScmContext::glGetFixedv(GLenum pname, GLfixed *params)
769 {
770 GLint iParam;
771
772 if(glGetIntegerv(pname, &iParam))
773 {
774 *params = I2X(iParam);
775 return true;
776 }
777
778 return false;
779 }
780
glGetFloatv(GLenum pname,GLfloat * params)781 bool GLEScmContext::glGetFloatv(GLenum pname, GLfloat *params)
782 {
783 GLint iParam;
784
785 if(glGetIntegerv(pname, &iParam))
786 {
787 *params = (GLfloat)iParam;
788 return true;
789 }
790
791 return false;
792 }
793
glGetIntegerv(GLenum pname,GLint * params)794 bool GLEScmContext::glGetIntegerv(GLenum pname, GLint *params)
795 {
796 if(GLEScontext::glGetIntegerv(pname, params))
797 return true;
798
799 const GLESpointer* ptr = NULL;
800
801 switch(pname){
802 case GL_VERTEX_ARRAY_BUFFER_BINDING:
803 case GL_VERTEX_ARRAY_SIZE:
804 case GL_VERTEX_ARRAY_STRIDE:
805 case GL_VERTEX_ARRAY_TYPE:
806 ptr = getPointer(GL_VERTEX_ARRAY_POINTER);
807 break;
808
809 case GL_NORMAL_ARRAY_BUFFER_BINDING:
810 case GL_NORMAL_ARRAY_STRIDE:
811 case GL_NORMAL_ARRAY_TYPE:
812 ptr = getPointer(GL_NORMAL_ARRAY_POINTER);
813 break;
814
815 case GL_COLOR_ARRAY_BUFFER_BINDING:
816 case GL_COLOR_ARRAY_SIZE:
817 case GL_COLOR_ARRAY_STRIDE:
818 case GL_COLOR_ARRAY_TYPE:
819 ptr = getPointer(GL_COLOR_ARRAY_POINTER);
820 break;
821
822 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
823 case GL_TEXTURE_COORD_ARRAY_SIZE:
824 case GL_TEXTURE_COORD_ARRAY_STRIDE:
825 case GL_TEXTURE_COORD_ARRAY_TYPE:
826 ptr = getPointer(GL_TEXTURE_COORD_ARRAY_POINTER);
827 break;
828
829 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
830 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
831 case GL_POINT_SIZE_ARRAY_TYPE_OES:
832 ptr = getPointer(GL_POINT_SIZE_ARRAY_POINTER_OES);
833 break;
834
835 default:
836 return false;
837 }
838
839 switch(pname)
840 {
841 case GL_VERTEX_ARRAY_BUFFER_BINDING:
842 case GL_NORMAL_ARRAY_BUFFER_BINDING:
843 case GL_COLOR_ARRAY_BUFFER_BINDING:
844 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
845 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
846 *params = ptr ? ptr->getBufferName() : 0;
847 break;
848
849 case GL_VERTEX_ARRAY_STRIDE:
850 case GL_NORMAL_ARRAY_STRIDE:
851 case GL_COLOR_ARRAY_STRIDE:
852 case GL_TEXTURE_COORD_ARRAY_STRIDE:
853 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
854 *params = ptr ? ptr->getStride() : 0;
855 break;
856
857 case GL_VERTEX_ARRAY_SIZE:
858 case GL_COLOR_ARRAY_SIZE:
859 case GL_TEXTURE_COORD_ARRAY_SIZE:
860 *params = ptr ? ptr->getSize() : 0;
861 break;
862
863 case GL_VERTEX_ARRAY_TYPE:
864 case GL_NORMAL_ARRAY_TYPE:
865 case GL_COLOR_ARRAY_TYPE:
866 case GL_TEXTURE_COORD_ARRAY_TYPE:
867 case GL_POINT_SIZE_ARRAY_TYPE_OES:
868 *params = ptr ? ptr->getType() : 0;
869 break;
870 }
871
872 return true;
873 }
874
getErrorCoreProfile()875 GLint GLEScmContext::getErrorCoreProfile() {
876 return core().getAndClearLastError();
877 }
878
enable(GLenum cap)879 void GLEScmContext::enable(GLenum cap) {
880 setEnable(cap, true);
881
882 if (m_coreProfileEngine) {
883 core().enable(cap);
884 } else {
885 if (cap==GL_TEXTURE_GEN_STR_OES) {
886 dispatcher().glEnable(GL_TEXTURE_GEN_S);
887 dispatcher().glEnable(GL_TEXTURE_GEN_T);
888 dispatcher().glEnable(GL_TEXTURE_GEN_R);
889 } else {
890 dispatcher().glEnable(cap);
891 }
892 }
893 }
894
disable(GLenum cap)895 void GLEScmContext::disable(GLenum cap) {
896 setEnable(cap, false);
897
898 if (m_coreProfileEngine) {
899 core().disable(cap);
900 } else {
901 if (cap==GL_TEXTURE_GEN_STR_OES) {
902 dispatcher().glDisable(GL_TEXTURE_GEN_S);
903 dispatcher().glDisable(GL_TEXTURE_GEN_T);
904 dispatcher().glDisable(GL_TEXTURE_GEN_R);
905 } else {
906 dispatcher().glDisable(cap);
907 }
908 }
909 }
910
shadeModel(GLenum mode)911 void GLEScmContext::shadeModel(GLenum mode) {
912 mShadeModel = mode;
913
914 if (m_coreProfileEngine) {
915 core().shadeModel(mode);
916 } else {
917 dispatcher().glShadeModel(mode);
918 }
919 }
920
matrixMode(GLenum mode)921 void GLEScmContext::matrixMode(GLenum mode) {
922 mCurrMatrixMode = mode;
923
924 if (m_coreProfileEngine) {
925 core().matrixMode(mode);
926 } else {
927 dispatcher().glMatrixMode(mode);
928 }
929 }
930
loadIdentity()931 void GLEScmContext::loadIdentity() {
932 currMatrix() = glm::mat4();
933
934 if (m_coreProfileEngine) {
935 core().loadIdentity();
936 } else {
937 dispatcher().glLoadIdentity();
938 }
939 }
940
loadMatrixf(const GLfloat * m)941 void GLEScmContext::loadMatrixf(const GLfloat* m) {
942 currMatrix() = glm::make_mat4(m);
943
944 if (m_coreProfileEngine) {
945 core().loadMatrixf(m);
946 } else {
947 dispatcher().glLoadMatrixf(m);
948 }
949 }
950
pushMatrix()951 void GLEScmContext::pushMatrix() {
952 if (currMatrixStack().size() >= kMaxMatrixStackSize) {
953 setGLerror(GL_STACK_OVERFLOW);
954 return;
955 }
956 currMatrixStack().emplace_back(currMatrixStack().back());
957
958 if (m_coreProfileEngine) {
959 core().pushMatrix();
960 } else {
961 dispatcher().glPushMatrix();
962 }
963 }
964
popMatrix()965 void GLEScmContext::popMatrix() {
966 if (currMatrixStack().size() == 1) {
967 setGLerror(GL_STACK_UNDERFLOW);
968 return;
969 }
970 currMatrixStack().pop_back();
971
972 if (m_coreProfileEngine) {
973 core().popMatrix();
974 } else {
975 dispatcher().glPopMatrix();
976 }
977 }
978
multMatrixf(const GLfloat * m)979 void GLEScmContext::multMatrixf(const GLfloat* m) {
980 currMatrix() *= glm::make_mat4(m);
981
982 if (m_coreProfileEngine) {
983 core().multMatrixf(m);
984 } else {
985 dispatcher().glMultMatrixf(m);
986 }
987 }
988
orthof(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)989 void GLEScmContext::orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
990 currMatrix() *= glm::ortho(left, right, bottom, top, zNear, zFar);
991
992 if (m_coreProfileEngine) {
993 core().orthof(left, right, bottom, top, zNear, zFar);
994 } else {
995 dispatcher().glOrthof(left,right,bottom,top,zNear,zFar);
996 }
997 }
998
frustumf(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)999 void GLEScmContext::frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
1000 currMatrix() *= glm::frustum(left, right, bottom, top, zNear, zFar);
1001
1002 if (m_coreProfileEngine) {
1003 core().frustumf(left, right, bottom, top, zNear, zFar);
1004 } else {
1005 dispatcher().glFrustumf(left,right,bottom,top,zNear,zFar);
1006 }
1007 }
1008
texEnvf(GLenum target,GLenum pname,GLfloat param)1009 void GLEScmContext::texEnvf(GLenum target, GLenum pname, GLfloat param) {
1010 // Assume |target| is GL_TEXTURE_ENV
1011 if (pname == GL_TEXTURE_ENV_MODE) {
1012 texEnvi(target, pname, (GLint)param);
1013 } else {
1014 mTexUnitEnvs[m_activeTexture][pname].val.floatVal[0] = param;
1015 mTexUnitEnvs[m_activeTexture][pname].type = GL_FLOAT;
1016 }
1017
1018 if (m_coreProfileEngine) {
1019 core().texEnvf(target, pname, param);
1020 } else {
1021 dispatcher().glTexEnvf(target, pname, param);
1022 }
1023 }
1024
texEnvfv(GLenum target,GLenum pname,const GLfloat * params)1025 void GLEScmContext::texEnvfv(GLenum target, GLenum pname, const GLfloat* params) {
1026 if (pname == GL_TEXTURE_ENV_COLOR) {
1027 for (int i = 0; i < 4; i++) {
1028 mTexUnitEnvs[m_activeTexture][pname].val.floatVal[i] = params[i];
1029 mTexUnitEnvs[m_activeTexture][pname].type = GL_FLOAT;
1030 }
1031 } else {
1032 texEnvf(target, pname, params[0]);
1033 }
1034
1035 if (m_coreProfileEngine) {
1036 core().texEnvfv(target, pname, params);
1037 } else {
1038 dispatcher().glTexEnvfv(target, pname, params);
1039 }
1040 }
1041
texEnvi(GLenum target,GLenum pname,GLint param)1042 void GLEScmContext::texEnvi(GLenum target, GLenum pname, GLint param) {
1043 mTexUnitEnvs[m_activeTexture][pname].val.intVal[0] = param;
1044 mTexUnitEnvs[m_activeTexture][pname].type = GL_INT;
1045
1046 if (m_coreProfileEngine) {
1047 core().texEnvi(target, pname, param);
1048 } else {
1049 dispatcher().glTexEnvi(target, pname, param);
1050 }
1051 }
1052
texEnviv(GLenum target,GLenum pname,const GLint * params)1053 void GLEScmContext::texEnviv(GLenum target, GLenum pname, const GLint* params) {
1054 mTexUnitEnvs[m_activeTexture][pname].val.intVal[0] = params[0];
1055 mTexUnitEnvs[m_activeTexture][pname].type = GL_INT;
1056
1057 if (m_coreProfileEngine) {
1058 core().texEnviv(target, pname, params);
1059 } else {
1060 dispatcher().glTexEnviv(target, pname, params);
1061 }
1062 }
1063
getTexEnvfv(GLenum env,GLenum pname,GLfloat * params)1064 void GLEScmContext::getTexEnvfv(GLenum env, GLenum pname, GLfloat* params) {
1065 *params = mTexUnitEnvs[m_activeTexture][pname].val.floatVal[0];
1066
1067 if (m_coreProfileEngine) {
1068 core().getTexEnvfv(env, pname, params);
1069 } else {
1070 dispatcher().glGetTexEnvfv(env, pname, params);
1071 }
1072 }
1073
getTexEnviv(GLenum env,GLenum pname,GLint * params)1074 void GLEScmContext::getTexEnviv(GLenum env, GLenum pname, GLint* params) {
1075 *params = mTexUnitEnvs[m_activeTexture][pname].val.intVal[0];
1076
1077 if (m_coreProfileEngine) {
1078 core().getTexEnviv(env, pname, params);
1079 } else {
1080 dispatcher().glGetTexEnviv(env, pname, params);
1081 }
1082 }
1083
texGenf(GLenum coord,GLenum pname,GLfloat param)1084 void GLEScmContext::texGenf(GLenum coord, GLenum pname, GLfloat param) {
1085 mTexGens[m_activeTexture][pname].val.floatVal[0] = param;
1086 mTexGens[m_activeTexture][pname].type = GL_FLOAT;
1087
1088 if (m_coreProfileEngine) {
1089 core().texGenf(coord, pname, param);
1090 } else {
1091 if (coord == GL_TEXTURE_GEN_STR_OES) {
1092 dispatcher().glTexGenf(GL_S,pname,param);
1093 dispatcher().glTexGenf(GL_T,pname,param);
1094 dispatcher().glTexGenf(GL_R,pname,param);
1095 } else {
1096 dispatcher().glTexGenf(coord,pname,param);
1097 }
1098 }
1099 }
1100
texGenfv(GLenum coord,GLenum pname,const GLfloat * params)1101 void GLEScmContext::texGenfv(GLenum coord, GLenum pname, const GLfloat* params) {
1102 mTexGens[m_activeTexture][pname].val.floatVal[0] = params[0];
1103 mTexGens[m_activeTexture][pname].type = GL_FLOAT;
1104
1105 if (m_coreProfileEngine) {
1106 core().texGenfv(coord, pname, params);
1107 } else {
1108 if (coord == GL_TEXTURE_GEN_STR_OES) {
1109 dispatcher().glTexGenfv(GL_S,pname,params);
1110 dispatcher().glTexGenfv(GL_T,pname,params);
1111 dispatcher().glTexGenfv(GL_R,pname,params);
1112 } else {
1113 dispatcher().glTexGenfv(coord,pname,params);
1114 }
1115 }
1116 }
1117
texGeni(GLenum coord,GLenum pname,GLint param)1118 void GLEScmContext::texGeni(GLenum coord, GLenum pname, GLint param) {
1119 mTexGens[m_activeTexture][pname].val.intVal[0] = param;
1120 mTexGens[m_activeTexture][pname].type = GL_INT;
1121
1122 if (m_coreProfileEngine) {
1123 core().texGeni(coord, pname, param);
1124 } else {
1125 if (coord == GL_TEXTURE_GEN_STR_OES) {
1126 dispatcher().glTexGeni(GL_S,pname,param);
1127 dispatcher().glTexGeni(GL_T,pname,param);
1128 dispatcher().glTexGeni(GL_R,pname,param);
1129 } else {
1130 dispatcher().glTexGeni(coord,pname,param);
1131 }
1132 }
1133 }
1134
texGeniv(GLenum coord,GLenum pname,const GLint * params)1135 void GLEScmContext::texGeniv(GLenum coord, GLenum pname, const GLint* params) {
1136 mTexGens[m_activeTexture][pname].val.intVal[0] = params[0];
1137 mTexGens[m_activeTexture][pname].type = GL_INT;
1138
1139 if (m_coreProfileEngine) {
1140 core().texGeniv(coord, pname, params);
1141 } else {
1142 if (coord == GL_TEXTURE_GEN_STR_OES) {
1143 dispatcher().glTexGeniv(GL_S,pname,params);
1144 dispatcher().glTexGeniv(GL_T,pname,params);
1145 dispatcher().glTexGeniv(GL_R,pname,params);
1146 } else {
1147 dispatcher().glTexGeniv(coord,pname,params);
1148 }
1149 }
1150 }
1151
getTexGeniv(GLenum coord,GLenum pname,GLint * params)1152 void GLEScmContext::getTexGeniv(GLenum coord, GLenum pname, GLint* params) {
1153 *params = mTexGens[m_activeTexture][pname].val.intVal[0];
1154
1155 if (m_coreProfileEngine) {
1156 core().getTexGeniv(coord, pname, params);
1157 } else {
1158 if (coord == GL_TEXTURE_GEN_STR_OES) {
1159 GLint state_s = GL_FALSE;
1160 GLint state_t = GL_FALSE;
1161 GLint state_r = GL_FALSE;
1162 dispatcher().glGetTexGeniv(GL_S,pname,&state_s);
1163 dispatcher().glGetTexGeniv(GL_T,pname,&state_t);
1164 dispatcher().glGetTexGeniv(GL_R,pname,&state_r);
1165 *params = state_s && state_t && state_r ? GL_TRUE: GL_FALSE;
1166 } else {
1167 dispatcher().glGetTexGeniv(coord,pname,params);
1168 }
1169 }
1170 }
1171
getTexGenfv(GLenum coord,GLenum pname,GLfloat * params)1172 void GLEScmContext::getTexGenfv(GLenum coord, GLenum pname, GLfloat* params) {
1173 params[0] = mTexGens[m_activeTexture][pname].val.floatVal[0];
1174 params[1] = mTexGens[m_activeTexture][pname].val.floatVal[1];
1175 params[2] = mTexGens[m_activeTexture][pname].val.floatVal[2];
1176 params[3] = mTexGens[m_activeTexture][pname].val.floatVal[3];
1177
1178 if (m_coreProfileEngine) {
1179 core().getTexGenfv(coord, pname, params);
1180 } else {
1181 if (coord == GL_TEXTURE_GEN_STR_OES) {
1182 GLfloat state_s = GL_FALSE;
1183 GLfloat state_t = GL_FALSE;
1184 GLfloat state_r = GL_FALSE;
1185 dispatcher().glGetTexGenfv(GL_S,pname,&state_s);
1186 dispatcher().glGetTexGenfv(GL_T,pname,&state_t);
1187 dispatcher().glGetTexGenfv(GL_R,pname,&state_r);
1188 *params = state_s && state_t && state_r ? GL_TRUE: GL_FALSE;
1189 } else {
1190 dispatcher().glGetTexGenfv(coord,pname,params);
1191 }
1192 }
1193 }
1194
materialf(GLenum face,GLenum pname,GLfloat param)1195 void GLEScmContext::materialf(GLenum face, GLenum pname, GLfloat param) {
1196 if (face != GL_FRONT_AND_BACK) {
1197 fprintf(stderr, "GL_INVALID_ENUM: GLES1's glMaterial(f/x) "
1198 "only supports GL_FRONT_AND_BACK for materials.\n");
1199 setGLerror(GL_INVALID_ENUM);
1200 return;
1201 }
1202 switch (pname) {
1203 case GL_AMBIENT:
1204 case GL_DIFFUSE:
1205 case GL_AMBIENT_AND_DIFFUSE:
1206 case GL_SPECULAR:
1207 case GL_EMISSION:
1208 fprintf(stderr, "GL_INVALID_ENUM: glMaterial(f/x) only supports "
1209 "GL_SHININESS for single parameter setting.\n");
1210 setGLerror(GL_INVALID_ENUM);
1211 return;
1212 case GL_SHININESS:
1213 if (param < 0.0f || param > 128.0f) {
1214 fprintf(stderr, "GL_INVALID_VALUE: Invalid specular exponent value %f. "
1215 "Only range [0.0, 128.0] supported.\n", param);
1216 setGLerror(GL_INVALID_VALUE);
1217 return;
1218 }
1219 mMaterial.specularExponent = param;
1220 break;
1221 default:
1222 fprintf(stderr, "Unknown parameter name 0x%x for glMaterial(f/x)\n", pname);
1223 setGLerror(GL_INVALID_ENUM);
1224 return;
1225 }
1226
1227 if (!m_coreProfileEngine) {
1228 dispatcher().glMaterialf(face, pname, param);
1229 }
1230 }
1231
materialfv(GLenum face,GLenum pname,const GLfloat * params)1232 void GLEScmContext::materialfv(GLenum face, GLenum pname, const GLfloat* params) {
1233 if (face != GL_FRONT_AND_BACK) {
1234 fprintf(stderr, "GL_INVALID_ENUM: GLES1's glMaterial(f/x)v "
1235 "only supports GL_FRONT_AND_BACK for materials.\n");
1236 setGLerror(GL_INVALID_ENUM);
1237 return;
1238 }
1239
1240 switch (pname) {
1241 case GL_AMBIENT:
1242 memcpy(&mMaterial.ambient, params, 4 * sizeof(GLfloat));
1243 break;
1244 case GL_DIFFUSE:
1245 memcpy(&mMaterial.diffuse, params, 4 * sizeof(GLfloat));
1246 break;
1247 case GL_AMBIENT_AND_DIFFUSE:
1248 memcpy(&mMaterial.ambient, params, 4 * sizeof(GLfloat));
1249 memcpy(&mMaterial.diffuse, params, 4 * sizeof(GLfloat));
1250 break;
1251 case GL_SPECULAR:
1252 memcpy(&mMaterial.specular, params, 4 * sizeof(GLfloat));
1253 break;
1254 case GL_EMISSION:
1255 memcpy(&mMaterial.emissive, params, 4 * sizeof(GLfloat));
1256 break;
1257 case GL_SHININESS:
1258 if (*params < 0.0f || *params > 128.0f) {
1259 fprintf(stderr, "GL_INVALID_VALUE: Invalid specular exponent value %f. "
1260 "Only range [0.0, 128.0] supported.\n", *params);
1261 setGLerror(GL_INVALID_VALUE);
1262 return;
1263 }
1264 mMaterial.specularExponent = *params;
1265 break;
1266 default:
1267 fprintf(stderr, "Unknown parameter name 0x%x for glMaterial(f/x)v.\n", pname);
1268 setGLerror(GL_INVALID_ENUM);
1269 return;
1270 }
1271
1272 if (!m_coreProfileEngine) {
1273 dispatcher().glMaterialfv(face, pname, params);
1274 }
1275 }
1276
getMaterialfv(GLenum face,GLenum pname,GLfloat * params)1277 void GLEScmContext::getMaterialfv(GLenum face, GLenum pname, GLfloat* params) {
1278 if (face != GL_FRONT && face != GL_BACK) {
1279 fprintf(stderr, "GL_INVALID_ENUM: glGetMaterial(f/x)v "
1280 "must take GL_FRONT or GL_BACK as face argument\n");
1281 setGLerror(GL_INVALID_ENUM);
1282 return;
1283 }
1284
1285 switch (pname) {
1286 case GL_AMBIENT:
1287 memcpy(params, &mMaterial.ambient, 4 * sizeof(GLfloat));
1288 break;
1289 case GL_DIFFUSE:
1290 memcpy(params, &mMaterial.diffuse, 4 * sizeof(GLfloat));
1291 break;
1292 case GL_SPECULAR:
1293 memcpy(params, &mMaterial.specular, 4 * sizeof(GLfloat));
1294 break;
1295 case GL_EMISSION:
1296 memcpy(params, &mMaterial.emissive, 4 * sizeof(GLfloat));
1297 break;
1298 case GL_SHININESS:
1299 *params = mMaterial.specularExponent;
1300 break;
1301 default:
1302 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glGetMaterial(f/x)v.\n", pname);
1303 setGLerror(GL_INVALID_ENUM);
1304 return;
1305 }
1306
1307 if (!m_coreProfileEngine) {
1308 dispatcher().glGetMaterialfv(face, pname, params);
1309 }
1310 }
1311
lightModelf(GLenum pname,GLfloat param)1312 void GLEScmContext::lightModelf(GLenum pname, GLfloat param) {
1313 switch (pname) {
1314 case GL_LIGHT_MODEL_AMBIENT:
1315 fprintf(stderr, "GL_INVALID_ENUM: glLightModelf only supports GL_LIGHT_MODEL_TWO_SIDE.\n");
1316 setGLerror(GL_INVALID_ENUM);
1317 return;
1318 case GL_LIGHT_MODEL_TWO_SIDE:
1319 if (param != 1.0f && param != 0.0f) {
1320 fprintf(stderr, "GL_INVALID_VALUE: glLightModelf only takes 0 or 1 "
1321 "for GL_LIGHT_MODEL_TWO_SIDE, but got %f\n", param);
1322 setGLerror(GL_INVALID_VALUE);
1323 }
1324 mLightModel.twoSided = param == 1.0f ? true : false;
1325 break;
1326 default:
1327 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glLightModel(f/x)v.\n", pname);
1328 setGLerror(GL_INVALID_ENUM);
1329 return;
1330 }
1331
1332 if (!m_coreProfileEngine) {
1333 dispatcher().glLightModelf(pname, param);
1334 }
1335 }
1336
lightModelfv(GLenum pname,const GLfloat * params)1337 void GLEScmContext::lightModelfv(GLenum pname, const GLfloat* params) {
1338 switch (pname) {
1339 case GL_LIGHT_MODEL_AMBIENT:
1340 memcpy(&mLightModel.color, params, 4 * sizeof(GLfloat));
1341 break;
1342 case GL_LIGHT_MODEL_TWO_SIDE:
1343 if (*params != 1.0f && *params != 0.0f) {
1344 fprintf(stderr, "GL_INVALID_VALUE: glLightModelf only takes 0 or 1 "
1345 "for GL_LIGHT_MODEL_TWO_SIDE, but got %f\n", *params);
1346 setGLerror(GL_INVALID_VALUE);
1347 }
1348 mLightModel.twoSided = *params == 1.0f ? true : false;
1349 break;
1350 default:
1351 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glLightModel(f/x)v.\n", pname);
1352 setGLerror(GL_INVALID_ENUM);
1353 return;
1354 }
1355
1356 if (!m_coreProfileEngine) {
1357 dispatcher().glLightModelfv(pname, params);
1358 }
1359 }
1360
lightf(GLenum light,GLenum pname,GLfloat param)1361 void GLEScmContext::lightf(GLenum light, GLenum pname, GLfloat param) {
1362 uint32_t lightIndex = light - GL_LIGHT0;
1363
1364 if (lightIndex >= kMaxLights) {
1365 fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for glLight(f/x) (wanted %u)\n",
1366 lightIndex);
1367 setGLerror(GL_INVALID_ENUM);
1368 return;
1369 }
1370
1371 switch (pname) {
1372 case GL_AMBIENT:
1373 case GL_DIFFUSE:
1374 case GL_SPECULAR:
1375 case GL_POSITION:
1376 case GL_SPOT_DIRECTION:
1377 fprintf(stderr, "GL_INVALID_ENUM: Invalid parameter name 0x%x "
1378 "for glLight(f/x). Needs glLight(f/x)v.\n", pname);
1379 setGLerror(GL_INVALID_ENUM);
1380 return;
1381 case GL_SPOT_EXPONENT:
1382 mLights[lightIndex].spotlightExponent = param;
1383 break;
1384 case GL_SPOT_CUTOFF:
1385 mLights[lightIndex].spotlightCutoffAngle = param;
1386 break;
1387 case GL_CONSTANT_ATTENUATION:
1388 mLights[lightIndex].attenuationConst = param;
1389 break;
1390 case GL_LINEAR_ATTENUATION:
1391 mLights[lightIndex].attenuationLinear = param;
1392 break;
1393 case GL_QUADRATIC_ATTENUATION:
1394 mLights[lightIndex].attenuationQuadratic = param;
1395 break;
1396 default:
1397 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1398 "for glLight(f/x).\n", pname);
1399 setGLerror(GL_INVALID_ENUM);
1400 return;
1401 }
1402
1403 if (!m_coreProfileEngine) {
1404 dispatcher().glLightf(light, pname, param);
1405 }
1406 }
1407
lightfv(GLenum light,GLenum pname,const GLfloat * params)1408 void GLEScmContext::lightfv(GLenum light, GLenum pname, const GLfloat* params) {
1409 uint32_t lightIndex = light - GL_LIGHT0;
1410
1411 if (lightIndex >= kMaxLights) {
1412 fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for "
1413 "glLight(f/x)v (wanted %u)\n",
1414 lightIndex);
1415 setGLerror(GL_INVALID_ENUM);
1416 return;
1417 }
1418
1419 switch (pname) {
1420 case GL_AMBIENT:
1421 memcpy(&mLights[lightIndex].ambient, params, 4 * sizeof(GLfloat));
1422 break;
1423 case GL_DIFFUSE:
1424 memcpy(&mLights[lightIndex].diffuse, params, 4 * sizeof(GLfloat));
1425 break;
1426 case GL_SPECULAR:
1427 memcpy(&mLights[lightIndex].specular, params, 4 * sizeof(GLfloat));
1428 break;
1429 case GL_POSITION:
1430 memcpy(&mLights[lightIndex].position, params, 4 * sizeof(GLfloat));
1431 break;
1432 case GL_SPOT_DIRECTION:
1433 memcpy(&mLights[lightIndex].direction, params, 3 * sizeof(GLfloat));
1434 break;
1435 case GL_SPOT_EXPONENT:
1436 mLights[lightIndex].spotlightExponent = *params;
1437 break;
1438 case GL_SPOT_CUTOFF:
1439 mLights[lightIndex].spotlightCutoffAngle = *params;
1440 break;
1441 case GL_CONSTANT_ATTENUATION:
1442 mLights[lightIndex].attenuationConst = *params;
1443 break;
1444 case GL_LINEAR_ATTENUATION:
1445 mLights[lightIndex].attenuationLinear = *params;
1446 break;
1447 case GL_QUADRATIC_ATTENUATION:
1448 mLights[lightIndex].attenuationQuadratic = *params;
1449 break;
1450 default:
1451 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1452 "for glLight(f/x).\n", pname);
1453 setGLerror(GL_INVALID_ENUM);
1454 return;
1455 }
1456
1457 if (!m_coreProfileEngine) {
1458 dispatcher().glLightfv(light, pname, params);
1459 }
1460 }
1461
getLightfv(GLenum light,GLenum pname,GLfloat * params)1462 void GLEScmContext::getLightfv(GLenum light, GLenum pname, GLfloat* params) {
1463 uint32_t lightIndex = light - GL_LIGHT0;
1464
1465 if (lightIndex >= kMaxLights) {
1466 fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for "
1467 "glGetLight(f/x)v (wanted %u)\n",
1468 lightIndex);
1469 setGLerror(GL_INVALID_ENUM);
1470 return;
1471 }
1472
1473 switch (pname) {
1474 case GL_AMBIENT:
1475 memcpy(params, &mLights[lightIndex].ambient, 4 * sizeof(GLfloat));
1476 break;
1477 case GL_DIFFUSE:
1478 memcpy(params, &mLights[lightIndex].diffuse, 4 * sizeof(GLfloat));
1479 break;
1480 case GL_SPECULAR:
1481 memcpy(params, &mLights[lightIndex].specular, 4 * sizeof(GLfloat));
1482 break;
1483 case GL_POSITION:
1484 memcpy(params, &mLights[lightIndex].position, 4 * sizeof(GLfloat));
1485 break;
1486 case GL_SPOT_DIRECTION:
1487 memcpy(params, &mLights[lightIndex].direction, 3 * sizeof(GLfloat));
1488 break;
1489 case GL_SPOT_EXPONENT:
1490 *params = mLights[lightIndex].spotlightExponent;
1491 break;
1492 case GL_SPOT_CUTOFF:
1493 *params = mLights[lightIndex].spotlightCutoffAngle;
1494 break;
1495 case GL_CONSTANT_ATTENUATION:
1496 *params = mLights[lightIndex].attenuationConst;
1497 break;
1498 case GL_LINEAR_ATTENUATION:
1499 *params = mLights[lightIndex].attenuationLinear;
1500 break;
1501 case GL_QUADRATIC_ATTENUATION:
1502 *params = mLights[lightIndex].attenuationQuadratic;
1503 break;
1504 default:
1505 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1506 "for glGetLight(f/x).\n", pname);
1507 setGLerror(GL_INVALID_ENUM);
1508 return;
1509 }
1510
1511 if (!m_coreProfileEngine) {
1512 dispatcher().glGetLightfv(light, pname, params);
1513 }
1514 }
1515
multiTexCoord4f(GLenum target,GLfloat s,GLfloat t,GLfloat r,GLfloat q)1516 void GLEScmContext::multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
1517
1518 mMultiTexCoord[target - GL_TEXTURE0].floatVal[0] = s;
1519 mMultiTexCoord[target - GL_TEXTURE0].floatVal[1] = t;
1520 mMultiTexCoord[target - GL_TEXTURE0].floatVal[2] = q;
1521 mMultiTexCoord[target - GL_TEXTURE0].floatVal[3] = r;
1522
1523 if (!m_coreProfileEngine) {
1524 dispatcher().glMultiTexCoord4f(target, s, t, r, q);
1525 }
1526 }
1527
normal3f(GLfloat nx,GLfloat ny,GLfloat nz)1528 void GLEScmContext::normal3f(GLfloat nx, GLfloat ny, GLfloat nz) {
1529 mNormal.type = GL_FLOAT;
1530 mNormal.val.floatVal[0] = nx;
1531 mNormal.val.floatVal[1] = ny;
1532 mNormal.val.floatVal[2] = nz;
1533
1534 if (!m_coreProfileEngine) {
1535 dispatcher().glNormal3f(nx, ny, nz);
1536 }
1537 }
1538
fogf(GLenum pname,GLfloat param)1539 void GLEScmContext::fogf(GLenum pname, GLfloat param) {
1540 switch (pname) {
1541 case GL_FOG_MODE: {
1542 GLenum mode = (GLenum)param;
1543 switch (mode) {
1544 case GL_EXP:
1545 case GL_EXP2:
1546 case GL_LINEAR:
1547 mFog.mode = mode;
1548 break;
1549 default:
1550 fprintf(stderr, "GL_INVALID_ENUM: Unknown GL_FOG_MODE 0x%x "
1551 "for glFog(f/x).\n", mode);
1552 setGLerror(GL_INVALID_ENUM);
1553 break;
1554 }
1555 break;
1556 }
1557 case GL_FOG_DENSITY:
1558 if (param < 0.0f) {
1559 fprintf(stderr, "GL_INVALID_VALUE: glFog(f/x): GL_FOG_DENSITY "
1560 "needs to be nonnegative, but got %f\n", param);
1561 setGLerror(GL_INVALID_VALUE);
1562 return;
1563 }
1564 mFog.density = param;
1565 break;
1566 case GL_FOG_START:
1567 mFog.start = param;
1568 break;
1569 case GL_FOG_END:
1570 mFog.end = param;
1571 break;
1572 case GL_FOG_COLOR:
1573 fprintf(stderr, "GL_INVALID_ENUM: GL_FOG_COLOR not allowed for glFog(f/x).\n");
1574 setGLerror(GL_INVALID_ENUM);
1575 break;
1576 default:
1577 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1578 "for glFog(f/x).\n", pname);
1579 setGLerror(GL_INVALID_ENUM);
1580 return;
1581 }
1582
1583 if (!m_coreProfileEngine) {
1584 dispatcher().glFogf(pname, param);
1585 }
1586 }
1587
fogfv(GLenum pname,const GLfloat * params)1588 void GLEScmContext::fogfv(GLenum pname, const GLfloat* params) {
1589 switch (pname) {
1590 case GL_FOG_MODE: {
1591 GLenum mode = (GLenum)params[0];
1592 switch (mode) {
1593 case GL_EXP:
1594 case GL_EXP2:
1595 case GL_LINEAR:
1596 mFog.mode = mode;
1597 break;
1598 default:
1599 fprintf(stderr, "GL_INVALID_ENUM: Unknown GL_FOG_MODE 0x%x "
1600 "for glFog(f/x)v.\n", mode);
1601 setGLerror(GL_INVALID_ENUM);
1602 break;
1603 }
1604 break;
1605 }
1606 case GL_FOG_DENSITY:
1607 if (params[0] < 0.0f) {
1608 fprintf(stderr, "GL_INVALID_VALUE: glFog(f/x)v: GL_FOG_DENSITY "
1609 "needs to be nonnegative, but got %f\n", params[0]);
1610 setGLerror(GL_INVALID_VALUE);
1611 return;
1612 }
1613 mFog.density = params[0];
1614 break;
1615 case GL_FOG_START:
1616 mFog.start = params[0];
1617 break;
1618 case GL_FOG_END:
1619 mFog.end = params[0];
1620 break;
1621 case GL_FOG_COLOR:
1622 memcpy(&mFog.color, params, 4 * sizeof(GLfloat));
1623 break;
1624 default:
1625 fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1626 "for glFog(f/x)v.\n", pname);
1627 setGLerror(GL_INVALID_ENUM);
1628 return;
1629 }
1630
1631 if (!m_coreProfileEngine) {
1632 dispatcher().glFogfv(pname, params);
1633 }
1634 }
1635
enableClientState(GLenum clientState)1636 void GLEScmContext::enableClientState(GLenum clientState) {
1637 if (m_coreProfileEngine) {
1638 core().enableClientState(clientState);
1639 } else {
1640 dispatcher().glEnableClientState(clientState);
1641 }
1642 }
1643
disableClientState(GLenum clientState)1644 void GLEScmContext::disableClientState(GLenum clientState) {
1645 if (m_coreProfileEngine) {
1646 core().disableClientState(clientState);
1647 } else {
1648 dispatcher().glDisableClientState(clientState);
1649 }
1650 }
1651
drawTexOES(float x,float y,float z,float width,float height)1652 void GLEScmContext::drawTexOES(float x, float y, float z, float width, float height) {
1653 if (m_coreProfileEngine) {
1654 core().drawTexOES(x, y, z, width, height);
1655 } else {
1656 auto& gl = dispatcher();
1657
1658 int numClipPlanes;
1659
1660 GLint viewport[4] = {};
1661 z = (z>1 ? 1 : (z<0 ? 0 : z));
1662
1663 float vertices[4*3] = {
1664 x , y, z,
1665 x , static_cast<float>(y+height), z,
1666 static_cast<float>(x+width), static_cast<float>(y+height), z,
1667 static_cast<float>(x+width), y, z
1668 };
1669 GLfloat texels[getMaxTexUnits()][4*2];
1670 memset((void*)texels, 0, getMaxTexUnits()*4*2*sizeof(GLfloat));
1671
1672 gl.glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
1673 gl.glPushAttrib(GL_TRANSFORM_BIT);
1674
1675 //setup projection matrix to draw in viewport aligned coordinates
1676 gl.glMatrixMode(GL_PROJECTION);
1677 gl.glPushMatrix();
1678 gl.glLoadIdentity();
1679 gl.glGetIntegerv(GL_VIEWPORT,viewport);
1680 gl.glOrtho(viewport[0],viewport[0] + viewport[2],viewport[1],viewport[1]+viewport[3],0,-1);
1681 //setup texture matrix
1682 gl.glMatrixMode(GL_TEXTURE);
1683 gl.glPushMatrix();
1684 gl.glLoadIdentity();
1685 //setup modelview matrix
1686 gl.glMatrixMode(GL_MODELVIEW);
1687 gl.glPushMatrix();
1688 gl.glLoadIdentity();
1689 //backup vbo's
1690 int array_buffer,element_array_buffer;
1691 gl.glGetIntegerv(GL_ARRAY_BUFFER_BINDING,&array_buffer);
1692 gl.glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,&element_array_buffer);
1693 gl.glBindBuffer(GL_ARRAY_BUFFER,0);
1694 gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
1695
1696 //disable clip planes
1697 gl.glGetIntegerv(GL_MAX_CLIP_PLANES,&numClipPlanes);
1698 for (int i=0;i<numClipPlanes;++i)
1699 gl.glDisable(GL_CLIP_PLANE0+i);
1700
1701 int nTexPtrs = 0;
1702 for (int i=0;i<getMaxTexUnits();++i) {
1703 if (isTextureUnitEnabled(GL_TEXTURE0+i)) {
1704 TextureData * texData = NULL;
1705 unsigned int texname = getBindedTexture(GL_TEXTURE0+i,GL_TEXTURE_2D);
1706 ObjectLocalName tex = getTextureLocalName(GL_TEXTURE_2D,texname);
1707 gl.glClientActiveTexture(GL_TEXTURE0+i);
1708 auto objData = shareGroup()->getObjectData(
1709 NamedObjectType::TEXTURE, tex);
1710 if (objData) {
1711 texData = (TextureData*)objData;
1712 //calculate texels
1713 texels[i][0] = (float)(texData->crop_rect[0])/(float)(texData->width);
1714 texels[i][1] = (float)(texData->crop_rect[1])/(float)(texData->height);
1715
1716 texels[i][2] = (float)(texData->crop_rect[0])/(float)(texData->width);
1717 texels[i][3] = (float)(texData->crop_rect[3]+texData->crop_rect[1])/(float)(texData->height);
1718
1719 texels[i][4] = (float)(texData->crop_rect[2]+texData->crop_rect[0])/(float)(texData->width);
1720 texels[i][5] = (float)(texData->crop_rect[3]+texData->crop_rect[1])/(float)(texData->height);
1721
1722 texels[i][6] = (float)(texData->crop_rect[2]+texData->crop_rect[0])/(float)(texData->width);
1723 texels[i][7] = (float)(texData->crop_rect[1])/(float)(texData->height);
1724
1725 gl.glTexCoordPointer(2,GL_FLOAT,0,texels[i]);
1726 nTexPtrs++;
1727 }
1728 }
1729 }
1730
1731 if (nTexPtrs>0) {
1732 //draw rectangle - only if we have some textures enabled & ready
1733 gl.glEnableClientState(GL_VERTEX_ARRAY);
1734 gl.glVertexPointer(3,GL_FLOAT,0,vertices);
1735 gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1736 gl.glDrawArrays(GL_TRIANGLE_FAN,0,4);
1737 }
1738
1739 //restore vbo's
1740 gl.glBindBuffer(GL_ARRAY_BUFFER,array_buffer);
1741 gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,element_array_buffer);
1742
1743 //restore matrix state
1744
1745 gl.glMatrixMode(GL_MODELVIEW);
1746 gl.glPopMatrix();
1747 gl.glMatrixMode(GL_TEXTURE);
1748 gl.glPopMatrix();
1749 gl.glMatrixMode(GL_PROJECTION);
1750 gl.glPopMatrix();
1751
1752 gl.glPopAttrib();
1753 gl.glPopClientAttrib();
1754 }
1755 }
1756
rotatef(float angle,float x,float y,float z)1757 void GLEScmContext::rotatef(float angle, float x, float y, float z) {
1758 glm::mat4 rot = glm::rotate(glm::mat4(), 3.14159265358979f / 180.0f * angle, glm::vec3(x, y, z));
1759 currMatrix() *= rot;
1760
1761 if (m_coreProfileEngine) {
1762 core().rotatef(angle, x, y, z);
1763 } else {
1764 dispatcher().glRotatef(angle, x, y, z);
1765 }
1766 }
1767
scalef(float x,float y,float z)1768 void GLEScmContext::scalef(float x, float y, float z) {
1769 glm::mat4 scale = glm::scale(glm::mat4(), glm::vec3(x, y, z));
1770 currMatrix() *= scale;
1771
1772 if (m_coreProfileEngine) {
1773 core().scalef(x, y, z);
1774 } else {
1775 dispatcher().glScalef(x, y, z);
1776 }
1777 }
1778
translatef(float x,float y,float z)1779 void GLEScmContext::translatef(float x, float y, float z) {
1780 glm::mat4 tr = glm::translate(glm::mat4(), glm::vec3(x, y, z));
1781 currMatrix() *= tr;
1782
1783 if (m_coreProfileEngine) {
1784 core().translatef(x, y, z);
1785 } else {
1786 dispatcher().glTranslatef(x, y, z);
1787 }
1788 }
1789
color4f(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)1790 void GLEScmContext::color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
1791
1792 mColor.type = GL_FLOAT;
1793 mColor.val.floatVal[0] = red;
1794 mColor.val.floatVal[1] = green;
1795 mColor.val.floatVal[2] = blue;
1796 mColor.val.floatVal[3] = alpha;
1797
1798 if (m_coreProfileEngine) {
1799 core().color4f(red,green,blue,alpha);
1800 } else{
1801 dispatcher().glColor4f(red,green,blue,alpha);
1802 }
1803 }
1804
color4ub(GLubyte red,GLubyte green,GLubyte blue,GLubyte alpha)1805 void GLEScmContext::color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
1806
1807 mColor.type = GL_UNSIGNED_BYTE;
1808 mColor.val.ubyteVal[0] = red;
1809 mColor.val.ubyteVal[1] = green;
1810 mColor.val.ubyteVal[2] = blue;
1811 mColor.val.ubyteVal[3] = alpha;
1812
1813 if (m_coreProfileEngine) {
1814 core().color4ub(red,green,blue,alpha);
1815 } else{
1816 dispatcher().glColor4ub(red,green,blue,alpha);
1817 }
1818 }
1819
drawArrays(GLenum mode,GLint first,GLsizei count)1820 void GLEScmContext::drawArrays(GLenum mode, GLint first, GLsizei count) {
1821 if (!isArrEnabled(GL_VERTEX_ARRAY)) return;
1822
1823 drawValidate();
1824
1825 GLuint prev_vbo;
1826 GLuint prev_ibo;
1827 dispatcher().glGetIntegerv(GL_ARRAY_BUFFER_BINDING,
1828 (GLint*)&prev_vbo);
1829 dispatcher().glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
1830 (GLint*)&prev_ibo);
1831 dispatcher().glBindBuffer(GL_ARRAY_BUFFER, 0);
1832 dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1833
1834 if (m_coreProfileEngine) {
1835 ArraysMap::iterator it;
1836 m_pointsIndex = -1;
1837
1838 // going over all clients arrays Pointers
1839 for (it = m_currVaoState.begin();
1840 it != m_currVaoState.end(); ++it) {
1841 GLenum array_id = (*it).first;
1842 GLESpointer* p = (*it).second;
1843 if (array_id == GL_VERTEX_ARRAY ||
1844 array_id == GL_NORMAL_ARRAY ||
1845 array_id == GL_COLOR_ARRAY ||
1846 array_id == GL_POINT_SIZE_ARRAY_OES ||
1847 array_id == GL_TEXTURE_COORD_ARRAY) {
1848 core().setupArrayForDraw(array_id, p, first, count, false, 0, nullptr);
1849 }
1850 }
1851
1852 GLenum activeTexture = m_clientActiveTexture + GL_TEXTURE0;
1853 setClientActiveTexture(activeTexture);
1854 core().clientActiveTexture(activeTexture);
1855 core().drawArrays(mode, first, count);
1856 } else {
1857 GLESConversionArrays tmpArrs;
1858
1859 setupArraysPointers(tmpArrs,first,count,0,NULL,true,nullptr);
1860
1861 if (mode == GL_POINTS && isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){
1862 drawPointsArrs(tmpArrs,first,count);
1863 } else {
1864 dispatcher().glDrawArrays(mode,first,count);
1865 }
1866 }
1867 dispatcher().glBindBuffer(GL_ARRAY_BUFFER, prev_vbo);
1868 dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_ibo);
1869 }
1870
drawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1871 void GLEScmContext::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
1872 if (!isArrEnabled(GL_VERTEX_ARRAY)) return;
1873
1874 drawValidate();
1875
1876 if(isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
1877 const unsigned char* buf = static_cast<unsigned char *>(getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));
1878 indices = buf + SafeUIntFromPointer(indices);
1879 }
1880
1881 GLuint prev_vbo;
1882 GLuint prev_ibo;
1883 dispatcher().glGetIntegerv(GL_ARRAY_BUFFER_BINDING,
1884 (GLint*)&prev_vbo);
1885 dispatcher().glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
1886 (GLint*)&prev_ibo);
1887 dispatcher().glBindBuffer(GL_ARRAY_BUFFER, 0);
1888 dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1889
1890 if (m_coreProfileEngine) {
1891 ArraysMap::iterator it;
1892 m_pointsIndex = -1;
1893
1894 // going over all clients arrays Pointers
1895 for (it = m_currVaoState.begin();
1896 it != m_currVaoState.end(); ++it) {
1897 GLenum array_id = (*it).first;
1898 GLESpointer* p = (*it).second;
1899 if (array_id == GL_VERTEX_ARRAY ||
1900 array_id == GL_NORMAL_ARRAY ||
1901 array_id == GL_COLOR_ARRAY ||
1902 array_id == GL_POINT_SIZE_ARRAY_OES ||
1903 array_id == GL_TEXTURE_COORD_ARRAY) {
1904 core().setupArrayForDraw(array_id, p, 0, count, true, type, indices);
1905 }
1906 }
1907
1908 GLenum activeTexture = m_clientActiveTexture + GL_TEXTURE0;
1909 setClientActiveTexture(activeTexture);
1910 core().clientActiveTexture(activeTexture);
1911 core().drawElements(mode, count, type, indices);
1912 } else {
1913 GLESConversionArrays tmpArrs;
1914
1915 setupArraysPointers(tmpArrs,0,count,type,indices,false,nullptr);
1916 if(mode == GL_POINTS && isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){
1917 drawPointsElems(tmpArrs,count,type,indices);
1918 }
1919 else{
1920 dispatcher().glDrawElements(mode,count,type,indices);
1921 }
1922 }
1923 dispatcher().glBindBuffer(GL_ARRAY_BUFFER, prev_vbo);
1924 dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_ibo);
1925 }
1926
clientActiveTexture(GLenum texture)1927 void GLEScmContext::clientActiveTexture(GLenum texture) {
1928 setClientActiveTexture(texture);
1929 if (m_coreProfileEngine) {
1930 core().clientActiveTexture(texture);
1931 } else {
1932 dispatcher().glClientActiveTexture(texture);
1933 }
1934 }
1935