示例#1
0
void SceneManager::Update(ESContext *esContext)
{
	//UserData *userData = (UserData*) esContext->userData;
	float    aspect;

	// Compute the window aspect ratio
	aspect = (GLfloat) esContext->width / (GLfloat) esContext->height;
	
	// Generate a perspective matrix with a 60 degree FOV
	esMatrixLoadIdentity( &perspectiveMatrix );
	
	esPerspective( &perspectiveMatrix, 60.0f, aspect, 0.5f, 50.0f );

	// Generate a model view matrix to rotate/translate the objects
	for(int i=0;i<(int)objects.size();i++)
	{
		esMatrixLoadIdentity( &objects[i]->mvMatrix );
		
		objects[i]->update();
		esTranslate(&objects[i]->mvMatrix, vecCameraPos[0],vecCameraPos[1],vecCameraPos[2]);
		esRotate(&objects[i]->mvMatrix, angle, 0.0f,1.0f,0.0f);

		// Compute the final MVP by multiplying the 
		// modelview and perspective matrices together
		esMatrixMultiply( &objects[i]->mvpMatrix, &objects[i]->mvMatrix, &perspectiveMatrix );
	}
}
///
// Update MVP matrix based on time
//
void Update ( ESContext *esContext, float deltaTime )
{
   UserData *userData = (UserData*) esContext->userData;
   ESMatrix perspective;
   ESMatrix modelview;
   float    aspect;
   
   // Compute a rotation angle based on time to rotate the cube
   userData->angle += ( deltaTime * 40.0f );
   if( userData->angle >= 360.0f )
      userData->angle -= 360.0f;

   // Compute the window aspect ratio
   aspect = (GLfloat) esContext->width / (GLfloat) esContext->height;
   
   // Generate a perspective matrix with a 60 degree FOV
   esMatrixLoadIdentity( &perspective );
   esPerspective( &perspective, 60.0f, aspect, 1.0f, 20.0f );

   // Generate a model view matrix to rotate/translate the cube
   esMatrixLoadIdentity( &modelview );

   // Translate away from the viewer
   esTranslate( &modelview, 0.0, 0.0, -2.0 );

   // Rotate the cube
   esRotate( &modelview, userData->angle, 1.0, 0.0, 1.0 );
   
   // Compute the final MVP by multiplying the 
   // modevleiw and perspective matrices together
   esMatrixMultiply( &userData->mvpMatrix, &modelview, &perspective );
}
示例#3
0
///
// Update a triangle using the shader pair created in Init()
//
static void Update ( ESContext *esContext, float deltaTime)
{

    UserData *userData = (UserData*) esContext->userData;
    ESMatrix perspective;
    ESMatrix modelview;

    float    aspect;

    // Compute a rotation angle based on time to rotate the cube
    userData->angle += 1;//( deltaTime * 40.0f );
    if( userData->angle >= 360.0f )
       userData->angle -= 360.0f;


    // Compute the window aspect ratio
    aspect = 1;//(GLfloat) esContext->width / (GLfloat) esContext->height;

    // Generate a perspective matrix with a 60 degree FOV
    esMatrixLoadIdentity( &perspective );
    esPerspective( &perspective, 50.0f, aspect, 1.0f, 20.0f );



    // Generate a model view matrix to rotate/translate the cube
    esMatrixLoadIdentity( &modelview );

    // Translate away from the viewer
    esTranslate( &modelview, 0.0, 0.0, -2.0 );

    esScale( &modelview,.2,.2,.2);
    // Rotate the cube
    esRotate( &modelview, userData->angle, .0, 1.0, .0 );

    // Compute the final MVP by multiplying the modevleiw and perspective matrices together
    esMatrixMultiply( &userData->mvpMatrix, &modelview, &perspective );

#if 1
    userData->normalMatrix = processNormalMatrix(modelview);


#else
    // Normal Matrix
    // Transform normals from object-space to eye-space
    bool invertible;
    GLKMatrix3 normalMatrix = GLKMatrix4GetMatrix3(GLKMatrix4InvertAndTranspose(modelViewMatrix, &invertible));
    if(!invertible)
        NSLog(@"MV matrix is not invertible");
    glUniformMatrix3fv(self.phongShader.uNormalMatrix, 1, 0, normalMatrix.m);
#endif

}
示例#4
0
文件: Camera.cpp 项目: iliescu6/GLT
void cCamera::Update(float deltaTime)
{
	UpdateInput(deltaTime);
	esMatrixLoadIdentity( & Camera );
	if(m_enabled)
	{
		cVector2di mousePos=INPUT->getMousePos();
		float rotatex=(float)(mousePos.x-m_prevMouseX);
		float rotatey=(float)(mousePos.y-m_prevMouseY);
		m_currentRot.x+=rotatex;
		m_currentRot.z+=rotatey;
		m_prevMouseX=mousePos.x;
		m_prevMouseY=mousePos.y;
	}


	esTranslate(&Camera,m_currentPos.x,m_currentPos.y,m_currentPos.z);
	esRotate(&Camera,m_currentRot.x,0,1,0);
	esRotate(&Camera,m_currentRot.z,1,0,0);
	
	InverseMatrix(Camera,View);
}
示例#5
0
void        SetSphereMVP(GLContext    *_context)
{
	UserData    *_user = (UserData*)_context->userObject;
	ESMatrix    identity;
////////////////////////球////////////////
	esMatrixLoadIdentity(&_user->lightSphereMatrix);
	esTranslate(&_user->lightSphereMatrix, 2.0f, 0.0f, 0.0f);
	esRotate(&_user->lightSphereMatrix, _user->angleArc, 0.0f, 1.0f, 0.0f);
	esTranslate(&_user->lightSphereMatrix, 0.0f, 0.0f, -4.0f);
	esMatrixMultiply(&_user->lightSphereMatrix, &_user->lightSphereMatrix, &_user->viewMatrix);
//获取法线矩阵
	esMatrixNormal(&_user->normalSphereMatrix, &_user->lightSphereMatrix);
	esMatrixMultiply(&_user->lightSphereMatrix, &_user->lightSphereMatrix, &_user->projMatrix);
	////////////////眼睛的的视野//////////////////
	esMatrixLoadIdentity(&_user->eyeSphereMatrix);
	esTranslate(&_user->eyeSphereMatrix, 2.0f, 0.0f, 0.0f);
	esRotate(&_user->eyeSphereMatrix, _user->angleArc, 0.0f, 1.0f, 0.0f);
	esTranslate(&_user->eyeSphereMatrix, 0.0f, 0.0f, -4.0f);

	esMatrixMultiply(&_user->eyeSphereMatrix, &_user->eyeSphereMatrix, &_user->eyeViewMatrix);
	esMatrixMultiply(&_user->eyeSphereMatrix, &_user->eyeSphereMatrix, &_user->projMatrix);
//球
}
示例#6
0
//固定不变的矩阵
void        SetFixedMatrix(GLContext *_context)
{
	UserData    *_user = (UserData*)_context->userObject;
	Size   _size = _context->getWinSize();
	esPerspective(&_user->projMatrix, 50.0f, _size.width / _size.height, 1.0f, 100.0f);
	//	esOrtho(&_user->projMatrix, -4.0f, 4.0f, -4.0f, 4.0f, 0.0f, 8.0f);
	//光源的视野
	//	esMatrixLookAt(&_user->viewMatrix, &GLVector3(4.0f, 2.5f, -4.0f), &GLVector3(0.0f, 0.0f, -4.0f), &GLVector3(0.0f, 1.0f, 0.0f));
	esMatrixLookAt(&_user->viewMatrix, &GLVector3(2.3f, 2.5f, -4.0f), &GLVector3(2.0f, 0.0f, -4.0f), &GLVector3(0.0f, 1.0f, 0.0f));
	//光线的方向
	ESMatrix3      trunkMatrix;
	esMatrixTrunk(&trunkMatrix, &_user->viewMatrix);
	_user->lightVector = esMatrixMultiplyVector3(&GLVector3(2.3f - 2.0f, 2.5f - 0.0f, -4.0f + 4.0f), &trunkMatrix);// normalize(&GLVector3(2.3f - 2.0f, 2.5f - 0.0f, -4.0f + 4.0f));
	_user->lightVector = normalize(&_user->lightVector);
	ESMatrix    identity;
	///////////////////地面//////////////////
	//旋转
	esRotate(&_user->lightGroundMatrix, -90.0f, 1.0f, 0.0f, 0.0f);
	//平移
	esTranslate(&_user->lightGroundMatrix, 0.0f, -1.0f, -4.0f);
	//视图矩阵
	esMatrixMultiply(&_user->lightGroundMatrix, &_user->lightGroundMatrix, &_user->viewMatrix);
	//获取法线矩阵
	esMatrixTrunk(&_user->normalGroundMatrix, &_user->lightGroundMatrix);
	GLVector3    rotatevector = esMatrixMultiplyVector3(&GLVector3(0.0f, 0.0f, 1.0f), &_user->normalGroundMatrix);
	esMatrixMultiply(&_user->lightGroundMatrix, &_user->lightGroundMatrix, &_user->projMatrix);
////////////////////
	//旋转
	esRotate(&_user->eyeGroundMatrix, -90.0f, 1.0f, 0.0f, 0.0f);
	//平移
	esTranslate(&_user->eyeGroundMatrix, 0.0f, -1.0f, -4.0f);
	//视图矩阵
	esMatrixLookAt(&_user->eyeViewMatrix, &GLVector3(0.0f, 1.0f, 0.0f), &GLVector3(0.0f, 0.0f, -8.0f), &GLVector3(0.0f, 1.0f, 0.0f));
	esMatrixMultiply(&_user->eyeGroundMatrix, &_user->eyeGroundMatrix, &_user->eyeViewMatrix);
	//MVP矩阵
	esMatrixMultiply(&_user->eyeGroundMatrix, &_user->eyeGroundMatrix, &_user->projMatrix);
}
示例#7
0
//+-----------------------------------------------------------------------------
//| Renders the geoset
//+-----------------------------------------------------------------------------
VOID MODEL_GEOSET::Render(CONST SEQUENCE_TIME& time, BOOL Animated)
{
	BuildMesh();
	glUseProgram(Graphics.Program());

	ESMatrix modelviewMatrix;
	ESMatrix perspectiveMatrix;
	ESMatrix mvpMatrix;

	int aspect;

	aspect = (GLfloat) 600 / (GLfloat) 800;
	esMatrixLoadIdentity(&perspectiveMatrix);
	esPerspective(&perspectiveMatrix, 60.0f, aspect, 1.0f, 20.0f);

	esMatrixLoadIdentity(&modelviewMatrix);
	esScale(&modelviewMatrix, 1.0f, 1.0f, 1.0f);
	esTranslate(&modelviewMatrix, 0.0f, 0.0f, 0.0f);

	static float angle = 0.0f;
	esRotate(&modelviewMatrix,angle, 1.0f, 0.0f, 0.0f);
	angle += 0.2f;

	esMatrixLoadIdentity(&mvpMatrix);
	esMatrixMultiply(&mvpMatrix, &modelviewMatrix, &perspectiveMatrix);
	glUniformMatrix4fv(Graphics.WVPMatrix(), 1, GL_FALSE, (GLfloat*) mvpMatrix.m);

	glEnable(GL_TEXTURE_2D);
	glEnable(GL_TEXTURE0);

	glActiveTexture(GL_TEXTURE0);
	glEnableVertexAttribArray(Graphics.Position());
	glEnableVertexAttribArray(Graphics.TexturePosition());
	
	glUniform1i(Graphics.Texture(), 0);

	glVertexAttribPointer(Graphics.Position(), 3, GL_FLOAT, GL_FALSE, sizeof(FLOAT) * 3, vertices);
	glVertexAttribPointer(Graphics.TexturePosition(), 2, GL_FLOAT, GL_FALSE, 2 * sizeof(FLOAT), TexturePositions);
	glDrawElements(GL_TRIANGLES, GeosetData.FaceContainer.GetTotalSize() * 3, GL_UNSIGNED_INT, indices);
	
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_TEXTURE0);
	glDisableVertexAttribArray(Graphics.TexturePosition());
	glDisableVertexAttribArray(Graphics.Texture());
}
示例#8
0
文件: cat.c 项目: 12019/freedreno
int main(int argc, char **argv)
{
	struct fd_state *state;
	struct fd_surface *surface, *lolstex1, *lolstex2;
	struct fd_program *cat_program, *tex_program;
	struct fd_bo *position_vbo, *normal_vbo;
	const char *cat_vertex_shader_asm =
		"@varying(R0)     vertex_normal                                                      \n"
		"@varying(R1)     vertex_position                                                    \n"
		"@attribute(R1)   normal                                                             \n"
		"@attribute(R2)   position                                                           \n"
		"@uniform(C0-C3)  ModelViewMatrix                                                    \n"
		"@uniform(C4-C7)  ModelViewProjectionMatrix                                          \n"
		"@uniform(C8-C10) NormalMatrix                                                       \n"
		"@const(C11)      1.000000, 0.000000, 0.000000, 0.000000                             \n"
		"EXEC                                                                                \n"
		"      FETCH:    VERTEX  R1.xyz_ = R0.x FMT_32_32_32_FLOAT SIGNED STRIDE(12) CONST(20, 0)\n"
		"      FETCH:    VERTEX  R2.xyz_ = R0.x FMT_32_32_32_FLOAT SIGNED STRIDE(12) CONST(20, 1)\n"
		"   (S)ALU:      MULADDv R0 = C7, R2.zzzz, C6                                        \n"
		"      ALU:      MULADDv R0 = R0, R2.yyyy, C5                                        \n"
		"ALLOC POSITION SIZE(0x0)                                                            \n"
		"EXEC                                                                                \n"
		"      ALU:      MULADDv export62 = R0, R2.xxxx, C4      ; gl_Position               \n"
		"      ALU:      MULv    R0.xyz_ = R1.zzzw, C10                                      \n"
		"      ALU:      MULADDv R0.xyz_ = R0, R1.yyyw, C9                                   \n"
		"      ALU:      MULADDv R0.xyz_ = R0, R1.xxxw, C8                                   \n"
		"      ALU:      DOT3v   R1.x___ = R0, R0                                            \n"
		"      ALU:      MULADDv R3 = C3, R2.zzzz, C2                                        \n"
		"EXEC                                                                                \n"
		"      ALU:      MULADDv R3 = R3, R2.yyyy, C1                                        \n"
		"      ALU:      MAXv    R0.____ = R0, R0                                            \n"
		"                RECIPSQ_IEEE     R0.___w = R1.xyzx                                  \n"
		"ALLOC PARAM/PIXEL SIZE(0x1)                                                         \n"
		"EXEC_END                                                                            \n"
		"      ALU:      MULADDv export1 = R3, R2.xxxx, C0                                   \n"
		"      ALU:      MULv    export0.xyz_ = R0, R0.wwww                                  \n";

	const char *cat_fragment_shader_asm =
/*
precision mediump float;
const vec4 MaterialDiffuse = vec4(0.000000, 0.000000, 1.000000, 1.000000);
const vec4 LightColor0 = vec4(0.800000, 0.800000, 0.800000, 1.000000);
const vec4 light_position = vec4(0.000000, 1.000000, 0.000000, 1.000000);
varying vec3 vertex_normal;
varying vec4 vertex_position;

void main(void)
{
    const vec4 diffuse_light_color = LightColor0;
    const vec4 lightAmbient = vec4(0.1, 0.1, 0.1, 1.0);
    const vec4 lightSpecular = vec4(0.8, 0.8, 0.8, 1.0);
    const vec4 matAmbient = vec4(0.2, 0.2, 0.2, 1.0);
    const vec4 matSpecular = vec4(1.0, 1.0, 1.0, 1.0);
    const float matShininess = 100.0;                     // C4.x
    vec3 eye_direction = normalize(-vertex_position.xyz);
    vec3 light_direction = normalize(light_position.xyz/light_position.w -
                                     vertex_position.xyz/vertex_position.w);
    vec3 normalized_normal = normalize(vertex_normal);

    // reflect(i,n) -> i - 2 * dot(n,i) * n
    vec3 reflection = reflect(-light_direction, normalized_normal);
    float specularTerm = pow(max(0.0, dot(reflection, eye_direction)), matShininess);
    float diffuseTerm = max(0.0, dot(normalized_normal, light_direction));
    vec4 specular = (lightSpecular * matSpecular);
    vec4 ambient = (lightAmbient * matAmbient);
    vec4 diffuse = (diffuse_light_color * MaterialDiffuse);
    vec4 result = (specular * specularTerm) + ambient + (diffuse * diffuseTerm);
    gl_FragColor = result;
}
*/
		"@varying(R0)    vertex_normal                                                                                \n"
		"@varying(R1)    vertex_position                                                                              \n"
		"@const(C0)      0.000000, 1.000000, 0.000000, 0.000000                                                       \n"
		"@const(C1)      0.800000, 0.800000, 0.800000, 1.000000                                                       \n"
		"@const(C2)      0.020000, 0.020000, 0.020000, 1.000000                                                       \n"
		"@const(C3)      0.000000, 0.000000, 0.800000, 1.000000                                                       \n"
		"@const(C4)      100.000000, 0.000000, 0.000000, 0.000000                                                     \n"
		"EXEC                                                                                                         \n"
		"   (S)ALU:      DOT3v   R2.x___ = R0, R0                ; normalize(vertex_normal)                           \n"
		"                RECIP_IEEE     R3.x___ = R1             ; 1/vertex_position.x ? R1.wyzw?                     \n"
		"      ALU:      MULADDv R3.xyz_ = C0.xyxw, -R1, R3.xxxw ; light_position.xyz/1.0 -                           \n"
		"                                                        ; vertex_position.xyz/vertex_position.w              \n"
		"      ALU:      DOT3v   R2.x___ = R3, R3                ; normalize(light_position...)                       \n"
		"                RECIPSQ_IEEE     R0.___w = R2.xyzx      ; normalize(vertex_normal)                           \n"
		"; here the RSQ sees the R2 value written in first instruction, rather than                                   \n"
		"; the R2 dst being calculated as part of the same VLIW instruction                                           \n"
		"      ALU:      MULv    R0.xyz_ = R0, R0.wwww           ; normalized_normal = normalize(vertex_normal)       \n"
		"                RECIPSQ_IEEE     R0.___w = R2.xyzx      ; normalize(light_position...)                       \n"
		"      ALU:      MULv    R2.xyz_ = R3, R0.wwww           ; light_direction = normalize(light_position...)     \n"
		"      ALU:      DOT3v   R3.x___ = -R1, -R1              ; normalize(-vertex_position.xyz)                    \n"
		"EXEC                                                                                                         \n"
		"; reflect(i,n) -> i - 2 * dot(n,i) * n                                                                       \n"
		"      ALU:      DOT3v   R3.x___ = -R2, R0               ; reflect(-light_direction, normalized_normal)       \n"
		"                RECIPSQ_IEEE     R0.___w = R3.xyzx      ; normalize(-vertex_position.xyz);                   \n"
		"      ALU:      MULv    R1.xyz_ = -R1, R0.wwww          ; eye_direction = normalize(-vertex_position.xyz)    \n"
		"                ADDs    R3.x___ = R3.xyzx               ; 2 * dot(n, i)                                      \n"
		"      ALU:      MULADDv R3.xyz_ = -R2, R0, -R3.xxxw     ; reflect(..) -> i + (n * (2 * dot(n, i))            \n"
		"      ALU:      DOT3v   R1.x___ = R1, R3                ; dot(reflection, eye_direction)                     \n"
		"      ALU:      MAXv    R1.x___ = R1, C0                ; max(0.0, dot(reflection, eye_direction)            \n"
		"      ALU:      DOT3v   R0.x___ = R2, R0                ; dot(normalized_normal, light_direction)            \n"
		"                LOG_CLAMP    R0.___w = R1.xyzx          ; pow(max(0.0, dot(...)), matShininess)              \n"
		"EXEC                                                                                                         \n"
		"      ALU:      MAXv    R0.x___ = R0, C0                ; diffuseTerm = max(0.0, dot(...))                   \n"
		"                MUL_CONST_0     R0.___w = C4.wyzx       ; specularTerm = pow(..., matShininess)              \n"
		"      ALU:      MAXv    R0.____ = R0, R0                                                                     \n"
		"                EXP_IEEE    R1.x___ = R0                ; specularTerm = pow(..)                             \n"
		"; C2 is ambient  = (lightAmbient * matAmbient)   = vec4(0.1,0.1,0.1,1.0) * vec4(0.2,0.2,0.2,1.0)             \n"
		"; C1 is specular = (lightSpecular * matSpecular) = vec4(0.8,0.8,0.8,1.0) * vec4(1.0,1.0,1.0,1.0)             \n"
		"      ALU:      MULADDv R1.x__w = C2, R1.xyzx, C1       ; ambient + (specularTerm * specular)                \n"
		"ALLOC PARAM/PIXEL SIZE(0x0)                                                                                  \n"
		"EXEC_END ADDR(0x12) CNT(0x1)                                                                                 \n"
		"      ALU:      MULADDv export0 = R1.xxxw, R0.xxxx, C3.xxzw     ; gl_FragColor                               \n"
		"NOP                                                                                                          \n";

	static const GLfloat texcoords[] = {
			0.0f, 1.0f,
			1.0f, 1.0f,
			0.0f, 0.0f,
			1.0f, 0.0f,
	};

	static const GLfloat tex1_vertices[] = {
			-0.95, +0.45, -1.0,
			+0.45, +0.45, -1.0,
			-0.95, +0.95, -1.0,
			+0.45, +0.95, -1.0
	};

	static const GLfloat tex2_vertices[] = {
			-0.45, -0.95, -1.0,
			+0.95, -0.95, -1.0,
			-0.45, -0.45, -1.0,
			+0.95, -0.45, -1.0
	};

	const char *tex_vertex_shader_asm =
		"@attribute(R1)  aPosition                                        \n"
		"@attribute(R2)  aTexCoord                                        \n"
		"@varying(R0)    vTexCoord                                        \n"
		"EXEC                                                             \n"
		"      FETCH:   VERTEX   R2.xy11 = R0.x FMT_32_32_FLOAT SIGNED    \n"
		"                                      STRIDE(8) CONST(20, 1)     \n"
		"   (S)FETCH:   VERTEX   R1.xyz1 = R0.x FMT_32_32_32_FLOAT SIGNED \n"
		"                                      STRIDE(12) CONST(20, 0)    \n"
		"ALLOC POSITION SIZE(0x0)                                         \n"
		"EXEC                                                             \n"
		"      ALU:   MAXv   export62 = R1, R1   ; gl_Position            \n"
		"ALLOC PARAM/PIXEL SIZE(0x0)                                      \n"
		"EXEC_END                                                         \n"
		"      ALU:   MAXv   export0 = R2, R2    ; vTexCoord              \n"
		"NOP                                                              \n";

	const char *tex_fragment_shader_asm =
		"@varying(R0)    vTexCoord                                        \n"
		"@sampler(0)     uTexture                                         \n"
		"EXEC                                                             \n"
		"   (S)FETCH:  SAMPLE  R0.xyzw = R0.xyx CONST(0)                  \n"
		"ALLOC PARAM/PIXEL SIZE(0x0)                                      \n"
		"EXEC_END                                                         \n"
		"      ALU:    MAXv    export0 = R0, R0 ; gl_FragColor            \n"
		"NOP                                                              \n";

	uint32_t width = 0, height = 0;
	int i, n = 1;

	if (argc == 2)
		n = atoi(argv[1]);

	DEBUG_MSG("----------------------------------------------------------------");
	RD_START("fd-cat", "");

	state = fd_init();
	if (!state)
		return -1;

	surface = fd_surface_screen(state, &width, &height);
	if (!surface)
		return -1;

	/* load textures: */
	lolstex1 = fd_surface_new_fmt(state, lolstex1_image.width, lolstex1_image.height,
			COLORX_8_8_8_8);
	fd_surface_upload(lolstex1, lolstex1_image.pixel_data);

	lolstex2 = fd_surface_new_fmt(state, lolstex2_image.width, lolstex2_image.height,
			COLORX_8_8_8_8);
	fd_surface_upload(lolstex2, lolstex2_image.pixel_data);

	fd_enable(state, GL_CULL_FACE);
	fd_depth_func(state, GL_LEQUAL);
	fd_enable(state, GL_DEPTH_TEST);
	fd_tex_param(state, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	fd_tex_param(state, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	fd_blend_func(state, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	/* this needs to come after enabling depth test as enabling depth test
	 * effects bin sizes:
	 */
	fd_make_current(state, surface);

	/* construct the two shader programs: */
	cat_program = fd_program_new();
	fd_program_attach_asm(cat_program, FD_SHADER_VERTEX, cat_vertex_shader_asm);
	fd_program_attach_asm(cat_program, FD_SHADER_FRAGMENT, cat_fragment_shader_asm);

	tex_program = fd_program_new();
	fd_program_attach_asm(tex_program, FD_SHADER_VERTEX, tex_vertex_shader_asm);
	fd_program_attach_asm(tex_program, FD_SHADER_FRAGMENT, tex_fragment_shader_asm);

	fd_link(state);

	position_vbo = fd_attribute_bo_new(state, cat_position_sz, cat_position);
	normal_vbo = fd_attribute_bo_new(state, cat_normal_sz, cat_normal);

	for (i = 0; i < n; i++) {
		GLfloat aspect = (GLfloat)height / (GLfloat)width;
		ESMatrix modelview;
		ESMatrix projection;
		ESMatrix modelviewprojection;
		float normal[9];
		float scale = 1.8;

		esMatrixLoadIdentity(&modelview);
		esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
		esRotate(&modelview, 45.0f - (0.5f * i), 0.0f, 1.0f, 0.0f);

		esMatrixLoadIdentity(&projection);
		esFrustum(&projection,
				-scale, +scale,
				-scale * aspect, +scale * aspect,
				5.5f, 10.0f);

		esMatrixLoadIdentity(&modelviewprojection);
		esMatrixMultiply(&modelviewprojection, &modelview, &projection);

		normal[0] = modelview.m[0][0];
		normal[1] = modelview.m[0][1];
		normal[2] = modelview.m[0][2];
		normal[3] = modelview.m[1][0];
		normal[4] = modelview.m[1][1];
		normal[5] = modelview.m[1][2];
		normal[6] = modelview.m[2][0];
		normal[7] = modelview.m[2][1];
		normal[8] = modelview.m[2][2];

		fd_clear_color(state, 0xff000000);
		fd_clear(state, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		fd_attribute_bo(state, "normal", normal_vbo);
		fd_attribute_bo(state, "position", position_vbo);

		fd_uniform_attach(state, "ModelViewMatrix",
				4, 4, &modelview.m[0][0]);
		fd_uniform_attach(state, "ModelViewProjectionMatrix",
				4, 4,  &modelviewprojection.m[0][0]);
		fd_uniform_attach(state, "NormalMatrix",
				3, 3, normal);

		/* draw cat: */
		fd_disable(state, GL_BLEND);
		fd_set_program(state, cat_program);
		fd_draw_arrays(state, GL_TRIANGLES, 0, cat_vertices);

		/* setup to draw text (common to tex1 and tex2): */
		fd_enable(state, GL_BLEND);
		fd_set_program(state, tex_program);
		fd_attribute_pointer(state, "aTexCoord", 2, 4, texcoords);

		/* draw tex1: */
		fd_set_texture(state, "uTexture", lolstex1);
		fd_attribute_pointer(state, "aPosition", 3, 4, tex1_vertices);
		fd_draw_arrays(state, GL_TRIANGLE_STRIP, 0, 4);

		/* draw tex2: */
		fd_set_texture(state, "uTexture", lolstex2);
		fd_attribute_pointer(state, "aPosition", 3, 4, tex2_vertices);
		fd_draw_arrays(state, GL_TRIANGLE_STRIP, 0, 4);

		fd_swap_buffers(state);
	}

	fd_flush(state);

	fd_dump_bmp(surface, "lolscat.bmp");

	fd_fini(state);

	RD_END();

	return 0;
}
示例#9
0
void         Draw(GLContext	*_context)
{
	UserData      *_user = (UserData *)_context->userObject;
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//very important
	//draw earth
	_user->object->enableObject();

	glBindBuffer(GL_ARRAY_BUFFER, _user->positionVertexBufferId);
	glEnableVertexAttribArray(0);//position
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL);

	glBindBuffer(GL_ARRAY_BUFFER, _user->texCoordVertexBufferId);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), NULL);

	glBindBuffer(GL_ARRAY_BUFFER, _user->normalVertexBufferId);
	glEnableVertexAttribArray(2);
	glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL);
	//
	ESMatrix     mvMatrix;
	esMatrixLoadIdentity(&mvMatrix);
	esTranslate(&mvMatrix, 0.0f, 0.0f, -5.0f);
	esRotate(&mvMatrix, 17.7f , 1.0f, 0.0f, 0.0f);
	esRotate(&mvMatrix, _user->earthAngle, 0.0f, 1.0f, 0.0f);

	glUniformMatrix4fv(_user->mvLoc, 1, GL_FALSE,(float*)mvMatrix.m);//mv matrix

	ESMatrix    projMatrix, mvpMatrix;
	esMatrixLoadIdentity(&projMatrix);
	esOrtho(&projMatrix, -1.0f, 1.0f, -1.0f, 1.0f, -10.0f, 10.0f);
	esMatrixMultiply(&mvpMatrix, &mvMatrix, &projMatrix);
	glUniformMatrix4fv(_user->mvpLoc, 1, GL_FALSE, (float *)mvpMatrix.m);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, _user->earthMapId);
	glUniform1i(_user->baseMapLoc, 0);

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glDrawArrays(GL_TRIANGLES, 0, sphereNumVerts);
	//画出月球
	
