This commit is contained in:
Luke Benstead 2021-04-09 15:24:47 +00:00
parent 03694d85bf
commit fe616028bb
66 changed files with 1950 additions and 631 deletions

3
.gitignore vendored
View File

@ -6,4 +6,5 @@
*.img
dc-build.sh
.buildconfig
GL/version.h
build/*
builddir/*

View File

@ -6,5 +6,18 @@ build:sh4-gcc:
image: kazade/dreamcast-sdk
script:
- source /etc/bash.bashrc
- make clean
- make samples
- mkdir builddir
- cd builddir
- cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/Dreamcast.cmake ..
- make
build:x86-gcc:
stage: build
image: fedora:33
before_script:
- sudo dnf install -y cmake gcc gcc-c++ SDL2-devel.i686 glibc-devel.i686
script:
- mkdir builddir
- cd builddir
- cmake ..
- make

146
CMakeLists.txt Normal file
View File

@ -0,0 +1,146 @@
cmake_minimum_required(VERSION 3.0)
project(GLdc)
# set the default backend
if(PLATFORM_DREAMCAST)
set(BACKEND "kospvr" CACHE STRING "Backend to use")
else()
set(BACKEND "software" CACHE STRING "Backend to use")
endif()
# List of possible backends
set_property(CACHE BACKEND PROPERTY STRINGS kospvr software)
message("\nCompiling using backend: ${BACKEND}\n")
string(TOUPPER ${BACKEND} BACKEND_UPPER)
add_definitions(-DBACKEND_${BACKEND_UPPER})
set(CMAKE_C_STANDARD 99)
include_directories(include)
if(NOT PLATFORM_DREAMCAST)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
endif()
set(
SOURCES
containers/aligned_vector.c
containers/named_array.c
containers/stack.c
GL/clip.c
GL/draw.c
GL/error.c
GL/flush.c
GL/fog.c
GL/framebuffer.c
GL/glu.c
GL/immediate.c
GL/lighting.c
GL/matrix.c
GL/profiler.c
GL/state.c
GL/texture.c
GL/util.c
GL/yalloc/yalloc.c
${CMAKE_CURRENT_BINARY_DIR}/version.c
)
execute_process(
COMMAND git describe --abbrev=4 --dirty --always --tags
OUTPUT_VARIABLE GLDC_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
configure_file(GL/version.c.in ${CMAKE_CURRENT_BINARY_DIR}/version.c)
if(PLATFORM_DREAMCAST)
set(SOURCES ${SOURCES} GL/platforms/sh4.c)
else()
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
link_libraries(${SDL2_LIBRARIES})
set(
SOURCES
${SOURCES}
GL/platforms/software.c
GL/platforms/software/edge_equation.c
GL/platforms/software/parameter_equation.c
)
endif()
add_library(GLdc STATIC ${SOURCES})
link_libraries(m)
include_directories(include)
link_libraries(GLdc)
function(gen_sample sample)
set(SAMPLE_SRCS ${ARGN})
set(GENROMFS "$ENV{KOS_BASE}/utils/genromfs/genromfs")
set(BIN2O $ENV{KOS_BASE}/utils/bin2o/bin2o)
set(ROMDISK_IMG "${CMAKE_SOURCE_DIR}/samples/${sample}/romdisk.img")
set(ROMDISK_O "${CMAKE_SOURCE_DIR}/samples/${sample}/romdisk.o")
set(ROMDISK_DIR "${CMAKE_SOURCE_DIR}/samples/${sample}/romdisk")
add_executable(${sample} ${SAMPLE_SRCS})
if(PLATFORM_DREAMCAST)
if(EXISTS "${CMAKE_SOURCE_DIR}/samples/${sample}/romdisk")
message("Generating romdisk for sample: ${sample}")
add_custom_command(
OUTPUT ${ROMDISK_IMG}
COMMAND ${GENROMFS} -f ${ROMDISK_IMG} -d ${ROMDISK_DIR} -v
)
add_custom_command(
OUTPUT ${ROMDISK_O}
COMMAND ${BIN2O} romdisk.img romdisk romdisk.o
DEPENDS ${ROMDISK_IMG}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/samples/${sample}"
)
add_custom_target(${sample}_romdisk DEPENDS ${ROMDISK_O})
add_dependencies(${sample} ${sample}_romdisk)
target_link_libraries(${sample} ${ROMDISK_O})
else()
message("No such romdisk for sample: ${sample} at 'samples/${sample}/romdisk'")
endif()
endif()
endfunction()
gen_sample(blend_test samples/blend_test/main.c)
gen_sample(depth_funcs samples/depth_funcs/main.c)
gen_sample(depth_funcs_alpha_testing samples/depth_funcs_alpha_testing/main.c samples/depth_funcs_alpha_testing/gl_png.c)
gen_sample(depth_funcs_ortho samples/depth_funcs_ortho/main.c)
gen_sample(lerabot01 samples/lerabot01/main.c)
gen_sample(lerabot_blend_test samples/lerabot_blend_test/main.c)
gen_sample(lights samples/lights/main.c)
gen_sample(mipmap samples/mipmap/main.c)
gen_sample(multitexture_arrays samples/multitexture_arrays/main.c samples/multitexture_arrays/pvr-texture.c)
gen_sample(nehe02 samples/nehe02/main.c)
gen_sample(nehe02de samples/nehe02de/main.c)
gen_sample(nehe02va samples/nehe02va/main.c)
gen_sample(nehe03 samples/nehe03/main.c)
gen_sample(nehe04 samples/nehe04/main.c)
gen_sample(nehe05 samples/nehe05/main.c)
gen_sample(nehe06 samples/nehe06/main.c)
gen_sample(nehe06_vq samples/nehe06_vq/main.c)
gen_sample(ortho2d samples/ortho2d/main.c)
gen_sample(paletted samples/paletted/main.c)
gen_sample(paletted_pcx samples/paletted_pcx/main.c)
gen_sample(polygon_offset samples/polygon_offset/main.c)
gen_sample(terrain samples/terrain/main.c)
gen_sample(zclip samples/zclip/main.c)
gen_sample(zclip_triangle samples/zclip_triangle/main.c)
gen_sample(zclip_trianglestrip samples/zclip_trianglestrip/main.c)
if(PLATFORM_DREAMCAST)
gen_sample(polymark samples/polymark/main.c)
gen_sample(quadmark samples/quadmark/main.c)
gen_sample(trimark samples/trimark/main.c)
endif()

View File

@ -4,14 +4,10 @@
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <dc/vec3f.h>
#include "../include/gl.h"
#include "../include/glext.h"
#include "private.h"
#include "profiler.h"
#include "sh4_math.h"
#include "platform.h"
static AttribPointer VERTEX_POINTER;
static AttribPointer UV_POINTER;
@ -439,7 +435,7 @@ GL_FORCE_INLINE void transformNormalToEyeSpace(GLfloat* normal) {
mat_trans_normal3(normal[0], normal[1], normal[2]);
}
PVRHeader* _glSubmissionTargetHeader(SubmissionTarget* target) {
PolyHeader *_glSubmissionTargetHeader(SubmissionTarget* target) {
assert(target->header_offset < target->output->vector.size);
return aligned_vector_at(&target->output->vector, target->header_offset);
}
@ -458,7 +454,7 @@ static inline void genTriangles(Vertex* output, GLuint count) {
GLuint i;
for(i = 0; i < count; i += 3) {
it->flags = PVR_CMD_VERTEX_EOL;
it->flags = GPU_CMD_VERTEX_EOL;
it += 3;
}
}
@ -468,13 +464,13 @@ static inline void genQuads(Vertex* output, GLuint count) {
GLuint i;
for(i = 0; i < count; i += 4) {
swapVertex((final - 1), final);
final->flags = PVR_CMD_VERTEX_EOL;
final->flags = GPU_CMD_VERTEX_EOL;
final += 4;
}
}
static void genTriangleStrip(Vertex* output, GLuint count) {
output[count - 1].flags = PVR_CMD_VERTEX_EOL;
output[count - 1].flags = GPU_CMD_VERTEX_EOL;
}
static void genTriangleFan(Vertex* output, GLuint count) {
@ -486,7 +482,7 @@ static void genTriangleFan(Vertex* output, GLuint count) {
GLubyte i = count - 2;
while(i--) {
*dst = *src--;
(*dst--).flags = PVR_CMD_VERTEX_EOL;
(*dst--).flags = GPU_CMD_VERTEX_EOL;
*dst-- = *src;
*dst-- = *output;
}
@ -655,7 +651,7 @@ GL_FORCE_INLINE void _readSTData(const GLuint first, const GLuint count, VertexE
const GLubyte ststride = (ST_POINTER.stride) ? ST_POINTER.stride : ST_POINTER.size * byte_size(ST_POINTER.type);
const void* stptr = ((GLubyte*) ST_POINTER.ptr + (first * ststride));
ReadUVFunc func = calcReadUVFunc();
ReadUVFunc func = calcReadSTFunc();
GLubyte* out = (GLubyte*) extra[0].st;
ITERATE(count) {
@ -697,7 +693,8 @@ GL_FORCE_INLINE void _readNormalData(const GLuint first, const GLuint count, Ver
}
GL_FORCE_INLINE void _readDiffuseData(const GLuint first, const GLuint count, Vertex* output) {
const GLuint cstride = (DIFFUSE_POINTER.stride) ? DIFFUSE_POINTER.stride : DIFFUSE_POINTER.size * byte_size(DIFFUSE_POINTER.type);
const GLuint size = (DIFFUSE_POINTER.size == GL_BGRA) ? 4 : DIFFUSE_POINTER.size;
const GLuint cstride = (DIFFUSE_POINTER.stride) ? DIFFUSE_POINTER.stride : size * byte_size(DIFFUSE_POINTER.type);
const GLubyte* cptr = ((GLubyte*) DIFFUSE_POINTER.ptr) + (first * cstride);
ReadDiffuseFunc func = calcReadDiffuseFunc();
@ -765,7 +762,7 @@ static void generateElements(
st_func(st, (GLubyte*) ve->st);
normal_func(nxyz, (GLubyte*) ve->nxyz);
output->flags = PVR_CMD_VERTEX;
output->flags = GPU_CMD_VERTEX;
++output;
++ve;
}
@ -786,7 +783,7 @@ static void generate(SubmissionTarget* target, const GLenum mode, const GLsizei
const GLubyte* pos = VERTEX_POINTER.ptr;
Vertex* it = start;
ITERATE(count) {
it->flags = PVR_CMD_VERTEX;
it->flags = GPU_CMD_VERTEX;
memcpy(it->xyz, pos, FAST_PATH_BYTE_SIZE);
it++;
pos += VERTEX_POINTER.stride;
@ -799,7 +796,7 @@ static void generate(SubmissionTarget* target, const GLenum mode, const GLsizei
Vertex* it = _glSubmissionTargetStart(target);
ITERATE(count) {
it->flags = PVR_CMD_VERTEX;
it->flags = GPU_CMD_VERTEX;
++it;
}
}
@ -843,25 +840,7 @@ static void transform(SubmissionTarget* target) {
_glApplyRenderMatrix(); /* Apply the Render Matrix Stack */
ITERATE(target->count) {
register float __x __asm__("fr12") = (vertex->xyz[0]);
register float __y __asm__("fr13") = (vertex->xyz[1]);
register float __z __asm__("fr14") = (vertex->xyz[2]);
register float __w __asm__("fr15") = (vertex->w);
__asm__ __volatile__(
"fldi1 fr15\n"
"ftrv xmtrx,fv12\n"
: "=f" (__x), "=f" (__y), "=f" (__z), "=f" (__w)
: "0" (__x), "1" (__y), "2" (__z), "3" (__w)
);
vertex->xyz[0] = __x;
vertex->xyz[1] = __y;
vertex->xyz[2] = __z;
vertex->w = __w;
++vertex;
}
TransformVertices(vertex, target->count);
}
static void clip(SubmissionTarget* target) {
@ -875,14 +854,17 @@ static void clip(SubmissionTarget* target) {
}
static void mat_transform3(const float* xyz, const float* xyzOut, const uint32_t count, const uint32_t inStride, const uint32_t outStride) {
uint8_t* dataIn = (uint8_t*) xyz;
const uint8_t* dataIn = (const uint8_t*) xyz;
uint8_t* dataOut = (uint8_t*) xyzOut;
ITERATE(count) {
float* in = (float*) dataIn;
const float* in = (const float*) dataIn;
float* out = (float*) dataOut;
mat_trans_single3_nodiv_nomod(in[0], in[1], in[2], out[0], out[1], out[2]);
TransformVec3NoMod(
in,
out
);
dataIn += inStride;
dataOut += outStride;
@ -890,14 +872,14 @@ static void mat_transform3(const float* xyz, const float* xyzOut, const uint32_t
}
static void mat_transform_normal3(const float* xyz, const float* xyzOut, const uint32_t count, const uint32_t inStride, const uint32_t outStride) {
uint8_t* dataIn = (uint8_t*) xyz;
const uint8_t* dataIn = (const uint8_t*) xyz;
uint8_t* dataOut = (uint8_t*) xyzOut;
ITERATE(count) {
float* in = (float*) dataIn;
const float* in = (const float*) dataIn;
float* out = (float*) dataOut;
mat_trans_normal3_nomod(in[0], in[1], in[2], out[0], out[1], out[2]);
TransformNormalNoMod(in, out);
dataIn += inStride;
dataOut += outStride;
@ -930,8 +912,8 @@ static void light(SubmissionTarget* target) {
_glPerformLighting(vertex, ES, target->count);
}
#define PVR_MIN_Z 0.2f
#define PVR_MAX_Z 1.0 + PVR_MIN_Z
#define GPU_MIN_Z 0.2f
#define GPU_MAX_Z 1.0 + GPU_MIN_Z
GL_FORCE_INLINE void divide(SubmissionTarget* target) {
TRACE();
@ -949,26 +931,26 @@ GL_FORCE_INLINE void divide(SubmissionTarget* target) {
}
}
GL_FORCE_INLINE void push(PVRHeader* header, GLboolean multiTextureHeader, PolyList* activePolyList, GLshort textureUnit) {
GL_FORCE_INLINE void push(PolyHeader* header, GLboolean multiTextureHeader, PolyList* activePolyList, GLshort textureUnit) {
TRACE();
// Compile the header
pvr_poly_cxt_t cxt = *_glGetPVRContext();
PolyContext cxt = *_glGetPVRContext();
cxt.list_type = activePolyList->list_type;
_glUpdatePVRTextureContext(&cxt, textureUnit);
if(multiTextureHeader) {
assert(cxt.list_type == PVR_LIST_TR_POLY);
assert(cxt.list_type == GPU_LIST_TR_POLY);
cxt.gen.alpha = PVR_ALPHA_ENABLE;
cxt.txr.alpha = PVR_TXRALPHA_ENABLE;
cxt.blend.src = PVR_BLEND_ZERO;
cxt.blend.dst = PVR_BLEND_DESTCOLOR;
cxt.depth.comparison = PVR_DEPTHCMP_EQUAL;
cxt.gen.alpha = GPU_ALPHA_ENABLE;
cxt.txr.alpha = GPU_TXRALPHA_ENABLE;
cxt.blend.src = GPU_BLEND_ZERO;
cxt.blend.dst = GPU_BLEND_DESTCOLOR;
cxt.depth.comparison = GPU_DEPTHCMP_EQUAL;
}
pvr_poly_compile(&header->hdr, &cxt);
CompilePolyHeader(header, &cxt);
/* Post-process the vertex list */
/*
@ -1136,7 +1118,7 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GL
assert(vertex);
PVRHeader* mtHeader = (PVRHeader*) vertex++;
PolyHeader* mtHeader = (PolyHeader*) vertex++;
/* Replace the UV coordinates with the ST ones */
VertexExtra* ve = aligned_vector_at(target->extras, 0);

View File

@ -8,10 +8,10 @@
KOS Open GL State Machine Error Code Implementation.
*/
#include "gl.h"
#include <stdio.h>
#include "private.h"
static GLenum last_error = GL_NO_ERROR;
static char error_function[64] = { '\0' };

View File

@ -1,57 +1,12 @@
#include <kos.h>
#include "../include/glkos.h"
#include "../containers/aligned_vector.h"
#include "private.h"
#include "profiler.h"
#include "version.h"
#define TA_SQ_ADDR (unsigned int *)(void *) \
(0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0))
static PolyList OP_LIST;
static PolyList PT_LIST;
static PolyList TR_LIST;
static void pvr_list_submit(void *src, int n) {
GLuint *d = TA_SQ_ADDR;
GLuint *s = src;
/* fill/write queues as many times necessary */
while(n--) {
__asm__("pref @%0" : : "r"(s + 8)); /* prefetch 32 bytes for next loop */
d[0] = *(s++);
d[1] = *(s++);
d[2] = *(s++);
d[3] = *(s++);
d[4] = *(s++);
d[5] = *(s++);
d[6] = *(s++);
d[7] = *(s++);
__asm__("pref @%0" : : "r"(d));
d += 8;
}
/* Wait for both store queues to complete */
d = (GLuint *)0xe0000000;
d[0] = d[8] = 0;
}
static void _glInitPVR(GLboolean autosort, GLboolean fsaa) {
pvr_init_params_t params = {
/* Enable opaque and translucent polygons with size 32 and 32 */
{PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32},
PVR_VERTEX_BUF_SIZE, /* Vertex buffer size */
0, /* No DMA */
fsaa, /* No FSAA */
(autosort) ? 0 : 1 /* Disable translucent auto-sorting to match traditional GL */
};
pvr_init(&params);
}
PolyList* _glActivePolyList() {
if(_glIsBlendingEnabled()) {
@ -92,7 +47,7 @@ void APIENTRY glKosInitEx(GLdcConfig* config) {
printf("\nWelcome to GLdc! Git revision: %s\n\n", GLDC_VERSION);
_glInitPVR(config->autosort_enabled, config->fsaa_enabled);
InitGPU(config->autosort_enabled, config->fsaa_enabled);
_glInitMatrices();
_glInitAttributePointers();
@ -105,9 +60,9 @@ void APIENTRY glKosInitEx(GLdcConfig* config) {
_glInitTextures();
OP_LIST.list_type = PVR_LIST_OP_POLY;
PT_LIST.list_type = PVR_LIST_PT_POLY;
TR_LIST.list_type = PVR_LIST_TR_POLY;
OP_LIST.list_type = GPU_LIST_OP_POLY;
PT_LIST.list_type = GPU_LIST_PT_POLY;
TR_LIST.list_type = GPU_LIST_TR_POLY;
aligned_vector_init(&OP_LIST.vector, sizeof(Vertex));
aligned_vector_init(&PT_LIST.vector, sizeof(Vertex));
@ -124,7 +79,6 @@ void APIENTRY glKosInit() {
glKosInitEx(&config);
}
#define QACRTA ((((unsigned int)0x10000000)>>26)<<2)&0x1c
void APIENTRY glKosSwapBuffers() {
static int frame_count = 0;
@ -133,24 +87,19 @@ void APIENTRY glKosSwapBuffers() {
profiler_push(__func__);
pvr_wait_ready();
SceneBegin();
SceneListBegin(GPU_LIST_OP_POLY);
SceneListSubmit(OP_LIST.vector.data, OP_LIST.vector.size);
SceneListFinish();
pvr_scene_begin();
QACR0 = QACRTA;
QACR1 = QACRTA;
SceneListBegin(GPU_LIST_PT_POLY);
SceneListSubmit(PT_LIST.vector.data, PT_LIST.vector.size);
SceneListFinish();
pvr_list_begin(PVR_LIST_OP_POLY);
pvr_list_submit(OP_LIST.vector.data, OP_LIST.vector.size);
pvr_list_finish();
pvr_list_begin(PVR_LIST_PT_POLY);
pvr_list_submit(PT_LIST.vector.data, PT_LIST.vector.size);
pvr_list_finish();
pvr_list_begin(PVR_LIST_TR_POLY);
pvr_list_submit(TR_LIST.vector.data, TR_LIST.vector.size);
pvr_list_finish();
pvr_scene_finish();
SceneListBegin(GPU_LIST_TR_POLY);
SceneListSubmit(TR_LIST.vector.data, TR_LIST.vector.size);
SceneListFinish();
SceneFinish();
aligned_vector_clear(&OP_LIST.vector);
aligned_vector_clear(&PT_LIST.vector);

View File

@ -10,13 +10,13 @@ static GLfloat FOG_COLOR [] = {0.0f, 0.0f, 0.0f, 0.0f};
static void updatePVRFog() {
if(FOG_MODE == GL_LINEAR) {
pvr_fog_table_linear(FOG_START, FOG_END);
GPUSetFogLinear(FOG_START, FOG_END);
} else if(FOG_MODE == GL_EXP) {
pvr_fog_table_exp(FOG_DENSITY);
GPUSetFogExp(FOG_DENSITY);
} else if(FOG_MODE == GL_EXP2) {
pvr_fog_table_exp2(FOG_DENSITY);
GPUSetFogExp2(FOG_DENSITY);
}
pvr_fog_table_color(FOG_COLOR[3], FOG_COLOR[0], FOG_COLOR[1], FOG_COLOR[2]);
GPUSetFogColor(FOG_COLOR[3], FOG_COLOR[0], FOG_COLOR[1], FOG_COLOR[2]);
}
void APIENTRY glFogf(GLenum pname, GLfloat param) {

View File

@ -2,8 +2,6 @@
#include <assert.h>
#include "private.h"
#include "../include/glkos.h"
#include "../include/glext.h"
typedef struct {
GLuint index;
@ -160,7 +158,7 @@ static GL_NO_INSTRUMENT GLboolean _glCalculateAverageTexel(GLuint pvrFormat, con
const GLubyte ARGB4444 = 1;
const GLubyte RGB565 = 2;
if((pvrFormat & PVR_TXRFMT_PAL8BPP) == PVR_TXRFMT_PAL8BPP) {
if((pvrFormat & GPU_TXRFMT_PAL8BPP) == GPU_TXRFMT_PAL8BPP) {
/* Paletted... all we can do really is just pick one of the
* 4 texels.. unless we want to change the palette (bad) or
* pick the closest available colour (slow, and probably bad)
@ -232,7 +230,7 @@ GLboolean _glGenerateMipmapTwiddled(const GLuint pvrFormat, const GLubyte* prevD
uint32_t i, j;
uint32_t stride = 0;
if((pvrFormat & PVR_TXRFMT_PAL8BPP) == PVR_TXRFMT_PAL8BPP) {
if((pvrFormat & GPU_TXRFMT_PAL8BPP) == GPU_TXRFMT_PAL8BPP) {
stride = 1;
} else {
stride = 2;
@ -281,7 +279,7 @@ void APIENTRY glGenerateMipmapEXT(GLenum target) {
return;
}
if((tex->color & PVR_TXRFMT_NONTWIDDLED) == PVR_TXRFMT_NONTWIDDLED) {
if((tex->color & GPU_TXRFMT_NONTWIDDLED) == GPU_TXRFMT_NONTWIDDLED) {
/* glTexImage2D should twiddle internally textures in nearly all cases
* so this error is unlikely */

View File

@ -6,7 +6,7 @@ void APIENTRY gluPerspective(GLfloat angle, GLfloat aspect,
GLfloat znear, GLfloat zfar) {
GLfloat fW, fH;
fH = tanf(angle * (F_PI / 360.0f)) * znear;
fH = tanf(angle * (M_PI / 360.0f)) * znear;
fW = fH * aspect;
glFrustum(-fW, fW, -fH, fH, znear, zfar);

View File

@ -10,11 +10,7 @@
#include <string.h>
#include <stdio.h>
#include "../include/gl.h"
#include "../include/glext.h"
#include "../include/glkos.h"
#include "profiler.h"
#include "private.h"
static GLboolean IMMEDIATE_MODE_ACTIVE = GL_FALSE;

View File

@ -3,8 +3,9 @@
#include <string.h>
#include <math.h>
#include <limits.h>
#include <dc/vec3f.h>
#include "private.h"
#include "platform.h"
#define _MIN(x, y) (x < y) ? x : y
@ -201,12 +202,7 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) {
if(LIGHTS[idx].isDirectional) {
//FIXME: Do we need to rotate directional lights?
} else {
mat_trans_single4(
LIGHTS[idx].position[0],
LIGHTS[idx].position[1],
LIGHTS[idx].position[2],
LIGHTS[idx].position[3]
);
TransformVec3(LIGHTS[idx].position);
}
}
break;
@ -387,10 +383,6 @@ GL_FORCE_INLINE GLboolean isSpecularColorMaterial() {
return (COLOR_MATERIAL_MODE == GL_SPECULAR);
}
GL_FORCE_INLINE void initVec3(struct vec3f* v, const GLfloat* src) {
memcpy(v, src, sizeof(GLfloat) * 3);
}
/*
* Implementation from here (MIT):
* https://github.com/appleseedhq/appleseed/blob/master/src/appleseed/foundation/math/fastmath.h
@ -455,7 +447,7 @@ GL_FORCE_INLINE void _glLightVertexPoint(
#undef _PROCESS_COMPONENT
}
void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const int32_t count) {
void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const uint32_t count) {
GLubyte i;
GLuint j;
@ -503,7 +495,7 @@ void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const int32_t count)
float Vx = -data->xyz[0];
float Vy = -data->xyz[1];
float Vz = -data->xyz[2];
vec3f_normalize(Vx, Vy, Vz);
VEC3_NORMALIZE(Vx, Vy, Vz);
const float Nx = data->n[0];
const float Ny = data->n[1];
@ -523,15 +515,15 @@ void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const int32_t count)
float Hy = (Ly + 0);
float Hz = (Lz + 1);
vec3f_normalize(Lx, Ly, Lz);
vec3f_normalize(Hx, Hy, Hz);
VEC3_NORMALIZE(Lx, Ly, Lz);
VEC3_NORMALIZE(Hx, Hy, Hz);
float LdotN, NdotH;
vec3f_dot(
VEC3_DOT(
Nx, Ny, Nz, Lx, Ly, Lz, LdotN
);
vec3f_dot(
VEC3_DOT(
Nx, Ny, Nz, Hx, Hy, Hz, NdotH
);
@ -544,8 +536,7 @@ void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const int32_t count)
);
} else {
float D;
vec3f_length(Lx, Ly, Lz, D);
VEC3_LENGTH(Lx, Ly, Lz, D);
float att = (
LIGHTS[i].constant_attenuation + (
@ -563,15 +554,15 @@ void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const int32_t count)
float Hy = (Ly + Vy);
float Hz = (Lz + Vz);
vec3f_normalize(Lx, Ly, Lz);
vec3f_normalize(Hx, Hy, Hz);
VEC3_NORMALIZE(Lx, Ly, Lz);
VEC3_NORMALIZE(Hx, Hy, Hz);
float LdotN, NdotH;
vec3f_dot(
VEC3_DOT(
Nx, Ny, Nz, Lx, Ly, Lz, LdotN
);
vec3f_dot(
VEC3_DOT(
Nx, Ny, Nz, Hx, Hy, Hz, NdotH
);

View File

@ -1,13 +1,9 @@
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <dc/fmath.h>
#include <dc/matrix.h>
#include <dc/matrix3d.h>
#include <dc/vec3f.h>
#include "private.h"
#include "../include/gl.h"
#include "../containers/stack.h"
#define DEG2RAD (0.01745329251994329576923690768489)
@ -36,18 +32,6 @@ static const Matrix4x4 IDENTITY = {
GLfloat NEAR_PLANE_DISTANCE = 0.0f;
static inline void upload_matrix(Matrix4x4* m) {
mat_load((matrix_t*) m);
}
static inline void multiply_matrix(Matrix4x4* m) {
mat_apply((matrix_t*) m);
}
static inline void download_matrix(Matrix4x4* m) {
mat_store((matrix_t*) m);
}
Matrix4x4* _glGetProjectionMatrix() {
return (Matrix4x4*) stack_top(&MATRIX_STACKS[1]);
}
@ -65,8 +49,10 @@ void _glInitMatrices() {
stack_push(&MATRIX_STACKS[1], IDENTITY);
stack_push(&MATRIX_STACKS[2], IDENTITY);
memcpy4(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4));
memcpy4(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4));
FASTCPY4(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4));
FASTCPY4(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4));
const VideoMode* vid_mode = GetVideoMode();
glDepthRange(0.0f, 1.0f);
glViewport(0, 0, vid_mode->width, vid_mode->height);
@ -110,7 +96,7 @@ static void transpose(GLfloat* m) {
}
static void recalculateNormalMatrix() {
memcpy4(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(Matrix4x4));
FASTCPY4(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(Matrix4x4));
inverse((GLfloat*) NORMAL_MATRIX);
transpose((GLfloat*) NORMAL_MATRIX);
}
@ -136,20 +122,16 @@ void APIENTRY glLoadIdentity() {
}
void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
static Matrix4x4 trn __attribute__((aligned(32))) = {
const Matrix4x4 trn __attribute__((aligned(32))) = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
x, y, z, 1.0f
};
trn[M12] = x;
trn[M13] = y;
trn[M14] = z;
upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
multiply_matrix(&trn);
download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
MultiplyMatrix4x4(&trn);
DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix();
@ -158,20 +140,16 @@ void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) {
static Matrix4x4 scale __attribute__((aligned(32))) = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
const Matrix4x4 scale __attribute__((aligned(32))) = {
x, 0.0f, 0.0f, 0.0f,
0.0f, y, 0.0f, 0.0f,
0.0f, 0.0f, z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
scale[M0] = x;
scale[M5] = y;
scale[M10] = z;
upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
multiply_matrix(&scale);
download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
MultiplyMatrix4x4(&scale);
DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix();
@ -179,7 +157,7 @@ void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) {
}
void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
static Matrix4x4 rotate __attribute__((aligned(32))) = {
Matrix4x4 rotate __attribute__((aligned(32))) = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
@ -190,7 +168,7 @@ void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
float c = cos(r);
float s = sin(r);
vec3f_normalize(x, y, z);
VEC3_NORMALIZE(x, y, z);
float invc = 1.0f - c;
float xs = x * s;
@ -212,9 +190,9 @@ void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
rotate[M9] = yz * invc - xs;
rotate[M10] = (z * z) * invc + c;
upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
multiply_matrix(&rotate);
download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
MultiplyMatrix4x4((const Matrix4x4*) &rotate);
DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix();
@ -258,7 +236,7 @@ void APIENTRY glOrtho(GLfloat left, GLfloat right,
GLfloat znear, GLfloat zfar) {
/* Ortho Matrix */
static Matrix4x4 OrthoMatrix __attribute__((aligned(32))) = {
Matrix4x4 OrthoMatrix __attribute__((aligned(32))) = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
@ -272,9 +250,9 @@ void APIENTRY glOrtho(GLfloat left, GLfloat right,
OrthoMatrix[M13] = -(top + bottom) / (top - bottom);
OrthoMatrix[M14] = -(zfar + znear) / (zfar - znear);
upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
multiply_matrix(&OrthoMatrix);
download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
MultiplyMatrix4x4((const Matrix4x4*) &OrthoMatrix);
DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
}
@ -284,9 +262,9 @@ void APIENTRY glFrustum(GLfloat left, GLfloat right,
GLfloat znear, GLfloat zfar) {
/* Frustum Matrix */
static Matrix4x4 FrustumMatrix __attribute__((aligned(32)));
Matrix4x4 FrustumMatrix __attribute__((aligned(32)));
memset(FrustumMatrix, 0, sizeof(float) * 16);
MEMSET(FrustumMatrix, 0, sizeof(float) * 16);
const float near2 = 2.0f * znear;
const float A = (right + left) / (right - left);
@ -303,39 +281,20 @@ void APIENTRY glFrustum(GLfloat left, GLfloat right,
FrustumMatrix[M11] = -1.0f;
FrustumMatrix[M14] = D;
upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
multiply_matrix(&FrustumMatrix);
download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
MultiplyMatrix4x4((const Matrix4x4*) &FrustumMatrix);
DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
}
/* Multiply the current matrix by an arbitrary matrix */
void glMultMatrixf(const GLfloat *m) {
static Matrix4x4 TEMP;
Matrix4x4 TEMP;
FASTCPY4(TEMP, m, sizeof(Matrix4x4));
TEMP[M0] = m[0];
TEMP[M1] = m[1];
TEMP[M2] = m[2];
TEMP[M3] = m[3];
TEMP[M4] = m[4];
TEMP[M5] = m[5];
TEMP[M6] = m[6];
TEMP[M7] = m[7];
TEMP[M8] = m[8];
TEMP[M9] = m[9];
TEMP[M10] = m[10];
TEMP[M11] = m[11];
TEMP[M12] = m[12];
TEMP[M13] = m[13];
TEMP[M14] = m[14];
TEMP[M15] = m[15];
upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
multiply_matrix((Matrix4x4*) &TEMP);
download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
MultiplyMatrix4x4((const Matrix4x4*) &TEMP);
DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix();
@ -400,9 +359,9 @@ void glMultTransposeMatrixf(const GLfloat *m) {
TEMP[M14] = m[11];
TEMP[M15] = m[15];
upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
multiply_matrix(&TEMP);
download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
MultiplyMatrix4x4((const Matrix4x4*) &TEMP);
DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix();
@ -411,6 +370,8 @@ void glMultTransposeMatrixf(const GLfloat *m) {
/* Set the GL viewport */
void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
const VideoMode* vid_mode = GetVideoMode();
gl_viewport_x1 = x;
gl_viewport_y1 = y;
gl_viewport_width = width;
@ -453,40 +414,40 @@ static inline void vec3f_cross(const GLfloat* v1, const GLfloat* v2, GLfloat* re
GL_FORCE_INLINE void vec3f_normalize_sh4(float *v){
float length, ilength;
ilength = MATH_fsrra(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
ilength = MATH_fsrra(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
length = MATH_Fast_Invert(ilength);
if (length)
{
v[0] *= ilength;
v[1] *= ilength;
v[2] *= ilength;
}
if (length)
{
v[0] *= ilength;
v[1] *= ilength;
v[2] *= ilength;
}
}
void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,
GLfloat upz) {
GLfloat m [16];
GLfloat f [3];
GLfloat u [3];
GLfloat s [3];
GLfloat f [3];
GLfloat u [3];
GLfloat s [3];
f[0] = centerx - eyex;
f[1] = centery - eyey;
f[2] = centerz - eyez;
f[0] = centerx - eyex;
f[1] = centery - eyey;
f[2] = centerz - eyez;
u[0] = upx;
u[1] = upy;
u[2] = upz;
u[0] = upx;
u[1] = upy;
u[2] = upz;
vec3f_normalize_sh4(f);
vec3f_cross(f, u, s);
vec3f_cross(f, u, s);
vec3f_normalize_sh4(s);
vec3f_cross(s, f, u);
vec3f_cross(s, f, u);
m[0] = s[0]; m[4] = s[1]; m[8] = s[2]; m[12] = 0.0f;
m[1] = u[0]; m[5] = u[1]; m[9] = u[2]; m[13] = 0.0f;
m[2] = -f[0]; m[6] = -f[1]; m[10] = -f[2]; m[14] = 0.0f;
m[0] = s[0]; m[4] = s[1]; m[8] = s[2]; m[12] = 0.0f;
m[1] = u[0]; m[5] = u[1]; m[9] = u[2]; m[13] = 0.0f;
m[2] = -f[0]; m[6] = -f[1]; m[10] = -f[2]; m[14] = 0.0f;
m[3] = 0.0f; m[7] = 0.0f; m[11] = 0.0f; m[15] = 1.0f;
static Matrix4x4 trn __attribute__((aligned(32))) = {
@ -501,26 +462,26 @@ void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
trn[M14] = -eyez;
// Does not modify internal Modelview matrix
upload_matrix(&m);
multiply_matrix(&trn);
multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
download_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
UploadMatrix4x4((const Matrix4x4*) &m);
MultiplyMatrix4x4((const Matrix4x4*) &trn);
MultiplyMatrix4x4(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
DownloadMatrix4x4(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
}
void _glApplyRenderMatrix() {
upload_matrix(&SCREENVIEW_MATRIX);
multiply_matrix(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)));
multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
UploadMatrix4x4((const Matrix4x4*) &SCREENVIEW_MATRIX);
MultiplyMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)));
MultiplyMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
}
void _glMatrixLoadTexture() {
upload_matrix(stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF)));
UploadMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF)));
}
void _glMatrixLoadModelView() {
upload_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
UploadMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
}
void _glMatrixLoadNormal() {
upload_matrix(&NORMAL_MATRIX);
UploadMatrix4x4((const Matrix4x4*) &NORMAL_MATRIX);
}

498
GL/platform.h Normal file
View File

@ -0,0 +1,498 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#define MEMSET(dst, v, size) memset((dst), (v), (size))
typedef enum GPUAlpha {
GPU_ALPHA_DISABLE = 0,
GPU_ALPHA_ENABLE = 1
} GPUAlpha;
typedef enum GPUTexture {
GPU_TEXTURE_DISABLE = 0,
GPU_TEXTURE_ENABLE = 1
} GPUTexture;
typedef enum GPUTextureAlpha {
GPU_TXRALPHA_DISABLE = 1,
GPU_TXRALPHA_ENABLE = 0
} GPUTextureAlpha;
typedef enum GPUList {
GPU_LIST_OP_POLY = 0,
GPU_LIST_OP_MOD = 1,
GPU_LIST_TR_POLY = 2,
GPU_LIST_TR_MOD = 3,
GPU_LIST_PT_POLY = 4
} GPUList;
typedef enum GPUBlend {
GPU_BLEND_ZERO = 0,
GPU_BLEND_ONE = 1,
GPU_BLEND_DESTCOLOR = 2,
GPU_BLEND_INVDESTCOLOR = 3,
GPU_BLEND_SRCALPHA = 4,
GPU_BLEND_INVSRCALPHA = 5,
GPU_BLEND_DESTALPHA = 6,
GPU_BLEND_INVDESTALPHA = 7
} GPUBlend;
typedef enum GPUDepthCompare {
GPU_DEPTHCMP_NEVER = 0,
GPU_DEPTHCMP_LESS = 1,
GPU_DEPTHCMP_EQUAL = 2,
GPU_DEPTHCMP_LEQUAL = 3,
GPU_DEPTHCMP_GREATER = 4,
GPU_DEPTHCMP_NOTEQUAL = 5,
GPU_DEPTHCMP_GEQUAL = 6,
GPU_DEPTHCMP_ALWAYS = 7
} GPUDepthCompare;
typedef enum GPUTextureFormat {
GPU_TXRFMT_NONE,
GPU_TXRFMT_VQ_DISABLE = (0 << 30),
GPU_TXRFMT_VQ_ENABLE = (1 << 30),
GPU_TXRFMT_ARGB1555 = (0 << 27),
GPU_TXRFMT_RGB565 = (1 << 27),
GPU_TXRFMT_ARGB4444 = (2 << 27),
GPU_TXRFMT_YUV422 = (3 << 27),
GPU_TXRFMT_BUMP = (4 << 27),
GPU_TXRFMT_PAL4BPP = (5 << 27),
GPU_TXRFMT_PAL8BPP = (6 << 27),
GPU_TXRFMT_TWIDDLED = (0 << 26),
GPU_TXRFMT_NONTWIDDLED = (1 << 26),
GPU_TXRFMT_NOSTRIDE = (0 << 21),
GPU_TXRFMT_STRIDE = (1 << 21)
} GPUTextureFormat;
static inline uint32_t GPUPaletteSelect8BPP(uint32_t x) {
return x << 25;
}
static inline uint32_t GPUPaletteSelect4BPP(uint32_t x) {
return x << 21;
}
typedef enum GPUCulling {
GPU_CULLING_NONE = 0,
GPU_CULLING_SMALL = 1,
GPU_CULLING_CCW = 2,
GPU_CULLING_CW = 3
} GPUCulling;
typedef enum GPUUVFlip {
GPU_UVFLIP_NONE = 0,
GPU_UVFLIP_V = 1,
GPU_UVFLIP_U = 2,
GPU_UVFLIP_UV = 3
} GPUUVFlip;
typedef enum GPUUVClamp {
GPU_UVCLAMP_NONE = 0,
GPU_UVCLAMP_V = 1,
GPU_UVCLAMP_U = 2,
GPU_UVCLAMP_UV = 3
} GPUUVClamp;
typedef enum GPUColorClamp {
GPU_CLRCLAMP_DISABLE = 0,
GPU_CLRCLAMP_ENABLE = 1
} GPUColorClamp;
typedef enum GPUFilter {
GPU_FILTER_NEAREST = 0,
GPU_FILTER_BILINEAR = 2,
GPU_FILTER_TRILINEAR1 = 4,
GPU_FILTER_TRILINEAR2 = 6
} GPUFilter;
typedef enum GPUDepthWrite {
GPU_DEPTHWRITE_ENABLE = 0,
GPU_DEPTHWRITE_DISABLE = 1
} GPUDepthWrite;
typedef enum GPUUserClip {
GPU_USERCLIP_DISABLE = 0,
GPU_USERCLIP_INSIDE = 2,
GPU_USERCLIP_OUTSIDE = 3
} GPUUserClip;
typedef enum GPUColorFormat {
GPU_CLRFMT_ARGBPACKED = 0,
GPU_CLRFMT_4FLOATS = 1,
GPU_CLRFMT_INTENSITY = 2,
GPU_CLRFMT_INTENSITY_PREV = 3
} GPUColorFormat;
typedef enum GPUUVFormat {
GPU_UVFMT_32BIT = 0,
GPU_UVFMT_16BIT = 1
} GPUUVFormat;
typedef enum GPUPaletteFormat {
GPU_PAL_ARGB1555 = 0,
GPU_PAL_RGB565 = 1,
GPU_PAL_ARGB4444 = 2,
GPU_PAL_ARGB8888 = 3
} GPUPaletteFormat;
typedef enum GPUFog {
GPU_FOG_TABLE = 0,
GPU_FOG_VERTEX = 1,
GPU_FOG_DISABLE = 2,
GPU_FOG_TABLE2 = 3
} GPUFog;
typedef enum GPUShade {
GPU_SHADE_FLAT = 0,
GPU_SHADE_GOURAUD = 1
} GPUShade;
typedef enum GPUTextureEnv {
GPU_TXRENV_REPLACE = 0,
GPU_TXRENV_MODULATE = 1,
GPU_TXRENV_DECAL = 2,
GPU_TXRENV_MODULATEALPHA = 3
} GPUTextureEnv;
typedef struct VideoMode {
uint16_t width;
uint16_t height;
} VideoMode;
const VideoMode* GetVideoMode();
/* Duplication of pvr_poly_cxt_t from KOS so that we can
* compile on non-KOS platforms for testing */
typedef struct {
GPUList list_type;
struct {
int alpha;
int shading;
int fog_type;
int culling;
int color_clamp;
int clip_mode;
int modifier_mode;
int specular;
int alpha2;
int fog_type2;
int color_clamp2;
} gen;
struct {
int src;
int dst;
int src_enable;
int dst_enable;
int src2;
int dst2;
int src_enable2;
int dst_enable2;
} blend;
struct {
int color;
int uv;
int modifier;
} fmt;
struct {
int comparison;
int write;
} depth;
struct {
int enable;
int filter;
int mipmap;
int mipmap_bias;
int uv_flip;
int uv_clamp;
int alpha;
int env;
int width;
int height;
int format;
void* base;
} txr;
struct {
int enable;
int filter;
int mipmap;
int mipmap_bias;
int uv_flip;
int uv_clamp;
int alpha;
int env;
int width;
int height;
int format;
void* base;
} txr2;
} PolyContext;
typedef struct {
uint32_t cmd;
uint32_t mode1;
uint32_t mode2;
uint32_t mode3;
uint32_t d1;
uint32_t d2;
uint32_t d3;
uint32_t d4;
} PolyHeader;
enum GPUCommand {
GPU_CMD_POLYHDR = 0x80840000,
GPU_CMD_VERTEX = 0xe0000000,
GPU_CMD_VERTEX_EOL = 0xf0000000,
GPU_CMD_USERCLIP = 0x20000000,
GPU_CMD_MODIFIER = 0x80000000,
GPU_CMD_SPRITE = 0xA0000000
};
typedef float Matrix4x4[16];
void SceneBegin();
void SceneListBegin(GPUList list);
void SceneListSubmit(void* src, int n);
void SceneListFinish();
void SceneFinish();
#define GPU_TA_CMD_TYPE_SHIFT 24
#define GPU_TA_CMD_TYPE_MASK (7 << GPU_TA_CMD_TYPE_SHIFT)
#define GPU_TA_CMD_USERCLIP_SHIFT 16
#define GPU_TA_CMD_USERCLIP_MASK (3 << GPU_TA_CMD_USERCLIP_SHIFT)
#define GPU_TA_CMD_CLRFMT_SHIFT 4
#define GPU_TA_CMD_CLRFMT_MASK (7 << GPU_TA_CMD_CLRFMT_SHIFT)
#define GPU_TA_CMD_SPECULAR_SHIFT 2
#define GPU_TA_CMD_SPECULAR_MASK (1 << GPU_TA_CMD_SPECULAR_SHIFT)
#define GPU_TA_CMD_SHADE_SHIFT 1
#define GPU_TA_CMD_SHADE_MASK (1 << GPU_TA_CMD_SHADE_SHIFT)
#define GPU_TA_CMD_UVFMT_SHIFT 0
#define GPU_TA_CMD_UVFMT_MASK (1 << GPU_TA_CMD_UVFMT_SHIFT)
#define GPU_TA_CMD_MODIFIER_SHIFT 7
#define GPU_TA_CMD_MODIFIER_MASK (1 << GPU_TA_CMD_MODIFIER_SHIFT)
#define GPU_TA_CMD_MODIFIERMODE_SHIFT 6
#define GPU_TA_CMD_MODIFIERMODE_MASK (1 << GPU_TA_CMD_MODIFIERMODE_SHIFT)
#define GPU_TA_PM1_DEPTHCMP_SHIFT 29
#define GPU_TA_PM1_DEPTHCMP_MASK (7 << GPU_TA_PM1_DEPTHCMP_SHIFT)
#define GPU_TA_PM1_CULLING_SHIFT 27
#define GPU_TA_PM1_CULLING_MASK (3 << GPU_TA_PM1_CULLING_SHIFT)
#define GPU_TA_PM1_DEPTHWRITE_SHIFT 26
#define GPU_TA_PM1_DEPTHWRITE_MASK (1 << GPU_TA_PM1_DEPTHWRITE_SHIFT)
#define GPU_TA_PM1_TXRENABLE_SHIFT 25
#define GPU_TA_PM1_TXRENABLE_MASK (1 << GPU_TA_PM1_TXRENABLE_SHIFT)
#define GPU_TA_PM1_MODIFIERINST_SHIFT 29
#define GPU_TA_PM1_MODIFIERINST_MASK (3 << GPU_TA_PM1_MODIFIERINST_SHIFT)
#define GPU_TA_PM2_SRCBLEND_SHIFT 29
#define GPU_TA_PM2_SRCBLEND_MASK (7 << GPU_TA_PM2_SRCBLEND_SHIFT)
#define GPU_TA_PM2_DSTBLEND_SHIFT 26
#define GPU_TA_PM2_DSTBLEND_MASK (7 << GPU_TA_PM2_DSTBLEND_SHIFT)
#define GPU_TA_PM2_SRCENABLE_SHIFT 25
#define GPU_TA_PM2_SRCENABLE_MASK (1 << GPU_TA_PM2_SRCENABLE_SHIFT)
#define GPU_TA_PM2_DSTENABLE_SHIFT 24
#define GPU_TA_PM2_DSTENABLE_MASK (1 << GPU_TA_PM2_DSTENABLE_SHIFT)
#define GPU_TA_PM2_FOG_SHIFT 22
#define GPU_TA_PM2_FOG_MASK (3 << GPU_TA_PM2_FOG_SHIFT)
#define GPU_TA_PM2_CLAMP_SHIFT 21
#define GPU_TA_PM2_CLAMP_MASK (1 << GPU_TA_PM2_CLAMP_SHIFT)
#define GPU_TA_PM2_ALPHA_SHIFT 20
#define GPU_TA_PM2_ALPHA_MASK (1 << GPU_TA_PM2_ALPHA_SHIFT)
#define GPU_TA_PM2_TXRALPHA_SHIFT 19
#define GPU_TA_PM2_TXRALPHA_MASK (1 << GPU_TA_PM2_TXRALPHA_SHIFT)
#define GPU_TA_PM2_UVFLIP_SHIFT 17
#define GPU_TA_PM2_UVFLIP_MASK (3 << GPU_TA_PM2_UVFLIP_SHIFT)
#define GPU_TA_PM2_UVCLAMP_SHIFT 15
#define GPU_TA_PM2_UVCLAMP_MASK (3 << GPU_TA_PM2_UVCLAMP_SHIFT)
#define GPU_TA_PM2_FILTER_SHIFT 12
#define GPU_TA_PM2_FILTER_MASK (7 << GPU_TA_PM2_FILTER_SHIFT)
#define GPU_TA_PM2_MIPBIAS_SHIFT 8
#define GPU_TA_PM2_MIPBIAS_MASK (15 << GPU_TA_PM2_MIPBIAS_SHIFT)
#define GPU_TA_PM2_TXRENV_SHIFT 6
#define GPU_TA_PM2_TXRENV_MASK (3 << GPU_TA_PM2_TXRENV_SHIFT)
#define GPU_TA_PM2_USIZE_SHIFT 3
#define GPU_TA_PM2_USIZE_MASK (7 << GPU_TA_PM2_USIZE_SHIFT)
#define GPU_TA_PM2_VSIZE_SHIFT 0
#define GPU_TA_PM2_VSIZE_MASK (7 << GPU_TA_PM2_VSIZE_SHIFT)
#define GPU_TA_PM3_MIPMAP_SHIFT 31
#define GPU_TA_PM3_MIPMAP_MASK (1 << GPU_TA_PM3_MIPMAP_SHIFT)
#define GPU_TA_PM3_TXRFMT_SHIFT 0
#define GPU_TA_PM3_TXRFMT_MASK 0xffffffff
/* Compile a polygon context into a polygon header */
static inline void CompilePolyHeader(PolyHeader *dst, const PolyContext *src) {
int u, v;
uint32_t txr_base;
/* Basically we just take each parameter, clip it, shift it
into place, and OR it into the final result. */
/* The base values for CMD */
dst->cmd = GPU_CMD_POLYHDR;
if(src->txr.enable == GPU_TEXTURE_ENABLE)
dst->cmd |= 8;
/* Or in the list type, shading type, color and UV formats */
dst->cmd |= (src->list_type << GPU_TA_CMD_TYPE_SHIFT) & GPU_TA_CMD_TYPE_MASK;
dst->cmd |= (src->fmt.color << GPU_TA_CMD_CLRFMT_SHIFT) & GPU_TA_CMD_CLRFMT_MASK;
dst->cmd |= (src->gen.shading << GPU_TA_CMD_SHADE_SHIFT) & GPU_TA_CMD_SHADE_MASK;
dst->cmd |= (src->fmt.uv << GPU_TA_CMD_UVFMT_SHIFT) & GPU_TA_CMD_UVFMT_MASK;
dst->cmd |= (src->gen.clip_mode << GPU_TA_CMD_USERCLIP_SHIFT) & GPU_TA_CMD_USERCLIP_MASK;
dst->cmd |= (src->fmt.modifier << GPU_TA_CMD_MODIFIER_SHIFT) & GPU_TA_CMD_MODIFIER_MASK;
dst->cmd |= (src->gen.modifier_mode << GPU_TA_CMD_MODIFIERMODE_SHIFT) & GPU_TA_CMD_MODIFIERMODE_MASK;
dst->cmd |= (src->gen.specular << GPU_TA_CMD_SPECULAR_SHIFT) & GPU_TA_CMD_SPECULAR_MASK;
/* Polygon mode 1 */
dst->mode1 = (src->depth.comparison << GPU_TA_PM1_DEPTHCMP_SHIFT) & GPU_TA_PM1_DEPTHCMP_MASK;
dst->mode1 |= (src->gen.culling << GPU_TA_PM1_CULLING_SHIFT) & GPU_TA_PM1_CULLING_MASK;
dst->mode1 |= (src->depth.write << GPU_TA_PM1_DEPTHWRITE_SHIFT) & GPU_TA_PM1_DEPTHWRITE_MASK;
dst->mode1 |= (src->txr.enable << GPU_TA_PM1_TXRENABLE_SHIFT) & GPU_TA_PM1_TXRENABLE_MASK;
/* Polygon mode 2 */
dst->mode2 = (src->blend.src << GPU_TA_PM2_SRCBLEND_SHIFT) & GPU_TA_PM2_SRCBLEND_MASK;
dst->mode2 |= (src->blend.dst << GPU_TA_PM2_DSTBLEND_SHIFT) & GPU_TA_PM2_DSTBLEND_MASK;
dst->mode2 |= (src->blend.src_enable << GPU_TA_PM2_SRCENABLE_SHIFT) & GPU_TA_PM2_SRCENABLE_MASK;
dst->mode2 |= (src->blend.dst_enable << GPU_TA_PM2_DSTENABLE_SHIFT) & GPU_TA_PM2_DSTENABLE_MASK;
dst->mode2 |= (src->gen.fog_type << GPU_TA_PM2_FOG_SHIFT) & GPU_TA_PM2_FOG_MASK;
dst->mode2 |= (src->gen.color_clamp << GPU_TA_PM2_CLAMP_SHIFT) & GPU_TA_PM2_CLAMP_MASK;
dst->mode2 |= (src->gen.alpha << GPU_TA_PM2_ALPHA_SHIFT) & GPU_TA_PM2_ALPHA_MASK;
if(src->txr.enable == GPU_TEXTURE_DISABLE) {
dst->mode3 = 0;
}
else {
dst->mode2 |= (src->txr.alpha << GPU_TA_PM2_TXRALPHA_SHIFT) & GPU_TA_PM2_TXRALPHA_MASK;
dst->mode2 |= (src->txr.uv_flip << GPU_TA_PM2_UVFLIP_SHIFT) & GPU_TA_PM2_UVFLIP_MASK;
dst->mode2 |= (src->txr.uv_clamp << GPU_TA_PM2_UVCLAMP_SHIFT) & GPU_TA_PM2_UVCLAMP_MASK;
dst->mode2 |= (src->txr.filter << GPU_TA_PM2_FILTER_SHIFT) & GPU_TA_PM2_FILTER_MASK;
dst->mode2 |= (src->txr.mipmap_bias << GPU_TA_PM2_MIPBIAS_SHIFT) & GPU_TA_PM2_MIPBIAS_MASK;
dst->mode2 |= (src->txr.env << GPU_TA_PM2_TXRENV_SHIFT) & GPU_TA_PM2_TXRENV_MASK;
switch(src->txr.width) {
case 8:
u = 0;
break;
case 16:
u = 1;
break;
case 32:
u = 2;
break;
case 64:
u = 3;
break;
case 128:
u = 4;
break;
case 256:
u = 5;
break;
case 512:
u = 6;
break;
case 1024:
u = 7;
break;
default:
assert(0 && "Invalid texture U size");
u = 0;
break;
}
switch(src->txr.height) {
case 8:
v = 0;
break;
case 16:
v = 1;
break;
case 32:
v = 2;
break;
case 64:
v = 3;
break;
case 128:
v = 4;
break;
case 256:
v = 5;
break;
case 512:
v = 6;
break;
case 1024:
v = 7;
break;
default:
assert(0 && "Invalid texture V size");
v = 0;
break;
}
dst->mode2 |= (u << GPU_TA_PM2_USIZE_SHIFT) & GPU_TA_PM2_USIZE_MASK;
dst->mode2 |= (v << GPU_TA_PM2_VSIZE_SHIFT) & GPU_TA_PM2_VSIZE_MASK;
/* Polygon mode 3 */
dst->mode3 = (src->txr.mipmap << GPU_TA_PM3_MIPMAP_SHIFT) & GPU_TA_PM3_MIPMAP_MASK;
dst->mode3 |= (src->txr.format << GPU_TA_PM3_TXRFMT_SHIFT) & GPU_TA_PM3_TXRFMT_MASK;
/* Convert the texture address */
txr_base = (uint32_t) src->txr.base;
txr_base = (txr_base & 0x00fffff8) >> 3;
dst->mode3 |= txr_base;
}
if(src->fmt.modifier && src->gen.modifier_mode) {
/* If we're affected by a modifier volume, silently promote the header
to the one that is affected by a modifier volume. */
dst->d1 = dst->mode2;
dst->d2 = dst->mode3;
}
else {
dst->d1 = dst->d2 = 0xffffffff;
}
dst->d3 = dst->d4 = 0xffffffff;
}
#ifdef BACKEND_KOSPVR
#include "platforms/sh4.h"
#else
#include "platforms/software.h"
#endif

72
GL/platforms/sh4.c Normal file
View File

@ -0,0 +1,72 @@
#include "../platform.h"
#include "sh4.h"
#define TA_SQ_ADDR (unsigned int *)(void *) \
(0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0))
#define QACRTA ((((unsigned int)0x10000000)>>26)<<2)&0x1c
#define PVR_VERTEX_BUF_SIZE 2560 * 256
void InitGPU(_Bool autosort, _Bool fsaa) {
pvr_init_params_t params = {
/* Enable opaque and translucent polygons with size 32 and 32 */
{PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32},
PVR_VERTEX_BUF_SIZE, /* Vertex buffer size */
0, /* No DMA */
fsaa, /* No FSAA */
(autosort) ? 0 : 1 /* Disable translucent auto-sorting to match traditional GL */
};
pvr_init(&params);
}
void SceneBegin() {
pvr_wait_ready();
pvr_scene_begin();
QACR0 = QACRTA;
QACR1 = QACRTA;
}
void SceneListBegin(GPUList list) {
pvr_list_begin(list);
}
void SceneListSubmit(void* src, int n) {
uint32_t *d = (uint32_t*) TA_SQ_ADDR;
uint32_t *s = src;
/* fill/write queues as many times necessary */
while(n--) {
__asm__("pref @%0" : : "r"(s + 8)); /* prefetch 32 bytes for next loop */
d[0] = *(s++);
d[1] = *(s++);
d[2] = *(s++);
d[3] = *(s++);
d[4] = *(s++);
d[5] = *(s++);
d[6] = *(s++);
d[7] = *(s++);
__asm__("pref @%0" : : "r"(d));
d += 8;
}
/* Wait for both store queues to complete */
d = (uint32_t *)0xe0000000;
d[0] = d[8] = 0;
}
void SceneListFinish() {
pvr_list_finish();
}
void SceneFinish() {
pvr_scene_finish();
}
const VideoMode* GetVideoMode() {
static VideoMode mode;
mode.width = vid_mode->width;
mode.height = vid_mode->height;
return &mode;
}

124
GL/platforms/sh4.h Normal file
View File

@ -0,0 +1,124 @@
#pragma once
#include <kos.h>
#include <dc/matrix.h>
#include <dc/pvr.h>
#include <dc/vec3f.h>
#include <dc/fmath.h>
#include <dc/matrix3d.h>
#include "../types.h"
#include "sh4_math.h"
#define FASTCPY(dst, src, bytes) \
(bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy(dst, src, bytes)
#define FASTCPY4(dst, src, bytes) \
(bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy4(dst, src, bytes)
#define MEMSET4(dst, v, size) memset4((dst), (v), (size))
#define VEC3_NORMALIZE(x, y, z) vec3f_normalize((x), (y), (z))
#define VEC3_LENGTH(x, y, z, l) vec3f_length((x), (y), (z), (l))
#define VEC3_DOT(x1, y1, z1, x2, y2, z2, d) vec3f_dot((x1), (y1), (z1), (x2), (y2), (z2), (d))
static inline void UploadMatrix4x4(const Matrix4x4* mat) {
mat_load((matrix_t*) mat);
}
static inline void DownloadMatrix4x4(Matrix4x4* mat) {
mat_store((matrix_t*) mat);
}
static inline void MultiplyMatrix4x4(const Matrix4x4* mat) {
mat_apply((matrix_t*) mat);
}
static inline void TransformVec3(float* x) {
mat_trans_single4(x[0], x[1], x[2], x[3]);
}
/* Transform a 3-element vector using the stored matrix (w == 1) */
static inline void TransformVec3NoMod(const float* xIn, float* xOut) {
mat_trans_single3_nodiv_nomod(xIn[0], xIn[1], xIn[2], xOut[0], xOut[1], xOut[2]);
}
/* Transform a 3-element normal using the stored matrix (w == 0)*/
static inline void TransformNormalNoMod(const float* in, float* out) {
mat_trans_normal3_nomod(in[0], in[1], in[2], out[0], out[1], out[2]);
}
/* Transform a 4-element vector in-place by the stored matrix */
inline void TransformVec4(float* x) {
}
static inline void TransformVertices(Vertex* vertices, const int count) {
Vertex* it = vertices;
for(int i = 0; i < count; ++i, ++it) {
register float __x __asm__("fr12") = (it->xyz[0]);
register float __y __asm__("fr13") = (it->xyz[1]);
register float __z __asm__("fr14") = (it->xyz[2]);
register float __w __asm__("fr15") = (it->w);
__asm__ __volatile__(
"fldi1 fr15\n"
"ftrv xmtrx,fv12\n"
: "=f" (__x), "=f" (__y), "=f" (__z), "=f" (__w)
: "0" (__x), "1" (__y), "2" (__z), "3" (__w)
);
it->xyz[0] = __x;
it->xyz[1] = __y;
it->xyz[2] = __z;
it->w = __w;
}
}
void InitGPU(_Bool autosort, _Bool fsaa);
static inline size_t GPUMemoryAvailable() {
return pvr_mem_available();
}
static inline void* GPUMemoryAlloc(size_t size) {
return pvr_mem_malloc(size);
}
static inline void GPUSetPaletteFormat(GPUPaletteFormat format) {
pvr_set_pal_format(format);
}
static inline void GPUSetPaletteEntry(uint32_t idx, uint32_t value) {
pvr_set_pal_entry(idx, value);
}
static inline void GPUSetBackgroundColour(float r, float g, float b) {
pvr_set_bg_color(r, g, b);
}
#define PT_ALPHA_REF 0x011c
static inline void GPUSetAlphaCutOff(uint8_t val) {
PVR_SET(PT_ALPHA_REF, val);
}
static inline void GPUSetClearDepth(float v) {
pvr_set_zclip(v);
}
static inline void GPUSetFogLinear(float start, float end) {
pvr_fog_table_linear(start, end);
}
static inline void GPUSetFogExp(float density) {
pvr_fog_table_exp(density);
}
static inline void GPUSetFogExp2(float density) {
pvr_fog_table_exp2(density);
}
static inline void GPUSetFogColor(float r, float g, float b, float a) {
pvr_fog_table_color(r, g, b, a);
}

330
GL/platforms/software.c Normal file
View File

@ -0,0 +1,330 @@
#include <SDL.h>
#include <stdlib.h>
#include <string.h>
#include "../platform.h"
#include "software.h"
#include "software/edge_equation.h"
#include "software/parameter_equation.h"
static size_t AVAILABLE_VRAM = 16 * 1024 * 1024;
static Matrix4x4 MATRIX;
static SDL_Window* WINDOW = NULL;
static SDL_Renderer* RENDERER = NULL;
static uint8_t BACKGROUND_COLOR[3] = {0, 0, 0};
GPUCulling CULL_MODE = GPU_CULLING_CCW;
static VideoMode vid_mode = {
640, 480
};
typedef struct GPUVertex {
uint32_t flags;
float x;
float y;
float z;
float u;
float v;
uint8_t bgra[4];
uint8_t obgra[4];
} GPUVertex;
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX(x, y) ((x) > (y) ? (x) : (y))
static void DrawTriangle(GPUVertex* v0, GPUVertex* v1, GPUVertex* v2) {
// Compute triangle bounding box.
int minX = MIN(MIN(v0->x, v1->x), v2->x);
int maxX = MAX(MAX(v0->x, v1->x), v2->x);
int minY = MIN(MIN(v0->y, v1->y), v2->y);
int maxY = MAX(MAX(v0->y, v1->y), v2->y);
// Clip to scissor rect.
minX = MAX(minX, 0);
maxX = MIN(maxX, vid_mode.width);
minY = MAX(minY, 0);
maxY = MIN(maxY, vid_mode.height);
// Compute edge equations.
EdgeEquation e0, e1, e2;
EdgeEquationInit(&e0, &v0->x, &v1->x);
EdgeEquationInit(&e1, &v1->x, &v2->x);
EdgeEquationInit(&e2, &v2->x, &v0->x);
float area = 0.5 * (e0.c + e1.c + e2.c);
/* This is very ugly. I don't understand the math properly
* so I just swap the vertex order if something is back-facing
* and we want to render it. Patches welcome! */
#define REVERSE_WINDING() \
GPUVertex* tv = v0; \
v0 = v1; \
v1 = tv; \
EdgeEquationInit(&e0, &v0->x, &v1->x); \
EdgeEquationInit(&e1, &v1->x, &v2->x); \
EdgeEquationInit(&e2, &v2->x, &v0->x); \
area = 0.5f * (e0.c + e1.c + e2.c) \
// Check if triangle is backfacing.
if(CULL_MODE == GPU_CULLING_CCW) {
if(area < 0) {
return;
}
} else if(CULL_MODE == GPU_CULLING_CW) {
if(area < 0) {
// We only draw front-facing polygons, so swap
// the back to front and draw
REVERSE_WINDING();
} else {
// Front facing, so bail
return;
}
} else if(area < 0) {
/* We're not culling, but this is backfacing, so swap vertices and edges */
REVERSE_WINDING();
}
ParameterEquation r, g, b;
ParameterEquationInit(&r, v0->bgra[2], v1->bgra[2], v2->bgra[2], &e0, &e1, &e2, area);
ParameterEquationInit(&g, v0->bgra[1], v1->bgra[1], v2->bgra[1], &e0, &e1, &e2, area);
ParameterEquationInit(&b, v0->bgra[0], v1->bgra[0], v2->bgra[0], &e0, &e1, &e2, area);
// Add 0.5 to sample at pixel centers.
for (float x = minX + 0.5f, xm = maxX + 0.5f; x <= xm; x += 1.0f)
for (float y = minY + 0.5f, ym = maxY + 0.5f; y <= ym; y += 1.0f)
{
if (EdgeEquationTestPoint(&e0, x, y) && EdgeEquationTestPoint(&e1, x, y) && EdgeEquationTestPoint(&e2, x, y)) {
int rint = ParameterEquationEvaluate(&r, x, y);
int gint = ParameterEquationEvaluate(&g, x, y);
int bint = ParameterEquationEvaluate(&b, x, y);
SDL_SetRenderDrawColor(RENDERER, rint, gint, bint, 255);
SDL_RenderDrawPoint(RENDERER, x, y);
}
}
}
void InitGPU(_Bool autosort, _Bool fsaa) {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
WINDOW = SDL_CreateWindow(
"GLdc",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
vid_mode.width, vid_mode.height,
SDL_WINDOW_SHOWN
);
RENDERER = SDL_CreateRenderer(
WINDOW, -1, SDL_RENDERER_ACCELERATED
);
}
void SceneBegin() {
SDL_SetRenderDrawColor(RENDERER, BACKGROUND_COLOR[0], BACKGROUND_COLOR[1], BACKGROUND_COLOR[2], 0);
SDL_RenderClear(RENDERER);
}
void SceneListBegin(GPUList list) {
}
void SceneListSubmit(void* src, int n) {
uint32_t vertex_counter = 0;
const uint32_t* flags = (const uint32_t*) src;
uint32_t step = sizeof(GPUVertex) / sizeof(uint32_t);
for(int i = 0; i < n; ++i, flags += step) {
if((*flags & GPU_CMD_POLYHDR) == GPU_CMD_POLYHDR) {
vertex_counter = 0;
uint32_t mode1 = *(flags + 1);
// Extract culling mode
uint32_t mask = mode1 & GPU_TA_PM1_CULLING_MASK;
CULL_MODE = mask >> GPU_TA_PM1_CULLING_SHIFT;
} else {
switch(*flags) {
case GPU_CMD_VERTEX_EOL:
case GPU_CMD_VERTEX: // Fallthrough
vertex_counter++;
break;
default:
break;
}
}
if(vertex_counter > 2) {
GPUVertex* v0 = (GPUVertex*) (flags - step - step);
GPUVertex* v1 = (GPUVertex*) (flags - step);
GPUVertex* v2 = (GPUVertex*) (flags);
(vertex_counter % 2 == 0) ? DrawTriangle(v0, v1, v2) : DrawTriangle(v1, v0, v2);
}
if((*flags) == GPU_CMD_VERTEX_EOL) {
vertex_counter = 0;
}
}
}
void SceneListFinish() {
}
void SceneFinish() {
SDL_RenderPresent(RENDERER);
/* Only sensible place to hook the quit signal */
SDL_Event e = {0};
while (SDL_PollEvent(&e))
switch (e.type) {
case SDL_QUIT:
exit(0);
break;
default:
break;
}
}
void UploadMatrix4x4(const Matrix4x4* mat) {
memcpy(&MATRIX, mat, sizeof(Matrix4x4));
}
void MultiplyMatrix4x4(const Matrix4x4* mat) {
Matrix4x4 product;
product[0] = MATRIX[0] * (*mat)[0] + MATRIX[4] * (*mat)[1] + MATRIX[8] * (*mat)[2] + MATRIX[12] * (*mat)[3];
product[1] = MATRIX[1] * (*mat)[0] + MATRIX[5] * (*mat)[1] + MATRIX[9] * (*mat)[2] + MATRIX[13] * (*mat)[3];
product[2] = MATRIX[2] * (*mat)[0] + MATRIX[6] * (*mat)[1] + MATRIX[10] * (*mat)[2] + MATRIX[14] * (*mat)[3];
product[3] = MATRIX[3] * (*mat)[0] + MATRIX[7] * (*mat)[1] + MATRIX[11] * (*mat)[2] + MATRIX[15] * (*mat)[3];
product[4] = MATRIX[0] * (*mat)[4] + MATRIX[4] * (*mat)[5] + MATRIX[8] * (*mat)[6] + MATRIX[12] * (*mat)[7];
product[5] = MATRIX[1] * (*mat)[4] + MATRIX[5] * (*mat)[5] + MATRIX[9] * (*mat)[6] + MATRIX[13] * (*mat)[7];
product[6] = MATRIX[2] * (*mat)[4] + MATRIX[6] * (*mat)[5] + MATRIX[10] * (*mat)[6] + MATRIX[14] * (*mat)[7];
product[7] = MATRIX[3] * (*mat)[4] + MATRIX[7] * (*mat)[5] + MATRIX[11] * (*mat)[6] + MATRIX[15] * (*mat)[7];
product[8] = MATRIX[0] * (*mat)[8] + MATRIX[4] * (*mat)[9] + MATRIX[8] * (*mat)[10] + MATRIX[12] * (*mat)[11];
product[9] = MATRIX[1] * (*mat)[8] + MATRIX[5] * (*mat)[9] + MATRIX[9] * (*mat)[10] + MATRIX[13] * (*mat)[11];
product[10] = MATRIX[2] * (*mat)[8] + MATRIX[6] * (*mat)[9] + MATRIX[10] * (*mat)[10] + MATRIX[14] * (*mat)[11];
product[11] = MATRIX[3] * (*mat)[8] + MATRIX[7] * (*mat)[9] + MATRIX[11] * (*mat)[10] + MATRIX[15] * (*mat)[11];
product[12] = MATRIX[0] * (*mat)[12] + MATRIX[4] * (*mat)[13] + MATRIX[8] * (*mat)[14] + MATRIX[12] * (*mat)[15];
product[13] = MATRIX[1] * (*mat)[12] + MATRIX[5] * (*mat)[13] + MATRIX[9] * (*mat)[14] + MATRIX[13] * (*mat)[15];
product[14] = MATRIX[2] * (*mat)[12] + MATRIX[6] * (*mat)[13] + MATRIX[10] * (*mat)[14] + MATRIX[14] * (*mat)[15];
product[15] = MATRIX[3] * (*mat)[12] + MATRIX[7] * (*mat)[13] + MATRIX[11] * (*mat)[14] + MATRIX[15] * (*mat)[15];
UploadMatrix4x4(&product);
}
void DownloadMatrix4x4(Matrix4x4* mat) {
memcpy(mat, &MATRIX, sizeof(Matrix4x4));
}
const VideoMode* GetVideoMode() {
return &vid_mode;
}
size_t GPUMemoryAvailable() {
return AVAILABLE_VRAM;
}
void* GPUMemoryAlloc(size_t size) {
if(size > AVAILABLE_VRAM) {
return NULL;
} else {
AVAILABLE_VRAM -= size;
return malloc(size);
}
}
void GPUSetPaletteFormat(GPUPaletteFormat format) {
}
void GPUSetPaletteEntry(uint32_t idx, uint32_t value) {
}
void GPUSetBackgroundColour(float r, float g, float b) {
BACKGROUND_COLOR[0] = r * 255.0f;
BACKGROUND_COLOR[1] = g * 255.0f;
BACKGROUND_COLOR[2] = b * 255.0f;
}
void GPUSetAlphaCutOff(uint8_t v) {
}
void GPUSetClearDepth(float v) {
}
void GPUSetFogLinear(float start, float end) {
}
void GPUSetFogExp(float density) {
}
void GPUSetFogExp2(float density) {
}
void GPUSetFogColor(float r, float g, float b, float a) {
}
void TransformVec3NoMod(const float* v, float* ret) {
ret[0] = v[0] * MATRIX[0] + v[1] * MATRIX[4] + v[2] * MATRIX[8] + 1.0f * MATRIX[12];
ret[1] = v[0] * MATRIX[1] + v[1] * MATRIX[5] + v[2] * MATRIX[9] + 1.0f * MATRIX[13];
ret[2] = v[0] * MATRIX[2] + v[1] * MATRIX[6] + v[2] * MATRIX[10] + 1.0f * MATRIX[14];
}
void TransformVec4NoMod(const float* v, float* ret) {
ret[0] = v[0] * MATRIX[0] + v[1] * MATRIX[4] + v[2] * MATRIX[8] + v[3] * MATRIX[12];
ret[1] = v[0] * MATRIX[1] + v[1] * MATRIX[5] + v[2] * MATRIX[9] + v[3] * MATRIX[13];
ret[2] = v[0] * MATRIX[2] + v[1] * MATRIX[6] + v[2] * MATRIX[10] + v[3] * MATRIX[14];
ret[3] = v[0] * MATRIX[3] + v[1] * MATRIX[7] + v[2] * MATRIX[11] + v[3] * MATRIX[15];
}
void TransformVec3(float* v) {
float ret[3];
TransformVec3NoMod(v, ret);
FASTCPY(v, ret, sizeof(float) * 3);
}
void TransformVec4(float* v) {
float ret[4];
TransformVec4NoMod(v, ret);
FASTCPY(v, ret, sizeof(float) * 4);
}
void TransformVertices(Vertex* vertices, const int count) {
float ret[4];
for(int i = 0; i < count; ++i, ++vertices) {
ret[0] = vertices->xyz[0];
ret[1] = vertices->xyz[1];
ret[2] = vertices->xyz[2];
ret[3] = 1.0f;
TransformVec4(ret);
vertices->xyz[0] = ret[0];
vertices->xyz[1] = ret[1];
vertices->xyz[2] = ret[2];
vertices->w = ret[3];
}
}

69
GL/platforms/software.h Normal file
View File

@ -0,0 +1,69 @@
#pragma once
#include <math.h>
#include <memory.h>
#include "../types.h"
#define MATH_Fast_Divide(n, d) (n / d)
#define MATH_fmac(a, b, c) (a * b + c)
#define MATH_Fast_Sqrt(x) sqrtf((x))
#define MATH_fsrra(x) (1.0f / sqrtf((x)))
#define MATH_Fast_Invert(x) (1.0f / (x))
#define FASTCPY(dst, src, bytes) memcpy(dst, src, bytes)
#define FASTCPY4(dst, src, bytes) memcpy(dst, src, bytes)
#define MEMSET4(dst, v, size) memset((dst), (v), (size))
#define VEC3_NORMALIZE(x, y, z) \
do { \
float l = MATH_fsrra((x) * (x) + (y) * (y) + (z) * (z)); \
x *= l; \
y *= l; \
z *= l; \
} while(0)
#define VEC3_LENGTH(x, y, z, d) \
d = MATH_Fast_Sqrt((x) * (x) + (y) * (y) + (z) * (z))
#define VEC3_DOT(x1, y1, z1, x2, y2, z2, d) \
d = (x1 * x2) + (y1 * y2) + (z1 * z2)
struct PolyHeader;
struct PolyContext;
void UploadMatrix4x4(const Matrix4x4* mat);
void MultiplyMatrix4x4(const Matrix4x4* mat);
void DownloadMatrix4x4(Matrix4x4* mat);
/* Transform a 3-element vector in-place using the stored matrix (w == 1) */
void TransformVec3(float* v);
/* Transform a 3-element vector using the stored matrix (w == 1) */
void TransformVec3NoMod(const float* v, float* ret);
/* Transform a 3-element normal using the stored matrix (w == 0)*/
static inline void TransformNormalNoMod(const float* xIn, float* xOut) {
}
void TransformVertices(Vertex* vertices, const int count);
void InitGPU(_Bool autosort, _Bool fsaa);
enum GPUPaletteFormat;
size_t GPUMemoryAvailable();
void* GPUMemoryAlloc(size_t size);
void GPUSetPaletteFormat(GPUPaletteFormat format);
void GPUSetPaletteEntry(uint32_t idx, uint32_t value);
void GPUSetBackgroundColour(float r, float g, float b);
void GPUSetAlphaCutOff(uint8_t v);
void GPUSetClearDepth(float v);
void GPUSetFogLinear(float start, float end);
void GPUSetFogExp(float density);
void GPUSetFogExp2(float density);
void GPUSetFogColor(float r, float g, float b, float a);

View File

@ -0,0 +1,20 @@
#include "edge_equation.h"
void EdgeEquationInit(EdgeEquation* edge, const float* v0, const float* v1) {
edge->a = v0[1] - v1[1];
edge->b = v1[0] - v0[0];
edge->c = -(edge->a * (v0[0] + v1[0]) + edge->b * (v0[1] + v1[1])) / 2;
edge->tie = edge->a != 0 ? edge->a > 0 : edge->b > 0;
}
float EdgeEquationEvaluate(const EdgeEquation* edge, float x, float y) {
return edge->a * x + edge->b * y + edge->c;
}
bool EdgeEquationTestValue(const EdgeEquation* edge, float value) {
return (value >= 0 || (value == 0 && edge->tie));
}
bool EdgeEquationTestPoint(const EdgeEquation* edge, float x, float y) {
return EdgeEquationTestValue(edge, EdgeEquationEvaluate(edge, x, y));
}

View File

@ -0,0 +1,17 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
typedef struct EdgeEquation {
float a;
float b;
float c;
bool tie;
} EdgeEquation;
void EdgeEquationInit(EdgeEquation* edge, const float* v0, const float* v1);
float EdgeEquationEvaluate(const EdgeEquation* edge, float x, float y);
bool EdgeEquationTestValue(const EdgeEquation* edge, float value);
bool EdgeEquationTestPoint(const EdgeEquation* edge, float x, float y);

View File

@ -0,0 +1,16 @@
#include "parameter_equation.h"
#include "edge_equation.h"
void ParameterEquationInit(ParameterEquation* equation, float p0, float p1, float p2, const EdgeEquation* e0, const EdgeEquation* e1, const EdgeEquation* e2, float area) {
float factor = 1.0f / (2.0f * area);
equation->a = factor * (p0 * e0->a + p1 * e1->a + p2 * e2->a);
equation->b = factor * (p0 * e0->b + p1 * e1->b + p2 * e2->b);
equation->c = factor * (p0 * e0->c + p1 * e1->c + p2 * e2->c);
}
float ParameterEquationEvaluate(const ParameterEquation* equation, float x, float y) {
return equation->a * x + equation->b * y + equation->c;
}

View File

@ -0,0 +1,16 @@
#pragma once
typedef struct ParameterEquation {
float a;
float b;
float c;
} ParameterEquation;
struct EdgeEquation;
void ParameterEquationInit(
ParameterEquation* equation,
float p0, float p1, float p2,
const struct EdgeEquation* e0, const struct EdgeEquation* e1, const struct EdgeEquation* e2, float area);
float ParameterEquationEvaluate(const ParameterEquation* equation, float x, float y);

View File

@ -2,16 +2,17 @@
#define PRIVATE_H
#include <stdint.h>
#include <dc/matrix.h>
#include <dc/pvr.h>
#include <dc/vec3f.h>
#include <dc/fmath.h>
#include <dc/matrix3d.h>
#include <stdio.h>
#include "platform.h"
#include "types.h"
#include "../include/GL/gl.h"
#include "../include/GL/glext.h"
#include "../include/GL/glkos.h"
#include "../include/gl.h"
#include "../containers/aligned_vector.h"
#include "../containers/named_array.h"
#include "sh4_math.h"
extern void* memcpy4 (void *dest, const void *src, size_t count);
@ -20,12 +21,6 @@ extern void* memcpy4 (void *dest, const void *src, size_t count);
#define GL_FORCE_INLINE static GL_INLINE_DEBUG
#define _GL_UNUSED(x) (void)(x)
#define FASTCPY(dst, src, bytes) \
(bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy(dst, src, bytes);
#define FASTCPY4(dst, src, bytes) \
(bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy4(dst, src, bytes);
#define _PACK4(v) ((v * 0xF) / 0xFF)
#define PACK_ARGB4444(a,r,g,b) (_PACK4(a) << 12) | (_PACK4(r) << 8) | (_PACK4(g) << 4) | (_PACK4(b))
#define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) )
@ -46,7 +41,6 @@ extern void* memcpy4 (void *dest, const void *src, size_t count);
#define MAX_TEXTURE_SIZE 1024
typedef float Matrix4x4[16];
/* This gives us an easy way to switch
* internal matrix order if necessary */
@ -89,9 +83,6 @@ typedef float Matrix4x4[16];
#define M15 15
#endif
typedef struct {
pvr_poly_hdr_t hdr;
} PVRHeader;
typedef struct {
unsigned int flags; /* Constant PVR_CMD_USERCLIP */
@ -192,19 +183,6 @@ typedef struct {
GLfloat specularMaterial[4];
} LightSource;
typedef struct {
/* Same 32 byte layout as pvr_vertex_t */
uint32_t flags;
float xyz[3];
float uv[2];
uint8_t bgra[4];
/* In the pvr_vertex_t structure, this next 4 bytes is oargb
* but we're not using that for now, so having W here makes the code
* simpler */
float w;
} Vertex;
#define argbcpy(dst, src) \
*((GLuint*) dst) = *((GLuint*) src) \
@ -263,7 +241,7 @@ typedef struct {
AlignedVector* extras;
} SubmissionTarget;
PVRHeader* _glSubmissionTargetHeader(SubmissionTarget* target);
PolyHeader* _glSubmissionTargetHeader(SubmissionTarget* target);
Vertex* _glSubmissionTargetStart(SubmissionTarget* target);
Vertex* _glSubmissionTargetEnd(SubmissionTarget* target);
@ -310,10 +288,10 @@ Matrix4x4* _glGetModelViewMatrix();
void _glWipeTextureOnFramebuffers(GLuint texture);
GLubyte _glCheckImmediateModeInactive(const char* func);
pvr_poly_cxt_t* _glGetPVRContext();
PolyContext* _glGetPVRContext();
GLubyte _glInitTextures();
void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit);
void _glUpdatePVRTextureContext(PolyContext* context, GLshort textureUnit);
void _glAllocateSpaceForMipmaps(TextureObject* active);
typedef struct {
@ -365,7 +343,7 @@ typedef struct {
float finalColour[4]; //16 bytes (to 40)
} EyeSpaceData;
extern void _glPerformLighting(Vertex* vertices, EyeSpaceData *es, const int32_t count);
extern void _glPerformLighting(Vertex* vertices, EyeSpaceData *es, const uint32_t count);
unsigned char _glIsClippingEnabled();
void _glEnableClipping(unsigned char v);
@ -378,7 +356,6 @@ GLuint _glFreeTextureMemory();
GLuint _glUsedTextureMemory();
GLuint _glFreeContiguousTextureMemory();
#define PVR_VERTEX_BUF_SIZE 2560 * 256
#define MAX_TEXTURE_UNITS 2
#define MAX_LIGHTS 8

View File

@ -1,4 +1,3 @@
#include <kos.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>

View File

@ -2,19 +2,11 @@
#include <string.h>
#include <stdio.h>
#include <dc/pvr.h>
#include <dc/vec3f.h>
#include <dc/video.h>
#include "../include/gl.h"
#include "../include/glext.h"
#include "../include/glkos.h"
#include "private.h"
static pvr_poly_cxt_t GL_CONTEXT;
static PolyContext GL_CONTEXT;
pvr_poly_cxt_t* _glGetPVRContext() {
PolyContext *_glGetPVRContext() {
return &GL_CONTEXT;
}
@ -43,12 +35,12 @@ GLboolean _glIsSharedTexturePaletteEnabled() {
static int _calc_pvr_face_culling() {
if(!CULLING_ENABLED) {
return PVR_CULLING_NONE;
return GPU_CULLING_NONE;
} else {
if(CULL_FACE == GL_BACK) {
return (FRONT_FACE == GL_CW) ? PVR_CULLING_CCW : PVR_CULLING_CW;
return (FRONT_FACE == GL_CW) ? GPU_CULLING_CCW : GPU_CULLING_CW;
} else {
return (FRONT_FACE == GL_CCW) ? PVR_CULLING_CCW : PVR_CULLING_CW;
return (FRONT_FACE == GL_CCW) ? GPU_CULLING_CCW : GPU_CULLING_CW;
}
}
}
@ -58,28 +50,28 @@ static GLboolean DEPTH_TEST_ENABLED = GL_FALSE;
static int _calc_pvr_depth_test() {
if(!DEPTH_TEST_ENABLED) {
return PVR_DEPTHCMP_ALWAYS;
return GPU_DEPTHCMP_ALWAYS;
}
switch(DEPTH_FUNC) {
case GL_NEVER:
return PVR_DEPTHCMP_NEVER;
return GPU_DEPTHCMP_NEVER;
case GL_LESS:
return PVR_DEPTHCMP_GREATER;
return GPU_DEPTHCMP_GREATER;
case GL_EQUAL:
return PVR_DEPTHCMP_EQUAL;
return GPU_DEPTHCMP_EQUAL;
case GL_LEQUAL:
return PVR_DEPTHCMP_GEQUAL;
return GPU_DEPTHCMP_GEQUAL;
case GL_GREATER:
return PVR_DEPTHCMP_LESS;
return GPU_DEPTHCMP_LESS;
case GL_NOTEQUAL:
return PVR_DEPTHCMP_NOTEQUAL;
return GPU_DEPTHCMP_NOTEQUAL;
case GL_GEQUAL:
return PVR_DEPTHCMP_LEQUAL;
return GPU_DEPTHCMP_LEQUAL;
break;
case GL_ALWAYS:
default:
return PVR_DEPTHCMP_ALWAYS;
return GPU_DEPTHCMP_ALWAYS;
}
}
@ -105,32 +97,32 @@ GLboolean _glIsAlphaTestEnabled() {
static int _calcPVRBlendFactor(GLenum factor) {
switch(factor) {
case GL_ZERO:
return PVR_BLEND_ZERO;
return GPU_BLEND_ZERO;
case GL_SRC_ALPHA:
return PVR_BLEND_SRCALPHA;
return GPU_BLEND_SRCALPHA;
case GL_DST_COLOR:
return PVR_BLEND_DESTCOLOR;
return GPU_BLEND_DESTCOLOR;
case GL_DST_ALPHA:
return PVR_BLEND_DESTALPHA;
return GPU_BLEND_DESTALPHA;
case GL_ONE_MINUS_DST_COLOR:
return PVR_BLEND_INVDESTCOLOR;
return GPU_BLEND_INVDESTCOLOR;
case GL_ONE_MINUS_SRC_ALPHA:
return PVR_BLEND_INVSRCALPHA;
return GPU_BLEND_INVSRCALPHA;
case GL_ONE_MINUS_DST_ALPHA:
return PVR_BLEND_INVDESTALPHA;
return GPU_BLEND_INVDESTALPHA;
case GL_ONE:
return PVR_BLEND_ONE;
return GPU_BLEND_ONE;
default:
fprintf(stderr, "Invalid blend mode: %u\n", (unsigned int) factor);
return PVR_BLEND_ONE;
return GPU_BLEND_ONE;
}
}
static void _updatePVRBlend(pvr_poly_cxt_t* context) {
static void _updatePVRBlend(PolyContext* context) {
if(BLEND_ENABLED || ALPHA_TEST_ENABLED) {
context->gen.alpha = PVR_ALPHA_ENABLE;
context->gen.alpha = GPU_ALPHA_ENABLE;
} else {
context->gen.alpha = PVR_ALPHA_DISABLE;
context->gen.alpha = GPU_ALPHA_DISABLE;
}
context->blend.src = _calcPVRBlendFactor(BLEND_SFACTOR);
@ -158,21 +150,21 @@ GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func) {
GLboolean TEXTURES_ENABLED [] = {GL_FALSE, GL_FALSE};
void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
void _glUpdatePVRTextureContext(PolyContext *context, GLshort textureUnit) {
const TextureObject *tx1 = (textureUnit == 0) ? _glGetTexture0() : _glGetTexture1();
/* Disable all texturing to start with */
context->txr.enable = PVR_TEXTURE_DISABLE;
context->txr2.enable = PVR_TEXTURE_DISABLE;
context->txr2.alpha = PVR_TXRALPHA_DISABLE;
context->txr.enable = GPU_TEXTURE_DISABLE;
context->txr2.enable = GPU_TEXTURE_DISABLE;
context->txr2.alpha = GPU_TXRALPHA_DISABLE;
if(!TEXTURES_ENABLED[textureUnit] || !tx1) {
return;
}
context->txr.alpha = (BLEND_ENABLED || ALPHA_TEST_ENABLED) ? PVR_TXRALPHA_ENABLE : PVR_TXRALPHA_DISABLE;
context->txr.alpha = (BLEND_ENABLED || ALPHA_TEST_ENABLED) ? GPU_TXRALPHA_ENABLE : GPU_TXRALPHA_DISABLE;
GLuint filter = PVR_FILTER_NEAREST;
GLuint filter = GPU_FILTER_NEAREST;
GLboolean enableMipmaps = GL_FALSE;
switch(tx1->minFilter) {
@ -199,17 +191,17 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
if(enableMipmaps) {
if(tx1->minFilter == GL_LINEAR_MIPMAP_NEAREST) {
filter = PVR_FILTER_TRILINEAR1;
filter = GPU_FILTER_TRILINEAR1;
} else if(tx1->minFilter == GL_LINEAR_MIPMAP_LINEAR) {
filter = PVR_FILTER_TRILINEAR2;
filter = GPU_FILTER_TRILINEAR2;
} else if(tx1->minFilter == GL_NEAREST_MIPMAP_LINEAR) {
filter = PVR_FILTER_BILINEAR;
filter = GPU_FILTER_BILINEAR;
} else {
filter = PVR_FILTER_NEAREST;
filter = GPU_FILTER_NEAREST;
}
} else {
if(tx1->minFilter == GL_LINEAR && tx1->magFilter == GL_LINEAR) {
filter = PVR_FILTER_BILINEAR;
filter = GPU_FILTER_BILINEAR;
}
}
@ -221,7 +213,7 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
}
if(tx1->data) {
context->txr.enable = PVR_TEXTURE_ENABLE;
context->txr.enable = GPU_TEXTURE_ENABLE;
context->txr.filter = filter;
context->txr.width = tx1->width;
context->txr.height = tx1->height;
@ -239,14 +231,14 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
if(tx1->isPaletted) {
if(_glIsSharedTexturePaletteEnabled()) {
TexturePalette* palette = _glGetSharedPalette(tx1->shared_bank);
context->txr.format |= PVR_TXRFMT_8BPP_PAL(palette->bank);
context->txr.format |= GPUPaletteSelect8BPP(palette->bank);
} else {
context->txr.format |= PVR_TXRFMT_8BPP_PAL((tx1->palette) ? tx1->palette->bank : 0);
context->txr.format |= GPUPaletteSelect8BPP((tx1->palette) ? tx1->palette->bank : 0);
}
}
context->txr.env = tx1->env;
context->txr.uv_flip = PVR_UVFLIP_NONE;
context->txr.uv_flip = GPU_UVFLIP_NONE;
context->txr.uv_clamp = tx1->uv_clamp;
}
}
@ -262,12 +254,12 @@ GLboolean _glIsColorMaterialEnabled() {
static GLfloat CLEAR_COLOUR[3];
void _glInitContext() {
memset(&GL_CONTEXT, 0, sizeof(pvr_poly_cxt_t));
memset(&GL_CONTEXT, 0, sizeof(PolyContext));
GL_CONTEXT.list_type = PVR_LIST_OP_POLY;
GL_CONTEXT.fmt.color = PVR_CLRFMT_ARGBPACKED;
GL_CONTEXT.fmt.uv = PVR_UVFMT_32BIT;
GL_CONTEXT.gen.color_clamp = PVR_CLRCLAMP_DISABLE;
GL_CONTEXT.list_type = GPU_LIST_OP_POLY;
GL_CONTEXT.fmt.color = GPU_CLRFMT_ARGBPACKED;
GL_CONTEXT.fmt.uv = GPU_UVFMT_32BIT;
GL_CONTEXT.gen.color_clamp = GPU_CLRCLAMP_DISABLE;
glClearDepth(1.0f);
glDepthFunc(GL_LESS);
@ -309,13 +301,13 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
_updatePVRBlend(&GL_CONTEXT);
} break;
case GL_SCISSOR_TEST: {
GL_CONTEXT.gen.clip_mode = PVR_USERCLIP_INSIDE;
GL_CONTEXT.gen.clip_mode = GPU_USERCLIP_INSIDE;
} break;
case GL_LIGHTING: {
LIGHTING_ENABLED = GL_TRUE;
} break;
case GL_FOG:
GL_CONTEXT.gen.fog_type = PVR_FOG_TABLE;
GL_CONTEXT.gen.fog_type = GPU_FOG_TABLE;
break;
case GL_COLOR_MATERIAL:
COLOR_MATERIAL_ENABLED = GL_TRUE;
@ -372,13 +364,13 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
_updatePVRBlend(&GL_CONTEXT);
break;
case GL_SCISSOR_TEST: {
GL_CONTEXT.gen.clip_mode = PVR_USERCLIP_DISABLE;
GL_CONTEXT.gen.clip_mode = GPU_USERCLIP_DISABLE;
} break;
case GL_LIGHTING: {
LIGHTING_ENABLED = GL_FALSE;
} break;
case GL_FOG:
GL_CONTEXT.gen.fog_type = PVR_FOG_DISABLE;
GL_CONTEXT.gen.fog_type = GPU_FOG_DISABLE;
break;
case GL_COLOR_MATERIAL:
COLOR_MATERIAL_ENABLED = GL_FALSE;
@ -419,7 +411,7 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
/* Clear Caps */
GLAPI void APIENTRY glClear(GLuint mode) {
if(mode & GL_COLOR_BUFFER_BIT) {
pvr_set_bg_color(CLEAR_COLOUR[0], CLEAR_COLOUR[1], CLEAR_COLOUR[2]);
GPUSetBackgroundColour(CLEAR_COLOUR[0], CLEAR_COLOUR[1], CLEAR_COLOUR[2]);
}
}
@ -429,9 +421,12 @@ GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
if(b > 1) b = 1;
if(a > 1) a = 1;
CLEAR_COLOUR[0] = r * a;
CLEAR_COLOUR[1] = g * a;
CLEAR_COLOUR[2] = b * a;
/* FIXME: The background-poly doesn't take an alpha value */
_GL_UNUSED(a);
CLEAR_COLOUR[0] = r;
CLEAR_COLOUR[1] = g;
CLEAR_COLOUR[2] = b;
}
/* Depth Testing */
@ -441,7 +436,7 @@ GLAPI void APIENTRY glClearDepthf(GLfloat depth) {
GLAPI void APIENTRY glClearDepth(GLfloat depth) {
/* We reverse because using invW means that farther Z == lower number */
pvr_set_zclip(1.0f - depth);
GPUSetClearDepth(1.0f - depth);
}
GLAPI void APIENTRY glDrawBuffer(GLenum mode) {
@ -455,7 +450,7 @@ GLAPI void APIENTRY glReadBuffer(GLenum mode) {
}
GLAPI void APIENTRY glDepthMask(GLboolean flag) {
GL_CONTEXT.depth.write = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE;
GL_CONTEXT.depth.write = (flag == GL_TRUE) ? GPU_DEPTHWRITE_ENABLE : GPU_DEPTHWRITE_DISABLE;
}
GLAPI void APIENTRY glDepthFunc(GLenum func) {
@ -484,12 +479,12 @@ GLAPI void APIENTRY glCullFace(GLenum mode) {
}
GLenum _glGetShadeModel() {
return (GL_CONTEXT.gen.shading == PVR_SHADE_FLAT) ? GL_FLAT : GL_SMOOTH;
return (GL_CONTEXT.gen.shading == GPU_SHADE_FLAT) ? GL_FLAT : GL_SMOOTH;
}
/* Shading - Flat or Goraud */
GLAPI void APIENTRY glShadeModel(GLenum mode) {
GL_CONTEXT.gen.shading = (mode == GL_SMOOTH) ? PVR_SHADE_GOURAUD : PVR_SHADE_FLAT;
GL_CONTEXT.gen.shading = (mode == GL_SMOOTH) ? GPU_SHADE_GOURAUD : GPU_SHADE_FLAT;
}
/* Blending */
@ -499,7 +494,6 @@ GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) {
_updatePVRBlend(&GL_CONTEXT);
}
#define PT_ALPHA_REF 0x011c
GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref) {
GLint validFuncs[] = {
@ -512,7 +506,7 @@ GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref) {
}
GLubyte val = (GLubyte)(ref * 255.0f);
PVR_SET(PT_ALPHA_REF, val);
GPUSetAlphaCutOff(val);
}
void glLineWidth(GLfloat width) {
@ -561,6 +555,9 @@ void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
PVRTileClipCommand *c = aligned_vector_extend(&_glActivePolyList()->vector, 1);
GLint miny, maxx, maxy;
const VideoMode* vid_mode = GetVideoMode();
GLsizei gl_scissor_width = MAX( MIN(width, vid_mode->width), 0 );
GLsizei gl_scissor_height = MAX( MIN(height, vid_mode->height), 0 );
@ -570,7 +567,7 @@ void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
maxy = (gl_scissor_height + miny);
/* load command structure while mapping screen coords to TA tiles */
c->flags = PVR_CMD_USERCLIP;
c->flags = GPU_CMD_USERCLIP;
c->d1 = c->d2 = c->d3 = 0;
c->sx = CLAMP(x / 32, 0, vid_mode->width / 32);
c->sy = CLAMP(miny / 32, 0, vid_mode->height / 32);
@ -583,7 +580,7 @@ GLboolean APIENTRY glIsEnabled(GLenum cap) {
case GL_DEPTH_TEST:
return DEPTH_TEST_ENABLED;
case GL_SCISSOR_TEST:
return GL_CONTEXT.gen.clip_mode == PVR_USERCLIP_INSIDE;
return GL_CONTEXT.gen.clip_mode == GPU_USERCLIP_INSIDE;
case GL_CULL_FACE:
return CULLING_ENABLED;
case GL_LIGHTING:
@ -643,10 +640,10 @@ void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) {
void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) {
switch(pname) {
case GL_PROJECTION_MATRIX:
memcpy4(params, _glGetProjectionMatrix(), sizeof(float) * 16);
FASTCPY4(params, _glGetProjectionMatrix(), sizeof(float) * 16);
break;
case GL_MODELVIEW_MATRIX:
memcpy4(params, _glGetModelViewMatrix(), sizeof(float) * 16);
FASTCPY4(params, _glGetModelViewMatrix(), sizeof(float) * 16);
break;
case GL_POLYGON_OFFSET_FACTOR:
*params = OFFSET_FACTOR;

View File

@ -7,13 +7,10 @@
#include <string.h>
#include "config.h"
#include "../include/glext.h"
#include "../include/glkos.h"
#include "platform.h"
#include "yalloc/yalloc.h"
#include <kos/string.h>
/* We always leave this amount of vram unallocated to prevent
* issues with the allocator */
#define PVR_MEM_BUFFER_SIZE (64 * 1024)
@ -55,7 +52,7 @@ static TexturePalette* _initTexturePalette() {
TexturePalette* palette = (TexturePalette*) malloc(sizeof(TexturePalette));
assert(palette);
memset4(palette, 0x0, sizeof(TexturePalette));
MEMSET4(palette, 0x0, sizeof(TexturePalette));
palette->bank = -1;
return palette;
}
@ -115,6 +112,54 @@ static void _glReleasePaletteSlot(GLshort slot, GLushort size) {
}
}
/* Linear/iterative twiddling algorithm from Marcus' tatest */
#define TWIDTAB(x) ( (x&1)|((x&2)<<1)|((x&4)<<2)|((x&8)<<3)|((x&16)<<4)| \
((x&32)<<5)|((x&64)<<6)|((x&128)<<7)|((x&256)<<8)|((x&512)<<9) )
#define TWIDOUT(x, y) ( TWIDTAB((y)) | (TWIDTAB((x)) << 1) )
static void GPUTextureTwiddle8PPP(void* src, void* dst, uint32_t w, uint32_t h) {
uint32_t x, y, yout, min, mask;
min = MIN(w, h);
mask = min - 1;
uint8_t* pixels;
uint16_t* vtex;
pixels = (uint8_t*) src;
vtex = (uint16_t*) dst;
for(y = 0; y < h; y += 2) {
yout = y;
for(x = 0; x < w; x++) {
vtex[TWIDOUT((yout & mask) / 2, x & mask) +
(x / min + yout / min)*min * min / 2] =
pixels[y * w + x] | (pixels[(y + 1) * w + x] << 8);
}
}
}
static void GPUTextureTwiddle16BPP(void * src, void* dst, uint32_t w, uint32_t h) {
uint32_t x, y, yout, min, mask;
min = MIN(w, h);
mask = min - 1;
uint16_t* pixels;
uint16_t* vtex;
pixels = (uint16_t*) src;
vtex = (uint16_t*) dst;
for(y = 0; y < h; y++) {
yout = y;
for(x = 0; x < w; x++) {
vtex[TWIDOUT(x & mask, yout & mask) +
(x / min + yout / min)*min * min] = pixels[y * w + x];
}
}
}
TexturePalette* _glGetSharedPalette(GLshort bank) {
assert(bank >= 0 && bank < 4);
return SHARED_PALETTES[bank];
@ -124,10 +169,10 @@ void _glSetInternalPaletteFormat(GLenum val) {
INTERNAL_PALETTE_FORMAT = val;
if(INTERNAL_PALETTE_FORMAT == GL_RGBA4) {
pvr_set_pal_format(PVR_PAL_ARGB4444);
GPUSetPaletteFormat(GPU_PAL_ARGB4444);
} else {
assert(INTERNAL_PALETTE_FORMAT == GL_RGBA8);
pvr_set_pal_format(PVR_PAL_ARGB8888);
GPUSetPaletteFormat(GPU_PAL_ARGB8888);
}
}
@ -146,9 +191,9 @@ void _glApplyColorTable(TexturePalette* src) {
for(i = 0; i < src->width; ++i) {
GLubyte* entry = &src->data[i * 4];
if(INTERNAL_PALETTE_FORMAT == GL_RGBA8) {
pvr_set_pal_entry(offset + i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
GPUSetPaletteEntry(offset + i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
} else {
pvr_set_pal_entry(offset + i, PACK_ARGB4444(entry[3], entry[0], entry[1], entry[2]));
GPUSetPaletteEntry(offset + i, PACK_ARGB4444(entry[3], entry[0], entry[1], entry[2]));
}
}
}
@ -333,9 +378,9 @@ GLubyte _glInitTextures() {
memset((void*) BANKS_USED, 0x0, sizeof(BANKS_USED));
memset((void*) SUBBANKS_USED, 0x0, sizeof(SUBBANKS_USED));
size_t vram_free = pvr_mem_available();
size_t vram_free = GPUMemoryAvailable();
YALLOC_SIZE = vram_free - PVR_MEM_BUFFER_SIZE; /* Take all but 64kb VRAM */
YALLOC_BASE = pvr_mem_malloc(YALLOC_SIZE);
YALLOC_BASE = GPUMemoryAlloc(YALLOC_SIZE);
yalloc_init(YALLOC_BASE, YALLOC_SIZE);
return 1;
}
@ -375,7 +420,7 @@ static void _glInitializeTextureObject(TextureObject* txr, unsigned int id) {
txr->width = txr->height = 0;
txr->mipmap = 0;
txr->uv_clamp = 0;
txr->env = PVR_TXRENV_MODULATEALPHA;
txr->env = GPU_TXRENV_MODULATEALPHA;
txr->data = NULL;
txr->mipmapCount = 0;
txr->minFilter = GL_NEAREST;
@ -497,13 +542,13 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
switch(param) {
case GL_MODULATE:
active->env = PVR_TXRENV_MODULATEALPHA;
active->env = GPU_TXRENV_MODULATEALPHA;
break;
case GL_DECAL:
active->env = PVR_TXRENV_DECAL;
active->env = GPU_TXRENV_DECAL;
break;
case GL_REPLACE:
active->env = PVR_TXRENV_REPLACE;
active->env = GPU_TXRENV_REPLACE;
break;
default:
break;
@ -631,7 +676,7 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target,
active->data = yalloc_alloc_and_defrag(imageSize);
if(data) {
sq_cpy(active->data, data, imageSize);
FASTCPY(active->data, data, imageSize);
}
}
@ -722,47 +767,47 @@ static GLint _cleanInternalFormat(GLint internalFormat) {
* the type was already 1555 (1-bit alpha) in which case we return that
*/
if(type == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED;
return GPU_TXRFMT_ARGB1555 | GPU_TXRFMT_NONTWIDDLED;
} else if(type == GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS) {
return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED;
return GPU_TXRFMT_ARGB1555 | GPU_TXRFMT_TWIDDLED;
} else if(type == GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS) {
return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED;
return GPU_TXRFMT_ARGB4444 | GPU_TXRFMT_TWIDDLED;
} else {
return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED;
return GPU_TXRFMT_ARGB4444 | GPU_TXRFMT_NONTWIDDLED;
}
case GL_RED:
case GL_RGB:
/* No alpha? Return RGB565 which is the best we can do without using palettes */
return PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED;
return GPU_TXRFMT_RGB565 | GPU_TXRFMT_NONTWIDDLED;
/* Compressed and twiddled versions */
case GL_UNSIGNED_SHORT_5_6_5_TWID_KOS:
return PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED;
return GPU_TXRFMT_RGB565 | GPU_TXRFMT_TWIDDLED;
case GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS:
return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED;
return GPU_TXRFMT_ARGB4444 | GPU_TXRFMT_TWIDDLED;
case GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS:
return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED;
return GPU_TXRFMT_ARGB1555 | GPU_TXRFMT_TWIDDLED;
case GL_COMPRESSED_RGB_565_VQ_KOS:
case GL_COMPRESSED_RGB_565_VQ_MIPMAP_KOS:
return PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE;
return GPU_TXRFMT_RGB565 | GPU_TXRFMT_NONTWIDDLED | GPU_TXRFMT_VQ_ENABLE;
case GL_COMPRESSED_RGB_565_VQ_TWID_KOS:
case GL_COMPRESSED_RGB_565_VQ_MIPMAP_TWID_KOS:
return PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE;
return GPU_TXRFMT_RGB565 | GPU_TXRFMT_TWIDDLED | GPU_TXRFMT_VQ_ENABLE;
case GL_COMPRESSED_ARGB_4444_VQ_TWID_KOS:
case GL_COMPRESSED_ARGB_4444_VQ_MIPMAP_TWID_KOS:
return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE;
return GPU_TXRFMT_ARGB4444 | GPU_TXRFMT_TWIDDLED | GPU_TXRFMT_VQ_ENABLE;
case GL_COMPRESSED_ARGB_4444_VQ_KOS:
case GL_COMPRESSED_ARGB_4444_VQ_MIPMAP_KOS:
return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE;
return GPU_TXRFMT_ARGB4444 | GPU_TXRFMT_NONTWIDDLED | GPU_TXRFMT_VQ_ENABLE;
case GL_COMPRESSED_ARGB_1555_VQ_KOS:
case GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_KOS:
return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE;
return GPU_TXRFMT_ARGB1555 | GPU_TXRFMT_NONTWIDDLED | GPU_TXRFMT_VQ_ENABLE;
case GL_COMPRESSED_ARGB_1555_VQ_TWID_KOS:
case GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_TWID_KOS:
return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE;
return GPU_TXRFMT_ARGB1555 | GPU_TXRFMT_TWIDDLED | GPU_TXRFMT_VQ_ENABLE;
case GL_COLOR_INDEX8_EXT:
return PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_TWIDDLED;
return GPU_TXRFMT_PAL8BPP | GPU_TXRFMT_TWIDDLED;
case GL_COLOR_INDEX4_EXT:
return PVR_TXRFMT_PAL4BPP | PVR_TXRFMT_TWIDDLED;
return GPU_TXRFMT_PAL4BPP | GPU_TXRFMT_TWIDDLED;
default:
return 0;
}
@ -1228,9 +1273,9 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
const GLubyte *pixels = (GLubyte*) (conversionBuffer) ? conversionBuffer : data;
if(internalFormat == GL_COLOR_INDEX8_EXT) {
pvr_txr_load_ex((void*) pixels, targetData, width, height, PVR_TXRLOAD_8BPP);
GPUTextureTwiddle8PPP((void*) pixels, targetData, width, height);
} else {
pvr_txr_load_ex((void*) pixels, targetData, width, height, PVR_TXRLOAD_16BPP);
GPUTextureTwiddle16BPP((void*) pixels, targetData, width, height);
}
/* We make sure we remove nontwiddled and add twiddled. We could always

16
GL/types.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include <stdint.h>
typedef struct {
/* Same 32 byte layout as pvr_vertex_t */
uint32_t flags;
float xyz[3];
float uv[2];
uint8_t bgra[4];
/* In the pvr_vertex_t structure, this next 4 bytes is oargb
* but we're not using that for now, so having W here makes the code
* simpler */
float w;
} Vertex;

View File

@ -1,4 +1,4 @@
#include "../include/glkos.h"
#include "private.h"
void APIENTRY glVertexPackColor3fKOS(GLVertexKOS* vertex, float r, float g, float b) {
vertex->bgra[3] = 255;

2
GL/version.c.in Normal file
View File

@ -0,0 +1,2 @@
const char* GLDC_VERSION = "@GLDC_VERSION@";

View File

@ -1,37 +0,0 @@
# KallistiOS ##version##
#
# kos-ports/libgl Makefile
# Copyright (C) 2013, 2014 Josh Pearson
# Copyright (C) 2014 Lawrence Sebald
# Copyright (C) 2020 Luke Benstead
TARGET = libGLdc.a
OBJS = GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o GL/glu.o GL/version.h
OBJS += GL/matrix.o GL/fog.o GL/error.o GL/clip.o containers/stack.o containers/named_array.o containers/aligned_vector.o GL/profiler.o
OBJS += GL/yalloc/yalloc.o
SUBDIRS =
KOS_CFLAGS += -ffast-math -Ofast -Iinclude
GL/version.h:
rm -f $@
@printf '#pragma once\n#define GLDC_VERSION "$(shell git describe --abbrev=4 --dirty --always --tags)"\n' > $@
link:
$(KOS_AR) rcs $(TARGET) $(OBJS)
build: GL/version.h $(OBJS) link
samples: build
$(KOS_MAKE) -C samples all
defaultall: create_kos_link $(OBJS) subdirs linklib samples
include $(KOS_BASE)/addons/Makefile.prefab
# creates the kos link to the headers
create_kos_link:
rm -f ../include/GL
ln -s ../GLdc/include ../include/GL

View File

@ -1,14 +1,12 @@
#pragma once
#ifndef ALIGNED_VECTOR_H
#define ALIGNED_VECTOR_H
#include <assert.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <assert.h>
typedef struct {
unsigned int size;
unsigned int capacity;
@ -39,5 +37,3 @@ static inline void* aligned_vector_back(AlignedVector* vector){
#ifdef __cplusplus
}
#endif
#endif // ALIGNED_VECTOR_H

View File

@ -4,6 +4,9 @@
__BEGIN_DECLS
extern const char* GLDC_VERSION;
/*
* Dreamcast specific compressed + twiddled formats.
* We use constants from the range 0xEEE0 onwards

View File

@ -17,7 +17,7 @@
__BEGIN_DECLS
#ifndef BUILD_LIBGL
#include <gl.h>
#include "gl.h"
#endif
#define GLU_FALSE 0

View File

@ -4,9 +4,9 @@
* output and incorrect depth testing
*/
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.

View File

@ -1,6 +1,6 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.

View File

@ -1,4 +1,3 @@
#include <kos.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@ -188,7 +187,7 @@ int dtex_to_gl_texture(texture *tex, char* filename) {
printf("Texture %s loaded\n", tex->path);
return(1);
};
}
void draw_textured_quad(texture *tex) {
if(glIsTexture(tex->id)) {

View File

@ -2,7 +2,7 @@
#define __GL_PNG_H__
#include <stdio.h>
#include <kos.h>
#include <stdint.h>
#include <GL/gl.h>
typedef struct _texture {

View File

@ -1,11 +1,11 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
#include "gl_png.h"
//$KOS_BASE/utils/texconv/texconv --in disk.png --format ARGB4444 --preview disk_preview.png --out disk.dtex
extern uint8 romdisk[];
extern uint8_t romdisk[];
KOS_INIT_ROMDISK(romdisk);
texture t;
int blendActive = -1;

View File

@ -1,6 +1,6 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.

View File

@ -1,11 +1,16 @@
#include <stdio.h>
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
#ifdef __DREAMCAST__
extern uint8 romdisk[];
KOS_INIT_ROMDISK(romdisk);
#endif
/* floats for x rotation, y rotation, z rotation */
float xrot, yrot, zrot;

View File

@ -4,9 +4,9 @@
* output and incorrect depth testing
*/
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.

View File

@ -1,12 +1,23 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glext.h"
#include "GL/glkos.h"
extern uint8 romdisk[];
#ifdef __DREAMCAST__
#include <kos.h>
extern uint8_t romdisk[];
KOS_INIT_ROMDISK(romdisk);
#define IMAGE_FILENAME "/rd/NeHe.bmp"
#else
#define IMAGE_FILENAME "samples/lights/romdisk/NeHe.bmp"
#endif
float xrot, yrot, zrot;
@ -89,7 +100,7 @@ int ImageLoad(char *filename, Image *image) {
}
if ((i = fread(image->data, size, 1, file)) != 1) {
printf(stderr, "Error reading image data from %s.\n", filename);
fprintf(stderr, "Error reading image data from %s.\n", filename);
return 0;
}
@ -115,7 +126,7 @@ void LoadGLTextures() {
exit(0);
}
if (!ImageLoad("/rd/NeHe.bmp", image1)) {
if (!ImageLoad(IMAGE_FILENAME, image1)) {
exit(1);
}

View File

@ -1,13 +1,21 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glext.h"
#include "GL/glkos.h"
extern uint8 romdisk[];
extern uint8_t romdisk[];
KOS_INIT_ROMDISK(romdisk);
#ifdef __DREAMCAST__
#define IMAGE_FILENAME "/rd/NeHe.bmp"
#else
#define IMAGE_FILENAME "samples/mipmap/romdisk/NeHe.bmp"
#endif
/* storage for one texture */
int texture[1];
@ -87,7 +95,7 @@ int ImageLoad(char *filename, Image *image) {
}
if ((i = fread(image->data, size, 1, file)) != 1) {
printf(stderr, "Error reading image data from %s.\n", filename);
fprintf(stderr, "Error reading image data from %s.\n", filename);
return 0;
}
@ -113,7 +121,7 @@ void LoadGLTextures() {
exit(0);
}
if (!ImageLoad("/rd/NeHe.bmp", image1)) {
if (!ImageLoad(IMAGE_FILENAME, image1)) {
exit(1);
}

View File

@ -8,11 +8,21 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "glext.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
#include "GL/glext.h"
#ifdef __DREAMCAST__
#define IMAGE1_FILENAME "/rd/wp001vq.pvr"
#define IMAGE2_FILENAME "/rd/FlareWS_256.pvr"
#else
#define IMAGE1_FILENAME "samples/multitexture_arrays/romdisk/wp001vq.pvr"
#define IMAGE2_FILENAME "samples/multitexture_arrays/romdisk/FlareWS_256.pvr"
#endif
/* Load a PVR texture - located in pvr-texture.c */
extern GLuint glTextureLoadPVR(char *fname, unsigned char isMipMapped, unsigned char glMipMap);
@ -29,7 +39,7 @@ GLfloat TEXCOORD_ARRAY[4 * 2] = { 0, 0,
0, 1
};
GLuint ARGB_ARRAY[4 * 1] = { 0xFFFF0000, 0xFF0000FF, 0xFF00FF00, 0xFFFFFF00 };
GLuint ARGB_ARRAY[4] = { 0xFFFF0000, 0xFF0000FF, 0xFF00FF00, 0xFFFFFF00 };
/* Multi-Texture Example using Open GL Vertex Buffer Submission. */
@ -91,7 +101,7 @@ void RenderCallback(GLuint texID0, GLuint texID1) {
glDisableClientState(GL_VERTEX_ARRAY);
}
extern uint8 romdisk[];
extern uint8_t romdisk[];
KOS_INIT_ROMDISK(romdisk);
int main(int argc, char **argv) {
@ -105,8 +115,8 @@ int main(int argc, char **argv) {
glLoadIdentity();
/* Load two PVR textures to OpenGL */
GLuint texID0 = glTextureLoadPVR("/rd/wp001vq.pvr", 0, 0);
GLuint texID1 = glTextureLoadPVR("/rd/FlareWS_256.pvr", 0, 0);
GLuint texID0 = glTextureLoadPVR(IMAGE1_FILENAME, 0, 0);
GLuint texID1 = glTextureLoadPVR(IMAGE2_FILENAME, 0, 0);
while(1) {
/* Draw the "scene" */

View File

@ -6,13 +6,14 @@
Load A PVR Texture to the PVR using Open GL
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <kos.h>
#include "../include/gl.h"
#include "../include/glu.h"
#include "../include/glkos.h"
#include "../include/glext.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
#include "GL/glext.h"
#define PVR_HDR_SIZE 0x20
#define MAX(x, y) ((x > y) ? x : y)
@ -51,8 +52,8 @@ static GLuint _glGetMipmapDataSize(GLuint width, GLuint height) {
glMipMap should be passed as 1 if Open GL should calculate the Mipmap levels, 0 otherwise */
GLuint glTextureLoadPVR(char *fname, unsigned char isMipMapped, unsigned char glMipMap) {
FILE *tex = NULL;
uint16 *TEX0 = NULL;
uint8 HDR[PVR_HDR_SIZE];
uint16_t *TEX0 = NULL;
uint8_t HDR[PVR_HDR_SIZE];
GLuint texID, texSize, texW, texH, texFormat;
/* Open the PVR texture file, and get its file size */

View File

@ -1,6 +1,6 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.
@ -16,7 +16,7 @@ void InitGL(int Width, int Height) // We call this right after our OpenG
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
glMatrixMode(GL_MODELVIEW);
glMatrixMode(GL_MODELVIEW);
}
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */

View File

@ -1,6 +1,6 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.

View File

@ -1,6 +1,6 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.

View File

@ -1,6 +1,7 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.

View File

@ -1,6 +1,6 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
GLfloat rtri;
GLfloat rquad;

View File

@ -1,6 +1,6 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
GLfloat rtri;
GLfloat rquad;

View File

@ -1,17 +1,26 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glext.h"
#include "GL/glkos.h"
extern uint8 romdisk[];
#ifdef __DREAMCAST__
#define IMAGE_FILENAME "/rd/NeHe.bmp"
extern uint8_t romdisk[];
KOS_INIT_ROMDISK(romdisk);
#else
#define IMAGE_FILENAME "samples/nehe06/romdisk/NeHe.bmp"
#endif
/* floats for x rotation, y rotation, z rotation */
float xrot, yrot, zrot;
/* storage for one texture */
int texture[1];
GLuint texture[1];
/* Image type - contains height, width, and data */
struct Image {
@ -89,7 +98,7 @@ int ImageLoad(char *filename, Image *image) {
}
if ((i = fread(image->data, size, 1, file)) != 1) {
printf(stderr, "Error reading image data from %s.\n", filename);
fprintf(stderr, "Error reading image data from %s.\n", filename);
return 0;
}
@ -115,7 +124,7 @@ void LoadGLTextures() {
exit(0);
}
if (!ImageLoad("/rd/NeHe.bmp", image1)) {
if (!ImageLoad(IMAGE_FILENAME, image1)) {
exit(1);
}

View File

@ -1,12 +1,15 @@
#include <stdio.h>
#include <stdlib.h>
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "glext.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
#include "GL/glext.h"
#ifdef __DREAMCAST__
extern uint8 romdisk[];
KOS_INIT_ROMDISK(romdisk);
#endif
/* floats for x rotation, y rotation, z rotation */
float xrot, yrot, zrot;

View File

@ -1,6 +1,6 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.

View File

@ -1,13 +1,14 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "gl.h"
#include "glext.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/glkos.h"
extern uint8 romdisk[];
extern uint8_t romdisk[];
KOS_INIT_ROMDISK(romdisk);
/* floats for x rotation, y rotation, z rotation */

View File

@ -4,13 +4,16 @@
#include <stdint.h>
#include <assert.h>
#include "gl.h"
#include "glext.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glext.h"
#include "GL/glkos.h"
extern uint8 romdisk[];
KOS_INIT_ROMDISK(romdisk);
#ifdef __DREAMCAST__
#include <kos.h>
extern uint8 romdisk[];
KOS_INIT_ROMDISK(romdisk);
#endif
/* floats for x rotation, y rotation, z rotation */
float xrot, yrot, zrot;

View File

@ -1,12 +1,17 @@
#include <kos.h>
typedef enum
{
false,
true
} bool;
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#ifdef __DREAMCAST__
#include <kos.h>
#endif
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.
@ -96,6 +101,7 @@ void drawPolygon()
int frames = 0;
void check_input()
{
#ifdef __DREAMCAST__
maple_device_t *cont;
cont_state_t *state;
@ -117,6 +123,7 @@ void check_input()
}
}
}
#endif
}
/* The main drawing function. */

View File

@ -10,6 +10,7 @@
#include <kos.h>
#include <GL/gl.h>
#include <GL/glkos.h>
#include <stdlib.h>
#include <time.h>

View File

@ -10,6 +10,7 @@
#include <kos.h>
#include <GL/gl.h>
#include <GL/glkos.h>
#include <stdlib.h>
#include <time.h>

View File

@ -1,9 +1,9 @@
#include <stdio.h>
#include <stdlib.h>
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
#define TERRAIN_SIZE 100
#define TERRAIN_SCALE 1.0f

View File

@ -1,15 +1,18 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "gl.h"
#include "glext.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glext.h"
#include "GL/glkos.h"
#ifdef __DREAMCAST__
#include <kos.h>
extern uint8 romdisk[];
KOS_INIT_ROMDISK(romdisk);
#endif
/* Image type - contains height, width, and data */
typedef struct // Create A Structure
@ -29,85 +32,85 @@ TextureImage lightmap;
GLboolean LoadTGA(TextureImage *texture, const char *filename) // Loads A TGA File Into Memory
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header
GLubyte TGAcompare[12]; // Used To Compare TGA Header
GLubyte header[6]; // First 6 Useful Bytes From The Header
GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File
GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram
GLuint temp; // Temporary Variable
GLuint type=GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP)
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header
GLubyte TGAcompare[12]; // Used To Compare TGA Header
GLubyte header[6]; // First 6 Useful Bytes From The Header
GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File
GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram
GLuint temp; // Temporary Variable
GLuint type=GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP)
FILE *file = fopen(filename, "rb"); // Open The TGA File
FILE *file = fopen(filename, "rb"); // Open The TGA File
if( file==NULL || // Does File Even Exist?
fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read?
memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || // Does The Header Match What We Want?
fread(header,1,sizeof(header),file)!=sizeof(header)) // If So Read Next 6 Header Bytes
{
if (file == NULL) { // Did The File Even Exist? *Added Jim Strong*
if( file==NULL || // Does File Even Exist?
fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read?
memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || // Does The Header Match What We Want?
fread(header,1,sizeof(header),file)!=sizeof(header)) // If So Read Next 6 Header Bytes
{
if (file == NULL) { // Did The File Even Exist? *Added Jim Strong*
fprintf(stderr, "Missing file\n");
return GL_FALSE; // Return False
return GL_FALSE; // Return False
} else
{
{
fprintf(stderr, "Invalid format\n");
fclose(file); // If Anything Failed, Close The File
return GL_FALSE; // Return False
}
}
fclose(file); // If Anything Failed, Close The File
return GL_FALSE; // Return False
}
}
texture->width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte)
texture->height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte)
texture->width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte)
texture->height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte)
if( texture->width <=0 || // Is The Width Less Than Or Equal To Zero
texture->height <=0 || // Is The Height Less Than Or Equal To Zero
(header[4]!=24 && header[4]!=32)) // Is The TGA 24 or 32 Bit?
{
fprintf(stderr, "Wrong format\n");
if( texture->width <=0 || // Is The Width Less Than Or Equal To Zero
texture->height <=0 || // Is The Height Less Than Or Equal To Zero
(header[4]!=24 && header[4]!=32)) // Is The TGA 24 or 32 Bit?
{
fprintf(stderr, "Wrong format\n");
fclose(file); // If Anything Failed, Close The File
return GL_FALSE; // Return False
}
return GL_FALSE; // Return False
}
texture->bpp = header[4]; // Grab The TGA's Bits Per Pixel (24 or 32)
bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The Bytes Per Pixel
imageSize = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data
texture->bpp = header[4]; // Grab The TGA's Bits Per Pixel (24 or 32)
bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The Bytes Per Pixel
imageSize = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data
texture->imageData=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data
texture->imageData=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data
if( texture->imageData==NULL || // Does The Storage Memory Exist?
fread(texture->imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved?
{
if(texture->imageData!=NULL) // Was Image Data Loaded
free(texture->imageData); // If So, Release The Image Data
if( texture->imageData==NULL || // Does The Storage Memory Exist?
fread(texture->imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved?
{
if(texture->imageData!=NULL) // Was Image Data Loaded
free(texture->imageData); // If So, Release The Image Data
fclose(file); // Close The File
return GL_FALSE; // Return False
}
fclose(file); // Close The File
return GL_FALSE; // Return False
}
GLuint i;
for(i = 0; i < (int)imageSize; i += bytesPerPixel) // Loop Through The Image Data
{ // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
temp=texture->imageData[i]; // Temporarily Store The Value At Image Data 'i'
texture->imageData[i] = texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte
texture->imageData[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
}
for(i = 0; i < (int)imageSize; i += bytesPerPixel) // Loop Through The Image Data
{ // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
temp=texture->imageData[i]; // Temporarily Store The Value At Image Data 'i'
texture->imageData[i] = texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte
texture->imageData[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
}
fclose (file); // Close The File
fclose (file); // Close The File
// Build A Texture From The Data
glGenTextures(1, &texture[0].texID); // Generate OpenGL texture IDs
// Build A Texture From The Data
glGenTextures(1, &texture[0].texID); // Generate OpenGL texture IDs
glBindTexture(GL_TEXTURE_2D, texture[0].texID); // Bind Our Texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered
glBindTexture(GL_TEXTURE_2D, texture[0].texID); // Bind Our Texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered
if (texture[0].bpp==24) // Was The TGA 24 Bits
{
type=GL_RGB; // If So Set The 'type' To GL_RGB
}
if (texture[0].bpp==24) // Was The TGA 24 Bits
{
type=GL_RGB; // If So Set The 'type' To GL_RGB
}
glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
return GL_TRUE; // Texture Building Went Ok, Return True
return GL_TRUE; // Texture Building Went Ok, Return True
}
// Load Bitmaps And Convert To Textures
void LoadGLTextures() {

View File

@ -2,9 +2,9 @@
#include <string.h>
#include <stdlib.h>
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */

View File

@ -2,9 +2,9 @@
#include <string.h>
#include <stdlib.h>
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glkos.h"
/* A general OpenGL initialization function. Sets all of the initial parameters. */

View File

@ -0,0 +1,59 @@
SET(CMAKE_SYSTEM_NAME Generic)
SET(PLATFORM_DREAMCAST TRUE)
SET(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_C_COMPILER $ENV{KOS_CC_BASE}/bin/sh-elf-gcc)
set(CMAKE_CXX_COMPILER $ENV{KOS_CC_BASE}/bin/sh-elf-g++)
add_compile_options(-ml -m4-single-only -ffunction-sections -fdata-sections)
set(CMAKE_EXE_LINKER_FLAGS " -ml -m4-single-only -Wl,-Ttext=0x8c010000 -Wl,--gc-sections -T$ENV{KOS_BASE}/utils/ldscripts/shlelf.xc -nodefaultlibs" CACHE INTERNAL "" FORCE)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_SYSTEM_INCLUDE_PATH "${CMAKE_SYSTEM_INCLUDE_PATH} $ENV{KOS_BASE}/include $ENV{KOS_BASE}/kernel/arch/dreamcast/include $ENV{KOS_BASE}/addons/include $ENV{KOS_BASE}/../kos-ports/include")
INCLUDE_DIRECTORIES(
$ENV{KOS_BASE}/include
$ENV{KOS_BASE}/kernel/arch/dreamcast/include
$ENV{KOS_BASE}/addons/include
$ENV{KOS_BASE}/../kos-ports/include
)
LINK_DIRECTORIES(
$ENV{KOS_BASE}/addons/lib/dreamcast
$ENV{KOS_PORTS}/lib
)
IF(${CMAKE_BUILD_TYPE} MATCHES Debug)
LINK_DIRECTORIES($ENV{KOS_BASE}/lib/dreamcast/debug)
ELSE()
LINK_DIRECTORIES($ENV{KOS_BASE}/lib/dreamcast)
ENDIF()
add_link_options(-L$ENV{KOS_BASE}/lib/dreamcast)
link_libraries(-Wl,--start-group -lstdc++ -lkallisti -lc -lgcc -Wl,--end-group m)
SET(CMAKE_EXECUTABLE_SUFFIX ".elf")
SET(CMAKE_EXECUTABLE_SUFFIX_CXX ".elf")
ADD_DEFINITIONS(
-D__DREAMCAST__
-DDREAMCAST
-D_arch_dreamcast
-D__arch_dreamcast
-D_arch_sub_pristine
)
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
ADD_DEFINITIONS(-DNDEBUG)
endif()
SET(CMAKE_ASM_FLAGS "")
SET(CMAKE_ASM_FLAGS_RELEASE "")