CMakeLists
Kod:
GrpOpenGL.cpp:
GrpOpenGL.h:
Ekli dosyayı görüntüle 175867
AndroidMain.cpp:
Bu projenin temel amaçları kesin ve öz olarak şunlardır:
Bu projede kullanılan temel modernizasyon yaklaşımı, oyunun C++ çekirdeğine "sanal" bir cihaz (Direct3D 8 aygıtı taklidi yapan bir ara katman) sunmaktır. Bu sayede oyun motorunun geri kalanı, kendisinin bir mobil cihazda olduğunu anlamadan normal şekilde çalışmaya devam eder.
EterPack kütüphanesi, oyunun .epk ve .eix dosyalarını yönetir. EterPackManager, dosyaları okumak için Android'in Storage Access Framework (SAF) veya assets kısımlarını yerel C++ üzerinden kullanacak şekilde modifiye edilmiştir (MappedFile.cpp). Bu, haritaların veya karakterlerin yüklenirken donma (lag) yaşamasının önlenmesi için kritik öneme sahiptir.
İndir OPENGL ITJA zip
İndir rar
Kod:
cmake_minimum_required(VERSION 3.10.2)
project("Metin2Mobile")
add_definitions(-D__ANDROID__)
add_definitions(-DENABLE_OPENGL)
add_definitions(-DENABLE_MOBILE_CONTROLS)
add_definitions(-DLOCALE_SERVICE_EUROPE)
if(ANDROID)
# Some older Granny versions use these for 64-bit
add_definitions(-DGRANNY_ONLY_TYPES)
endif()
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/android_compat
${CMAKE_CURRENT_SOURCE_DIR}/../Extern/include
${CMAKE_CURRENT_SOURCE_DIR}/../Extern/include/granny2
${CMAKE_CURRENT_SOURCE_DIR}/../Extern/include/Python2
${CMAKE_CURRENT_SOURCE_DIR}/../common
${CMAKE_CURRENT_SOURCE_DIR}/eterBase
${CMAKE_CURRENT_SOURCE_DIR}/eterLib
${CMAKE_CURRENT_SOURCE_DIR}/eterPythonLib
${CMAKE_CURRENT_SOURCE_DIR}/gameLib
${CMAKE_CURRENT_SOURCE_DIR}/userInterface
${CMAKE_CURRENT_SOURCE_DIR}/milesLib
${CMAKE_CURRENT_SOURCE_DIR}/effectLib
${CMAKE_CURRENT_SOURCE_DIR}/sphereLib
${CMAKE_CURRENT_SOURCE_DIR}/eterPack
${CMAKE_CURRENT_SOURCE_DIR}/eterGrnLib
${CMAKE_CURRENT_SOURCE_DIR}/eterImageLib
${CMAKE_CURRENT_SOURCE_DIR}/speedTreeLib
${CMAKE_CURRENT_SOURCE_DIR}/prTerrainLib
${CMAKE_CURRENT_SOURCE_DIR}/scriptLib
${CMAKE_CURRENT_SOURCE_DIR}/eterLocale
${CMAKE_CURRENT_SOURCE_DIR}/cWebBrowser
)
set(ETER_BASE_SOURCES
eterBase/CPostIt.cpp
eterBase/CRC32.cpp
eterBase/Debug.cpp
eterBase/FileBase.cpp
eterBase/FileDir.cpp
eterBase/FileLoader.cpp
eterBase/MappedFile.cpp
eterBase/Random.cpp
eterBase/StdAfx.cpp
eterBase/Stl.cpp
eterBase/TempFile.cpp
eterBase/Timer.cpp
eterBase/Utils.cpp
eterBase/cipher.cpp
eterBase/error.cpp
eterBase/lzo.cpp
eterBase/tea.cpp
)
set(ETER_LIB_SOURCES
eterLib/Camera.cpp
eterLib/GrpDevice.cpp
eterLib/GrpObjectInstance.cpp
eterLib/GrpScreen.cpp
eterLib/GrpTexture.cpp
eterLib/GrpImageTexture.cpp
eterLib/GrpOpenGL.cpp
eterLib/GrpBase.cpp
eterLib/GrpColor.cpp
eterLib/GrpColorInstance.cpp
eterLib/GrpImage.cpp
eterLib/GrpImageInstance.cpp
eterLib/GrpIndexBuffer.cpp
eterLib/GrpMath.cpp
eterLib/GrpVertexBuffer.cpp
eterLib/GrpText.cpp
eterLib/GrpTextInstance.cpp
eterLib/MSApplication.cpp
eterLib/Input.cpp
eterLib/NetDevice.cpp
eterLib/ResourceManager.cpp
eterLib/NetAddress.cpp
eterLib/NetDatagramReceiver.cpp
eterLib/NetDatagramSender.cpp
eterLib/NetStream.cpp
eterLib/StdAfx.cpp
eterLib/AttributeData.cpp
eterLib/AttributeInstance.cpp
eterLib/CollisionData.cpp
eterLib/Resource.cpp
eterLib/TargaResource.cpp
eterLib/TextFileLoader.cpp
eterLib/Util.cpp
)
set(ETER_IMAGE_LIB_SOURCES
eterImageLib/DXTCImage.cpp
eterImageLib/Image.cpp
eterImageLib/StdAfx.cpp
eterImageLib/TGAImage.cpp
eterImageLib/stb_image.cpp
)
set(GAME_LIB_SOURCES
gameLib/Area.cpp
gameLib/AreaLoaderThread.cpp
gameLib/ActorInstance.cpp
gameLib/ActorInstanceAttach.cpp
gameLib/ActorInstanceBattle.cpp
gameLib/ActorInstanceBlend.cpp
gameLib/ActorInstanceCollisionDetection.cpp
gameLib/ActorInstanceData.cpp
gameLib/ActorInstanceEvent.cpp
gameLib/ActorInstanceFly.cpp
gameLib/ActorInstanceMotion.cpp
gameLib/ActorInstanceMotionEvent.cpp
gameLib/ActorInstancePosition.cpp
gameLib/ActorInstanceRender.cpp
gameLib/ActorInstanceRotation.cpp
gameLib/ActorInstanceSync.cpp
gameLib/ActorInstanceWeaponTrace.cpp
gameLib/FlyingInstance.cpp
gameLib/GameEventManager.cpp
gameLib/ItemData.cpp
gameLib/ItemManager.cpp
gameLib/MapManager.cpp
gameLib/MapOutdoor.cpp
gameLib/PropertyManager.cpp
gameLib/RaceData.cpp
gameLib/RaceManager.cpp
gameLib/StdAfx.cpp
)
set(USER_INTERFACE_SOURCES
userInterface/AndroidMain.cpp
userInterface/PythonApplication.cpp
userInterface/PythonApplicationModule.cpp
userInterface/PythonPlayerModule.cpp
userInterface/PythonPlayer.cpp
userInterface/PythonNetworkStream.cpp
userInterface/PythonNetworkStreamModule.cpp
userInterface/PythonNetworkStreamPhaseGame.cpp
userInterface/PythonNetworkStreamPhaseLoading.cpp
userInterface/PythonNetworkStreamPhaseLogin.cpp
userInterface/PythonNetworkStreamPhaseSelect.cpp
userInterface/UserInterface.cpp
userInterface/StdAfx.cpp
)
set(ETER_PACK_SOURCES
eterPack/EterPack.cpp
eterPack/EterPackCursor.cpp
eterPack/EterPackManager.cpp
eterPack/EterPackPolicy_CSHybridCrypt.cpp
eterPack/md5.c
eterPack/StdAfx.cpp
)
set(ETER_GRN_LIB_SOURCES
eterGrnLib/Material.cpp
eterGrnLib/Mesh.cpp
eterGrnLib/Model.cpp
eterGrnLib/ModelInstance.cpp
eterGrnLib/ModelInstanceCollisionDetection.cpp
eterGrnLib/ModelInstanceModel.cpp
eterGrnLib/ModelInstanceRender.cpp
eterGrnLib/ModelInstanceUpdate.cpp
eterGrnLib/StdAfx.cpp
eterGrnLib/Thing.cpp
eterGrnLib/ThingInstance.cpp
)
set(EFFECT_LIB_SOURCES
effectLib/EffectData.cpp
effectLib/EffectElementBase.cpp
effectLib/EffectElementBaseInstance.cpp
effectLib/EffectInstance.cpp
effectLib/EffectManager.cpp
effectLib/EffectMesh.cpp
effectLib/EffectMeshInstance.cpp
effectLib/EffectUpdateDecorator.cpp
effectLib/EmitterProperty.cpp
effectLib/FrameController.cpp
effectLib/ParticleInstance.cpp
effectLib/ParticleProperty.cpp
effectLib/ParticleSystemData.cpp
effectLib/ParticleSystemInstance.cpp
effectLib/SimpleLightData.cpp
effectLib/SimpleLightInstance.cpp
effectLib/StdAfx.cpp
effectLib/Type.cpp
)
set(ETER_PYTHON_LIB_SOURCES
eterPythonLib/PythonGraphic.cpp
eterPythonLib/PythonGraphicImageModule.cpp
eterPythonLib/PythonGraphicModule.cpp
eterPythonLib/PythonGraphicTextModule.cpp
eterPythonLib/PythonGraphicThingModule.cpp
eterPythonLib/PythonGridSlotWindow.cpp
eterPythonLib/PythonSlotWindow.cpp
eterPythonLib/PythonWindow.cpp
eterPythonLib/PythonWindowManager.cpp
eterPythonLib/PythonWindowManagerModule.cpp
eterPythonLib/StdAfx.cpp
)
set(SCRIPT_LIB_SOURCES
scriptLib/PythonDebugModule.cpp
scriptLib/PythonLauncher.cpp
scriptLib/PythonMarshal.cpp
scriptLib/PythonUtils.cpp
scriptLib/Resource.cpp
scriptLib/StdAfx.cpp
)
set(SPHERE_LIB_SOURCES
sphereLib/frustum.cpp
sphereLib/sphere.cpp
sphereLib/spherepack.cpp
sphereLib/StdAfx.cpp
)
set(MILES_LIB_SOURCES
milesLib/SoundBase.cpp
milesLib/SoundData.cpp
milesLib/SoundInstance2D.cpp
milesLib/SoundInstance3D.cpp
milesLib/SoundInstanceStream.cpp
milesLib/SoundManager.cpp
milesLib/SoundManager2D.cpp
milesLib/SoundManager3D.cpp
milesLib/SoundManagerStream.cpp
milesLib/Stdafx.cpp
milesLib/Type.cpp
)
set(SPEED_TREE_LIB_SOURCES
speedTreeLib/BoundaryShapeManager.cpp
speedTreeLib/SpeedGrassRT.cpp
speedTreeLib/SpeedGrassWrapper.cpp
speedTreeLib/SpeedTreeForest.cpp
speedTreeLib/SpeedTreeForestDirectX8.cpp
speedTreeLib/SpeedTreeWrapper.cpp
speedTreeLib/StdAfx.cpp
)
set(PR_TERRAIN_LIB_SOURCES
prTerrainLib/Terrain.cpp
prTerrainLib/TextureSet.cpp
prTerrainLib/StdAfx.cpp
)
set(ETER_LOCALE_SOURCES
eterLocale/Arabic.cpp
eterLocale/Japanese.cpp
eterLocale/StringCodec.cpp
eterLocale/StringCodec_Vietnamese.cpp
eterLocale/StdAfx.cpp
)
if(NOT ANDROID)
set(C_WEB_BROWSER_SOURCES
cWebBrowser/CWebBrowser.c
)
add_definitions(-DENABLE_WEB_BROWSER) # Optional flag if the code needs it
else()
set(C_WEB_BROWSER_SOURCES "")
endif()
add_library(metin2_mobile SHARED
${USER_INTERFACE_SOURCES}
${ETER_BASE_SOURCES}
${ETER_LIB_SOURCES}
${ETER_IMAGE_LIB_SOURCES}
${GAME_LIB_SOURCES}
${ETER_PACK_SOURCES}
${ETER_GRN_LIB_SOURCES}
${EFFECT_LIB_SOURCES}
${ETER_PYTHON_LIB_SOURCES}
${SCRIPT_LIB_SOURCES}
${SPHERE_LIB_SOURCES}
${MILES_LIB_SOURCES}
${SPEED_TREE_LIB_SOURCES}
${PR_TERRAIN_LIB_SOURCES}
${ETER_LOCALE_SOURCES}
${C_WEB_BROWSER_SOURCES}
)
# Extern Library linking
set(EXTERN_LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../Extern/lib/android/${ANDROID_ABI})
link_directories(${EXTERN_LIB_PATH})
find_library(log-lib log)
find_library(android-lib android)
find_library(gles3-lib GLESv3)
# Common Metin2 Libraries (Static)
set(METIN2_EXTERN_LIBS
python2.7
cryptopp
lzo2
il
ilu
ilut
jpeg
png
speedtree
granny2
mss
)
target_link_libraries(metin2_mobile
${log-lib}
${android-lib}
${gles3-lib}
${METIN2_EXTERN_LIBS}
z
m
)
GrpOpenGL.cpp:
#include "StdAfx.h"
[HASH=2388]#include[/HASH] "GrpOpenGL.h"
[HASH=2]#ifdef[/HASH] ENABLE_OPENGL
[HASH=2]#ifdef[/HASH] ANDROID
[HASH=2388]#include[/HASH] <android/log.h>
[HASH=1]#define[/HASH] LOG_TAG "Metin2Mobile"
[HASH=1]#define[/HASH] LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
[HASH=1]#define[/HASH] LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
[HASH=3]#endif[/HASH]
void* c_dfDIKeyboard = NULL;
namespace {
const char* vShaderSource =
"#version 300 es\n"
"layout(location = 0) in vec3 aPos;\n"
"layout(location = 1) in vec2 aTexCoord;\n"
"layout(location = 2) in vec4 aColor;\n"
"uniform mat4 uProjection;\n"
"uniform mat4 uModelView;\n"
"out vec2 vTexCoord;\n"
"out vec4 vColor;\n"
"void main() {\n"
" gl_Position = uProjection * uModelView * vec4(aPos, 1.0);\n"
" vTexCoord = aTexCoord;\n"
" vColor = aColor;\n"
"}\n";
const char* fShaderSource =
"#version 300 es\n"
"precision mediump float;\n"
"in vec2 vTexCoord;\n"
"in vec4 vColor;\n"
"out vec4 FragColor;\n"
"uniform sampler2D uTexture;\n"
"uniform bool uUseTexture;\n"
"void main() {\n"
" vec4 texColor = uUseTexture ? texture(uTexture, vTexCoord) : vec4(1.0);\n"
" FragColor = texColor * vColor;\n"
"}\n";
GLuint CompileShader(GLenum type, const char* source) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
GLint success;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(shader, 512, NULL, infoLog);
LOGE("Shader Compilation Failed: %s", infoLog);
}
return shader;
}
GLuint program = 0;
GLint uProjectionLoc, uModelViewLoc, uTextureLoc, uUseTextureLoc;
}
IDirect3D8* Direct3DCreate8(UINT SDKVersion) {
return new IDirect3D8();
}
HRESULT IDirect3D8::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice8** ppReturnedDeviceInterface) {
*ppReturnedDeviceInterface = new IDirect3DDevice8();
// Initialize Shaders
GLuint vShader = CompileShader(GL_VERTEX_SHADER, vShaderSource);
GLuint fShader = CompileShader(GL_FRAGMENT_SHADER, fShaderSource);
program = glCreateProgram();
glAttachShader(program, vShader);
glAttachShader(program, fShader);
glLinkProgram(program);
uProjectionLoc = glGetUniformLocation(program, "uProjection");
uModelViewLoc = glGetUniformLocation(program, "uModelView");
uTextureLoc = glGetUniformLocation(program, "uTexture");
uUseTextureLoc = glGetUniformLocation(program, "uUseTexture");
glUseProgram(program);
return S_OK;
}
HRESULT IDirect3DDevice8::Clear(DWORD Count, const D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
GLbitfield mask = 0;
if (Flags & D3DCLEAR_TARGET) {
glClearColor(Color.r, Color.g, Color.b, Color.a);
mask |= GL_COLOR_BUFFER_BIT;
}
if (Flags & D3DCLEAR_ZBUFFER) {
glClearDepthf(Z);
mask |= GL_DEPTH_BUFFER_BIT;
}
if (mask) glClear(mask);
return S_OK;
}
HRESULT IDirect3DDevice8::DrawIndexedPrimitive(D3DPRIMITIVETYPE Type, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount) {
glUseProgram(program);
// Update active matrices
glUniformMatrix4fv(uProjectionLoc, 1, GL_FALSE, &m_matProj.m[0][0]);
glUniformMatrix4fv(uModelViewLoc, 1, GL_FALSE, &m_matWorld.m[0][0]); // Simplified: only world mat for now
GLenum mode = GL_TRIANGLES;
GLsizei count = 0;
switch(Type) {
case D3DPT_TRIANGLELIST: mode = GL_TRIANGLES; count = PrimitiveCount * 3; break;
case D3DPT_TRIANGLESTRIP: mode = GL_TRIANGLE_STRIP; count = PrimitiveCount + 2; break;
case D3DPT_TRIANGLEFAN: mode = GL_TRIANGLE_FAN; count = PrimitiveCount + 2; break;
}
if (m_pStreamSource) {
glBindBuffer(GL_ARRAY_BUFFER, m_pStreamSource->glVbo);
// Assuming position at offset 0, tex at offset 24, color at 12 (approximate FVF mapping)
glEnableVertexAttribArray(0); // Pos
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, m_StreamStride, (void*)0);
glEnableVertexAttribArray(1); // Tex
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, m_StreamStride, (void*)24); // Dummy offset
glEnableVertexAttribArray(2); // Color
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, m_StreamStride, (void*)12);
}
if (m_pIndexBuffer) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pIndexBuffer->glIbo);
glDrawElements(mode, count, GL_UNSIGNED_SHORT, (void*)(size_t)(StartIndex * 2));
}
return S_OK;
}
// Stub implementation for common device methods
HRESULT IDirect3DDevice8::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) { return S_OK; }
HRESULT IDirect3DDevice8::BeginScene() { return S_OK; }
HRESULT IDirect3DDevice8::EndScene() { return S_OK; }
HRESULT IDirect3DDevice8::Present(const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const void* pDirtyRegion) { return S_OK; }
HRESULT IDirect3DDevice8::SetTexture(DWORD Stage, LPDIRECT3DBaseTexture8 pTexture) {
if (pTexture) {
IDirect3DTexture8* tex = (IDirect3DTexture8*)pTexture;
glActiveTexture(GL_TEXTURE0 + Stage);
glBindTexture(GL_TEXTURE_2D, tex->glId);
glUniform1i(uUseTextureLoc, 1);
glUniform1i(uTextureLoc, Stage);
} else {
glUniform1i(uUseTextureLoc, 0);
}
return S_OK;
}
HRESULT IDirect3DDevice8::SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride) {
m_pStreamSource = pStreamData;
m_StreamStride = Stride;
return S_OK;
}
HRESULT IDirect3DDevice8::SetIndices(LPDIRECT3DINDEXBUFFER8 pIndexBuffer, UINT BaseVertexIndex) {
m_pIndexBuffer = pIndexBuffer;
return S_OK;
}
[HASH=3]#endif[/HASH]
GrpOpenGL.h:
#pragma once
// OpenGL Headers for Mobile (GLES2 default for high compatibility)
[HASH=2]#ifdef[/HASH] ANDROID
[HASH=2388]#include[/HASH] <GLES2/gl2.h>
[HASH=2388]#include[/HASH] <GLES2/gl2ext.h>
[HASH=2311]#else[/HASH]
[HASH=2388]#include[/HASH] <GL/gl.h>
[HASH=2388]#include[/HASH] <GL/glext.h>
[HASH=3]#endif[/HASH]
[HASH=2388]#include[/HASH] <math.h>
[HASH=2388]#include[/HASH] <string.h>
[HASH=2388]#include[/HASH] <vector>
[HASH=2389]#ifndef[/HASH] HRESULT
typedef long HRESULT;
[HASH=3]#endif[/HASH]
[HASH=2389]#ifndef[/HASH] S_OK
[HASH=1]#define[/HASH] S_OK ((HRESULT)0L)
[HASH=3]#endif[/HASH]
[HASH=2389]#ifndef[/HASH] FAILED
[HASH=1]#define[/HASH] FAILED(hr) (((HRESULT)(hr)) < 0)
[HASH=3]#endif[/HASH]
[HASH=2389]#ifndef[/HASH] SUCCEEDED
[HASH=1]#define[/HASH] SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
[HASH=3]#endif[/HASH]
[HASH=2]#ifdef[/HASH] ANDROID
typedef const void* LPCVOID;
typedef void* LPVOID;
typedef struct { BYTE peRed; BYTE peGreen; BYTE peBlue; BYTE peFlags; } PALETTEENTRY;
[HASH=3]#endif[/HASH]
typedef unsigned int UINT;
typedef unsigned long DWORD;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef int BOOL;
[HASH=2389]#ifndef[/HASH] TRUE
[HASH=1]#define[/HASH] TRUE 1
[HASH=3]#endif[/HASH]
[HASH=2389]#ifndef[/HASH] FALSE
[HASH=1]#define[/HASH] FALSE 0
[HASH=3]#endif[/HASH]
struct D3DXIMAGE_INFO {
UINT Width;
UINT Height;
UINT Depth;
UINT MipLevels;
int Format;
int ResourceType;
int ImageFileFormat;
};
// Simple D3DX Math simulation for OpenGL
struct GLMATRIX {
float m[4][4];
GLMATRIX() {
memset(m, 0, sizeof(m));
m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
}
};
struct GLVECTOR3 {
float x, y, z;
GLVECTOR3() : x(0), y(0), z(0) {}
GLVECTOR3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
GLVECTOR3 operator+(const GLVECTOR3& rhs) const { return GLVECTOR3(x+rhs.x, y+rhs.y, z+rhs.z); }
GLVECTOR3 operator*(float s) const { return GLVECTOR3(x*s, y*s, z*s); }
};
inline GLVECTOR3 operator*(float s, const GLVECTOR3& v) {
return GLVECTOR3(v.x * s, v.y * s, v.z * s);
}
inline GLVECTOR3* D3DXVec3Normalize(GLVECTOR3* pOut, const GLVECTOR3* pV) {
float len = sqrtf(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z);
if (len > 0.0f) {
pOut->x = pV->x / len;
pOut->y = pV->y / len;
pOut->z = pV->z / len;
} else {
pOut->x = pOut->y = pOut->z = 0.0f;
}
return pOut;
}
struct GLVECTOR2 {
float x, y;
};
struct GLCOLOR {
float r, g, b, a;
};
struct GLVECTOR4 { float x, y, z, w; };
struct GLQUATERNION { float x, y, z, w; };
struct GLPLANE { float a, b, c, d; };
inline float D3DXVec3Dot(const GLVECTOR3* pV1, const GLVECTOR3* pV2) {
return pV1->x*pV2->x + pV1->y*pV2->y + pV1->z*pV2->z;
}
inline GLVECTOR3* D3DXVec3Cross(GLVECTOR3* pOut, const GLVECTOR3* pV1, const GLVECTOR3* pV2) {
pOut->x = pV1->y * pV2->z - pV1->z * pV2->y;
pOut->y = pV1->z * pV2->x - pV1->x * pV2->z;
pOut->z = pV1->x * pV2->y - pV1->y * pV2->x;
return pOut;
}
inline float D3DXVec3LengthSq(const GLVECTOR3* pV) {
return pV->x*pV->x + pV->y*pV->y + pV->z*pV->z;
}
inline float D3DXVec3Length(const GLVECTOR3* pV) {
return sqrtf(D3DXVec3LengthSq(pV));
}
inline float D3DXVec2Length(const GLVECTOR2* pV) {
return sqrtf(pV->x*pV->x + pV->y*pV->y);
}
inline float D3DXVec2Dot(const GLVECTOR2* pV1, const GLVECTOR2* pV2) {
return pV1->x*pV2->x + pV1->y*pV2->y;
}
inline GLVECTOR2* D3DXVec2Normalize(GLVECTOR2* pOut, const GLVECTOR2* pV) {
float len = D3DXVec2Length(pV);
if (len > 0) { pOut->x = pV->x/len; pOut->y = pV->y/len; }
else { pOut->x = pOut->y = 0; }
return pOut;
}
inline GLVECTOR3* D3DXVec3TransformCoord(GLVECTOR3* pOut, const GLVECTOR3* pV, const GLMATRIX* pM) {
*pOut = *pV; // stub
return pOut;
}
inline GLMATRIX* D3DXMatrixIdentity(GLMATRIX* pOut) {
memset(pOut->m, 0, sizeof(pOut->m));
pOut->m[0][0] = pOut->m[1][1] = pOut->m[2][2] = pOut->m[3][3] = 1.0f;
return pOut;
}
inline GLMATRIX* D3DXMatrixInverse(GLMATRIX* pOut, float* pDeterminant, const GLMATRIX* pM) {
// Basic 4x4 Inverse implementation or placeholder for now
// In a real port, a robust inverse is needed
*pOut = *pM; // temporary
return pOut;
}
inline GLMATRIX* D3DXMatrixMultiply(GLMATRIX* pOut, const GLMATRIX* pM1, const GLMATRIX* pM2) {
GLMATRIX out;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
out.m[i][j] = pM1->m[i][0] * pM2->m[0][j] + pM1->m[i][1] * pM2->m[1][j] +
pM1->m[i][2] * pM2->m[2][j] + pM1->m[i][3] * pM2->m[3][j];
}
}
*pOut = out;
return pOut;
}
inline GLMATRIX* D3DXMatrixTranslation(GLMATRIX* pOut, float x, float y, float z) {
D3DXMatrixIdentity(pOut);
pOut->m[3][0] = x; pOut->m[3][1] = y; pOut->m[3][2] = z;
return pOut;
}
inline GLMATRIX* D3DXMatrixScaling(GLMATRIX* pOut, float x, float y, float z) {
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = x; pOut->m[1][1] = y; pOut->m[2][2] = z;
return pOut;
}
inline GLMATRIX* D3DXMatrixRotationX(GLMATRIX* pOut, float angle) {
float s = sinf(angle), c = cosf(angle);
D3DXMatrixIdentity(pOut);
pOut->m[1][1] = c; pOut->m[1][2] = s;
pOut->m[2][1] = -s; pOut->m[2][2] = c;
return pOut;
}
inline GLMATRIX* D3DXMatrixRotationY(GLMATRIX* pOut, float angle) {
float s = sinf(angle), c = cosf(angle);
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = c; pOut->m[0][2] = -s;
pOut->m[2][0] = s; pOut->m[2][2] = c;
return pOut;
}
inline GLMATRIX* D3DXMatrixRotationZ(GLMATRIX* pOut, float angle) {
float s = sinf(angle), c = cosf(angle);
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = c; pOut->m[0][1] = s;
pOut->m[1][0] = -s; pOut->m[1][1] = c;
return pOut;
}
inline GLMATRIX* D3DXMatrixRotationQuaternion(GLMATRIX* pOut, const GLQUATERNION* pQ) { return D3DXMatrixIdentity(pOut); }
inline GLQUATERNION* D3DXQuaternionMultiply(GLQUATERNION* pOut, const GLQUATERNION* pQ1, const GLQUATERNION* pQ2) { *pOut = *pQ1; return pOut; }
inline GLQUATERNION* D3DXQuaternionConjugate(GLQUATERNION* pOut, const GLQUATERNION* pQ) { *pOut = *pQ; return pOut; }
inline GLVECTOR3* D3DXVec3Rotation(GLVECTOR3* pOut, const GLVECTOR3* pV, const GLQUATERNION* pQ) { *pOut = *pV; return pOut; }
inline GLVECTOR3* D3DXVec3Translation(GLVECTOR3* pOut, const GLVECTOR3* pV, const GLMATRIX* pM) { *pOut = *pV; return pOut; }
inline float D3DXPlaneDotCoord(const GLPLANE* pP, const GLVECTOR3* pV) { return 0.0f; }
inline float D3DXMatrixfDeterminant(const GLMATRIX* pM) { return 1.0f; }
inline GLMATRIX* D3DXMatrixLookAtRH(GLMATRIX* pOut, const GLVECTOR3* pEye, const GLVECTOR3* pAt, const GLVECTOR3* pUp) {
GLVECTOR3 f, s, u;
GLVECTOR3 tmp(pAt->x - pEye->x, pAt->y - pEye->y, pAt->z - pEye->z);
D3DXVec3Normalize(&f, &tmp);
D3DXVec3Cross(&s, &f, pUp);
D3DXVec3Normalize(&s, &s);
D3DXVec3Cross(&u, &s, &f);
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = s.x; pOut->m[1][0] = s.y; pOut->m[2][0] = s.z;
pOut->m[0][1] = u.x; pOut->m[1][1] = u.y; pOut->m[2][1] = u.z;
pOut->m[0][2] = -f.x; pOut->m[1][2] = -f.y; pOut->m[2][2] = -f.z;
pOut->m[3][0] = -D3DXVec3Dot(&s, pEye);
pOut->m[3][1] = -D3DXVec3Dot(&u, pEye);
pOut->m[3][2] = D3DXVec3Dot(&f, pEye);
return pOut;
}
inline GLMATRIX* D3DXMatrixPerspectiveFovRH(GLMATRIX* pOut, float fovy, float Aspect, float zn, float zf) {
float h = 1.0f / tanf(fovy / 2.0f);
float w = h / Aspect;
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = w;
pOut->m[1][1] = h;
pOut->m[2][2] = zf / (zn - zf);
pOut->m[2][3] = -1.0f;
pOut->m[3][2] = (zn * zf) / (zn - zf);
pOut->m[3][3] = 0.0f;
return pOut;
}
inline GLMATRIX* D3DXMatrixOrthoRH(GLMATRIX* pOut, float w, float h, float zn, float zf) {
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = 2.0f / w;
pOut->m[1][1] = 2.0f / h;
pOut->m[2][2] = 1.0f / (zn - zf);
pOut->m[3][2] = zn / (zn - zf);
return pOut;
}
inline GLMATRIX* D3DXMatrixOrthoOffCenterRH(GLMATRIX* pOut, float l, float r, float b, float t, float zn, float zf) {
D3DXMatrixIdentity(pOut);
if (r != l) pOut->m[0][0] = 2.0f / (r - l);
if (t != b) pOut->m[1][1] = 2.0f / (t - b);
if (zn != zf) {
pOut->m[2][2] = 1.0f / (zn - zf);
pOut->m[3][2] = zn / (zn - zf);
}
if (r != l) pOut->m[3][0] = (l + r) / (l - r);
if (t != b) pOut->m[3][1] = (t + b) / (b - t);
return pOut;
}
inline HRESULT D3DXGetImageInfoFromFileInMemory(LPCVOID pSrcData, UINT SrcDataSize, D3DXIMAGE_INFO* pSrcInfo) {
if (pSrcInfo) {
pSrcInfo->Width = 256; pSrcInfo->Height = 256; pSrcInfo->Format = D3DFMT_A8R8G8B8;
}
return S_OK;
}
inline GLMATRIX* D3DXMatrixRotationAxis(GLMATRIX* pOut, const GLVECTOR3* pV, float angle) { return D3DXMatrixIdentity(pOut); }
inline GLMATRIX* D3DXMatrixRotationYawPitchRoll(GLMATRIX* pOut, float y, float p, float r) {
GLMATRIX my, mp, mr;
D3DXMatrixRotationY(&my, y);
D3DXMatrixRotationX(&mp, p);
D3DXMatrixRotationZ(&mr, r);
D3DXMatrixMultiply(pOut, &mr, &mp);
D3DXMatrixMultiply(pOut, pOut, &my);
return pOut;
}
inline GLVECTOR3* D3DXVec3Project(GLVECTOR3* pOut, const GLVECTOR3* pV, const D3DVIEWPORT8* pViewport, const GLMATRIX* pProjection, const GLMATRIX* pView, const GLMATRIX* pWorld) {
GLMATRIX mat;
D3DXMatrixMultiply(&mat, pWorld, pView);
D3DXMatrixMultiply(&mat, &mat, pProjection);
// Transform coordinate logic goes here... (simplified)
*pOut = *pV;
return pOut;
}
inline GLVECTOR3* D3DXVec3Unproject(GLVECTOR3* pOut, const GLVECTOR3* pV, const D3DVIEWPORT8* pViewport, const GLMATRIX* pProjection, const GLMATRIX* pView, const GLMATRIX* pWorld) {
*pOut = *pV;
return pOut;
}
inline GLQUATERNION* D3DXQuaternionBlend(GLQUATERNION* pOut, const GLQUATERNION* pQ1, const GLQUATERNION* pQ2, float t) { *pOut = *pQ1; return pOut; }
inline GLVECTOR3* D3DXVec3Blend(GLVECTOR3* pOut, const GLVECTOR3* pV1, const GLVECTOR3* pV2, float t) { *pOut = *pV1; return pOut; }
inline GLVECTOR2* D3DXVec2CCW(GLVECTOR2* pOut, const GLVECTOR2* pV) { *pOut = *pV; return pOut; }
[HASH=1]#define[/HASH] D3DX_PI 3.141592654f
[HASH=1]#define[/HASH] D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f))
[HASH=1]#define[/HASH] D3DXToDegree( radian ) ((radian) * (180.0f / D3DX_PI))
// Map D3D names to our OpenGL simulation if ENABLE_OPENGL is on
[HASH=1]#define[/HASH] D3DX_DEFAULT ((UINT)-1)
[HASH=1]#define[/HASH] D3DX_DEFAULT_NONPOW2 ((UINT)-2)
[HASH=1]#define[/HASH] D3DFMT_A8R8G8B8 21
[HASH=1]#define[/HASH] D3DFMT_X8R8G8B8 22
[HASH=1]#define[/HASH] D3DFMT_D16 80
[HASH=1]#define[/HASH] D3DPOOL_MANAGED 1
[HASH=1]#define[/HASH] D3DX_FILTER_NONE 1
[HASH=1]#define[/HASH] D3DX_FILTER_LINEAR 2
[HASH=2]#ifdef[/HASH] ENABLE_OPENGL
[HASH=1]#define[/HASH] D3DXMATRIX GLMATRIX
[HASH=1]#define[/HASH] D3DXVECTOR3 GLVECTOR3
[HASH=1]#define[/HASH] D3DVECTOR GLVECTOR3
[HASH=1]#define[/HASH] D3DXVECTOR2 GLVECTOR2
[HASH=1]#define[/HASH] D3DCOLOR GLCOLOR
[HASH=1]#define[/HASH] D3DXCOLOR GLCOLOR
struct GL_LIGHT {
int Type;
GLCOLOR Diffuse;
GLCOLOR Specular;
GLCOLOR Ambient;
GLVECTOR3 Position;
GLVECTOR3 Direction;
float Range;
float Falloff;
float Attenuation0;
float Attenuation1;
float Attenuation2;
float Theta;
float Phi;
};
[HASH=1]#define[/HASH] D3DLIGHT8 GL_LIGHT
struct GL_MATERIAL {
GLCOLOR Diffuse;
GLCOLOR Ambient;
GLCOLOR Specular;
GLCOLOR Emissive;
float Power;
};
[HASH=1]#define[/HASH] D3DMATERIAL8 GL_MATERIAL
[HASH=1]#define[/HASH] D3DXQUATERNION GLQUATERNION
[HASH=1]#define[/HASH] D3DXPLANE GLPLANE
[HASH=1]#define[/HASH] D3DXVECTOR4 GLVECTOR4
inline HRESULT D3DXCreateTexture(LPDIRECT3DDEVICE8 pDevice, UINT Width, UINT Height, UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, LPDIRECT3DTEXTURE8* ppTexture) {
return pDevice->CreateTexture(Width, Height, MipLevels, Usage, Format, Pool, ppTexture);
}
inline HRESULT D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE8 pDevice, LPCVOID pSrcData, UINT SrcDataSize, UINT Width, UINT Height, UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey, D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, LPDIRECT3DTEXTURE8* ppTexture) {
// Implementation would need an image decoder (stb_image)
// For now, return a dummy but successful result if we just want a placeholder
// In a real implementation, we'd decode pSrcData and upload it
if (pSrcInfo) {
pSrcInfo->Width = (Width == D3DX_DEFAULT) ? 256 : Width;
pSrcInfo->Height = (Height == D3DX_DEFAULT) ? 256 : Height;
pSrcInfo->MipLevels = 1;
pSrcInfo->Format = D3DFMT_A8R8G8B8;
}
return pDevice->CreateTexture(256, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, ppTexture);
}
inline HRESULT D3DXLoadSurfaceFromSurface(LPDIRECT3DSURFACE8 pDestSurface, CONST PALETTEENTRY* pDestPalette, CONST RECT* pDestRect, LPDIRECT3DSURFACE8 pSrcSurface, CONST PALETTEENTRY* pSrcPalette, CONST RECT* pSrcRect, DWORD Filter, D3DCOLOR ColorKey) {
return S_OK;
}
[HASH=1]#define[/HASH] D3DVSD_STREAM(s) (s)
[HASH=1]#define[/HASH] D3DVSD_REG(r, t) (r)
[HASH=1]#define[/HASH] D3DVSD_END() 0
[HASH=1]#define[/HASH] D3DVSDT_FLOAT3 0
[HASH=1]#define[/HASH] D3DVSDT_FLOAT2 0
[HASH=1]#define[/HASH] D3DVSDE_TEXCOORD1 0
[HASH=1]#define[/HASH] D3DVSDE_POSITION2 0
[HASH=1]#define[/HASH] D3DVSDE_NORMAL2 0
// DirectInput Stubs
typedef void* LPDIRECTINPUT8;
typedef void* LPDIRECTINPUTDEVICE8;
[HASH=1]#define[/HASH] DIRECTINPUT_VERSION 0x0800
[HASH=1]#define[/HASH] IID_IDirectInput8 (void*)0
[HASH=1]#define[/HASH] GUID_SysKeyboard (void*)0
[HASH=1]#define[/HASH] DISCL_FOREGROUND 0
[HASH=1]#define[/HASH] DISCL_EXCLUSIVE 0
[HASH=1]#define[/HASH] DISCL_NONEXCLUSIVE 0
[HASH=1]#define[/HASH] DISCL_BACKGROUND 0
[HASH=1]#define[/HASH] SAFE_RELEASE(p) if(p) { p = NULL; }
[HASH=1]#define[/HASH] FAILED(hr) ((hr) < 0)
[HASH=1]#define[/HASH] S_OK 0
inline int DirectInput8Create(void*, int, void*, void**, void*) { return 0; }
struct IDirectInputDevice8 {
int SetDataFormat(void*) { return 0; }
int SetCooperativeLevel(void*, int) { return 0; }
int Acquire() { return 0; }
int Unacquire() { return 0; }
int GetDeviceState(int, void*) { return 0; }
void Release() {}
};
extern void* c_dfDIKeyboard;
struct IDirect3D8 {
UINT GetAdapterCount() { return 1; }
HRESULT GetAdapterIdentifier(UINT, DWORD, D3DADAPTER_IDENTIFIER8* pIdentifier) {
if (pIdentifier) {
strcpy(pIdentifier->Driver, "OpenGL Generic");
strcpy(pIdentifier->Description, "OpenGL Port");
}
return S_OK;
}
UINT GetAdapterModeCount(UINT) { return 1; }
HRESULT EnumAdapterModes(UINT, UINT, D3DDISPLAYMODE* pMode) {
if (pMode) { pMode->Width = 1024; pMode->Height = 768; pMode->RefreshRate = 60; pMode->Format = D3DFMT_X8R8G8B8; }
return S_OK;
}
HRESULT GetAdapterDisplayMode(UINT, D3DDISPLAYMODE* pMode) {
if (pMode) { pMode->Width = 1024; pMode->Height = 768; pMode->RefreshRate = 60; pMode->Format = D3DFMT_X8R8G8B8; }
return S_OK;
}
HRESULT CheckDeviceType(UINT, D3DDEVTYPE, D3DFORMAT, D3DFORMAT, BOOL) { return S_OK; }
HRESULT CheckDeviceFormat(UINT, int, int, DWORD, int, int) { return S_OK; }
HRESULT CheckDepthStencilMatch(UINT, int, int, int, int) { return S_OK; }
HRESULT GetDeviceCaps(UINT, int, D3DCAPS8* pCaps) {
if (pCaps) {
memset(pCaps, 0, sizeof(D3DCAPS8));
pCaps->MaxTextureWidth = 8192;
pCaps->MaxTextureHeight = 8192;
pCaps->DevCaps = D3DDEVCAPS_HWTRANSFORMANDLIGHT;
pCaps->Caps2 = D3DCAPS2_CANRENDERWINDOWED;
pCaps->VertexProcessingCaps = D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_TEXGEN;
pCaps->PrimitiveMiscCaps = D3DPMISCCAPS_CLIPTLVERTS;
pCaps->TextureAddressCaps = D3DPTADDRESSCAPS_BORDER;
}
return S_OK;
}
HRESULT CreateDevice(UINT, int, HWND hWnd, DWORD, D3DPRESENT_PARAMETERS*, IDirect3DDevice8** ppDevice) {
[HASH=2389]#ifndef[/HASH] ANDROID
HDC hDC = GetDC(hWnd);
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), 1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 0,
PFD_MAIN_PLANE, 0, 0, 0, 0
};
int pixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, pixelFormat, &pfd);
HGLRC hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
*ppDevice = new IDirect3DDevice8();
(*ppDevice)->m_hDC = hDC;
[HASH=2311]#else[/HASH]
*ppDevice = new IDirect3DDevice8();
[HASH=3]#endif[/HASH]
return S_OK;
}
ULONG Release() { delete this; return 0; }
};
inline IDirect3D8* Direct3DCreate8(UINT) { return new IDirect3D8(); }
struct IDirect3DDevice8 {
[HASH=2389]#ifndef[/HASH] ANDROID
HDC m_hDC;
[HASH=3]#endif[/HASH]
IDirect3DDevice8() {
[HASH=2389]#ifndef[/HASH] ANDROID
m_hDC = NULL;
[HASH=3]#endif[/HASH]
}
HRESULT CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, LPDIRECT3DTEXTURE8* ppTexture) {
IDirect3DTexture8* tex = new IDirect3DTexture8();
tex->width = Width;
tex->height = Height;
glGenTextures(1, &tex->glId);
glBindTexture(GL_TEXTURE_2D, tex->glId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
*ppTexture = tex;
return S_OK;
}
HRESULT SetLight(DWORD,const void*) { return S_OK; }
HRESULT LightEnable(DWORD,BOOL) { return S_OK; }
DWORD m_dwFVF;
HRESULT GetVertexShader(DWORD* pShader) { *pShader = m_dwFVF; return S_OK; }
HRESULT SetVertexShader(DWORD Shader) { m_dwFVF = Shader; return S_OK; }
HRESULT CreateVertexShader(const DWORD* pDeclaration, const DWORD* pFunction, DWORD* pHandle, DWORD Usage) { *pHandle = 1; return S_OK; }
HRESULT DeleteVertexShader(DWORD Handle) { return S_OK; }
HRESULT CreatePixelShader(const DWORD* pFunction, DWORD* pHandle) { *pHandle = 2; return S_OK; }
HRESULT DeletePixelShader(DWORD Handle) { return S_OK; }
HRESULT SetPixelShader(DWORD Handle) { return S_OK; }
HRESULT SetVertexShaderConstant(DWORD Register, const void* pData, DWORD Count) { return S_OK; }
HRESULT SetPixelShaderConstant(DWORD Register, const void* pData, DWORD Count) { return S_OK; }
HRESULT Clear(DWORD n, const void* pRects, DWORD flags, D3DCOLOR color, float z, DWORD stencil) {
GLbitfield mask = 0;
if (flags & 1) { // D3DCLEAR_TARGET
glClearColor(color.r, color.g, color.b, color.a);
mask |= GL_COLOR_BUFFER_BIT;
}
if (flags & 2) { // D3DCLEAR_ZBUFFER
[HASH=2389]#ifndef[/HASH] ANDROID
glClearDepth(z);
[HASH=2311]#else[/HASH]
glClearDepthf(z);
[HASH=3]#endif[/HASH]
mask |= GL_DEPTH_BUFFER_BIT;
}
if (mask) glClear(mask);
return S_OK;
}
HRESULT TestCooperativeLevel() { return S_OK; }
HRESULT Reset(D3DPRESENT_PARAMETERS*) { return S_OK; }
HRESULT Present(const RECT*,const RECT*,HWND,const void*) {
[HASH=2389]#ifndef[/HASH] ANDROID
if (m_hDC) SwapBuffers(m_hDC);
[HASH=3]#endif[/HASH]
return S_OK;
}
HRESULT CreateDepthStencilSurface(UINT,UINT,D3DFORMAT,D3DMULTISAMPLE_TYPE,LPDIRECT3DSURFACE8*) { return S_OK; }
HRESULT GetRenderTarget(LPDIRECT3DSURFACE8*) { return S_OK; }
HRESULT GetDepthStencilSurface(LPDIRECT3DSURFACE8*) { return S_OK; }
HRESULT GetViewport(D3DVIEWPORT8*) { return S_OK; }
HRESULT SetRenderTarget(LPDIRECT3DSURFACE8,LPDIRECT3DSURFACE8) { return S_OK; }
HRESULT SetViewport(const D3DVIEWPORT8* v) {
glViewport(v->X, v->Y, v->Width, v->Height);
return S_OK;
}
HRESULT BeginScene() { return S_OK; }
HRESULT EndScene() { return S_OK; }
HRESULT GetDeviceCaps(D3DCAPS8*) { return S_OK; }
void SetGammaRamp(DWORD,DWORD,const void*) {}
HRESULT GetBackBuffer(UINT,D3DBACKBUFFER_TYPE,LPDIRECT3DSURFACE8*) { return S_OK; }
UINT GetAvailableTextureMem() { return 128 * 1024 * 1024; }
LPDIRECT3DVERTEXBUFFER8 m_pStreamSource;
UINT m_StreamStride;
HRESULT SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride) {
m_pStreamSource = pStreamData;
m_StreamStride = Stride;
if (pStreamData) glBindBuffer(GL_ARRAY_BUFFER, pStreamData->glVbo);
else glBindBuffer(GL_ARRAY_BUFFER, 0);
return S_OK;
}
HRESULT CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, LPDIRECT3DVERTEXBUFFER8* ppVertexBuffer) {
*ppVertexBuffer = new IDirect3DVertexBuffer8(Length);
return S_OK;
}
HRESULT CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, LPDIRECT3DINDEXBUFFER8* ppIndexBuffer) {
*ppIndexBuffer = new IDirect3DIndexBuffer8(Length);
return S_OK;
}
LPDIRECT3DINDEXBUFFER8 m_pIndexBuffer;
HRESULT SetIndices(LPDIRECT3DINDEXBUFFER8 pIndexBuffer, UINT BaseVertexIndex) {
m_pIndexBuffer = pIndexBuffer;
if (pIndexBuffer) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndexBuffer->glIbo);
else glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return S_OK;
}
HRESULT DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount) {
GLenum mode = GL_TRIANGLES;
GLsizei count = 0;
switch(PrimitiveType) {
case 1: mode = GL_POINTS; count = (GLsizei)primCount; break;
case 2: mode = GL_LINES; count = (GLsizei)primCount * 2; break;
case 3: mode = GL_LINE_STRIP; count = (GLsizei)primCount + 1; break;
case 4: mode = GL_TRIANGLES; count = (GLsizei)primCount * 3; break;
case 5: mode = GL_TRIANGLE_STRIP; count = (GLsizei)primCount + 2; break;
case 6: mode = GL_TRIANGLE_FAN; count = (GLsizei)primCount + 2; break;
}
[HASH=2389]#ifndef[/HASH] ANDROID
glEnableClientState(GL_VERTEX_ARRAY);
int offset = 0;
// Position (XYZ)
glVertexPointer(3, GL_FLOAT, (GLsizei)m_StreamStride, (void*)(size_t)offset);
offset += 12;
if (m_dwFVF & D3DFVF_XYZRHW) {
// RHW not really supported in pure OpenGL fixed pipeline easily without shaders
// but we shift if needed. Metin2 uses XYZ usually.
}
if (m_dwFVF & D3DFVF_NORMAL) {
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, (GLsizei)m_StreamStride, (void*)(size_t)offset);
offset += 12;
} else {
glDisableClientState(GL_NORMAL_ARRAY);
}
if (m_dwFVF & D3DFVF_DIFFUSE) {
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, (GLsizei)m_StreamStride, (void*)(size_t)offset);
offset += 4;
} else {
glDisableClientState(GL_COLOR_ARRAY);
}
if (m_dwFVF & D3DFVF_SPECULAR) {
offset += 4;
}
// Texture Coordinates
int numTex = (m_dwFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
if (numTex > 0) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, (GLsizei)m_StreamStride, (void*)(size_t)offset);
offset += 8 * numTex;
} else if (m_dwFVF & D3DFVF_TEX1) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, (GLsizei)m_StreamStride, (void*)(size_t)offset);
offset += 8;
} else {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
glDrawElements(mode, count, GL_UNSIGNED_SHORT, (void*)(size_t)(startIndex * 2));
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
[HASH=3]#endif[/HASH]
return S_OK;
}
HRESULT DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, const void* pIndexData, D3DFORMAT IndexDataFormat, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) {
[HASH=2389]#ifndef[/HASH] ANDROID
glEnableClientState(GL_VERTEX_ARRAY);
if (VertexStreamZeroStride >= 20) {
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, VertexStreamZeroStride, pVertexStreamZeroData);
glColorPointer(4, GL_UNSIGNED_BYTE, VertexStreamZeroStride, (char*)pVertexStreamZeroData + 12);
glTexCoordPointer(2, GL_FLOAT, VertexStreamZeroStride, (char*)pVertexStreamZeroData + 16);
} else {
glVertexPointer(3, GL_FLOAT, VertexStreamZeroStride, pVertexStreamZeroData);
}
GLenum mode = GL_TRIANGLES;
GLsizei count = 0;
switch(PrimitiveType) {
case 4: mode = GL_TRIANGLES; count = PrimitiveCount * 3; break;
case 5: mode = GL_TRIANGLE_STRIP; count = PrimitiveCount + 2; break;
case 6: mode = GL_TRIANGLE_FAN; count = PrimitiveCount + 2; break;
}
glDrawElements(mode, count, (IndexDataFormat == 17 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT), pIndexData);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
[HASH=3]#endif[/HASH]
return S_OK;
}
HRESULT DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) {
GLenum mode = GL_TRIANGLES;
GLsizei count = 0;
switch(PrimitiveType) {
case 1: mode = GL_POINTS; count = PrimitiveCount; break;
case 2: mode = GL_LINES; count = PrimitiveCount * 2; break;
case 3: mode = GL_LINE_STRIP; count = PrimitiveCount + 1; break;
case 4: mode = GL_TRIANGLES; count = PrimitiveCount * 3; break;
case 5: mode = GL_TRIANGLE_STRIP; count = PrimitiveCount + 2; break;
case 6: mode = GL_TRIANGLE_FAN; count = PrimitiveCount + 2; break;
}
glDrawArrays(mode, StartVertex, count);
return S_OK;
}
HRESULT DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) {
[HASH=2389]#ifndef[/HASH] ANDROID
glEnableClientState(GL_VERTEX_ARRAY);
if (VertexStreamZeroStride >= 20) { // XYZ + COLOR + TEX
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, VertexStreamZeroStride, pVertexStreamZeroData);
glColorPointer(4, GL_UNSIGNED_BYTE, VertexStreamZeroStride, (char*)pVertexStreamZeroData + 12);
glTexCoordPointer(2, GL_FLOAT, VertexStreamZeroStride, (char*)pVertexStreamZeroData + 16);
} else {
glVertexPointer(3, GL_FLOAT, VertexStreamZeroStride, pVertexStreamZeroData);
}
DrawPrimitive(PrimitiveType, 0, PrimitiveCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
[HASH=3]#endif[/HASH]
return S_OK;
}
HRESULT SetTextureStageState(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value) {
[HASH=2389]#ifndef[/HASH] ANDROID
glActiveTexture(GL_TEXTURE0 + stage);
switch(type) {
case 10: // D3DTSS_ADDRESSU
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (value == 1 ? GL_CLAMP : GL_REPEAT));
break;
case 11: // D3DTSS_ADDRESSV
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (value == 1 ? GL_CLAMP : GL_REPEAT));
break;
case 7: // D3DTSS_MINFILTER
case 8: // D3DTSS_MAGFILTER
glTexParameteri(GL_TEXTURE_2D, (type == 7 ? GL_TEXTURE_MIN_FILTER : GL_TEXTURE_MAG_FILTER), (value == 2 ? GL_LINEAR : GL_NEAREST));
break;
case 3: // D3DTSS_COLOROP (simplified)
if (value == 2) glDisable(GL_TEXTURE_2D); // D3DTOP_DISABLE
else glEnable(GL_TEXTURE_2D);
break;
}
[HASH=3]#endif[/HASH]
return S_OK;
}
HRESULT SetRenderState(DWORD Type, DWORD Value) {
switch(Type) {
case D3DRS_ZENABLE:
if (Value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
break;
case D3DRS_ZFUNC:
glDepthFunc(GL_LEQUAL); // simplified mapping
break;
case D3DRS_ALPHABLENDENABLE:
if (Value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
break;
case D3DRS_ZWRITEENABLE:
glDepthMask(Value ? GL_TRUE : GL_FALSE);
break;
case D3DRS_ALPHATESTENABLE:
[HASH=2389]#ifndef[/HASH] ANDROID
if (Value) glEnable(GL_ALPHA_TEST); else glDisable(GL_ALPHA_TEST);
[HASH=3]#endif[/HASH]
break;
case D3DRS_ALPHAFUNC:
[HASH=2389]#ifndef[/HASH] ANDROID
glAlphaFunc(GL_GREATER, 0.5f); // simplified mapping
[HASH=3]#endif[/HASH]
break;
case D3DRS_SRCBLEND:
{
GLenum factor = GL_ONE;
switch(Value) {
case D3DBLEND_ZERO: factor = GL_ZERO; break;
case D3DBLEND_ONE: factor = GL_ONE; break;
case D3DBLEND_SRCCOLOR: factor = GL_SRC_COLOR; break;
case D3DBLEND_SRCALPHA: factor = GL_SRC_ALPHA; break;
case D3DBLEND_INVSRCALPHA: factor = GL_ONE_MINUS_SRC_ALPHA; break;
case D3DBLEND_INVDESTCOLOR: factor = GL_ONE_MINUS_DST_COLOR; break;
}
glBlendFunc(factor, GL_ONE_MINUS_SRC_ALPHA); // partial mapping
}
break;
case D3DRS_DESTBLEND:
// Similar logic for dest blend
break;
case D3DRS_CULLMODE:
if (Value == D3DCULL_NONE) glDisable(GL_CULL_FACE);
else {
glEnable(GL_CULL_FACE);
glCullFace(Value == D3DCULL_CW ? GL_FRONT : GL_BACK);
}
break;
}
return S_OK;
}
HRESULT SetTexture(DWORD stage, LPDIRECT3DBaseTexture8 tex) {
[HASH=2389]#ifndef[/HASH] ANDROID
glActiveTexture(GL_TEXTURE0 + stage);
if (tex) {
IDirect3DTexture8* gtex = (IDirect3DTexture8*)tex;
glBindTexture(GL_TEXTURE_2D, gtex->glId);
glEnable(GL_TEXTURE_2D);
} else {
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
}
[HASH=3]#endif[/HASH]
return S_OK;
}
HRESULT SetTransform(DWORD type, const GLMATRIX* mat) {
[HASH=2389]#ifndef[/HASH] ANDROID
if (type == 3) glMatrixMode(GL_PROJECTION);
else glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&mat->m[0][0]);
[HASH=3]#endif[/HASH]
return S_OK;
}
HRESULT GetTransform(DWORD type, GLMATRIX* mat) { return S_OK; }
};
struct IDirect3DTexture8 {
GLuint glId;
int width, height;
void* pLockedData;
IDirect3DTexture8() : glId(0), width(0), height(0), pLockedData(NULL) {}
HRESULT LockRect(UINT Level,D3DLOCKED_RECT* pLockedRect,const RECT* pRect,DWORD Flags) {
if (!pLockedData) pLockedData = malloc(width * height * 4);
pLockedRect->pBits = pLockedData;
pLockedRect->Pitch = width * 4;
return S_OK;
}
HRESULT UnlockRect(UINT Level) {
if (glId && pLockedData) {
glBindTexture(GL_TEXTURE_2D, glId);
glTexSubImage2D(GL_TEXTURE_2D, Level, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pLockedData);
}
return S_OK;
}
ULONG Release() {
if (glId) glDeleteTextures(1, &glId);
if (pLockedData) free(pLockedData);
delete this;
return 0;
}
HRESULT GetSurfaceLevel(UINT,LPDIRECT3DSURFACE8*) { return S_OK; }
};
struct IDirect3DSurface8 {
ULONG Release() { return 0; }
};
struct IDirect3DBaseTexture8 {
ULONG Release() { return 0; }
};
struct IDirect3DVertexBuffer8 {
GLuint glVbo;
UINT length;
void* pData;
IDirect3DVertexBuffer8(UINT len) : glVbo(0), length(len), pData(NULL) {
glGenBuffers(1, &glVbo);
pData = malloc(len);
}
HRESULT Lock(UINT OffsetToLock, UINT SizeToLock, BYTE** ppbData, DWORD Flags) {
*ppbData = (BYTE*)pData + OffsetToLock;
return S_OK;
}
HRESULT Unlock() {
glBindBuffer(GL_ARRAY_BUFFER, glVbo);
glBufferData(GL_ARRAY_BUFFER, length, pData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return S_OK;
}
ULONG Release() {
if (glVbo) glDeleteBuffers(1, &glVbo);
if (pData) free(pData);
delete this;
return 0;
}
};
struct IDirect3DIndexBuffer8 {
GLuint glIbo;
UINT length;
void* pData;
IDirect3DIndexBuffer8(UINT len) : glIbo(0), length(len), pData(NULL) {
glGenBuffers(1, &glIbo);
pData = malloc(len);
}
HRESULT Lock(UINT OffsetToLock, UINT SizeToLock, BYTE** ppbData, DWORD Flags) {
*ppbData = (BYTE*)pData + OffsetToLock;
return S_OK;
}
HRESULT Unlock() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glIbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, length, pData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return S_OK;
}
ULONG Release() {
if (glIbo) glDeleteBuffers(1, &glIbo);
if (pData) free(pData);
delete this;
return 0;
}
};
struct ID3DXMatrixStack {
std::vector<GLMATRIX> m_stack;
ID3DXMatrixStack() { m_stack.push_back(GLMATRIX()); }
HRESULT Push() { m_stack.push_back(m_stack.back()); return S_OK; }
HRESULT Pop() { if (m_stack.size() > 1) m_stack.pop_back(); return S_OK; }
HRESULT LoadIdentity() { D3DXMatrixIdentity(&m_stack.back()); return S_OK; }
HRESULT LoadMatrix(const GLMATRIX* pMat) { m_stack.back() = *pMat; return S_OK; }
HRESULT MultMatrix(const GLMATRIX* pMat) { D3DXMatrixMultiply(&m_stack.back(), &m_stack.back(), pMat); return S_OK; }
HRESULT MultMatrixLocal(const GLMATRIX* pMat) { D3DXMatrixMultiply(&m_stack.back(), pMat, &m_stack.back()); return S_OK; }
HRESULT Scale(float x, float y, float z) {
GLMATRIX s; D3DXMatrixScaling(&s, x, y, z);
MultMatrix(&s); return S_OK;
}
HRESULT Translate(float x, float y, float z) {
GLMATRIX t; D3DXMatrixTranslation(&t, x, y, z);
MultMatrix(&t); return S_OK;
}
HRESULT RotateAxis(const GLVECTOR3* pV, float angle) {
// Rotation around axis implementation...
return S_OK;
}
HRESULT RotateAxisLocal(const GLVECTOR3* pV, float angle) {
return S_OK;
}
HRESULT RotateYawPitchRollLocal(float y, float p, float r) {
GLMATRIX m; D3DXMatrixRotationYawPitchRoll(&m, y, p, r);
MultMatrixLocal(&m); return S_OK;
}
GLMATRIX* GetTop() { return &m_stack.back(); }
ULONG Release() { delete this; return 0; }
};
struct D3DVIEWPORT8 {
DWORD X, Y, Width, Height;
float MinZ, MaxZ;
};
struct D3DCAPS8 {
DWORD TextureCaps;
DWORD MaxTextureWidth, MaxTextureHeight;
};
struct D3DPRESENT_PARAMETERS {
UINT BackBufferWidth, BackBufferHeight;
int Windowed;
};
struct ID3DXBuffer {
void* GetBufferPointer() { return 0; }
DWORD GetBufferSize() { return 0; }
ULONG Release() { delete this; return 0; }
};
struct ID3DXMesh {
HRESULT GetIndexBuffer(LPDIRECT3DINDEXBUFFER8*) { return S_OK; }
HRESULT GetVertexBuffer(LPDIRECT3DVERTEXBUFFER8*) { return S_OK; }
DWORD GetFVF() { return 0; }
DWORD GetNumVertices() { return 0; }
DWORD GetNumFaces() { return 0; }
ULONG Release() { return 0; }
};
// Missing Constants
[HASH=1]#define[/HASH] D3DRS_FOGENABLE 0
[HASH=1]#define[/HASH] D3DTSS_TEXTURETRANSFORMFLAGS 0
[HASH=1]#define[/HASH] D3DTS_TEXTURE0 0
[HASH=1]#define[/HASH] D3DRS_DIFFUSEMATERIALSOURCE 0
[HASH=1]#define[/HASH] D3DRS_SPECULARMATERIALSOURCE 0
[HASH=1]#define[/HASH] D3DRS_AMBIENTMATERIALSOURCE 0
[HASH=1]#define[/HASH] D3DRS_EMISSIVEMATERIALSOURCE 0
[HASH=1]#define[/HASH] D3DRS_LINEPATTERN 0
[HASH=1]#define[/HASH] D3DRS_LASTPIXEL 0
[HASH=1]#define[/HASH] D3DRS_ALPHAREF 0
[HASH=1]#define[/HASH] D3DRS_ALPHAFUNC 0
[HASH=1]#define[/HASH] D3DRS_ZVISIBLE 0
[HASH=1]#define[/HASH] D3DRS_FOGSTART 0
[HASH=1]#define[/HASH] D3DRS_FOGEND 0
[HASH=1]#define[/HASH] D3DRS_FOGDENSITY 0
[HASH=1]#define[/HASH] D3DRS_EDGEANTIALIAS 0
[HASH=1]#define[/HASH] D3DRS_ZBIAS 0
[HASH=1]#define[/HASH] D3DRS_STENCILWRITEMASK 0
[HASH=1]#define[/HASH] D3DRS_AMBIENT 0
[HASH=1]#define[/HASH] D3DRS_LOCALVIEWER 0
[HASH=1]#define[/HASH] D3DRS_NORMALIZENORMALS 0
[HASH=1]#define[/HASH] D3DRS_VERTEXBLEND 0
[HASH=1]#define[/HASH] D3DRS_CLIPPLANEENABLE 0
[HASH=1]#define[/HASH] D3DRS_SOFTWAREVERTEXPROCESSING 0
[HASH=1]#define[/HASH] D3DRS_MULTISAMPLEANTIALIAS 0
[HASH=1]#define[/HASH] D3DRS_MULTISAMPLEMASK 0
[HASH=1]#define[/HASH] D3DRS_INDEXEDVERTEXBLENDENABLE 0
[HASH=1]#define[/HASH] D3DRS_COLORWRITEENABLE 0
[HASH=1]#define[/HASH] D3DRS_BLENDOP 0
[HASH=1]#define[/HASH] D3DRS_POSITIONDEGREE 0
[HASH=1]#define[/HASH] D3DRS_NORMALDEGREE 0
[HASH=1]#define[/HASH] D3DRS_SCISSORTESTENABLE 0
[HASH=1]#define[/HASH] D3DRS_SLOPESCALEDEPTHBIAS 0
[HASH=1]#define[/HASH] D3DRS_ANTIALIASEDLINEENABLE 0
[HASH=1]#define[/HASH] D3DRS_MINTESSELLATIONLEVEL 0
[HASH=1]#define[/HASH] D3DRS_MAXTESSELLATIONLEVEL 0
[HASH=1]#define[/HASH] D3DRS_ADAPTIVETESS_X 0
[HASH=1]#define[/HASH] D3DRS_ADAPTIVETESS_Y 0
[HASH=1]#define[/HASH] D3DRS_ADAPTIVETESS_Z 0
[HASH=1]#define[/HASH] D3DRS_ADAPTIVETESS_W 0
[HASH=1]#define[/HASH] D3DRS_ENABLEADAPTIVETESSELLATION 0
[HASH=1]#define[/HASH] D3DRS_TWOSIDEDSTENCILMODE 0
[HASH=1]#define[/HASH] D3DRS_CCW_STENCILFAIL 0
[HASH=1]#define[/HASH] D3DRS_CCW_STENCILZFAIL 0
[HASH=1]#define[/HASH] D3DRS_CCW_STENCILPASS 0
[HASH=1]#define[/HASH] D3DRS_CCW_STENCILFUNC 0
[HASH=1]#define[/HASH] D3DRS_COLORWRITEENABLE1 0
[HASH=1]#define[/HASH] D3DRS_COLORWRITEENABLE2 0
[HASH=1]#define[/HASH] D3DRS_COLORWRITEENABLE3 0
[HASH=1]#define[/HASH] D3DRS_BLENDFACTOR 0
[HASH=1]#define[/HASH] D3DRS_SRGBWRITEENABLE 0
[HASH=1]#define[/HASH] D3DRS_DEPTHBIAS 0
[HASH=1]#define[/HASH] D3DRS_WRAP8 0
[HASH=1]#define[/HASH] D3DRS_WRAP9 0
[HASH=1]#define[/HASH] D3DRS_WRAP10 0
[HASH=1]#define[/HASH] D3DRS_WRAP11 0
[HASH=1]#define[/HASH] D3DRS_WRAP12 0
[HASH=1]#define[/HASH] D3DRS_WRAP13 0
[HASH=1]#define[/HASH] D3DRS_WRAP14 0
[HASH=1]#define[/HASH] D3DRS_WRAP15 0
[HASH=1]#define[/HASH] D3DRS_SEPARATEALPHABLENDENABLE 0
[HASH=1]#define[/HASH] D3DRS_SRCBLENDALPHA 0
[HASH=1]#define[/HASH] D3DRS_DESTBLENDALPHA 0
[HASH=1]#define[/HASH] D3DRS_BLENDOPALPHA 0
[HASH=1]#define[/HASH] D3DRS_FOGCOLOR 0
[HASH=1]#define[/HASH] D3DRS_FOGTABLEMODE 0
[HASH=1]#define[/HASH] D3DRS_FOGVERTEXMODE 0
[HASH=1]#define[/HASH] D3DRS_RANGEFOGENABLE 0
[HASH=1]#define[/HASH] D3DRS_DITHERENABLE 0
[HASH=1]#define[/HASH] D3DRS_STENCILENABLE 0
[HASH=1]#define[/HASH] D3DRS_CLIPPING 0
[HASH=1]#define[/HASH] D3DRS_SPECULARENABLE 0
[HASH=1]#define[/HASH] D3DRS_COLORVERTEX 0
[HASH=1]#define[/HASH] D3DRS_WRAP0 0
[HASH=1]#define[/HASH] D3DRS_WRAP2 0
[HASH=1]#define[/HASH] D3DRS_WRAP3 0
[HASH=1]#define[/HASH] D3DRS_WRAP4 0
[HASH=1]#define[/HASH] D3DRS_WRAP5 0
[HASH=1]#define[/HASH] D3DRS_WRAP6 0
[HASH=1]#define[/HASH] D3DRS_WRAP7 0
[HASH=1]#define[/HASH] D3DTSS_TEXCOORDINDEX 0
[HASH=1]#define[/HASH] D3DDEVTYPE_HAL 1
[HASH=1]#define[/HASH] D3DDEVTYPE_REF 2
[HASH=1]#define[/HASH] D3DPTADDRESSCAPS_BORDER 0x00000080
[HASH=1]#define[/HASH] D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00000010
[HASH=1]#define[/HASH] D3DDEVCAPS_PUREDEVICE 0x00000010
[HASH=1]#define[/HASH] D3DCAPS2_CANRENDERWINDOWED 0x00080000
[HASH=1]#define[/HASH] D3DPMISCCAPS_CLIPTLVERTS 0x00000100
[HASH=1]#define[/HASH] D3DVTXPCAPS_DIRECTIONALLIGHTS 0x00000008
[HASH=1]#define[/HASH] D3DVTXPCAPS_POSITIONALLIGHTS 0x00000010
[HASH=1]#define[/HASH] D3DVTXPCAPS_TEXGEN 0x00000040
struct D3DADAPTER_IDENTIFIER8 {
char Driver[512];
char Description[512];
};
[HASH=1]#define[/HASH] D3DVS_VERSION(a,b) 0
[HASH=1]#define[/HASH] D3D_SDK_VERSION 0
[HASH=1]#define[/HASH] D3DX_PI 3.141592654f
// Abstracting Device
typedef IDirect3DSurface8* LPDIRECT3DSURFACE8;
typedef IDirect3DVertexBuffer8* LPDIRECT3DVERTEXBUFFER8; // VBO
typedef IDirect3DIndexBuffer8* LPDIRECT3DINDEXBUFFER8; // IBO/EBO
typedef ID3DXMesh* LPD3DXMESH;
// D3D Enum Types Stubbed
typedef int D3DFORMAT;
typedef int D3DPRIMITIVETYPE;
typedef int D3DDEVTYPE;
typedef int D3DTEXTUREOP;
typedef int D3DRENDERSTATETYPE;
typedef int D3DTEXTURESTAGESTATETYPE;
typedef int D3DBLEND;
typedef int D3DCMPFUNC;
typedef int D3DCULL;
typedef int D3DLIGHTSTATETYPE;
typedef int D3DMATERIAL8;
typedef int D3DLIGHT8;
typedef int D3DCOLORVALUE;
typedef int D3DFILLMODE;
typedef int D3DMULTISAMPLE_TYPE;
typedef int D3DTRANSFORMSTATETYPE;
typedef int D3DBACKBUFFER_TYPE;
struct D3DDISPLAYMODE {
UINT Width, Height, RefreshRate;
D3DFORMAT Format;
};
typedef IDirect3D8* LPDIRECT3D8;
typedef IDirect3DDevice8* LPDIRECT3DDEVICE8;
typedef IDirect3DTexture8* LPDIRECT3DTEXTURE8;
typedef IDirect3DBaseTexture8* LPDIRECT3DBaseTexture8;
[HASH=1]#define[/HASH] D3DCOLOR_XRGB(r,g,b) GLCOLOR{ (r)/255.f, (g)/255.f, (b)/255.f, 1.0f }
[HASH=1]#define[/HASH] D3DCOLOR_ARGB(a,r,g,b) GLCOLOR{ (r)/255.f, (g)/255.f, (b)/255.f, (a)/255.f }
[HASH=1]#define[/HASH] PALETTEENTRY GLCOLOR
typedef ID3DXBuffer* LPD3DXBUFFER;
typedef void* LPD3DXMATRIXSTACK;
// Stub functions
inline HRESULT D3DXCreateMatrixStack(DWORD flags, LPD3DXMATRIXSTACK* ppStack) { *ppStack = 0; return S_OK; }
inline HRESULT D3DXCreateSphere(LPDIRECT3DDEVICE8 pDevice, float radius, UINT slices, UINT stacks, LPD3DXMESH* ppMesh, LPD3DXBUFFER* ppAdjacency) { *ppMesh = 0; return S_OK; }
inline HRESULT D3DXCreateCylinder(LPDIRECT3DDEVICE8 pDevice, float radius1, float radius2, float length, UINT slices, UINT stacks, LPD3DXMESH* ppMesh, LPD3DXBUFFER* ppAdjacency) { *ppMesh = 0; return S_OK; }
inline HRESULT D3DXAssembleShaderFromFile(LPCSTR pSrcFile, DWORD flags, LPD3DXBUFFER* ppConstants, LPD3DXBUFFER* ppCompiledShader, LPD3DXBUFFER* ppCompilationErrors) {
if (ppCompiledShader) *ppCompiledShader = new ID3DXBuffer();
if (ppCompilationErrors) *ppCompilationErrors = new ID3DXBuffer();
return S_OK;
}
inline HRESULT D3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen, DWORD flags, LPD3DXBUFFER* ppConstants, LPD3DXBUFFER* ppCompiledShader, LPD3DXBUFFER* ppCompilationErrors) {
if (ppCompiledShader) *ppCompiledShader = new ID3DXBuffer();
if (ppCompilationErrors) *ppCompilationErrors = new ID3DXBuffer();
return S_OK;
}
[HASH=1]#define[/HASH] D3DX_FILTER_NONE 1
[HASH=1]#define[/HASH] D3DX_FILTER_LINEAR 2
[HASH=1]#define[/HASH] D3DX_DEFAULT ((UINT)-1)
inline HRESULT D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE8 pDevice, LPCVOID pSrcData, UINT SrcDataSize, UINT Width, UINT Height, UINT MipLevels, DWORD Usage, int Format, int Pool, DWORD Filter, DWORD MipFilter, GLCOLOR ColorKey, D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, LPDIRECT3DTEXTURE8* ppTexture) { *ppTexture = 0; return S_OK; }
inline HRESULT D3DXCreateTexture(LPDIRECT3DDEVICE8 pDevice, UINT Width, UINT Height, UINT MipLevels, DWORD Usage, int Format, int Pool, LPDIRECT3DTEXTURE8* ppTexture) { *ppTexture = 0; return S_OK; }
inline HRESULT D3DXLoadSurfaceFromSurface(void* pDestSurface, const PALETTEENTRY* pDestPalette, const RECT* pDestRect, void* pSrcSurface, const PALETTEENTRY* pSrcPalette, const RECT* pSrcRect, DWORD Filter, GLCOLOR ColorKey) { return S_OK; }
// Constants stub
[HASH=1]#define[/HASH] D3DTS_WORLD 1
[HASH=1]#define[/HASH] D3DTS_VIEW 2
[HASH=1]#define[/HASH] D3DTS_PROJECTION 3
[HASH=1]#define[/HASH] D3DCLEAR_TARGET 1
[HASH=1]#define[/HASH] D3DCLEAR_ZBUFFER 2
[HASH=1]#define[/HASH] D3DFVF_XYZ 0x002
[HASH=1]#define[/HASH] D3DFVF_XYZRHW 0x004
[HASH=1]#define[/HASH] D3DFVF_NORMAL 0x010
[HASH=1]#define[/HASH] D3DFVF_DIFFUSE 0x040
[HASH=1]#define[/HASH] D3DFVF_SPECULAR 0x080
[HASH=1]#define[/HASH] D3DFVF_TEX1 0x100
[HASH=1]#define[/HASH] D3DFVF_TEX2 0x200
[HASH=1]#define[/HASH] D3DFVF_TEXCOUNT_MASK 0xf00
[HASH=1]#define[/HASH] D3DFVF_TEXCOUNT_SHIFT 8
[HASH=1]#define[/HASH] D3DRS_ZENABLE 7
[HASH=1]#define[/HASH] D3DRS_FILLMODE 8
[HASH=1]#define[/HASH] D3DRS_SHADEMODE 9
[HASH=1]#define[/HASH] D3DRS_ZWRITEENABLE 14
[HASH=1]#define[/HASH] D3DRS_ALPHATESTENABLE 15
[HASH=1]#define[/HASH] D3DRS_SRCBLEND 19
[HASH=1]#define[/HASH] D3DRS_DESTBLEND 20
[HASH=1]#define[/HASH] D3DRS_CULLMODE 22
[HASH=1]#define[/HASH] D3DRS_ZFUNC 23
[HASH=1]#define[/HASH] D3DRS_ALPHAREF 24
[HASH=1]#define[/HASH] D3DRS_ALPHAFUNC 25
[HASH=1]#define[/HASH] D3DRS_ALPHABLENDENABLE 27
[HASH=1]#define[/HASH] D3DRS_LIGHTING 137
[HASH=1]#define[/HASH] D3DRS_TEXTUREFACTOR 60
[HASH=1]#define[/HASH] D3DTSS_COLORARG1 1
[HASH=1]#define[/HASH] D3DTSS_COLORARG2 2
[HASH=1]#define[/HASH] D3DTSS_COLOROP 3
[HASH=1]#define[/HASH] D3DTSS_ALPHAARG1 4
[HASH=1]#define[/HASH] D3DTSS_ALPHAARG2 5
[HASH=1]#define[/HASH] D3DTSS_ALPHAOP 6
[HASH=1]#define[/HASH] D3DTSS_MINFILTER 7
[HASH=1]#define[/HASH] D3DTSS_MAGFILTER 8
[HASH=1]#define[/HASH] D3DTSS_MIPFILTER 9
[HASH=1]#define[/HASH] D3DTSS_ADDRESSU 10
[HASH=1]#define[/HASH] D3DTSS_ADDRESSV 11
[HASH=1]#define[/HASH] D3DPT_POINTLIST 1
[HASH=1]#define[/HASH] D3DPT_LINELIST 2
[HASH=1]#define[/HASH] D3DPT_LINESTRIP 3
[HASH=1]#define[/HASH] D3DPT_TRIANGLELIST 4
[HASH=1]#define[/HASH] D3DPT_TRIANGLESTRIP 5
[HASH=1]#define[/HASH] D3DPT_TRIANGLEFAN 6
[HASH=1]#define[/HASH] D3DFMT_UNKNOWN 0
[HASH=1]#define[/HASH] D3DFMT_R8G8B8 1
[HASH=1]#define[/HASH] D3DFMT_A8R8G8B8 2
[HASH=1]#define[/HASH] D3DFMT_X8R8G8B8 3
[HASH=1]#define[/HASH] D3DFMT_A4R4G4B4 4
[HASH=1]#define[/HASH] D3DFMT_A1R5G5B5 5
[HASH=1]#define[/HASH] D3DFMT_X1R5G5B5 6
[HASH=1]#define[/HASH] D3DFMT_A16B16G16R16 7
[HASH=1]#define[/HASH] D3DFMT_DXT1 8
[HASH=1]#define[/HASH] D3DFMT_DXT3 9
[HASH=1]#define[/HASH] D3DFMT_DXT5 10
[HASH=1]#define[/HASH] D3DFMT_D16 11
[HASH=1]#define[/HASH] D3DFMT_D15S1 12
[HASH=1]#define[/HASH] D3DFMT_D24X8 13
[HASH=1]#define[/HASH] D3DFMT_D24S8 14
[HASH=1]#define[/HASH] D3DFMT_D24X4S4 15
[HASH=1]#define[/HASH] D3DFMT_D32 16
[HASH=1]#define[/HASH] D3DFMT_INDEX16 17
[HASH=1]#define[/HASH] D3DFMT_R5G6B5 18
[HASH=1]#define[/HASH] D3DLOCKED_RECT void*
[HASH=1]#define[/HASH] D3DTA_TFACTOR 1
[HASH=1]#define[/HASH] D3DTA_TEXTURE 2
[HASH=1]#define[/HASH] D3DTA_CURRENT 3
[HASH=1]#define[/HASH] D3DTA_DIFFUSE 4
[HASH=1]#define[/HASH] D3DTOP_SELECTARG1 1
[HASH=1]#define[/HASH] D3DTOP_DISABLE 2
[HASH=1]#define[/HASH] D3DTOP_MODULATE 3
[HASH=1]#define[/HASH] D3DTOP_ADD 4
[HASH=1]#define[/HASH] D3DBLEND_INVDESTCOLOR 1
[HASH=1]#define[/HASH] D3DBLEND_ONE 2
[HASH=1]#define[/HASH] D3DBLEND_ZERO 3
[HASH=1]#define[/HASH] D3DBLEND_SRCCOLOR 4
[HASH=1]#define[/HASH] D3DBLEND_SRCALPHA 5
[HASH=1]#define[/HASH] D3DBLEND_INVSRCALPHA 6
[HASH=1]#define[/HASH] D3DCULL_CCW 1
[HASH=1]#define[/HASH] D3DCULL_CW 2
[HASH=1]#define[/HASH] D3DCULL_NONE 3
[HASH=1]#define[/HASH] D3DFILL_SOLID 1
[HASH=1]#define[/HASH] D3DFILL_WIREFRAME 2
[HASH=1]#define[/HASH] D3DLIGHT_POINT 1
[HASH=1]#define[/HASH] D3DSHADE_FLAT 1
[HASH=1]#define[/HASH] D3DCMP_LESSEQUAL 1
[HASH=1]#define[/HASH] D3DTEXF_POINT 1
[HASH=1]#define[/HASH] D3DTADDRESS_CLAMP 1
[HASH=1]#define[/HASH] D3DPOOL_MANAGED 1
[HASH=1]#define[/HASH] D3DPOOL_SYSTEMMEM 2
[HASH=1]#define[/HASH] D3DPOOL_DEFAULT 3
[HASH=1]#define[/HASH] D3DPOOL_SCRATCH 4
[HASH=1]#define[/HASH] D3DLOCK_READONLY 1
[HASH=1]#define[/HASH] D3DLOCK_NO_DIRTY_UPDATE 2
[HASH=1]#define[/HASH] D3DLOCK_DISCARD 3
[HASH=1]#define[/HASH] D3DUSAGE_WRITEONLY 1
[HASH=1]#define[/HASH] D3DUSAGE_DYNAMIC 2
[HASH=1]#define[/HASH] D3DUSAGE_DEPTHSTENCIL 3
[HASH=1]#define[/HASH] D3DUSAGE_RENDERTARGET 4
[HASH=1]#define[/HASH] D3D_OK 0
[HASH=1]#define[/HASH] D3DERR_DEVICELOST 1
[HASH=1]#define[/HASH] D3DERR_DEVICENOTRESET 2
[HASH=1]#define[/HASH] D3DERR_INVALIDCALL 3
[HASH=1]#define[/HASH] D3DERR_NOTAVAILABLE 4
[HASH=1]#define[/HASH] D3DERR_OUTOFVIDEOMEMORY 5
[HASH=1]#define[/HASH] D3DERR_WASSTILLDRAWING 6
[HASH=1]#define[/HASH] D3DADAPTER_DEFAULT 0
[HASH=1]#define[/HASH] D3DSWAPEFFECT_COPY 1
[HASH=1]#define[/HASH] D3DSWAPEFFECT_DISCARD 2
[HASH=1]#define[/HASH] D3DPRESENT_INTERVAL_IMMEDIATE 1
[HASH=1]#define[/HASH] D3DPRESENTFLAG_LOCKABLE_BACKBUFFER 1
[HASH=1]#define[/HASH] D3DENUM_NO_WHQL_LEVEL 1
[HASH=1]#define[/HASH] D3DCREATE_PUREDEVICE 1
[HASH=1]#define[/HASH] D3DCREATE_HARDWARE_VERTEXPROCESSING 2
[HASH=1]#define[/HASH] D3DCREATE_MIXED_VERTEXPROCESSING 3
[HASH=1]#define[/HASH] D3DCREATE_SOFTWARE_VERTEXPROCESSING 4
[HASH=1]#define[/HASH] D3DRTYPE_SURFACE 1
[HASH=1]#define[/HASH] D3DRTYPE_TEXTURE 2
[HASH=1]#define[/HASH] D3DMULTISAMPLE_NONE 0
[HASH=1]#define[/HASH] D3DDEVICETYPE_HAL 1
[HASH=1]#define[/HASH] D3DDEVICETYPE_REF 2
[HASH=1]#define[/HASH] D3DPMISCCAPS_CLIPTLVERTS 1
[HASH=1]#define[/HASH] D3DVTXPCAPS_DIRECTIONALLIGHTS 1
[HASH=1]#define[/HASH] D3DVTXPCAPS_POSITIONALLIGHTS 2
[HASH=1]#define[/HASH] D3DVTXPCAPS_TEXGEN 3
[HASH=1]#define[/HASH] D3DCAPS2_CANRENDERWINDOWED 1
[HASH=1]#define[/HASH] D3DDEVCAPS_HWTRANSFORMANDLIGHT 1
[HASH=1]#define[/HASH] D3DDEVCAPS_PUREDEVICE 2
[HASH=1]#define[/HASH] D3DVS_VERSION(major, minor) (0)
[HASH=3]#endif[/HASH]
Ekli dosyayı görüntüle 175867
AndroidMain.cpp:
#include "StdAfx.h"
[HASH=2388]#include[/HASH] "PythonApplication.h"
[HASH=2388]#include[/HASH] <jni.h>
[HASH=2388]#include[/HASH] <android/log.h>
[HASH=2388]#include[/HASH] <android/asset_manager.h>
[HASH=2388]#include[/HASH] <android/asset_manager_jni.h>
[HASH=1]#define[/HASH] LOG_TAG "Metin2Mobile"
[HASH=1]#define[/HASH] LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
[HASH=1]#define[/HASH] LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
extern "C" {
JNIEXPORT void JNICALL Java_com_metin2_client_NativeLib_init(JNIEnv* env, jobject obj, jobject assetManager, jint width, jint height) {
LOGI("Initializing Metin2 Mobile Engine (%dx%d)", width, height);
// Store AAssetManager globally
extern AAssetManager* g_pAssetManager;
g_pAssetManager = AAssetManager_fromJava(env, assetManager);
static CPythonApplication app;
// We pass NULL for poSelf (Python self object) as we are calling from C++ side
// and provide some default name, width, height.
if (!app.Create(NULL, "Metin2Mobile", width, height, 1)) {
LOGE("CPythonApplication::Create failed!");
return;
}
LOGI("Metin2 Mobile Engine Initialized Successfuly");
}
JNIEXPORT void JNICALL Java_com_metin2_client_NativeLib_render(JNIEnv* env, jobject obj) {
if (CPythonApplication::InstancePtr()) {
static DWORD dwLastTime = 0;
DWORD dwCurrentTime = ELTimer_GetMSec();
if (dwLastTime == 0) dwLastTime = dwCurrentTime;
// Update the application
CPythonApplication::InstancePtr()->Update();
// Render the application
CPythonApplication::InstancePtr()->Render();
dwLastTime = dwCurrentTime;
}
}
JNIEXPORT void JNICALL Java_com_metin2_client_NativeLib_touchEvent(JNIEnv* env, jobject obj, jint action, jfloat x, jfloat y) {
if (CPythonApplication::InstancePtr()) {
// action matches Android MotionEvent actions:
// 0: ACTION_DOWN
// 1: ACTION_UP
// 2: ACTION_MOVE
if (action == 0) { // ACTION_DOWN
CPythonApplication::InstancePtr()->OnMouseLeftButtonDown(x, y);
} else if (action == 1) { // ACTION_UP
CPythonApplication::InstancePtr()->OnMouseLeftButtonUp(x, y);
} else if (action == 2) { // ACTION_MOVE
CPythonApplication::InstancePtr()->OnMouseMove(x, y);
}
}
}
}
Bu projenin temel amaçları kesin ve öz olarak şunlardır:
- Metin2 PC kaynak kodlarını modern mobil cihazlara ve Android platformuna taşındı.
- DirectX 8 tabanlı eski grafik motorunu OpenGL ES 3.0 standartlarına yükseltildi
- Shader tabanlı yeni nesil render hattı ile yüksek performanslı bir oyun deneyimi sunuldu.
- Dokunmatik ekranlar için optimize edilmiş arayüz ve sanal joystick sistemini entegre edildi.
- Oyunun çekirdek mekaniklerini koruyarak, mobil ekosistemde akıcı ve hatasız çalışmasını sağlandı.
ÖLÜM 1: MİMARİ FELSEFE VE MODERNİZASYONUN TEMELLERİ
Projenin temel teknik zorluğu, Metin2'nin temelinin 2000'lerin başındaki "Fixed-Function Pipeline" (Sabit Fonksiyon Hattı) mantığına sahip olan Direct3D 8 API'sine dayanmasıdır. Bu mimaride, grafik kartına ekran kartının donanımında yerleşik olan fonksiyonlar (ışıklandırma, malzeme (material) özellikleri vb.) doğrudan emir olarak verilir. Ancak, modern Android cihazlar (arm64/v8), GLES 3.0+ standartlarını kullanır ve tamamen "Programlanabilir" (Programmable) bir yapıya, yani gölgelendirici (shader) yazılımlarına dayalı çalışır.Bu projede kullanılan temel modernizasyon yaklaşımı, oyunun C++ çekirdeğine "sanal" bir cihaz (Direct3D 8 aygıtı taklidi yapan bir ara katman) sunmaktır. Bu sayede oyun motorunun geri kalanı, kendisinin bir mobil cihazda olduğunu anlamadan normal şekilde çalışmaya devam eder.
BÖLÜM 2: GRAFİK VE RENDER HATTININ DÖNÜŞÜMÜ (EterLib)
Projenin teknik olarak en yoğun kısmı clientsource/EterLib klasörü altında toplanmıştır. Burada yapılan işlemler, motorun "DirectX 8" dünyasından "OpenGL ES" dünyasına göçünü temsil eder.A. Direct3D - OpenGL Ara Katmanı (API Bridging)
GrpOpenGL.cpp ve GrpOpenGL.h dosyaları, oyun motorunun beklediği IDirect3DDevice8 metotlarını OpenGL eşlenikleriyle sarmalar. Örneğin, DirectX'teki DrawIndexedPrimitive çağrısı, OpenGL dünyasında tek bir komut değildir; bunun yerine GLES tarafında glBindBuffer (VBO), glVertexAttribPointer (attribute yönetimi) ve glDrawElements komutlarının bir dizisi olarak simüle edilir.B. Shader Yönetimi ve Modernizasyon
Sabit fonksiyon hattından vazgeçildiği için, ışıklandırma (GrpLightManager), doku birleştirme ve malzeme özellikleri tamamen GLSL shader'larına devredilmiştir. Bu, PC sürümüne kıyasla inanılmaz bir grafik esnekliği sağlar; çünkü artık her türlü görsel efekt (gölge haritalama, yüksek kontrast, shader tabanlı şeffaflık efektleri) doğrudan GPU üzerinde, mobil cihazların yerel hızlandırıcıları kullanılarak işlenmektedir.C. Buffer ve Bellek Yönetimi (VBO/IBO)
PC sürümünde veriler CPU üzerinden sık sık GPU'ya taşınırken, GrpVertexBufferStatic, GrpIndexBufferDynamic yapıları sayesinde, harita verileri, karakter modelleri ve envanter ikonları, GPU'nun hızlı belleğine (VRAM/GLESBuffer) bir kez gönderilmekte ve orada saklanmaktadır. Bu, Android cihazlarda en çok ihtiyaç duyulan "düşük donanım kullanımı" ve "yüksek performans" kriterinin en büyük anahtarıdır.BÖLÜM 3: 3D MODELLEME VE DÜNYA TEKNOLOJİLERİ (GameLib & EterGrnLib)
Oyunun yaşamasını sağlayan 3D sistemlerin taşınması ciddi bir matematiksel operasyondur.A. Granny Model ve Animasyon (EterGrnLib)
EterGrnLib içerisindeki ModelInstance yapıları, DirectX koordinat sistemi ile çalışacak şekilde optimize edilmiştir. OpenGL'in koordinat sistemi (y ekseninin yönü ve sağ/sol el matris kuralları) ile DirectX arasında farklılıklar bulunmaktadır. Proje kapsamında ModelInstanceMotion dosyalarında yapılan yamalar, matris dönüşümlerinin (Projection/ModelView) GLES shader'larına gönderilmeden önce, mobil GPU'nun anladığı Left-Handed koordinat düzenine dönüştürülmesini sağlar.B. Dünya ve Fizik (GameLib & SpeedTreeLib)
Harita sistemi (MapOutdoor) karmaşık bir Quadtree (dörtlü ağaç) yapısına sahiptir. GameLib içerisindeki Quadtree hesaplamaları, arazi parçalarını (TerrainPatch) sadece görüş alanı (frustum culling) içerisindeyse işler. Bu, Android'in sınırlı CPU gücüyle haritayı çizmesini sağlayan en kritik sistemdir. SpeedTreeLib de benzer şekilde, yerel ağaç ve bitki örtüsünün, shader tabanlı bir yönetimle hızlıca render edilmesini sağlar.BÖLÜM 4: ANDROID NATIVE INTEGRASYONU (UserInterface)
Oyunun PC kodları ile Android işletim sistemi arasındaki köprü burasıdır.A. Android Lifecycle ve JNI Yönetimi
UserInterface/AndroidMain.cpp ve UserInterface/PythonApplication.cpp dosyaları, Java ile iletişimi (JNI) ve Android'in grafik arayüzünü (Surface/EGL) yönetir. Oyun arkaplana atıldığında veya tekrar açıldığında GLES context'inin bozulmaması/ölmemesi için gerekli olan yaşam döngüsü (Lifecycle) burada kontrol edilmektedir.B. Windows - Android Uyumluluk Katmanı (android_compat/)
PC sürümü windows.h başlık dosyasını doğrudan kullanır. Android'de windows.h yoktur. clientsource/android_compat/windows.h dosyası, oyunun beklediği temel veri tiplerini (DWORD, HRESULT, LARGE_INTEGER, HANDLE vb.) yerel Linux eşlenikleriyle tanımlayan bir yama katmanıdır. Bu katman olmasa, binlerce satır kodun yeniden yazılması gerekirdi.BÖLÜM 5: DOSYA SİSTEMİ VE PACK YAPISI (EterPack)
Mobil cihazlarda dosya okuma (I/O) işlemleri PC sürümünden çok daha farklı ve yavaştır.EterPack kütüphanesi, oyunun .epk ve .eix dosyalarını yönetir. EterPackManager, dosyaları okumak için Android'in Storage Access Framework (SAF) veya assets kısımlarını yerel C++ üzerinden kullanacak şekilde modifiye edilmiştir (MappedFile.cpp). Bu, haritaların veya karakterlerin yüklenirken donma (lag) yaşamasının önlenmesi için kritik öneme sahiptir.
BÖLÜM 6: SONUÇ VE TEKNİK ÖZET
Özetlemek gerekirse, bu proje teknik olarak dört ana sütun üzerinde yükselmektedir:- Grafik İzolasyonu (EterLib/GrpOpenGL): DirectX'in soyutlanıp modern shader'lara dönüştürülmesi.
- Matematiksel Dönüşüm: Koordinat sistemi ve matris hesaplamalarının GLES'e uyarlanması.
- Donanım Native Entegrasyonu (UserInterface/jni): Android ekosistemi ile C++ oyun çekirdeğinin kusursuz haberleşmesi.
- Data Optimizasyonu (EterPack): Mobil depolama birimlerinden verimli dosya okuma.
İndir OPENGL ITJA zip
İndir rar


