2016-06-24 15:24:58 +02:00
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
#include "../rwbase.h"
|
|
|
|
#include "../rwerror.h"
|
|
|
|
#include "../rwplg.h"
|
|
|
|
#include "../rwpipeline.h"
|
|
|
|
#include "../rwobjects.h"
|
|
|
|
#include "../rwengine.h"
|
|
|
|
#ifdef RW_OPENGL
|
|
|
|
#include <GL/glew.h>
|
|
|
|
#endif
|
|
|
|
#include "rwgl3.h"
|
|
|
|
#include "rwgl3shader.h"
|
|
|
|
|
2020-04-17 21:44:32 +02:00
|
|
|
#define PLUGIN_ID ID_DRIVER
|
|
|
|
|
2016-06-24 15:24:58 +02:00
|
|
|
namespace rw {
|
|
|
|
namespace gl3 {
|
|
|
|
|
|
|
|
int32 nativeRasterOffset;
|
|
|
|
|
2020-04-17 21:44:32 +02:00
|
|
|
static Raster*
|
2020-04-16 17:46:42 +02:00
|
|
|
rasterCreateTexture(Raster *raster)
|
2016-06-24 15:24:58 +02:00
|
|
|
{
|
2020-04-16 17:46:42 +02:00
|
|
|
#ifdef RW_OPENGL
|
|
|
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
|
|
|
switch(raster->format & 0xF00){
|
|
|
|
case Raster::C8888:
|
|
|
|
natras->internalFormat = GL_RGBA;
|
|
|
|
natras->format = GL_RGBA;
|
|
|
|
natras->type = GL_UNSIGNED_BYTE;
|
|
|
|
natras->hasAlpha = 1;
|
2017-08-27 17:13:10 +02:00
|
|
|
break;
|
2020-04-16 17:46:42 +02:00
|
|
|
case Raster::C888:
|
|
|
|
natras->internalFormat = GL_RGB;
|
|
|
|
natras->format = GL_RGB;
|
|
|
|
natras->type = GL_UNSIGNED_BYTE;
|
|
|
|
natras->hasAlpha = 0;
|
2017-08-27 17:13:10 +02:00
|
|
|
break;
|
2020-04-16 17:46:42 +02:00
|
|
|
case Raster::C1555:
|
|
|
|
// TODO: check if this is correct
|
|
|
|
natras->internalFormat = GL_RGBA;
|
|
|
|
natras->format = GL_RGBA;
|
|
|
|
natras->type = GL_UNSIGNED_SHORT_5_5_5_1;
|
|
|
|
natras->hasAlpha = 1;
|
2017-08-27 17:13:10 +02:00
|
|
|
break;
|
|
|
|
default:
|
2020-04-17 21:44:32 +02:00
|
|
|
RWERROR((ERR_INVRASTER));
|
|
|
|
return nil;
|
2017-08-27 17:13:10 +02:00
|
|
|
}
|
|
|
|
|
2020-04-16 17:46:42 +02:00
|
|
|
glGenTextures(1, &natras->texid);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
|
|
|
|
raster->width, raster->height,
|
|
|
|
0, natras->format, natras->type, nil);
|
|
|
|
natras->filterMode = 0;
|
|
|
|
natras->addressU = 0;
|
|
|
|
natras->addressV = 0;
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
2020-04-17 21:44:32 +02:00
|
|
|
return raster;
|
|
|
|
#else
|
|
|
|
return nil;
|
2020-04-16 17:46:42 +02:00
|
|
|
#endif
|
|
|
|
}
|
2016-06-24 15:24:58 +02:00
|
|
|
|
|
|
|
#ifdef RW_OPENGL
|
2020-04-16 17:46:42 +02:00
|
|
|
|
|
|
|
// This is totally fake right now, can't render to it. Only used to copy into from FB
|
|
|
|
// For rendering the idea would probably be to render to the backbuffer and copy it here afterwards.
|
|
|
|
// alternatively just use FBOs but that probably needs some more infrastructure.
|
2020-04-17 21:44:32 +02:00
|
|
|
static Raster*
|
2020-04-16 17:46:42 +02:00
|
|
|
rasterCreateCameraTexture(Raster *raster)
|
|
|
|
{
|
2020-04-17 21:44:32 +02:00
|
|
|
if(raster->format & (Raster::PAL4 | Raster::PAL8)){
|
|
|
|
RWERROR((ERR_NOTEXTURE));
|
|
|
|
return nil;
|
|
|
|
}
|
2020-04-16 17:46:42 +02:00
|
|
|
|
|
|
|
// TODO: figure out what the backbuffer is and use that as a default
|
2016-07-15 11:55:52 +02:00
|
|
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
|
|
|
switch(raster->format & 0xF00){
|
|
|
|
case Raster::C8888:
|
2020-04-16 17:46:42 +02:00
|
|
|
default:
|
2016-07-15 11:55:52 +02:00
|
|
|
natras->internalFormat = GL_RGBA;
|
|
|
|
natras->format = GL_RGBA;
|
2016-08-03 20:32:43 +02:00
|
|
|
natras->type = GL_UNSIGNED_BYTE;
|
2016-07-15 11:55:52 +02:00
|
|
|
natras->hasAlpha = 1;
|
|
|
|
break;
|
|
|
|
case Raster::C888:
|
|
|
|
natras->internalFormat = GL_RGB;
|
|
|
|
natras->format = GL_RGB;
|
2016-08-03 20:32:43 +02:00
|
|
|
natras->type = GL_UNSIGNED_BYTE;
|
2016-07-15 11:55:52 +02:00
|
|
|
natras->hasAlpha = 0;
|
|
|
|
break;
|
2016-08-03 20:32:43 +02:00
|
|
|
case Raster::C1555:
|
|
|
|
// TODO: check if this is correct
|
|
|
|
natras->internalFormat = GL_RGBA;
|
|
|
|
natras->format = GL_RGBA;
|
|
|
|
natras->type = GL_UNSIGNED_SHORT_5_5_5_1;
|
|
|
|
natras->hasAlpha = 1;
|
|
|
|
break;
|
2016-07-15 11:55:52 +02:00
|
|
|
}
|
|
|
|
|
2016-06-24 15:24:58 +02:00
|
|
|
glGenTextures(1, &natras->texid);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
2016-07-15 11:55:52 +02:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
|
|
|
|
raster->width, raster->height,
|
|
|
|
0, natras->format, natras->type, nil);
|
2018-07-02 07:01:34 +02:00
|
|
|
natras->filterMode = 0;
|
|
|
|
natras->addressU = 0;
|
|
|
|
natras->addressV = 0;
|
2016-06-24 15:24:58 +02:00
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
2020-04-17 21:44:32 +02:00
|
|
|
return raster;
|
2020-04-16 17:46:42 +02:00
|
|
|
}
|
|
|
|
|
2020-04-17 21:44:32 +02:00
|
|
|
static Raster*
|
2020-04-16 17:46:42 +02:00
|
|
|
rasterCreateCamera(Raster *raster)
|
|
|
|
{
|
|
|
|
// TODO: set/check width, height, depth, format?
|
|
|
|
raster->flags |= Raster::DONTALLOCATE;
|
|
|
|
raster->originalWidth = raster->width;
|
|
|
|
raster->originalHeight = raster->height;
|
|
|
|
raster->stride = 0;
|
|
|
|
raster->pixels = nil;
|
2020-04-17 21:44:32 +02:00
|
|
|
return raster;
|
2020-04-16 17:46:42 +02:00
|
|
|
}
|
|
|
|
|
2020-04-17 21:44:32 +02:00
|
|
|
static Raster*
|
2020-04-16 17:46:42 +02:00
|
|
|
rasterCreateZbuffer(Raster *raster)
|
|
|
|
{
|
|
|
|
// TODO: set/check width, height, depth, format?
|
|
|
|
raster->flags |= Raster::DONTALLOCATE;
|
2020-04-17 21:44:32 +02:00
|
|
|
return raster;
|
2020-04-16 17:46:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2020-04-17 21:44:32 +02:00
|
|
|
Raster*
|
2020-04-16 17:46:42 +02:00
|
|
|
rasterCreate(Raster *raster)
|
|
|
|
{
|
|
|
|
switch(raster->type){
|
|
|
|
case Raster::NORMAL:
|
|
|
|
case Raster::TEXTURE:
|
|
|
|
// Dummy to use as subraster
|
|
|
|
// ^ what did i do there?
|
|
|
|
if(raster->width == 0 || raster->height == 0){
|
|
|
|
raster->flags |= Raster::DONTALLOCATE;
|
|
|
|
raster->stride = 0;
|
2020-04-17 21:44:32 +02:00
|
|
|
return raster;
|
2020-04-16 17:46:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(raster->flags & Raster::DONTALLOCATE)
|
2020-04-17 21:44:32 +02:00
|
|
|
return raster;
|
|
|
|
return rasterCreateTexture(raster);
|
2020-04-16 17:46:42 +02:00
|
|
|
|
|
|
|
#ifdef RW_OPENGL
|
|
|
|
case Raster::CAMERATEXTURE:
|
|
|
|
if(raster->flags & Raster::DONTALLOCATE)
|
2020-04-17 21:44:32 +02:00
|
|
|
return raster;
|
|
|
|
return rasterCreateCameraTexture(raster);
|
2020-04-16 17:46:42 +02:00
|
|
|
|
|
|
|
case Raster::ZBUFFER:
|
2020-04-17 21:44:32 +02:00
|
|
|
return rasterCreateZbuffer(raster);
|
2020-04-16 17:46:42 +02:00
|
|
|
case Raster::CAMERA:
|
2020-04-17 21:44:32 +02:00
|
|
|
return rasterCreateCamera(raster);
|
2016-06-24 15:24:58 +02:00
|
|
|
#endif
|
2020-04-16 17:46:42 +02:00
|
|
|
|
|
|
|
default:
|
|
|
|
assert(0 && "unsupported format");
|
|
|
|
}
|
2020-04-17 21:44:32 +02:00
|
|
|
return nil;
|
2016-06-24 15:24:58 +02:00
|
|
|
}
|
|
|
|
|
2016-06-27 21:59:35 +02:00
|
|
|
uint8*
|
2019-08-07 22:37:43 +02:00
|
|
|
rasterLock(Raster*, int32 level, int32 lockMode)
|
2016-06-24 15:24:58 +02:00
|
|
|
{
|
|
|
|
printf("locking\n");
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2016-06-27 21:59:35 +02:00
|
|
|
void
|
2016-06-24 15:24:58 +02:00
|
|
|
rasterUnlock(Raster*, int32)
|
|
|
|
{
|
|
|
|
printf("unlocking\n");
|
|
|
|
}
|
|
|
|
|
2016-06-27 21:59:35 +02:00
|
|
|
int32
|
2016-06-24 15:24:58 +02:00
|
|
|
rasterNumLevels(Raster*)
|
|
|
|
{
|
|
|
|
printf("numlevels\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-04-17 21:44:32 +02:00
|
|
|
bool32
|
|
|
|
imageFindRasterFormat(Image *img, int32 type,
|
|
|
|
int32 *width, int32 *height, int32 *depth, int32 *format)
|
|
|
|
{
|
|
|
|
assert(0 && "not yet");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool32
|
2016-06-24 15:24:58 +02:00
|
|
|
rasterFromImage(Raster *raster, Image *image)
|
|
|
|
{
|
2020-04-17 21:44:32 +02:00
|
|
|
assert(0 && "not yet");
|
2016-06-24 15:24:58 +02:00
|
|
|
int32 format;
|
|
|
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
|
|
|
|
2016-07-15 11:55:52 +02:00
|
|
|
switch(image->depth){
|
|
|
|
case 32:
|
|
|
|
format = Raster::C8888;
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
format = Raster::C888;
|
|
|
|
break;
|
2016-08-03 20:32:43 +02:00
|
|
|
case 16:
|
|
|
|
format = Raster::C1555;
|
|
|
|
break;
|
2016-07-15 11:55:52 +02:00
|
|
|
default:
|
|
|
|
assert(0 && "image depth\n");
|
|
|
|
}
|
|
|
|
format |= Raster::TEXTURE;
|
2016-06-24 15:24:58 +02:00
|
|
|
|
|
|
|
raster->type = format & 0x7;
|
|
|
|
raster->flags = format & 0xF8;
|
|
|
|
raster->format = format & 0xFF00;
|
|
|
|
rasterCreate(raster);
|
|
|
|
|
|
|
|
natras->hasAlpha = image->hasAlpha();
|
|
|
|
|
|
|
|
#ifdef RW_OPENGL
|
|
|
|
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
2016-07-15 11:55:52 +02:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
|
|
|
|
raster->width, raster->height,
|
|
|
|
0, natras->format, natras->type, image->pixels);
|
2016-06-24 15:24:58 +02:00
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
#endif
|
2020-04-17 21:44:32 +02:00
|
|
|
return 1;
|
2016-06-24 15:24:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void*
|
|
|
|
createNativeRaster(void *object, int32 offset, int32)
|
|
|
|
{
|
|
|
|
Gl3Raster *ras = PLUGINOFFSET(Gl3Raster, object, offset);
|
|
|
|
ras->texid = 0;
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void*
|
|
|
|
destroyNativeRaster(void *object, int32, int32)
|
|
|
|
{
|
|
|
|
//Gl3Raster *ras = PLUGINOFFSET(Gl3Raster, object, offset);
|
|
|
|
// TODO
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void*
|
|
|
|
copyNativeRaster(void *dst, void *, int32 offset, int32)
|
|
|
|
{
|
|
|
|
Gl3Raster *d = PLUGINOFFSET(Gl3Raster, dst, offset);
|
|
|
|
d->texid = 0;
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
2016-06-25 17:58:52 +02:00
|
|
|
void registerNativeRaster(void)
|
|
|
|
{
|
2016-06-29 12:53:02 +02:00
|
|
|
nativeRasterOffset = Raster::registerPlugin(sizeof(Gl3Raster),
|
|
|
|
ID_RASTERGL3,
|
|
|
|
createNativeRaster,
|
|
|
|
destroyNativeRaster,
|
|
|
|
copyNativeRaster);
|
2016-06-25 17:58:52 +02:00
|
|
|
}
|
|
|
|
|
2016-06-24 15:24:58 +02:00
|
|
|
}
|
|
|
|
}
|