Files
2026-02-02 04:50:13 +01:00

841 lines
25 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
#include "watchmaker/3d/render/opengl_3d.h"
#include "watchmaker/windows_hacks.h"
#include "watchmaker/t3d.h"
#include "watchmaker/3d/math/Matrix4x4.h"
#include "watchmaker/3d/render/opengl_renderer.h"
#include "watchmaker/ll/ll_system.h"
#include "watchmaker/3d/render/opengl_2d.h"
#include "watchmaker/renderer.h"
#include "watchmaker/globvar.h"
#include "watchmaker/work_dirs.h"
#ifdef USE_OPENGL_GAME
#include "graphics/opengl/system_headers.h"
#include "watchmaker/3d/render/shadows.h"
#include "watchmaker/file_utils.h"
#include "watchmaker/tga_util.h"
#define MAXTEXTURES 2000
namespace Watchmaker {
#define T3D_FASTFILE (1<<23) // fastfile
// Tecture formats
int NumAvailableFormats = 0;
gAvailFormat AvailableFormats[50];
gAvailFormat *gCurrentFormat;
// Point VB
int g_lpD3DPointsBuffer;
unsigned int gNumPointsBuffer;
// Tecture list
gTexture gTextureList[MAXTEXTURES];
unsigned int gNumTextureList = 0;
// {ines array
uint16 gLinesArray[MAX_LINES];
unsigned int gNumLinesArray = 0;
// screen traingles
Vertex gTriangles[100];
unsigned int gNumTrianglesArray = 0;
// camera info
Matrix4x4 rWorldMatrix;
Matrix4x4 rProjectionMatrix;
float gNearPlane, gFarPlane;
// saved matrix
Matrix4x4 rLinesViewMatrix;
// user matrix
#define MAX_USER_VIEW_MATRICES 2000 // TODO: Why do we get so many of them?
Matrix4x4 rUserViewMatrix[MAX_USER_VIEW_MATRICES];
unsigned int rNumUserViewMatrices = 0;
// user vertext buffer
void *g_lpD3DUserVertexBuffer = nullptr;
unsigned int g_dwD3DUserVertexBufferCounter = 0;
//***********************************************************************************************
uint16 *rGetLinesArrayPtr() {
return &gLinesArray[gNumLinesArray];
}
//***********************************************************************************************
void rAddLinesArray() {
gNumLinesArray++;
}
//***********************************************************************************************
void *rLockPointArray() {
warning("TODO: Implement rLockPointArray");
#if 0
HRESULT hResult;
LPVOID v;
if ((hResult = g_lpD3DPointsBuffer->Lock(DDLOCK_SURFACEMEMORYPTR, &v, NULL)) != D3D_OK) {
char str[255];
GetDDErrorString(hResult, str, 1);
DebugLogFile("rLockPointArray: Unable to lock points vertexbuffer:\r\n%s", str);
return NULL;
}
gVertex *gv = (gVertex *)v;
return &gv[rGetNumPointArray()];
#endif
return nullptr;
}
void rAddTrianglesArray(float x, float y, int r, int g, int b, int a) {
gTriangles[gNumTrianglesArray].sx = x;
gTriangles[gNumTrianglesArray].sy = y;
gTriangles[gNumTrianglesArray].sz = 1.0f;
gTriangles[gNumTrianglesArray].color = RGBA_MAKE(r, g, b, a);
gNumTrianglesArray++;
}
//***********************************************************************************************
void rUnlockPointArray() {
warning("TODO: Implement rUnlockPointArray");
#if 0
g_lpD3DPointsBuffer->Unlock();
#endif
}
//***********************************************************************************************
unsigned int rGetNumPointArray() {
return gNumPointsBuffer;
}
//***********************************************************************************************
void rAddPointArray() {
gNumPointsBuffer++;
}
//***********************************************************************************************
bool rSetViewMatrix(float _00, float _01, float _02,
float _03, float _04, float _05,
float _06, float _07, float _08,
float _tx, float _ty, float _tz) {
Matrix4x4 rViewMatrix;
rViewMatrix.setIdentity();
rViewMatrix.setValue(1, 1, _00);
rViewMatrix.setValue(1, 2, _01);
rViewMatrix.setValue(1, 3, _02);
rViewMatrix.setValue(1, 4, _tx);
rViewMatrix.setValue(2, 1, _03);
rViewMatrix.setValue(2, 2, _04);
rViewMatrix.setValue(2, 3, _05);
rViewMatrix.setValue(2, 4, _ty);
rViewMatrix.setValue(3, 1, -_06);
rViewMatrix.setValue(3, 2, -_07);
rViewMatrix.setValue(3, 3, -_08);
rViewMatrix.setValue(3, 4, _tz);
rViewMatrix.setValue(4, 1, 0.0f);
rViewMatrix.setValue(4, 2, 0.0f);
rViewMatrix.setValue(4, 3, 0.0f);
rViewMatrix.setValue(4, 4, 1.0f);
g_renderer->setTransformMatrix(TransformMatrix::VIEW, rViewMatrix);
return true;
}
void rSetViewMatrix(const t3dM3X3F &viewMatrix, const t3dV3F &translation) {
rSetViewMatrix(viewMatrix.M[0], viewMatrix.M[1], viewMatrix.M[2],
viewMatrix.M[3], viewMatrix.M[4], viewMatrix.M[5],
viewMatrix.M[6], viewMatrix.M[7], viewMatrix.M[8],
translation.x, translation.y, -translation.z);
}
void rSaveViewMatrix() {
g_renderer->pushModelView();
}
//***********************************************************************************************
void rRestoreViewMatrix() {
g_renderer->popModelView();
}
//***********************************************************************************************
bool rBuildLinesViewMatrix(float _00, float _01, float _02,
float _03, float _04, float _05,
float _06, float _07, float _08,
float _tx, float _ty, float _tz) {
rLinesViewMatrix.setIdentity();
rLinesViewMatrix.setValue(1, 1, _00);
rLinesViewMatrix.setValue(1, 2, _01);
rLinesViewMatrix.setValue(1, 3, _02);
rLinesViewMatrix.setValue(1, 4, _tx);
rLinesViewMatrix.setValue(2, 1, _03);
rLinesViewMatrix.setValue(2, 2, _04);
rLinesViewMatrix.setValue(2, 3, _05);
rLinesViewMatrix.setValue(2, 4, _ty);
rLinesViewMatrix.setValue(3, 1, -_06);
rLinesViewMatrix.setValue(3, 2, -_07);
rLinesViewMatrix.setValue(3, 3, -_08);
rLinesViewMatrix.setValue(3, 4, -_tz);
rLinesViewMatrix.setValue(4, 1, 0.0f);
rLinesViewMatrix.setValue(4, 2, 0.0f);
rLinesViewMatrix.setValue(4, 3, 0.0f);
rLinesViewMatrix.setValue(4, 4, 1.0f);
return true;
}
int rBuildLinesViewMatrix(const t3dM3X3F &viewMatrix, const t3dV3F &translation) {
return rBuildLinesViewMatrix(viewMatrix.M[0], viewMatrix.M[1], viewMatrix.M[2],
viewMatrix.M[3], viewMatrix.M[4], viewMatrix.M[5],
viewMatrix.M[6], viewMatrix.M[7], viewMatrix.M[8],
translation.x, translation.y, translation.z);
}
//***********************************************************************************************
int rAddUserViewMatrix(float _00, float _01, float _02,
float _03, float _04, float _05,
float _06, float _07, float _08,
float _tx, float _ty, float _tz) {
Matrix4x4 rTempViewMatrix;
Matrix4x4 *um;
unsigned int i;
rTempViewMatrix.setIdentity();
rTempViewMatrix.setValue(1, 1, _00);
rTempViewMatrix.setValue(1, 2, _01);
rTempViewMatrix.setValue(1, 3, _02);
rTempViewMatrix.setValue(1, 4, _tx);
rTempViewMatrix.setValue(2, 1, _03);
rTempViewMatrix.setValue(2, 2, _04);
rTempViewMatrix.setValue(2, 3, _05);
rTempViewMatrix.setValue(2, 4, _ty);
rTempViewMatrix.setValue(3, 1, -_06);
rTempViewMatrix.setValue(3, 2, -_07);
rTempViewMatrix.setValue(3, 3, -_08);
rTempViewMatrix.setValue(3, 4, -_tz);
rTempViewMatrix.setValue(4, 1, 0.0f);
rTempViewMatrix.setValue(4, 2, 0.0f);
rTempViewMatrix.setValue(4, 3, 0.0f);
rTempViewMatrix.setValue(4, 4, 1.0f);
auto &tmp = rTempViewMatrix;
//warning("Adding: ");
//tmp.print();
for (i = 0, um = &rUserViewMatrix[0]; i < rNumUserViewMatrices; i++, um++) {
//warning("Comparing %d", i);
//um->print();
if (*um == tmp) {
return i;
}
}
if (i >= MAX_USER_VIEW_MATRICES) {
DebugLogFile("Too many UserViewMatrix %d (MAX is %d)\n", i, MAX_USER_VIEW_MATRICES);
return -1;
}
*um = tmp;
rNumUserViewMatrices ++;
return rNumUserViewMatrices - 1;
}
int rAddUserViewMatrix(const t3dM3X3F &viewMatrix, const t3dV3F &translation) {
return rAddUserViewMatrix(viewMatrix.M[0], viewMatrix.M[1], viewMatrix.M[2],
viewMatrix.M[3], viewMatrix.M[4], viewMatrix.M[5],
viewMatrix.M[6], viewMatrix.M[7], viewMatrix.M[8],
translation.x, translation.y, translation.z);
}
void rResetPipeline() {
gNumLinesArray = 0;
gNumPointsBuffer = 0;
gNumShadowBoxesList = 0;
rNumUserViewMatrices = 0;
g_dwD3DUserVertexBufferCounter = 0;
return;
}
//*********************************************************************************************
void *rGetUserVertexBuffer() {
return g_lpD3DUserVertexBuffer;
}
//*********************************************************************************************
unsigned int rGetUserVertexBufferCounter() {
return g_dwD3DUserVertexBufferCounter;
}
//*********************************************************************************************
void rSetUserVertexBufferCounter(unsigned int uvbc) {
g_dwD3DUserVertexBufferCounter = uvbc;
}
gVertex *rLockVertexPtr(void *vb, int flags) {
warning("TODO: Implement rLockVertexPtr");
#if 0
LPVOID v;
DWORD dim, lock_flags;
HRESULT hResult;
LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuffer1 = (LPDIRECT3DVERTEXBUFFER7)vb;
lock_flags = DDLOCK_SURFACEMEMORYPTR;
if (flags & rVBLOCK_READONLY)
lock_flags |= DDLOCK_READONLY;
else if (flags & rVBLOCK_WRITEONLY)
lock_flags |= DDLOCK_WRITEONLY;
if (flags & rVBLOCK_NOSYSLOCK)
lock_flags |= DDLOCK_NOSYSLOCK;
if ((hResult = lpD3DVertexBuffer1->Lock(lock_flags, &v, &dim)) != D3D_OK) {
char str[255];
GetDDErrorString(hResult, str, 1);
DebugLogFile("Unable to lock vertexbuffer:\r\n%s", str);
return NULL;
}
return (gVertex *)v;
#endif
return nullptr;
}
Graphics::Surface *gCreateSurface(int width, int height, void *ptr) {
auto surface = new Graphics::Surface();
surface->w = width;
surface->h = height;
surface->pitch = width * 4; // TODO
surface->setPixels(ptr);
return surface;
}
//***********************************************************************************************
bool rUnlockVertexPtr(void *vb) {
warning("Implement rUnlockVertexPtr");
#if 0
LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuffer1 = (LPDIRECT3DVERTEXBUFFER7)vb;
if (lpD3DVertexBuffer1->Unlock() != D3D_OK) {
DebugLogFile("VertexBuffer Unlock error");
return FALSE;
}
#endif
return TRUE;
}
//***********************************************************************************************
void rSetLinesViewMatrix() {
g_renderer->setTransformMatrix(TransformMatrix::VIEW, rLinesViewMatrix);
}
//***********************************************************************************************
void rSetUserViewMatrix(int num) {
auto &matrix = rUserViewMatrix[num];
g_renderer->setTransformMatrix(TransformMatrix::VIEW, matrix);
}
//*********************************************************************************************
unsigned int gGetTextureListPosition() {
unsigned int pos = 1;
while (!gTextureList[pos].isEmpty()) { // TODO: Do we need the surface?
pos++;
}
if (pos > MAXTEXTURES)
return 0;
if (pos > gNumTextureList)
gNumTextureList = pos;
return pos;
}
//*********************************************************************************************
void gBuildAlternateName(char *AltName, const char *Name) {
int len, i, j;
if (!Name || !AltName) return;
len = strlen(Name);
memset(AltName, 0, len + 4);
memcpy(AltName, Name, len);
for (i = len - 1; i >= 0; i--) {
if ((AltName[i] == '.') && (i < (len - 3))) {
AltName[i + 1] = 'd';
AltName[i + 2] = 'd';
AltName[i + 3] = 's';
}
if (AltName[i] == '\\' || AltName[i] == '/') {
for (j = len; j >= i; j--)
AltName[j + 3] = AltName[j];
AltName[i + 0] = 'D';
AltName[i + 1] = 'D';
AltName[i + 2] = 'S';
break;
}
}
//warning("Build alternate name %s -> %s", Name, AltName);
}
//*********************************************************************************************
void gBuildAlternateName(char *AltName, char *Name) {
int len, i, j;
if (!Name || !AltName) return;
len = strlen(Name);
memset(AltName, 0, len + 4);
memcpy(AltName, Name, len);
for (i = len - 1; i >= 0; i--) {
if ((AltName[i] == '.') && (i < (len - 3))) {
AltName[i + 1] = 'd';
AltName[i + 2] = 'd';
AltName[i + 3] = 's';
}
if (AltName[i] == '\\') {
for (j = len; j >= i; j--)
AltName[j + 3] = AltName[j];
AltName[i + 0] = 'D';
AltName[i + 1] = 'D';
AltName[i + 2] = 'S';
break;
}
}
}
//*********************************************************************************************
gTexture *gUserTexture(Texture *texture, unsigned int dimx, unsigned int dimy) {
gTexture *Texture;
int pos;
//DDSURFACEDESC2 DDSurfDesc;
pos = gGetTextureListPosition();
if (pos == 0) {
DebugLogFile("gUserTexture: Can't create more textures");
return nullptr;
}
Texture = &gTextureList[pos];
*Texture = gTexture();
Texture->Flags = CurLoaderFlags;
{
#if 0
memset(&DDSurfDesc, 0, sizeof(DDSURFACEDESC2));
memcpy(&DDSurfDesc.ddpfPixelFormat, &gCurrentFormat->SurfaceDesc, sizeof(DDPIXELFORMAT));
DDSurfDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
if (gRenderFlags & gAGPSUPPORTED) {
//Alloc texture in AGP
DDSurfDesc.ddsCaps.dwCaps = DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY |
DDSCAPS_TEXTURE;
} else {
//No AGP support; alloc in sysmem
DDSurfDesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
DDSurfDesc.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
}
#endif
if (dimx > 8) {
if (dimx > 16) {
if (dimx > 32) {
if (dimx > 64) {
if (dimx > 128) {
dimx = 256;
} else {
dimx = 128;
}
} else {
dimx = 64;
}
} else {
dimx = 32;
}
} else {
dimx = 16;
}
}
if (dimy > 8) {
if (dimy > 16) {
if (dimy > 32) {
if (dimy > 64) {
if (dimy > 128) {
dimy = 256;
} else {
dimy = 128;
}
} else {
dimy = 64;
}
} else {
dimy = 32;
}
} else {
dimy = 16;
}
}
#if 0
DDSurfDesc.dwWidth = dimx;
DDSurfDesc.dwHeight = dimy;
if (!(Texture->lpDDSurface = gCreateSurface(&DDSurfDesc, Texture->lpDDSurface))) {
DebugLogFile("gCreateSurface FAILED: Can't create surface");
return NULL;
}
strcpy(Texture->Name, "UserTexture");
gClear(Texture->lpDDSurface, 0, 0, dimx, dimy, 0, 0, 0);
#endif
Texture->ID = pos;
Texture->DimX = dimx;
Texture->DimY = dimy;
#if 0
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = 0;
ddck.dwColorSpaceHighValue = 0;
Texture->lpDDSurface->SetColorKey(DDCKEY_SRCBLT, &ddck);
#endif
}
Texture->_texture = texture;
return Texture;
}
class SurfaceBackedTextureData : public TextureData {
bool _owned = true;
public:
Graphics::Surface *_surface;
SurfaceBackedTextureData(Graphics::Surface *surface, bool owned = true) : TextureData(DxtCompression::UNCOMPRESSED), _surface(surface), _owned(owned) {}
~SurfaceBackedTextureData() override {
if (_owned) {
_surface->free();
delete _surface;
}
}
int getWidth() const override {
return _surface->w;
}
int getHeight() const override {
return _surface->h;
}
int getDataSize() const override {
return _surface->w * _surface->h * _surface->format.bytesPerPixel;
}
const void *getData() const override {
return _surface->getPixels();
}
};
Common::SharedPtr<TextureData> createTextureFromSurface(Graphics::Surface &surface, int texFormat) {
return Common::SharedPtr<TextureData>(new SurfaceBackedTextureData(&surface, false));
}
//*********************************************************************************************
gTexture *gLoadTexture(WorkDirs &workDirs, const char *TextName, unsigned int _LoaderFlags) {
//bool bAlpha = FALSE
bool bUseAlternate = FALSE;
gTexture *texture = nullptr;
int32 pos = 0;
char AlternateName[500] {};
uint32 date1 = 0, date2 = 0, time1 = 0, time2 = 0;
//uint32 magic,retv;
unsigned long dwWidth = 0, dwHeight = 0;
//DDSURFACEDESC2 DDSurfDesc;
//Graphics::Surface *lpSSource = nullptr;
if (!TextName) return nullptr;
//lpSSource = nullptr;
//warning("gLoadTexture(%s)", TextName);
// Check if already loaded
for (uint32 i = 0; i < gNumTextureList; i++) {
if (gTextureList[i].name.equalsIgnoreCase(TextName)) {
//Texture already loaded; just assign pointers
texture = &gTextureList[i];
texture->ID = i;
return texture;
}
}
/* VERSIONE ORIGINALE by FAB
gBuildAlternateName( AlternateName, TextName );
if( ( CurLoaderFlags & T3D_FASTFILE ) || ( !t3dGetFileDate( &date1, &time1, TextName ) ) )
bUseAlternate = TRUE;
if( !t3dGetFileDate( &date2, &time2, AlternateName ) )
{
if( bUseAlternate == TRUE )
{
DebugLogFile("gAddMaterial:gLoadTexture: Cannot find %s and alternate %s.\n", TextName, AlternateName );
return NULL;
}
}
else if( bUseAlternate == FALSE )
{
if( ( date2 > date1 ) || ( ( date2 == date1 ) && ( time2 >= time1 ) ) )
bUseAlternate = TRUE;
}
*/
gBuildAlternateName(AlternateName, TextName);
if (!t3dGetFileDate(&date1, &time1, TextName)) // if it doesn't find the .tga texture, try the dds
bUseAlternate = TRUE;
if (!t3dGetFileDate(&date2, &time2, AlternateName)) { //se non trova la texture .dds
if (bUseAlternate == TRUE) { // does not find the .dds texture and furthermore the .tga does not exist
DebugLogFile("gAddMaterial:gLoadTexture: Cannot find %s and alternate %s.\n", TextName, AlternateName);
return nullptr;
}
} else if (bUseAlternate == FALSE) { // if there is the .dds and there is also the .tga see which is newer
if ((date2 > date1) || ((date2 == date1) && (time2 >= time1)))
bUseAlternate = TRUE;
}
if ((pos = gGetTextureListPosition()) == 0) {
DebugLogFile("gLoadTexture: Can't create more textures");
return nullptr;
}
texture = &gTextureList[pos];
*texture = gTexture();
texture->_texture = createGLTexture();
if (bUseAlternate) {
auto stream = workDirs.resolveFile(AlternateName);
if (!stream) {
DebugLogFile("gAddMaterial:gLoadTexture: Cannot find %s.\n", AlternateName);
return nullptr;
}
auto ddsTextureData = loadDdsTexture(*stream);
texture->_texture->assignData(*ddsTextureData);
dwWidth = ddsTextureData->getWidth();
dwHeight = ddsTextureData->getHeight();
//lpSSource = nullptr;
#if 0
if (gRenderFlags & gDXT1SUPPORTED) {
/* if( gRenderFlags & gAGPSUPPORTED )
{ // Alloc texture in AGP
DDSurfDesc.ddsCaps.dwCaps= DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE;
}
else
*/ { //No AGP support; alloc in sysmem
DDSurfDesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
DDSurfDesc.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
}
lpSSource = Texture->lpDDSurface;
} else
DDSurfDesc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
if (!(lpSSource = gCreateSurface(&DDSurfDesc, lpSSource))) {
DebugLogFile("gLoadTexture: gCreateSurface FAILED: Can't create surface DDS");
return NULL;
}
if ((lpSSource->Lock(NULL, &DDSurfDesc, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL))) { // Lock and fill with the dds
DebugLogFile("gLoadTexture: Can't lock surface DDS");
return NULL;
}
t3dReadData(DDSurfDesc.lpSurface, DDSurfDesc.dwLinearSize);
if ((lpSSource->Unlock(NULL))) {
DebugLogFile("gLoadTexture: Can't unlock surface DDS");
return NULL;
}
#endif
stream = nullptr;
} else { // TGA
auto stream = workDirs.resolveFile(TextName);
auto image = ReadTgaImage(TextName, *stream, Graphics::PixelFormat::createFormatRGBA32(), 0); // TODO Flags
SurfaceBackedTextureData texData(image);
texture->_texture->assignData(texData);
#if 0
//warning("TODO: Handle TGA");
if (!t3dOpenFile(TextName)) {
DebugLogFile("gAddMaterial:gLoadTexture: Cannot find %s.\n", TextName);
return NULL;
}
// Parse the PPM header
if (!loadTGAHeader(&dwWidth, &dwHeight)) {
t3dCloseFile();
DebugLogFile("gAddMaterial: gLoadTexture: Could not load or parse TGA header in %s.\n", TextName);
return NULL;
}
#endif
}
#if 0 // Replaced by createTextureFromSurface
if (!(gRenderFlags & gDXT1SUPPORTED) || (bUseAlternate == FALSE)) {
memset(&DDSurfDesc, 0, sizeof(DDSURFACEDESC2));
memcpy(&DDSurfDesc.ddpfPixelFormat, &gCurrentFormat->SurfaceDesc, sizeof(DDPIXELFORMAT));
DDSurfDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
/* if (gRenderFlags&gAGPSUPPORTED)
{ //Alloc texture in AGP
DDSurfDesc.ddsCaps.dwCaps= DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY |
DDSCAPS_TEXTURE;
}
else
*/ { //No AGP support; alloc in sysmem
DDSurfDesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
DDSurfDesc.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
}
DDSurfDesc.dwWidth = dwWidth;
DDSurfDesc.dwHeight = dwHeight;
if (!(Texture->lpDDSurface = gCreateSurface(&DDSurfDesc, Texture->lpDDSurface))) {
DebugLogFile("gLoadTexture: gCreateSurface FAILED: Can't create surface");
return NULL;
}
}
#endif
texture->name = TextName;
if (bUseAlternate) {
#if 0
// DebugFile( "Carico |%s|", AlternateName );
if (!(gRenderFlags & gDXT1SUPPORTED)) {
if (Texture->lpDDSurface->Blt(NULL, lpSSource, NULL, DDBLT_WAIT, NULL) != DD_OK) {
DebugLogFile("gLoadTexture: Can't Blit DDS texture");
return NULL;
}
lpSSource->Release();
} else
Texture->lpDDSurface = lpSSource;
#endif
} else {
#if 0
// DebugFile( "Carico |%s|", TextName );
Texture->lpDDSurface->Lock(NULL, &DDSurfDesc, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); //Lock and fill with the tga
if (gCurrentFormat->abits)
bAlpha = TRUE;
if (!ReadTgaImage(TextName, &DDSurfDesc, bAlpha)) {
DebugLogFile("gLoadTexture: Error reading TGA file");
return NULL;
}
Texture->lpDDSurface->Unlock(NULL);
#endif
}
texture->RealDimX = dwWidth;
texture->RealDimY = dwHeight;
if (_LoaderFlags & rSURFACEHALF) {
warning("Half-res loading not implemented");
#if 0
LPDIRECTDRAWSURFACE7 surf;
HRESULT err;
dwWidth /= 2;
dwHeight /= 2;
memset(&DDSurfDesc, 0, sizeof(DDSURFACEDESC2));
memcpy(&DDSurfDesc.ddpfPixelFormat, &gCurrentFormat->SurfaceDesc, sizeof(DDPIXELFORMAT));
DDSurfDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
/* if (gRenderFlags&gAGPSUPPORTED)
{ //Alloc texture in AGP
DDSurfDesc.ddsCaps.dwCaps= DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY |
DDSCAPS_TEXTURE;
}
else
*/ { //No AGP support; alloc in sysmem
DDSurfDesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
DDSurfDesc.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
}
surf = NULL;
DDSurfDesc.dwWidth = dwWidth;
DDSurfDesc.dwHeight = dwHeight;
if (!(surf = gCreateSurface(&DDSurfDesc, surf))) {
DebugLogFile("gLoadTexture (rSURFACEHALF) FAILED: Can't create surface");
return NULL;
}
if ((err = surf->Blt(NULL, Texture->lpDDSurface, NULL, 0, NULL)) != DD_OK) {
char str[255];
GetDDErrorString(err, str, 1);
DebugLogFile("gLoadTexture: BltStretch failed.\n%s", str);
}
//Release old texture
Texture->lpDDSurface->Release();
//Assign the newone
Texture->lpDDSurface = surf;
#endif
}
texture->ID = pos;
texture->Flags = CurLoaderFlags;
texture->DimX = dwWidth;
texture->DimY = dwHeight;
return texture;
}
bool Renderer::addMaterial(gMaterial &material, const Common::String &name, int NumFaces, unsigned int _LoaderFlags) {
//warning("AddMaterial(%s)", name.c_str());
if (hasFileExtension(name, "avi")) {
auto tex = createGLTexture();
if ((material.Movie = gLoadMovie(*_workDirs, name.c_str(), tex)) == nullptr)
return false;
if ((material.Texture = gUserTexture(tex, 64, 128)) == nullptr)
// if( (Material->Texture=gUserTexture( Material->Movie->g_psiStreamInfo.rcFrame.right,
// Material->Movie->g_psiStreamInfo.rcFrame.bottom)) == NULL )
return false;
material.addProperty(T3D_MATERIAL_MOVIE);
} else {
if ((material.Texture = gLoadTexture(*_workDirs, name.c_str(), _LoaderFlags)) == nullptr)
return false;
}
//f
material.addProperty(T3D_MATERIAL_NOLIGHTMAP);
return true;
}
} // End of namespace Watchmaker
#endif // USE_OPENGL_GAME