ios,android读取文件

ios,android读取文件
不同平台读取文件的方式是不一样的。我们来看代码:
/********************************************************************
 Copyright(C), 2012-2013,
 FileName:FileUnits.h
 Description:
 Author:cloud
 Created:2014/10/17
 history:
17:10:2014 16:54 by
*********************************************************************/
#pragma once
#include "Singleton.h"
#include "PlatformConfig.h"



namespace cloud
{

	class FileUtils:public Singleton<FileUtils>
	{
	public:
		DECLARE_SINGLETON_CREATE_DESTROY
		FileUtils(void);
		~FileUtils(void);
		void readFile(const char* filePathName,unsigned char** outData,unsigned int& outLen);
		void writeFile(const char* filePathName,unsigned char* inData,unsigned int inLen);
	private:
		
		
	};

}

/********************************************************************
 Copyright(C), 2012-2013,
 FileName:FileUtils.cpp
 Description:
 Author:cloud
 Created:2014/10/17
 history:
17:10:2014 16:55 by
*********************************************************************/
#include "FileUtils.h"
#include <string>
#if (TARGET_PLATFORM == PLATFORM_ANDROID)
#include "FileUtilsAndroid.h"
#elif (TARGET_PLATFORM == PLATFORM_IOS)
#include "FileUtilsIos.h"
#endif




namespace cloud
{	
	IMPLEMENT_SINGLETON_ALL(FileUtils);
	FileUtils::FileUtils()
	{

	}

	FileUtils::~FileUtils()
	{
		
	}


	void FileUtils::readFile(const char* filePathName,unsigned char** outData,unsigned int& outLen)
	{
#if (TARGET_PLATFORM == PLATFORM_ANDROID)
		FileUtilsAndroid::readFile(filePathName,outData,outLen);
#elif (TARGET_PLATFORM == PLATFORM_IOS) 
		FileUtilsIos::readFile(filePathName,outData,outLen);
#elif (TARGET_PLATFORM == PLATFORM_WIN32)
		FILE *fp = fopen(filePathName, "rb");
		if (fp == NULL)
		{
			return;
		}
		fseek(fp,0,SEEK_END);
		outLen = ftell(fp);
		fseek(fp,0,SEEK_SET);
		unsigned char* data = (unsigned char*)malloc(outLen);
		fread(data,1,outLen,fp);
		*outData = data;		
		fclose(fp);

#endif

	}

	void FileUtils::writeFile(const char* filePathName,unsigned char* outData,unsigned int outLen)
	{

	}
}
win32直接fopen读取,ios 会调用FileUtilsIos读取,android会调用FileUtilsAndroid读取。
/********************************************************************
 Copyright(C), 2012-2013,
 FileName:FileUnitsIos.cpp
 Description:
 Author:cloud
 Created:2014/10/17
 history:
17:10:2014 16:55 by
*********************************************************************/
#include "FileUtilsIos.h"
#include <string>



namespace cloud
{	
	void FileUtilsIos::readFile(const char* filePathName,unsigned char** outData,unsigned int& outLen)
	{
		NSString* file = [NSString stringWithUTF8String:filePathName];
        NSString* path = [[NSBundle mainBundle] pathForResource:file ofType:nil];
        NSData *fileData = [NSData dataWithContentsOfFile:path];
        outLen = [fileData length];
		unsigned char* putData = (unsigned char*)[fileData bytes];
        unsigned char* data = (unsigned char*)malloc(outLen);
        memcpy(data,putData,outLen);
        *outData = data;
	}

	void FileUtilsIos::writeFile(const char* filePathName,unsigned char* outData,unsigned int outLen)
	{

	}
}
android 稍微复杂点.
/********************************************************************
 Copyright(C), 2012-2013,
 FileName:FileUnitsAndroid.cpp
 Description:
 Author:cloud
 Created:2014/10/17
 history:
17:10:2014 16:55 by
*********************************************************************/
#include "FileUtilsAndroid.h"
#include <string>