_user->object->enableObject();
	glBindBuffer(GL_ARRAY_BUFFER, _user->positionVertexBufferId);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL);

	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 2 * sizeof(float), GL_FLOAT, GL_FALSE, 2 * sizeof(float), NULL);

	glEnableVertexAttribArray(2);
	glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL);

	esMatrixLoadIdentity(&mvMatrix);
	esTranslate(&mvMatrix, 0.0f, 0.0f, -5.0f);
	esScale(&mvMatrix, 0.25f, 0.25f, 0.25f);
	esRotate(&mvMatrix, 17.7f, 1.0f, 0.0f, 0.0f);
	esRotate(&mvMatrix, _user->moonAngle, 0.0f, 1.0f, 0.0f);
	esTranslate(&mvMatrix, 4.0f, 0.0f, 0.0f);
	glUniformMatrix4fv(_user->mvLoc, 1, GL_FALSE, (float*)mvMatrix.m);

	esMatrixLoadIdentity(&projMatrix);
	esOrtho(&projMatrix, -1.0f, 1.0f, -1.0f, 1.0f, -10.0f, 10.0f);
	esMatrixMultiply(&mvpMatrix, &mvMatrix, &projMatrix);
	glUniformMatrix4fv(_user->mvpLoc, 1, GL_FALSE, (float*)mvpMatrix.m);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, _user->moonMapId);
	glUniform1i(_user->baseMapLoc, 0);

	glBlendFunc(GL_ONE, GL_ZERO);
	glDrawArrays(GL_TRIANGLES, 0, sphereNumVerts);
	
}
示例#10
0
int main(int argc, char **argv)
{
    int rv;
    int width = 256;
    int height = 256;
    int padded_width = etna_align_up(width, 64);
    int padded_height = etna_align_up(height, 64);

    printf("padded_width %i padded_height %i\n", padded_width, padded_height);
    rv = viv_open();
    if(rv!=0)
    {
        fprintf(stderr, "Error opening device\n");
        exit(1);
    }
    printf("Succesfully opened device\n");

    bool supertiled = VIV_FEATURE(chipMinorFeatures0,SUPER_TILED);
    unsigned bits_per_tile = VIV_FEATURE(chipMinorFeatures0,2BITPERTILE)?2:4;

    printf("Supertile: %i, bits per tile: %i\n", supertiled, bits_per_tile);

    etna_vidmem *rt = 0; /* main render target */
    etna_vidmem *rt_ts = 0; /* tile status for main render target */
    etna_vidmem *z = 0; /* depth for main render target */
    etna_vidmem *z_ts = 0; /* depth ts for main render target */
    etna_vidmem *vtx = 0; /* vertex buffer */
    etna_vidmem *aux_rt = 0; /* auxilary render target */
    etna_vidmem *aux_rt_ts = 0; /* tile status for auxilary render target */
    etna_vidmem *bmp = 0; /* bitmap */

    size_t rt_size = padded_width * padded_height * 4;
    size_t rt_ts_size = etna_align_up((padded_width * padded_height * 4)*bits_per_tile/0x80, 0x100);
    size_t z_size = padded_width * padded_height * 2;
    size_t z_ts_size = etna_align_up((padded_width * padded_height * 2)*bits_per_tile/0x80, 0x100);
    size_t bmp_size = width * height * 4;

    if(etna_vidmem_alloc_linear(&rt, rt_size, gcvSURF_RENDER_TARGET, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
            etna_vidmem_alloc_linear(&rt_ts, rt_ts_size, gcvSURF_TILE_STATUS, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
            etna_vidmem_alloc_linear(&z, z_size, gcvSURF_DEPTH, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
            etna_vidmem_alloc_linear(&z_ts, z_ts_size, gcvSURF_TILE_STATUS, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
            etna_vidmem_alloc_linear(&vtx, VERTEX_BUFFER_SIZE, gcvSURF_VERTEX, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
            etna_vidmem_alloc_linear(&aux_rt, 0x4000, gcvSURF_RENDER_TARGET, gcvPOOL_SYSTEM, true)!=ETNA_OK ||
            etna_vidmem_alloc_linear(&aux_rt_ts, 0x80*bits_per_tile, gcvSURF_TILE_STATUS, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
            etna_vidmem_alloc_linear(&bmp, bmp_size, gcvSURF_BITMAP, gcvPOOL_DEFAULT, true)!=ETNA_OK
      )
    {
        fprintf(stderr, "Error allocating video memory\n");
        exit(1);
    }

    /* Phew, now we got all the memory we need.
     * Write interleaved attribute vertex stream.
     * Unlike the GL example we only do this once, not every time glDrawArrays is called, the same would be accomplished
     * from GL by using a vertex buffer object.
     */
    for(int vert=0; vert<NUM_VERTICES; ++vert)
    {
        int src_idx = vert * COMPONENTS_PER_VERTEX;
        int dest_idx = vert * COMPONENTS_PER_VERTEX * 3;
        for(int comp=0; comp<COMPONENTS_PER_VERTEX; ++comp)
        {
            ((float*)vtx->logical)[dest_idx+comp+0] = vVertices[src_idx + comp]; /* 0 */
            ((float*)vtx->logical)[dest_idx+comp+3] = vNormals[src_idx + comp]; /* 1 */
            ((float*)vtx->logical)[dest_idx+comp+6] = vColors[src_idx + comp]; /* 2 */
        }
    }

    etna_ctx *ctx = 0;
    if(etna_create(&ctx) != ETNA_OK)
    {
        printf("Unable to create context\n");
        exit(1);
    }

    /* XXX how important is the ordering? I suppose we could group states (except the flushes, kickers, semaphores etc)
     * and simply submit them at once. Especially for consecutive states and masked stated this could be a big win
     * in DMA command buffer size. */


    for(int frame=0; frame<1; ++frame)
    {
        printf("*** FRAME %i ****\n", frame);
        /* XXX part of this can be put outside the loop, but until we have usable context management
         * this is safest.
         */

        etna_set_state(ctx, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x1);
        etna_set_state(ctx, VIVS_RA_CONTROL, 0x1);

        etna_set_state(ctx, VIVS_PA_W_CLIP_LIMIT, 0x34000001);
        etna_set_state(ctx, VIVS_PA_SYSTEM_MODE, 0x11);
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_BIT(VIVS_PA_CONFIG_UNK22, 0));
        etna_set_state(ctx, VIVS_SE_CONFIG, 0x0);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);
        etna_set_state(ctx, VIVS_PE_COLOR_FORMAT,
                       ETNA_MASKED_BIT(VIVS_PE_COLOR_FORMAT_PARTIAL, 0));
        etna_set_state(ctx, VIVS_PE_ALPHA_CONFIG,
                       ETNA_MASKED_BIT(VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_COLOR, 0) &
                       ETNA_MASKED_BIT(VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_ALPHA, 0) &
                       ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_SRC_FUNC_COLOR, BLEND_FUNC_ONE) &
                       ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_SRC_FUNC_ALPHA, BLEND_FUNC_ONE) &
                       ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_DST_FUNC_COLOR, BLEND_FUNC_ZERO) &
                       ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_DST_FUNC_ALPHA, BLEND_FUNC_ZERO) &
                       ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_EQ_COLOR, BLEND_EQ_ADD) &
                       ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_EQ_ALPHA, BLEND_EQ_ADD));
        etna_set_state(ctx, VIVS_PE_ALPHA_BLEND_COLOR,
                       VIVS_PE_ALPHA_BLEND_COLOR_B(0) |
                       VIVS_PE_ALPHA_BLEND_COLOR_G(0) |
                       VIVS_PE_ALPHA_BLEND_COLOR_R(0) |
                       VIVS_PE_ALPHA_BLEND_COLOR_A(0));
        etna_set_state(ctx, VIVS_PE_ALPHA_OP, ETNA_MASKED_BIT(VIVS_PE_ALPHA_OP_ALPHA_TEST, 0));
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_INL(VIVS_PA_CONFIG_CULL_FACE_MODE, OFF));
        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_WRITE_ENABLE, 0));
        etna_set_state(ctx, VIVS_PE_STENCIL_CONFIG, ETNA_MASKED(VIVS_PE_STENCIL_CONFIG_REF_FRONT, 0) &
                       ETNA_MASKED(VIVS_PE_STENCIL_CONFIG_MASK_FRONT, 0xff) &
                       ETNA_MASKED(VIVS_PE_STENCIL_CONFIG_WRITE_MASK, 0xff) &
                       ETNA_MASKED_INL(VIVS_PE_STENCIL_CONFIG_MODE, DISABLED));
        etna_set_state(ctx, VIVS_PE_STENCIL_OP, ETNA_MASKED(VIVS_PE_STENCIL_OP_FUNC_FRONT, COMPARE_FUNC_ALWAYS) &
                       ETNA_MASKED(VIVS_PE_STENCIL_OP_FUNC_BACK, COMPARE_FUNC_ALWAYS) &
                       ETNA_MASKED(VIVS_PE_STENCIL_OP_FAIL_FRONT, STENCIL_OP_KEEP) &
                       ETNA_MASKED(VIVS_PE_STENCIL_OP_FAIL_BACK, STENCIL_OP_KEEP) &
                       ETNA_MASKED(VIVS_PE_STENCIL_OP_DEPTH_FAIL_FRONT, STENCIL_OP_KEEP) &
                       ETNA_MASKED(VIVS_PE_STENCIL_OP_DEPTH_FAIL_BACK, STENCIL_OP_KEEP) &
                       ETNA_MASKED(VIVS_PE_STENCIL_OP_PASS_FRONT, STENCIL_OP_KEEP) &
                       ETNA_MASKED(VIVS_PE_STENCIL_OP_PASS_BACK, STENCIL_OP_KEEP));

        etna_set_state(ctx, VIVS_PE_COLOR_FORMAT, ETNA_MASKED(VIVS_PE_COLOR_FORMAT_COMPONENTS, 0xf));

        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_EARLY_Z, 0));
        etna_set_state(ctx, VIVS_SE_DEPTH_SCALE, 0x0);
        etna_set_state(ctx, VIVS_SE_DEPTH_BIAS, 0x0);

        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_INL(VIVS_PA_CONFIG_FILL_MODE, SOLID));
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_INL(VIVS_PA_CONFIG_SHADE_MODEL, SMOOTH));
        etna_set_state(ctx, VIVS_PE_COLOR_FORMAT,
                       ETNA_MASKED(VIVS_PE_COLOR_FORMAT_FORMAT, RS_FORMAT_X8R8G8B8) &
                       ETNA_MASKED_BIT(VIVS_PE_COLOR_FORMAT_SUPER_TILED, supertiled));

        etna_set_state(ctx, VIVS_PE_COLOR_ADDR, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_PE_COLOR_STRIDE, padded_width * 4);
        etna_set_state(ctx, VIVS_GL_MULTI_SAMPLE_CONFIG,
                       ETNA_MASKED_INL(VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES, NONE) &
                       ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES, 0xf) &
                       ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12, 0x0) &
                       ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16, 0x0)
                      );
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);
        etna_set_state(ctx, VIVS_PE_COLOR_FORMAT, ETNA_MASKED_BIT(VIVS_PE_COLOR_FORMAT_PARTIAL, 1));
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);
        etna_set_state(ctx, VIVS_TS_COLOR_CLEAR_VALUE, 0);
        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address); /* ADDR_B */
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_TS_MEM_CONFIG, VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR);

        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG,
                       ETNA_MASKED_INL(VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT, D16) &
                       ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_SUPER_TILED, supertiled)
                      );
        etna_set_state(ctx, VIVS_PE_DEPTH_ADDR, z->address); /* ADDR_C */
        etna_set_state(ctx, VIVS_PE_DEPTH_STRIDE, padded_width * 2);
        etna_set_state(ctx, VIVS_PE_HDEPTH_CONTROL, VIVS_PE_HDEPTH_CONTROL_FORMAT_DISABLED);
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_NORMALIZE, 65535.0);
        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_EARLY_Z, 0));
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_DEPTH);

        etna_set_state(ctx, VIVS_TS_DEPTH_CLEAR_VALUE, 0xffffffff);
        etna_set_state(ctx, VIVS_TS_DEPTH_STATUS_BASE, z_ts->address); /* ADDR_D */
        etna_set_state(ctx, VIVS_TS_DEPTH_SURFACE_BASE, z->address); /* ADDR_C */
        etna_set_state(ctx, VIVS_TS_MEM_CONFIG,
                       VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR |
                       VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR |
                       VIVS_TS_MEM_CONFIG_DEPTH_16BPP |
                       VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION);
        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_EARLY_Z, 1)); /* flip-flopping once again */

        /* Warm up RS on aux render target */
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_warm_up_rs(ctx, aux_rt->address, aux_rt_ts->address);

        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address); /* ADDR_B */
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address); /* ADDR_A */

        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_warm_up_rs(ctx, aux_rt->address, aux_rt_ts->address);

        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address); /* ADDR_B */
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);

        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_warm_up_rs(ctx, aux_rt->address, aux_rt_ts->address);
        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address); /* ADDR_B */
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address); /* ADDR_A */

        etna_stall(ctx, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE);

        /* Set up the resolve to clear tile status for main render target
         * Regard the TS as an image of width 16 with 4 bytes per pixel (64 bytes per row)
         * XXX need to clear the depth ts too.
         * */
        etna_set_state(ctx, VIVS_RS_CONFIG,
                       (RS_FORMAT_X8R8G8B8 << VIVS_RS_CONFIG_SOURCE_FORMAT__SHIFT) |
                       (RS_FORMAT_X8R8G8B8 << VIVS_RS_CONFIG_DEST_FORMAT__SHIFT)
                      );
        etna_set_state_multi(ctx, VIVS_RS_DITHER(0), 2, (uint32_t[]) {
            0xffffffff, 0xffffffff
        });
        etna_set_state(ctx, VIVS_RS_DEST_ADDR, rt_ts->address); /* ADDR_B */
        etna_set_state(ctx, VIVS_RS_DEST_STRIDE, 0x40);
        etna_set_state(ctx, VIVS_RS_WINDOW_SIZE,
                       ((rt_ts_size/0x40) << VIVS_RS_WINDOW_SIZE_HEIGHT__SHIFT) |
                       (16 << VIVS_RS_WINDOW_SIZE_WIDTH__SHIFT));
        etna_set_state(ctx, VIVS_RS_FILL_VALUE(0), (bits_per_tile==4)?0x11111111:0x55555555);
        etna_set_state(ctx, VIVS_RS_CLEAR_CONTROL,
                       VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1 |
                       (0xffff << VIVS_RS_CLEAR_CONTROL_BITS__SHIFT));
        etna_set_state(ctx, VIVS_RS_EXTRA_CONFIG,
                       0); /* no AA, no endian switch */
        etna_set_state(ctx, VIVS_RS_KICKER,
                       0xbeebbeeb);
        /** Done */

        etna_set_state(ctx, VIVS_TS_COLOR_CLEAR_VALUE, 0xff7f7f7f);
        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address); /* ADDR_B */
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_TS_MEM_CONFIG,
                       VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR |
                       VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR |
                       VIVS_TS_MEM_CONFIG_DEPTH_16BPP |
                       VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION);
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_INL(VIVS_PA_CONFIG_CULL_FACE_MODE, CCW));
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);

        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_WRITE_ENABLE, 0));
        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED_INL(VIVS_PE_DEPTH_CONFIG_DEPTH_MODE, NONE));
        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_WRITE_ENABLE, 0));
        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED(VIVS_PE_DEPTH_CONFIG_DEPTH_FUNC, COMPARE_FUNC_ALWAYS));
        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED_INL(VIVS_PE_DEPTH_CONFIG_DEPTH_MODE, Z));
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_NEAR, 0.0);
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_FAR, 1.0);
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_NORMALIZE, 65535.0);

        /* set up primitive assembly */
        etna_set_state_f32(ctx, VIVS_PA_VIEWPORT_OFFSET_Z, 0.0);
        etna_set_state_f32(ctx, VIVS_PA_VIEWPORT_SCALE_Z, 1.0);
        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_ONLY_DEPTH, 0));
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_OFFSET_X, width << 15);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_OFFSET_Y, height << 15);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_SCALE_X, width << 15);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_SCALE_Y, height << 15);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_LEFT, 0);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_TOP, 0);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_RIGHT, (width << 16) | 5);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_BOTTOM, (height << 16) | 5);

        /* shader setup */
        etna_set_state(ctx, VIVS_VS_END_PC, vs_size/16);
        etna_set_state_multi(ctx, VIVS_VS_INPUT_COUNT, 3, (uint32_t[]) {
            /* VIVS_VS_INPUT_COUNT */ (1<<8) | 3,
            /* VIVS_VS_TEMP_REGISTER_CONTROL */ 6 << VIVS_VS_TEMP_REGISTER_CONTROL_NUM_TEMPS__SHIFT,
            /* VIVS_VS_OUTPUT(0) */ 4
        });
        etna_set_state(ctx, VIVS_VS_START_PC, 0x0);
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(45), 0.5); /* u11.y */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(44), 1.0); /* u11.x */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(27), 0.0); /* u6.w */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(23), 20.0); /* u5.w */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(19), 2.0); /* u4.w */

        /* Now load the shader itself */
        etna_set_state_multi(ctx, VIVS_VS_INST_MEM(0), vs_size/4, vs);
        etna_set_state(ctx, VIVS_RA_CONTROL, 0x1);
        etna_set_state_multi(ctx, VIVS_PS_END_PC, 2, (uint32_t[]) {
            /* VIVS_PS_END_PC */ ps_size/16,
            /* VIVS_PS_OUTPUT_REG */ 0x1
        });
        etna_set_state(ctx, VIVS_PS_START_PC, 0x0);
        etna_set_state(ctx, VIVS_PA_SHADER_ATTRIBUTES(0), 0x200);
        etna_set_state(ctx, VIVS_GL_VARYING_NUM_COMPONENTS,  /* one varying, with four components */
                       (4 << VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__SHIFT)
                      );
        etna_set_state_multi(ctx, VIVS_GL_VARYING_COMPONENT_USE(0), 2, (uint32_t[]) { /* one varying, with four components */
            (VARYING_COMPONENT_USE_USED << VIVS_GL_VARYING_COMPONENT_USE_COMP0__SHIFT) |
            (VARYING_COMPONENT_USE_USED << VIVS_GL_VARYING_COMPONENT_USE_COMP1__SHIFT) |
            (VARYING_COMPONENT_USE_USED << VIVS_GL_VARYING_COMPONENT_USE_COMP2__SHIFT) |
            (VARYING_COMPONENT_USE_USED << VIVS_GL_VARYING_COMPONENT_USE_COMP3__SHIFT)
            , 0
        });
        etna_set_state_multi(ctx, VIVS_PS_INST_MEM(0), ps_size/4, ps);
        etna_set_state(ctx, VIVS_PS_INPUT_COUNT, (31<<8)|2);
        etna_set_state(ctx, VIVS_PS_TEMP_REGISTER_CONTROL,
                       (2 << VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS__SHIFT));
        etna_set_state(ctx, VIVS_PS_CONTROL,
                       VIVS_PS_CONTROL_UNK1
                      );
        etna_set_state(ctx, VIVS_PA_ATTRIBUTE_ELEMENT_COUNT, 0x100);
        etna_set_state(ctx, VIVS_GL_VARYING_TOTAL_COMPONENTS,  /* one varying, with four components */
                       VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(4)
                      );
        etna_set_state(ctx, VIVS_VS_LOAD_BALANCING, 0xf3f0582);
        etna_set_state(ctx, VIVS_VS_OUTPUT_COUNT, 2);
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_BIT(VIVS_PA_CONFIG_POINT_SIZE_ENABLE, 0));

        /*   Compute transform matrices in the same way as cube egl demo */
        ESMatrix modelview;
        esMatrixLoadIdentity(&modelview);
        esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
        esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f);
        esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f);
        esRotate(&modelview, frame*0.5f, 0.0f, 0.0f, 1.0f);

        GLfloat aspect = (GLfloat)(height) / (GLfloat)(width);

        ESMatrix projection;
        esMatrixLoadIdentity(&projection);
        esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f);

        ESMatrix modelviewprojection;
        esMatrixLoadIdentity(&modelviewprojection);
        esMatrixMultiply(&modelviewprojection, &modelview, &projection);

        ESMatrix inverse, normal; /* compute inverse transpose normal transformation matrix */
        esMatrixInverse3x3(&inverse, &modelview);
        esMatrixTranspose(&normal, &inverse);

        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(0), 16, (uint32_t*)&modelviewprojection.m[0][0]);
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(16), 3, (uint32_t*)&normal.m[0][0]); /* u4.xyz */
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(20), 3, (uint32_t*)&normal.m[1][0]); /* u5.xyz */
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(24), 3, (uint32_t*)&normal.m[2][0]); /* u6.xyz */
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(28), 16, (uint32_t*)&modelview.m[0][0]);
        etna_set_state(ctx, VIVS_FE_VERTEX_STREAM_BASE_ADDR, vtx->address); /* ADDR_E */
        etna_set_state(ctx, VIVS_FE_VERTEX_STREAM_CONTROL,
                       0x24 << VIVS_FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__SHIFT);
        etna_set_state(ctx, VIVS_FE_VERTEX_ELEMENT_CONFIG(0),
                       VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT |
                       (ENDIAN_MODE_NO_SWAP << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) |
                       (0 << VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__SHIFT) |
                       (3 <<VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__SHIFT) |
                       VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF |
                       (0x0 << VIVS_FE_VERTEX_ELEMENT_CONFIG_START__SHIFT) |
                       (0xc << VIVS_FE_VERTEX_ELEMENT_CONFIG_END__SHIFT));
        etna_set_state(ctx, VIVS_FE_VERTEX_ELEMENT_CONFIG(1),
                       VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT |
                       (ENDIAN_MODE_NO_SWAP << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) |
                       (0 << VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__SHIFT) |
                       (3 <<VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__SHIFT) |
                       VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF |
                       (0xc << VIVS_FE_VERTEX_ELEMENT_CONFIG_START__SHIFT) |
                       (0x18 << VIVS_FE_VERTEX_ELEMENT_CONFIG_END__SHIFT));
        etna_set_state(ctx, VIVS_FE_VERTEX_ELEMENT_CONFIG(2),
                       VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT |
                       (ENDIAN_MODE_NO_SWAP << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) |
                       VIVS_FE_VERTEX_ELEMENT_CONFIG_NONCONSECUTIVE |
                       (0 << VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__SHIFT) |
                       (3 <<VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__SHIFT) |
                       VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF |
                       (0x18 << VIVS_FE_VERTEX_ELEMENT_CONFIG_START__SHIFT) |
                       (0x24 << VIVS_FE_VERTEX_ELEMENT_CONFIG_END__SHIFT));
        etna_set_state(ctx, VIVS_VS_INPUT(0), 0x20100);
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_BIT(VIVS_PA_CONFIG_POINT_SPRITE_ENABLE, 0));

        for(int prim=0; prim<6; ++prim)
        {
            etna_draw_primitives(ctx, PRIMITIVE_TYPE_TRIANGLE_STRIP, prim*4, 2);
        }
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);

        etna_flush(ctx);

        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_set_state(ctx, VIVS_RS_CONFIG,
                       VIVS_RS_CONFIG_SOURCE_FORMAT(RS_FORMAT_X8R8G8B8) |
                       VIVS_RS_CONFIG_SOURCE_TILED |
                       VIVS_RS_CONFIG_DEST_FORMAT(RS_FORMAT_X8R8G8B8) |
                       VIVS_RS_CONFIG_DEST_TILED);
        etna_set_state(ctx, VIVS_RS_SOURCE_STRIDE, (padded_width * 4 * 4) | (supertiled?VIVS_RS_SOURCE_STRIDE_TILING:0));
        etna_set_state(ctx, VIVS_RS_DEST_STRIDE, (padded_width * 4 * 4) | (supertiled?VIVS_RS_DEST_STRIDE_TILING:0));
        etna_set_state(ctx, VIVS_RS_DITHER(0), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_DITHER(1), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_CLEAR_CONTROL, VIVS_RS_CLEAR_CONTROL_MODE_DISABLED);
        etna_set_state(ctx, VIVS_RS_EXTRA_CONFIG, 0); /* no AA, no endian switch */
        etna_set_state(ctx, VIVS_RS_SOURCE_ADDR, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_RS_DEST_ADDR, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_RS_WINDOW_SIZE,
                       VIVS_RS_WINDOW_SIZE_HEIGHT(padded_height) |
                       VIVS_RS_WINDOW_SIZE_WIDTH(padded_width));
        etna_set_state(ctx, VIVS_RS_KICKER, 0xbeebbeeb);

        /* Submit second command buffer */
        etna_flush(ctx);

        etna_warm_up_rs(ctx, aux_rt->address, aux_rt_ts->address);

        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address); /* ADDR_B */
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);
        etna_set_state(ctx, VIVS_TS_MEM_CONFIG,
                       VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR |
                       VIVS_TS_MEM_CONFIG_DEPTH_16BPP |
                       VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);
        etna_set_state(ctx, VIVS_PE_COLOR_FORMAT,
                       ETNA_MASKED_BIT(VIVS_PE_COLOR_FORMAT_PARTIAL, 0));

        /* Submit third command buffer, wait for pixel engine to finish */
        etna_finish(ctx);

        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_set_state(ctx, VIVS_RS_CONFIG,
                       VIVS_RS_CONFIG_SOURCE_FORMAT(RS_FORMAT_X8R8G8B8) |
                       VIVS_RS_CONFIG_SOURCE_TILED |
                       VIVS_RS_CONFIG_DEST_FORMAT(RS_FORMAT_X8R8G8B8) /*|
                VIVS_RS_CONFIG_SWAP_RB*/);
        etna_set_state(ctx, VIVS_RS_SOURCE_STRIDE, (padded_width * 4 * 4) | (supertiled?VIVS_RS_SOURCE_STRIDE_TILING:0));
        etna_set_state(ctx, VIVS_RS_DEST_STRIDE, width * 4);
        etna_set_state(ctx, VIVS_RS_DITHER(0), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_DITHER(1), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_CLEAR_CONTROL, VIVS_RS_CLEAR_CONTROL_MODE_DISABLED);
        etna_set_state(ctx, VIVS_RS_EXTRA_CONFIG, 0); /* no AA, no endian switch */
        etna_set_state(ctx, VIVS_RS_SOURCE_ADDR, rt->address);
        etna_set_state(ctx, VIVS_RS_DEST_ADDR, bmp->address);
        etna_set_state(ctx, VIVS_RS_WINDOW_SIZE,
                       VIVS_RS_WINDOW_SIZE_HEIGHT(height) |
                       VIVS_RS_WINDOW_SIZE_WIDTH(width));
        etna_set_state(ctx, VIVS_RS_KICKER, 0xbeebbeeb);
        etna_finish(ctx);
    }
    bmp_dump32(bmp->logical, width, height, false, "/tmp/fb.bmp");
    printf("Dump complete\n");

    /* Unlock video memory */
    if(etna_vidmem_unlock(bmp) != 0)
    {
        fprintf(stderr, "Cannot unlock vidmem\n");
        exit(1);
    }

    etna_free(ctx);
    viv_close();
    return 0;
}
void test_cube_textured(GLint mag_filter, GLint min_filter,
		GLint wrap_s, GLint wrap_t)
{
	GLint width, height;
	GLint modelviewmatrix_handle, modelviewprojectionmatrix_handle, normalmatrix_handle;
	GLuint texturename = 0, texture_handle;
	EGLint pbuffer_attribute_list[] = {
		EGL_WIDTH, 256,
		EGL_HEIGHT, 256,
		EGL_LARGEST_PBUFFER, EGL_TRUE,
		EGL_NONE
	};
	GLfloat vVertices[] = {
			// front
			-1.0f, -1.0f, +1.0f, // point blue
			+1.0f, -1.0f, +1.0f, // point magenta
			-1.0f, +1.0f, +1.0f, // point cyan
			+1.0f, +1.0f, +1.0f, // point white
			// back
			+1.0f, -1.0f, -1.0f, // point red
			-1.0f, -1.0f, -1.0f, // point black
			+1.0f, +1.0f, -1.0f, // point yellow
			-1.0f, +1.0f, -1.0f, // point green
			// right
			+1.0f, -1.0f, +1.0f, // point magenta
			+1.0f, -1.0f, -1.0f, // point red
			+1.0f, +1.0f, +1.0f, // point white
			+1.0f, +1.0f, -1.0f, // point yellow
			// left
			-1.0f, -1.0f, -1.0f, // point black
			-1.0f, -1.0f, +1.0f, // point blue
			-1.0f, +1.0f, -1.0f, // point green
			-1.0f, +1.0f, +1.0f, // point cyan
			// top
			-1.0f, +1.0f, +1.0f, // point cyan
			+1.0f, +1.0f, +1.0f, // point white
			-1.0f, +1.0f, -1.0f, // point green
			+1.0f, +1.0f, -1.0f, // point yellow
			// bottom
			-1.0f, -1.0f, -1.0f, // point black
			+1.0f, -1.0f, -1.0f, // point red
			-1.0f, -1.0f, +1.0f, // point blue
			+1.0f, -1.0f, +1.0f  // point magenta
	};

	GLfloat vTexCoords[] = {
			//front
			1.0f, 1.0f, //point blue
			0.0f, 1.0f, //point magenta
			1.0f, 0.0f, //point cyan
			0.0f, 0.0f, //point white
			//back
			1.0f, 1.0f, //point red
			0.0f, 1.0f, //point black
			1.0f, 0.0f, //point yellow
			0.0f, 0.0f, //point green
			//right
			1.0f, 1.0f, //point magenta
			0.0f, 1.0f, //point red
			1.0f, 0.0f, //point white
			0.0f, 0.0f, //point yellow
			//left
			1.0f, 1.0f, //point black
			0.0f, 1.0f, //point blue
			1.0f, 0.0f, //point green
			0.0f, 0.0f, //point cyan
			//top
			1.0f, 1.0f, //point cyan
			0.0f, 1.0f, //point white
			1.0f, 0.0f, //point green
			0.0f, 0.0f, //point yellow
			//bottom
			1.0f, 0.0f, //point black
			0.0f, 0.0f, //point red
			1.0f, 1.0f, //point blue
			0.0f, 1.0f, //point magenta
	};

	GLfloat vNormals[] = {
			// front
			+0.0f, +0.0f, +1.0f, // forward
			+0.0f, +0.0f, +1.0f, // forward
			+0.0f, +0.0f, +1.0f, // forward
			+0.0f, +0.0f, +1.0f, // forward
			// back
			+0.0f, +0.0f, -1.0f, // backbard
			+0.0f, +0.0f, -1.0f, // backbard
			+0.0f, +0.0f, -1.0f, // backbard
			+0.0f, +0.0f, -1.0f, // backbard
			// right
			+1.0f, +0.0f, +0.0f, // right
			+1.0f, +0.0f, +0.0f, // right
			+1.0f, +0.0f, +0.0f, // right
			+1.0f, +0.0f, +0.0f, // right
			// left
			-1.0f, +0.0f, +0.0f, // left
			-1.0f, +0.0f, +0.0f, // left
			-1.0f, +0.0f, +0.0f, // left
			-1.0f, +0.0f, +0.0f, // left
			// top
			+0.0f, +1.0f, +0.0f, // up
			+0.0f, +1.0f, +0.0f, // up
			+0.0f, +1.0f, +0.0f, // up
			+0.0f, +1.0f, +0.0f, // up
			// bottom
			+0.0f, -1.0f, +0.0f, // down
			+0.0f, -1.0f, +0.0f, // down
			+0.0f, -1.0f, +0.0f, // down
			+0.0f, -1.0f, +0.0f  // down
	};
	EGLSurface surface;

	DEBUG_MSG("----------------------------------------------------------------");
	RD_START("cube-textured", "mag_filter=%04x, min_filter=%04x, wrap_s=%04x, wrap_t=%04x",
			mag_filter, min_filter, wrap_s, wrap_t);

	ECHK(surface = eglCreatePbufferSurface(display, config, pbuffer_attribute_list));

	ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width));
	ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height));

	DEBUG_MSG("PBuffer: %dx%d", width, height);

	/* connect the context to the surface */
	ECHK(eglMakeCurrent(display, surface, surface, context));
	GCHK(glFlush());

	if (!program) {
		program = get_program(vertex_shader_source, fragment_shader_source);

		GCHK(glBindAttribLocation(program, 0, "in_position"));
		GCHK(glBindAttribLocation(program, 1, "in_normal"));
		GCHK(glBindAttribLocation(program, 2, "in_TexCoord"));

		link_program(program);
		GCHK(glFlush());
	}

	GCHK(glViewport(0, 0, width, height));
	GCHK(glFlush());


	/* clear the color buffer */
	GCHK(glClearColor(0.5, 0.5, 0.5, 1.0));
	GCHK(glFlush());
	GCHK(glClear(GL_COLOR_BUFFER_BIT));
	GCHK(glFlush());

	GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices));
	GCHK(glFlush());
	GCHK(glEnableVertexAttribArray(0));
	GCHK(glFlush());

	GCHK(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, vNormals));
	GCHK(glFlush());
	GCHK(glEnableVertexAttribArray(1));
	GCHK(glFlush());

	GCHK(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, vTexCoords));
	GCHK(glEnableVertexAttribArray(2));

	ESMatrix modelview;
	esMatrixLoadIdentity(&modelview);
	esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
	esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f);
	esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f);
	esRotate(&modelview, 10.0f, 0.0f, 0.0f, 1.0f);

	GLfloat aspect = (GLfloat)(height) / (GLfloat)(width);

	ESMatrix projection;
	esMatrixLoadIdentity(&projection);
	esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f);

	ESMatrix modelviewprojection;
	esMatrixLoadIdentity(&modelviewprojection);
	esMatrixMultiply(&modelviewprojection, &modelview, &projection);

	float normal[9];
	normal[0] = modelview.m[0][0];
	normal[1] = modelview.m[0][1];
	normal[2] = modelview.m[0][2];
	normal[3] = modelview.m[1][0];
	normal[4] = modelview.m[1][1];
	normal[5] = modelview.m[1][2];
	normal[6] = modelview.m[2][0];
	normal[7] = modelview.m[2][1];
	normal[8] = modelview.m[2][2];

	GCHK(glActiveTexture(GL_TEXTURE0));
	GCHK(glFlush());
	GCHK(glGenTextures(1, &texturename));
	GCHK(glFlush());
	GCHK(glBindTexture(GL_TEXTURE_2D, texturename));
	GCHK(glFlush());
	GCHK(glTexImage2D(
			GL_TEXTURE_2D, 0, GL_RGB,
			cube_texture.width, cube_texture.height, 0,
			GL_RGB, GL_UNSIGNED_BYTE, cube_texture.pixel_data));
	GCHK(glFlush());

	/* Note: cube turned black until these were defined. */
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter));
	GCHK(glFlush());
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter));
	GCHK(glFlush());
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s));
	GCHK(glFlush());
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t));
	GCHK(glFlush());

	GCHK(modelviewmatrix_handle = glGetUniformLocation(program, "modelviewMatrix"));
	GCHK(modelviewprojectionmatrix_handle = glGetUniformLocation(program, "modelviewprojectionMatrix"));
	GCHK(normalmatrix_handle = glGetUniformLocation(program, "normalMatrix"));
	GCHK(texture_handle = glGetUniformLocation(program, "uTexture"));
	GCHK(glFlush());

	GCHK(glUniformMatrix4fv(modelviewmatrix_handle, 1, GL_FALSE, &modelview.m[0][0]));
	GCHK(glFlush());
	GCHK(glUniformMatrix4fv(modelviewprojectionmatrix_handle, 1, GL_FALSE, &modelviewprojection.m[0][0]));
	GCHK(glFlush());
	GCHK(glUniformMatrix3fv(normalmatrix_handle, 1, GL_FALSE, normal));
	GCHK(glFlush());
	GCHK(glUniform1i(texture_handle, 0)); /* '0' refers to texture unit 0. */
	GCHK(glFlush());

	GCHK(glEnable(GL_CULL_FACE));
	GCHK(glFlush());

	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
	GCHK(glFlush());
	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 4, 4));
	GCHK(glFlush());
	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 8, 4));
	GCHK(glFlush());
	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 12, 4));
	GCHK(glFlush());
	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 16, 4));
	GCHK(glFlush());
	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 20, 4));
	GCHK(glFlush());

	ECHK(eglSwapBuffers(display, surface));
	GCHK(glFlush());

	ECHK(eglDestroySurface(display, surface));
	GCHK(glFlush());

	RD_END();
}
示例#12
0
文件: cat.c 项目: Dm47021/freedreno-1
int main(int argc, char **argv)
{
	struct fd_state *state;
	struct fd_surface *surface, *lolstex1, *lolstex2;
	struct fd_program *cat_program, *tex_program;
	struct fd_bo *position_vbo, *normal_vbo;
	const char *cat_vertex_shader_asm =
		"@out(r2.y)     gl_Position                                       \n"
		"@varying(r0.x-r0.z)     vertex_normal                            \n"
		"@varying(r1.y-r2.x)     vertex_position                          \n"
		"@attribute(r0.x-r0.z)   normal                                   \n"
		"@attribute(r0.w-r1.y)   position                                 \n"
		"@uniform(c0.x-c3.w)  ModelViewMatrix                             \n"
		"@uniform(c4.x-c7.w)  ModelViewProjectionMatrix                   \n"
		"@uniform(c8.x-c10.w) NormalMatrix                                \n"
		"(sy)(ss)(rpt2)mul.f r1.z, r0.z, (r)c10.x                         \n"
		"(rpt3)mad.f32 r2.y, (r)c2.x, r1.y, (r)c3.x                       \n"
		"(rpt2)mad.f32 r1.z, (r)c9.x, r0.y, (r)r1.z                       \n"
		"(rpt3)mad.f32 r3.y, (r)c6.x, r1.y, (r)c7.x                       \n"
		"(rpt2)mad.f32 r0.x, (r)c8.x, r0.x, (r)r1.z                       \n"
		"(rpt3)mad.f32 r1.y, (r)c1.x, r1.x, (r)r2.y                       \n"
		"mul.f r2.y, r0.x, r0.x                                           \n"
		"(rpt3)mad.f32 r2.z, (r)c5.x, r1.x, (r)r3.y                       \n"
		"mad.f32 r1.x, r0.y, r0.y, r2.y                                   \n"
		"(rpt3)mad.f32 r1.y, (r)c0.x, r0.w, (r)r1.y                       \n"
		"mad.f32 r1.x, r0.z, r0.z, r1.x                                   \n"
		"(rpt3)mad.f32 r2.y, (r)c4.x, r0.w, (r)r2.z                       \n"
		"(rpt1)nop                                                        \n"
		"rsq r0.w, r1.x                                                   \n"
		"(ss)(rpt2)mul.f r0.x, (r)r0.x, r0.w                              \n"
		"end                                                              \n";

	const char *cat_fragment_shader_asm =
/*
precision mediump float;
const vec4 MaterialDiffuse = vec4(0.000000, 0.000000, 1.000000, 1.000000);
const vec4 LightColor0 = vec4(0.800000, 0.800000, 0.800000, 1.000000);
const vec4 light_position = vec4(0.000000, 1.000000, 0.000000, 1.000000);
varying vec3 vertex_normal;
varying vec4 vertex_position;

void main(void)
{
    const vec4 diffuse_light_color = LightColor0;
    const vec4 lightAmbient = vec4(0.1, 0.1, 0.1, 1.0);
    const vec4 lightSpecular = vec4(0.8, 0.8, 0.8, 1.0);
    const vec4 matAmbient = vec4(0.2, 0.2, 0.2, 1.0);
    const vec4 matSpecular = vec4(1.0, 1.0, 1.0, 1.0);
    const float matShininess = 100.0;                     // C4.x
    vec3 eye_direction = normalize(-vertex_position.xyz);
    vec3 light_direction = normalize(light_position.xyz/light_position.w -
                                     vertex_position.xyz/vertex_position.w);
    vec3 normalized_normal = normalize(vertex_normal);

    // reflect(i,n) -> i - 2 * dot(n,i) * n
    vec3 reflection = reflect(-light_direction, normalized_normal);
    float specularTerm = pow(max(0.0, dot(reflection, eye_direction)), matShininess);
    float diffuseTerm = max(0.0, dot(normalized_normal, light_direction));
    vec4 specular = (lightSpecular * matSpecular);
    vec4 ambient = (lightAmbient * matAmbient);
    vec4 diffuse = (diffuse_light_color * MaterialDiffuse);
    vec4 result = (specular * specularTerm) + ambient + (diffuse * diffuseTerm);
    gl_FragColor = result;
}
*/
		"@out(hr0.y)             gl_FragColor                             \n"
		"@varying(r0.x-r0.z)     vertex_normal                            \n"
		"@varying(r1.y-r2.x)     vertex_position                          \n"
		"@const(c0.x)            0.000000, 1.000000, 0.000000, 0.000000   \n"
		"@const(c1.x)            0.800000, 0.800000, 0.800000, 1.000000   \n"
		"@const(c2.x)            0.020000, 0.020000, 0.020000, 1.000000   \n"
		"@const(c3.x)            0.000000, 0.000000, 0.800000, 1.000000   \n"
		"@const(c4.x)            100.000000, 0.000000, 0.000000, 0.000000 \n"
		"@const(c5.x)            2.000000, 0.000000, 0.000000, 0.000000   \n"
		"(sy)(ss)(rpt3)bary.f hr0.x, (r)3, r0.x                           \n"
		"(rpt2)bary.f (ei)hr1.x, (r)0, r0.x                               \n"
		"(rpt2)nop                                                        \n"
		"rcp hr0.w, hr0.w                                                 \n"
		"mul.f hr1.w, hr1.x, hr1.x                                        \n"
		"mul.f hr2.x, (neg)hr0.x, (neg)hr0.x                              \n"
		"mad.f16 hr1.w, hr1.y, hr1.y, hr1.w                               \n"
		"mad.f16 hr2.x, (neg)hr0.y, (neg)hr0.y, hr2.x                     \n"
		"mad.f16 hr1.w, hr1.z, hr1.z, hr1.w                               \n"
		"mad.f16 hr2.x, (neg)hr0.z, (neg)hr0.z, hr2.x                     \n"
		"(ss)(rpt1)mul.f hr2.y, (r)hr0.x, hr0.w                           \n"
		"mul.f hr0.w, hr0.z, hr0.w                                        \n"
		"(rpt1)nop                                                        \n"
		"rsq hr1.w, hr1.w                                                 \n"
		"add.f hr2.z, (neg)hr2.z, hc0.y                                   \n"
		"mul.f hr2.w, (neg)hr2.y, (neg)hr2.y                              \n"
		"rsq hr2.x, hr2.x                                                 \n"
		"(rpt1)nop                                                        \n"
		"mad.f16 hr2.w, hr2.z, hr2.z, hr2.w                               \n"
		"nop                                                              \n"
		"mad.f16 hr2.w, (neg)hr0.w, (neg)hr0.w, hr2.w                     \n"
		"(ss)(rpt2)mul.f hr1.x, (r)hr1.x, hr1.w                           \n"
		"(rpt2)mul.f hr0.x, (neg)(r)hr0.x, hr2.x                          \n"
		"rsq hr1.w, hr2.w                                                 \n"
		"(ss)mul.f hr2.w, (neg)hr2.y, hr1.w                               \n"
		"mul.f hr3.x, hr2.z, hr1.w                                        \n"
		"mul.f hr3.y, (neg)hr0.w, hr1.w                                   \n"
		"nop                                                              \n"
		"mul.f hr0.w, (neg)hr2.w, hr1.x                                   \n"
		"mul.f hr1.w, hr2.w, hr1.x                                        \n"
		"mad.f16 hr0.w, (neg)hr3.x, hr1.y, hr0.w                          \n"
		"mad.f16 hr1.w, hr3.x, hr1.y, hr1.w                               \n"
		"mad.f16 hr0.w, (neg)hr3.y, hr1.z, hr0.w                          \n"
		"mad.f16 hr1.w, hr3.y, hr1.z, hr1.w                               \n"
		"(rpt1)nop                                                        \n"
		"mul.f hr0.w, hr0.w, hc5.x                                        \n"
		"max.f hr1.w, hr1.w, hc0.x                                        \n"
		"(rpt1)nop                                                        \n"
		"(rpt2)mad.f16 hr0.w, (r)hr1.x, (neg)hr0.w, (neg)(r)hr2.w         \n"
		"mul.f hr1.z, hr1.w, hc3.z                                        \n"
		"mul.f hr0.x, hr0.x, hr0.w                                        \n"
		"nop                                                              \n"
		"mad.f16 hr0.x, hr0.y, hr1.x, hr0.x                               \n"
		"nop                                                              \n"
		"mad.f16 hr0.x, hr0.z, hr1.y, hr0.x                               \n"
		"(rpt2)nop                                                        \n"
		"max.f hr0.x, hr0.x, hc0.x                                        \n"
		"(rpt5)nop                                                        \n"
		"log2 hr0.x, hr0.x                                                \n"
		"(ss)mul.f hr0.x, hr0.x, hc4.x                                    \n"
		"(rpt5)nop                                                        \n"
		"exp2 hr0.x, hr0.x                                                \n"
		"(ss)mul.f hr0.y, hr0.x, hc1.x                                    \n"
		"add.f hr0.x, hr0.x, hc2.w                                        \n"
		"(rpt1)nop                                                        \n"
		"add.f hr0.y, hr0.y, hc2.x                                        \n"
		"add.f hr1.x, hr0.x, hr1.w                                        \n"
		"(rpt1)nop                                                        \n"
		"add.f hr0.w, hr0.y, hr1.z                                        \n"
		"mov.f16f16 hr0.z, hr0.y                                          \n"
		"end                                                              \n";

	static const GLfloat texcoords[] = {
			0.0f, 1.0f,
			1.0f, 1.0f,
			0.0f, 0.0f,
			1.0f, 0.0f,
	};

	static const GLfloat tex1_vertices[] = {
			-0.95, +0.45, -1.0,
			+0.45, +0.45, -1.0,
			-0.95, +0.95, -1.0,
			+0.45, +0.95, -1.0
	};

	static const GLfloat tex2_vertices[] = {
			-0.45, -0.95, -1.0,
			+0.95, -0.95, -1.0,
			-0.45, -0.45, -1.0,
			+0.95, -0.45, -1.0
	};

	const char *tex_vertex_shader_asm =
		"@out(r0.x)             gl_Position                               \n"
		"@attribute(r0.x-r0.w)  aPosition                                 \n"
		"@attribute(r1.x-r1.y)  aTexCoord                                 \n"
		"@varying(r1.x-r1.y)    vTexCoord                                 \n"
		"(sy)(ss)end                                                      \n";

	const char *tex_fragment_shader_asm =
		"@out(hr0.x)            gl_FragColor                              \n"
		"@varying(r1.x-r1.y)    vTexCoord                                 \n"
		"@sampler(0)            uTexture                                  \n"
		"(sy)(ss)(rpt1)bary.f (ei)r0.z, (r)0, r0.x                        \n"
		"(rpt5)nop                                                        \n"
		"sam (f16)(xyzw)hr0.x, r0.z, s#0, t#0                             \n"
		"end                                                              \n";

	uint32_t width = 0, height = 0;
	int i, n = 1;

	if (argc == 2)
		n = atoi(argv[1]);

	DEBUG_MSG("----------------------------------------------------------------");
	RD_START("fd-cat", "");

	state = fd_init();
	if (!state)
		return -1;

	surface = fd_surface_screen(state, &width, &height);
	if (!surface)
		return -1;

	/* load textures: */
	lolstex1 = fd_surface_new_fmt(state, lolstex1_image.width, lolstex1_image.height,
			RB_R8G8B8A8_UNORM);
	fd_surface_upload(lolstex1, lolstex1_image.pixel_data);

	lolstex2 = fd_surface_new_fmt(state, lolstex2_image.width, lolstex2_image.height,
			RB_R8G8B8A8_UNORM);
	fd_surface_upload(lolstex2, lolstex2_image.pixel_data);

	fd_enable(state, GL_CULL_FACE);
	fd_depth_func(state, GL_LEQUAL);
	fd_enable(state, GL_DEPTH_TEST);
	fd_tex_param(state, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	fd_tex_param(state, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	fd_blend_func(state, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	/* this needs to come after enabling depth test as enabling depth test
	 * effects bin sizes:
	 */
	fd_make_current(state, surface);

	/* construct the two shader programs: */
	cat_program = fd_program_new();
	fd_program_attach_asm(cat_program, FD_SHADER_VERTEX, cat_vertex_shader_asm);
	fd_program_attach_asm(cat_program, FD_SHADER_FRAGMENT, cat_fragment_shader_asm);

	tex_program = fd_program_new();
	fd_program_attach_asm(tex_program, FD_SHADER_VERTEX, tex_vertex_shader_asm);
	fd_program_attach_asm(tex_program, FD_SHADER_FRAGMENT, tex_fragment_shader_asm);

	fd_link(state);

	position_vbo = fd_attribute_bo_new(state, cat_position_sz, cat_position);
	normal_vbo = fd_attribute_bo_new(state, cat_normal_sz, cat_normal);

	for (i = 0; i < n; i++) {
		GLfloat aspect = (GLfloat)height / (GLfloat)width;
		ESMatrix modelview;
		ESMatrix projection;
		ESMatrix modelviewprojection;
		float normal[9];
		float scale = 1.3;

		esMatrixLoadIdentity(&modelview);
		esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
		esRotate(&modelview, 45.0f - (0.5f * i), 0.0f, 1.0f, 0.0f);

		esMatrixLoadIdentity(&projection);
		esFrustum(&projection,
				-scale, +scale,
				-scale * aspect, +scale * aspect,
				5.5f, 10.0f);

		esMatrixLoadIdentity(&modelviewprojection);
		esMatrixMultiply(&modelviewprojection, &modelview, &projection);

		normal[0] = modelview.m[0][0];
		normal[1] = modelview.m[0][1];
		normal[2] = modelview.m[0][2];
		normal[3] = modelview.m[1][0];
		normal[4] = modelview.m[1][1];
		normal[5] = modelview.m[1][2];
		normal[6] = modelview.m[2][0];
		normal[7] = modelview.m[2][1];
		normal[8] = modelview.m[2][2];

		fd_clear_color(state, (float[]){ 0.0, 0.0, 0.0, 1.0 });
		fd_clear(state, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		fd_attribute_bo(state, "normal",
				VFMT_FLOAT_32_32_32, normal_vbo);
		fd_attribute_bo(state, "position",
				VFMT_FLOAT_32_32_32, position_vbo);

		fd_uniform_attach(state, "ModelViewMatrix",
				4, 4, &modelview.m[0][0]);
		fd_uniform_attach(state, "ModelViewProjectionMatrix",
				4, 4,  &modelviewprojection.m[0][0]);
		fd_uniform_attach(state, "NormalMatrix",
				3, 3, normal);

		/* draw cat: */
		fd_disable(state, GL_BLEND);
		fd_set_program(state, cat_program);
		fd_draw_arrays(state, GL_TRIANGLES, 0, cat_vertices);

		/* setup to draw text (common to tex1 and tex2): */
		fd_enable(state, GL_BLEND);
		fd_set_program(state, tex_program);
		fd_attribute_pointer(state, "aTexCoord",
				VFMT_FLOAT_32_32, 4, texcoords);

		/* draw tex1: */
		fd_set_texture(state, "uTexture", lolstex1);
		fd_attribute_pointer(state, "aPosition",
				VFMT_FLOAT_32_32_32, 4, tex1_vertices);
		fd_draw_arrays(state, GL_TRIANGLE_STRIP, 0, 4);

		/* draw tex2: */
		fd_set_texture(state, "uTexture", lolstex2);
		fd_attribute_pointer(state, "aPosition",
				VFMT_FLOAT_32_32_32, 4, tex2_vertices);
		fd_draw_arrays(state, GL_TRIANGLE_STRIP, 0, 4);

		fd_swap_buffers(state);
	}
示例#13
0
void         Draw(GLContext	*_context)
{
	UserData      *_user = (UserData *)_context->userObject;
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//very important
	//draw earth
	_user->object->enableObject();

	_user->mSphere->bindVertexObject(0);
	_user->mSphere->bindTexCoordObject(1);
	_user->mSphere->bindNormalObject(2);
	//
	ESMatrix     mvMatrix;
	esMatrixLoadIdentity(&mvMatrix);
	esRotate(&mvMatrix, 17.7f, 1.0f, 0.0f, 0.0f);
	esRotate(&mvMatrix, _user->earthAngle, 0.0f, 1.0f, 0.0f);
	esTranslate(&mvMatrix, 0.0f, 0.0f, -5.0f);

	glUniformMatrix4fv(_user->mvLoc, 1, GL_FALSE, (float*)mvMatrix.m);//mv matrix

	ESMatrix    projMatrix, mvpMatrix;
	esMatrixLoadIdentity(&projMatrix);
	esFrustum(&projMatrix, -1.0f, 1.0f, -1.0f, 1.0f, 3.0f, 10.0f);
	esMatrixMultiply(&mvpMatrix, &mvMatrix, &projMatrix);
	glUniformMatrix4fv(_user->mvpLoc, 1, GL_FALSE, (float *)mvpMatrix.m);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, _user->earthMapId);
	glUniform1i(_user->baseMapLoc, 0);

	glUniform4fv(_user->lightColorLoc, 1, (float *)&GLVector4(0.9f,0.9f,1.0f,1.0f));
	_user->mSphere->drawShape();

//画出月球

	_user->object->enableObject();
	_user->mSphere->bindVertexObject(0);
	_user->mSphere->bindTexCoordObject(1);
	_user->mSphere->bindNormalObject(2);

	esMatrixLoadIdentity(&mvMatrix);
	esScale(&mvMatrix, 0.25f, 0.25f, 0.25f);
	esRotate(&mvMatrix, 17.7f, 1.0f, 0.0f, 0.0f);
	esRotate(&mvMatrix,_user->moonAngle,10.0f,1.0f,0.0f);//自传
	esTranslate(&mvMatrix, 2.0f, 0.0f, 0.0f);
	esRotate(&mvMatrix, _user->moonAngle, 0.0f, 1.0f, 0.0f);
	esTranslate(&mvMatrix, 0.0f, 0.0f, -5.0f);
	esMatrixMultiply(&mvMatrix, &mvMatrix, &_user->viewMatrix);

	glUniformMatrix4fv(_user->mvLoc, 1, GL_FALSE, (float*)mvMatrix.m);

	esMatrixLoadIdentity(&projMatrix);
	esFrustum(&projMatrix, -1.0f, 1.0f, -1.0f, 1.0f, 3.0f, 10.0f);
	esMatrixMultiply(&mvpMatrix, &mvMatrix, &projMatrix);
	glUniformMatrix4fv(_user->mvpLoc, 1, GL_FALSE, (float*)mvpMatrix.m);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, _user->moonMapId);
	glUniform1i(_user->baseMapLoc, 0);

	glUniform4fv(_user->lightColorLoc,1,(float *)&GLVector4(1.0f,1.0f,1.0f,1.0f));
	_user->mSphere->drawShape();

}
示例#14
0
文件: egl.c 项目: cmotc/lima
int
main(int argc, char *argv[])
{
	EGLDisplay display;
	EGLSurface surface;
	GLuint vertex_shader;
	GLuint fragment_shader;
	GLuint program;
	GLint ret;
	GLint width, height;
	GLuint texture;

	const char *vertex_shader_source =
		"uniform mat4 modelviewMatrix;\n"
		"uniform mat4 modelviewprojectionMatrix;\n"
		"uniform mat3 normalMatrix;\n"
		"\n"
		"attribute vec4 in_position;    \n"
		"attribute vec3 in_normal;      \n"
		"attribute vec2 in_coord;       \n"
		"\n"
		"vec4 lightSource = vec4(10.0, 20.0, 40.0, 0.0);\n"
		"                             \n"
		"varying vec4 vVaryingColor;  \n"
		"varying vec2 coord;          \n"
		"                             \n"
		"void main()                  \n"
		"{                            \n"
		"    gl_Position = modelviewprojectionMatrix * in_position;\n"
		"    vec3 vEyeNormal = normalMatrix * in_normal;\n"
		"    vec4 vPosition4 = modelviewMatrix * in_position;\n"
		"    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;\n"
		"    vec3 vLightDir = normalize(lightSource.xyz - vPosition3);\n"
		"    float diff = max(0.0, dot(vEyeNormal, vLightDir));\n"
		"    vVaryingColor = vec4(diff * vec3(1.0, 1.0, 1.0), 1.0);\n"
		"    coord = in_coord;        \n"
		"}                            \n";
	const char *fragment_shader_source =
		"precision mediump float;     \n"
		"                             \n"
		"varying vec4 vVaryingColor;  \n"
		"varying vec2 coord;          \n"
		"                             \n"
		"uniform sampler2D in_texture; \n"
		"                             \n"
		"void main()                  \n"
		"{                            \n"
		"    gl_FragColor = vVaryingColor * texture2D(in_texture, coord);\n"
		"}                            \n";

	buffer_size(&width, &height);

	printf("Buffer dimensions %dx%d\n", width, height);
	float aspect = (float) height / width;

	display = egl_display_init();
	surface = egl_surface_init(display, 2, width, height);

	glViewport(0, 0, width, height);

	glClearColor(0.5, 0.5, 0.5, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);

	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);

	vertex_shader = vertex_shader_compile(vertex_shader_source);
	fragment_shader = fragment_shader_compile(fragment_shader_source);

	program = glCreateProgram();
	if (!program) {
		printf("Error: failed to create program!\n");
		return -1;
	}

	glAttachShader(program, vertex_shader);
	glAttachShader(program, fragment_shader);

	glBindAttribLocation(program, 0, "in_position");
	glBindAttribLocation(program, 1, "in_normal");
	glBindAttribLocation(program, 2, "in_coord");

	glLinkProgram(program);

	glGetProgramiv(program, GL_LINK_STATUS, &ret);
	if (!ret) {
		char *log;

		printf("Error: program linking failed!:\n");
		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &ret);

		if (ret > 1) {
			log = malloc(ret);
			glGetProgramInfoLog(program, ret, NULL, log);
			printf("%s", log);
		}
		return -1;
	}

	glUseProgram(program);

	unsigned int vertices_buffer;
	glGenBuffers(1, &vertices_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, vertices_buffer);
	glBufferData(GL_ARRAY_BUFFER, 4 * 3 * COMPANION_VERTEX_COUNT,
		     companion_vertices, GL_STATIC_DRAW);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

	unsigned int normals_buffer;
	glGenBuffers(1, &normals_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, normals_buffer);
	glBufferData(GL_ARRAY_BUFFER, 4 * 3 * COMPANION_VERTEX_COUNT,
		     companion_normals, GL_STATIC_DRAW);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

	unsigned int texture_coordinates_buffer;
	glGenBuffers(1, &texture_coordinates_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, texture_coordinates_buffer);
	glBufferData(GL_ARRAY_BUFFER, 4 * 3 * COMPANION_VERTEX_COUNT,
		     companion_texture_coordinates, GL_STATIC_DRAW);
	glEnableVertexAttribArray(2);
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);

	unsigned int elements_buffer;
	glGenBuffers(1, &elements_buffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elements_buffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * COMPANION_INDEX_COUNT,
		     companion_triangles, GL_STATIC_DRAW);

	glActiveTexture(GL_TEXTURE0);

	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);

	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
		     COMPANION_TEXTURE_WIDTH, COMPANION_TEXTURE_HEIGHT, 0,
		     GL_RGB, GL_UNSIGNED_BYTE, companion_texture);

	GLint texture_loc = glGetUniformLocation(program, "in_texture");
	glUniform1i(texture_loc, 0); // 0 -> GL_TEXTURE0 in glActiveTexture

	ESMatrix modelview;
	esMatrixLoadIdentity(&modelview);
	esTranslate(&modelview, 0.0, 0.0, -4.0);
	esRotate(&modelview, -30.0, 1.0, 0.0, 0.0);
	esRotate(&modelview, -45.0, 0.0, 1.0, 0.0);

	ESMatrix projection;
	esMatrixLoadIdentity(&projection);
	esFrustum(&projection, -1.0, +1.0, -1.0 * aspect, +1.0 * aspect,
		  1.0, 10.0);

	ESMatrix modelviewprojection;
	esMatrixLoadIdentity(&modelviewprojection);
	esMatrixMultiply(&modelviewprojection, &modelview, &projection);

	float normal[9];
	normal[0] = modelview.m[0][0];
	normal[1] = modelview.m[0][1];
	normal[2] = modelview.m[0][2];
	normal[3] = modelview.m[1][0];
	normal[4] = modelview.m[1][1];
	normal[5] = modelview.m[1][2];
	normal[6] = modelview.m[2][0];
	normal[7] = modelview.m[2][1];
	normal[8] = modelview.m[2][2];

	GLint modelviewmatrix_handle =
		glGetUniformLocation(program, "modelviewMatrix");
	GLint modelviewprojectionmatrix_handle =
		glGetUniformLocation(program, "modelviewprojectionMatrix");
	GLint normalmatrix_handle =
		glGetUniformLocation(program, "normalMatrix");

	glUniformMatrix4fv(modelviewmatrix_handle,
			   1, GL_FALSE, &modelview.m[0][0]);
	glUniformMatrix4fv(modelviewprojectionmatrix_handle,
			   1, GL_FALSE, &modelviewprojection.m[0][0]);
	glUniformMatrix3fv(normalmatrix_handle, 1, GL_FALSE, normal);

	glDrawElements(GL_TRIANGLES, COMPANION_INDEX_COUNT,
		       GL_UNSIGNED_SHORT, NULL);

	eglSwapBuffers(display, surface);

	usleep(1000000);

	fflush(stdout);

	return 0;
}
示例#15
0
int main(int argc, char **argv)
{
    int rv;
    int width, height;
    int width_s, height_s;
    int padded_width, padded_height;
    int backbuffer = 0;
    int supersample_x = 2; // 1 or 2
    int supersample_y = 2; // 1 or 2
    int extra_ps_inputs = 0;
    
    fb_info fb;
    rv = fb_open(0, &fb);
    if(rv!=0)
    {
        exit(1);
    }
    width = fb.fb_var.xres;
    height = fb.fb_var.yres;
    width_s = width * supersample_x;
    height_s = height * supersample_y;
    padded_width = etna_align_up(width_s, 64);
    padded_height = etna_align_up(height_s, 64);
    extra_ps_inputs = (supersample_x > 1 || supersample_y > 1); // in case of supersample, there is an extra input to PS

    printf("padded_width %i padded_height %i\n", padded_width, padded_height);
    rv = viv_open();
    if(rv!=0)
    {
        fprintf(stderr, "Error opening device\n");
        exit(1);
    }
    printf("Succesfully opened device\n");

    etna_vidmem *rt = 0; /* main render target */
    etna_vidmem *rt_ts = 0; /* tile status for main render target */
    etna_vidmem *z = 0; /* depth for main render target */
    etna_vidmem *z_ts = 0; /* depth ts for main render target */
    etna_vidmem *vtx = 0; /* vertex buffer */
    etna_vidmem *idx = 0; /* index buffer */
    etna_vidmem *aux_rt = 0; /* auxilary render target */
    etna_vidmem *aux_rt_ts = 0; /* tile status for auxilary render target */
    etna_vidmem *tex = 0; /* texture */
    etna_vidmem *bmp = 0; /* bitmap */

    /* TODO: anti aliasing (doubles width/height) */
    size_t rt_size = padded_width * padded_height * 4;
    size_t rt_ts_size = etna_align_up((padded_width * padded_height * 4)/0x100, 0x100);
    size_t z_size = padded_width * padded_height * 2;
    size_t z_ts_size = etna_align_up((padded_width * padded_height * 2)/0x100, 0x100);
    size_t bmp_size = width * height * 4;

    if(etna_vidmem_alloc_linear(&rt, rt_size, gcvSURF_RENDER_TARGET, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&rt_ts, rt_ts_size, gcvSURF_TILE_STATUS, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&z, z_size, gcvSURF_DEPTH, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&z_ts, z_ts_size, gcvSURF_TILE_STATUS, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&vtx, VERTEX_BUFFER_SIZE, gcvSURF_VERTEX, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&idx, INDEX_BUFFER_SIZE, gcvSURF_INDEX, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&aux_rt, 0x4000, gcvSURF_RENDER_TARGET, gcvPOOL_SYSTEM, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&aux_rt_ts, 0x100, gcvSURF_TILE_STATUS, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&tex, 0x100000, gcvSURF_TEXTURE, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&bmp, bmp_size, gcvSURF_BITMAP, gcvPOOL_DEFAULT, true)!=ETNA_OK
       )
    {
        fprintf(stderr, "Error allocating video memory\n");
        exit(1);
    }

    /* Phew, now we got all the memory we need.
     * Write interleaved attribute vertex stream.
     * Unlike the GL example we only do this once, not every time glDrawArrays is called, the same would be accomplished
     * from GL by using a vertex buffer object.
     */
    memset(vtx->logical, 0, 0x5ef80);
#ifndef INDEXED
    printf("Interleaving vertices...\n");
    float *vertices_array = companion_vertices_array();
    float *texture_coordinates_array =
            companion_texture_coordinates_array();
    float *normals_array = companion_normals_array();
    assert(COMPANION_ARRAY_COUNT*(3+3+2)*sizeof(float) < VERTEX_BUFFER_SIZE);
    for(int vert=0; vert<COMPANION_ARRAY_COUNT; ++vert)
    {
        int dest_idx = vert * (3 + 3 + 2);
        for(int comp=0; comp<3; ++comp)
            ((float*)vtx->logical)[dest_idx+comp+0] = vertices_array[vert*3 + comp]; /* 0 */
        for(int comp=0; comp<3; ++comp)
            ((float*)vtx->logical)[dest_idx+comp+3] = normals_array[vert*3 + comp]; /* 1 */
        for(int comp=0; comp<2; ++comp)
            ((float*)vtx->logical)[dest_idx+comp+6] = texture_coordinates_array[vert*2 + comp]; /* 2 */
    }
#else
    printf("Interleaving vertices and copying index buffer...\n");
    assert(COMPANION_VERTEX_COUNT*(3+3+2)*sizeof(float) < VERTEX_BUFFER_SIZE);
    for(int vert=0; vert<COMPANION_VERTEX_COUNT; ++vert)
    {
        int dest_idx = vert * (3 + 3 + 2);
        for(int comp=0; comp<3; ++comp)
            ((float*)vtx->logical)[dest_idx+comp+0] = companion_vertices[vert][comp]; /* 0 */
        for(int comp=0; comp<3; ++comp)
            ((float*)vtx->logical)[dest_idx+comp+3] = companion_normals[vert][comp]; /* 1 */
        for(int comp=0; comp<2; ++comp)
            ((float*)vtx->logical)[dest_idx+comp+6] = companion_texture_coordinates[vert][comp]; /* 2 */
    }
    assert(COMPANION_TRIANGLE_COUNT*3*sizeof(unsigned short) < INDEX_BUFFER_SIZE);
    memcpy(idx->logical, &companion_triangles[0][0], COMPANION_TRIANGLE_COUNT*3*sizeof(unsigned short));
#endif
    /* Fill in texture (convert from RGB linear to tiled) */
#define TILE_WIDTH (4)
#define TILE_HEIGHT (4)
#define TILE_WORDS (TILE_WIDTH*TILE_HEIGHT)
    unsigned ytiles = COMPANION_TEXTURE_HEIGHT / TILE_HEIGHT;
    unsigned xtiles = COMPANION_TEXTURE_WIDTH / TILE_WIDTH;
    unsigned dst_stride = xtiles * TILE_WORDS;

    for(unsigned ty=0; ty<ytiles; ++ty)
    {
        for(unsigned tx=0; tx<xtiles; ++tx)
        {
            unsigned ofs = ty * dst_stride + tx * TILE_WORDS;
            for(unsigned y=0; y<TILE_HEIGHT; ++y)
            {
                for(unsigned x=0; x<TILE_WIDTH; ++x)
                {
                    unsigned srcy = ty*TILE_HEIGHT + y;
                    unsigned srcx = tx*TILE_WIDTH + x;
                    unsigned src_ofs = (srcy*COMPANION_TEXTURE_WIDTH+srcx)*3;
                    unsigned r,g,b,a;
#ifndef TEST_PATTERN /* actual texture */
                    r = ((uint8_t*)companion_texture)[src_ofs+0];
                    g = ((uint8_t*)companion_texture)[src_ofs+1];
                    b = ((uint8_t*)companion_texture)[src_ofs+2];
#else /* test pattern */
                    r = srcx; g = srcy; b = 0;
#endif
                    a = 255;

                    ((uint32_t*)tex->logical)[ofs] = ((a&0xFF) << 24) | ((b&0xFF) << 16) | ((g&0xFF) << 8) | (r&0xFF);
                    ofs += 1;
                }
            }
        }
    }

    etna_ctx *ctx = 0;
    if(etna_create(&ctx) != ETNA_OK)
    {
        printf("Unable to create context\n");
        exit(1);
    }

    for(int frame=0; frame<1000; ++frame)
    {
        printf("*** FRAME %i ****\n", frame);
        /* XXX part of this can be put outside the loop, but until we have usable context management
         * this is safest.
         */
        etna_set_state(ctx, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x1);
        etna_set_state(ctx, VIVS_RA_CONTROL, 0x1);
        etna_set_state(ctx, VIVS_PA_W_CLIP_LIMIT, 0x34000001);
        etna_set_state(ctx, VIVS_PA_SYSTEM_MODE, 0x11);
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_BIT(VIVS_PA_CONFIG_UNK22, 0));
        etna_set_state(ctx, VIVS_SE_CONFIG, 0x0);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);

        etna_set_state(ctx, VIVS_PE_ALPHA_CONFIG,
                ETNA_MASKED_BIT(VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_COLOR, 0) &
                ETNA_MASKED_BIT(VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_ALPHA, 0) &
                ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_SRC_FUNC_COLOR, BLEND_FUNC_ONE) &
                ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_SRC_FUNC_ALPHA, BLEND_FUNC_ONE) &
                ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_DST_FUNC_COLOR, BLEND_FUNC_ZERO) &
                ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_DST_FUNC_ALPHA, BLEND_FUNC_ZERO) &
                ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_EQ_COLOR, BLEND_EQ_ADD) &
                ETNA_MASKED(VIVS_PE_ALPHA_CONFIG_EQ_ALPHA, BLEND_EQ_ADD));
        etna_set_state(ctx, VIVS_PE_ALPHA_BLEND_COLOR, 
                VIVS_PE_ALPHA_BLEND_COLOR_B(0) | 
                VIVS_PE_ALPHA_BLEND_COLOR_G(0) | 
                VIVS_PE_ALPHA_BLEND_COLOR_R(0) | 
                VIVS_PE_ALPHA_BLEND_COLOR_A(0));
        etna_set_state(ctx, VIVS_PE_ALPHA_OP, ETNA_MASKED_BIT(VIVS_PE_ALPHA_OP_ALPHA_TEST, 0));
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_INL(VIVS_PA_CONFIG_CULL_FACE_MODE, CCW));
        etna_set_state(ctx, VIVS_PE_STENCIL_CONFIG, ETNA_MASKED(VIVS_PE_STENCIL_CONFIG_REF_FRONT, 0) &
                                                    ETNA_MASKED(VIVS_PE_STENCIL_CONFIG_MASK_FRONT, 0xff) & 
                                                    ETNA_MASKED(VIVS_PE_STENCIL_CONFIG_WRITE_MASK, 0xff) &
                                                    ETNA_MASKED_INL(VIVS_PE_STENCIL_CONFIG_MODE, DISABLED));
        etna_set_state(ctx, VIVS_PE_STENCIL_OP, ETNA_MASKED(VIVS_PE_STENCIL_OP_FUNC_FRONT, COMPARE_FUNC_ALWAYS) &
                                                ETNA_MASKED(VIVS_PE_STENCIL_OP_FUNC_BACK, COMPARE_FUNC_ALWAYS) &
                                                ETNA_MASKED(VIVS_PE_STENCIL_OP_FAIL_FRONT, STENCIL_OP_KEEP) & 
                                                ETNA_MASKED(VIVS_PE_STENCIL_OP_FAIL_BACK, STENCIL_OP_KEEP) & 
                                                ETNA_MASKED(VIVS_PE_STENCIL_OP_DEPTH_FAIL_FRONT, STENCIL_OP_KEEP) & 
                                                ETNA_MASKED(VIVS_PE_STENCIL_OP_DEPTH_FAIL_BACK, STENCIL_OP_KEEP) &
                                                ETNA_MASKED(VIVS_PE_STENCIL_OP_PASS_FRONT, STENCIL_OP_KEEP) &
                                                ETNA_MASKED(VIVS_PE_STENCIL_OP_PASS_BACK, STENCIL_OP_KEEP));

        etna_set_state(ctx, VIVS_SE_DEPTH_SCALE, 0x0);
        etna_set_state(ctx, VIVS_SE_DEPTH_BIAS, 0x0);
        
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_INL(VIVS_PA_CONFIG_FILL_MODE, SOLID) & 
                                            ETNA_MASKED_INL(VIVS_PA_CONFIG_SHADE_MODEL, SMOOTH));
        
        etna_set_state(ctx, VIVS_PE_COLOR_FORMAT, 
                ETNA_MASKED_BIT(VIVS_PE_COLOR_FORMAT_PARTIAL, 0) & 
                ETNA_MASKED(VIVS_PE_COLOR_FORMAT_COMPONENTS, 0xf) &
                ETNA_MASKED(VIVS_PE_COLOR_FORMAT_FORMAT, RS_FORMAT_X8R8G8B8) &
                ETNA_MASKED_BIT(VIVS_PE_COLOR_FORMAT_SUPER_TILED, 1));

        etna_set_state(ctx, VIVS_PE_COLOR_ADDR, rt->address);
        etna_set_state(ctx, VIVS_PE_COLOR_STRIDE, padded_width * 4); 

        uint32_t ts_msaa_config;
        if(supersample_x == 2 && supersample_y == 2)
        {
            // 4X MSAA
            etna_set_state(ctx, VIVS_GL_MULTI_SAMPLE_CONFIG, 
                    ETNA_MASKED_INL(VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES, 4X) &
                    ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES, 0xf) &
                    ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12, 0x0) &
                    ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16, 0x0)
                    ); 
            etna_set_state(ctx, VIVS_RA_MULTISAMPLE_UNK00E04, 0x0);
            etna_set_state(ctx, VIVS_RA_MULTISAMPLE_UNK00E10(2), 0xaaa22a22);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(8), 0x262a2288);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(9), 0x886688a2);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(10), 0x888866aa);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(11), 0x668888a6);
            etna_set_state(ctx, VIVS_RA_MULTISAMPLE_UNK00E10(1), 0xe6ae622a);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(4), 0x46622a88);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(5), 0x888888ae);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(6), 0x888888e6);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(7), 0x888888ca);
            etna_set_state(ctx, VIVS_RA_MULTISAMPLE_UNK00E10(0), 0xeaa26e26);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(0), 0x4a6e2688);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(1), 0x888888a2);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(2), 0x888888ea);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(3), 0x888888c6);
            ts_msaa_config = VIVS_TS_MEM_CONFIG_MSAA | VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A8R8G8B8;
        } else if(supersample_x == 2 && supersample_y == 1)
        {
            // 2X MSAA
            etna_set_state(ctx, VIVS_GL_MULTI_SAMPLE_CONFIG, 
                    ETNA_MASKED_INL(VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES, 2X) &
                    ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES, 0xf) &
                    ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12, 0x0) &
                    ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16, 0x0)
                    ); 
            etna_set_state(ctx, VIVS_RA_MULTISAMPLE_UNK00E04, 0x0);
            etna_set_state(ctx, VIVS_RA_MULTISAMPLE_UNK00E10(0), 0xaa22);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(0), 0x66aa2288);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(1), 0x88558800);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(2), 0x88881100);
            etna_set_state(ctx, VIVS_RA_CENTROID_TABLE(3), 0x33888800);
            ts_msaa_config = VIVS_TS_MEM_CONFIG_MSAA | VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A8R8G8B8;
        } else { // No multisampling
            etna_set_state(ctx, VIVS_GL_MULTI_SAMPLE_CONFIG, 
                    ETNA_MASKED_INL(VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES, NONE) &
                    ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES, 0xf) &
                    ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12, 0x0) &
                    ETNA_MASKED(VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16, 0x0)
                    ); 
            ts_msaa_config = 0;
        }

        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);

        etna_set_state(ctx, VIVS_TS_COLOR_CLEAR_VALUE, 0);
        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address);
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address);

        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, 
                ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_WRITE_ENABLE, 0) &
                ETNA_MASKED_INL(VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT, D16) &
                ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_SUPER_TILED, 1) &
                ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_EARLY_Z, 1));
        etna_set_state(ctx, VIVS_PE_DEPTH_ADDR, z->address);
        etna_set_state(ctx, VIVS_PE_DEPTH_STRIDE, padded_width * 2);
        etna_set_state(ctx, VIVS_PE_HDEPTH_CONTROL, VIVS_PE_HDEPTH_CONTROL_FORMAT_DISABLED);
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_NORMALIZE, 65535.0);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_DEPTH);

        etna_set_state(ctx, VIVS_TS_DEPTH_CLEAR_VALUE, 0xffffffff);
        etna_set_state(ctx, VIVS_TS_DEPTH_STATUS_BASE, z_ts->address);
        etna_set_state(ctx, VIVS_TS_DEPTH_SURFACE_BASE, z->address);
        etna_set_state(ctx, VIVS_TS_MEM_CONFIG, 
                VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR |
                VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR |
                VIVS_TS_MEM_CONFIG_DEPTH_16BPP | 
                VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION | 
                ts_msaa_config);

