hostsupport/hostopengles20/src/GLES2/vertex.c
branchbug235_bringup_0
changeset 53 c2ef9095503a
parent 20 d2d6724aef32
equal deleted inserted replaced
52:39e5f73667ba 53:c2ef9095503a
       
     1 /* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2  *
       
     3  * Permission is hereby granted, free of charge, to any person obtaining a
       
     4  * copy of this software and associated documentation files (the "Software"),
       
     5  * to deal in the Software without restriction, including without limitation
       
     6  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       
     7  * and/or sell copies of the Software, and to permit persons to whom the
       
     8  * Software is furnished to do so, subject to the following conditions:
       
     9  *
       
    10  * The above copyright notice and this permission notice shall be included
       
    11  * in all copies or substantial portions of the Software.
       
    12  *
       
    13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
       
    14  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
       
    16  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
       
    17  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
       
    18  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
       
    19  *
       
    20  * Initial Contributors:
       
    21  * Nokia Corporation - initial contribution.
       
    22  *
       
    23  * Contributors:
       
    24  *
       
    25  * Description:
       
    26  *
       
    27  */
       
    28 
       
    29 #include "common.h"
       
    30 #include "hgl.h"
       
    31 #include "context.h"
       
    32 #include "vertex.h"
       
    33 #include "get.h"
       
    34 #include "half.h"
       
    35 
       
    36 #define DEBUG_VERTEX 0
       
    37 
       
    38 GLboolean dglGetVertexAttrib(const DGLContext *ctx, GLuint index, GLenum pname, DGLType type, void* params)
       
    39 {
       
    40 	GLint i;
       
    41 
       
    42 	switch(pname)
       
    43 	{
       
    44 		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
       
    45 			i = ctx->vertex_arrays[index].enabled;
       
    46 			break;
       
    47 
       
    48 		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
       
    49 			i = ctx->vertex_arrays[index].size;
       
    50 			break;
       
    51 
       
    52 		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
       
    53 			i = ctx->vertex_arrays[index].stride;
       
    54 			break;
       
    55 
       
    56 		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
       
    57 			i = ctx->vertex_arrays[index].type;
       
    58 			break;
       
    59 
       
    60 		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
       
    61 			i = ctx->vertex_arrays[index].normalized;
       
    62 			break;
       
    63 
       
    64 		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
       
    65 			i = ctx->vertex_arrays[index].buffer != NULL ? ctx->vertex_arrays[index].buffer->obj.name : 0;
       
    66 			break;
       
    67 
       
    68 		case GL_CURRENT_VERTEX_ATTRIB:
       
    69 			if(index == 0)
       
    70 			{
       
    71 				// Attribute zero can't be set in desktop GL.
       
    72 				if(type == DGLES2_TYPE_INT)
       
    73 				{
       
    74 					((GLint*)params)[0] = (GLint)ctx->attrib_zero[0];
       
    75 					((GLint*)params)[1] = (GLint)ctx->attrib_zero[1];
       
    76 					((GLint*)params)[2] = (GLint)ctx->attrib_zero[2];
       
    77 					((GLint*)params)[3] = (GLint)ctx->attrib_zero[3];
       
    78 				}
       
    79 				else
       
    80 				{
       
    81 					DGLES2_ASSERT(type == DGLES2_TYPE_FLOAT);
       
    82 					((GLfloat*)params)[0] = ctx->attrib_zero[0];
       
    83 					((GLfloat*)params)[1] = ctx->attrib_zero[1];
       
    84 					((GLfloat*)params)[2] = ctx->attrib_zero[2];
       
    85 					((GLfloat*)params)[3] = ctx->attrib_zero[3];
       
    86 				}
       
    87 			}
       
    88 			else
       
    89 			{
       
    90 				if(type == DGLES2_TYPE_INT)
       
    91 				{
       
    92 					ctx->hgl.GetVertexAttribiv(index, GL_CURRENT_VERTEX_ATTRIB, params);
       
    93 				}
       
    94 				else
       
    95 				{
       
    96 					DGLES2_ASSERT(type == DGLES2_TYPE_FLOAT);
       
    97 					ctx->hgl.GetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, params);
       
    98 				}
       
    99 			}
       
   100 			return GL_TRUE;
       
   101 
       
   102 		default:
       
   103 			return GL_FALSE;
       
   104 	}
       
   105 
       
   106 	if(type == DGLES2_TYPE_INT)
       
   107 	{
       
   108 		*(GLint*)params = i;
       
   109 	}
       
   110 	else
       
   111 	{
       
   112 		DGLES2_ASSERT(type == DGLES2_TYPE_FLOAT);
       
   113 		*(GLfloat*)params = (GLfloat)i;
       
   114 	}
       
   115 
       
   116 	return GL_TRUE;
       
   117 }
       
   118 
       
   119 GL_APICALL_BUILD void GL_APIENTRY glDisableVertexAttribArray(GLuint index)
       
   120 {
       
   121 	DGLES2_ENTER();
       
   122 	DGLES2_ERROR_IF(index >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   123 #	if(DEBUG_VERTEX == 1)
       
   124 	Dprintf("Disabling array %d\n", index);
       
   125 #	endif
       
   126 	ctx->vertex_arrays[index].enabled = GL_FALSE;
       
   127 	ctx->hgl.DisableVertexAttribArray(index);
       
   128 	DGLES2_LEAVE();
       
   129 }
       
   130 
       
   131 // Function to convert fixed and half float arrays to float arrays.
       
   132 static void dglConvertArrays(DGLContext* ctx, GLint first, GLsizei count)
       
   133 {
       
   134 	unsigned int i;
       
   135 	for(i = 0; i < ctx->max_vertex_attribs; ++i)
       
   136 	{
       
   137 		DGLVertexArray* va = ctx->vertex_arrays + i;
       
   138 		if(!va->enabled)
       
   139 		{
       
   140 			continue;
       
   141 		}
       
   142 		{
       
   143 			if(va->type == GL_FIXED || va->type == GL_HALF_FLOAT_OES)
       
   144 			{
       
   145 				const void* ptr = va->buffer != NULL ? va->buffer->data : va->ptr;
       
   146 
       
   147 				GLsizei stride;
       
   148 				if(va->stride)
       
   149 				{
       
   150 					stride = va->stride;
       
   151 				}
       
   152 				else if(va->type == GL_FIXED)
       
   153 				{
       
   154 					stride = va->size * sizeof(GLfixed);
       
   155 				}
       
   156 				else
       
   157 				{
       
   158 					DGLES2_ASSERT(va->type == GL_HALF_FLOAT_OES);
       
   159 					stride = va->size * sizeof(khronos_int16_t);
       
   160 				}
       
   161 
       
   162 	#			if(DEBUG_VERTEX == 1)
       
   163 				Dprintf("Converting %d fixed/half float indices to float.\n", count);
       
   164 	#			endif
       
   165 
       
   166 				if(va->floatptr) free(va->floatptr);
       
   167 
       
   168 				va->floatptr = malloc(sizeof(GLfloat)*count*va->size);
       
   169 				{
       
   170 					GLsizei j;
       
   171 					for(j = 0; j < count; ++j)
       
   172 					{
       
   173 						signed k;
       
   174 						for(k = 0; k < va->size; ++k)
       
   175 						{
       
   176 							if(va->type == GL_FIXED)
       
   177 							{
       
   178 								va->floatptr[j*va->size + k] = ((GLfixed*)(((char*)ptr) + stride*(first + j)))[k] / 65536.0f;
       
   179 							}
       
   180 							else
       
   181 							{
       
   182 								khronos_int16_t half;
       
   183 								DGLES2_ASSERT(va->type == GL_HALF_FLOAT_OES);
       
   184 								half = ((khronos_int16_t*)(((char*)ptr) + stride*(first + j)))[k];
       
   185 								va->floatptr[j*va->size + k] = dglConvertHalfToFloat(half);
       
   186 							}
       
   187 						}
       
   188 					}
       
   189 				}
       
   190 				ctx->hgl.VertexAttribPointer(i, va->size, GL_FLOAT, va->normalized, 0, va->floatptr - first);
       
   191 			}
       
   192 		}
       
   193 	}
       
   194 }
       
   195 
       
   196 GL_APICALL_BUILD void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
       
   197 {
       
   198 	DGLES2_ENTER();
       
   199 	DGLES2_ERROR_IF(first < 0, GL_INVALID_VALUE);
       
   200 	DGLES2_ERROR_IF(count < 0, GL_INVALID_VALUE);
       
   201 	dglConvertArrays(ctx, first, count);
       
   202 	DGLES2_BEGIN_DRAWING();
       
   203 	ctx->hgl.DrawArrays(mode, first, count);
       
   204 	DGLES2_END_DRAWING();
       
   205 	DGLES2_LEAVE();
       
   206 }
       
   207 
       
   208 GL_APICALL_BUILD void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
       
   209 {
       
   210 	DGLES2_ENTER();
       
   211 	DGLES2_ERROR_IF(count < 0, GL_INVALID_VALUE);
       
   212 	{
       
   213 		GLsizei indice_size;
       
   214 		switch(type)
       
   215 		{
       
   216 			case GL_UNSIGNED_BYTE: indice_size = sizeof(GLubyte); break;
       
   217 			case GL_UNSIGNED_SHORT: indice_size = sizeof(GLushort); break;
       
   218 			default:
       
   219 			{
       
   220 				DGLES2_ERROR(GL_INVALID_ENUM);
       
   221 			}
       
   222 		}
       
   223 		dglConvertArrays(ctx, (GLint)((size_t)indices/indice_size), count);
       
   224 		DGLES2_BEGIN_DRAWING();
       
   225 		ctx->hgl.DrawElements(mode, count, type, indices);
       
   226 		DGLES2_END_DRAWING();
       
   227 	}
       
   228 	DGLES2_LEAVE();
       
   229 }
       
   230 
       
   231 GL_APICALL_BUILD void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
       
   232 {
       
   233 	DGLES2_ENTER();
       
   234 	DGLES2_ERROR_IF(index >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   235 #	if(DEBUG_VERTEX == 1)
       
   236 	Dprintf("Enabling array %d\n", index);
       
   237 #	endif
       
   238 	ctx->vertex_arrays[index].enabled = GL_TRUE;
       
   239 	ctx->hgl.EnableVertexAttribArray(index);
       
   240 	DGLES2_LEAVE();
       
   241 }
       
   242 
       
   243 GL_APICALL_BUILD void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
       
   244 {
       
   245 	DGLES2_ENTER();
       
   246 	DGLES2_ERROR_IF(index >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   247 	if(!dglGetVertexAttrib(ctx, index, pname, DGLES2_TYPE_FLOAT, params))
       
   248 	{
       
   249 		DGLES2_ERROR(GL_INVALID_ENUM);
       
   250 	}
       
   251 	DGLES2_LEAVE();
       
   252 }
       
   253 
       
   254 GL_APICALL_BUILD void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
       
   255 {
       
   256 	DGLES2_ENTER();
       
   257 	DGLES2_ERROR_IF(index >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   258 	if(!dglGetVertexAttrib(ctx, index, pname, DGLES2_TYPE_INT, params))
       
   259 	{
       
   260 		DGLES2_ERROR(GL_INVALID_ENUM);
       
   261 	}
       
   262 	DGLES2_LEAVE();
       
   263 }
       
   264 
       
   265 GL_APICALL_BUILD void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
       
   266 {
       
   267 	DGLES2_ENTER();
       
   268 	DGLES2_ERROR_IF(index >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   269 	DGLES2_ERROR_IF(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER, GL_INVALID_ENUM);
       
   270 	*pointer = (void*)ctx->vertex_arrays[index].ptr;
       
   271 	DGLES2_LEAVE();
       
   272 }
       
   273 
       
   274 GL_APICALL_BUILD void GL_APIENTRY glVertexAttrib1f(GLuint indx, GLfloat x)
       
   275 {
       
   276 	DGLES2_ENTER();
       
   277 	DGLES2_ERROR_IF(indx >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   278 	if(indx == 0)
       
   279 	{
       
   280 		// Attribute zero can't be set in desktop GL.
       
   281 		ctx->attrib_zero[0] = x;
       
   282 	}
       
   283 	else
       
   284 	{
       
   285 		ctx->hgl.VertexAttrib1f(indx, x);
       
   286 	}
       
   287 	DGLES2_LEAVE();
       
   288 }
       
   289 
       
   290 GL_APICALL_BUILD void GL_APIENTRY glVertexAttrib1fv(GLuint indx, const GLfloat* values)
       
   291 {
       
   292 	DGLES2_ENTER();
       
   293 	DGLES2_ERROR_IF(indx >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   294 	if(indx == 0)
       
   295 	{
       
   296 		// Attribute zero can't be set in desktop GL.
       
   297 		ctx->attrib_zero[0] = values[0];
       
   298 	}
       
   299 	else
       
   300 	{
       
   301 		ctx->hgl.VertexAttrib1fv(indx, values);
       
   302 	}
       
   303 	DGLES2_LEAVE();
       
   304 }
       
   305 
       
   306 GL_APICALL_BUILD void GL_APIENTRY glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
       
   307 {
       
   308 	DGLES2_ENTER();
       
   309 	DGLES2_ERROR_IF(indx >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   310 	if(indx == 0)
       
   311 	{
       
   312 		// Attribute zero can't be set in desktop GL.
       
   313 		ctx->attrib_zero[0] = x;
       
   314 		ctx->attrib_zero[1] = y;
       
   315 	}
       
   316 	else
       
   317 	{
       
   318 		ctx->hgl.VertexAttrib2f(indx, x, y);
       
   319 	}
       
   320 	DGLES2_LEAVE();
       
   321 }
       
   322 
       
   323 GL_APICALL_BUILD void GL_APIENTRY glVertexAttrib2fv(GLuint indx, const GLfloat* values)
       
   324 {
       
   325 	DGLES2_ENTER();
       
   326 	DGLES2_ERROR_IF(indx >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   327 	if(indx == 0)
       
   328 	{
       
   329 		// Attribute zero can't be set in desktop GL.
       
   330 		ctx->attrib_zero[0] = values[0];
       
   331 	}
       
   332 	else
       
   333 	{
       
   334 		ctx->hgl.VertexAttrib2fv(indx, values);
       
   335 	}
       
   336 	DGLES2_LEAVE();
       
   337 }
       
   338 
       
   339 GL_APICALL_BUILD void GL_APIENTRY glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
       
   340 {
       
   341 	DGLES2_ENTER();
       
   342 	DGLES2_ERROR_IF(indx >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   343 	if(indx == 0)
       
   344 	{
       
   345 		// Attribute zero can't be set in desktop GL.
       
   346 		ctx->attrib_zero[0] = x;
       
   347 		ctx->attrib_zero[1] = y;
       
   348 		ctx->attrib_zero[2] = z;
       
   349 	}
       
   350 	else
       
   351 	{
       
   352 		ctx->hgl.VertexAttrib3f(indx, x, y, z);
       
   353 	}
       
   354 	DGLES2_LEAVE();
       
   355 }
       
   356 
       
   357 GL_APICALL_BUILD void GL_APIENTRY glVertexAttrib3fv(GLuint indx, const GLfloat* values)
       
   358 {
       
   359 	DGLES2_ENTER();
       
   360 	DGLES2_ERROR_IF(indx >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   361 	if(indx == 0)
       
   362 	{
       
   363 		// Attribute zero can't be set in desktop GL.
       
   364 		ctx->attrib_zero[0] = values[0];
       
   365 		ctx->attrib_zero[1] = values[1];
       
   366 		ctx->attrib_zero[2] = values[2];
       
   367 	}
       
   368 	else
       
   369 	{
       
   370 		ctx->hgl.VertexAttrib3fv(indx, values);
       
   371 	}
       
   372 	DGLES2_LEAVE();
       
   373 }
       
   374 
       
   375 GL_APICALL_BUILD void GL_APIENTRY glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
       
   376 {
       
   377 	DGLES2_ENTER();
       
   378 	DGLES2_ERROR_IF(indx >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   379 	if(indx == 0)
       
   380 	{
       
   381 		// Attribute zero can't be set in desktop GL.
       
   382 		ctx->attrib_zero[0] = x;
       
   383 		ctx->attrib_zero[1] = y;
       
   384 		ctx->attrib_zero[2] = z;
       
   385 		ctx->attrib_zero[3] = w;
       
   386 	}
       
   387 	else
       
   388 	{
       
   389 		ctx->hgl.VertexAttrib4f(indx, x, y, z, w);
       
   390 	}
       
   391 	DGLES2_LEAVE();
       
   392 }
       
   393 
       
   394 GL_APICALL_BUILD void GL_APIENTRY glVertexAttrib4fv(GLuint indx, const GLfloat* values)
       
   395 {
       
   396 	DGLES2_ENTER();
       
   397 	DGLES2_ERROR_IF(indx >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   398 	if(indx == 0)
       
   399 	{
       
   400 		// Attribute zero can't be set in desktop GL.
       
   401 		ctx->attrib_zero[0] = values[0];
       
   402 		ctx->attrib_zero[1] = values[1];
       
   403 		ctx->attrib_zero[2] = values[2];
       
   404 		ctx->attrib_zero[3] = values[3];
       
   405 	}
       
   406 	else
       
   407 	{
       
   408 		ctx->hgl.VertexAttrib4fv(indx, values);
       
   409 	}
       
   410 	DGLES2_LEAVE();
       
   411 }
       
   412 
       
   413 GL_APICALL_BUILD void GL_APIENTRY glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
       
   414 {
       
   415 	DGLES2_ENTER();
       
   416 	DGLES2_ERROR_IF(indx >= ctx->max_vertex_attribs, GL_INVALID_VALUE);
       
   417 	DGLES2_ERROR_IF(size < 1 || size > 4, GL_INVALID_VALUE);
       
   418 	DGLES2_ERROR_IF(type != GL_BYTE &&
       
   419 					type != GL_UNSIGNED_BYTE &&
       
   420 					type != GL_SHORT &&
       
   421 					type != GL_UNSIGNED_SHORT &&
       
   422 					type != GL_FIXED &&
       
   423 					type != GL_FLOAT &&
       
   424 					type != GL_HALF_FLOAT_OES, 
       
   425 					GL_INVALID_ENUM);
       
   426 	DGLES2_ERROR_IF(stride < 0, GL_INVALID_VALUE);
       
   427 #	if(DEBUG_VERTEX == 1)
       
   428 	Dprintf("Array %d at %p (%d elements every %d bytes)\n", indx, ptr, size, stride);
       
   429 #	endif
       
   430 
       
   431 	{
       
   432 		DGLVertexArray* va = ctx->vertex_arrays + indx;
       
   433 
       
   434 		if(type != GL_FIXED && type != GL_HALF_FLOAT_OES)
       
   435 		{
       
   436 			ctx->hgl.VertexAttribPointer(indx, size, type, normalized, stride, ptr);
       
   437 		}
       
   438 
       
   439 		if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
   440 		{
       
   441 			va->size = size;
       
   442 			va->type = type;
       
   443 			va->normalized = normalized;
       
   444 			va->stride = stride;
       
   445 			va->ptr = ptr;
       
   446 			
       
   447 			va->buffer = DGLContext_findBuffer(ctx, ctx->buffer_binding);
       
   448 		}
       
   449 	}
       
   450 	DGLES2_LEAVE();
       
   451 }
       
   452