namespace cloud
{	

	AAssetManager* FileUtilsAndroid::assetmanager = nullptr;

	void FileUtilsAndroid::setAssetmanager(AAssetManager* a) {
		if (nullptr == a) {
			
			return;
		}
		FileUtilsAndroid::assetmanager = a;
	}


	void FileUtilsAndroid::readFile(const char* filePathName,unsigned char** outData,unsigned int& outLen)
	{
		// read asset data
		AAsset* asset =
			AAssetManager_open(FileUtilsAndroid::assetmanager,
			filePathName,
			AASSET_MODE_UNKNOWN);
		if (nullptr == asset) {
			return ;
		}
		bool forString = false;
		off_t fileSize = AAsset_getLength(asset);
		unsigned char* data = NULL;
		if (forString)
		{
			data = (unsigned char*) malloc(fileSize + 1);
			data[fileSize] = '\0';
		}
		else
		{
			data = (unsigned char*) malloc(fileSize);
		}

		int bytesread = AAsset_read(asset, (void*)data, fileSize);
		int size = bytesread;

		AAsset_close(asset);
		*outData = data;
		outLen = size;
	}

	void FileUtilsAndroid::writeFile(const char* filePathName,unsigned char* outData,unsigned int outLen)
	{

	}
}

asserts 的设置在这里
void Java_com_cloudgame_org_GameJniHelper_initGameAssets(JNIEnv *env, jclass cls,jobject assetManager)
	{
		AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
		cloud::FileUtilsAndroid::setAssetmanager(mgr);
		LOG("init assets");
	}

package com.cloudgame.org;
import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;

public class GameJniHelper {
	void initJniHelperMethod(Activity activity)
	{
		
		initGameAssets(activity.getAssets());
	}
	
	
	private native void initGameAssets(AssetManager ass);	
	static {
		System.loadLibrary("cloudGameEngine");
		}
}

来看渲染吧。
/********************************************************************
 Copyright(C), 2012-2013,
 FileName:Renderer.cpp
 Description:
 Author:cloud
 Created:2014/10/17
 history:
17:10:2014 16:55 by
*********************************************************************/
#include "Renderer.h"
#include "Engine.h"
#include "FileUtils.h"


#include "vector"
#include "string"
#include <fstream>
#define STRINGIFY(A) #A


namespace cloud
{	
	typedef struct {
		float _position[3];
		float _color[4];
		float _texCoord[2];
	} Vertex;

	//
	//测试代码
	// An array of 3 vectors which represents 3 vertices
	
	Vertex Vertices[] = {	
		{{-80,  120, 1}, {1, 1, 1, 1}, {0, 1}},

		{{-80, -120, 1}, {1, 1, 1, 1}, {0, 0}},

		{{ 80,  120, 1}, {1, 1, 1, 1}, {1, 1}},

		{{ 80, -120, 1}, {1, 1, 1, 1}, {1, 0}}	

	};

	

	static void checkGlError(const char* op) {
		for (GLint error = glGetError(); error; error
			= glGetError()) {
				LOG("after %s() glError (0x%x)\n", op, error);
		}
	}
	GLuint Texture = 0;
	
