mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-08-20 09:57:10 +00:00
its so peak
This commit is contained in:
parent
afd41f33e8
commit
0b96b3064d
|
|
@ -35,8 +35,10 @@ static void makeGLCtxKey() { pthread_key_create(&s_glCtxKey, nullptr); }
|
||||||
|
|
||||||
// Pre-created pool of shared contexts for worker threads
|
// Pre-created pool of shared contexts for worker threads
|
||||||
|
|
||||||
// TODO: WAS MAX_SHARED_CONTEXTS = 8 but seems to no render well on AMD cards
|
// AMD drivers (especially on Linux/Mesa) can be very sensitive to the number of shared contexts
|
||||||
static const int MAX_SHARED_CONTEXTS = 3;
|
// and concurrent display list compilation. 8 was original, 4 was an attempt to fix it.
|
||||||
|
// 6 covers the 5 concurrent worker threads (update + 3x rebuild + main thread).
|
||||||
|
static const int MAX_SHARED_CONTEXTS = 6;
|
||||||
static GLFWwindow *s_sharedContexts[MAX_SHARED_CONTEXTS] = {};
|
static GLFWwindow *s_sharedContexts[MAX_SHARED_CONTEXTS] = {};
|
||||||
static int s_sharedContextCount = 0;
|
static int s_sharedContextCount = 0;
|
||||||
static int s_nextSharedContext = 0;
|
static int s_nextSharedContext = 0;
|
||||||
|
|
@ -81,8 +83,6 @@ void C4JRender::Initialise()
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||||||
glfwWindowHint(GLFW_DEPTH_BITS, 24);
|
glfwWindowHint(GLFW_DEPTH_BITS, 24);
|
||||||
glfwWindowHint(GLFW_STENCIL_BITS, 8);
|
glfwWindowHint(GLFW_STENCIL_BITS, 8);
|
||||||
glfwWindowHint(GLFW_DEPTH_BITS, 24);
|
|
||||||
glfwWindowHint(GLFW_STENCIL_BITS, 8);
|
|
||||||
|
|
||||||
GLFWmonitor *fsMonitor = s_fullscreen ? primaryMonitor : nullptr;
|
GLFWmonitor *fsMonitor = s_fullscreen ? primaryMonitor : nullptr;
|
||||||
s_window = glfwCreateWindow(s_windowWidth, s_windowHeight,
|
s_window = glfwCreateWindow(s_windowWidth, s_windowHeight,
|
||||||
|
|
@ -130,10 +130,10 @@ void C4JRender::Initialise()
|
||||||
|
|
||||||
// Pre-create shared GL contexts for worker threads (chunk builders etc.)
|
// Pre-create shared GL contexts for worker threads (chunk builders etc.)
|
||||||
// Must be done on the main thread because GLFW requires it.
|
// Must be done on the main thread because GLFW requires it.
|
||||||
|
// Ensure they are invisible so they don't interfere with the window manager.
|
||||||
|
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||||
for (int i = 0; i < MAX_SHARED_CONTEXTS; i++) {
|
for (int i = 0; i < MAX_SHARED_CONTEXTS; i++) {
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
|
||||||
s_sharedContexts[i] = glfwCreateWindow(1, 1, "", nullptr, s_window);
|
s_sharedContexts[i] = glfwCreateWindow(1, 1, "", nullptr, s_window);
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
|
|
||||||
if (s_sharedContexts[i]) {
|
if (s_sharedContexts[i]) {
|
||||||
s_sharedContextCount++;
|
s_sharedContextCount++;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -141,6 +141,8 @@ void C4JRender::Initialise()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
|
||||||
|
|
||||||
// Ensure main thread still has the context
|
// Ensure main thread still has the context
|
||||||
glfwMakeContextCurrent(s_window);
|
glfwMakeContextCurrent(s_window);
|
||||||
fprintf(stderr, "[4J_Render] Created %d shared GL contexts for worker threads\n", s_sharedContextCount);
|
fprintf(stderr, "[4J_Render] Created %d shared GL contexts for worker threads\n", s_sharedContextCount);
|
||||||
|
|
@ -175,12 +177,25 @@ void C4JRender::InitialiseContext()
|
||||||
pthread_mutex_unlock(&s_sharedCtxMutex);
|
pthread_mutex_unlock(&s_sharedCtxMutex);
|
||||||
|
|
||||||
if (!shared) {
|
if (!shared) {
|
||||||
fprintf(stderr, "[4J_Render] ERROR: no shared GL contexts left for worker thread!\n");
|
fprintf(stderr, "[4J_Render] ERROR: no shared GL contexts left for worker thread %lu!\n", (unsigned long)pthread_self());
|
||||||
|
fflush(stderr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
glfwMakeContextCurrent(shared);
|
glfwMakeContextCurrent(shared);
|
||||||
|
|
||||||
|
// Initialize some basic state for this context to ensure consistent display list recording
|
||||||
|
::glEnable(GL_TEXTURE_2D);
|
||||||
|
::glEnable(GL_DEPTH_TEST);
|
||||||
|
::glDepthFunc(GL_LEQUAL);
|
||||||
|
::glAlphaFunc(GL_GREATER, 0.1f);
|
||||||
|
::glEnable(GL_BLEND);
|
||||||
|
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
::glShadeModel(GL_SMOOTH);
|
||||||
|
::glEnable(GL_COLOR_MATERIAL);
|
||||||
|
::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||||
|
|
||||||
pthread_setspecific(s_glCtxKey, shared);
|
pthread_setspecific(s_glCtxKey, shared);
|
||||||
fprintf(stderr, "[4J_Render] Assigned shared GL context %p to worker thread\n", (void*)shared);
|
fprintf(stderr, "[4J_Render] Assigned shared GL context %p to worker thread %lu\n", (void*)shared, (unsigned long)pthread_self());
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,15 +304,23 @@ void C4JRender::Set_matrixDirty() {} // immediate-mode
|
||||||
|
|
||||||
static GLenum mapPrimType(int pt)
|
static GLenum mapPrimType(int pt)
|
||||||
{
|
{
|
||||||
|
// Handle GL constants first
|
||||||
|
if (pt == GL_QUADS) return GL_QUADS;
|
||||||
|
if (pt == GL_TRIANGLES) return GL_TRIANGLES;
|
||||||
|
if (pt == GL_LINES) return GL_LINES;
|
||||||
|
if (pt == GL_LINE_STRIP) return GL_LINE_STRIP;
|
||||||
|
if (pt == GL_TRIANGLE_STRIP) return GL_TRIANGLE_STRIP;
|
||||||
|
if (pt == GL_TRIANGLE_FAN) return GL_TRIANGLE_FAN;
|
||||||
|
|
||||||
|
// Map from ePrimitiveType enum
|
||||||
switch (pt) {
|
switch (pt) {
|
||||||
case 0: return GL_TRIANGLES; // C4JRender::PRIMITIVE_TYPE_TRIANGLE_LIST
|
case C4JRender::PRIMITIVE_TYPE_TRIANGLE_LIST: return GL_TRIANGLES;
|
||||||
case GL_LINES: return GL_LINES;
|
case C4JRender::PRIMITIVE_TYPE_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP;
|
||||||
case GL_LINE_STRIP: return GL_LINE_STRIP;
|
case C4JRender::PRIMITIVE_TYPE_TRIANGLE_FAN: return GL_TRIANGLE_FAN;
|
||||||
case GL_TRIANGLES: return GL_TRIANGLES;
|
case C4JRender::PRIMITIVE_TYPE_QUAD_LIST: return GL_QUADS;
|
||||||
case GL_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP;
|
case C4JRender::PRIMITIVE_TYPE_LINE_LIST: return GL_LINES;
|
||||||
case GL_TRIANGLE_FAN: return GL_TRIANGLE_FAN;
|
case C4JRender::PRIMITIVE_TYPE_LINE_STRIP: return GL_LINE_STRIP;
|
||||||
case GL_QUADS: return GL_QUADS;
|
default: return GL_TRIANGLES;
|
||||||
default: return GL_TRIANGLES;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -332,8 +355,13 @@ void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count,
|
||||||
// Strip mipmap-disable flag: Tesselator adds +1.0 (= +8192) to u when mipmaps off
|
// Strip mipmap-disable flag: Tesselator adds +1.0 (= +8192) to u when mipmaps off
|
||||||
if (fu >= 1.0f) fu -= 1.0f;
|
if (fu >= 1.0f) fu -= 1.0f;
|
||||||
|
|
||||||
|
// Unit 1 (lightmap) UVs
|
||||||
|
float fu2 = (float)vert[6] / 256.0f;
|
||||||
|
float fv2 = (float)vert[7] / 256.0f;
|
||||||
|
|
||||||
::glColor3f(r, g, b);
|
::glColor3f(r, g, b);
|
||||||
::glTexCoord2f(fu, fv);
|
::glTexCoord2f(fu, fv);
|
||||||
|
::glMultiTexCoord2f(GL_TEXTURE1, fu2, fv2);
|
||||||
::glVertex3f(x, y, z);
|
::glVertex3f(x, y, z);
|
||||||
}
|
}
|
||||||
::glEnd();
|
::glEnd();
|
||||||
|
|
@ -354,19 +382,32 @@ void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count,
|
||||||
int8_t ny = (int8_t)((normalInt >> 8) & 0xFF);
|
int8_t ny = (int8_t)((normalInt >> 8) & 0xFF);
|
||||||
int8_t nz = (int8_t)((normalInt >> 16) & 0xFF);
|
int8_t nz = (int8_t)((normalInt >> 16) & 0xFF);
|
||||||
|
|
||||||
::glNormal3f(nx / 127.0f, ny / 127.0f, nz / 127.0f);
|
unsigned int tex2Int = idata[i * 8 + 7];
|
||||||
|
|
||||||
|
if (nx != 0 || ny != 0 || nz != 0) {
|
||||||
|
::glNormal3f(nx / 127.0f, ny / 127.0f, nz / 127.0f);
|
||||||
|
}
|
||||||
|
|
||||||
// Only override current GL color when the vertex actually carries one.
|
// Only override current GL color when the vertex actually carries one.
|
||||||
// colorInt == 0 is the Tesselator sentinel for "no colour set"
|
// colorInt == 0 is the Tesselator sentinel for "no colour set"
|
||||||
// (alpha=0 with all channels zero). Skipping glColor4ub here lets
|
|
||||||
// sky/fog colour set before glCallList() pass through unchanged.
|
|
||||||
if (colorInt != 0) {
|
if (colorInt != 0) {
|
||||||
::glColor4ub(cr, cg, cb, ca);
|
::glColor4ub(cr, cg, cb, ca);
|
||||||
}
|
}
|
||||||
|
|
||||||
::glTexCoord2f(fdata[3], fdata[4]);
|
::glTexCoord2f(fdata[3], fdata[4]);
|
||||||
|
|
||||||
|
// Unit 1 (lightmap) UVs - 0xfe00fe00 is sentinel for "no Unit 1 UVs"
|
||||||
|
if (tex2Int != 0xfe00fe00) {
|
||||||
|
float u2 = (float)(short)(tex2Int & 0xFFFF) / 256.0f;
|
||||||
|
float v2 = (float)(short)((tex2Int >> 16) & 0xFFFF) / 256.0f;
|
||||||
|
::glMultiTexCoord2f(GL_TEXTURE1, u2, v2);
|
||||||
|
}
|
||||||
|
|
||||||
::glVertex3f(fdata[0], fdata[1], fdata[2]);
|
::glVertex3f(fdata[0], fdata[1], fdata[2]);
|
||||||
}
|
}
|
||||||
::glEnd();
|
::glEnd();
|
||||||
}
|
}
|
||||||
|
::glFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -374,22 +415,34 @@ void C4JRender::CBuffLockStaticCreations() {}
|
||||||
|
|
||||||
int C4JRender::CBuffCreate(int count)
|
int C4JRender::CBuffCreate(int count)
|
||||||
{
|
{
|
||||||
return (int)::glGenLists(count);
|
int id = (int)::glGenLists(count);
|
||||||
|
::glFlush();
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4JRender::CBuffDelete(int first, int count)
|
void C4JRender::CBuffDelete(int first, int count)
|
||||||
{
|
{
|
||||||
if (first > 0 && count > 0) ::glDeleteLists(first, count);
|
if (first > 0 && count > 0) {
|
||||||
|
::glDeleteLists(first, count);
|
||||||
|
::glFlush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4JRender::CBuffStart(int index, bool /*full*/)
|
void C4JRender::CBuffStart(int index, bool /*full*/)
|
||||||
{
|
{
|
||||||
if (index > 0) ::glNewList(index, GL_COMPILE);
|
if (index > 0) {
|
||||||
|
::glNewList(index, GL_COMPILE);
|
||||||
|
::glFlush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4JRender::CBuffClear(int index)
|
void C4JRender::CBuffClear(int index)
|
||||||
{
|
{
|
||||||
if (index > 0) { ::glNewList(index, GL_COMPILE); ::glEndList(); }
|
if (index > 0) {
|
||||||
|
::glNewList(index, GL_COMPILE);
|
||||||
|
::glEndList();
|
||||||
|
::glFlush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int C4JRender::CBuffSize(int /*index*/) { return 0; }
|
int C4JRender::CBuffSize(int /*index*/) { return 0; }
|
||||||
|
|
@ -397,6 +450,7 @@ int C4JRender::CBuffSize(int /*index*/) { return 0; }
|
||||||
void C4JRender::CBuffEnd()
|
void C4JRender::CBuffEnd()
|
||||||
{
|
{
|
||||||
::glEndList();
|
::glEndList();
|
||||||
|
::glFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool C4JRender::CBuffCall(int index, bool /*full*/)
|
bool C4JRender::CBuffCall(int index, bool /*full*/)
|
||||||
|
|
@ -435,7 +489,21 @@ void C4JRender::TextureBind(int idx)
|
||||||
|
|
||||||
void C4JRender::TextureBindVertex(int idx)
|
void C4JRender::TextureBindVertex(int idx)
|
||||||
{
|
{
|
||||||
(void)idx;
|
// Unit 1 used for lightmapping in fixed-function or standard shaders
|
||||||
|
::glActiveTexture(GL_TEXTURE1);
|
||||||
|
if (idx < 0) {
|
||||||
|
::glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
::glDisable(GL_TEXTURE_2D);
|
||||||
|
} else {
|
||||||
|
::glEnable(GL_TEXTURE_2D);
|
||||||
|
::glBindTexture(GL_TEXTURE_2D, (GLuint)idx);
|
||||||
|
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||||
|
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||||
|
}
|
||||||
|
::glActiveTexture(GL_TEXTURE0);
|
||||||
|
::glFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4JRender::TextureSetTextureLevels(int levels)
|
void C4JRender::TextureSetTextureLevels(int levels)
|
||||||
|
|
@ -457,6 +525,8 @@ void C4JRender::TextureData(int width, int height, void *data, int level,
|
||||||
width, height, 0,
|
width, height, 0,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
|
||||||
|
::glFlush();
|
||||||
|
|
||||||
if (level == 0) {
|
if (level == 0) {
|
||||||
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
@ -470,6 +540,7 @@ void C4JRender::TextureDataUpdate(int xoffset, int yoffset,
|
||||||
{
|
{
|
||||||
::glTexSubImage2D(GL_TEXTURE_2D, level, xoffset, yoffset,
|
::glTexSubImage2D(GL_TEXTURE_2D, level, xoffset, yoffset,
|
||||||
width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
::glFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4JRender::TextureSetParam(int param, int value)
|
void C4JRender::TextureSetParam(int param, int value)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue