Files
mcpe/thirdparty/GL/GLExt.cpp
f f83ead9f8d WIP Android Port (#79)
* WIP Android Port

Android port. Still needs touch controls and mouse turning (if that's even possible on android) and file saving and SoundSystemSL
You control the camera and movement with your controller for now. You can navigate the gui using touch.
Options.cpp,LocalPlayer.cpp,Minecraft.cpp is configured to use controller.
Blocked out some code in ControllerTurnInput.cpp,Controller.cpp that didn't make sense.

* Fix glClear

glClear is supossed to use GL_DEPTH_BUFFER_BIT (thx TheBrokenRail)

* * Fix build.

* * Ignore assets.

* * More stuff

* * Fix more build errors.

* * It finally built

What I needed to do is rebuild the debug keystore because apparently android studio created it with sha1 digest alg which isn't supported by ant

* * Clean up filters.

* * Add cramped mode to the pause screen.

* * Fix a bug with the hotbar

* * In NinecraftApp::handleBack, pause the game if there is no screen.

* * AppPlatform_android: Add placeholder SoundSystem instance till we get SoundSystemSL working

* * Add properly working touch code.

* * Oh, remove some testing things

* * Fix state resetting when going in background and back in foreground
* Fix bug where the sky isn't being regenerated on graphics reset
* Fix bug where the m_currBoundTex isn't reset in Textures::clear potentially leaving a texture with that ID unassigned and corrupted
* Fix bug in CThread where the thread is detached and then also joined.
* Don't log anything if the program isn't in debug mode.

* * Add virtual keyboard support.

The screen instance slides so that the focused text box is kept visible.

* Rename from com.minecraftcpp to com.reminecraftpe

---------

Co-authored-by: iProgramInCpp <iprogramincpp@gmail.com>
2023-11-03 12:54:39 +02:00

505 lines
11 KiB
C++

/********************************************************************
Minecraft: Pocket Edition - Decompilation Project
Copyright (C) 2023 iProgramInCpp
The following code is licensed under the BSD 1 clause license.
SPDX-License-Identifier: BSD-1-Clause
********************************************************************/
#ifdef _WIN32
#include "GL.hpp"
#include <unordered_map>
#ifdef _WIN32
HWND GetHWND();
#ifndef USE_OPENGL_2
// this is stupidly hacky
typedef BOOL(WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval);
#endif
#endif
// Don't undefine. It will make the game MUCH slower.
#define USE_HARDWARE_GL_BUFFERS
#ifdef USE_HARDWARE_GL_BUFFERS
PFNGLBINDBUFFERPROC p_glBindBuffer;
PFNGLBUFFERDATAPROC p_glBufferData;
PFNGLGENBUFFERSPROC p_glGenBuffers;
PFNGLDELETEBUFFERSPROC p_glDeleteBuffers;
#endif
#ifndef USE_OPENGL_2
// Note: don't use xglSwapIntervalEXT if you want vsync, you don't know if it's supported
// on your platform so you need to query the extension APIs
PFNWGLSWAPINTERVALEXTPROC p_wglSwapIntervalEXT;
#endif
bool xglInitted()
{
#ifdef USE_HARDWARE_GL_BUFFERS
return p_glBindBuffer && p_glBufferData && p_glGenBuffers && p_glDeleteBuffers;
#else
return true;
#endif
}
void xglInit()
{
#ifdef USE_HARDWARE_GL_BUFFERS
#ifdef _WIN32
p_glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
p_glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
p_glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");
p_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");
#else
p_glBindBuffer = (PFNGLBINDBUFFERPROC)glBindBuffer;
p_glBufferData = (PFNGLBUFFERDATAPROC)glBufferData;
p_glGenBuffers = (PFNGLGENBUFFERSPROC)glGenBuffers;
p_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)glDeleteBuffers;
#endif
#endif
#ifndef USE_OPENGL_2
p_wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
#endif
#ifdef USE_HARDWARE_GL_BUFFERS
if (!xglInitted())
{
const char* const GL_ERROR_MSG = "Error initializing GL extensions. OpenGL 2.0 or later is required. Update your graphics drivers!";
LOG_E(GL_ERROR_MSG);
#ifdef _WIN32
MessageBoxA(GetHWND(), GL_ERROR_MSG, "OpenGL Error", MB_OK);
#endif
}
#endif
}
#ifdef USE_HARDWARE_GL_BUFFERS
void xglBindBuffer(GLenum target, GLuint buffer)
{
p_glBindBuffer(target, buffer);
}
void xglBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
p_glBufferData(target, size, data, usage);
}
void xglGenBuffers(GLsizei num, GLuint* buffers)
{
p_glGenBuffers(num, buffers);
}
void xglDeleteBuffers(GLsizei num, GLuint* buffers)
{
p_glDeleteBuffers(num, buffers);
}
void xglEnableClientState(GLenum _array)
{
glEnableClientState(_array);
}
void xglDisableClientState(GLenum _array)
{
glDisableClientState(_array);
}
void xglTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
glTexCoordPointer(size, type, stride, pointer);
}
void xglColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
glColorPointer(size, type, stride, pointer);
}
void xglVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
glVertexPointer(size, type, stride, pointer);
}
void xglDrawArrays(GLenum mode, GLint first, GLsizei count)
{
glDrawArrays(mode, first, count);
}
#endif
#ifndef USE_GL_ORTHO_F
void xglOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearpl, GLfloat farpl)
{
return glOrtho(GLdouble(left), GLdouble(right), GLdouble(bottom), GLfloat(top), GLdouble(nearpl), GLdouble(farpl));
}
#endif
void xglSwapIntervalEXT(int interval)
{
#ifndef USE_OPENGL_2
if (!p_wglSwapIntervalEXT)
return;
p_wglSwapIntervalEXT(interval);
#endif
}
#ifndef USE_HARDWARE_GL_BUFFERS
// ** Incomplete software based emulation of OpenGL vertex buffers.
#define USE_DISPLAY_LISTS
struct GLBuffer
{
GLuint m_id;
GLvoid* m_pBufferData;
GLsizei m_bufferSize;
GLenum m_usage; // as passed into glBufferData
// vertex pointer
GLint m_vtx_size;
GLenum m_vtx_type;
GLsizei m_vtx_stride;
GLint m_vtx_offset;
// texture coord pointer
GLint m_tc_size;
GLenum m_tc_type;
GLsizei m_tc_stride;
GLint m_tc_offset;
// color pointer
GLint m_col_size;
GLenum m_col_type;
GLsizei m_col_stride;
GLint m_col_offset;
// associated display list
GLuint m_AssociatedDisplayList; // used if USE_DISPLAY_LISTS is on
GLBuffer(GLuint id)
{
m_id = id;
m_pBufferData = nullptr;
m_bufferSize = 0;
m_usage = 0;
m_AssociatedDisplayList = 0;
}
void DeletePreExistingDLIfNeeded()
{
#ifdef USE_DISPLAY_LISTS
if (m_AssociatedDisplayList != 0)
glDeleteLists(m_AssociatedDisplayList, 1);
m_AssociatedDisplayList = 0;
#endif
}
bool HasDisplayList()
{
#ifndef USE_DISPLAY_LISTS
return false;
#endif
return m_AssociatedDisplayList != 0;
}
GLuint GetDisplayList()
{
return m_AssociatedDisplayList;
}
void SetDisplayList(GLuint dl)
{
m_AssociatedDisplayList = dl;
}
void SetVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* offset)
{
int ioffset = int(size_t(offset));
if (m_vtx_size == size &&
m_vtx_type == type &&
m_vtx_stride == stride &&
m_vtx_offset == ioffset)
return;
DeletePreExistingDLIfNeeded();
m_vtx_size = size;
m_vtx_type = type;
m_vtx_stride = stride;
m_vtx_offset = ioffset;
}
void SetTextureCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* offset)
{
int ioffset = int(size_t(offset));
if (m_tc_size == size &&
m_tc_type == type &&
m_tc_stride == stride &&
m_tc_offset == ioffset)
return;
DeletePreExistingDLIfNeeded();
m_tc_size = size;
m_tc_type = type;
m_tc_stride = stride;
m_tc_offset = int(size_t(offset));
}
void SetColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* offset)
{
int ioffset = int(size_t(offset));
if (m_col_size == size &&
m_col_type == type &&
m_col_stride == stride &&
m_col_offset == ioffset)
return;
DeletePreExistingDLIfNeeded();
m_col_size = size;
m_col_type = type;
m_col_stride = stride;
m_col_offset = int(size_t(offset));
}
};
typedef std::unordered_map<GLuint, GLBuffer*> GLBufferMap;
GLBufferMap g_GLBuffers;
GLBuffer* g_pCurrentlyBoundGLBuffer = nullptr;
GLuint g_NextGLBufferID;
bool g_bUseVertexArrays, g_bUseColorArrays, g_bUseTextureCoordArrays; // modified by xgl[En/Dis]ableClientState
void xglGenBuffers(GLsizei num, GLuint* buffers)
{
for (GLsizei i = 0; i < num; i++)
{
*buffers++ = ++g_NextGLBufferID;
g_GLBuffers[g_NextGLBufferID] = new GLBuffer(g_NextGLBufferID);
}
LOG_I("g_NextGLBufferID=%d", g_NextGLBufferID);
}
void xglAssert2(bool condition, const char* condstr, const char* file, int line)
{
if (condition) return;
LOG_E("Error: Assertion failed at %s:%d: %s", file, line, condstr);
#ifdef _MSC_VER
assert(false);
#endif
exit(1);
}
#define xglAssert(condition) xglAssert2(condition,#condition,__FILE__,__LINE__)
void xglVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
xglAssert(g_pCurrentlyBoundGLBuffer != nullptr);
g_pCurrentlyBoundGLBuffer->SetVertexPointer(size, type, stride, pointer);
}
void xglTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
xglAssert(g_pCurrentlyBoundGLBuffer != nullptr);
g_pCurrentlyBoundGLBuffer->SetTextureCoordPointer(size, type, stride, pointer);
}
void xglColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
xglAssert(g_pCurrentlyBoundGLBuffer != nullptr);
g_pCurrentlyBoundGLBuffer->SetColorPointer(size, type, stride, pointer);
}
void xglBindBuffer(GLenum target, GLuint bufferID)
{
xglAssert(target == GL_ARRAY_BUFFER);
GLBufferMap::iterator iter = g_GLBuffers.find(bufferID);
if (iter == g_GLBuffers.end())
return;
g_pCurrentlyBoundGLBuffer = iter->second;
}
void xglBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
xglAssert(target == GL_ARRAY_BUFFER);
xglAssert(g_pCurrentlyBoundGLBuffer != nullptr);
GLBuffer* pBuf = g_pCurrentlyBoundGLBuffer;
// check if the data is the SAME:
if (pBuf->m_bufferSize == size && memcmp(pBuf->m_pBufferData, data, size) == 0)
{
//nope
pBuf->m_usage = usage;
return;
}
pBuf->DeletePreExistingDLIfNeeded();
// free the old data, if there was any
if (pBuf->m_pBufferData)
{
free(pBuf->m_pBufferData);
pBuf->m_pBufferData = nullptr;
}
pBuf->m_pBufferData = (GLvoid*)malloc(size);
xglAssert(pBuf->m_pBufferData != nullptr);
memcpy(pBuf->m_pBufferData, data, size);
pBuf->m_usage = usage;
}
void xglDeleteBuffer(GLsizei num)
{
GLBufferMap::iterator iter = g_GLBuffers.find(num);
xglAssert(iter != g_GLBuffers.end());
if (iter->second == g_pCurrentlyBoundGLBuffer)
g_pCurrentlyBoundGLBuffer = nullptr;
iter->second->DeletePreExistingDLIfNeeded();
delete iter->second;
g_GLBuffers.erase(iter);
}
void xglDeleteBuffers(GLsizei num, GLuint* buffers)
{
for (GLsizei i = 0; i < num; i++)
{
xglDeleteBuffer(buffers[i]);
buffers[i] = 0;
}
}
void xglEnableClientState(GLenum _array)
{
if (_array == GL_VERTEX_ARRAY)
{
g_bUseVertexArrays = true;
return;
}
if (_array == GL_COLOR_ARRAY)
{
g_bUseColorArrays = true;
return;
}
if (_array == GL_TEXTURE_COORD_ARRAY)
{
g_bUseTextureCoordArrays = true;
return;
}
glEnableClientState(_array);
}
void xglDisableClientState(GLenum _array)
{
if (_array == GL_VERTEX_ARRAY)
{
g_bUseVertexArrays = false;
return;
}
if (_array == GL_COLOR_ARRAY)
{
g_bUseColorArrays = false;
return;
}
if (_array == GL_TEXTURE_COORD_ARRAY)
{
g_bUseTextureCoordArrays = false;
return;
}
glDisableClientState(_array);
}
void xglDrawArrays(GLenum mode, GLint first, GLsizei count)
{
xglAssert(g_pCurrentlyBoundGLBuffer != nullptr);
GLBuffer* pBuf = g_pCurrentlyBoundGLBuffer;
#ifdef USE_DISPLAY_LISTS
if (pBuf->HasDisplayList())
{
glCallList(pBuf->GetDisplayList());
return;
}
GLuint currDL = glGenLists(1);
pBuf->SetDisplayList(currDL);
glNewList(currDL, GL_COMPILE);
#endif
glBegin(mode);
for (GLsizeiptr i = first, j = 0; j < count; i++, j++)
{
uintptr_t addr = uintptr_t(pBuf->m_pBufferData);
void* pVtx = (void*)(addr + pBuf->m_vtx_offset + i * pBuf->m_vtx_stride);
void* pCol = (void*)(addr + pBuf->m_col_offset + i * pBuf->m_col_stride);
void* pTC = (void*)(addr + pBuf->m_tc_offset + i * pBuf->m_tc_stride);
if (g_bUseTextureCoordArrays)
{
if (pBuf->m_tc_type == GL_FLOAT)
{
float* pfTC = (float*)pTC;
/**/ if (pBuf->m_tc_size == 2)
glTexCoord2fv(pfTC);
else xglAssert(!"Unimplemented texcoord size!");
}
else xglAssert(!"Unimplemented texcoord type!");
}
if (g_bUseColorArrays)
{
if (pBuf->m_col_type == GL_UNSIGNED_BYTE)
{
uint8_t* pfCol = (uint8_t*)pCol;
/**/ if (pBuf->m_col_size == 4)
glColor4f(float(pfCol[0])/255.0f, float(pfCol[1])/255.0f, float(pfCol[2])/255.0f, float(pfCol[3])/255.0f);
else xglAssert(!"Unimplemented color size!");
}
else xglAssert(!"Unimplemented color type!");
}
if (g_bUseVertexArrays)
{
if (pBuf->m_vtx_type == GL_FLOAT)
{
float* pfVtx = (float*)pVtx;
/**/ if (pBuf->m_vtx_size == 3)
glVertex3fv(pfVtx);
else if (pBuf->m_vtx_size == 2)
glVertex2fv(pfVtx);
else xglAssert(!"Unimplemented texcoord size!");
}
else xglAssert(!"Unimplemented vertex type!");
}
}
glEnd();
#ifdef USE_DISPLAY_LISTS
glEndList();
glCallList(pBuf->GetDisplayList());
#endif
}
#endif
#endif