	GLuint loadBMP_custom(const char * imagepath)
	{
		// Data read from the header of the BMP file
		unsigned char header[54]; // Each BMP file begins by a 54-bytes header
		unsigned int dataPos;     //Position in the file where the actual data begins
		unsigned int width,height;
		unsigned int imageSize;    //= width*height*3
		// Actual RGB data
		unsigned char * data;


		unsigned char* outData = NULL;
		unsigned int outLen = 0;
		FileUtils::getInstance()->readFile(imagepath,&outData,outLen);
		memcpy(header,outData,54);		

		if (header[0] != 'B' || header[1] != 'M')
		{
			printf("Not a correct BMP filen");
			return 0;
		}

		dataPos		= *(int*)&(header[0x0A]);
		imageSize	= *(int*)&(header[0x22]);
		width		= *(int*)&(header[0x12]);
		height		= *(int*)&(header[0x16]);

		if (imageSize == 0)
		{
			imageSize = width * height * 3;
		}

		if (dataPos == 0)
		{
			dataPos = 54;
		}

		// Create a buffer
		data = new unsigned char [imageSize];
		// Read the actual data from the file into the buffer
		memcpy(data,outData+54,imageSize);
		//Everything is in memory now, the file can be closed
		free(outData);



		GLuint textureID;
		glGenTextures(1, &textureID);

		// "Bind" the newly created texture : all future texture functions will modify this texture
		glBindTexture(GL_TEXTURE_2D, textureID);

		// Give the image to OpenGL
		glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

		// 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		// 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		// 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		// 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		// 	glGenerateMipmap(GL_TEXTURE_2D);
		delete[] data;
		return textureID;

	}
	//


	

	IMPLEMENT_SINGLETON_ALL(Renderer);
	Renderer::Renderer(void):_isInit(false)
	{		
		
	}

	void Renderer::resetProjection()
	{
		Size designSize = Engine::getInstance()->getDesignSize();		
		_projection =glm::ortho(-designSize.width * 0.5f, designSize.width * 0.5f, -designSize.height * 0.5f, designSize.height * 0.5f, 0.1f, 100.0f);	
	}

	Renderer::~Renderer(void)
	{
	}

	GLuint Renderer::LoadShaders()
	{
		//Create the shaders
		int VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
		int FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);


		static const char* VERTEX_SHADER =STRINGIFY(
		uniform mat4 uMVPMatrix;
		attribute vec3 vertexPosition;
		attribute vec2 vertexUV;
		attribute vec4 vertexColor;
		
		varying vec2 UV;
		varying vec4 color;


		void main(void)
		{
			vec4 v = vec4(vertexPosition,1);
			gl_Position = uMVPMatrix * v;			
			UV = vertexUV;
			color = vertexColor;
		}

		);

		static const char * FRAG_SHADER=STRINGIFY(
		varying mediump vec2 UV;
		varying mediump vec4 color;
		uniform sampler2D myTextureSampler;
		void main(void)
		{
			gl_FragColor =   color * texture2D( myTextureSampler,UV);
		}

		);

		


		int Result = GL_FALSE;
		int InfoLogLength;

		//compile Vertex Shader
		LOG("Compiling shader : n");
		char const * VertexSourcePointer = VERTEX_SHADER;
		glShaderSource(VertexShaderID,1,&VertexSourcePointer,NULL);
		glCompileShader(VertexShaderID);

		// Check vertex Shader
		glGetShaderiv(VertexShaderID,GL_COMPILE_STATUS,&Result);
		glGetShaderiv(VertexShaderID,GL_INFO_LOG_LENGTH,&InfoLogLength);
 		std::vector<char> VerTexShaderErrorMessage(InfoLogLength); 
 		glGetShaderInfoLog(VertexShaderID,InfoLogLength,NULL,&VerTexShaderErrorMessage[0]);
 		LOG("%s\n",&VerTexShaderErrorMessage[0]);

		//compile Fragment Shader
		LOG("Compiling shader : n");
		char const * FragmentSourcePointer = FRAG_SHADER;
		glShaderSource(FragmentShaderID,1,&FragmentSourcePointer,NULL);
		glCompileShader(FragmentShaderID);

		// Check vertex Shader
		glGetShaderiv(FragmentShaderID,GL_COMPILE_STATUS,&Result);
		glGetShaderiv(FragmentShaderID,GL_INFO_LOG_LENGTH,&InfoLogLength);
 		std::vector<char> FragmentShaderErrorMessage(InfoLogLength); 
 		glGetShaderInfoLog(FragmentShaderID,InfoLogLength,NULL,&FragmentShaderErrorMessage[0]);
 		LOG("%s\n",&FragmentShaderErrorMessage[0]);