#ifdef EXTRA_DELAYS
        /* Warm up RS on aux render target (is this needed?) */
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_warm_up_rs(ctx, aux_rt->address, aux_rt_ts->address);

        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts_physical);
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt_physical);

        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_warm_up_rs(ctx, aux_rt_physical, aux_rt_ts_physical);

        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts_physical);
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt_physical);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
       
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_warm_up_rs(ctx, aux_rt_physical, aux_rt_ts_physical);
        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts_physical);
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt_physical);
#endif
        /* sync rasterizer to pixel engine after changes to PE config */
        etna_stall(ctx, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE);

        /* Set up the resolve to clear tile status for main render target and depth
         * Regard the TS as an image of width 16 with 4 bytes per pixel (64 bytes per row)
         * */
        etna_set_state(ctx, VIVS_RS_CONFIG,
                VIVS_RS_CONFIG_SOURCE_FORMAT(RS_FORMAT_A8R8G8B8) |
                VIVS_RS_CONFIG_DEST_FORMAT(RS_FORMAT_A8R8G8B8)
                );
        etna_set_state_multi(ctx, VIVS_RS_DITHER(0), 2, (uint32_t[]){0xffffffff, 0xffffffff});
        etna_set_state(ctx, VIVS_RS_FILL_VALUE(0), 0x55555555);
        etna_set_state(ctx, VIVS_RS_CLEAR_CONTROL, 
                VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1 |
                (0xffff << VIVS_RS_CLEAR_CONTROL_BITS__SHIFT));
        etna_set_state(ctx, VIVS_RS_EXTRA_CONFIG, 0);
        /*    clear color ts */
        etna_set_state(ctx, VIVS_RS_DEST_ADDR, rt_ts->address);
        etna_set_state(ctx, VIVS_RS_DEST_STRIDE, 0x40);
        etna_set_state(ctx, VIVS_RS_WINDOW_SIZE, 
                ((rt_ts_size/0x40) << VIVS_RS_WINDOW_SIZE_HEIGHT__SHIFT) |
                (16 << VIVS_RS_WINDOW_SIZE_WIDTH__SHIFT));
        etna_set_state(ctx, VIVS_RS_KICKER, 0xbeebbeeb);
        /*    clear depth ts */
        etna_set_state(ctx, VIVS_RS_DEST_ADDR, z_ts->address);
        etna_set_state(ctx, VIVS_RS_DEST_STRIDE, 0x40);
        etna_set_state(ctx, VIVS_RS_WINDOW_SIZE, 
                ((z_ts_size/0x40) << VIVS_RS_WINDOW_SIZE_HEIGHT__SHIFT) |
                (16 << VIVS_RS_WINDOW_SIZE_WIDTH__SHIFT));
        etna_set_state(ctx, VIVS_RS_KICKER, 0xbeebbeeb);
        /** Done */
        
        etna_set_state(ctx, VIVS_TS_COLOR_CLEAR_VALUE, 0xff7f7f7f);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);

        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address);
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);

        /* depth setup */
        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_WRITE_ENABLE, 1) & 
                                                  ETNA_MASKED(VIVS_PE_DEPTH_CONFIG_DEPTH_FUNC, COMPARE_FUNC_LESS) & 
                                                  ETNA_MASKED_INL(VIVS_PE_DEPTH_CONFIG_DEPTH_MODE, Z) &
                                                  ETNA_MASKED_BIT(VIVS_PE_DEPTH_CONFIG_ONLY_DEPTH, 0));
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_NEAR, 0.0);
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_FAR, 1.0);
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_NORMALIZE, 65535.0);

        /* set up primitive assembly and setup engine */
        etna_set_state_f32(ctx, VIVS_PA_VIEWPORT_OFFSET_Z, 0.0);
        etna_set_state_f32(ctx, VIVS_PA_VIEWPORT_SCALE_Z, 1.0);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_OFFSET_X, width << 15);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_OFFSET_Y, height << 15);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_SCALE_X, width << 15);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_SCALE_Y, height << 15);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_LEFT, 0);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_TOP, 0);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_RIGHT, (width << 16) | 5);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_BOTTOM, (height << 16) | 5);

        /* set up texture unit */
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_TEXTURE);
        etna_set_state(ctx, VIVS_TE_SAMPLER_SIZE(0), 
                VIVS_TE_SAMPLER_SIZE_WIDTH(512)|VIVS_TE_SAMPLER_SIZE_HEIGHT(512));
        etna_set_state(ctx, VIVS_TE_SAMPLER_LOG_SIZE(0), 
                VIVS_TE_SAMPLER_LOG_SIZE_WIDTH(9<<5) |
                VIVS_TE_SAMPLER_LOG_SIZE_HEIGHT(9<<5));
        etna_set_state(ctx, VIVS_TE_SAMPLER_LOD_ADDR(0,0), tex->address);
        etna_set_state(ctx, VIVS_TE_SAMPLER_CONFIG0(0), 
                VIVS_TE_SAMPLER_CONFIG0_TYPE(TEXTURE_TYPE_2D)|
                VIVS_TE_SAMPLER_CONFIG0_UWRAP(TEXTURE_WRAPMODE_CLAMP_TO_EDGE)|
                VIVS_TE_SAMPLER_CONFIG0_VWRAP(TEXTURE_WRAPMODE_CLAMP_TO_EDGE)|
                VIVS_TE_SAMPLER_CONFIG0_MIN(TEXTURE_FILTER_LINEAR)|
                VIVS_TE_SAMPLER_CONFIG0_MIP(TEXTURE_FILTER_NONE)|
                VIVS_TE_SAMPLER_CONFIG0_MAG(TEXTURE_FILTER_LINEAR)|
                VIVS_TE_SAMPLER_CONFIG0_FORMAT(TEXTURE_FORMAT_X8R8G8B8));
        etna_set_state(ctx, VIVS_TE_SAMPLER_LOD_CONFIG(0), 0x00000000); /*   TE.SAMPLER[0].LOD_CONFIG := 0x0 */

        /* shader setup */
        etna_set_state(ctx, VIVS_VS_END_PC, vs_size/16);
        etna_set_state_multi(ctx, VIVS_VS_INPUT_COUNT, 3, (uint32_t[]){
                /* VIVS_VS_INPUT_COUNT */ VIVS_VS_INPUT_COUNT_UNK8(1) | VIVS_VS_INPUT_COUNT_COUNT(3),
                /* VIVS_VS_TEMP_REGISTER_CONTROL */ VIVS_VS_TEMP_REGISTER_CONTROL_NUM_TEMPS(6),
                /* VIVS_VS_OUTPUT(0) */ 0x10004});
        etna_set_state(ctx, VIVS_VS_START_PC, 0x0);
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(45), 0.5); /* u11.y */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(44), 1.0); /* u11.x */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(27), 0.0); /* u6.w */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(23), 20.0); /* u5.w */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(19), 2.0); /* u4.w */

        /* Now load the shader itself */
        etna_set_state_multi(ctx, VIVS_VS_INST_MEM(0), vs_size/4, vs);
        etna_set_state(ctx, VIVS_RA_CONTROL, 0x3);
        etna_set_state_f32(ctx, VIVS_PS_UNIFORMS(0), 1.0); /* u0.x */
        etna_set_state_multi(ctx, VIVS_PS_END_PC, 2, (uint32_t[]){
                /* VIVS_PS_END_PC */ ps_size/16,
                /* VIVS_PS_OUTPUT_REG */ 0x1});
        etna_set_state(ctx, VIVS_PS_START_PC, 0x0);
        etna_set_state(ctx, VIVS_PA_ATTRIBUTE_ELEMENT_COUNT, 0x200);
        etna_set_state(ctx, VIVS_PA_SHADER_ATTRIBUTES(0), 0x200);
        etna_set_state(ctx, VIVS_PA_SHADER_ATTRIBUTES(1), 0x200);
        etna_set_state(ctx, VIVS_GL_VARYING_NUM_COMPONENTS,  
                VIVS_GL_VARYING_NUM_COMPONENTS_VAR0(4)| /* position */
                VIVS_GL_VARYING_NUM_COMPONENTS_VAR1(2)  /* texture coordinate */
                );
        etna_set_state_multi(ctx, VIVS_GL_VARYING_COMPONENT_USE(0), 2, (uint32_t[]){
                VIVS_GL_VARYING_COMPONENT_USE_COMP0(VARYING_COMPONENT_USE_USED) |
                VIVS_GL_VARYING_COMPONENT_USE_COMP1(VARYING_COMPONENT_USE_USED) |
                VIVS_GL_VARYING_COMPONENT_USE_COMP2(VARYING_COMPONENT_USE_USED) |
                VIVS_GL_VARYING_COMPONENT_USE_COMP3(VARYING_COMPONENT_USE_USED) |
                VIVS_GL_VARYING_COMPONENT_USE_COMP4(VARYING_COMPONENT_USE_USED) |
                VIVS_GL_VARYING_COMPONENT_USE_COMP5(VARYING_COMPONENT_USE_USED)
                , 0
                });
        etna_set_state_multi(ctx, VIVS_PS_INST_MEM(0), ps_size/4, ps);
        etna_set_state(ctx, VIVS_PS_INPUT_COUNT, 
                VIVS_PS_INPUT_COUNT_UNK8(31)| VIVS_PS_INPUT_COUNT_COUNT(3 + extra_ps_inputs));
        etna_set_state(ctx, VIVS_PS_TEMP_REGISTER_CONTROL, 
                VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(3 + extra_ps_inputs));
        etna_set_state(ctx, VIVS_PS_CONTROL, VIVS_PS_CONTROL_UNK1);
        etna_set_state(ctx, VIVS_GL_VARYING_TOTAL_COMPONENTS,
                VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(6)); /* 4+2=6 total varying components */
        etna_set_state(ctx, VIVS_VS_LOAD_BALANCING, 0xf3f0542); /* depends on number of inputs/outputs/varyings? XXX how exactly */
        etna_set_state(ctx, VIVS_VS_OUTPUT_COUNT, 3);
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_BIT(VIVS_PA_CONFIG_POINT_SIZE_ENABLE, 0));
        
        /*   Compute transform matrices in the same way as cube egl demo */ 
        ESMatrix modelview;
        esMatrixLoadIdentity(&modelview);
        esTranslate(&modelview, 0.0f, 0.0f, -9.0f);
        esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f);
        esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f);
        esRotate(&modelview, frame*0.5f, 0.0f, 0.0f, 1.0f);
	esScale(&modelview, 0.475f, 0.475f, 0.475f);
        GLfloat aspect = (GLfloat)(height) / (GLfloat)(width);
        ESMatrix projection;
        esMatrixLoadIdentity(&projection);
        esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f);
        ESMatrix modelviewprojection;
        esMatrixLoadIdentity(&modelviewprojection);
        esMatrixMultiply(&modelviewprojection, &modelview, &projection);
        ESMatrix inverse, normal; /* compute inverse transpose normal transformation matrix */
        esMatrixInverse3x3(&inverse, &modelview);
        esMatrixTranspose(&normal, &inverse);
        
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(0), 16, (uint32_t*)&modelviewprojection.m[0][0]);
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(16), 3, (uint32_t*)&normal.m[0][0]); /* u4.xyz */
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(20), 3, (uint32_t*)&normal.m[1][0]); /* u5.xyz */
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(24), 3, (uint32_t*)&normal.m[2][0]); /* u6.xyz */
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(28), 16, (uint32_t*)&modelview.m[0][0]);
#ifdef INDEXED
        etna_set_state(ctx, VIVS_FE_INDEX_STREAM_BASE_ADDR, idx->address);
        etna_set_state(ctx, VIVS_FE_INDEX_STREAM_CONTROL, VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT);
#endif
        etna_set_state(ctx, VIVS_FE_VERTEX_STREAM_BASE_ADDR, vtx->address);
        etna_set_state(ctx, VIVS_FE_VERTEX_STREAM_CONTROL, 
                VIVS_FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE((3 + 3 + 2)*4));
        etna_set_state(ctx, VIVS_FE_VERTEX_ELEMENT_CONFIG(0), 
                VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT |
                (ENDIAN_MODE_NO_SWAP << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(0) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM_3 |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_START(0x0) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_END(0xc));
        etna_set_state(ctx, VIVS_FE_VERTEX_ELEMENT_CONFIG(1), 
                VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT |
                (ENDIAN_MODE_NO_SWAP << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(0) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM_3 |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_START(0xc) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_END(0x18));
        etna_set_state(ctx, VIVS_FE_VERTEX_ELEMENT_CONFIG(2), 
                VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT |
                (ENDIAN_MODE_NO_SWAP << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NONCONSECUTIVE |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(0) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM_2 |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_START(0x18) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_END(0x20));
        etna_set_state(ctx, VIVS_VS_INPUT(0), 0x20100);
        etna_set_state(ctx, VIVS_PA_CONFIG, ETNA_MASKED_BIT(VIVS_PA_CONFIG_POINT_SPRITE_ENABLE, 0));

#ifdef INDEXED
        etna_draw_indexed_primitives(ctx, PRIMITIVE_TYPE_TRIANGLES, 0, COMPANION_TRIANGLE_COUNT, 0);
#else
        etna_draw_primitives(ctx, PRIMITIVE_TYPE_TRIANGLES, 0, COMPANION_TRIANGLE_COUNT);
#endif
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
#ifdef EXTRA_DELAYS
        etna_flush(ctx);
#endif
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_set_state(ctx, VIVS_RS_CONFIG,
                VIVS_RS_CONFIG_SOURCE_FORMAT(RS_FORMAT_A8R8G8B8) |
                VIVS_RS_CONFIG_SOURCE_TILED |
                VIVS_RS_CONFIG_DEST_FORMAT(RS_FORMAT_A8R8G8B8) |
                VIVS_RS_CONFIG_DEST_TILED);
        etna_set_state(ctx, VIVS_RS_SOURCE_STRIDE, (padded_width * 4 * 4) | VIVS_RS_SOURCE_STRIDE_TILING);
        etna_set_state(ctx, VIVS_RS_DEST_STRIDE, (padded_width * 4 * 4) | VIVS_RS_DEST_STRIDE_TILING);
        etna_set_state(ctx, VIVS_RS_DITHER(0), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_DITHER(1), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_CLEAR_CONTROL, VIVS_RS_CLEAR_CONTROL_MODE_DISABLED);
        etna_set_state(ctx, VIVS_RS_EXTRA_CONFIG, 0); 
        etna_set_state(ctx, VIVS_RS_SOURCE_ADDR, rt->address);
        etna_set_state(ctx, VIVS_RS_DEST_ADDR, rt->address);
        etna_set_state(ctx, VIVS_RS_WINDOW_SIZE, 
                VIVS_RS_WINDOW_SIZE_HEIGHT(padded_height) |
                VIVS_RS_WINDOW_SIZE_WIDTH(padded_width));
        etna_set_state(ctx, VIVS_RS_KICKER, 0xbeebbeeb);
#ifdef EXTRA_DELAYS
        etna_flush(ctx);

        etna_warm_up_rs(ctx, aux_rt->address, aux_rt_ts->address);
#endif

        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address);
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);
        etna_set_state(ctx, VIVS_TS_MEM_CONFIG, 
                VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR |
                VIVS_TS_MEM_CONFIG_DEPTH_16BPP | 
                VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);

        /* Wait for pixel engine to finish */
#ifdef EXTRA_DELAYS
        etna_finish(ctx);
#else
        etna_stall(ctx, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
#endif

        /* Copy result to framebuffer */
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_set_state(ctx, VIVS_RS_CONFIG,
                VIVS_RS_CONFIG_SOURCE_FORMAT(RS_FORMAT_A8R8G8B8) |
                VIVS_RS_CONFIG_SOURCE_TILED |
                ((supersample_x>1)?VIVS_RS_CONFIG_DOWNSAMPLE_X:0) |
                ((supersample_y>1)?VIVS_RS_CONFIG_DOWNSAMPLE_Y:0) |
                VIVS_RS_CONFIG_DEST_FORMAT(RS_FORMAT_A8R8G8B8) |
                VIVS_RS_CONFIG_SWAP_RB);
        etna_set_state(ctx, VIVS_RS_SOURCE_STRIDE, (padded_width * 4 * 4) | VIVS_RS_SOURCE_STRIDE_TILING);
        etna_set_state(ctx, VIVS_RS_DEST_STRIDE, fb.fb_fix.line_length);
        etna_set_state(ctx, VIVS_RS_DITHER(0), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_DITHER(1), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_CLEAR_CONTROL, VIVS_RS_CLEAR_CONTROL_MODE_DISABLED);
        etna_set_state(ctx, VIVS_RS_EXTRA_CONFIG, 0);
        etna_set_state(ctx, VIVS_RS_SOURCE_ADDR, rt->address);
        etna_set_state(ctx, VIVS_RS_DEST_ADDR, fb.physical[backbuffer]);
        etna_set_state(ctx, VIVS_RS_WINDOW_SIZE, 
                VIVS_RS_WINDOW_SIZE_HEIGHT(height * supersample_y) |
                VIVS_RS_WINDOW_SIZE_WIDTH(width * supersample_x));
        etna_set_state(ctx, VIVS_RS_KICKER, 0xbeebbeeb);
        etna_finish(ctx);

        /* switch buffers */
        fb_set_buffer(&fb, backbuffer);
        backbuffer = 1-backbuffer;
    }
    
    etna_free(ctx);
    viv_close();
    return 0;
}
示例#16
0
static void engine_draw_frame(struct engine* engine) 
{
    if (engine->display == NULL)
    {
        // No display.
        return;
    }

	ESMatrix perspective;
	ESMatrix modelview;
	float    aspect;
	ESMatrix lookAtMatrix;

	static float EyePos[4] = {0.0f,2.0f,3.2f,0.0f};
	static float LightPos[4] = {4.0f,0.0f,3.2f,0.0f};
	static int LightPosDirection = 1.0f;  //1 is up, -1 is down

	//do some movement of the light in the phong shader
	LightPos[1]+= 0.25f * LightPosDirection;
	if(LightPos[1]>20.0f ||  LightPos[1] < -20.0f)
		LightPosDirection*=-1;

	//here we go
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
	glFrontFace(GL_CW);

	glEnable(GL_DEPTH_TEST);
	glClearDepthf(1.0f);
	glClear(  GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glDepthMask(GL_FALSE);
	//set up the perspective and frustum, etc
	esMatrixLoadIdentity( &perspective );

	if(ContextHeight > ContextWidth) 
	{
		aspect = ContextHeight / ContextWidth;
		esFrustum(&perspective, 1, -1.0f, -aspect, aspect, 0.1f, 50.0f);
	}
	else 
	{
		aspect = ContextWidth/ContextHeight;
		esFrustum(&perspective, -aspect, aspect, 1, -1.0f, 0.1f, 50.0f);
	}

	//SKYBOX
	esMatrixLoadIdentity( &modelview );
	esMatrixLoadIdentity(&lookAtMatrix);
	esLookAt(&lookAtMatrix,0,0,0,0,0,1,0,1,0);

		esRotate(&modelview,-RotateY,0,1,0);
		esRotate(&modelview, -RotateX, 1, 0,0);
		esTranslate(&modelview, 0,0,-1);

		esMatrixMultiply(&modelview,&modelview,&lookAtMatrix);
		esMatrixMultiply( &MVPMatrix,&modelview,&perspective );

		glUseProgram(TexPassThruShader.ID);

		glActiveTexture(GL_TEXTURE0);
		glUniform1i(TexPassThruSampler,0);

		glUniformMatrix4fv(TexPassThruMVPMatrixUniform, 1, GL_FALSE, (GLfloat*) &MVPMatrix.m[0][0] );

		//FRONT
			glBindTexture(GL_TEXTURE_2D,CubeSkyBox.Front.Tex.ID[0]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		 	//vert
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Front.VBOVertId);
			glEnableVertexAttribArray(TexPassThruPositionAttributes);
			glVertexAttribPointer(TexPassThruPositionAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);

			//tex
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Front.VBOTexCoordId);
			glEnableVertexAttribArray(TexPassThruTexCoordAttributes);
			glVertexAttribPointer(TexPassThruTexCoordAttributes,2,GL_FLOAT,GL_FALSE,0,0);

			//index
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,CubeSkyBox.Front.VBOIndexId);
			glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE,0);

		//LEFT
			glBindTexture(GL_TEXTURE_2D,CubeSkyBox.Left.Tex.ID[0]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

			//vert
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Left.VBOVertId);
			glEnableVertexAttribArray(TexPassThruPositionAttributes);
			glVertexAttribPointer(TexPassThruPositionAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);

			//tex
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Left.VBOTexCoordId);
			glEnableVertexAttribArray(TexPassThruTexCoordAttributes);
			glVertexAttribPointer(TexPassThruTexCoordAttributes,2,GL_FLOAT,GL_FALSE,0,0);

			//index
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,CubeSkyBox.Left.VBOIndexId);
			glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE,0);

		//RIGHT

			glBindTexture(GL_TEXTURE_2D,CubeSkyBox.Right.Tex.ID[0]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

			//vert
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Right.VBOVertId);
			glEnableVertexAttribArray(TexPassThruPositionAttributes);
			glVertexAttribPointer(TexPassThruPositionAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);

			//tex
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Right.VBOTexCoordId);
			glEnableVertexAttribArray(TexPassThruTexCoordAttributes);
			glVertexAttribPointer(TexPassThruTexCoordAttributes,2,GL_FLOAT,GL_FALSE,0,0);

			//index
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,CubeSkyBox.Right.VBOIndexId);
			glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE,0);

		//BACK

			glBindTexture(GL_TEXTURE_2D,CubeSkyBox.Back.Tex.ID[0]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

			//vert
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Back.VBOVertId);
			glEnableVertexAttribArray(TexPassThruPositionAttributes);
			glVertexAttribPointer(TexPassThruPositionAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);

			//tex
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Back.VBOTexCoordId);
			glEnableVertexAttribArray(TexPassThruTexCoordAttributes);
			glVertexAttribPointer(TexPassThruTexCoordAttributes,2,GL_FLOAT,GL_FALSE,0,0);

			//index
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,CubeSkyBox.Back.VBOIndexId);
			glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE,0);

	//BOTTOM

			glBindTexture(GL_TEXTURE_2D,CubeSkyBox.Bottom.Tex.ID[0]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

			//vert
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Bottom.VBOVertId);
			glEnableVertexAttribArray(TexPassThruPositionAttributes);
			glVertexAttribPointer(TexPassThruPositionAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);

			//tex
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Bottom.VBOTexCoordId);
			glEnableVertexAttribArray(TexPassThruTexCoordAttributes);
			glVertexAttribPointer(TexPassThruTexCoordAttributes,2,GL_FLOAT,GL_FALSE,0,0);

			//index
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,CubeSkyBox.Bottom.VBOIndexId);
			glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE,0);

	//TOP

			glBindTexture(GL_TEXTURE_2D,CubeSkyBox.Top.Tex.ID[0]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

			//vert
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Top.VBOVertId);
			glEnableVertexAttribArray(TexPassThruPositionAttributes);
			glVertexAttribPointer(TexPassThruPositionAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);

			//tex
			glBindBuffer(GL_ARRAY_BUFFER,CubeSkyBox.Top.VBOTexCoordId);
			glEnableVertexAttribArray(TexPassThruTexCoordAttributes);
			glVertexAttribPointer(TexPassThruTexCoordAttributes,2,GL_FLOAT,GL_FALSE,0,0);

			//index
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,CubeSkyBox.Top.VBOIndexId);
			glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE,0);


		glDepthMask(GL_TRUE);

	//MESH
	esMatrixLoadIdentity( &modelview );
	esMatrixLoadIdentity(&lookAtMatrix);
	esLookAt(&lookAtMatrix,0,0,0,0,0,1,0,1,0);
	esTranslate(&modelview, -StatueMesh.CenterX,-StatueMesh.CenterY,-StatueMesh.CenterZ);
	esRotate(&modelview,RotateY,0,1,0);
	esRotate(&modelview, RotateX, 1, 0,0);
	esScale(&modelview,ScaleAmount,ScaleAmount,ScaleAmount);
	esMatrixMultiply(&modelview,&modelview,&lookAtMatrix);
	esMatrixMultiply( &MVPMatrix,&modelview,&perspective );

	//turn on the shader
	switch(ShaderToUse) 
	{

		case 0: //environment mapping shader

			glBindTexture(GL_TEXTURE_2D,0);

			glUseProgram(EnvironmentMappingShader.ID);
			checkGlError("glUseProgram");

			glActiveTexture(GL_TEXTURE1);

			glBindTexture(GL_TEXTURE_CUBE_MAP,EnvironmentCubeTexture.ID[0]);

			glUniform1i(EnvironmentMappingShaderCubeSampler,1);

			glUniformMatrix4fv( EnvironmentMappingShaderMVPMatrixUniform, 1, GL_FALSE, (GLfloat*) &MVPMatrix.m[0][0] );

			//Vertex Buffer
			glBindBuffer(GL_ARRAY_BUFFER,StatueMesh.VBOVertices.Id);
			glEnableVertexAttribArray(EnvironmentMappingShaderPositionAttributes);
			glVertexAttribPointer(EnvironmentMappingShaderPositionAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);

			//Normals
			glBindBuffer(GL_ARRAY_BUFFER,StatueMesh.VBONormals.Id);
			glEnableVertexAttribArray(EnvironmentMappingShaderNormalAttributes);
			glVertexAttribPointer(EnvironmentMappingShaderNormalAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);

			//Indices
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,StatueMesh.VBOIndices.Id);

			//draw call
			glDrawElements(GL_TRIANGLES, StatueMesh.IndexCount, GL_UNSIGNED_SHORT,0);

			glUseProgram(0);
			break;

		case 1: //phong
			glUseProgram(PhongShader.ID);
			checkGlError("glUseProgram");

			glActiveTexture(GL_TEXTURE0);

			glBindTexture(GL_TEXTURE_2D,StoneTexture.ID[0]);

			glUniform1i(TextureSampler,0);

			// Load the MVP matrix
			glUniformMatrix4fv( MVPMatrixUniform, 1, GL_FALSE, (GLfloat*) &MVPMatrix.m[0][0] );

			//Uniforms
			glUniform4fv( EyePosUniform, 1,  (GLfloat*) &EyePos );
			glUniform4fv( LightPosUniform, 1,  (GLfloat*) &LightPos );

			//Vertex Buffer
			glBindBuffer(GL_ARRAY_BUFFER,StatueMesh.VBOVertices.Id);
			glEnableVertexAttribArray(PositionAttributes);
			glVertexAttribPointer(PositionAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);

			//Texture Coordinates
			glBindBuffer(GL_ARRAY_BUFFER,StatueMesh.VBOTexCoords.Id);
			glEnableVertexAttribArray(TexCoordAttributes);
			glVertexAttribPointer(TexCoordAttributes,2,GL_FLOAT,GL_FALSE,0,0);

			//Normals
			glBindBuffer(GL_ARRAY_BUFFER,StatueMesh.VBONormals.Id);
			glEnableVertexAttribArray(NormalAttributes);
			glVertexAttribPointer(NormalAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);

			//Indices
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,StatueMesh.VBOIndices.Id);

			//draw call
			glDrawElements(GL_TRIANGLES, StatueMesh.IndexCount, GL_UNSIGNED_SHORT,0);
			break;

		case 2: //depth as color shader
			glUseProgram(DepthShader.ID);
			glUniformMatrix4fv( DepthShaderMVPMatrixUniform, 1, GL_FALSE, (GLfloat*) &MVPMatrix.m[0][0] );

			//Vertex Buffer
			glBindBuffer(GL_ARRAY_BUFFER,StatueMesh.VBOVertices.Id);
			glEnableVertexAttribArray(DepthShaderPositionAttributes);
			glVertexAttribPointer(DepthShaderPositionAttributes, 3, GL_FLOAT, GL_FALSE, 0, 0);
			//Indices
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,StatueMesh.VBOIndices.Id);

			//draw call
			glDrawElements(GL_TRIANGLES, StatueMesh.IndexCount, GL_UNSIGNED_SHORT,0);
			break;

		default:
			break;
	}

    eglSwapBuffers(engine->display, engine->surface);
}
示例#17
0
void test_cube_textured(GLint mag_filter, GLint min_filter,
		GLint wrap_s, GLint wrap_t, GLint wrap_r, GLenum format, GLenum type)
{
	GLint width, height;
	GLint modelviewmatrix_handle, modelviewprojectionmatrix_handle, normalmatrix_handle;
	GLuint texturename = 0, texture_handle;
	GLfloat vVertices[] = {
			// front
			-1.0f, -1.0f, +1.0f, // point blue
			+1.0f, -1.0f, +1.0f, // point magenta
			-1.0f, +1.0f, +1.0f, // point cyan
			+1.0f, +1.0f, +1.0f, // point white
			// back
			+1.0f, -1.0f, -1.0f, // point red
			-1.0f, -1.0f, -1.0f, // point black
			+1.0f, +1.0f, -1.0f, // point yellow
			-1.0f, +1.0f, -1.0f, // point green
			// right
			+1.0f, -1.0f, +1.0f, // point magenta
			+1.0f, -1.0f, -1.0f, // point red
			+1.0f, +1.0f, +1.0f, // point white
			+1.0f, +1.0f, -1.0f, // point yellow
			// left
			-1.0f, -1.0f, -1.0f, // point black
			-1.0f, -1.0f, +1.0f, // point blue
			-1.0f, +1.0f, -1.0f, // point green
			-1.0f, +1.0f, +1.0f, // point cyan
			// top
			-1.0f, +1.0f, +1.0f, // point cyan
			+1.0f, +1.0f, +1.0f, // point white
			-1.0f, +1.0f, -1.0f, // point green
			+1.0f, +1.0f, -1.0f, // point yellow
			// bottom
			-1.0f, -1.0f, -1.0f, // point black
			+1.0f, -1.0f, -1.0f, // point red
			-1.0f, -1.0f, +1.0f, // point blue
			+1.0f, -1.0f, +1.0f  // point magenta
	};

	GLfloat vTexCoords[] = {
			//front
			1.0f, 1.0f, //point blue
			0.0f, 1.0f, //point magenta
			1.0f, 0.0f, //point cyan
			0.0f, 0.0f, //point white
			//back
			1.0f, 1.0f, //point red
			0.0f, 1.0f, //point black
			1.0f, 0.0f, //point yellow
			0.0f, 0.0f, //point green
			//right
			1.0f, 1.0f, //point magenta
			0.0f, 1.0f, //point red
			1.0f, 0.0f, //point white
			0.0f, 0.0f, //point yellow
			//left
			1.0f, 1.0f, //point black
			0.0f, 1.0f, //point blue
			1.0f, 0.0f, //point green
			0.0f, 0.0f, //point cyan
			//top
			1.0f, 1.0f, //point cyan
			0.0f, 1.0f, //point white
			1.0f, 0.0f, //point green
			0.0f, 0.0f, //point yellow
			//bottom
			1.0f, 0.0f, //point black
			0.0f, 0.0f, //point red
			1.0f, 1.0f, //point blue
			0.0f, 1.0f, //point magenta
	};

	GLfloat vNormals[] = {
			// front
			+0.0f, +0.0f, +1.0f, // forward
			+0.0f, +0.0f, +1.0f, // forward
			+0.0f, +0.0f, +1.0f, // forward
			+0.0f, +0.0f, +1.0f, // forward
			// back
			+0.0f, +0.0f, -1.0f, // backbard
			+0.0f, +0.0f, -1.0f, // backbard
			+0.0f, +0.0f, -1.0f, // backbard
			+0.0f, +0.0f, -1.0f, // backbard
			// right
			+1.0f, +0.0f, +0.0f, // right
			+1.0f, +0.0f, +0.0f, // right
			+1.0f, +0.0f, +0.0f, // right
			+1.0f, +0.0f, +0.0f, // right
			// left
			-1.0f, +0.0f, +0.0f, // left
			-1.0f, +0.0f, +0.0f, // left
			-1.0f, +0.0f, +0.0f, // left
			-1.0f, +0.0f, +0.0f, // left
			// top
			+0.0f, +1.0f, +0.0f, // up
			+0.0f, +1.0f, +0.0f, // up
			+0.0f, +1.0f, +0.0f, // up
			+0.0f, +1.0f, +0.0f, // up
			// bottom
			+0.0f, -1.0f, +0.0f, // down
			+0.0f, -1.0f, +0.0f, // down
			+0.0f, -1.0f, +0.0f, // down
			+0.0f, -1.0f, +0.0f  // down
	};
	EGLSurface surface;
	const int texwidth = 333;
	const int texheight = 222;
	static uint8_t *buf = NULL;

	if (!buf) {
		int i;
		buf = malloc(texwidth * texheight * 16);
		for (i = 0; i < (texwidth * texheight * 16); i++)
			buf[i] = i;
	}

	RD_START("cube-textured", "mag_filter=%04x, min_filter=%04x, "
			"wrap_s=%04x, wrap_t=%04x, wrap_r=%04x, format=%s, type=%s",
			mag_filter, min_filter, wrap_s, wrap_t, wrap_r,
			formatname(format), typename(type));

	display = get_display();

	/* get an appropriate EGL frame buffer configuration */
	ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config));
	DEBUG_MSG("num_config: %d", num_config);

	/* create an EGL rendering context */
	ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list));

	surface = make_window(display, config, 256, 256);

	ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width));
	ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height));

	DEBUG_MSG("Buffer: %dx%d", width, height);

	/* connect the context to the surface */
	ECHK(eglMakeCurrent(display, surface, surface, context));

	program = get_program(vertex_shader_source, fragment_shader_source);

	GCHK(glBindAttribLocation(program, 0, "in_position"));
	GCHK(glBindAttribLocation(program, 1, "in_normal"));
	GCHK(glBindAttribLocation(program, 2, "in_TexCoord"));

	link_program(program);

	GCHK(glViewport(0, 0, width, height));


	/* clear the color buffer */
	GCHK(glClearColor(0.5, 0.5, 0.5, 1.0));
	GCHK(glClear(GL_COLOR_BUFFER_BIT));

	GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices));
	GCHK(glEnableVertexAttribArray(0));

	GCHK(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, vNormals));
	GCHK(glEnableVertexAttribArray(1));

	GCHK(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, vTexCoords));
	GCHK(glEnableVertexAttribArray(2));

	ESMatrix modelview;
	esMatrixLoadIdentity(&modelview);
	esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
	esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f);
	esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f);
	esRotate(&modelview, 10.0f, 0.0f, 0.0f, 1.0f);

	GLfloat aspect = (GLfloat)(height) / (GLfloat)(width);

	ESMatrix projection;
	esMatrixLoadIdentity(&projection);
	esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f);

	ESMatrix modelviewprojection;
	esMatrixLoadIdentity(&modelviewprojection);
	esMatrixMultiply(&modelviewprojection, &modelview, &projection);

	float normal[9];
	normal[0] = modelview.m[0][0];
	normal[1] = modelview.m[0][1];
	normal[2] = modelview.m[0][2];
	normal[3] = modelview.m[1][0];
	normal[4] = modelview.m[1][1];
	normal[5] = modelview.m[1][2];
	normal[6] = modelview.m[2][0];
	normal[7] = modelview.m[2][1];
	normal[8] = modelview.m[2][2];

	GCHK(glActiveTexture(GL_TEXTURE0));
	GCHK(glGenTextures(1, &texturename));
	GCHK(glBindTexture(GL_TEXTURE_2D, texturename));
	GCHK(glTexImage2D(GL_TEXTURE_2D, 0, format, texwidth, texheight,
			0, format, type, buf));

	/* Note: cube turned black until these were defined. */
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter));
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter));
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s));
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t));
	GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R_OES, wrap_r));

	GCHK(modelviewmatrix_handle = glGetUniformLocation(program, "modelviewMatrix"));
	GCHK(modelviewprojectionmatrix_handle = glGetUniformLocation(program, "modelviewprojectionMatrix"));
	GCHK(normalmatrix_handle = glGetUniformLocation(program, "normalMatrix"));
	GCHK(texture_handle = glGetUniformLocation(program, "uTexture"));

	GCHK(glUniformMatrix4fv(modelviewmatrix_handle, 1, GL_FALSE, &modelview.m[0][0]));
	GCHK(glUniformMatrix4fv(modelviewprojectionmatrix_handle, 1, GL_FALSE, &modelviewprojection.m[0][0]));
	GCHK(glUniformMatrix3fv(normalmatrix_handle, 1, GL_FALSE, normal));
	GCHK(glUniform1i(texture_handle, 0)); /* '0' refers to texture unit 0. */

	GCHK(glEnable(GL_CULL_FACE));

	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 4, 4));
	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 8, 4));
	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 12, 4));
	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 16, 4));
	GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 20, 4));

	ECHK(eglSwapBuffers(display, surface));
	GCHK(glFlush());

	ECHK(eglDestroySurface(display, surface));

	ECHK(eglTerminate(display));

	RD_END();
}
示例#18
0
void Draw ( ESContext *esContext )
{
    UserData *userData = esContext->userData;
    glViewport(0, 0, esContext->width, esContext->height);

    /* clear the color buffer */
    glClearColor(0.5, 0.5, 0.5, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, vNormals);
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, vColors);
    glEnableVertexAttribArray(2);

    glUseProgram(userData->program);
    ESMatrix modelview;
    esMatrixLoadIdentity(&modelview);
    esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
    esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f);
    esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f);
    esRotate(&modelview, 10.0f, 0.0f, 0.0f, 1.0f);

    GLfloat aspect = (GLfloat)(esContext->height) / (GLfloat)(esContext->width);

    ESMatrix projection;
    esMatrixLoadIdentity(&projection);
    esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f);

    ESMatrix modelviewprojection;
    esMatrixLoadIdentity(&modelviewprojection);
    esMatrixMultiply(&modelviewprojection, &modelview, &projection);

    float normal[9];
    normal[0] = modelview.m[0][0];
    normal[1] = modelview.m[0][1];
    normal[2] = modelview.m[0][2];
    normal[3] = modelview.m[1][0];
    normal[4] = modelview.m[1][1];
    normal[5] = modelview.m[1][2];
    normal[6] = modelview.m[2][0];
    normal[7] = modelview.m[2][1];
    normal[8] = modelview.m[2][2];

    GLint modelviewmatrix_handle = glGetUniformLocation(userData->program, "modelviewMatrix");
    GLint modelviewprojectionmatrix_handle = glGetUniformLocation(userData->program, "modelviewprojectionMatrix");
    GLint normalmatrix_handle = glGetUniformLocation(userData->program, "normalMatrix");

    glUniformMatrix4fv(modelviewmatrix_handle, 1, GL_FALSE, &modelview.m[0][0]);
    glUniformMatrix4fv(modelviewprojectionmatrix_handle, 1, GL_FALSE, &modelviewprojection.m[0][0]);
    glUniformMatrix3fv(normalmatrix_handle, 1, GL_FALSE, normal);

    glEnable(GL_CULL_FACE);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
    glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
    glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
    glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);
    glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);

    userData->frames ++;
