mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-12 00:56:40 -04:00
Merge pull request #1090 from UnknownShadow200/GfxRewrite
Graphics rendering backend related changes
This commit is contained in:
commit
8a20397b6e
@ -61,8 +61,8 @@ build_win64() {
|
|||||||
|
|
||||||
# ----------------------------- compile linux
|
# ----------------------------- compile linux
|
||||||
# I installed gcc and gcc-multilib packages
|
# I installed gcc and gcc-multilib packages
|
||||||
NIX32_FLAGS="-no-pie -fno-pie -m32 -fvisibility=hidden -rdynamic -DCC_BUILD_ICON"
|
NIX32_FLAGS="-no-pie -fno-pie -m32 -fvisibility=hidden -fcf-protection=none -rdynamic -DCC_BUILD_ICON"
|
||||||
NIX64_FLAGS="-no-pie -fno-pie -m64 -fvisibility=hidden -rdynamic -DCC_BUILD_ICON"
|
NIX64_FLAGS="-no-pie -fno-pie -m64 -fvisibility=hidden -fcf-protection=none -rdynamic -DCC_BUILD_ICON"
|
||||||
|
|
||||||
build_nix32() {
|
build_nix32() {
|
||||||
echo "Building linux32.."
|
echo "Building linux32.."
|
||||||
|
@ -34,7 +34,7 @@ void AxisLinesRenderer_Render(void) {
|
|||||||
if (!AxisLinesRenderer_Enabled) return;
|
if (!AxisLinesRenderer_Enabled) return;
|
||||||
/* Don't do it in a ContextRecreated handler, because we only want VB recreated if ShowAxisLines in on. */
|
/* Don't do it in a ContextRecreated handler, because we only want VB recreated if ShowAxisLines in on. */
|
||||||
if (!axisLines_vb) {
|
if (!axisLines_vb) {
|
||||||
Gfx_RecreateDynamicVb(&axisLines_vb, VERTEX_FORMAT_COLOURED, AXISLINES_NUM_VERTICES);
|
axisLines_vb = Gfx_CreateDynamicVb(VERTEX_FORMAT_COLOURED, AXISLINES_NUM_VERTICES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Camera.Active->isThirdPerson) {
|
if (Camera.Active->isThirdPerson) {
|
||||||
|
194
src/Entity.c
194
src/Entity.c
@ -9,8 +9,6 @@
|
|||||||
#include "Funcs.h"
|
#include "Funcs.h"
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "Lighting.h"
|
#include "Lighting.h"
|
||||||
#include "Drawer2D.h"
|
|
||||||
#include "Particle.h"
|
|
||||||
#include "Http.h"
|
#include "Http.h"
|
||||||
#include "Chat.h"
|
#include "Chat.h"
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
@ -22,6 +20,7 @@
|
|||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "Errors.h"
|
#include "Errors.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
#include "EntityRenderers.h"
|
||||||
|
|
||||||
const char* const NameMode_Names[NAME_MODE_COUNT] = { "None", "Hovered", "All", "AllHovered", "AllUnscaled" };
|
const char* const NameMode_Names[NAME_MODE_COUNT] = { "None", "Hovered", "All", "AllHovered", "AllUnscaled" };
|
||||||
const char* const ShadowMode_Names[SHADOW_MODE_COUNT] = { "None", "SnapToBlock", "Circle", "CircleAll" };
|
const char* const ShadowMode_Names[SHADOW_MODE_COUNT] = { "None", "SnapToBlock", "Circle", "CircleAll" };
|
||||||
@ -47,6 +46,11 @@ void Entity_Init(struct Entity* e) {
|
|||||||
Entity_SetModel(e, &model);
|
Entity_SetModel(e, &model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Entity_SetName(struct Entity* e, const cc_string* name) {
|
||||||
|
EntityNames_Delete(e);
|
||||||
|
String_CopyToRawArray(e->NameRaw, name);
|
||||||
|
}
|
||||||
|
|
||||||
Vec3 Entity_GetEyePosition(struct Entity* e) {
|
Vec3 Entity_GetEyePosition(struct Entity* e) {
|
||||||
Vec3 pos = e->Position; pos.Y += Entity_GetEyeHeight(e); return pos;
|
Vec3 pos = e->Position; pos.Y += Entity_GetEyeHeight(e); return pos;
|
||||||
}
|
}
|
||||||
@ -191,103 +195,6 @@ cc_bool Entity_TouchesAnyWater(struct Entity* e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
|
||||||
*-----------------------------------------------------Entity nametag------------------------------------------------------*
|
|
||||||
*#########################################################################################################################*/
|
|
||||||
#define NAME_IS_EMPTY -30000
|
|
||||||
#define NAME_OFFSET 3 /* offset of back layer of name above an entity */
|
|
||||||
|
|
||||||
static void MakeNameTexture(struct Entity* e) {
|
|
||||||
cc_string colorlessName; char colorlessBuffer[STRING_SIZE];
|
|
||||||
BitmapCol shadowColor = BitmapCol_Make(80, 80, 80, 255);
|
|
||||||
BitmapCol origWhiteColor;
|
|
||||||
|
|
||||||
struct DrawTextArgs args;
|
|
||||||
struct FontDesc font;
|
|
||||||
struct Context2D ctx;
|
|
||||||
int width, height;
|
|
||||||
cc_string name;
|
|
||||||
|
|
||||||
/* Names are always drawn using default.png font */
|
|
||||||
Font_MakeBitmapped(&font, 24, FONT_FLAGS_NONE);
|
|
||||||
/* Don't want DPI scaling or padding */
|
|
||||||
font.size = 24; font.height = 24;
|
|
||||||
|
|
||||||
name = String_FromRawArray(e->NameRaw);
|
|
||||||
DrawTextArgs_Make(&args, &name, &font, false);
|
|
||||||
width = Drawer2D_TextWidth(&args);
|
|
||||||
|
|
||||||
if (!width) {
|
|
||||||
e->NameTex.ID = 0;
|
|
||||||
e->NameTex.X = NAME_IS_EMPTY;
|
|
||||||
} else {
|
|
||||||
String_InitArray(colorlessName, colorlessBuffer);
|
|
||||||
width += NAME_OFFSET;
|
|
||||||
height = Drawer2D_TextHeight(&args) + NAME_OFFSET;
|
|
||||||
|
|
||||||
Context2D_Alloc(&ctx, width, height);
|
|
||||||
{
|
|
||||||
origWhiteColor = Drawer2D.Colors['f'];
|
|
||||||
|
|
||||||
Drawer2D.Colors['f'] = shadowColor;
|
|
||||||
Drawer2D_WithoutColors(&colorlessName, &name);
|
|
||||||
args.text = colorlessName;
|
|
||||||
Context2D_DrawText(&ctx, &args, NAME_OFFSET, NAME_OFFSET);
|
|
||||||
|
|
||||||
Drawer2D.Colors['f'] = origWhiteColor;
|
|
||||||
args.text = name;
|
|
||||||
Context2D_DrawText(&ctx, &args, 0, 0);
|
|
||||||
}
|
|
||||||
Context2D_MakeTexture(&e->NameTex, &ctx);
|
|
||||||
Context2D_Free(&ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DrawName(struct Entity* e) {
|
|
||||||
struct VertexTextured vertices[4];
|
|
||||||
struct Model* model;
|
|
||||||
struct Matrix mat;
|
|
||||||
Vec3 pos;
|
|
||||||
float scale;
|
|
||||||
Vec2 size;
|
|
||||||
|
|
||||||
if (e->NameTex.X == NAME_IS_EMPTY) return;
|
|
||||||
if (!e->NameTex.ID) MakeNameTexture(e);
|
|
||||||
Gfx_BindTexture(e->NameTex.ID);
|
|
||||||
|
|
||||||
model = e->Model;
|
|
||||||
Vec3_TransformY(&pos, model->GetNameY(e), &e->Transform);
|
|
||||||
|
|
||||||
scale = model->nameScale * e->ModelScale.Y;
|
|
||||||
scale = scale > 1.0f ? (1.0f/70.0f) : (scale/70.0f);
|
|
||||||
size.X = e->NameTex.Width * scale; size.Y = e->NameTex.Height * scale;
|
|
||||||
|
|
||||||
if (Entities.NamesMode == NAME_MODE_ALL_UNSCALED && LocalPlayer_Instance.Hacks.CanSeeAllNames) {
|
|
||||||
Matrix_Mul(&mat, &Gfx.View, &Gfx.Projection); /* TODO: This mul is slow, avoid it */
|
|
||||||
/* Get W component of transformed position */
|
|
||||||
scale = pos.X * mat.row1.W + pos.Y * mat.row2.W + pos.Z * mat.row3.W + mat.row4.W;
|
|
||||||
size.X *= scale * 0.2f; size.Y *= scale * 0.2f;
|
|
||||||
}
|
|
||||||
|
|
||||||
Particle_DoRender(&size, &pos, &e->NameTex.uv, PACKEDCOL_WHITE, vertices);
|
|
||||||
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
|
||||||
Gfx_UpdateDynamicVb_IndexedTris(Gfx_texVb, vertices, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Deletes the texture containing the entity's nametag */
|
|
||||||
CC_NOINLINE static void DeleteNameTex(struct Entity* e) {
|
|
||||||
Gfx_DeleteTexture(&e->NameTex.ID);
|
|
||||||
e->NameTex.X = 0; /* X is used as an 'empty name' flag */
|
|
||||||
}
|
|
||||||
|
|
||||||
void Entity_SetName(struct Entity* e, const cc_string* name) {
|
|
||||||
DeleteNameTex(e);
|
|
||||||
String_CopyToRawArray(e->NameRaw, name);
|
|
||||||
/* name texture redraw deferred until necessary */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*------------------------------------------------------Entity skins-------------------------------------------------------*
|
*------------------------------------------------------Entity skins-------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
@ -529,7 +436,6 @@ void Entity_LerpAngles(struct Entity* e, float t) {
|
|||||||
*--------------------------------------------------------Entities---------------------------------------------------------*
|
*--------------------------------------------------------Entities---------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
struct _EntitiesData Entities;
|
struct _EntitiesData Entities;
|
||||||
static EntityID entities_closestId;
|
|
||||||
|
|
||||||
void Entities_Tick(struct ScheduledTask* task) {
|
void Entities_Tick(struct ScheduledTask* task) {
|
||||||
int i;
|
int i;
|
||||||
@ -550,82 +456,16 @@ void Entities_RenderModels(double delta, float t) {
|
|||||||
Gfx_SetAlphaTest(false);
|
Gfx_SetAlphaTest(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Entities_RenderNames(void) {
|
|
||||||
struct LocalPlayer* p = &LocalPlayer_Instance;
|
|
||||||
cc_bool hadFog;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (Entities.NamesMode == NAME_MODE_NONE) return;
|
|
||||||
entities_closestId = Entities_GetClosest(&p->Base);
|
|
||||||
if (!p->Hacks.CanSeeAllNames || Entities.NamesMode != NAME_MODE_ALL) return;
|
|
||||||
|
|
||||||
Gfx_SetAlphaTest(true);
|
|
||||||
hadFog = Gfx_GetFog();
|
|
||||||
if (hadFog) Gfx_SetFog(false);
|
|
||||||
|
|
||||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
|
||||||
if (!Entities.List[i]) continue;
|
|
||||||
if (i != entities_closestId || i == ENTITIES_SELF_ID) {
|
|
||||||
Entities.List[i]->VTABLE->RenderName(Entities.List[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Gfx_SetAlphaTest(false);
|
|
||||||
if (hadFog) Gfx_SetFog(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Entities_RenderHoveredNames(void) {
|
|
||||||
struct LocalPlayer* p = &LocalPlayer_Instance;
|
|
||||||
cc_bool allNames, hadFog;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (Entities.NamesMode == NAME_MODE_NONE) return;
|
|
||||||
allNames = !(Entities.NamesMode == NAME_MODE_HOVERED || Entities.NamesMode == NAME_MODE_ALL)
|
|
||||||
&& p->Hacks.CanSeeAllNames;
|
|
||||||
|
|
||||||
Gfx_SetAlphaTest(true);
|
|
||||||
Gfx_SetDepthTest(false);
|
|
||||||
hadFog = Gfx_GetFog();
|
|
||||||
if (hadFog) Gfx_SetFog(false);
|
|
||||||
|
|
||||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
|
||||||
if (!Entities.List[i]) continue;
|
|
||||||
if ((i == entities_closestId || allNames) && i != ENTITIES_SELF_ID) {
|
|
||||||
Entities.List[i]->VTABLE->RenderName(Entities.List[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Gfx_SetAlphaTest(false);
|
|
||||||
Gfx_SetDepthTest(true);
|
|
||||||
if (hadFog) Gfx_SetFog(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Entity_ContextLost(struct Entity* e) { DeleteNameTex(e); }
|
|
||||||
|
|
||||||
static void Entities_ContextLost(void* obj) {
|
static void Entities_ContextLost(void* obj) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
|
||||||
if (!Entities.List[i]) continue;
|
|
||||||
Entity_ContextLost(Entities.List[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Gfx.ManagedTextures) return;
|
if (Gfx.ManagedTextures) return;
|
||||||
|
|
||||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||||
if (!Entities.List[i]) continue;
|
if (!Entities.List[i]) continue;
|
||||||
DeleteSkin(Entities.List[i]);
|
DeleteSkin(Entities.List[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* No OnContextCreated, names/skin textures remade when needed */
|
/* No OnContextCreated, skin textures remade when needed */
|
||||||
|
|
||||||
static void Entities_ChatFontChanged(void* obj) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
|
||||||
if (!Entities.List[i]) continue;
|
|
||||||
DeleteNameTex(Entities.List[i]);
|
|
||||||
/* name redraw is deferred until rendered */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Entities_Remove(EntityID id) {
|
void Entities_Remove(EntityID id) {
|
||||||
struct Entity* e = Entities.List[id];
|
struct Entity* e = Entities.List[id];
|
||||||
@ -747,7 +587,7 @@ struct IGameComponent TabList_Component = {
|
|||||||
|
|
||||||
static void Player_Despawn(struct Entity* e) {
|
static void Player_Despawn(struct Entity* e) {
|
||||||
DeleteSkin(e);
|
DeleteSkin(e);
|
||||||
Entity_ContextLost(e);
|
EntityNames_Delete(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -868,9 +708,8 @@ static void LocalPlayer_RenderModel(struct Entity* e, double deltaTime, float t)
|
|||||||
Model_Render(e->Model, e);
|
Model_Render(e->Model, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LocalPlayer_RenderName(struct Entity* e) {
|
static cc_bool LocalPlayer_ShouldRenderName(struct Entity* e) {
|
||||||
if (!Camera.Active->isThirdPerson) return;
|
return Camera.Active->isThirdPerson;
|
||||||
DrawName(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LocalPlayer_CheckJumpVelocity(void* obj) {
|
static void LocalPlayer_CheckJumpVelocity(void* obj) {
|
||||||
@ -894,7 +733,7 @@ static void LocalPlayer_GetMovement(float* xMoving, float* zMoving) {
|
|||||||
|
|
||||||
static const struct EntityVTABLE localPlayer_VTABLE = {
|
static const struct EntityVTABLE localPlayer_VTABLE = {
|
||||||
LocalPlayer_Tick, Player_Despawn, LocalPlayer_SetLocation, Entity_GetColor,
|
LocalPlayer_Tick, Player_Despawn, LocalPlayer_SetLocation, Entity_GetColor,
|
||||||
LocalPlayer_RenderModel, LocalPlayer_RenderName
|
LocalPlayer_RenderModel, LocalPlayer_ShouldRenderName
|
||||||
};
|
};
|
||||||
static void LocalPlayer_Init(void) {
|
static void LocalPlayer_Init(void) {
|
||||||
struct LocalPlayer* p = &LocalPlayer_Instance;
|
struct LocalPlayer* p = &LocalPlayer_Instance;
|
||||||
@ -1150,19 +989,19 @@ static void NetPlayer_RenderModel(struct Entity* e, double deltaTime, float t) {
|
|||||||
if (e->ShouldRender) Model_Render(e->Model, e);
|
if (e->ShouldRender) Model_Render(e->Model, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NetPlayer_RenderName(struct Entity* e) {
|
static cc_bool NetPlayer_ShouldRenderName(struct Entity* e) {
|
||||||
float distance;
|
float distance;
|
||||||
int threshold;
|
int threshold;
|
||||||
if (!e->ShouldRender) return;
|
if (!e->ShouldRender) return false;
|
||||||
|
|
||||||
distance = Model_RenderDistance(e);
|
distance = Model_RenderDistance(e);
|
||||||
threshold = Entities.NamesMode == NAME_MODE_ALL_UNSCALED ? 8192 * 8192 : 32 * 32;
|
threshold = Entities.NamesMode == NAME_MODE_ALL_UNSCALED ? 8192 * 8192 : 32 * 32;
|
||||||
if (distance <= (float)threshold) DrawName(e);
|
return distance <= (float)threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct EntityVTABLE netPlayer_VTABLE = {
|
static const struct EntityVTABLE netPlayer_VTABLE = {
|
||||||
NetPlayer_Tick, Player_Despawn, NetPlayer_SetLocation, Entity_GetColor,
|
NetPlayer_Tick, Player_Despawn, NetPlayer_SetLocation, Entity_GetColor,
|
||||||
NetPlayer_RenderModel, NetPlayer_RenderName
|
NetPlayer_RenderModel, NetPlayer_ShouldRenderName
|
||||||
};
|
};
|
||||||
void NetPlayer_Init(struct NetPlayer* p) {
|
void NetPlayer_Init(struct NetPlayer* p) {
|
||||||
Mem_Set(p, 0, sizeof(struct NetPlayer));
|
Mem_Set(p, 0, sizeof(struct NetPlayer));
|
||||||
@ -1176,7 +1015,6 @@ void NetPlayer_Init(struct NetPlayer* p) {
|
|||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static void Entities_Init(void) {
|
static void Entities_Init(void) {
|
||||||
Event_Register_(&GfxEvents.ContextLost, NULL, Entities_ContextLost);
|
Event_Register_(&GfxEvents.ContextLost, NULL, Entities_ContextLost);
|
||||||
Event_Register_(&ChatEvents.FontChanged, NULL, Entities_ChatFontChanged);
|
|
||||||
Event_Register_(&InputEvents.Down, NULL, LocalPlayer_InputDown);
|
Event_Register_(&InputEvents.Down, NULL, LocalPlayer_InputDown);
|
||||||
Event_Register_(&InputEvents.Up, NULL, LocalPlayer_InputUp);
|
Event_Register_(&InputEvents.Up, NULL, LocalPlayer_InputUp);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ struct EntityVTABLE {
|
|||||||
void (*SetLocation)(struct Entity* e, struct LocationUpdate* update);
|
void (*SetLocation)(struct Entity* e, struct LocationUpdate* update);
|
||||||
PackedCol (*GetCol)(struct Entity* e);
|
PackedCol (*GetCol)(struct Entity* e);
|
||||||
void (*RenderModel)(struct Entity* e, double deltaTime, float t);
|
void (*RenderModel)(struct Entity* e, double deltaTime, float t);
|
||||||
void (*RenderName)(struct Entity* e);
|
cc_bool (*ShouldRenderName)(struct Entity* e);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Skin is still being downloaded asynchronously */
|
/* Skin is still being downloaded asynchronously */
|
||||||
@ -155,10 +155,6 @@ CC_VAR extern struct _EntitiesData {
|
|||||||
void Entities_Tick(struct ScheduledTask* task);
|
void Entities_Tick(struct ScheduledTask* task);
|
||||||
/* Renders all entities */
|
/* Renders all entities */
|
||||||
void Entities_RenderModels(double delta, float t);
|
void Entities_RenderModels(double delta, float t);
|
||||||
/* Renders the name tags of entities, depending on Entities.NamesMode */
|
|
||||||
void Entities_RenderNames(void);
|
|
||||||
/* Renders hovered entity name tags (these appears through blocks) */
|
|
||||||
void Entities_RenderHoveredNames(void);
|
|
||||||
/* Removes the given entity, raising EntityEvents.Removed event */
|
/* Removes the given entity, raising EntityEvents.Removed event */
|
||||||
void Entities_Remove(EntityID id);
|
void Entities_Remove(EntityID id);
|
||||||
/* Gets the ID of the closest entity to the given entity */
|
/* Gets the ID of the closest entity to the given entity */
|
||||||
|
@ -9,15 +9,29 @@
|
|||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
#include "Particle.h"
|
||||||
|
#include "Drawer2D.h"
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*------------------------------------------------------Entity Shadow------------------------------------------------------*
|
*------------------------------------------------------Entity Shadow------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static cc_bool shadows_boundTex;
|
static cc_bool shadows_boundTex;
|
||||||
|
static GfxResourceID shadows_VB;
|
||||||
static GfxResourceID shadows_tex;
|
static GfxResourceID shadows_tex;
|
||||||
static float shadow_radius, shadow_uvScale;
|
static float shadow_radius, shadow_uvScale;
|
||||||
struct ShadowData { float Y; BlockID Block; cc_uint8 A; };
|
struct ShadowData { float Y; BlockID Block; cc_uint8 A; };
|
||||||
|
|
||||||
|
/* Circle shadows extend at most 4 blocks vertically */
|
||||||
|
#define SHADOW_MAX_RANGE 4
|
||||||
|
/* Circle shadows on blocks underneath the top block can be chopped up into at most 4 pieces */
|
||||||
|
#define SHADOW_MAX_PER_SUB_BLOCK (4 * 4)
|
||||||
|
/* Circle shadows use at most:
|
||||||
|
- 4 vertices for top most block
|
||||||
|
- MAX_PER_SUB_BLOCK for everyblock underneath the top block */
|
||||||
|
#define SHADOW_MAX_PER_COLUMN (4 + SHADOW_MAX_PER_SUB_BLOCK * (SHADOW_MAX_RANGE - 1))
|
||||||
|
/* Circle shadows may be split across (x,z), (x,z+1), (x+1,z), (x+1,z+1) */
|
||||||
|
#define SHADOW_MAX_VERTS 4 * SHADOW_MAX_PER_COLUMN
|
||||||
|
|
||||||
static cc_bool lequal(float a, float b) { return a < b || Math_AbsF(a - b) < 0.001f; }
|
static cc_bool lequal(float a, float b) { return a < b || Math_AbsF(a - b) < 0.001f; }
|
||||||
static void EntityShadow_DrawCoords(struct VertexTextured** vertices, struct Entity* e, struct ShadowData* data, float x1, float z1, float x2, float z2) {
|
static void EntityShadow_DrawCoords(struct VertexTextured** vertices, struct Entity* e, struct ShadowData* data, float x1, float z1, float x2, float z2) {
|
||||||
PackedCol col;
|
PackedCol col;
|
||||||
@ -72,7 +86,8 @@ static void EntityShadow_DrawCircle(struct VertexTextured** vertices, struct Ent
|
|||||||
min = Blocks.MinBB[data[0].Block]; max = Blocks.MaxBB[data[0].Block];
|
min = Blocks.MinBB[data[0].Block]; max = Blocks.MaxBB[data[0].Block];
|
||||||
|
|
||||||
EntityShadow_DrawCoords(vertices, e, &data[0], x + min.X, z + min.Z, x + max.X, z + max.Z);
|
EntityShadow_DrawCoords(vertices, e, &data[0], x + min.X, z + min.Z, x + max.X, z + max.Z);
|
||||||
for (i = 1; i < 4; i++) {
|
for (i = 1; i < 4; i++)
|
||||||
|
{
|
||||||
if (data[i].Block == BLOCK_AIR) return;
|
if (data[i].Block == BLOCK_AIR) return;
|
||||||
nMin = Blocks.MinBB[data[i].Block]; nMax = Blocks.MaxBB[data[i].Block];
|
nMin = Blocks.MinBB[data[i].Block]; nMax = Blocks.MaxBB[data[i].Block];
|
||||||
|
|
||||||
@ -112,7 +127,8 @@ static cc_bool EntityShadow_GetBlocks(struct Entity* e, int x, int y, int z, str
|
|||||||
posY = e->Position.Y;
|
posY = e->Position.Y;
|
||||||
outside = !World_ContainsXZ(x, z);
|
outside = !World_ContainsXZ(x, z);
|
||||||
|
|
||||||
for (i = 0; y >= 0 && i < 4; y--) {
|
for (i = 0; y >= 0 && i < 4; y--)
|
||||||
|
{
|
||||||
if (!outside) {
|
if (!outside) {
|
||||||
block = World_GetBlock(x, y, z);
|
block = World_GetBlock(x, y, z);
|
||||||
} else if (y == Env.EdgeHeight - 1) {
|
} else if (y == Env.EdgeHeight - 1) {
|
||||||
@ -146,10 +162,9 @@ static cc_bool EntityShadow_GetBlocks(struct Entity* e, int x, int y, int z, str
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void EntityShadow_Draw(struct Entity* e) {
|
static void EntityShadow_Draw(struct Entity* e) {
|
||||||
struct VertexTextured vertices[128];
|
struct VertexTextured vertices[128]; /* TODO this is less than maxVertes */
|
||||||
struct VertexTextured* ptr;
|
struct VertexTextured* ptr;
|
||||||
struct ShadowData data[4];
|
struct ShadowData data[4];
|
||||||
GfxResourceID vb;
|
|
||||||
Vec3 pos;
|
Vec3 pos;
|
||||||
float radius;
|
float radius;
|
||||||
int y, count;
|
int y, count;
|
||||||
@ -163,16 +178,13 @@ static void EntityShadow_Draw(struct Entity* e) {
|
|||||||
shadow_radius = radius / 16.0f;
|
shadow_radius = radius / 16.0f;
|
||||||
shadow_uvScale = 16.0f / (radius * 2.0f);
|
shadow_uvScale = 16.0f / (radius * 2.0f);
|
||||||
|
|
||||||
/* TODO: Should shadow component use its own VB? */
|
|
||||||
ptr = vertices;
|
ptr = vertices;
|
||||||
if (Entities.ShadowsMode == SHADOW_MODE_SNAP_TO_BLOCK) {
|
if (Entities.ShadowsMode == SHADOW_MODE_SNAP_TO_BLOCK) {
|
||||||
vb = Gfx_texVb;
|
|
||||||
x1 = Math_Floor(pos.X); z1 = Math_Floor(pos.Z);
|
x1 = Math_Floor(pos.X); z1 = Math_Floor(pos.Z);
|
||||||
if (!EntityShadow_GetBlocks(e, x1, y, z1, data)) return;
|
if (!EntityShadow_GetBlocks(e, x1, y, z1, data)) return;
|
||||||
|
|
||||||
EntityShadow_DrawSquareShadow(&ptr, data[0].Y, x1, z1);
|
EntityShadow_DrawSquareShadow(&ptr, data[0].Y, x1, z1);
|
||||||
} else {
|
} else {
|
||||||
vb = Models.Vb;
|
|
||||||
x1 = Math_Floor(pos.X - shadow_radius); z1 = Math_Floor(pos.Z - shadow_radius);
|
x1 = Math_Floor(pos.X - shadow_radius); z1 = Math_Floor(pos.Z - shadow_radius);
|
||||||
x2 = Math_Floor(pos.X + shadow_radius); z2 = Math_Floor(pos.Z + shadow_radius);
|
x2 = Math_Floor(pos.X + shadow_radius); z2 = Math_Floor(pos.Z + shadow_radius);
|
||||||
|
|
||||||
@ -198,7 +210,8 @@ static void EntityShadow_Draw(struct Entity* e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
count = (int)(ptr - vertices);
|
count = (int)(ptr - vertices);
|
||||||
Gfx_UpdateDynamicVb_IndexedTris(vb, vertices, count);
|
Gfx_SetDynamicVbData(shadows_VB, vertices, count);
|
||||||
|
Gfx_DrawVb_IndexedTris(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -225,7 +238,7 @@ static void EntityShadows_MakeTexture(void) {
|
|||||||
row[x] = dist < sh_half * sh_half ? color : 0;
|
row[x] = dist < sh_half * sh_half ? color : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Gfx_RecreateTexture(&shadows_tex, &bmp, 0, false);
|
shadows_tex = Gfx_CreateTexture(&bmp, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityShadows_Render(void) {
|
void EntityShadows_Render(void) {
|
||||||
@ -233,7 +246,10 @@ void EntityShadows_Render(void) {
|
|||||||
if (Entities.ShadowsMode == SHADOW_MODE_NONE) return;
|
if (Entities.ShadowsMode == SHADOW_MODE_NONE) return;
|
||||||
|
|
||||||
shadows_boundTex = false;
|
shadows_boundTex = false;
|
||||||
if (!shadows_tex) EntityShadows_MakeTexture();
|
if (!shadows_tex)
|
||||||
|
EntityShadows_MakeTexture();
|
||||||
|
if (!shadows_VB)
|
||||||
|
shadows_VB = Gfx_CreateDynamicVb(VERTEX_FORMAT_TEXTURED, SHADOW_MAX_VERTS);
|
||||||
|
|
||||||
Gfx_SetAlphaArgBlend(true);
|
Gfx_SetAlphaArgBlend(true);
|
||||||
Gfx_SetDepthWrite(false);
|
Gfx_SetDepthWrite(false);
|
||||||
@ -256,19 +272,193 @@ void EntityShadows_Render(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Entity nametag------------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
static GfxResourceID names_VB;
|
||||||
|
#define NAME_IS_EMPTY -30000
|
||||||
|
#define NAME_OFFSET 3 /* offset of back layer of name above an entity */
|
||||||
|
|
||||||
|
static void MakeNameTexture(struct Entity* e) {
|
||||||
|
cc_string colorlessName; char colorlessBuffer[STRING_SIZE];
|
||||||
|
BitmapCol shadowColor = BitmapCol_Make(80, 80, 80, 255);
|
||||||
|
BitmapCol origWhiteColor;
|
||||||
|
|
||||||
|
struct DrawTextArgs args;
|
||||||
|
struct FontDesc font;
|
||||||
|
struct Context2D ctx;
|
||||||
|
int width, height;
|
||||||
|
cc_string name;
|
||||||
|
|
||||||
|
/* Names are always drawn using default.png font */
|
||||||
|
Font_MakeBitmapped(&font, 24, FONT_FLAGS_NONE);
|
||||||
|
/* Don't want DPI scaling or padding */
|
||||||
|
font.size = 24; font.height = 24;
|
||||||
|
|
||||||
|
name = String_FromRawArray(e->NameRaw);
|
||||||
|
DrawTextArgs_Make(&args, &name, &font, false);
|
||||||
|
width = Drawer2D_TextWidth(&args);
|
||||||
|
|
||||||
|
if (!width) {
|
||||||
|
e->NameTex.ID = 0;
|
||||||
|
e->NameTex.X = NAME_IS_EMPTY;
|
||||||
|
} else {
|
||||||
|
String_InitArray(colorlessName, colorlessBuffer);
|
||||||
|
width += NAME_OFFSET;
|
||||||
|
height = Drawer2D_TextHeight(&args) + NAME_OFFSET;
|
||||||
|
|
||||||
|
Context2D_Alloc(&ctx, width, height);
|
||||||
|
{
|
||||||
|
origWhiteColor = Drawer2D.Colors['f'];
|
||||||
|
|
||||||
|
Drawer2D.Colors['f'] = shadowColor;
|
||||||
|
Drawer2D_WithoutColors(&colorlessName, &name);
|
||||||
|
args.text = colorlessName;
|
||||||
|
Context2D_DrawText(&ctx, &args, NAME_OFFSET, NAME_OFFSET);
|
||||||
|
|
||||||
|
Drawer2D.Colors['f'] = origWhiteColor;
|
||||||
|
args.text = name;
|
||||||
|
Context2D_DrawText(&ctx, &args, 0, 0);
|
||||||
|
}
|
||||||
|
Context2D_MakeTexture(&e->NameTex, &ctx);
|
||||||
|
Context2D_Free(&ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawName(struct Entity* e) {
|
||||||
|
struct VertexTextured* vertices;
|
||||||
|
struct Model* model;
|
||||||
|
struct Matrix mat;
|
||||||
|
Vec3 pos;
|
||||||
|
float scale;
|
||||||
|
Vec2 size;
|
||||||
|
|
||||||
|
if (!e->VTABLE->ShouldRenderName(e)) return;
|
||||||
|
if (e->NameTex.X == NAME_IS_EMPTY) return;
|
||||||
|
if (!e->NameTex.ID) MakeNameTexture(e);
|
||||||
|
Gfx_BindTexture(e->NameTex.ID);
|
||||||
|
|
||||||
|
if (!names_VB)
|
||||||
|
names_VB = Gfx_CreateDynamicVb(VERTEX_FORMAT_TEXTURED, 4);
|
||||||
|
|
||||||
|
model = e->Model;
|
||||||
|
Vec3_TransformY(&pos, model->GetNameY(e), &e->Transform);
|
||||||
|
|
||||||
|
scale = model->nameScale * e->ModelScale.Y;
|
||||||
|
scale = scale > 1.0f ? (1.0f/70.0f) : (scale/70.0f);
|
||||||
|
size.X = e->NameTex.Width * scale; size.Y = e->NameTex.Height * scale;
|
||||||
|
|
||||||
|
if (Entities.NamesMode == NAME_MODE_ALL_UNSCALED && LocalPlayer_Instance.Hacks.CanSeeAllNames) {
|
||||||
|
Matrix_Mul(&mat, &Gfx.View, &Gfx.Projection); /* TODO: This mul is slow, avoid it */
|
||||||
|
/* Get W component of transformed position */
|
||||||
|
scale = pos.X * mat.row1.W + pos.Y * mat.row2.W + pos.Z * mat.row3.W + mat.row4.W;
|
||||||
|
size.X *= scale * 0.2f; size.Y *= scale * 0.2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
||||||
|
|
||||||
|
vertices = (struct VertexTextured*)Gfx_LockDynamicVb(names_VB, VERTEX_FORMAT_TEXTURED, 4);
|
||||||
|
Particle_DoRender(&size, &pos, &e->NameTex.uv, PACKEDCOL_WHITE, vertices);
|
||||||
|
Gfx_UnlockDynamicVb(names_VB);
|
||||||
|
|
||||||
|
Gfx_DrawVb_IndexedTris(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityNames_Delete(struct Entity* e) {
|
||||||
|
Gfx_DeleteTexture(&e->NameTex.ID);
|
||||||
|
e->NameTex.X = 0; /* X is used as an 'empty name' flag */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Names rendering-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
static EntityID closestEntityId;
|
||||||
|
|
||||||
|
void EntityNames_Render(void) {
|
||||||
|
struct LocalPlayer* p = &LocalPlayer_Instance;
|
||||||
|
cc_bool hadFog;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (Entities.NamesMode == NAME_MODE_NONE) return;
|
||||||
|
closestEntityId = Entities_GetClosest(&p->Base);
|
||||||
|
if (!p->Hacks.CanSeeAllNames || Entities.NamesMode != NAME_MODE_ALL) return;
|
||||||
|
|
||||||
|
Gfx_SetAlphaTest(true);
|
||||||
|
hadFog = Gfx_GetFog();
|
||||||
|
if (hadFog) Gfx_SetFog(false);
|
||||||
|
|
||||||
|
for (i = 0; i < ENTITIES_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (!Entities.List[i]) continue;
|
||||||
|
if (i != closestEntityId || i == ENTITIES_SELF_ID) {
|
||||||
|
DrawName(Entities.List[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx_SetAlphaTest(false);
|
||||||
|
if (hadFog) Gfx_SetFog(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityNames_RenderHovered(void) {
|
||||||
|
struct LocalPlayer* p = &LocalPlayer_Instance;
|
||||||
|
cc_bool allNames, hadFog;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (Entities.NamesMode == NAME_MODE_NONE) return;
|
||||||
|
allNames = !(Entities.NamesMode == NAME_MODE_HOVERED || Entities.NamesMode == NAME_MODE_ALL)
|
||||||
|
&& p->Hacks.CanSeeAllNames;
|
||||||
|
|
||||||
|
Gfx_SetAlphaTest(true);
|
||||||
|
Gfx_SetDepthTest(false);
|
||||||
|
hadFog = Gfx_GetFog();
|
||||||
|
if (hadFog) Gfx_SetFog(false);
|
||||||
|
|
||||||
|
for (i = 0; i < ENTITIES_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (!Entities.List[i]) continue;
|
||||||
|
if ((i == closestEntityId || allNames) && i != ENTITIES_SELF_ID) {
|
||||||
|
DrawName(Entities.List[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx_SetAlphaTest(false);
|
||||||
|
Gfx_SetDepthTest(true);
|
||||||
|
if (hadFog) Gfx_SetFog(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeleteAllNameTextures(void) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ENTITIES_MAX_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (!Entities.List[i]) continue;
|
||||||
|
EntityNames_Delete(Entities.List[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void EntityNames_ChatFontChanged(void* obj) {
|
||||||
|
DeleteAllNameTextures();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*-----------------------------------------------Entity renderers component------------------------------------------------*
|
*-----------------------------------------------Entity renderers component------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static void EntityRenderers_ContextLost(void* obj) {
|
static void EntityRenderers_ContextLost(void* obj) {
|
||||||
Gfx_DeleteTexture(&shadows_tex);
|
Gfx_DeleteTexture(&shadows_tex);
|
||||||
|
Gfx_DeleteDynamicVb(&shadows_VB);
|
||||||
|
|
||||||
|
Gfx_DeleteDynamicVb(&names_VB);
|
||||||
|
DeleteAllNameTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EntityRenderers_Init(void) {
|
static void EntityRenderers_Init(void) {
|
||||||
Event_Register_(&GfxEvents.ContextLost, NULL, EntityRenderers_ContextLost);
|
Event_Register_(&GfxEvents.ContextLost, NULL, EntityRenderers_ContextLost);
|
||||||
|
Event_Register_(&ChatEvents.FontChanged, NULL, EntityNames_ChatFontChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EntityRenderers_Free(void) {
|
static void EntityRenderers_Free(void) {
|
||||||
Gfx_DeleteTexture(&shadows_tex);
|
EntityRenderers_ContextLost(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IGameComponent EntityRenderers_Component = {
|
struct IGameComponent EntityRenderers_Component = {
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
#ifndef CC_ENTITYRENDERERS_H
|
#ifndef CC_ENTITYRENDERERS_H
|
||||||
#define CC_ENTITYRENDERERS_H
|
#define CC_ENTITYRENDERERS_H
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
/* Renders supporting objects for entities (shadows)
|
/* Renders supporting objects for entities (shadows and names)
|
||||||
Copyright 2014-2023 ClassiCube | Licensed under BSD-3
|
Copyright 2014-2023 ClassiCube | Licensed under BSD-3
|
||||||
*/
|
*/
|
||||||
struct IGameComponent;
|
struct IGameComponent;
|
||||||
extern struct IGameComponent EntityRenderers_Component;
|
extern struct IGameComponent EntityRenderers_Component;
|
||||||
|
struct Entity;
|
||||||
|
|
||||||
/* Draws shadows under entities, depending on Entities.ShadowsMode */
|
/* Draws shadows under entities, depending on Entities.ShadowsMode */
|
||||||
void EntityShadows_Render(void);
|
void EntityShadows_Render(void);
|
||||||
|
|
||||||
|
/* Deletes the texture containing the entity's nametag */
|
||||||
|
void EntityNames_Delete(struct Entity* e);
|
||||||
|
/* Renders the name tags of entities, depending on Entities.NamesMode */
|
||||||
|
void EntityNames_Render(void);
|
||||||
|
/* Renders hovered entity name tags (these appears through blocks) */
|
||||||
|
void EntityNames_RenderHovered(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -272,11 +272,42 @@ static GfxResourceID skybox_tex, skybox_vb;
|
|||||||
#define SKYBOX_COUNT (6 * 4)
|
#define SKYBOX_COUNT (6 * 4)
|
||||||
cc_bool EnvRenderer_ShouldRenderSkybox(void) { return skybox_tex && !EnvRenderer_Minimal; }
|
cc_bool EnvRenderer_ShouldRenderSkybox(void) { return skybox_tex && !EnvRenderer_Minimal; }
|
||||||
|
|
||||||
|
static void AllocateSkyboxVB(void) {
|
||||||
|
static const struct VertexTextured vertices[SKYBOX_COUNT] = {
|
||||||
|
/* Front quad */
|
||||||
|
{ -1, -1, -1, 0, 0.25f, 1.00f }, { 1, -1, -1, 0, 0.50f, 1.00f },
|
||||||
|
{ 1, 1, -1, 0, 0.50f, 0.50f }, { -1, 1, -1, 0, 0.25f, 0.50f },
|
||||||
|
/* Left quad */
|
||||||
|
{ -1, -1, 1, 0, 0.00f, 1.00f }, { -1, -1, -1, 0, 0.25f, 1.00f },
|
||||||
|
{ -1, 1, -1, 0, 0.25f, 0.50f }, { -1, 1, 1, 0, 0.00f, 0.50f },
|
||||||
|
/* Back quad */
|
||||||
|
{ 1, -1, 1, 0, 0.75f, 1.00f }, { -1, -1, 1, 0, 1.00f, 1.00f },
|
||||||
|
{ -1, 1, 1, 0, 1.00f, 0.50f }, { 1, 1, 1, 0, 0.75f, 0.50f },
|
||||||
|
/* Right quad */
|
||||||
|
{ 1, -1, -1, 0, 0.50f, 1.00f }, { 1, -1, 1, 0, 0.75f, 1.00f },
|
||||||
|
{ 1, 1, 1, 0, 0.75f, 0.50f }, { 1, 1, -1, 0, 0.50f, 0.50f },
|
||||||
|
/* Top quad */
|
||||||
|
{ 1, 1, -1, 0, 0.50f, 0.50f }, { 1, 1, 1, 0, 0.50f, 0.00f },
|
||||||
|
{ -1, 1, 1, 0, 0.25f, 0.00f }, { -1, 1, -1, 0, 0.25f, 0.50f },
|
||||||
|
/* Bottom quad */
|
||||||
|
{ 1, -1, -1, 0, 0.75f, 0.50f }, { 1, -1, 1, 0, 0.75f, 0.00f },
|
||||||
|
{ -1, -1, 1, 0, 0.50f, 0.00f }, { -1, -1, -1, 0, 0.50f, 0.50f },
|
||||||
|
};
|
||||||
|
struct VertexTextured* data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
data = (struct VertexTextured*)Gfx_RecreateAndLockVb(&skybox_vb,
|
||||||
|
VERTEX_FORMAT_TEXTURED, SKYBOX_COUNT);
|
||||||
|
Mem_Copy(data, vertices, sizeof(vertices));
|
||||||
|
for (i = 0; i < SKYBOX_COUNT; i++) { data[i].Col = Env.SkyboxCol; }
|
||||||
|
Gfx_UnlockVb(skybox_vb);
|
||||||
|
}
|
||||||
|
|
||||||
void EnvRenderer_RenderSkybox(void) {
|
void EnvRenderer_RenderSkybox(void) {
|
||||||
struct Matrix m, rotX, rotY, view;
|
struct Matrix m, rotX, rotY, view;
|
||||||
float rotTime;
|
float rotTime;
|
||||||
Vec3 pos;
|
Vec3 pos;
|
||||||
if (!skybox_vb) return;
|
if (!skybox_vb) AllocateSkyboxVB();
|
||||||
|
|
||||||
Gfx_SetDepthWrite(false);
|
Gfx_SetDepthWrite(false);
|
||||||
Gfx_BindTexture(skybox_tex);
|
Gfx_BindTexture(skybox_tex);
|
||||||
@ -302,42 +333,6 @@ void EnvRenderer_RenderSkybox(void) {
|
|||||||
Gfx_SetDepthWrite(true);
|
Gfx_SetDepthWrite(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateSkybox(void) {
|
|
||||||
static const struct VertexTextured vertices[SKYBOX_COUNT] = {
|
|
||||||
/* Front quad */
|
|
||||||
{ -1, -1, -1, 0, 0.25f, 1.00f }, { 1, -1, -1, 0, 0.50f, 1.00f },
|
|
||||||
{ 1, 1, -1, 0, 0.50f, 0.50f }, { -1, 1, -1, 0, 0.25f, 0.50f },
|
|
||||||
/* Left quad */
|
|
||||||
{ -1, -1, 1, 0, 0.00f, 1.00f }, { -1, -1, -1, 0, 0.25f, 1.00f },
|
|
||||||
{ -1, 1, -1, 0, 0.25f, 0.50f }, { -1, 1, 1, 0, 0.00f, 0.50f },
|
|
||||||
/* Back quad */
|
|
||||||
{ 1, -1, 1, 0, 0.75f, 1.00f }, { -1, -1, 1, 0, 1.00f, 1.00f },
|
|
||||||
{ -1, 1, 1, 0, 1.00f, 0.50f }, { 1, 1, 1, 0, 0.75f, 0.50f },
|
|
||||||
/* Right quad */
|
|
||||||
{ 1, -1, -1, 0, 0.50f, 1.00f }, { 1, -1, 1, 0, 0.75f, 1.00f },
|
|
||||||
{ 1, 1, 1, 0, 0.75f, 0.50f }, { 1, 1, -1, 0, 0.50f, 0.50f },
|
|
||||||
/* Top quad */
|
|
||||||
{ 1, 1, -1, 0, 0.50f, 0.50f }, { 1, 1, 1, 0, 0.50f, 0.00f },
|
|
||||||
{ -1, 1, 1, 0, 0.25f, 0.00f }, { -1, 1, -1, 0, 0.25f, 0.50f },
|
|
||||||
/* Bottom quad */
|
|
||||||
{ 1, -1, -1, 0, 0.75f, 0.50f }, { 1, -1, 1, 0, 0.75f, 0.00f },
|
|
||||||
{ -1, -1, 1, 0, 0.50f, 0.00f }, { -1, -1, -1, 0, 0.50f, 0.50f },
|
|
||||||
};
|
|
||||||
struct VertexTextured* data;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
Gfx_DeleteVb(&skybox_vb);
|
|
||||||
if (Gfx.LostContext) return;
|
|
||||||
if (EnvRenderer_Minimal) return;
|
|
||||||
|
|
||||||
data = (struct VertexTextured*)Gfx_RecreateAndLockVb(&skybox_vb,
|
|
||||||
VERTEX_FORMAT_TEXTURED, SKYBOX_COUNT);
|
|
||||||
Mem_Copy(data, vertices, sizeof(vertices));
|
|
||||||
for (i = 0; i < SKYBOX_COUNT; i++) { data[i].Col = Env.SkyboxCol; }
|
|
||||||
Gfx_UnlockVb(skybox_vb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*----------------------------------------------------------Weather--------------------------------------------------------*
|
*----------------------------------------------------------Weather--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
@ -347,7 +342,10 @@ static double weather_accumulator;
|
|||||||
static IVec3 lastPos;
|
static IVec3 lastPos;
|
||||||
|
|
||||||
#define WEATHER_EXTENT 4
|
#define WEATHER_EXTENT 4
|
||||||
#define WEATHER_VERTS_COUNT 8 * (WEATHER_EXTENT * 2 + 1) * (WEATHER_EXTENT * 2 + 1)
|
#define WEATHER_VERTS 8 /* 2 quads per tile */
|
||||||
|
#define WEATHER_RANGE (WEATHER_EXTENT * 2 + 1)
|
||||||
|
|
||||||
|
#define WEATHER_VERTS_COUNT WEATHER_RANGE * WEATHER_RANGE * WEATHER_VERTS
|
||||||
#define Weather_Pack(x, z) ((x) * World.Length + (z))
|
#define Weather_Pack(x, z) ((x) * World.Length + (z))
|
||||||
|
|
||||||
static void InitWeatherHeightmap(void) {
|
static void InitWeatherHeightmap(void) {
|
||||||
@ -428,26 +426,31 @@ static float CalcRainAlphaAt(float x) {
|
|||||||
return 178 + falloff * Env.WeatherFade;
|
return 178 + falloff * Env.WeatherFade;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RainCoord { int dx, dz; float y; };
|
||||||
static RNGState snowDirRng;
|
static RNGState snowDirRng;
|
||||||
|
|
||||||
void EnvRenderer_RenderWeather(double deltaTime) {
|
void EnvRenderer_RenderWeather(double deltaTime) {
|
||||||
struct VertexTextured vertices[WEATHER_VERTS_COUNT];
|
struct RainCoord coords[WEATHER_RANGE * WEATHER_RANGE];
|
||||||
|
int i, weather, numCoords = 0;
|
||||||
struct VertexTextured* v;
|
struct VertexTextured* v;
|
||||||
int weather, vCount;
|
|
||||||
IVec3 pos;
|
|
||||||
cc_bool moved, particles;
|
cc_bool moved, particles;
|
||||||
float speed, vOffsetBase, vOffset;
|
float speed, vOffsetBase, vOffset;
|
||||||
|
IVec3 pos;
|
||||||
|
|
||||||
PackedCol col;
|
PackedCol color;
|
||||||
int dist, dx, dz, x, z;
|
int dist, dx, dz, x, z;
|
||||||
float alpha, y, height;
|
float alpha, y, height;
|
||||||
float uOffset1, uOffset2;
|
float uOffset1, uOffset2, uSpeed;
|
||||||
float worldV, v1, v2, vPlane1Offset;
|
float worldV, v1, v2, vPlane1Offset;
|
||||||
float x1,y1,z1, x2,y2,z2;
|
float x1,y1,z1, x2,y2,z2;
|
||||||
|
|
||||||
weather = Env.Weather;
|
weather = Env.Weather;
|
||||||
if (weather == WEATHER_SUNNY) return;
|
if (weather == WEATHER_SUNNY) return;
|
||||||
if (!Weather_Heightmap) InitWeatherHeightmap();
|
|
||||||
Gfx_BindTexture(weather == WEATHER_RAINY ? rain_tex : snow_tex);
|
if (!Weather_Heightmap)
|
||||||
|
InitWeatherHeightmap();
|
||||||
|
if (!weather_vb)
|
||||||
|
weather_vb = Gfx_CreateDynamicVb(VERTEX_FORMAT_TEXTURED, WEATHER_VERTS_COUNT);
|
||||||
|
|
||||||
IVec3_Floor(&pos, &Camera.CurrentPos);
|
IVec3_Floor(&pos, &Camera.CurrentPos);
|
||||||
moved = pos.X != lastPos.X || pos.Y != lastPos.Y || pos.Z != lastPos.Z;
|
moved = pos.X != lastPos.X || pos.Y != lastPos.Y || pos.Z != lastPos.Z;
|
||||||
@ -457,39 +460,68 @@ void EnvRenderer_RenderWeather(double deltaTime) {
|
|||||||
pos.Y += 64;
|
pos.Y += 64;
|
||||||
pos.Y = max(World.Height, pos.Y);
|
pos.Y = max(World.Height, pos.Y);
|
||||||
|
|
||||||
speed = (weather == WEATHER_RAINY ? 1.0f : 0.2f) * Env.WeatherSpeed;
|
|
||||||
vOffsetBase = (float)Game.Time * speed;
|
|
||||||
vPlane1Offset = weather == WEATHER_RAINY ? 0 : 0.25f; /* Offset v on 1 plane while snowing to avoid the unnatural mirrored texture effect */
|
|
||||||
particles = weather == WEATHER_RAINY;
|
|
||||||
weather_accumulator += deltaTime;
|
weather_accumulator += deltaTime;
|
||||||
|
particles = weather == WEATHER_RAINY && (weather_accumulator >= 0.25 || moved);
|
||||||
v = vertices;
|
|
||||||
col = Env.SunCol;
|
|
||||||
|
|
||||||
for (dx = -WEATHER_EXTENT; dx <= WEATHER_EXTENT; dx++) {
|
for (dx = -WEATHER_EXTENT; dx <= WEATHER_EXTENT; dx++) {
|
||||||
for (dz = -WEATHER_EXTENT; dz <= WEATHER_EXTENT; dz++) {
|
for (dz = -WEATHER_EXTENT; dz <= WEATHER_EXTENT; dz++) {
|
||||||
x = pos.X + dx; z = pos.Z + dz;
|
x = pos.X + dx; z = pos.Z + dz;
|
||||||
|
|
||||||
y = GetRainHeight(x, z);
|
y = GetRainHeight(x, z);
|
||||||
height = pos.Y - y;
|
if (pos.Y <= y) continue;
|
||||||
if (height <= 0) continue;
|
if (particles) Particles_RainSnowEffect((float)x, y, (float)z);
|
||||||
|
|
||||||
if (particles && (weather_accumulator >= 0.25 || moved)) {
|
coords[numCoords].dx = dx;
|
||||||
Particles_RainSnowEffect((float)x, y, (float)z);
|
coords[numCoords].y = y;
|
||||||
|
coords[numCoords].dz = dz;
|
||||||
|
numCoords++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx_BindTexture(weather == WEATHER_RAINY ? rain_tex : snow_tex);
|
||||||
|
if (particles) weather_accumulator = 0;
|
||||||
|
if (!numCoords) return;
|
||||||
|
|
||||||
|
Gfx_SetAlphaTest(false);
|
||||||
|
Gfx_SetDepthWrite(false);
|
||||||
|
Gfx_SetAlphaArgBlend(true);
|
||||||
|
|
||||||
|
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
||||||
|
v = (struct VertexTextured*)Gfx_LockDynamicVb(weather_vb,
|
||||||
|
VERTEX_FORMAT_TEXTURED, numCoords * WEATHER_VERTS);
|
||||||
|
|
||||||
|
color = Env.SunCol;
|
||||||
|
speed = (weather == WEATHER_RAINY ? 1.0f : 0.2f) * Env.WeatherSpeed;
|
||||||
|
|
||||||
|
vOffsetBase = (float)Game.Time * speed;
|
||||||
|
vPlane1Offset = weather == WEATHER_RAINY ? 0 : 0.25f; /* Offset v on 1 plane while snowing to avoid the unnatural mirrored texture effect */
|
||||||
|
|
||||||
|
for (i = 0; i < numCoords; i++)
|
||||||
|
{
|
||||||
|
dx = coords[i].dx;
|
||||||
|
y = coords[i].y;
|
||||||
|
dz = coords[i].dz;
|
||||||
|
|
||||||
|
height = pos.Y - y;
|
||||||
|
|
||||||
dist = dx * dx + dz * dz;
|
dist = dx * dx + dz * dz;
|
||||||
alpha = CalcRainAlphaAt((float)dist);
|
alpha = CalcRainAlphaAt((float)dist);
|
||||||
Math_Clamp(alpha, 0.0f, 255.0f);
|
Math_Clamp(alpha, 0.0f, 255.0f);
|
||||||
col = (col & PACKEDCOL_RGB_MASK) | PackedCol_A_Bits(alpha);
|
color = (color & PACKEDCOL_RGB_MASK) | PackedCol_A_Bits(alpha);
|
||||||
|
|
||||||
|
x = dx + pos.X;
|
||||||
|
z = dz + pos.Z;
|
||||||
|
|
||||||
uOffset1 = 0;
|
uOffset1 = 0;
|
||||||
uOffset2 = 0;
|
uOffset2 = 0;
|
||||||
if (weather == WEATHER_SNOWY) {
|
if (weather == WEATHER_SNOWY) {
|
||||||
Random_Seed(&snowDirRng, (x + 1217 * z) & 0x7fffffff);
|
Random_Seed(&snowDirRng, (x + 1217 * z) & 0x7fffffff);
|
||||||
|
|
||||||
/* Multiply horizontal speed by a random float from -1 to 1 */
|
/* Multiply horizontal speed by a random float from -1 to 1 */
|
||||||
uOffset1 = ((float)Game.Time * (Random_Float(&snowDirRng) * 2 + -1)) * Env.WeatherSpeed * 0.5f;
|
uSpeed = (float)Game.Time * Env.WeatherSpeed * 0.5f;
|
||||||
uOffset2 = ((float)Game.Time * (Random_Float(&snowDirRng) * 2 + -1)) * Env.WeatherSpeed * 0.5f;
|
uOffset1 = uSpeed * (Random_Float(&snowDirRng) * 2 + -1);
|
||||||
|
uOffset2 = uSpeed * (Random_Float(&snowDirRng) * 2 + -1);
|
||||||
|
|
||||||
/* Multiply vertical speed by a random float from 1.0 to 0.25 */
|
/* Multiply vertical speed by a random float from 1.0 to 0.25 */
|
||||||
vOffset = vOffsetBase * (float)(Random_Float(&snowDirRng) * (1.0f - 0.25f) + 0.25f);
|
vOffset = vOffsetBase * (float)(Random_Float(&snowDirRng) * (1.0f - 0.25f) + 0.25f);
|
||||||
} else {
|
} else {
|
||||||
@ -502,30 +534,19 @@ void EnvRenderer_RenderWeather(double deltaTime) {
|
|||||||
x1 = (float)x; y1 = (float)y; z1 = (float)z;
|
x1 = (float)x; y1 = (float)y; z1 = (float)z;
|
||||||
x2 = (float)(x + 1); y2 = (float)(y + height); z2 = (float)(z + 1);
|
x2 = (float)(x + 1); y2 = (float)(y + height); z2 = (float)(z + 1);
|
||||||
|
|
||||||
v->X = x1; v->Y = y1; v->Z = z1; v->Col = col; v->U = 0.0f + uOffset1; v->V = v1+vPlane1Offset; v++;
|
v->X = x1; v->Y = y1; v->Z = z1; v->Col = color; v->U = uOffset1; v->V = v1 + vPlane1Offset; v++;
|
||||||
v->X = x1; v->Y = y2; v->Z = z1; v->Col = col; v->U = 0.0f + uOffset1; v->V = v2+vPlane1Offset; v++;
|
v->X = x1; v->Y = y2; v->Z = z1; v->Col = color; v->U = uOffset1; v->V = v2 + vPlane1Offset; v++;
|
||||||
v->X = x2; v->Y = y2; v->Z = z2; v->Col = col; v->U = 1.0f + uOffset1; v->V = v2+vPlane1Offset; v++;
|
v->X = x2; v->Y = y2; v->Z = z2; v->Col = color; v->U = uOffset1 + 1.0f; v->V = v2 + vPlane1Offset; v++;
|
||||||
v->X = x2; v->Y = y1; v->Z = z2; v->Col = col; v->U = 1.0f + uOffset1; v->V = v1+vPlane1Offset; v++;
|
v->X = x2; v->Y = y1; v->Z = z2; v->Col = color; v->U = uOffset1 + 1.0f; v->V = v1 + vPlane1Offset; v++;
|
||||||
|
|
||||||
v->X = x2; v->Y = y1; v->Z = z1; v->Col = col; v->U = 1.0f + uOffset2; v->V = v1; v++;
|
v->X = x2; v->Y = y1; v->Z = z1; v->Col = color; v->U = uOffset2 + 1.0f; v->V = v1; v++;
|
||||||
v->X = x2; v->Y = y2; v->Z = z1; v->Col = col; v->U = 1.0f + uOffset2; v->V = v2; v++;
|
v->X = x2; v->Y = y2; v->Z = z1; v->Col = color; v->U = uOffset2 + 1.0f; v->V = v2; v++;
|
||||||
v->X = x1; v->Y = y2; v->Z = z2; v->Col = col; v->U = 0.0f + uOffset2; v->V = v2; v++;
|
v->X = x1; v->Y = y2; v->Z = z2; v->Col = color; v->U = uOffset2; v->V = v2; v++;
|
||||||
v->X = x1; v->Y = y1; v->Z = z2; v->Col = col; v->U = 0.0f + uOffset2; v->V = v1; v++;
|
v->X = x1; v->Y = y1; v->Z = z2; v->Col = color; v->U = uOffset2; v->V = v1; v++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (particles && (weather_accumulator >= 0.25f || moved)) {
|
Gfx_UnlockDynamicVb(weather_vb);
|
||||||
weather_accumulator = 0;
|
Gfx_DrawVb_IndexedTris(numCoords * WEATHER_VERTS);
|
||||||
}
|
|
||||||
if (v == vertices) return;
|
|
||||||
|
|
||||||
Gfx_SetAlphaTest(false);
|
|
||||||
Gfx_SetDepthWrite(false);
|
|
||||||
Gfx_SetAlphaArgBlend(true);
|
|
||||||
|
|
||||||
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
|
||||||
vCount = (int)(v - vertices);
|
|
||||||
Gfx_UpdateDynamicVb_IndexedTris(weather_vb, vertices, vCount);
|
|
||||||
|
|
||||||
Gfx_SetAlphaArgBlend(false);
|
Gfx_SetAlphaArgBlend(false);
|
||||||
Gfx_SetDepthWrite(true);
|
Gfx_SetDepthWrite(true);
|
||||||
@ -808,13 +829,12 @@ static void UpdateAll(void) {
|
|||||||
UpdateMapEdges();
|
UpdateMapEdges();
|
||||||
UpdateClouds();
|
UpdateClouds();
|
||||||
UpdateSky();
|
UpdateSky();
|
||||||
UpdateSkybox();
|
Gfx_DeleteVb(&skybox_vb);
|
||||||
EnvRenderer_UpdateFog();
|
EnvRenderer_UpdateFog();
|
||||||
|
|
||||||
Gfx_DeleteDynamicVb(&weather_vb);
|
Gfx_DeleteDynamicVb(&weather_vb);
|
||||||
|
/* TODO: Unnecessary to delete the weather VB? */
|
||||||
if (Gfx.LostContext) return;
|
if (Gfx.LostContext) return;
|
||||||
/* TODO: Don't allocate unless used? */
|
|
||||||
Gfx_RecreateDynamicVb(&weather_vb, VERTEX_FORMAT_TEXTURED, WEATHER_VERTS_COUNT);
|
|
||||||
/* TODO: Don't need to do this on every new map */
|
/* TODO: Don't need to do this on every new map */
|
||||||
UpdateBorderTextures();
|
UpdateBorderTextures();
|
||||||
}
|
}
|
||||||
@ -873,7 +893,7 @@ static void OnEnvVariableChanged(void* obj, int envVar) {
|
|||||||
UpdateSky();
|
UpdateSky();
|
||||||
UpdateClouds();
|
UpdateClouds();
|
||||||
} else if (envVar == ENV_VAR_SKYBOX_COLOR) {
|
} else if (envVar == ENV_VAR_SKYBOX_COLOR) {
|
||||||
UpdateSkybox();
|
Gfx_DeleteVb(&skybox_vb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ static void Game_Render3D(double delta, float t) {
|
|||||||
|
|
||||||
AxisLinesRenderer_Render();
|
AxisLinesRenderer_Render();
|
||||||
Entities_RenderModels(delta, t);
|
Entities_RenderModels(delta, t);
|
||||||
Entities_RenderNames();
|
EntityNames_Render();
|
||||||
|
|
||||||
Particles_Render(t);
|
Particles_Render(t);
|
||||||
Camera.Active->GetPickedBlock(&Game_SelectedPos); /* TODO: only pick when necessary */
|
Camera.Active->GetPickedBlock(&Game_SelectedPos); /* TODO: only pick when necessary */
|
||||||
@ -496,7 +496,7 @@ static void Game_Render3D(double delta, float t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Selections_Render();
|
Selections_Render();
|
||||||
Entities_RenderHoveredNames();
|
EntityNames_RenderHovered();
|
||||||
Camera_KeyLookUpdate();
|
Camera_KeyLookUpdate();
|
||||||
InputHandler_Tick();
|
InputHandler_Tick();
|
||||||
if (!Game_HideGui) HeldBlockRenderer_Render(delta);
|
if (!Game_HideGui) HeldBlockRenderer_Render(delta);
|
||||||
@ -573,6 +573,7 @@ static void Game_RenderFrame(double delta) {
|
|||||||
Gfx_RecreateContext();
|
Gfx_RecreateContext();
|
||||||
/* all good, context is back */
|
/* all good, context is back */
|
||||||
} else {
|
} else {
|
||||||
|
Game.Time += delta; /* TODO: Not set in two places? */
|
||||||
Server.Tick(NULL);
|
Server.Tick(NULL);
|
||||||
Thread_Sleep(16);
|
Thread_Sleep(16);
|
||||||
return;
|
return;
|
||||||
|
162
src/Graphics.h
162
src/Graphics.h
@ -25,14 +25,14 @@ typedef enum MatrixType_ {
|
|||||||
#define SIZEOF_VERTEX_TEXTURED 24
|
#define SIZEOF_VERTEX_TEXTURED 24
|
||||||
|
|
||||||
#if defined CC_BUILD_PSP
|
#if defined CC_BUILD_PSP
|
||||||
/* 3 floats for position (XYZ), 4 bytes for colour. */
|
/* 3 floats for position (XYZ), 4 bytes for colour */
|
||||||
struct VertexColoured { PackedCol Col; float X, Y, Z; };
|
struct VertexColoured { PackedCol Col; float X, Y, Z; };
|
||||||
/* 3 floats for position (XYZ), 2 floats for texture coordinates (UV), 4 bytes for colour. */
|
/* 3 floats for position (XYZ), 2 floats for texture coordinates (UV), 4 bytes for colour */
|
||||||
struct VertexTextured { float U, V; PackedCol Col; float X, Y, Z; };
|
struct VertexTextured { float U, V; PackedCol Col; float X, Y, Z; };
|
||||||
#else
|
#else
|
||||||
/* 3 floats for position (XYZ), 4 bytes for colour. */
|
/* 3 floats for position (XYZ), 4 bytes for colour */
|
||||||
struct VertexColoured { float X, Y, Z; PackedCol Col; };
|
struct VertexColoured { float X, Y, Z; PackedCol Col; };
|
||||||
/* 3 floats for position (XYZ), 2 floats for texture coordinates (UV), 4 bytes for colour. */
|
/* 3 floats for position (XYZ), 2 floats for texture coordinates (UV), 4 bytes for colour */
|
||||||
struct VertexTextured { float X, Y, Z; PackedCol Col; float U, V; };
|
struct VertexTextured { float X, Y, Z; PackedCol Col; float U, V; };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -45,9 +45,9 @@ CC_VAR extern struct _GfxData {
|
|||||||
float _unused;
|
float _unused;
|
||||||
/* Whether context graphics has been lost (all creation/render calls fail) */
|
/* Whether context graphics has been lost (all creation/render calls fail) */
|
||||||
cc_bool LostContext;
|
cc_bool LostContext;
|
||||||
/* Whether some textures are created with mipmaps. */
|
/* Whether some textures are created with mipmaps */
|
||||||
cc_bool Mipmaps;
|
cc_bool Mipmaps;
|
||||||
/* Whether managed textures are actually supported. */
|
/* Whether managed textures are actually supported */
|
||||||
/* If not, you must free/create them just like normal textures */
|
/* If not, you must free/create them just like normal textures */
|
||||||
cc_bool ManagedTextures;
|
cc_bool ManagedTextures;
|
||||||
/* Whether graphics context has been created */
|
/* Whether graphics context has been created */
|
||||||
@ -56,7 +56,6 @@ CC_VAR extern struct _GfxData {
|
|||||||
} Gfx;
|
} Gfx;
|
||||||
|
|
||||||
extern GfxResourceID Gfx_defaultIb;
|
extern GfxResourceID Gfx_defaultIb;
|
||||||
extern GfxResourceID Gfx_quadVb, Gfx_texVb;
|
|
||||||
extern const cc_string Gfx_LowPerfMessage;
|
extern const cc_string Gfx_LowPerfMessage;
|
||||||
|
|
||||||
#define ICOUNT(verticesCount) (((verticesCount) >> 2) * 6)
|
#define ICOUNT(verticesCount) (((verticesCount) >> 2) * 6)
|
||||||
@ -77,58 +76,58 @@ void* Gfx_RecreateAndLockVb(GfxResourceID* vb, VertexFormat fmt, int count);
|
|||||||
/* Creates a new texture. (and also generates mipmaps if mipmaps) */
|
/* Creates a new texture. (and also generates mipmaps if mipmaps) */
|
||||||
/* Supported flags: TEXTURE_FLAG_MANAGED, TEXTURE_FLAG_DYNAMIC */
|
/* Supported flags: TEXTURE_FLAG_MANAGED, TEXTURE_FLAG_DYNAMIC */
|
||||||
/* NOTE: Only set mipmaps to true if Gfx_Mipmaps is also true, because whether textures
|
/* NOTE: Only set mipmaps to true if Gfx_Mipmaps is also true, because whether textures
|
||||||
use mipmapping may be either a per-texture or global state depending on the backend. */
|
use mipmapping may be either a per-texture or global state depending on the backend */
|
||||||
CC_API GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps);
|
CC_API GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps);
|
||||||
/* Updates a region of the given texture. (and mipmapped regions if mipmaps) */
|
/* Updates a region of the given texture. (and mipmapped regions if mipmaps) */
|
||||||
CC_API void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, struct Bitmap* part, cc_bool mipmaps);
|
CC_API void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, struct Bitmap* part, cc_bool mipmaps);
|
||||||
/* Updates a region of the given texture. (and mipmapped regions if mipmaps) */
|
/* Updates a region of the given texture. (and mipmapped regions if mipmaps) */
|
||||||
/* NOTE: rowWidth is in pixels (so for normal bitmaps, rowWidth equals width) */ /* OBSOLETE */
|
/* NOTE: rowWidth is in pixels (so for normal bitmaps, rowWidth equals width) */ /* OBSOLETE */
|
||||||
void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps);
|
void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps);
|
||||||
/* Sets the currently active texture. */
|
/* Sets the currently active texture */
|
||||||
CC_API void Gfx_BindTexture(GfxResourceID texId);
|
CC_API void Gfx_BindTexture(GfxResourceID texId);
|
||||||
/* Deletes the given texture, then sets it to 0. */
|
/* Deletes the given texture, then sets it to 0 */
|
||||||
CC_API void Gfx_DeleteTexture(GfxResourceID* texId);
|
CC_API void Gfx_DeleteTexture(GfxResourceID* texId);
|
||||||
/* NOTE: Completely useless now, and does nothing in all graphics backends */
|
/* NOTE: Completely useless now, and does nothing in all graphics backends */
|
||||||
/* (used to set whether texture colour is used when rendering vertices) */
|
/* (used to set whether texture colour is used when rendering vertices) */
|
||||||
CC_API void Gfx_SetTexturing(cc_bool enabled);
|
CC_API void Gfx_SetTexturing(cc_bool enabled);
|
||||||
/* Turns on mipmapping. (if Gfx_Mipmaps is enabled) */
|
/* Turns on mipmapping. (if Gfx_Mipmaps is enabled) */
|
||||||
/* NOTE: You must have created textures with mipmaps true for this to work. */
|
/* NOTE: You must have created textures with mipmaps true for this to work */
|
||||||
CC_API void Gfx_EnableMipmaps(void);
|
CC_API void Gfx_EnableMipmaps(void);
|
||||||
/* Turns off mipmapping. (if Gfx_Mipmaps is enabled) */
|
/* Turns off mipmapping. (if Gfx_Mipmaps is enabled) */
|
||||||
/* NOTE: You must have created textures with mipmaps true for this to work. */
|
/* NOTE: You must have created textures with mipmaps true for this to work */
|
||||||
CC_API void Gfx_DisableMipmaps(void);
|
CC_API void Gfx_DisableMipmaps(void);
|
||||||
|
|
||||||
/* Returns whether fog blending is enabled. */
|
/* Returns whether fog blending is enabled */
|
||||||
CC_API cc_bool Gfx_GetFog(void);
|
CC_API cc_bool Gfx_GetFog(void);
|
||||||
/* Sets whether fog blending is enabled. */
|
/* Sets whether fog blending is enabled */
|
||||||
CC_API void Gfx_SetFog(cc_bool enabled);
|
CC_API void Gfx_SetFog(cc_bool enabled);
|
||||||
/* Sets the colour of the blended fog. */
|
/* Sets the colour of the blended fog */
|
||||||
CC_API void Gfx_SetFogCol(PackedCol col);
|
CC_API void Gfx_SetFogCol(PackedCol col);
|
||||||
/* Sets thickness of fog for FOG_EXP/FOG_EXP2 modes. */
|
/* Sets thickness of fog for FOG_EXP/FOG_EXP2 modes */
|
||||||
CC_API void Gfx_SetFogDensity(float value);
|
CC_API void Gfx_SetFogDensity(float value);
|
||||||
/* Sets extent/end of fog for FOG_LINEAR mode. */
|
/* Sets extent/end of fog for FOG_LINEAR mode */
|
||||||
CC_API void Gfx_SetFogEnd(float value);
|
CC_API void Gfx_SetFogEnd(float value);
|
||||||
/* Sets in what way fog is blended. */
|
/* Sets in what way fog is blended */
|
||||||
CC_API void Gfx_SetFogMode(FogFunc func);
|
CC_API void Gfx_SetFogMode(FogFunc func);
|
||||||
|
|
||||||
/* Sets whether backface culling is performed. */
|
/* Sets whether backface culling is performed */
|
||||||
CC_API void Gfx_SetFaceCulling(cc_bool enabled);
|
CC_API void Gfx_SetFaceCulling(cc_bool enabled);
|
||||||
/* Sets whether pixels with an alpha of less than 128 are discarded. */
|
/* Sets whether pixels with an alpha of less than 128 are discarded */
|
||||||
CC_API void Gfx_SetAlphaTest(cc_bool enabled);
|
CC_API void Gfx_SetAlphaTest(cc_bool enabled);
|
||||||
/* Sets whether existing and new pixels are blended together. */
|
/* Sets whether existing and new pixels are blended together */
|
||||||
CC_API void Gfx_SetAlphaBlending(cc_bool enabled);
|
CC_API void Gfx_SetAlphaBlending(cc_bool enabled);
|
||||||
/* Sets whether blending between the alpha components of texture and vertex colour is performed. */
|
/* Sets whether blending between the alpha components of texture and vertex colour is performed */
|
||||||
CC_API void Gfx_SetAlphaArgBlend(cc_bool enabled);
|
CC_API void Gfx_SetAlphaArgBlend(cc_bool enabled);
|
||||||
|
|
||||||
/* Clears the colour and depth buffer to default. */
|
/* Clears the colour and depth buffer to default */
|
||||||
CC_API void Gfx_Clear(void);
|
CC_API void Gfx_Clear(void);
|
||||||
/* Sets the colour that the colour buffer is cleared to. */
|
/* Sets the colour that the colour buffer is cleared to */
|
||||||
CC_API void Gfx_ClearCol(PackedCol col);
|
CC_API void Gfx_ClearCol(PackedCol col);
|
||||||
/* Sets whether pixels may be discard based on z/depth. */
|
/* Sets whether pixels may be discard based on z/depth */
|
||||||
CC_API void Gfx_SetDepthTest(cc_bool enabled);
|
CC_API void Gfx_SetDepthTest(cc_bool enabled);
|
||||||
/* Sets whether R/G/B/A of pixels are actually written to the colour buffer channels. */
|
/* Sets whether R/G/B/A of pixels are actually written to the colour buffer channels */
|
||||||
CC_API void Gfx_SetColWriteMask(cc_bool r, cc_bool g, cc_bool b, cc_bool a);
|
CC_API void Gfx_SetColWriteMask(cc_bool r, cc_bool g, cc_bool b, cc_bool a);
|
||||||
/* Sets whether z/depth of pixels is actually written to the depth buffer. */
|
/* Sets whether z/depth of pixels is actually written to the depth buffer */
|
||||||
CC_API void Gfx_SetDepthWrite(cc_bool enabled);
|
CC_API void Gfx_SetDepthWrite(cc_bool enabled);
|
||||||
/* Sets whether the game should only write output to depth buffer */
|
/* Sets whether the game should only write output to depth buffer */
|
||||||
/* NOTE: Implicitly calls Gfx_SetColWriteMask */
|
/* NOTE: Implicitly calls Gfx_SetColWriteMask */
|
||||||
@ -136,25 +135,25 @@ CC_API void Gfx_DepthOnlyRendering(cc_bool depthOnly);
|
|||||||
|
|
||||||
/* Callback function to initialise/fill out the contents of an index buffer */
|
/* Callback function to initialise/fill out the contents of an index buffer */
|
||||||
typedef void (*Gfx_FillIBFunc)(cc_uint16* indices, int count, void* obj);
|
typedef void (*Gfx_FillIBFunc)(cc_uint16* indices, int count, void* obj);
|
||||||
/* Creates a new index buffer and fills out its contents. */
|
/* Creates a new index buffer and fills out its contents */
|
||||||
CC_API GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj);
|
CC_API GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj);
|
||||||
/* Sets the currently active index buffer. */
|
/* Sets the currently active index buffer */
|
||||||
CC_API void Gfx_BindIb(GfxResourceID ib);
|
CC_API void Gfx_BindIb(GfxResourceID ib);
|
||||||
/* Deletes the given index buffer, then sets it to 0. */
|
/* Deletes the given index buffer, then sets it to 0 */
|
||||||
CC_API void Gfx_DeleteIb(GfxResourceID* ib);
|
CC_API void Gfx_DeleteIb(GfxResourceID* ib);
|
||||||
|
|
||||||
/* Creates a new vertex buffer. */
|
/* Creates a new vertex buffer */
|
||||||
CC_API GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count);
|
CC_API GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count);
|
||||||
/* Sets the currently active vertex buffer. */
|
/* Sets the currently active vertex buffer */
|
||||||
CC_API void Gfx_BindVb(GfxResourceID vb);
|
CC_API void Gfx_BindVb(GfxResourceID vb);
|
||||||
/* Deletes the given vertex buffer, then sets it to 0. */
|
/* Deletes the given vertex buffer, then sets it to 0 */
|
||||||
CC_API void Gfx_DeleteVb(GfxResourceID* vb);
|
CC_API void Gfx_DeleteVb(GfxResourceID* vb);
|
||||||
/* Acquires temp memory for changing the contents of a vertex buffer. */
|
/* Acquires temp memory for changing the contents of a vertex buffer */
|
||||||
CC_API void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count);
|
CC_API void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count);
|
||||||
/* Submits the changed contents of a vertex buffer. */
|
/* Submits the changed contents of a vertex buffer */
|
||||||
CC_API void Gfx_UnlockVb(GfxResourceID vb);
|
CC_API void Gfx_UnlockVb(GfxResourceID vb);
|
||||||
|
|
||||||
/* TODO: How to make LockDynamicVb work with OpenGL 1.1 Builder stupidity.. */
|
/* TODO: How to make LockDynamicVb work with OpenGL 1.1 Builder stupidity. */
|
||||||
#ifdef CC_BUILD_GL11
|
#ifdef CC_BUILD_GL11
|
||||||
/* Special case of Gfx_Create/LockVb for building chunks in Builder.c */
|
/* Special case of Gfx_Create/LockVb for building chunks in Builder.c */
|
||||||
GfxResourceID Gfx_CreateVb2(void* vertices, VertexFormat fmt, int count);
|
GfxResourceID Gfx_CreateVb2(void* vertices, VertexFormat fmt, int count);
|
||||||
@ -166,39 +165,34 @@ void Gfx_BindVb_Textured(GfxResourceID vb);
|
|||||||
#define Gfx_BindVb_Textured Gfx_BindVb
|
#define Gfx_BindVb_Textured Gfx_BindVb
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Creates a new dynamic vertex buffer, whose contents can be updated later. */
|
/* Creates a new dynamic vertex buffer, whose contents can be updated later */
|
||||||
CC_API GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices);
|
CC_API GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices);
|
||||||
#ifndef CC_BUILD_GL11
|
/* Sets the active vertex buffer to the given dynamic vertex buffer */
|
||||||
/* Static and dynamic vertex buffers are drawn in the same way */
|
CC_API void Gfx_BindDynamicVb(GfxResourceID vb);
|
||||||
#define Gfx_BindDynamicVb Gfx_BindVb
|
/* Deletes the given dynamic vertex buffer, then sets it to 0 */
|
||||||
#define Gfx_DeleteDynamicVb Gfx_DeleteVb
|
CC_API void Gfx_DeleteDynamicVb(GfxResourceID* vb);
|
||||||
#else
|
/* Acquires temp memory for changing the contents of a dynamic vertex buffer */
|
||||||
/* OpenGL 1.1 draws static vertex buffers completely differently. */
|
|
||||||
void Gfx_BindDynamicVb(GfxResourceID vb);
|
|
||||||
void Gfx_DeleteDynamicVb(GfxResourceID* vb);
|
|
||||||
#endif
|
|
||||||
/* Acquires temp memory for changing the contents of a dynamic vertex buffer. */
|
|
||||||
CC_API void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count);
|
CC_API void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count);
|
||||||
/* Binds then submits the changed contents of a dynamic vertex buffer. */
|
/* Binds then submits the changed contents of a dynamic vertex buffer */
|
||||||
CC_API void Gfx_UnlockDynamicVb(GfxResourceID vb);
|
CC_API void Gfx_UnlockDynamicVb(GfxResourceID vb);
|
||||||
|
|
||||||
/* Sets the format of the rendered vertices. */
|
/* Sets the format of the rendered vertices */
|
||||||
CC_API void Gfx_SetVertexFormat(VertexFormat fmt);
|
CC_API void Gfx_SetVertexFormat(VertexFormat fmt);
|
||||||
/* Updates the data of a dynamic vertex buffer. */
|
/* Updates the data of a dynamic vertex buffer */
|
||||||
CC_API void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount);
|
CC_API void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount);
|
||||||
/* Renders vertices from the currently bound vertex buffer as lines. */
|
/* Renders vertices from the currently bound vertex buffer as lines */
|
||||||
CC_API void Gfx_DrawVb_Lines(int verticesCount);
|
CC_API void Gfx_DrawVb_Lines(int verticesCount);
|
||||||
/* Renders vertices from the currently bound vertex and index buffer as triangles. */
|
/* Renders vertices from the currently bound vertex and index buffer as triangles */
|
||||||
/* NOTE: Offsets each index by startVertex. */
|
/* NOTE: Offsets each index by startVertex */
|
||||||
CC_API void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex);
|
CC_API void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex);
|
||||||
/* Renders vertices from the currently bound vertex and index buffer as triangles. */
|
/* Renders vertices from the currently bound vertex and index buffer as triangles */
|
||||||
CC_API void Gfx_DrawVb_IndexedTris(int verticesCount);
|
CC_API void Gfx_DrawVb_IndexedTris(int verticesCount);
|
||||||
/* Special case Gfx_DrawVb_IndexedTris_Range for map renderer */
|
/* Special case Gfx_DrawVb_IndexedTris_Range for map renderer */
|
||||||
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex);
|
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex);
|
||||||
|
|
||||||
/* Loads the given matrix over the currently active matrix. */
|
/* Loads the given matrix over the currently active matrix */
|
||||||
CC_API void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix);
|
CC_API void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix);
|
||||||
/* Loads the identity matrix over the currently active matrix. */
|
/* Loads the identity matrix over the currently active matrix */
|
||||||
CC_API void Gfx_LoadIdentityMatrix(MatrixType type);
|
CC_API void Gfx_LoadIdentityMatrix(MatrixType type);
|
||||||
CC_API void Gfx_EnableTextureOffset(float x, float y);
|
CC_API void Gfx_EnableTextureOffset(float x, float y);
|
||||||
CC_API void Gfx_DisableTextureOffset(void);
|
CC_API void Gfx_DisableTextureOffset(void);
|
||||||
@ -210,56 +204,52 @@ void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, f
|
|||||||
/* NOTE: Projection matrix calculation is here because it can depend the graphics backend */
|
/* NOTE: Projection matrix calculation is here because it can depend the graphics backend */
|
||||||
/* (e.g. OpenGL uses a Z clip space range of [-1, 1], whereas Direct3D9 uses [0, 1]) */
|
/* (e.g. OpenGL uses a Z clip space range of [-1, 1], whereas Direct3D9 uses [0, 1]) */
|
||||||
|
|
||||||
/* Outputs a .png screenshot of the backbuffer. */
|
/* Outputs a .png screenshot of the backbuffer */
|
||||||
cc_result Gfx_TakeScreenshot(struct Stream* output);
|
cc_result Gfx_TakeScreenshot(struct Stream* output);
|
||||||
/* Warns in chat if the backend has problems with the user's GPU. */
|
/* Warns in chat if the backend has problems with the user's GPU */
|
||||||
/* Returns whether legacy rendering mode for borders/sky/clouds is needed. */
|
/* Returns whether legacy rendering mode for borders/sky/clouds is needed */
|
||||||
cc_bool Gfx_WarnIfNecessary(void);
|
cc_bool Gfx_WarnIfNecessary(void);
|
||||||
/* Sets up state for rendering a new frame. */
|
/* Sets up state for rendering a new frame */
|
||||||
void Gfx_BeginFrame(void);
|
void Gfx_BeginFrame(void);
|
||||||
/* Finishes rendering a frame, and swaps it with the back buffer. */
|
/* Finishes rendering a frame, and swaps it with the back buffer */
|
||||||
void Gfx_EndFrame(void);
|
void Gfx_EndFrame(void);
|
||||||
/* Sets whether to synchronise with monitor refresh to avoid tearing, and maximum frame rate. */
|
/* Sets whether to synchronise with monitor refresh to avoid tearing, and maximum frame rate */
|
||||||
/* NOTE: VSync setting may be unsupported or just ignored. */
|
/* NOTE: VSync setting may be unsupported or just ignored */
|
||||||
void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMillis);
|
void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMillis);
|
||||||
/* Updates state when the window's dimensions have changed. */
|
/* Updates state when the window's dimensions have changed */
|
||||||
/* NOTE: This may require recreating the context depending on the backend. */
|
/* NOTE: This may require recreating the context depending on the backend */
|
||||||
void Gfx_OnWindowResize(void);
|
void Gfx_OnWindowResize(void);
|
||||||
/* Gets information about the user's GPU and current backend state. */
|
/* Gets information about the user's GPU and current backend state */
|
||||||
/* Backend state may include depth buffer bits, free memory, etc. */
|
/* Backend state may include depth buffer bits, free memory, etc */
|
||||||
/* NOTE: Each line is separated by \n. */
|
/* NOTE: Each line is separated by \n */
|
||||||
void Gfx_GetApiInfo(cc_string* info);
|
void Gfx_GetApiInfo(cc_string* info);
|
||||||
|
|
||||||
/* Raises ContextLost event and updates state for lost contexts. */
|
/* Raises ContextLost event and updates state for lost contexts */
|
||||||
void Gfx_LoseContext(const char* reason);
|
void Gfx_LoseContext(const char* reason);
|
||||||
/* Raises ContextRecreated event and restores internal state. */
|
/* Raises ContextRecreated event and restores internal state */
|
||||||
void Gfx_RecreateContext(void);
|
void Gfx_RecreateContext(void);
|
||||||
/* Attempts to restore a lost context. */
|
/* Attempts to restore a lost context */
|
||||||
cc_bool Gfx_TryRestoreContext(void);
|
cc_bool Gfx_TryRestoreContext(void);
|
||||||
|
|
||||||
/* Binds and draws the specified subset of the vertices in the current dynamic vertex buffer. */
|
/* Renders a 2D flat coloured rectangle */
|
||||||
/* NOTE: This replaces the dynamic vertex buffer's data first with the given vertices before drawing. */
|
|
||||||
void Gfx_UpdateDynamicVb_IndexedTris(GfxResourceID vb, void* vertices, int vCount);
|
|
||||||
|
|
||||||
/* Renders a 2D flat coloured rectangle. */
|
|
||||||
void Gfx_Draw2DFlat(int x, int y, int width, int height, PackedCol color);
|
void Gfx_Draw2DFlat(int x, int y, int width, int height, PackedCol color);
|
||||||
/* Renders a 2D flat vertical gradient rectangle. */
|
/* Renders a 2D flat vertical gradient rectangle */
|
||||||
void Gfx_Draw2DGradient(int x, int y, int width, int height, PackedCol top, PackedCol bottom);
|
void Gfx_Draw2DGradient(int x, int y, int width, int height, PackedCol top, PackedCol bottom);
|
||||||
/* Renders a 2D coloured texture. */
|
/* Renders a 2D coloured texture */
|
||||||
void Gfx_Draw2DTexture(const struct Texture* tex, PackedCol color);
|
void Gfx_Draw2DTexture(const struct Texture* tex, PackedCol color);
|
||||||
/* Fills out the vertices for rendering a 2D coloured texture. */
|
/* Fills out the vertices for rendering a 2D coloured texture */
|
||||||
void Gfx_Make2DQuad(const struct Texture* tex, PackedCol color, struct VertexTextured** vertices);
|
void Gfx_Make2DQuad(const struct Texture* tex, PackedCol color, struct VertexTextured** vertices);
|
||||||
|
|
||||||
/* Switches state to be suitable for drawing 2D graphics. */
|
/* Switches state to be suitable for drawing 2D graphics */
|
||||||
/* NOTE: This means turning off fog/depth test, changing matrices, etc.*/
|
/* NOTE: This means turning off fog/depth test, changing matrices, etc.*/
|
||||||
void Gfx_Begin2D(int width, int height);
|
void Gfx_Begin2D(int width, int height);
|
||||||
/* Switches state to be suitable for drawing 3D graphics. */
|
/* Switches state to be suitable for drawing 3D graphics */
|
||||||
/* NOTE: This means restoring fog/depth test, restoring matrices, etc. */
|
/* NOTE: This means restoring fog/depth test, restoring matrices, etc */
|
||||||
void Gfx_End2D(void);
|
void Gfx_End2D(void);
|
||||||
|
|
||||||
/* Sets appropriate alpha test/blending for given block draw type. */
|
/* Sets appropriate alpha test/blending for given block draw type */
|
||||||
void Gfx_SetupAlphaState(cc_uint8 draw);
|
void Gfx_SetupAlphaState(cc_uint8 draw);
|
||||||
/* Undoes changes to alpha test/blending state by Gfx_SetupAlphaState. */
|
/* Undoes changes to alpha test/blending state by Gfx_SetupAlphaState */
|
||||||
void Gfx_RestoreAlphaState(cc_uint8 draw);
|
void Gfx_RestoreAlphaState(cc_uint8 draw);
|
||||||
|
|
||||||
/* Statically initialises the position and dimensions of this texture */
|
/* Statically initialises the position and dimensions of this texture */
|
||||||
@ -272,8 +262,8 @@ void Gfx_RestoreAlphaState(cc_uint8 draw);
|
|||||||
/* Useful to only draw a sub-region of the texture's pixels */
|
/* Useful to only draw a sub-region of the texture's pixels */
|
||||||
#define Tex_SetUV(tex, u1,v1, u2,v2) tex.uv.U1 = u1; tex.uv.V1 = v1; tex.uv.U2 = u2; tex.uv.V2 = v2;
|
#define Tex_SetUV(tex, u1,v1, u2,v2) tex.uv.U1 = u1; tex.uv.V1 = v1; tex.uv.U2 = u2; tex.uv.V2 = v2;
|
||||||
|
|
||||||
/* Binds then renders the given texture. */
|
/* Binds then renders the given texture */
|
||||||
void Texture_Render(const struct Texture* tex);
|
void Texture_Render(const struct Texture* tex);
|
||||||
/* Binds then renders the given texture. */
|
/* Binds then renders the given texture */
|
||||||
void Texture_RenderShaded(const struct Texture* tex, PackedCol shadeColor);
|
void Texture_RenderShaded(const struct Texture* tex, PackedCol shadeColor);
|
||||||
#endif
|
#endif
|
||||||
|
@ -228,7 +228,7 @@ static void ToMortonTexture(C3D_Tex* tex, int originX, int originY,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
C3D_Tex* tex = Mem_Alloc(1, sizeof(C3D_Tex), "GPU texture desc");
|
C3D_Tex* tex = Mem_Alloc(1, sizeof(C3D_Tex), "GPU texture desc");
|
||||||
bool success = C3D_TexInit(tex, bmp->width, bmp->height, GPU_RGBA8);
|
bool success = C3D_TexInit(tex, bmp->width, bmp->height, GPU_RGBA8);
|
||||||
//if (!success) Logger_Abort("Failed to create 3DS texture");
|
//if (!success) Logger_Abort("Failed to create 3DS texture");
|
||||||
@ -379,12 +379,9 @@ static cc_uint8* gfx_vertices;
|
|||||||
static cc_uint16* gfx_indices;
|
static cc_uint16* gfx_indices;
|
||||||
|
|
||||||
static void* AllocBuffer(int count, int elemSize) {
|
static void* AllocBuffer(int count, int elemSize) {
|
||||||
void* ptr = linearAlloc(count * elemSize);
|
return linearAlloc(count * elemSize);
|
||||||
//cc_uintptr addr = ptr;
|
//cc_uintptr addr = ptr;
|
||||||
//Platform_Log3("BUFFER CREATE: %i X %i = %x", &count, &elemSize, &addr);
|
//Platform_Log3("BUFFER CREATE: %i X %i = %x", &count, &elemSize, &addr);
|
||||||
|
|
||||||
if (!ptr) Logger_Abort("Failed to allocate memory for buffer");
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FreeBuffer(GfxResourceID* buffer) {
|
static void FreeBuffer(GfxResourceID* buffer) {
|
||||||
@ -396,6 +393,8 @@ static void FreeBuffer(GfxResourceID* buffer) {
|
|||||||
|
|
||||||
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
|
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
|
||||||
void* ib = AllocBuffer(count, sizeof(cc_uint16));
|
void* ib = AllocBuffer(count, sizeof(cc_uint16));
|
||||||
|
if (!ib) Logger_Abort("Failed to allocate memory for index buffer");
|
||||||
|
|
||||||
fillFunc(ib, count, obj);
|
fillFunc(ib, count, obj);
|
||||||
return ib;
|
return ib;
|
||||||
}
|
}
|
||||||
@ -405,7 +404,7 @@ void Gfx_BindIb(GfxResourceID ib) { gfx_indices = ib; }
|
|||||||
void Gfx_DeleteIb(GfxResourceID* ib) { FreeBuffer(ib); }
|
void Gfx_DeleteIb(GfxResourceID* ib) { FreeBuffer(ib); }
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
return AllocBuffer(count, strideSizes[fmt]);
|
return AllocBuffer(count, strideSizes[fmt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,10 +430,12 @@ void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
|||||||
void Gfx_UnlockVb(GfxResourceID vb) { gfx_vertices = vb; }
|
void Gfx_UnlockVb(GfxResourceID vb) { gfx_vertices = vb; }
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
return AllocBuffer(maxVertices, strideSizes[fmt]);
|
return AllocBuffer(maxVertices, strideSizes[fmt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) { Gfx_BindVb(vb); }
|
||||||
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
return vb;
|
return vb;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#ifdef CC_BUILD_D3D11
|
#ifdef CC_BUILD_D3D11
|
||||||
#include "_GraphicsBase.h"
|
#include "_GraphicsBase.h"
|
||||||
#include "Errors.h"
|
#include "Errors.h"
|
||||||
#include "Logger.h"
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "_D3D11Shaders.h"
|
#include "_D3D11Shaders.h"
|
||||||
|
|
||||||
@ -202,16 +201,11 @@ static void D3D11_DoMipmaps(ID3D11Resource* texture, int x, int y, struct Bitmap
|
|||||||
if (prev != bmp->scan0) Mem_Free(prev);
|
if (prev != bmp->scan0) Mem_Free(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
ID3D11Texture2D* tex = NULL;
|
ID3D11Texture2D* tex = NULL;
|
||||||
ID3D11ShaderResourceView* view = NULL;
|
ID3D11ShaderResourceView* view = NULL;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (!Math_IsPowOf2(bmp->width) || !Math_IsPowOf2(bmp->height)) {
|
|
||||||
Logger_Abort("Textures must have power of two dimensions");
|
|
||||||
}
|
|
||||||
if (Gfx.LostContext) return 0;
|
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC desc = { 0 };
|
D3D11_TEXTURE2D_DESC desc = { 0 };
|
||||||
desc.Width = bmp->width;
|
desc.Width = bmp->width;
|
||||||
desc.Height = bmp->height;
|
desc.Height = bmp->height;
|
||||||
@ -343,11 +337,11 @@ static ID3D11Buffer* CreateVertexBuffer(VertexFormat fmt, int count, cc_bool dyn
|
|||||||
/* TODO set data initially */
|
/* TODO set data initially */
|
||||||
|
|
||||||
HRESULT hr = ID3D11Device_CreateBuffer(device, &desc, NULL, &buffer);
|
HRESULT hr = ID3D11Device_CreateBuffer(device, &desc, NULL, &buffer);
|
||||||
if (hr) Logger_Abort2(hr, "Failed to create index buffer");
|
if (hr) Logger_Abort2(hr, "Failed to create vertex buffer");
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
/* TODO immutable? */
|
/* TODO immutable? */
|
||||||
return CreateVertexBuffer(fmt, count, false);
|
return CreateVertexBuffer(fmt, count, false);
|
||||||
}
|
}
|
||||||
@ -371,6 +365,46 @@ void Gfx_UnlockVb(GfxResourceID vb) {
|
|||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
|
return CreateVertexBuffer(fmt, maxVertices, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_DeleteDynamicVb(GfxResourceID* vb) {
|
||||||
|
ID3D11Buffer* buffer = (ID3D11Buffer*)(*vb);
|
||||||
|
if (buffer) ID3D11Buffer_Release(buffer);
|
||||||
|
*vb = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static D3D11_MAPPED_SUBRESOURCE mapDesc;
|
||||||
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
|
ID3D11Buffer* buffer = (ID3D11Buffer*)vb;
|
||||||
|
mapDesc.pData = NULL;
|
||||||
|
|
||||||
|
HRESULT hr = ID3D11DeviceContext_Map(context, buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapDesc);
|
||||||
|
if (hr) Logger_Abort2(hr, "Failed to lock dynamic VB");
|
||||||
|
return mapDesc.pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_UnlockDynamicVb(GfxResourceID vb) {
|
||||||
|
ID3D11Buffer* buffer = (ID3D11Buffer*)vb;
|
||||||
|
ID3D11DeviceContext_Unmap(context, buffer, 0);
|
||||||
|
Gfx_BindDynamicVb(vb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
|
||||||
|
void* data = Gfx_LockDynamicVb(vb, gfx_format, vCount);
|
||||||
|
Mem_Copy(data, vertices, vCount * gfx_stride);
|
||||||
|
Gfx_UnlockDynamicVb(vb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Vertex rendering----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
||||||
if (fmt == gfx_format) return;
|
if (fmt == gfx_format) return;
|
||||||
gfx_format = fmt;
|
gfx_format = fmt;
|
||||||
@ -400,37 +434,6 @@ void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
|
||||||
*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------*
|
|
||||||
*#########################################################################################################################*/
|
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
|
||||||
// TODO pass true instead
|
|
||||||
return CreateVertexBuffer(fmt, maxVertices, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static D3D11_MAPPED_SUBRESOURCE mapDesc;
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
|
||||||
ID3D11Buffer* buffer = (ID3D11Buffer*)vb;
|
|
||||||
mapDesc.pData = NULL;
|
|
||||||
|
|
||||||
HRESULT hr = ID3D11DeviceContext_Map(context, buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapDesc);
|
|
||||||
if (hr) Logger_Abort2(hr, "Failed to lock dynamic VB");
|
|
||||||
return mapDesc.pData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gfx_UnlockDynamicVb(GfxResourceID vb) {
|
|
||||||
ID3D11Buffer* buffer = (ID3D11Buffer*)vb;
|
|
||||||
ID3D11DeviceContext_Unmap(context, buffer, 0);
|
|
||||||
Gfx_BindVb(vb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
|
|
||||||
void* data = Gfx_LockDynamicVb(vb, gfx_format, vCount);
|
|
||||||
Mem_Copy(data, vertices, vCount * gfx_stride);
|
|
||||||
Gfx_UnlockDynamicVb(vb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Matrices--------------------------------------------------------*
|
*---------------------------------------------------------Matrices--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
@ -517,6 +520,12 @@ void Gfx_BindVb(GfxResourceID vb) {
|
|||||||
ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &buffer, &gfx_stride, offset);
|
ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &buffer, &gfx_stride, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) {
|
||||||
|
ID3D11Buffer* buffer = (ID3D11Buffer*)vb;
|
||||||
|
static UINT32 offset[] = { 0 };
|
||||||
|
ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &buffer, &gfx_stride, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//########################################################################################################################
|
//########################################################################################################################
|
||||||
//--------------------------------------------------------Vertex shader---------------------------------------------------
|
//--------------------------------------------------------Vertex shader---------------------------------------------------
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#ifdef CC_BUILD_D3D9
|
#ifdef CC_BUILD_D3D9
|
||||||
#include "_GraphicsBase.h"
|
#include "_GraphicsBase.h"
|
||||||
#include "Errors.h"
|
#include "Errors.h"
|
||||||
#include "Logger.h"
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
|
||||||
/* Avoid pointless includes */
|
/* Avoid pointless includes */
|
||||||
@ -19,7 +18,7 @@
|
|||||||
/* https://docs.microsoft.com/en-us/windows/win32/dxtecharts/the-direct3d-transformation-pipeline */
|
/* https://docs.microsoft.com/en-us/windows/win32/dxtecharts/the-direct3d-transformation-pipeline */
|
||||||
|
|
||||||
/* https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dfvf-texcoordsizen */
|
/* https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dfvf-texcoordsizen */
|
||||||
static DWORD d3d9_formatMappings[2] = { D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 };
|
static DWORD d3d9_formatMappings[] = { D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 };
|
||||||
/* Current format and size of vertices */
|
/* Current format and size of vertices */
|
||||||
static int gfx_stride, gfx_format = -1;
|
static int gfx_stride, gfx_format = -1;
|
||||||
|
|
||||||
@ -247,17 +246,6 @@ static void Gfx_RestoreState(void) {
|
|||||||
D3D9_RestoreRenderStates();
|
D3D9_RestoreRenderStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
static cc_bool D3D9_CheckResult(cc_result res, const char* func) {
|
|
||||||
if (!res) return true;
|
|
||||||
|
|
||||||
if (res == D3DERR_OUTOFVIDEOMEMORY || res == E_OUTOFMEMORY) {
|
|
||||||
if (!Game_ReduceVRAM()) Logger_Abort("Out of video memory!");
|
|
||||||
} else {
|
|
||||||
Logger_Abort2(res, func);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Textures--------------------------------------------------------*
|
*---------------------------------------------------------Textures--------------------------------------------------------*
|
||||||
@ -320,6 +308,17 @@ static void D3D9_DoMipmaps(IDirect3DTexture9* texture, int x, int y, struct Bitm
|
|||||||
if (prev != bmp->scan0) Mem_Free(prev);
|
if (prev != bmp->scan0) Mem_Free(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cc_bool D3D9_CheckResult(cc_result res, const char* func) {
|
||||||
|
if (!res) return true;
|
||||||
|
|
||||||
|
if (res == D3DERR_OUTOFVIDEOMEMORY || res == E_OUTOFMEMORY) {
|
||||||
|
if (!Game_ReduceVRAM()) Logger_Abort("Out of video memory!");
|
||||||
|
} else {
|
||||||
|
Logger_Abort2(res, func);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static IDirect3DTexture9* DoCreateTexture(struct Bitmap* bmp, int levels, int pool) {
|
static IDirect3DTexture9* DoCreateTexture(struct Bitmap* bmp, int levels, int pool) {
|
||||||
IDirect3DTexture9* tex;
|
IDirect3DTexture9* tex;
|
||||||
cc_result res;
|
cc_result res;
|
||||||
@ -332,7 +331,7 @@ static IDirect3DTexture9* DoCreateTexture(struct Bitmap* bmp, int levels, int po
|
|||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
IDirect3DTexture9* tex;
|
IDirect3DTexture9* tex;
|
||||||
IDirect3DTexture9* sys;
|
IDirect3DTexture9* sys;
|
||||||
cc_result res;
|
cc_result res;
|
||||||
@ -340,11 +339,6 @@ GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipm
|
|||||||
int mipmapsLevels = CalcMipmapsLevels(bmp->width, bmp->height);
|
int mipmapsLevels = CalcMipmapsLevels(bmp->width, bmp->height);
|
||||||
int levels = 1 + (mipmaps ? mipmapsLevels : 0);
|
int levels = 1 + (mipmaps ? mipmapsLevels : 0);
|
||||||
|
|
||||||
if (!Math_IsPowOf2(bmp->width) || !Math_IsPowOf2(bmp->height)) {
|
|
||||||
Logger_Abort("Textures must have power of two dimensions");
|
|
||||||
}
|
|
||||||
if (Gfx.LostContext) return 0;
|
|
||||||
|
|
||||||
if (flags & TEXTURE_FLAG_MANAGED) {
|
if (flags & TEXTURE_FLAG_MANAGED) {
|
||||||
while ((res = IDirect3DDevice9_CreateTexture(device, bmp->width, bmp->height, levels,
|
while ((res = IDirect3DDevice9_CreateTexture(device, bmp->width, bmp->height, levels,
|
||||||
0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL)))
|
0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL)))
|
||||||
@ -596,14 +590,16 @@ void Gfx_DeleteIb(GfxResourceID* ib) { D3D9_FreeResource(ib); }
|
|||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static IDirect3DVertexBuffer9* D3D9_AllocVertexBuffer(VertexFormat fmt, int count, DWORD usage) {
|
static IDirect3DVertexBuffer9* D3D9_AllocVertexBuffer(VertexFormat fmt, int count, DWORD usage) {
|
||||||
IDirect3DVertexBuffer9* vbuffer;
|
IDirect3DVertexBuffer9* vbuffer;
|
||||||
cc_result res;
|
|
||||||
int size = count * strideSizes[fmt];
|
int size = count * strideSizes[fmt];
|
||||||
|
cc_result res;
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
res = IDirect3DDevice9_CreateVertexBuffer(device, size, usage,
|
res = IDirect3DDevice9_CreateVertexBuffer(device, size, usage,
|
||||||
d3d9_formatMappings[fmt], D3DPOOL_DEFAULT, &vbuffer, NULL);
|
d3d9_formatMappings[fmt], D3DPOOL_DEFAULT, &vbuffer, NULL);
|
||||||
if (D3D9_CheckResult(res, "D3D9_CreateVb failed")) break;
|
|
||||||
}
|
if (res == D3DERR_OUTOFVIDEOMEMORY || res == E_OUTOFMEMORY)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (res) Logger_Abort2(res, "D3D9_AllocVertexBuffer failed");
|
||||||
return vbuffer;
|
return vbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,17 +623,18 @@ static void* D3D9_LockVb(GfxResourceID vb, VertexFormat fmt, int count, int lock
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
return D3D9_AllocVertexBuffer(fmt, count, D3DUSAGE_WRITEONLY);
|
return D3D9_AllocVertexBuffer(fmt, count, D3DUSAGE_WRITEONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_DeleteVb(GfxResourceID* vb) { D3D9_FreeResource(vb); }
|
||||||
|
|
||||||
void Gfx_BindVb(GfxResourceID vb) {
|
void Gfx_BindVb(GfxResourceID vb) {
|
||||||
IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb;
|
IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb;
|
||||||
cc_result res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, gfx_stride);
|
cc_result res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, gfx_stride);
|
||||||
if (res) Logger_Abort2(res, "D3D9_BindVb");
|
if (res) Logger_Abort2(res, "D3D9_BindVb");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DeleteVb(GfxResourceID* vb) { D3D9_FreeResource(vb); }
|
|
||||||
void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
return D3D9_LockVb(vb, fmt, count, 0);
|
return D3D9_LockVb(vb, fmt, count, 0);
|
||||||
}
|
}
|
||||||
@ -649,6 +646,43 @@ void Gfx_UnlockVb(GfxResourceID vb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
|
return D3D9_AllocVertexBuffer(fmt, maxVertices, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_DeleteDynamicVb(GfxResourceID* vb) { D3D9_FreeResource(vb); }
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) {
|
||||||
|
IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb;
|
||||||
|
cc_result res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, gfx_stride);
|
||||||
|
if (res) Logger_Abort2(res, "D3D9_BindDynamicVb");
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
|
return D3D9_LockVb(vb, fmt, count, D3DLOCK_DISCARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_UnlockDynamicVb(GfxResourceID vb) {
|
||||||
|
Gfx_UnlockVb(vb);
|
||||||
|
Gfx_BindDynamicVb(vb); /* TODO: Inline this? */
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
|
||||||
|
int size = vCount * gfx_stride;
|
||||||
|
IDirect3DVertexBuffer9* buffer = (IDirect3DVertexBuffer9*)vb;
|
||||||
|
D3D9_SetVbData(buffer, vertices, size, D3DLOCK_DISCARD);
|
||||||
|
|
||||||
|
cc_result res = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, gfx_stride);
|
||||||
|
if (res) Logger_Abort2(res, "D3D9_SetDynamicVbData - Bind");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*-----------------------------------------------------Vertex rendering----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
||||||
cc_result res;
|
cc_result res;
|
||||||
if (fmt == gfx_format) return;
|
if (fmt == gfx_format) return;
|
||||||
@ -689,33 +723,6 @@ void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
|
||||||
*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------*
|
|
||||||
*#########################################################################################################################*/
|
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
|
||||||
if (Gfx.LostContext) return 0;
|
|
||||||
return D3D9_AllocVertexBuffer(fmt, maxVertices, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
|
||||||
return D3D9_LockVb(vb, fmt, count, D3DLOCK_DISCARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gfx_UnlockDynamicVb(GfxResourceID vb) {
|
|
||||||
Gfx_UnlockVb(vb);
|
|
||||||
Gfx_BindVb(vb); /* TODO: Inline this? */
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
|
|
||||||
int size = vCount * gfx_stride;
|
|
||||||
IDirect3DVertexBuffer9* buffer = (IDirect3DVertexBuffer9*)vb;
|
|
||||||
D3D9_SetVbData(buffer, vertices, size, D3DLOCK_DISCARD);
|
|
||||||
|
|
||||||
cc_result res = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, gfx_stride);
|
|
||||||
if (res) Logger_Abort2(res, "D3D9_SetDynamicVbData - Bind");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Matrices--------------------------------------------------------*
|
*---------------------------------------------------------Matrices--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
@ -127,11 +127,8 @@ void Gfx_DeleteIb(GfxResourceID* ib) { }
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*------------------------------------------------------Vertex buffers-----------------------------------------------------*
|
*------------------------------------------------------Vertex buffers-----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
void* data = memalign(16, count * strideSizes[fmt]);
|
return memalign(16, count * strideSizes[fmt]);
|
||||||
if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
|
|
||||||
return data;
|
|
||||||
//return Mem_Alloc(count, strideSizes[fmt], "gfx VB");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_BindVb(GfxResourceID vb) { gfx_vertices = vb; }
|
void Gfx_BindVb(GfxResourceID vb) { gfx_vertices = vb; }
|
||||||
@ -153,13 +150,12 @@ void Gfx_UnlockVb(GfxResourceID vb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
void* data = memalign(16, maxVertices * strideSizes[fmt]);
|
return memalign(16, maxVertices * strideSizes[fmt]);
|
||||||
if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
|
|
||||||
return data;
|
|
||||||
//return Mem_Alloc(maxVertices, strideSizes[fmt], "gfx VB");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) { Gfx_BindVb(vb); }
|
||||||
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
vb_size = count * strideSizes[fmt];
|
vb_size = count * strideSizes[fmt];
|
||||||
return vb;
|
return vb;
|
||||||
@ -283,12 +279,9 @@ static void ConvertTexture(cc_uint16* dst, struct Bitmap* bmp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
GLuint texId = gldcGenTexture();
|
GLuint texId = gldcGenTexture();
|
||||||
gldcBindTexture(texId);
|
gldcBindTexture(texId);
|
||||||
if (!Math_IsPowOf2(bmp->width) || !Math_IsPowOf2(bmp->height)) {
|
|
||||||
Logger_Abort("Textures must have power of two dimensions");
|
|
||||||
}
|
|
||||||
|
|
||||||
gldcAllocTexture(bmp->width, bmp->height, GL_RGBA,
|
gldcAllocTexture(bmp->width, bmp->height, GL_RGBA,
|
||||||
GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS);
|
GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS);
|
||||||
@ -299,6 +292,7 @@ GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipm
|
|||||||
ConvertTexture(pixels, bmp);
|
ConvertTexture(pixels, bmp);
|
||||||
return texId;
|
return texId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: struct GPUTexture ??
|
// TODO: struct GPUTexture ??
|
||||||
static void ConvertSubTexture(cc_uint16* dst, int texWidth, int texHeight,
|
static void ConvertSubTexture(cc_uint16* dst, int texWidth, int texHeight,
|
||||||
int originX, int originY,
|
int originX, int originY,
|
||||||
|
@ -136,7 +136,7 @@ static void ReorderPixels(CCTexture* tex, struct Bitmap* bmp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
if (bmp->width < 4 || bmp->height < 4) {
|
if (bmp->width < 4 || bmp->height < 4) {
|
||||||
Platform_LogConst("ERROR: Tried to create texture smaller than 4x4");
|
Platform_LogConst("ERROR: Tried to create texture smaller than 4x4");
|
||||||
return 0;
|
return 0;
|
||||||
@ -293,10 +293,8 @@ void Gfx_DeleteIb(GfxResourceID* ib) { }
|
|||||||
static cc_uint8* gfx_vertices;
|
static cc_uint8* gfx_vertices;
|
||||||
static int vb_size;
|
static int vb_size;
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
void* data = memalign(16, count * strideSizes[fmt]);
|
return memalign(16, count * strideSizes[fmt]);
|
||||||
if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_BindVb(GfxResourceID vb) { gfx_vertices = vb; }
|
void Gfx_BindVb(GfxResourceID vb) { gfx_vertices = vb; }
|
||||||
@ -318,12 +316,12 @@ void Gfx_UnlockVb(GfxResourceID vb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
void* data = memalign(16, maxVertices * strideSizes[fmt]);
|
return memalign(16, maxVertices * strideSizes[fmt]);
|
||||||
if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) { Gfx_BindVb(vb); }
|
||||||
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
vb_size = count * strideSizes[fmt];
|
vb_size = count * strideSizes[fmt];
|
||||||
return vb;
|
return vb;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#if defined CC_BUILD_GL && !defined CC_BUILD_GLMODERN
|
#if defined CC_BUILD_GL && !defined CC_BUILD_GLMODERN
|
||||||
#include "_GraphicsBase.h"
|
#include "_GraphicsBase.h"
|
||||||
#include "Errors.h"
|
#include "Errors.h"
|
||||||
#include "Logger.h"
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
/* The OpenGL backend is a bit of a mess, since it's really 2 backends in one:
|
/* The OpenGL backend is a bit of a mess, since it's really 2 backends in one:
|
||||||
* - OpenGL 1.1 (completely lacking GPU, fallbacks to say Windows built-in software rasteriser)
|
* - OpenGL 1.1 (completely lacking GPU, fallbacks to say Windows built-in software rasteriser)
|
||||||
@ -243,18 +242,19 @@ void Gfx_DeleteIb(GfxResourceID* ib) { }
|
|||||||
*------------------------------------------------------Vertex buffers-----------------------------------------------------*
|
*------------------------------------------------------Vertex buffers-----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
#ifndef CC_BUILD_GL11
|
#ifndef CC_BUILD_GL11
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
GfxResourceID id = _genBuffer();
|
GfxResourceID id = _genBuffer();
|
||||||
_glBindBuffer(GL_ARRAY_BUFFER, id);
|
_glBindBuffer(GL_ARRAY_BUFFER, id);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_BindVb(GfxResourceID vb) { _glBindBuffer(GL_ARRAY_BUFFER, vb); }
|
void Gfx_BindVb(GfxResourceID vb) {
|
||||||
|
_glBindBuffer(GL_ARRAY_BUFFER, vb);
|
||||||
|
}
|
||||||
|
|
||||||
void Gfx_DeleteVb(GfxResourceID* vb) {
|
void Gfx_DeleteVb(GfxResourceID* vb) {
|
||||||
GfxResourceID id = *vb;
|
GfxResourceID id = *vb;
|
||||||
if (!id) return;
|
if (id) _delBuffer(id);
|
||||||
_delBuffer(id);
|
|
||||||
*vb = 0;
|
*vb = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +266,9 @@ void Gfx_UnlockVb(GfxResourceID vb) {
|
|||||||
_glBufferData(GL_ARRAY_BUFFER, tmpSize, tmpData, GL_STATIC_DRAW);
|
_glBufferData(GL_ARRAY_BUFFER, tmpSize, tmpData, GL_STATIC_DRAW);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) { return glGenLists(1); }
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
|
return glGenLists(1);
|
||||||
|
}
|
||||||
void Gfx_BindVb(GfxResourceID vb) { activeList = (GLuint)vb; }
|
void Gfx_BindVb(GfxResourceID vb) { activeList = (GLuint)vb; }
|
||||||
|
|
||||||
void Gfx_DeleteVb(GfxResourceID* vb) {
|
void Gfx_DeleteVb(GfxResourceID* vb) {
|
||||||
@ -317,19 +319,25 @@ GfxResourceID Gfx_CreateVb2(void* vertices, VertexFormat fmt, int count) {
|
|||||||
*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------*
|
*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
#ifndef CC_BUILD_GL11
|
#ifndef CC_BUILD_GL11
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
GfxResourceID id;
|
GfxResourceID id = _genBuffer();
|
||||||
cc_uint32 size;
|
cc_uint32 size = maxVertices * strideSizes[fmt];
|
||||||
if (Gfx.LostContext) return 0;
|
|
||||||
|
|
||||||
id = _genBuffer();
|
|
||||||
size = maxVertices * strideSizes[fmt];
|
|
||||||
|
|
||||||
_glBindBuffer(GL_ARRAY_BUFFER, id);
|
_glBindBuffer(GL_ARRAY_BUFFER, id);
|
||||||
_glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
|
_glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) {
|
||||||
|
_glBindBuffer(GL_ARRAY_BUFFER, vb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_DeleteDynamicVb(GfxResourceID* vb) {
|
||||||
|
GfxResourceID id = *vb;
|
||||||
|
if (id) _delBuffer(id);
|
||||||
|
*vb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
return FastAllocTempMem(count * strideSizes[fmt]);
|
return FastAllocTempMem(count * strideSizes[fmt]);
|
||||||
}
|
}
|
||||||
@ -345,8 +353,8 @@ void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
|
|||||||
_glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices);
|
_glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
return (GfxResourceID)Mem_Alloc(maxVertices, strideSizes[fmt], "creating dynamic vb");
|
return (GfxResourceID)Mem_TryAlloc(maxVertices, strideSizes[fmt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_BindDynamicVb(GfxResourceID vb) {
|
void Gfx_BindDynamicVb(GfxResourceID vb) {
|
||||||
@ -370,6 +378,97 @@ void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*----------------------------------------------------------Drawing--------------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
#ifdef CC_BUILD_GL11
|
||||||
|
/* point to client side dynamic array */
|
||||||
|
#define VB_PTR ((cc_uint8*)dynamicListData)
|
||||||
|
#define IB_PTR gl_indices
|
||||||
|
#else
|
||||||
|
/* no client side array, use vertex buffer object */
|
||||||
|
#define VB_PTR 0
|
||||||
|
#define IB_PTR NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void GL_SetupVbColoured(void) {
|
||||||
|
_glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + 0));
|
||||||
|
_glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + 12));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GL_SetupVbTextured(void) {
|
||||||
|
_glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 0));
|
||||||
|
_glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 12));
|
||||||
|
_glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GL_SetupVbColoured_Range(int startVertex) {
|
||||||
|
cc_uint32 offset = startVertex * SIZEOF_VERTEX_COLOURED;
|
||||||
|
_glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + offset));
|
||||||
|
_glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + offset + 12));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GL_SetupVbTextured_Range(int startVertex) {
|
||||||
|
cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED;
|
||||||
|
_glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset));
|
||||||
|
_glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 12));
|
||||||
|
_glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
||||||
|
if (fmt == gfx_format) return;
|
||||||
|
gfx_format = fmt;
|
||||||
|
gfx_stride = strideSizes[fmt];
|
||||||
|
|
||||||
|
if (fmt == VERTEX_FORMAT_TEXTURED) {
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
gfx_setupVBFunc = GL_SetupVbTextured;
|
||||||
|
gfx_setupVBRangeFunc = GL_SetupVbTextured_Range;
|
||||||
|
} else {
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
gfx_setupVBFunc = GL_SetupVbColoured;
|
||||||
|
gfx_setupVBRangeFunc = GL_SetupVbColoured_Range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_DrawVb_Lines(int verticesCount) {
|
||||||
|
gfx_setupVBFunc();
|
||||||
|
glDrawArrays(GL_LINES, 0, verticesCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
|
||||||
|
#ifdef CC_BUILD_GL11
|
||||||
|
if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; }
|
||||||
|
#endif
|
||||||
|
gfx_setupVBRangeFunc(startVertex);
|
||||||
|
_glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_DrawVb_IndexedTris(int verticesCount) {
|
||||||
|
#ifdef CC_BUILD_GL11
|
||||||
|
if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; }
|
||||||
|
#endif
|
||||||
|
gfx_setupVBFunc();
|
||||||
|
_glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CC_BUILD_GL11
|
||||||
|
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { glCallList(activeList); }
|
||||||
|
#else
|
||||||
|
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
||||||
|
cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED;
|
||||||
|
_glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset));
|
||||||
|
_glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 12));
|
||||||
|
_glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 16));
|
||||||
|
_glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR);
|
||||||
|
}
|
||||||
|
#endif /* !CC_BUILD_GL11 */
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Textures--------------------------------------------------------*
|
*---------------------------------------------------------Textures--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
@ -612,95 +711,4 @@ static void GLBackend_Init(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
|
||||||
*----------------------------------------------------------Drawing--------------------------------------------------------*
|
|
||||||
*#########################################################################################################################*/
|
|
||||||
#ifdef CC_BUILD_GL11
|
|
||||||
/* point to client side dynamic array */
|
|
||||||
#define VB_PTR ((cc_uint8*)dynamicListData)
|
|
||||||
#define IB_PTR gl_indices
|
|
||||||
#else
|
|
||||||
/* no client side array, use vertex buffer object */
|
|
||||||
#define VB_PTR 0
|
|
||||||
#define IB_PTR NULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void GL_SetupVbColoured(void) {
|
|
||||||
_glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + 0));
|
|
||||||
_glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + 12));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void GL_SetupVbTextured(void) {
|
|
||||||
_glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 0));
|
|
||||||
_glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 12));
|
|
||||||
_glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void GL_SetupVbColoured_Range(int startVertex) {
|
|
||||||
cc_uint32 offset = startVertex * SIZEOF_VERTEX_COLOURED;
|
|
||||||
_glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + offset));
|
|
||||||
_glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + offset + 12));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void GL_SetupVbTextured_Range(int startVertex) {
|
|
||||||
cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED;
|
|
||||||
_glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset));
|
|
||||||
_glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 12));
|
|
||||||
_glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
|
||||||
if (fmt == gfx_format) return;
|
|
||||||
gfx_format = fmt;
|
|
||||||
gfx_stride = strideSizes[fmt];
|
|
||||||
|
|
||||||
if (fmt == VERTEX_FORMAT_TEXTURED) {
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
gfx_setupVBFunc = GL_SetupVbTextured;
|
|
||||||
gfx_setupVBRangeFunc = GL_SetupVbTextured_Range;
|
|
||||||
} else {
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
gfx_setupVBFunc = GL_SetupVbColoured;
|
|
||||||
gfx_setupVBRangeFunc = GL_SetupVbColoured_Range;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gfx_DrawVb_Lines(int verticesCount) {
|
|
||||||
gfx_setupVBFunc();
|
|
||||||
glDrawArrays(GL_LINES, 0, verticesCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
|
|
||||||
#ifdef CC_BUILD_GL11
|
|
||||||
if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; }
|
|
||||||
#endif
|
|
||||||
gfx_setupVBRangeFunc(startVertex);
|
|
||||||
_glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gfx_DrawVb_IndexedTris(int verticesCount) {
|
|
||||||
#ifdef CC_BUILD_GL11
|
|
||||||
if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; }
|
|
||||||
#endif
|
|
||||||
gfx_setupVBFunc();
|
|
||||||
_glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CC_BUILD_GL11
|
|
||||||
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { glCallList(activeList); }
|
|
||||||
#else
|
|
||||||
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
|
||||||
cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED;
|
|
||||||
_glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset));
|
|
||||||
_glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 12));
|
|
||||||
_glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 16));
|
|
||||||
_glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR);
|
|
||||||
}
|
|
||||||
#endif /* !CC_BUILD_GL11 */
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#if defined CC_BUILD_GL && defined CC_BUILD_GLMODERN
|
#if defined CC_BUILD_GL && defined CC_BUILD_GLMODERN
|
||||||
#include "_GraphicsBase.h"
|
#include "_GraphicsBase.h"
|
||||||
#include "Errors.h"
|
#include "Errors.h"
|
||||||
#include "Logger.h"
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
/* OpenGL 2.0 backend (alternative modern-ish backend) */
|
/* OpenGL 2.0 backend (alternative modern-ish backend) */
|
||||||
|
|
||||||
@ -125,16 +124,17 @@ void Gfx_DeleteIb(GfxResourceID* ib) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*------------------------------------------------------Vertex buffers-----------------------------------------------------*
|
*------------------------------------------------------Vertex buffers-----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
return GL_GenAndBind(GL_ARRAY_BUFFER);
|
return GL_GenAndBind(GL_ARRAY_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_BindVb(GfxResourceID vb) { glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vb); }
|
void Gfx_BindVb(GfxResourceID vb) {
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vb);
|
||||||
|
}
|
||||||
|
|
||||||
void Gfx_DeleteVb(GfxResourceID* vb) {
|
void Gfx_DeleteVb(GfxResourceID* vb) {
|
||||||
GLuint id = (GLuint)(*vb);
|
GLuint id = (GLuint)(*vb);
|
||||||
if (!id) return;
|
if (id) glDeleteBuffers(1, &id);
|
||||||
glDeleteBuffers(1, &id);
|
|
||||||
*vb = 0;
|
*vb = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,17 +150,24 @@ void Gfx_UnlockVb(GfxResourceID vb) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------*
|
*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
GLuint id;
|
GLuint id = GL_GenAndBind(GL_ARRAY_BUFFER);
|
||||||
cc_uint32 size;
|
cc_uint32 size = maxVertices * strideSizes[fmt];
|
||||||
if (Gfx.LostContext) return 0;
|
|
||||||
|
|
||||||
id = GL_GenAndBind(GL_ARRAY_BUFFER);
|
|
||||||
size = maxVertices * strideSizes[fmt];
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) {
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_DeleteDynamicVb(GfxResourceID* vb) {
|
||||||
|
GLuint id = (GLuint)(*vb);
|
||||||
|
if (id) glDeleteBuffers(1, &id);
|
||||||
|
*vb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
return FastAllocTempMem(count * strideSizes[fmt]);
|
return FastAllocTempMem(count * strideSizes[fmt]);
|
||||||
}
|
}
|
||||||
|
@ -494,10 +494,8 @@ void Gfx_DeleteIb(GfxResourceID* ib) { }
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*------------------------------------------------------Vertex buffers-----------------------------------------------------*
|
*------------------------------------------------------Vertex buffers-----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
void* data = rsxMemalign(128, count * strideSizes[fmt]);
|
return rsxMemalign(128, count * strideSizes[fmt]);
|
||||||
if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_BindVb(GfxResourceID vb) {
|
void Gfx_BindVb(GfxResourceID vb) {
|
||||||
@ -536,12 +534,12 @@ void Gfx_UnlockVb(GfxResourceID vb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices)
|
||||||
void* data = rsxMemalign(128, maxVertices * strideSizes[fmt]);
|
return rsxMemalign(128, maxVertices * strideSizes[fmt]);
|
||||||
if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) { Gfx_BindVb(vb); }
|
||||||
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
vb_size = count * strideSizes[fmt];
|
vb_size = count * strideSizes[fmt];
|
||||||
return vb;
|
return vb;
|
||||||
@ -568,7 +566,7 @@ typedef struct CCTexture_ {
|
|||||||
cc_uint32 pixels[];
|
cc_uint32 pixels[];
|
||||||
} CCTexture;
|
} CCTexture;
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
int size = bmp->width * bmp->height * 4;
|
int size = bmp->width * bmp->height * 4;
|
||||||
CCTexture* tex = (CCTexture*)rsxMemalign(128, 128 + size);
|
CCTexture* tex = (CCTexture*)rsxMemalign(128, 128 + size);
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ typedef struct CCTexture_ {
|
|||||||
cc_uint32 pixels[];
|
cc_uint32 pixels[];
|
||||||
} CCTexture;
|
} CCTexture;
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
int size = bmp->width * bmp->height * 4;
|
int size = bmp->width * bmp->height * 4;
|
||||||
CCTexture* tex = (CCTexture*)memalign(16, 16 + size);
|
CCTexture* tex = (CCTexture*)memalign(16, 16 + size);
|
||||||
|
|
||||||
@ -284,11 +284,8 @@ void Gfx_BindIb(GfxResourceID ib) { }
|
|||||||
void Gfx_DeleteIb(GfxResourceID* ib) { }
|
void Gfx_DeleteIb(GfxResourceID* ib) { }
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
void* data = memalign(16, count * strideSizes[fmt]);
|
return memalign(16, count * strideSizes[fmt]);
|
||||||
if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
|
|
||||||
return data;
|
|
||||||
//return Mem_Alloc(count, strideSizes[fmt], "gfx VB");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_BindVb(GfxResourceID vb) { gfx_vertices = vb; }
|
void Gfx_BindVb(GfxResourceID vb) { gfx_vertices = vb; }
|
||||||
@ -310,13 +307,12 @@ void Gfx_UnlockVb(GfxResourceID vb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
void* data = memalign(16, maxVertices * strideSizes[fmt]);
|
return memalign(16, maxVertices * strideSizes[fmt]);
|
||||||
if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
|
|
||||||
return data;
|
|
||||||
//return Mem_Alloc(maxVertices, strideSizes[fmt], "gfx VB");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) { Gfx_BindVb(vb); }
|
||||||
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
vb_size = count * strideSizes[fmt];
|
vb_size = count * strideSizes[fmt];
|
||||||
return vb;
|
return vb;
|
||||||
|
@ -661,7 +661,7 @@ static void GPUTextures_DeleteUnreferenced(void) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Textures--------------------------------------------------------*
|
*---------------------------------------------------------Textures--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
int size = bmp->width * bmp->height * 4;
|
int size = bmp->width * bmp->height * 4;
|
||||||
struct GPUTexture* tex = GPUTexture_Alloc(size);
|
struct GPUTexture* tex = GPUTexture_Alloc(size);
|
||||||
Mem_Copy(tex->data, bmp->scan0, size);
|
Mem_Copy(tex->data, bmp->scan0, size);
|
||||||
@ -891,7 +891,7 @@ void Gfx_DeleteIb(GfxResourceID* ib) { GPUBuffer_Unref(ib); }
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*-------------------------------------------------------Vertex buffers----------------------------------------------------*
|
*-------------------------------------------------------Vertex buffers----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
return GPUBuffer_Alloc(count * strideSizes[fmt]);
|
return GPUBuffer_Alloc(count * strideSizes[fmt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,10 +911,12 @@ void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
|||||||
void Gfx_UnlockVb(GfxResourceID vb) { Gfx_BindVb(vb); }
|
void Gfx_UnlockVb(GfxResourceID vb) { Gfx_BindVb(vb); }
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
return GPUBuffer_Alloc(maxVertices * strideSizes[fmt]);
|
return GPUBuffer_Alloc(maxVertices * strideSizes[fmt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) { Gfx_BindVb(vb); }
|
||||||
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
struct GPUBuffer* buffer = (struct GPUBuffer*)vb;
|
struct GPUBuffer* buffer = (struct GPUBuffer*)vb;
|
||||||
return buffer->data;
|
return buffer->data;
|
||||||
|
@ -198,7 +198,7 @@ static void ConvertTexture(cc_uint32* dst, struct Bitmap* bmp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
int size = 16 + bmp->width * bmp->height * 4;
|
int size = 16 + bmp->width * bmp->height * 4;
|
||||||
CCTexture* tex = MmAllocateContiguousMemoryEx(size, 0, MAX_RAM_ADDR, 0, 0x404);
|
CCTexture* tex = MmAllocateContiguousMemoryEx(size, 0, MAX_RAM_ADDR, 0, 0x404);
|
||||||
|
|
||||||
@ -394,10 +394,7 @@ static cc_uint8* gfx_vertices;
|
|||||||
static cc_uint16* gfx_indices;
|
static cc_uint16* gfx_indices;
|
||||||
|
|
||||||
static void* AllocBuffer(int count, int elemSize) {
|
static void* AllocBuffer(int count, int elemSize) {
|
||||||
void* ptr = MmAllocateContiguousMemoryEx(count * elemSize, 0, MAX_RAM_ADDR, 0, PAGE_WRITECOMBINE | PAGE_READWRITE);
|
return MmAllocateContiguousMemoryEx(count * elemSize, 0, MAX_RAM_ADDR, 0, PAGE_WRITECOMBINE | PAGE_READWRITE);
|
||||||
|
|
||||||
if (!ptr) Logger_Abort("Failed to allocate memory for buffer");
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FreeBuffer(GfxResourceID* buffer) {
|
static void FreeBuffer(GfxResourceID* buffer) {
|
||||||
@ -409,6 +406,8 @@ static void FreeBuffer(GfxResourceID* buffer) {
|
|||||||
|
|
||||||
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
|
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
|
||||||
void* ib = AllocBuffer(count, sizeof(cc_uint16));
|
void* ib = AllocBuffer(count, sizeof(cc_uint16));
|
||||||
|
if (!ib) Logger_Abort("Failed to allocate memory for index buffer");
|
||||||
|
|
||||||
fillFunc(ib, count, obj);
|
fillFunc(ib, count, obj);
|
||||||
return ib;
|
return ib;
|
||||||
}
|
}
|
||||||
@ -418,7 +417,7 @@ void Gfx_BindIb(GfxResourceID ib) { gfx_indices = ib; }
|
|||||||
void Gfx_DeleteIb(GfxResourceID* ib) { FreeBuffer(ib); }
|
void Gfx_DeleteIb(GfxResourceID* ib) { FreeBuffer(ib); }
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
return AllocBuffer(count, strideSizes[fmt]);
|
return AllocBuffer(count, strideSizes[fmt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,10 +449,12 @@ void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) { return vb; }
|
|||||||
void Gfx_UnlockVb(GfxResourceID vb) { }
|
void Gfx_UnlockVb(GfxResourceID vb) { }
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
return AllocBuffer(maxVertices, strideSizes[fmt]);
|
return AllocBuffer(maxVertices, strideSizes[fmt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_BindDynamicVb(GfxResourceID vb) { Gfx_BindVb(vb); }
|
||||||
|
|
||||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
return vb;
|
return vb;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,9 @@ void Model_SetupState(struct Model* model, struct Entity* e) {
|
|||||||
|
|
||||||
void Model_UpdateVB(void) {
|
void Model_UpdateVB(void) {
|
||||||
struct Model* model = Models.Active;
|
struct Model* model = Models.Active;
|
||||||
Gfx_UpdateDynamicVb_IndexedTris(Models.Vb, Models.Vertices, model->index);
|
|
||||||
|
Gfx_SetDynamicVbData(Models.Vb, Models.Vertices, model->index);
|
||||||
|
Gfx_DrawVb_IndexedTris(model->index);
|
||||||
model->index = 0;
|
model->index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,6 @@ static int selections_count;
|
|||||||
static struct SelectionBox selections_list[SELECTIONS_MAX];
|
static struct SelectionBox selections_list[SELECTIONS_MAX];
|
||||||
static cc_uint8 selections_ids[SELECTIONS_MAX];
|
static cc_uint8 selections_ids[SELECTIONS_MAX];
|
||||||
static GfxResourceID selections_VB, selections_LineVB;
|
static GfxResourceID selections_VB, selections_LineVB;
|
||||||
static cc_bool selections_used;
|
|
||||||
|
|
||||||
void Selections_Add(cc_uint8 id, const IVec3* p1, const IVec3* p2, PackedCol color) {
|
void Selections_Add(cc_uint8 id, const IVec3* p1, const IVec3* p2, PackedCol color) {
|
||||||
struct SelectionBox sel;
|
struct SelectionBox sel;
|
||||||
@ -142,10 +141,9 @@ static void Selections_ContextLost(void* obj) {
|
|||||||
Gfx_DeleteDynamicVb(&selections_LineVB);
|
Gfx_DeleteDynamicVb(&selections_LineVB);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Selections_ContextRecreated(void* obj) {
|
static void AllocateVertexBuffers(void) {
|
||||||
if (!selections_used) return;
|
selections_VB = Gfx_CreateDynamicVb(VERTEX_FORMAT_COLOURED, SELECTIONS_MAX_VERTICES);
|
||||||
Gfx_RecreateDynamicVb(&selections_VB, VERTEX_FORMAT_COLOURED, SELECTIONS_MAX_VERTICES);
|
selections_LineVB = Gfx_CreateDynamicVb(VERTEX_FORMAT_COLOURED, SELECTIONS_MAX_VERTICES);
|
||||||
Gfx_RecreateDynamicVb(&selections_LineVB, VERTEX_FORMAT_COLOURED, SELECTIONS_MAX_VERTICES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Selections_QuickSort(int left, int right) {
|
static void Selections_QuickSort(int left, int right) {
|
||||||
@ -181,10 +179,9 @@ void Selections_Render(void) {
|
|||||||
}
|
}
|
||||||
Selections_QuickSort(0, selections_count - 1);
|
Selections_QuickSort(0, selections_count - 1);
|
||||||
|
|
||||||
if (!selections_VB) { /* lazy init as most servers don't use this */
|
/* lazy init as most servers don't use this */
|
||||||
selections_used = true;
|
if (!selections_VB) AllocateVertexBuffers();
|
||||||
Selections_ContextRecreated(NULL);
|
|
||||||
}
|
|
||||||
count = selections_count * SELECTIONS_VERTICES;
|
count = selections_count * SELECTIONS_VERTICES;
|
||||||
Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED);
|
Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED);
|
||||||
|
|
||||||
@ -216,7 +213,6 @@ void Selections_Render(void) {
|
|||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static void OnInit(void) {
|
static void OnInit(void) {
|
||||||
Event_Register_(&GfxEvents.ContextLost, NULL, Selections_ContextLost);
|
Event_Register_(&GfxEvents.ContextLost, NULL, Selections_ContextLost);
|
||||||
Event_Register_(&GfxEvents.ContextRecreated, NULL, Selections_ContextRecreated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnReset(void) { selections_count = 0; }
|
static void OnReset(void) { selections_count = 0; }
|
||||||
|
@ -102,17 +102,12 @@ static void Gfx_DoMipmaps(int x, int y, struct Bitmap* bmp, int rowWidth, cc_boo
|
|||||||
if (prev != bmp->scan0) Mem_Free(prev);
|
if (prev != bmp->scan0) Mem_Free(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
GLuint texId;
|
GLuint texId;
|
||||||
glGenTextures(1, &texId);
|
glGenTextures(1, &texId);
|
||||||
glBindTexture(GL_TEXTURE_2D, texId);
|
glBindTexture(GL_TEXTURE_2D, texId);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
if (!Math_IsPowOf2(bmp->width) || !Math_IsPowOf2(bmp->height)) {
|
|
||||||
Logger_Abort("Textures must have power of two dimensions");
|
|
||||||
}
|
|
||||||
if (Gfx.LostContext) return 0;
|
|
||||||
|
|
||||||
if (mipmaps) {
|
if (mipmaps) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
|
||||||
if (customMipmapsLevels) {
|
if (customMipmapsLevels) {
|
||||||
@ -163,8 +158,7 @@ void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, struct Bitmap* par
|
|||||||
|
|
||||||
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
||||||
GLuint id = (GLuint)(*texId);
|
GLuint id = (GLuint)(*texId);
|
||||||
if (!id) return;
|
if (id) glDeleteTextures(1, &id);
|
||||||
glDeleteTextures(1, &id);
|
|
||||||
*texId = 0;
|
*texId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,14 @@
|
|||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "Bitmap.h"
|
#include "Bitmap.h"
|
||||||
#include "Chat.h"
|
#include "Chat.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
struct _GfxData Gfx;
|
struct _GfxData Gfx;
|
||||||
GfxResourceID Gfx_defaultIb;
|
GfxResourceID Gfx_defaultIb;
|
||||||
GfxResourceID Gfx_quadVb, Gfx_texVb;
|
static GfxResourceID Gfx_quadVb, Gfx_texVb;
|
||||||
const cc_string Gfx_LowPerfMessage = String_FromConst("&eRunning in reduced performance mode (game minimised or hidden)");
|
const cc_string Gfx_LowPerfMessage = String_FromConst("&eRunning in reduced performance mode (game minimised or hidden)");
|
||||||
|
|
||||||
static const int strideSizes[2] = { SIZEOF_VERTEX_COLOURED, SIZEOF_VERTEX_TEXTURED };
|
static const int strideSizes[] = { SIZEOF_VERTEX_COLOURED, SIZEOF_VERTEX_TEXTURED };
|
||||||
/* Whether mipmaps must be created for all dimensions down to 1x1 or not */
|
/* Whether mipmaps must be created for all dimensions down to 1x1 or not */
|
||||||
static cc_bool customMipmapsLevels;
|
static cc_bool customMipmapsLevels;
|
||||||
|
|
||||||
@ -142,44 +143,47 @@ void* Gfx_RecreateAndLockVb(GfxResourceID* vb, VertexFormat fmt, int count) {
|
|||||||
return Gfx_LockVb(*vb, fmt, count);
|
return Gfx_LockVb(*vb, fmt, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_UpdateDynamicVb_IndexedTris(GfxResourceID vb, void* vertices, int vCount) {
|
|
||||||
Gfx_SetDynamicVbData(vb, vertices, vCount);
|
|
||||||
Gfx_DrawVb_IndexedTris(vCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef CC_BUILD_3DS
|
#ifndef CC_BUILD_3DS
|
||||||
void Gfx_Draw2DFlat(int x, int y, int width, int height, PackedCol color) {
|
void Gfx_Draw2DFlat(int x, int y, int width, int height, PackedCol color) {
|
||||||
struct VertexColoured verts[4];
|
struct VertexColoured* v;
|
||||||
struct VertexColoured* v = verts;
|
|
||||||
|
Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED);
|
||||||
|
v = (struct VertexColoured*)Gfx_LockDynamicVb(Gfx_quadVb, VERTEX_FORMAT_COLOURED, 4);
|
||||||
|
|
||||||
v->X = (float)x; v->Y = (float)y; v->Z = 0; v->Col = color; v++;
|
v->X = (float)x; v->Y = (float)y; v->Z = 0; v->Col = color; v++;
|
||||||
v->X = (float)(x + width); v->Y = (float)y; v->Z = 0; v->Col = color; v++;
|
v->X = (float)(x + width); v->Y = (float)y; v->Z = 0; v->Col = color; v++;
|
||||||
v->X = (float)(x + width); v->Y = (float)(y + height); v->Z = 0; v->Col = color; v++;
|
v->X = (float)(x + width); v->Y = (float)(y + height); v->Z = 0; v->Col = color; v++;
|
||||||
v->X = (float)x; v->Y = (float)(y + height); v->Z = 0; v->Col = color; v++;
|
v->X = (float)x; v->Y = (float)(y + height); v->Z = 0; v->Col = color; v++;
|
||||||
|
|
||||||
Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED);
|
Gfx_UnlockDynamicVb(Gfx_quadVb);
|
||||||
Gfx_UpdateDynamicVb_IndexedTris(Gfx_quadVb, verts, 4);
|
Gfx_DrawVb_IndexedTris(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_Draw2DGradient(int x, int y, int width, int height, PackedCol top, PackedCol bottom) {
|
void Gfx_Draw2DGradient(int x, int y, int width, int height, PackedCol top, PackedCol bottom) {
|
||||||
struct VertexColoured verts[4];
|
struct VertexColoured* v;
|
||||||
struct VertexColoured* v = verts;
|
|
||||||
|
Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED);
|
||||||
|
v = (struct VertexColoured*)Gfx_LockDynamicVb(Gfx_quadVb, VERTEX_FORMAT_COLOURED, 4);
|
||||||
|
|
||||||
v->X = (float)x; v->Y = (float)y; v->Z = 0; v->Col = top; v++;
|
v->X = (float)x; v->Y = (float)y; v->Z = 0; v->Col = top; v++;
|
||||||
v->X = (float)(x + width); v->Y = (float)y; v->Z = 0; v->Col = top; v++;
|
v->X = (float)(x + width); v->Y = (float)y; v->Z = 0; v->Col = top; v++;
|
||||||
v->X = (float)(x + width); v->Y = (float)(y + height); v->Z = 0; v->Col = bottom; v++;
|
v->X = (float)(x + width); v->Y = (float)(y + height); v->Z = 0; v->Col = bottom; v++;
|
||||||
v->X = (float)x; v->Y = (float)(y + height); v->Z = 0; v->Col = bottom; v++;
|
v->X = (float)x; v->Y = (float)(y + height); v->Z = 0; v->Col = bottom; v++;
|
||||||
|
|
||||||
Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED);
|
Gfx_UnlockDynamicVb(Gfx_quadVb);
|
||||||
Gfx_UpdateDynamicVb_IndexedTris(Gfx_quadVb, verts, 4);
|
Gfx_DrawVb_IndexedTris(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_Draw2DTexture(const struct Texture* tex, PackedCol color) {
|
void Gfx_Draw2DTexture(const struct Texture* tex, PackedCol color) {
|
||||||
struct VertexTextured texVerts[4];
|
struct VertexTextured* ptr;
|
||||||
struct VertexTextured* ptr = texVerts;
|
|
||||||
Gfx_Make2DQuad(tex, color, &ptr);
|
|
||||||
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
||||||
Gfx_UpdateDynamicVb_IndexedTris(Gfx_texVb, texVerts, 4);
|
ptr = (struct VertexTextured*)Gfx_LockDynamicVb(Gfx_texVb, VERTEX_FORMAT_TEXTURED, 4);
|
||||||
|
|
||||||
|
Gfx_Make2DQuad(tex, color, &ptr);
|
||||||
|
|
||||||
|
Gfx_UnlockDynamicVb(Gfx_texVb);
|
||||||
|
Gfx_DrawVb_IndexedTris(4);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -333,6 +337,17 @@ static CC_NOINLINE int CalcMipmapsLevels(int width, int height) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps);
|
||||||
|
|
||||||
|
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
|
if (!Math_IsPowOf2(bmp->width) || !Math_IsPowOf2(bmp->height)) {
|
||||||
|
Logger_Abort("Textures must have power of two dimensions");
|
||||||
|
}
|
||||||
|
if (Gfx.LostContext) return 0;
|
||||||
|
|
||||||
|
return Gfx_AllocTexture(bmp, flags, mipmaps);
|
||||||
|
}
|
||||||
|
|
||||||
void Texture_Render(const struct Texture* tex) {
|
void Texture_Render(const struct Texture* tex) {
|
||||||
Gfx_BindTexture(tex->ID);
|
Gfx_BindTexture(tex->ID);
|
||||||
Gfx_Draw2DTexture(tex, PACKEDCOL_WHITE);
|
Gfx_Draw2DTexture(tex, PACKEDCOL_WHITE);
|
||||||
@ -344,6 +359,37 @@ void Texture_RenderShaded(const struct Texture* tex, PackedCol shadeColor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*------------------------------------------------------Vertex buffers-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
static GfxResourceID Gfx_AllocStaticVb( VertexFormat fmt, int count);
|
||||||
|
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices);
|
||||||
|
|
||||||
|
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
|
||||||
|
GfxResourceID vb;
|
||||||
|
/* if (Gfx.LostContext) return 0; TODO check this ???? probably breaks things */
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if ((vb = Gfx_AllocStaticVb(fmt, count))) return vb;
|
||||||
|
|
||||||
|
if (!Game_ReduceVRAM()) Logger_Abort("Out of video memory! (allocating static VB)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||||
|
GfxResourceID vb;
|
||||||
|
if (Gfx.LostContext) return 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if ((vb = Gfx_AllocDynamicVb(fmt, maxVertices))) return vb;
|
||||||
|
|
||||||
|
if (!Game_ReduceVRAM()) Logger_Abort("Out of video memory! (allocating dynamic VB)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*----------------------------------------------------Graphics component---------------------------------------------------*
|
*----------------------------------------------------Graphics component---------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user