		//Link the program
		LOG("Linking programn");
		GLuint ProgramID = glCreateProgram();
		glAttachShader(ProgramID,VertexShaderID);
		glAttachShader(ProgramID,FragmentShaderID);
		glLinkProgram(ProgramID);

		//Check the program
		glGetProgramiv(ProgramID,GL_LINK_STATUS,&Result);
		glGetProgramiv(ProgramID,GL_INFO_LOG_LENGTH,&InfoLogLength);
		std::vector<char> ProgramErrorMessage(InfoLogLength);
		//glGetProgramInfoLog(ProgramID,InfoLogLength,NULL,&ProgramErrorMessage[0]);
		//LOG("%s\n",&ProgramErrorMessage[0]);

		glDeleteShader(VertexShaderID);
		glDeleteShader(FragmentShaderID);

		return ProgramID;
	}

	void Renderer::renderQuad()
	{
		
		if(!_isInit)
		{
			_programID = LoadShaders();				
			_view = glm::lookAt(
				glm::vec3(0,0,100), // Camera is at (4,3,3), in World Space
				glm::vec3(0,0,0), // and looks at the origin
				glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)		
				);
			glUseProgram(_programID);
			_matrixID = glGetUniformLocation(_programID,"uMVPMatrix");
			_vertexPosition = glGetAttribLocation(_programID,"vertexPosition");
			_vertexUV = glGetAttribLocation(_programID,"vertexUV");
			_vertexColor = glGetAttribLocation(_programID,"vertexColor");
			resetProjection();	
			

			glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
			Texture = loadBMP_custom("uvtemplate.bmp");
			_isInit = true;
		}
		



		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		
		caculateMVP(Mat4(1.0f));
		glBindTexture(GL_TEXTURE_2D,Texture);
		
		

int kQuadSize  = sizeof(Vertex);
 		long offset = (long)Vertices;
		int diff = offsetof( Vertex, _position);

		glEnableVertexAttribArray(_vertexPosition); 	
		glVertexAttribPointer(
			_vertexPosition,			// attribute 0. No particular reason for 0, but must match the layout in the shader.
			3,			// size
			GL_FLOAT,	// type
			GL_FALSE,	// normalized?
			kQuadSize,			// stride
			(void*)(offset + diff)	// array buffer offset
			);



		diff = offsetof( Vertex, _texCoord);
		glEnableVertexAttribArray(_vertexUV); 	
		glVertexAttribPointer(
			_vertexUV,			// attribute 0. No particular reason for 0, but must match the layout in the shader.
			2,			// size
			GL_FLOAT,	// type
			GL_FALSE,	// normalized?
			kQuadSize,			// stride
			(void*)(offset + diff)	// array buffer offset
			);


		diff = offsetof( Vertex, _color);		
		glEnableVertexAttribArray(_vertexColor); 				
		glVertexAttribPointer(
			_vertexColor,			// attribute 0. No particular reason for 0, but must match the layout in the shader.
			4,			// size
			GL_FLOAT,	// type
			GL_FALSE,	// normalized?
			kQuadSize,			// stride
			(void*)(offset + diff)	// array buffer offset
			);
		
		glDrawArrays(GL_TRIANGLE_STRIP,0,4);// Starting from vertex 0; 3 vertices total -> 1 triangle          

		glDisableVertexAttribArray(0);
		glDisableVertexAttribArray(1);
		glDisableVertexAttribArray(2);
	}

	void Renderer::caculateMVP(Mat4 model)
	{   		
				
		Mat4 MVP = _projection * _view * model;// Remember, matrix multiplication is the other way around					
		glUniformMatrix4fv(_matrixID,1,GL_FALSE,&MVP[0][0]);		
		
		
	}
}

这样就能读取纹理并且渲染了。
这里遇到两个神bug,glGetProgramInfoLog在android平台出错,但显示是mvp设置出错。之前,glEnableVertexAttribArray,glVertexAttribPointer是手写固定的0,1,2.win32与android没问题,ios上位置不正确。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值