#ifdef HOOK
    // If logging, exit mainloop after a few frames
    if(userData->frames == 5)
    {
        esContext->terminate = TRUE;
    }
#endif
}
示例#19
0
void test_cat(void)
{
	GLint width, height;
	GLint modelviewmatrix_handle, modelviewprojectionmatrix_handle, normalmatrix_handle;
	GLuint position_vbo, normal_vbo;
	EGLSurface surface;
	float scale = 1.3;

	DEBUG_MSG("----------------------------------------------------------------");
	RD_START("cat", "");

	display = get_display();

	/* get an appropriate EGL frame buffer configuration */
	ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config));
	DEBUG_MSG("num_config: %d", num_config);

	/* create an EGL rendering context */
	ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list));

	surface = make_window(display, config, 400, 240);

	ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width));
	ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height));

	DEBUG_MSG("Buffer: %dx%d", width, height);

	/* connect the context to the surface */
	ECHK(eglMakeCurrent(display, surface, surface, context));

	program = get_program(vertex_shader_source, fragment_shader_source);

	GCHK(glBindAttribLocation(program, 0, "normal"));
	GCHK(glBindAttribLocation(program, 1, "position"));

	/* upload the attribute vbo's, only done once: */
	GCHK(glGenBuffers(1, &normal_vbo));
	GCHK(glBindBuffer(GL_ARRAY_BUFFER, normal_vbo));
	GCHK(glBufferData(GL_ARRAY_BUFFER, sizeof(cat_normal), cat_normal, GL_STATIC_DRAW));

	GCHK(glGenBuffers(1, &position_vbo));
	GCHK(glBindBuffer(GL_ARRAY_BUFFER, position_vbo));
	GCHK(glBufferData(GL_ARRAY_BUFFER, sizeof(cat_position), cat_position, GL_STATIC_DRAW));

	link_program(program);

	GCHK(glViewport(0, 0, width, height));

	/* clear the color buffer */
	GCHK(glClearColor(0.5, 0.5, 0.5, 1.0));
	GCHK(glEnable(GL_DEPTH_TEST));
	GCHK(glDepthFunc(GL_LEQUAL));
	GCHK(glEnable(GL_CULL_FACE));
	GCHK(glCullFace(GL_BACK));
	GCHK(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT));

	GCHK(glEnableVertexAttribArray(0));
	GCHK(glBindBuffer(GL_ARRAY_BUFFER, normal_vbo));
	GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL));

	GCHK(glEnableVertexAttribArray(1));
	GCHK(glBindBuffer(GL_ARRAY_BUFFER, position_vbo));
	GCHK(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL));

	ESMatrix modelview;
	esMatrixLoadIdentity(&modelview);
	esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
	esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f);

	GLfloat aspect = (GLfloat)(height) / (GLfloat)(width);

	ESMatrix projection;
	esMatrixLoadIdentity(&projection);
	esFrustum(&projection,
			-scale, +scale,
			-scale * aspect, +scale * aspect,
			5.5f, 10.0f);

	ESMatrix modelviewprojection;
	esMatrixLoadIdentity(&modelviewprojection);
	esMatrixMultiply(&modelviewprojection, &modelview, &projection);

	float normal[9];
	normal[0] = modelview.m[0][0];
	normal[1] = modelview.m[0][1];
	normal[2] = modelview.m[0][2];
	normal[3] = modelview.m[1][0];
	normal[4] = modelview.m[1][1];
	normal[5] = modelview.m[1][2];
	normal[6] = modelview.m[2][0];
	normal[7] = modelview.m[2][1];
	normal[8] = modelview.m[2][2];

	GCHK(modelviewmatrix_handle = glGetUniformLocation(program, "ModelViewMatrix"));
	GCHK(modelviewprojectionmatrix_handle = glGetUniformLocation(program, "ModelViewProjectionMatrix"));
	GCHK(normalmatrix_handle = glGetUniformLocation(program, "NormalMatrix"));

	GCHK(glUniformMatrix4fv(modelviewmatrix_handle, 1, GL_FALSE, &modelview.m[0][0]));
	GCHK(glUniformMatrix4fv(modelviewprojectionmatrix_handle, 1, GL_FALSE, &modelviewprojection.m[0][0]));
	GCHK(glUniformMatrix3fv(normalmatrix_handle, 1, GL_FALSE, normal));

	GCHK(glDrawArrays(GL_TRIANGLES, 0, cat_vertices));

	ECHK(eglSwapBuffers(display, surface));
	GCHK(glFlush());

	ECHK(eglDestroySurface(display, surface));

	ECHK(eglTerminate(display));

	RD_END();
}
示例#20
0
int main(int argc, char *argv[])
{
	EGLDisplay display;
	EGLint egl_major, egl_minor;
	EGLConfig config;
	EGLint num_config;
	EGLContext context;
	EGLSurface surface;
	GLuint vertex_shader;
	GLuint fragment_shader;
	GLuint program;
	GLint ret;
	GLint width, height;
#ifdef HOOK
        the_hook("/mnt/sdcard/egl2.fdr");
#endif

	const char *vertex_shader_source =
	  "uniform mat4 modelviewMatrix;\n"
	  "uniform mat4 modelviewprojectionMatrix;\n"
	  "uniform mat3 normalMatrix;\n"
	  "\n"
	  "attribute vec4 in_position;    \n"
	  "attribute vec3 in_normal;      \n"
	  "attribute vec2 in_texcoord;       \n"
	  "\n"
	  "vec4 lightSource = vec4(2.0, 2.0, 20.0, 0.0);\n"
	  "                             \n"
	  "varying vec4 vColor;         \n"
	  "varying vec2 vTexCoord;         \n"
          "uniform sampler2D s_texture;                      \n"
	  "                             \n"
	  "void main()                  \n"
	  "{                            \n"
          "    float texvalue = texture2D(s_texture, in_texcoord).x;\n"
	  "    gl_Position = modelviewprojectionMatrix * (in_position + vec4(0.2 * texvalue * in_normal, 0));\n"
	  "    vec3 vEyeNormal = normalMatrix * in_normal;\n"
	  "    vec4 vPosition4 = modelviewMatrix * in_position;\n"
	  "    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;\n"
	  "    vec3 vLightDir = normalize(lightSource.xyz - vPosition3);\n"
	  "    float diff = max(0.0, dot(vEyeNormal, vLightDir));\n"
	  "    vColor = vec4(diff, 0.0, 0.0, 1.0);\n"
	  "    vTexCoord = in_texcoord;\n"
	  "}                            \n";

	const char *fragment_shader_source =
	  "precision mediump float;     \n"
	  "                             \n"
	  "varying vec4 vColor;         \n"
	  "varying vec2 vTexCoord;         \n"
	  "                             \n"
	  "void main()                  \n"
	  "{                            \n"
	  "    gl_FragColor = vColor;// * texture2D(s_texture, vTexCoord);   \n"
	  "}                            \n";
	
        display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
	if (display == EGL_NO_DISPLAY) {
		printf("Error: No display found!\n");
		return -1;
	}

	if (!eglInitialize(display, &egl_major, &egl_minor)) {
		printf("Error: eglInitialise failed!\n");
		return -1;
	}

	printf("Using display %p with EGL version %d.%d\n",
	       display, egl_major, egl_minor);

	printf("EGL Version \"%s\"\n", eglQueryString(display, EGL_VERSION));
	printf("EGL Vendor \"%s\"\n", eglQueryString(display, EGL_VENDOR));
	printf("EGL Extensions \"%s\"\n", eglQueryString(display, EGL_EXTENSIONS));

	/* get an appropriate EGL frame buffer configuration */
	eglChooseConfig(display, config_attribute_list, &config, 1, &num_config);

	/* create an EGL rendering context */
	context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list);
	if (context == EGL_NO_CONTEXT) {
		printf("Error: eglCreateContext failed: %d\n", eglGetError());
		return -1;
	}

	surface = eglCreatePbufferSurface(display, config, pbuffer_attribute_list);
	if (surface == EGL_NO_SURFACE) {
		printf("Error: eglCreatePbufferSurface failed: %d (%s)\n",
		       eglGetError(), eglStrError(eglGetError()));
		return -1;
	}

	if (!eglQuerySurface(display, surface, EGL_WIDTH, &width) ||
	    !eglQuerySurface(display, surface, EGL_HEIGHT, &height)) {
		printf("Error: eglQuerySurface failed: %d (%s)\n",
		       eglGetError(), eglStrError(eglGetError()));
		return -1;
	}
	printf("PBuffer: %dx%d\n", width, height);
        printf("GL Extensions \"%s\"\n", glGetString(GL_EXTENSIONS));

	/* connect the context to the surface */
	if (!eglMakeCurrent(display, surface, surface, context)) {
		printf("Error: eglMakeCurrent() failed: %d (%s)\n",
		       eglGetError(), eglStrError(eglGetError()));
		return -1;
	}

	vertex_shader = glCreateShader(GL_VERTEX_SHADER);
	if (!vertex_shader) {
		printf("Error: glCreateShader(GL_VERTEX_SHADER) failed: %d (%s)\n",
		       eglGetError(), eglStrError(eglGetError()));
		return -1;
	}


	glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
	glCompileShader(vertex_shader);

	glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &ret);
	if (!ret) {
		char *log;

		printf("Error: vertex shader compilation failed!:\n");
		glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &ret);

		if (ret > 1) {
			log = malloc(ret);
			glGetShaderInfoLog(vertex_shader, ret, NULL, log);
			printf("%s", log);
		}
		return -1;
	} else
		printf("Vertex shader compilation succeeded!\n");

	fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
	if (!fragment_shader) {
		printf("Error: glCreateShader(GL_FRAGMENT_SHADER) failed: %d (%s)\n",
		       eglGetError(), eglStrError(eglGetError()));
		return -1;
	}


	glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
	glCompileShader(fragment_shader);

	glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &ret);
	if (!ret) {
		char *log;

		printf("Error: fragment shader compilation failed!:\n");
		glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &ret);

		if (ret > 1) {
			log = malloc(ret);
			glGetShaderInfoLog(fragment_shader, ret, NULL, log);
			printf("%s", log);
		}
		return -1;
	} else
		printf("Fragment shader compilation succeeded!\n");

	program = glCreateProgram();
	if (!program) {
		printf("Error: failed to create program!\n");
		return -1;
	}
        
        GLfloat *vVertices;
        GLfloat *vNormals;
        GLfloat *vTexCoords;
        GLushort *vIndices;
        int numIndices = esGenSphere(40, 1.0f, &vVertices, &vNormals,
                                            &vTexCoords, &vIndices, NULL);
        GLuint texId = createSimpleTexture();
	
        glAttachShader(program, vertex_shader);
	glAttachShader(program, fragment_shader);

	glBindAttribLocation(program, 0, "in_position");
	glBindAttribLocation(program, 1, "in_normal");
	glBindAttribLocation(program, 2, "in_texcoord");

	glLinkProgram(program);

	glGetProgramiv(program, GL_LINK_STATUS, &ret);
	if (!ret) {
		char *log;

		printf("Error: program linking failed!:\n");
		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &ret);

		if (ret > 1) {
			log = malloc(ret);
			glGetProgramInfoLog(program, ret, NULL, log);
			printf("%s", log);
		}
		return -1;
	} else
		printf("program linking succeeded!\n");

	glUseProgram(program);

	glViewport(0, 0, width, height);

	/* clear the color buffer */
	glClearColor(0.5, 0.5, 0.5, 1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
	glEnableVertexAttribArray(0);

	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, vNormals);
	glEnableVertexAttribArray(1);

	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, vTexCoords);
	glEnableVertexAttribArray(2);

	ESMatrix modelview;
	esMatrixLoadIdentity(&modelview);
	esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
	esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f);
	esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f);
	esRotate(&modelview, 10.0f, 0.0f, 0.0f, 1.0f);

	GLfloat aspect = (GLfloat)(height) / (GLfloat)(width);

	ESMatrix projection;
	esMatrixLoadIdentity(&projection);
	esFrustum(&projection, -1.8f, +1.8f, -1.8f * aspect, +1.8f * aspect, 6.0f, 10.0f);

	ESMatrix modelviewprojection;
	esMatrixLoadIdentity(&modelviewprojection);
	esMatrixMultiply(&modelviewprojection, &modelview, &projection);

	float normal[9];
	normal[0] = modelview.m[0][0];
	normal[1] = modelview.m[0][1];
	normal[2] = modelview.m[0][2];
	normal[3] = modelview.m[1][0];
	normal[4] = modelview.m[1][1];
	normal[5] = modelview.m[1][2];
	normal[6] = modelview.m[2][0];
	normal[7] = modelview.m[2][1];
	normal[8] = modelview.m[2][2];

	GLint modelviewmatrix_handle = glGetUniformLocation(program, "modelviewMatrix");
	GLint modelviewprojectionmatrix_handle = glGetUniformLocation(program, "modelviewprojectionMatrix");
	GLint normalmatrix_handle = glGetUniformLocation(program, "normalMatrix");
        GLint sampler_handle = glGetUniformLocation(program, "s_texture");

	glUniformMatrix4fv(modelviewmatrix_handle, 1, GL_FALSE, &modelview.m[0][0]);
	glUniformMatrix4fv(modelviewprojectionmatrix_handle, 1, GL_FALSE, &modelviewprojection.m[0][0]);
	glUniformMatrix3fv(normalmatrix_handle, 1, GL_FALSE, normal);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texId);
        glUniform1i(sampler_handle, 0);

	glEnable(GL_CULL_FACE);
        glEnable(GL_DEPTH_TEST);

        glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, vIndices);

	glFlush();

	fflush(stdout);
        dump_gl_screen("/sdcard/egl2.bmp", width, height);

#ifdef HOOK
        close_hook();
#endif

	return 0;
}
示例#21
0
int
main(int argc, char *argv[])
{
	EGLDisplay display;
	EGLint egl_major, egl_minor;
	EGLConfig config;
	EGLint num_config;
	EGLContext context;
	EGLSurface surface;
	GLuint vertex_shader;
	GLuint fragment_shader;
	GLuint program;
	GLint ret;
	GLint width, height;

	const char *vertex_shader_source =
	  "uniform mat4 modelviewMatrix;\n"
	  "uniform mat4 modelviewprojectionMatrix;\n"
	  "uniform mat3 normalMatrix;\n"
	  "\n"
	  "attribute vec4 in_position;    \n"
	  "attribute vec3 in_normal;      \n"
	  "attribute vec4 in_color;       \n"
	  "\n"
	  "vec4 lightSource = vec4(2.0, 2.0, 20.0, 0.0);\n"
	  "                             \n"
	  "varying vec4 vVaryingColor;         \n"
	  "                             \n"
	  "void main()                  \n"
	  "{                            \n"
	  "    gl_Position = modelviewprojectionMatrix * in_position;\n"
	  "    vec3 vEyeNormal = normalMatrix * in_normal;\n"
	  "    vec4 vPosition4 = modelviewMatrix * in_position;\n"
	  "    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;\n"
	  "    vec3 vLightDir = normalize(lightSource.xyz - vPosition3);\n"
	  "    float diff = max(0.0, dot(vEyeNormal, vLightDir));\n"
	  "    vVaryingColor = vec4(diff * in_color.rgb, 1.0);\n"
	  "}                            \n";

	const char *fragment_shader_source =
	  "precision mediump float;     \n"
	  "                             \n"
	  "varying vec4 vVaryingColor;         \n"
	  "                             \n"
	  "void main()                  \n"
	  "{                            \n"
	  "    gl_FragColor = vVaryingColor;   \n"
	  "}                            \n";

	GLfloat vVertices[] = {
	  // front
	  -1.0f, -1.0f, +1.0f, // point blue
	  +1.0f, -1.0f, +1.0f, // point magenta
	  -1.0f, +1.0f, +1.0f, // point cyan
	  +1.0f, +1.0f, +1.0f, // point white
	  // back
	  +1.0f, -1.0f, -1.0f, // point red
	  -1.0f, -1.0f, -1.0f, // point black
	  +1.0f, +1.0f, -1.0f, // point yellow
	  -1.0f, +1.0f, -1.0f, // point green
	  // right
	  +1.0f, -1.0f, +1.0f, // point magenta
	  +1.0f, -1.0f, -1.0f, // point red
	  +1.0f, +1.0f, +1.0f, // point white
	  +1.0f, +1.0f, -1.0f, // point yellow
	  // left
	  -1.0f, -1.0f, -1.0f, // point black
	  -1.0f, -1.0f, +1.0f, // point blue
	  -1.0f, +1.0f, -1.0f, // point green
	  -1.0f, +1.0f, +1.0f, // point cyan
	  // top
	  -1.0f, +1.0f, +1.0f, // point cyan
	  +1.0f, +1.0f, +1.0f, // point white
	  -1.0f, +1.0f, -1.0f, // point green
	  +1.0f, +1.0f, -1.0f, // point yellow
	  // bottom
	  -1.0f, -1.0f, -1.0f, // point black
	  +1.0f, -1.0f, -1.0f, // point red
	  -1.0f, -1.0f, +1.0f, // point blue
	  +1.0f, -1.0f, +1.0f  // point magenta
	};

	GLfloat vColors[] = {
	  // front
	  0.0f,  0.0f,  1.0f, // blue
	  1.0f,  0.0f,  1.0f, // magenta
	  0.0f,  1.0f,  1.0f, // cyan
	  1.0f,  1.0f,  1.0f, // white
	  // back
	  1.0f,  0.0f,  0.0f, // red
	  0.0f,  0.0f,  0.0f, // black
	  1.0f,  1.0f,  0.0f, // yellow
	  0.0f,  1.0f,  0.0f, // green
	  // right
	  1.0f,  0.0f,  1.0f, // magenta
	  1.0f,  0.0f,  0.0f, // red
	  1.0f,  1.0f,  1.0f, // white
	  1.0f,  1.0f,  0.0f, // yellow
	  // left
	  0.0f,  0.0f,  0.0f, // black
	  0.0f,  0.0f,  1.0f, // blue
	  0.0f,  1.0f,  0.0f, // green
	  0.0f,  1.0f,  1.0f, // cyan
	  // top
	  0.0f,  1.0f,  1.0f, // cyan
	  1.0f,  1.0f,  1.0f, // white
	  0.0f,  1.0f,  0.0f, // green
	  1.0f,  1.0f,  0.0f, // yellow
	  // bottom
	  0.0f,  0.0f,  0.0f, // black
	  1.0f,  0.0f,  0.0f, // red
	  0.0f,  0.0f,  1.0f, // blue
	  1.0f,  0.0f,  1.0f  // magenta
	};

	GLfloat vNormals[] = {
	  // front
	  +0.0f, +0.0f, +1.0f, // forward
	  +0.0f, +0.0f, +1.0f, // forward
	  +0.0f, +0.0f, +1.0f, // forward
	  +0.0f, +0.0f, +1.0f, // forward
	  // back
	  +0.0f, +0.0f, -1.0f, // backbard
	  +0.0f, +0.0f, -1.0f, // backbard
	  +0.0f, +0.0f, -1.0f, // backbard
	  +0.0f, +0.0f, -1.0f, // backbard
	  // right
	  +1.0f, +0.0f, +0.0f, // right
	  +1.0f, +0.0f, +0.0f, // right
	  +1.0f, +0.0f, +0.0f, // right
	  +1.0f, +0.0f, +0.0f, // right
	  // left
	  -1.0f, +0.0f, +0.0f, // left
	  -1.0f, +0.0f, +0.0f, // left
	  -1.0f, +0.0f, +0.0f, // left
	  -1.0f, +0.0f, +0.0f, // left
	  // top
	  +0.0f, +1.0f, +0.0f, // up
	  +0.0f, +1.0f, +0.0f, // up
	  +0.0f, +1.0f, +0.0f, // up
	  +0.0f, +1.0f, +0.0f, // up
	  // bottom
	  +0.0f, -1.0f, +0.0f, // down
	  +0.0f, -1.0f, +0.0f, // down
	  +0.0f, -1.0f, +0.0f, // down
	  +0.0f, -1.0f, +0.0f  // down
	};

	display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
	if (display == EGL_NO_DISPLAY) {
		printf("Error: No display found!\n");
		return -1;
	}

	if (!eglInitialize(display, &egl_major, &egl_minor)) {
		printf("Error: eglInitialise failed!\n");
		return -1;
	}

	printf("Using display %p with EGL version %d.%d\n",
	       display, egl_major, egl_minor);

	printf("EGL Version \"%s\"\n", eglQueryString(display, EGL_VERSION));
	printf("EGL Vendor \"%s\"\n", eglQueryString(display, EGL_VENDOR));
	printf("EGL Extensions \"%s\"\n", eglQueryString(display, EGL_EXTENSIONS));

	/* get an appropriate EGL frame buffer configuration */
	eglChooseConfig(display, config_attribute_list, &config, 1, &num_config);

	/* create an EGL rendering context */
	context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list);
	if (context == EGL_NO_CONTEXT) {
		printf("Error: eglCreateContext failed: %d\n", eglGetError());
		return -1;
	}

	surface = eglCreatePbufferSurface(display, config, pbuffer_attribute_list);
	if (surface == EGL_NO_SURFACE) {
		printf("Error: eglCreatePbufferSurface failed: %d (%s)\n",
		       eglGetError(), eglStrError(eglGetError()));
		return -1;
	}

	if (!eglQuerySurface(display, surface, EGL_WIDTH, &width) ||
	    !eglQuerySurface(display, surface, EGL_HEIGHT, &height)) {
		printf("Error: eglQuerySurface failed: %d (%s)\n",
		       eglGetError(), eglStrError(eglGetError()));
		return -1;
	}
	printf("PBuffer: %dx%d\n", width, height);

	/* connect the context to the surface */
	if (!eglMakeCurrent(display, surface, surface, context)) {
		printf("Error: eglMakeCurrent() failed: %d (%s)\n",
		       eglGetError(), eglStrError(eglGetError()));
		return -1;
	}

	vertex_shader = glCreateShader(GL_VERTEX_SHADER);
	if (!vertex_shader) {
		printf("Error: glCreateShader(GL_VERTEX_SHADER) failed: %d (%s)\n",
		       eglGetError(), eglStrError(eglGetError()));
		return -1;
	}


	glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
	glCompileShader(vertex_shader);

	glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &ret);
	if (!ret) {
		char *log;

		printf("Error: vertex shader compilation failed!:\n");
		glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &ret);

		if (ret > 1) {
			log = malloc(ret);
			glGetShaderInfoLog(vertex_shader, ret, NULL, log);
			printf("%s", log);
		}
		return -1;
	} else
		printf("Vertex shader compilation succeeded!\n");

	fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
	if (!fragment_shader) {
		printf("Error: glCreateShader(GL_FRAGMENT_SHADER) failed: %d (%s)\n",
		       eglGetError(), eglStrError(eglGetError()));
		return -1;
	}


	glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
	glCompileShader(fragment_shader);

	glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &ret);
	if (!ret) {
		char *log;

		printf("Error: fragment shader compilation failed!:\n");
		glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &ret);

		if (ret > 1) {
			log = malloc(ret);
			glGetShaderInfoLog(fragment_shader, ret, NULL, log);
			printf("%s", log);
		}
		return -1;
	} else
		printf("Fragment shader compilation succeeded!\n");

	program = glCreateProgram();
	if (!program) {
		printf("Error: failed to create program!\n");
		return -1;
	}

	glAttachShader(program, vertex_shader);
	glAttachShader(program, fragment_shader);

	glBindAttribLocation(program, 0, "in_position");
	glBindAttribLocation(program, 1, "in_normal");
	glBindAttribLocation(program, 2, "in_color");

	glLinkProgram(program);

	glGetProgramiv(program, GL_LINK_STATUS, &ret);
	if (!ret) {
		char *log;

		printf("Error: program linking failed!:\n");
		glGetProgramiv(program, GL_INFO_LOG_LENGTH, &ret);

		if (ret > 1) {
			log = malloc(ret);
			glGetProgramInfoLog(program, ret, NULL, log);
			printf("%s", log);
		}
		return -1;
	} else
		printf("program linking succeeded!\n");

	glUseProgram(program);

	glViewport(0, 0, width, height);

	/* clear the color buffer */
	glClearColor(0.5, 0.5, 0.5, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
	glEnableVertexAttribArray(0);

	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, vNormals);
	glEnableVertexAttribArray(1);

	glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, vColors);
	glEnableVertexAttribArray(2);

	ESMatrix modelview;
	esMatrixLoadIdentity(&modelview);
	esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
	esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f);
	esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f);
	esRotate(&modelview, 10.0f, 0.0f, 0.0f, 1.0f);

	GLfloat aspect = (GLfloat)(height) / (GLfloat)(width);

	ESMatrix projection;
	esMatrixLoadIdentity(&projection);
	esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f);

	ESMatrix modelviewprojection;
	esMatrixLoadIdentity(&modelviewprojection);
	esMatrixMultiply(&modelviewprojection, &modelview, &projection);

	float normal[9];
	normal[0] = modelview.m[0][0];
	normal[1] = modelview.m[0][1];
	normal[2] = modelview.m[0][2];
	normal[3] = modelview.m[1][0];
	normal[4] = modelview.m[1][1];
	normal[5] = modelview.m[1][2];
	normal[6] = modelview.m[2][0];
	normal[7] = modelview.m[2][1];
	normal[8] = modelview.m[2][2];

	GLint modelviewmatrix_handle = glGetUniformLocation(program, "modelviewMatrix");
	GLint modelviewprojectionmatrix_handle = glGetUniformLocation(program, "modelviewprojectionMatrix");
	GLint normalmatrix_handle = glGetUniformLocation(program, "normalMatrix");

	glUniformMatrix4fv(modelviewmatrix_handle, 1, GL_FALSE, &modelview.m[0][0]);
	glUniformMatrix4fv(modelviewprojectionmatrix_handle, 1, GL_FALSE, &modelviewprojection.m[0][0]);
	glUniformMatrix3fv(normalmatrix_handle, 1, GL_FALSE, normal);

	glEnable(GL_CULL_FACE);

	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
	glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
	glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
	glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);
	glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);

	glFlush();

	usleep(1000000);

	fflush(stdout);

	return 0;
}
示例#22
0
文件: limare.c 项目: cmotc/lima
int
main(int argc, char *argv[])
{
	struct limare_state *state;
	int ret;

	const char *vertex_shader_source =
		"uniform mat4 modelviewMatrix;\n"
		"uniform mat4 modelviewprojectionMatrix;\n"
		"uniform mat3 normalMatrix;\n"
		"\n"
		"attribute vec4 in_position;    \n"
		"attribute vec3 in_normal;      \n"
		"attribute vec2 in_coord;       \n"
		"\n"
		"vec4 lightSource = vec4(10.0, 20.0, 40.0, 0.0);\n"
		"                             \n"
		"varying vec4 vVaryingColor;  \n"
		"varying vec2 coord;          \n"
		"                             \n"
		"void main()                  \n"
		"{                            \n"
		"    gl_Position = modelviewprojectionMatrix * in_position;\n"
		"    vec3 vEyeNormal = normalMatrix * in_normal;\n"
		"    vec4 vPosition4 = modelviewMatrix * in_position;\n"
		"    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;\n"
		"    vec3 vLightDir = normalize(lightSource.xyz - vPosition3);\n"
		"    float diff = max(0.0, dot(vEyeNormal, vLightDir));\n"
		"    vVaryingColor = vec4(diff * vec3(1.0, 1.0, 1.0), 1.0);\n"
		"    coord = in_coord;        \n"
		"}                            \n";
	const char *fragment_shader_source =
		"precision mediump float;     \n"
		"                             \n"
		"varying vec4 vVaryingColor;  \n"
		"varying vec2 coord;          \n"
		"                             \n"
		"uniform sampler2D in_texture; \n"
		"                             \n"
		"void main()                  \n"
		"{                            \n"
		"    gl_FragColor = vVaryingColor * texture2D(in_texture, coord);\n"
		"}                            \n";

	float *vertices_array = companion_vertices_array();
	float *texture_coordinates_array =
		companion_texture_coordinates_array();
	float *normals_array = companion_normals_array();

	state = limare_init();
	if (!state)
		return -1;

	limare_buffer_clear(state);

	ret = limare_state_setup(state, 0, 0, 0xFF505050);
	if (ret)
		return ret;

	int width, height;
	limare_buffer_size(state, &width, &height);
	float aspect = (float) height / width;

	limare_enable(state, GL_DEPTH_TEST);
	limare_enable(state, GL_CULL_FACE);
	limare_depth_mask(state, 1);

	int program = limare_program_new(state);
	vertex_shader_attach(state, program, vertex_shader_source);
	fragment_shader_attach(state, program, fragment_shader_source);

	limare_link(state);

	int vertices_buffer =
		limare_attribute_buffer_upload(state, LIMARE_ATTRIB_FLOAT,
					       3, 0, COMPANION_ARRAY_COUNT,
					       vertices_array);

	int texture_coordinates_buffer =
		limare_attribute_buffer_upload(state, LIMARE_ATTRIB_FLOAT,
					       2, 0, COMPANION_ARRAY_COUNT,
					       texture_coordinates_array);

	int normals_buffer =
		limare_attribute_buffer_upload(state, LIMARE_ATTRIB_FLOAT,
					       3, 0, COMPANION_ARRAY_COUNT,
					       normals_array);

	limare_attribute_buffer_attach(state, "in_position", vertices_buffer);
	limare_attribute_buffer_attach(state, "in_coord",
				       texture_coordinates_buffer);
	limare_attribute_buffer_attach(state, "in_normal", normals_buffer);

	int texture = limare_texture_upload(state, companion_texture,
					    COMPANION_TEXTURE_WIDTH,
					    COMPANION_TEXTURE_HEIGHT,
					    COMPANION_TEXTURE_FORMAT, 0);
	limare_texture_attach(state, "in_texture", texture);

	ESMatrix modelview;
	esMatrixLoadIdentity(&modelview);
	esTranslate(&modelview, 0.0, 0.0, -4.0);
	esRotate(&modelview, -30.0, 1.0, 0.0, 0.0);
	esRotate(&modelview, -45.0, 0.0, 1.0, 0.0);

	ESMatrix projection;
	esMatrixLoadIdentity(&projection);
	esFrustum(&projection, -1.0, +1.0, -1.0 * aspect, +1.0 * aspect,
		  1.0, 10.0);

	ESMatrix modelviewprojection;
	esMatrixLoadIdentity(&modelviewprojection);
	esMatrixMultiply(&modelviewprojection, &modelview, &projection);

	float normal[9];
	normal[0] = modelview.m[0][0];
	normal[1] = modelview.m[0][1];
	normal[2] = modelview.m[0][2];
	normal[3] = modelview.m[1][0];
	normal[4] = modelview.m[1][1];
	normal[5] = modelview.m[1][2];
	normal[6] = modelview.m[2][0];
	normal[7] = modelview.m[2][1];
	normal[8] = modelview.m[2][2];

	limare_uniform_attach(state, "modelviewMatrix", 16,
			      &modelview.m[0][0]);
	limare_uniform_attach(state, "modelviewprojectionMatrix", 16,
			      &modelviewprojection.m[0][0]);
	limare_uniform_attach(state, "normalMatrix", 9, normal);

	limare_frame_new(state);

	ret = limare_draw_arrays(state, GL_TRIANGLES, 0, COMPANION_ARRAY_COUNT);
	if (ret)
		return ret;

	ret = limare_frame_flush(state);
	if (ret)
		return ret;

	limare_buffer_swap(state);

	limare_finish(state);

	return 0;
}
示例#23
0
int main(int argc, char **argv)
{
    int rv;
    int width = 256;
    int height = 256;
    int padded_width, padded_height;
    
    fb_info fb;
    rv = fb_open(0, &fb);
    if(rv!=0)
    {
        exit(1);
    }
    width = fb.fb_var.xres;
    height = fb.fb_var.yres;
    padded_width = etna_align_up(width, 64);
    padded_height = etna_align_up(height, 64);

    printf("padded_width %i padded_height %i\n", padded_width, padded_height);
    rv = viv_open();
    if(rv!=0)
    {
        fprintf(stderr, "Error opening device\n");
        exit(1);
    }
    printf("Succesfully opened device\n");

    etna_ctx *ctx = 0;
    if(etna_create(&ctx) != ETNA_OK)
    {
        printf("Unable to create context\n");
        exit(1);
    }

    /* Initialize buffers synchronization structure */
    etna_bswap_buffers *buffers = 0;
    if(etna_bswap_create(ctx, &buffers, (int (*)(void *, int))&fb_set_buffer, NULL, &fb) < 0)
    {
        fprintf(stderr, "Error creating buffer swapper\n");
        exit(1);
    }

    /* Allocate video memory */
    etna_vidmem *rt = 0; /* main render target */
    etna_vidmem *rt_ts = 0; /* tile status for main render target */
    etna_vidmem *z = 0; /* depth for main render target */
    etna_vidmem *z_ts = 0; /* depth ts for main render target */
    etna_vidmem *vtx = 0; /* vertex buffer */
    etna_vidmem *aux_rt = 0; /* auxilary render target */
    etna_vidmem *aux_rt_ts = 0; /* tile status for auxilary render target */
    etna_vidmem *tex = 0; /* texture */

    size_t rt_size = padded_width * padded_height * 4;
    size_t rt_ts_size = etna_align_up((padded_width * padded_height * 4)/0x100, 0x100);
    size_t z_size = padded_width * padded_height * 2;
    size_t z_ts_size = etna_align_up((padded_width * padded_height * 2)/0x100, 0x100);

    dds_texture *dds = 0;
    if(argc<2 || !dds_load(argv[1], &dds))
    {
        printf("Error loading texture\n");
        exit(1);
    }

    if(etna_vidmem_alloc_linear(&rt, rt_size, gcvSURF_RENDER_TARGET, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&rt_ts, rt_ts_size, gcvSURF_TILE_STATUS, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&z, z_size, gcvSURF_DEPTH, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&z_ts, z_ts_size, gcvSURF_TILE_STATUS, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&vtx, VERTEX_BUFFER_SIZE, gcvSURF_VERTEX, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&aux_rt, 0x4000, gcvSURF_RENDER_TARGET, gcvPOOL_SYSTEM, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&aux_rt_ts, 0x100, gcvSURF_TILE_STATUS, gcvPOOL_DEFAULT, true)!=ETNA_OK ||
       etna_vidmem_alloc_linear(&tex, dds->size, gcvSURF_TEXTURE, gcvPOOL_DEFAULT, true)!=ETNA_OK
       )
    {
        fprintf(stderr, "Error allocating video memory\n");
        exit(1);
    }

    uint32_t tex_format = 0;
    uint32_t tex_base_width = dds->slices[0][0].width;
    uint32_t tex_base_height = dds->slices[0][0].height;
    uint32_t tex_base_log_width = (int)(logf(tex_base_width) * RCPLOG2 * 32.0f + 0.5f);
    uint32_t tex_base_log_height = (int)(logf(tex_base_height) * RCPLOG2 * 32.0f + 0.5f);
    printf("Loading compressed texture (format %i, %ix%i) log_width=%i log_height=%i\n", dds->fmt, tex_base_width, tex_base_height, tex_base_log_width, tex_base_log_height);
    if(dds->fmt == FMT_X8R8G8B8 || dds->fmt == FMT_A8R8G8B8)
    {
        for(int ix=0; ix<dds->num_mipmaps; ++ix)
        {
            printf("%08x: Tiling mipmap %i (%ix%i)\n", dds->slices[0][ix].offset, ix, dds->slices[0][ix].width, dds->slices[0][ix].height);
            etna_texture_tile((void*)((size_t)tex->logical + dds->slices[0][ix].offset), 
                    dds->slices[0][ix].data, dds->slices[0][ix].width, dds->slices[0][ix].height, dds->slices[0][ix].stride, 4);
        }
        tex_format = TEXTURE_FORMAT_X8R8G8B8;
    } else if(dds->fmt == FMT_DXT1 || dds->fmt == FMT_DXT3 || dds->fmt == FMT_DXT5 || dds->fmt == FMT_ETC1)
    {
        printf("Uploading compressed texture\n");
        memcpy(tex->logical, dds->data, dds->size);
        switch(dds->fmt)
        {
        case FMT_DXT1: tex_format = TEXTURE_FORMAT_DXT1; break;
        case FMT_DXT3: tex_format = TEXTURE_FORMAT_DXT2_DXT3; break;
        case FMT_DXT5: tex_format = TEXTURE_FORMAT_DXT4_DXT5; break;
        case FMT_ETC1: tex_format = TEXTURE_FORMAT_ETC1; break;
        }
    } else
    {
        printf("Unknown texture format\n");
        exit(1);
    }

    /* Phew, now we got all the memory we need.
     * Write interleaved attribute vertex stream.
     * Unlike the GL example we only do this once, not every time glDrawArrays is called, the same would be accomplished
     * from GL by using a vertex buffer object.
     */
    for(int vert=0; vert<NUM_VERTICES; ++vert)
    {
        int dest_idx = vert * (3 + 3 + 2);
        for(int comp=0; comp<3; ++comp)
            ((float*)vtx->logical)[dest_idx+comp+0] = vVertices[vert*3 + comp]; /* 0 */
        for(int comp=0; comp<3; ++comp)
            ((float*)vtx->logical)[dest_idx+comp+3] = vNormals[vert*3 + comp]; /* 1 */
        for(int comp=0; comp<2; ++comp)
            ((float*)vtx->logical)[dest_idx+comp+6] = vTexCoords[vert*2 + comp]; /* 2 */
    }

    for(int frame=0; frame<1000; ++frame)
    {
        if(frame%50 == 0)
            printf("*** FRAME %i ****\n", frame);
        /*   Compute transform matrices in the same way as cube egl demo */ 
        ESMatrix modelview, projection, modelviewprojection;
        ESMatrix inverse, normal; 
        esMatrixLoadIdentity(&modelview);
        esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
        esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f);
        esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f);
        esRotate(&modelview, frame*0.5f, 0.0f, 0.0f, 1.0f);
        GLfloat aspect = (GLfloat)(height) / (GLfloat)(width);
        esMatrixLoadIdentity(&projection);
        esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f);
        esMatrixLoadIdentity(&modelviewprojection);
        esMatrixMultiply(&modelviewprojection, &modelview, &projection);
        esMatrixInverse3x3(&inverse, &modelview);
        esMatrixTranspose(&normal, &inverse);

        /* XXX part of this can be put outside the loop, but until we have usable context management
         * this is safest.
         */
        etna_set_state(ctx, VIVS_RA_CONTROL, 0x3);
        
        etna_set_state(ctx, VIVS_GL_MULTI_SAMPLE_CONFIG, 
                VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE |
                VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES(0xf) /*|
                VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12 |
                VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16 */
                ); 
        etna_set_state(ctx, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x1);
        etna_set_state(ctx, VIVS_GL_VARYING_NUM_COMPONENTS,  
                VIVS_GL_VARYING_NUM_COMPONENTS_VAR0(4)| /* position */
                VIVS_GL_VARYING_NUM_COMPONENTS_VAR1(2)  /* texture coordinate */
                );
        etna_set_state(ctx, VIVS_GL_VARYING_TOTAL_COMPONENTS,
                VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(4 + 2)
                );
        etna_set_state_multi(ctx, VIVS_GL_VARYING_COMPONENT_USE(0), 2, (uint32_t[]){
                VIVS_GL_VARYING_COMPONENT_USE_COMP0(VARYING_COMPONENT_USE_USED) |
                VIVS_GL_VARYING_COMPONENT_USE_COMP1(VARYING_COMPONENT_USE_USED) |
                VIVS_GL_VARYING_COMPONENT_USE_COMP2(VARYING_COMPONENT_USE_USED) |
                VIVS_GL_VARYING_COMPONENT_USE_COMP3(VARYING_COMPONENT_USE_USED) |
                VIVS_GL_VARYING_COMPONENT_USE_COMP4(VARYING_COMPONENT_USE_USED) |
                VIVS_GL_VARYING_COMPONENT_USE_COMP5(VARYING_COMPONENT_USE_USED)
                , 0
                });

        etna_set_state(ctx, VIVS_PA_W_CLIP_LIMIT, 0x34000001);
        etna_set_state(ctx, VIVS_PA_SYSTEM_MODE, 0x11);
        etna_set_state(ctx, VIVS_PA_CONFIG, /* VIVS_PA_CONFIG_UNK22 | */
                                            VIVS_PA_CONFIG_CULL_FACE_MODE_CCW |
                                            VIVS_PA_CONFIG_FILL_MODE_SOLID |
                                            VIVS_PA_CONFIG_SHADE_MODEL_SMOOTH /* |
                                            VIVS_PA_CONFIG_POINT_SIZE_ENABLE |
                                            VIVS_PA_CONFIG_POINT_SPRITE_ENABLE*/);
        etna_set_state_f32(ctx, VIVS_PA_VIEWPORT_OFFSET_Z, 0.0);
        etna_set_state_f32(ctx, VIVS_PA_VIEWPORT_SCALE_Z, 1.0);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_OFFSET_X, width << 15);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_OFFSET_Y, height << 15);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_SCALE_X, width << 15);
        etna_set_state_fixp(ctx, VIVS_PA_VIEWPORT_SCALE_Y, height << 15);
        etna_set_state(ctx, VIVS_PA_ATTRIBUTE_ELEMENT_COUNT, 0x200);
        etna_set_state(ctx, VIVS_PA_SHADER_ATTRIBUTES(0), 0x200);
        etna_set_state(ctx, VIVS_PA_SHADER_ATTRIBUTES(1), 0x200);

        etna_set_state(ctx, VIVS_SE_CONFIG, 0x0);
        etna_set_state(ctx, VIVS_SE_DEPTH_SCALE, 0x0);
        etna_set_state(ctx, VIVS_SE_DEPTH_BIAS, 0x0);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_LEFT, 0);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_TOP, 0);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_RIGHT, (width << 16) | 5);
        etna_set_state_fixp(ctx, VIVS_SE_SCISSOR_BOTTOM, (height << 16) | 5);

        etna_set_state(ctx, VIVS_PE_ALPHA_CONFIG,
                /* VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_COLOR | */
                /* VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_ALPHA | */
                VIVS_PE_ALPHA_CONFIG_SRC_FUNC_COLOR(BLEND_FUNC_ONE) |
                VIVS_PE_ALPHA_CONFIG_SRC_FUNC_ALPHA(BLEND_FUNC_ONE) |
                VIVS_PE_ALPHA_CONFIG_DST_FUNC_COLOR(BLEND_FUNC_ZERO) |
                VIVS_PE_ALPHA_CONFIG_DST_FUNC_ALPHA(BLEND_FUNC_ZERO) |
                VIVS_PE_ALPHA_CONFIG_EQ_COLOR(BLEND_EQ_ADD) |
                VIVS_PE_ALPHA_CONFIG_EQ_ALPHA(BLEND_EQ_ADD));
        etna_set_state(ctx, VIVS_PE_ALPHA_BLEND_COLOR, 
                VIVS_PE_ALPHA_BLEND_COLOR_B(0) | 
                VIVS_PE_ALPHA_BLEND_COLOR_G(0) | 
                VIVS_PE_ALPHA_BLEND_COLOR_R(0) | 
                VIVS_PE_ALPHA_BLEND_COLOR_A(0));
        etna_set_state(ctx, VIVS_PE_ALPHA_OP, /* VIVS_PE_ALPHA_OP_ALPHA_TEST */ 0);
        etna_set_state(ctx, VIVS_PE_STENCIL_CONFIG, VIVS_PE_STENCIL_CONFIG_REF_FRONT(0) |
                                                    VIVS_PE_STENCIL_CONFIG_MASK_FRONT(0xff) | 
                                                    VIVS_PE_STENCIL_CONFIG_WRITE_MASK(0xff) |
                                                    VIVS_PE_STENCIL_CONFIG_MODE_DISABLED);
        etna_set_state(ctx, VIVS_PE_STENCIL_OP, VIVS_PE_STENCIL_OP_FUNC_FRONT(COMPARE_FUNC_ALWAYS) |
                                                VIVS_PE_STENCIL_OP_FUNC_BACK(COMPARE_FUNC_ALWAYS) |
                                                VIVS_PE_STENCIL_OP_FAIL_FRONT(STENCIL_OP_KEEP) | 
                                                VIVS_PE_STENCIL_OP_FAIL_BACK(STENCIL_OP_KEEP) |
                                                VIVS_PE_STENCIL_OP_DEPTH_FAIL_FRONT(STENCIL_OP_KEEP) |
                                                VIVS_PE_STENCIL_OP_DEPTH_FAIL_BACK(STENCIL_OP_KEEP) |
                                                VIVS_PE_STENCIL_OP_PASS_FRONT(STENCIL_OP_KEEP) |
                                                VIVS_PE_STENCIL_OP_PASS_BACK(STENCIL_OP_KEEP));
        etna_set_state(ctx, VIVS_PE_COLOR_FORMAT, 
                VIVS_PE_COLOR_FORMAT_COMPONENTS(0xf) |
                VIVS_PE_COLOR_FORMAT_FORMAT(RS_FORMAT_X8R8G8B8) |
                VIVS_PE_COLOR_FORMAT_SUPER_TILED |
                VIVS_PE_COLOR_FORMAT_OVERWRITE);
        etna_set_state(ctx, VIVS_PE_DEPTH_CONFIG, 
                VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D16 |
                VIVS_PE_DEPTH_CONFIG_SUPER_TILED |
                VIVS_PE_DEPTH_CONFIG_EARLY_Z |
                /* VIVS_PE_DEPTH_CONFIG_WRITE_ENABLE | */
                VIVS_PE_DEPTH_CONFIG_DEPTH_FUNC(COMPARE_FUNC_ALWAYS) |
                VIVS_PE_DEPTH_CONFIG_DEPTH_MODE_Z
                /* VIVS_PE_DEPTH_CONFIG_ONLY_DEPTH */
                );
        etna_set_state(ctx, VIVS_PE_DEPTH_ADDR, z->address);
        etna_set_state(ctx, VIVS_PE_DEPTH_STRIDE, padded_width * 2);
        etna_set_state(ctx, VIVS_PE_HDEPTH_CONTROL, VIVS_PE_HDEPTH_CONTROL_FORMAT_DISABLED);
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_NORMALIZE, 65535.0);
        etna_set_state(ctx, VIVS_PE_COLOR_ADDR, rt->address);
        etna_set_state(ctx, VIVS_PE_COLOR_STRIDE, padded_width * 4); 
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_NEAR, 0.0);
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_FAR, 1.0);
        etna_set_state_f32(ctx, VIVS_PE_DEPTH_NORMALIZE, 65535.0);

        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_set_state(ctx, VIVS_RS_FLUSH_CACHE, VIVS_RS_FLUSH_CACHE_FLUSH);
        etna_stall(ctx, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE);

        /* Set up the resolve to clear tile status for main render target 
         * Regard the TS plane as an image of width 16 with 4 bytes per pixel (64 bytes per row)
         * XXX need to clear the depth ts too? we don't really use depth buffer in this sample
         * */
        etna_set_state(ctx, VIVS_TS_MEM_CONFIG, 0);
        etna_set_state(ctx, VIVS_RS_CONFIG,
                VIVS_RS_CONFIG_SOURCE_FORMAT(RS_FORMAT_X8R8G8B8) |
                VIVS_RS_CONFIG_DEST_FORMAT(RS_FORMAT_X8R8G8B8)
                );
        etna_set_state_multi(ctx, VIVS_RS_DITHER(0), 2, (uint32_t[]){0xffffffff, 0xffffffff});
        etna_set_state(ctx, VIVS_RS_DEST_ADDR, rt_ts->address); /* ADDR_B */
        etna_set_state(ctx, VIVS_RS_DEST_STRIDE, 0x40);
        etna_set_state(ctx, VIVS_RS_WINDOW_SIZE, 
                ((rt_ts_size/0x40) << VIVS_RS_WINDOW_SIZE_HEIGHT__SHIFT) |
                (16 << VIVS_RS_WINDOW_SIZE_WIDTH__SHIFT));
        etna_set_state(ctx, VIVS_RS_FILL_VALUE(0), 0x55555555);
        etna_set_state(ctx, VIVS_RS_CLEAR_CONTROL, 
                VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1 |
                (0xffff << VIVS_RS_CLEAR_CONTROL_BITS__SHIFT));
        etna_set_state(ctx, VIVS_RS_EXTRA_CONFIG, 0);
        etna_set_state(ctx, VIVS_RS_KICKER, 0xbeebbeeb);
        /** Done */
       
        /* Now set up TS */
        etna_set_state(ctx, VIVS_TS_MEM_CONFIG, 
                VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR |
                VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR |
                VIVS_TS_MEM_CONFIG_DEPTH_16BPP | 
                VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION);
        etna_set_state(ctx, VIVS_TS_DEPTH_CLEAR_VALUE, 0xffffffff);
        etna_set_state(ctx, VIVS_TS_DEPTH_STATUS_BASE, z_ts->address);
        etna_set_state(ctx, VIVS_TS_DEPTH_SURFACE_BASE, z->address);
        etna_set_state(ctx, VIVS_TS_COLOR_CLEAR_VALUE, 0xff303030);
        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address);
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);

        /* set up texture unit */
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_TEXTURE);
        etna_set_state(ctx, VIVS_TE_SAMPLER_SIZE(0), 
                VIVS_TE_SAMPLER_SIZE_WIDTH(tex_base_width)|
                VIVS_TE_SAMPLER_SIZE_HEIGHT(tex_base_height));
        etna_set_state(ctx, VIVS_TE_SAMPLER_LOG_SIZE(0), 
                VIVS_TE_SAMPLER_LOG_SIZE_WIDTH(tex_base_log_width) |
                VIVS_TE_SAMPLER_LOG_SIZE_HEIGHT(tex_base_log_height));
        for(int ix=0; ix<dds->num_mipmaps; ++ix)
        {
            etna_set_state(ctx, VIVS_TE_SAMPLER_LOD_ADDR(0,ix), tex->address + dds->slices[0][ix].offset);
        }
        etna_set_state(ctx, VIVS_TE_SAMPLER_CONFIG0(0), 
                VIVS_TE_SAMPLER_CONFIG0_TYPE(TEXTURE_TYPE_2D)|
                VIVS_TE_SAMPLER_CONFIG0_UWRAP(TEXTURE_WRAPMODE_CLAMP_TO_EDGE)|
                VIVS_TE_SAMPLER_CONFIG0_VWRAP(TEXTURE_WRAPMODE_CLAMP_TO_EDGE)|
                VIVS_TE_SAMPLER_CONFIG0_MIN(TEXTURE_FILTER_LINEAR)|
                VIVS_TE_SAMPLER_CONFIG0_MIP(TEXTURE_FILTER_LINEAR)|
                VIVS_TE_SAMPLER_CONFIG0_MAG(TEXTURE_FILTER_LINEAR)|
                VIVS_TE_SAMPLER_CONFIG0_FORMAT(tex_format));
        etna_set_state(ctx, VIVS_TE_SAMPLER_LOD_CONFIG(0), 
                VIVS_TE_SAMPLER_LOD_CONFIG_MAX((dds->num_mipmaps - 1)<<5) | VIVS_TE_SAMPLER_LOD_CONFIG_MIN(0));
        //etna_set_state(ctx, VIVS_TE_SAMPLER_UNK2100(0), 0);
        //etna_set_state(ctx, VIVS_TE_SAMPLER_UNK2140(0), 0);

        /* shader setup */
        etna_set_state(ctx, VIVS_VS_START_PC, 0x0);
        etna_set_state(ctx, VIVS_VS_END_PC, vs_size/16);
        etna_set_state_multi(ctx, VIVS_VS_INPUT_COUNT, 3, (uint32_t[]){
                /* VIVS_VS_INPUT_COUNT */ VIVS_VS_INPUT_COUNT_UNK8(1) | VIVS_VS_INPUT_COUNT_COUNT(3),
                /* VIVS_VS_TEMP_REGISTER_CONTROL */ VIVS_VS_TEMP_REGISTER_CONTROL_NUM_TEMPS(6),
                /* VIVS_VS_OUTPUT(0) */ VIVS_VS_OUTPUT_O0(4) | 
                                        VIVS_VS_OUTPUT_O1(0) | 
                                        VIVS_VS_OUTPUT_O2(1)});
        etna_set_state_multi(ctx, VIVS_VS_INST_MEM(0), vs_size/4, vs);
        etna_set_state(ctx, VIVS_VS_OUTPUT_COUNT, 3);
        etna_set_state(ctx, VIVS_VS_LOAD_BALANCING, 0xf3f0542); /* depends on number of inputs/outputs/varyings? XXX how exactly */
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(0), 16, (uint32_t*)&modelviewprojection.m[0][0]);
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(16), 3, (uint32_t*)&normal.m[0][0]); /* u4.xyz */
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(20), 3, (uint32_t*)&normal.m[1][0]); /* u5.xyz */
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(24), 3, (uint32_t*)&normal.m[2][0]); /* u6.xyz */
        etna_set_state_multi(ctx, VIVS_VS_UNIFORMS(28), 16, (uint32_t*)&modelview.m[0][0]);
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(19), 2.0); /* u4.w */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(23), 20.0); /* u5.w */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(27), 0.0); /* u6.w */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(45), 0.5); /* u11.y */
        etna_set_state_f32(ctx, VIVS_VS_UNIFORMS(44), 1.0); /* u11.x */
        etna_set_state(ctx, VIVS_VS_INPUT(0), VIVS_VS_INPUT_I0(0) | 
                                        VIVS_VS_INPUT_I1(1) | 
                                        VIVS_VS_INPUT_I2(2));

        etna_set_state(ctx, VIVS_PS_START_PC, 0x0);
        etna_set_state_multi(ctx, VIVS_PS_END_PC, 2, (uint32_t[]){
                /* VIVS_PS_END_PC */ ps_size/16,
                /* VIVS_PS_OUTPUT_REG */ 0x1});
        etna_set_state_multi(ctx, VIVS_PS_INST_MEM(0), ps_size/4, ps);
        etna_set_state(ctx, VIVS_PS_INPUT_COUNT, VIVS_PS_INPUT_COUNT_UNK8(31) | VIVS_PS_INPUT_COUNT_COUNT(3));
        etna_set_state(ctx, VIVS_PS_TEMP_REGISTER_CONTROL, VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(3));
        etna_set_state(ctx, VIVS_PS_CONTROL, VIVS_PS_CONTROL_UNK1);
        etna_set_state_f32(ctx, VIVS_PS_UNIFORMS(0), 1.0); /* u0.x */

        etna_set_state(ctx, VIVS_FE_VERTEX_STREAM_BASE_ADDR, vtx->address); /* ADDR_E */
        etna_set_state(ctx, VIVS_FE_VERTEX_STREAM_CONTROL, 
                VIVS_FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE((3 + 3 + 2)*4));
        etna_set_state(ctx, VIVS_FE_VERTEX_ELEMENT_CONFIG(0), 
                VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT |
                (ENDIAN_MODE_NO_SWAP << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(0) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(3) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_START(0x0) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_END(0xc));
        etna_set_state(ctx, VIVS_FE_VERTEX_ELEMENT_CONFIG(1), 
                VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT |
                (ENDIAN_MODE_NO_SWAP << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(0) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(3) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_START(0xc) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_END(0x18));
        etna_set_state(ctx, VIVS_FE_VERTEX_ELEMENT_CONFIG(2), 
                VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT |
                (ENDIAN_MODE_NO_SWAP << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NONCONSECUTIVE |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(0) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(2) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_START(0x18) |
                VIVS_FE_VERTEX_ELEMENT_CONFIG_END(0x20));

        for(int prim=0; prim<6; ++prim)
        {
            etna_draw_primitives(ctx, PRIMITIVE_TYPE_TRIANGLE_STRIP, prim*4, 2);
        }
#if 0
        /* resolve to self */
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_set_state(ctx, VIVS_RS_CONFIG,
                VIVS_RS_CONFIG_SOURCE_FORMAT(RS_FORMAT_X8R8G8B8) |
                VIVS_RS_CONFIG_SOURCE_TILED |
                VIVS_RS_CONFIG_DEST_FORMAT(RS_FORMAT_X8R8G8B8) |
                VIVS_RS_CONFIG_DEST_TILED);
        etna_set_state(ctx, VIVS_RS_SOURCE_STRIDE, (padded_width * 4 * 4) | VIVS_RS_SOURCE_STRIDE_TILING);
        etna_set_state(ctx, VIVS_RS_DEST_STRIDE, (padded_width * 4 * 4) | VIVS_RS_DEST_STRIDE_TILING);
        etna_set_state(ctx, VIVS_RS_DITHER(0), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_DITHER(1), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_CLEAR_CONTROL, VIVS_RS_CLEAR_CONTROL_MODE_DISABLED);
        etna_set_state(ctx, VIVS_RS_EXTRA_CONFIG, 0); /* no AA, no endian switch */
        etna_set_state(ctx, VIVS_RS_SOURCE_ADDR, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_RS_DEST_ADDR, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_RS_WINDOW_SIZE, 
                VIVS_RS_WINDOW_SIZE_HEIGHT(padded_height) |
                VIVS_RS_WINDOW_SIZE_WIDTH(padded_width));
        etna_set_state(ctx, VIVS_RS_KICKER, 0xbeebbeeb);

        etna_set_state(ctx, VIVS_RS_FLUSH_CACHE, VIVS_RS_FLUSH_CACHE_FLUSH);

        etna_set_state(ctx, VIVS_TS_COLOR_STATUS_BASE, rt_ts->address); /* ADDR_B */
        etna_set_state(ctx, VIVS_TS_COLOR_SURFACE_BASE, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);
        etna_set_state(ctx, VIVS_TS_MEM_CONFIG, 
                VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR |
                VIVS_TS_MEM_CONFIG_DEPTH_16BPP | 
                VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);
#endif
        etna_stall(ctx, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);

        /* copy to screen */
        etna_bswap_wait_available(buffers);
        etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH);
        etna_set_state(ctx, VIVS_RS_CONFIG,
                VIVS_RS_CONFIG_SOURCE_FORMAT(RS_FORMAT_X8R8G8B8) |
                VIVS_RS_CONFIG_SOURCE_TILED |
                VIVS_RS_CONFIG_DEST_FORMAT(RS_FORMAT_X8R8G8B8) |
                VIVS_RS_CONFIG_SWAP_RB);
        etna_set_state(ctx, VIVS_RS_SOURCE_STRIDE, (padded_width * 4 * 4) | VIVS_RS_SOURCE_STRIDE_TILING);
        etna_set_state(ctx, VIVS_RS_DEST_STRIDE, fb.fb_fix.line_length);
        etna_set_state(ctx, VIVS_RS_DITHER(0), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_DITHER(1), 0xffffffff);
        etna_set_state(ctx, VIVS_RS_CLEAR_CONTROL, VIVS_RS_CLEAR_CONTROL_MODE_DISABLED);
        etna_set_state(ctx, VIVS_RS_EXTRA_CONFIG, 
                0); /* no AA, no endian switch */
        etna_set_state(ctx, VIVS_RS_SOURCE_ADDR, rt->address); /* ADDR_A */
        etna_set_state(ctx, VIVS_RS_DEST_ADDR, fb.physical[buffers->backbuffer]); /* ADDR_J */
        etna_set_state(ctx, VIVS_RS_WINDOW_SIZE, 
                VIVS_RS_WINDOW_SIZE_HEIGHT(height) |
                VIVS_RS_WINDOW_SIZE_WIDTH(width));
        etna_set_state(ctx, VIVS_RS_KICKER, 0xbeebbeeb);

        etna_flush(ctx);
        etna_bswap_queue_swap(buffers);
    }
#ifdef DUMP
    bmp_dump32(fb.logical[1-backbuffer], width, height, false, "/mnt/sdcard/fb.bmp");
    printf("Dump complete\n");
#endif
    etna_bswap_free(buffers);
    etna_free(ctx);
    viv_close();
    return 0;
}