Multitexturing support
- added CImage class for loading/saving images and a simple test for it - added libpng library to build - added Gfx::Texture struct - updated the Gfx::CDevice interface to include new features - implemented the new features in Gfx::CGLDevicedev-ui
parent
d9c5a439d0
commit
f95df35dc5
|
@ -8,6 +8,7 @@ project(colobot C CXX)
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(SDL REQUIRED)
|
find_package(SDL REQUIRED)
|
||||||
find_package(SDL_image REQUIRED)
|
find_package(SDL_image REQUIRED)
|
||||||
|
find_package(PNG REQUIRED)
|
||||||
|
|
||||||
# TODO: check for SDL version. Should be >= 1.2.10
|
# TODO: check for SDL version. Should be >= 1.2.10
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ app/app.cpp
|
||||||
app/main.cpp
|
app/main.cpp
|
||||||
app/system.cpp
|
app/system.cpp
|
||||||
common/event.cpp
|
common/event.cpp
|
||||||
|
common/image.cpp
|
||||||
common/iman.cpp
|
common/iman.cpp
|
||||||
# common/metafile.cpp
|
# common/metafile.cpp
|
||||||
# common/misc.cpp
|
# common/misc.cpp
|
||||||
|
@ -150,10 +151,16 @@ set(LIBS
|
||||||
${SDL_LIBRARY}
|
${SDL_LIBRARY}
|
||||||
${SDLIMAGE_LIBRARY}
|
${SDLIMAGE_LIBRARY}
|
||||||
${OPENGL_LIBRARY}
|
${OPENGL_LIBRARY}
|
||||||
|
${PNG_LIBRARIES}
|
||||||
#CBot -- not yet WinAPI-independent
|
#CBot -- not yet WinAPI-independent
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(. ${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(. ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${SDL_INCLUDE_DIR}
|
||||||
|
${SDL_IMAGE_INCLUDE_DIR}
|
||||||
|
${SDLTTF_INCLUDE_DIR}
|
||||||
|
${PNG_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/CBot)
|
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/CBot)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,221 @@
|
||||||
|
// * This file is part of the COLOBOT source code
|
||||||
|
// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
|
||||||
|
// *
|
||||||
|
// * 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/.
|
||||||
|
|
||||||
|
// image.cpp
|
||||||
|
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
#include <SDL/SDL_image.h>
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* <---------------------------------------------------------------> */
|
||||||
|
|
||||||
|
/* The following code is from savesurf program by Angelo "Encelo" Theodorou
|
||||||
|
Source: http://encelo.netsons.org/old/sdl/
|
||||||
|
The code was refactored and modified slightly to fit the needs.
|
||||||
|
The copyright information below is kept unchanged. */
|
||||||
|
|
||||||
|
|
||||||
|
/* SaveSurf: an example on how to save a SDLSurface in PNG
|
||||||
|
Copyright (C) 2006 Angelo "Encelo" Theodorou
|
||||||
|
|
||||||
|
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 2 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, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
|
||||||
|
This program is part of "Mars, Land of No Mercy" SDL examples,
|
||||||
|
you can find other examples on http://marsnomercy.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
std::string PNG_ERROR = "";
|
||||||
|
|
||||||
|
void PNGUserError(png_structp ctx, png_const_charp str)
|
||||||
|
{
|
||||||
|
PNG_ERROR = std::string(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PNGColortypeFromSurface(SDL_Surface *surface)
|
||||||
|
{
|
||||||
|
int colortype = PNG_COLOR_MASK_COLOR; /* grayscale not supported */
|
||||||
|
|
||||||
|
if (surface->format->palette)
|
||||||
|
colortype |= PNG_COLOR_MASK_PALETTE;
|
||||||
|
else if (surface->format->Amask)
|
||||||
|
colortype |= PNG_COLOR_MASK_ALPHA;
|
||||||
|
|
||||||
|
return colortype;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PNGSaveSurface(const char *filename, SDL_Surface *surf)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
png_structp png_ptr;
|
||||||
|
png_infop info_ptr;
|
||||||
|
int i, colortype;
|
||||||
|
png_bytep *row_pointers;
|
||||||
|
|
||||||
|
PNG_ERROR = "";
|
||||||
|
|
||||||
|
/* Opening output file */
|
||||||
|
fp = fopen(filename, "wb");
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
PNG_ERROR = std::string("Could not open file '") + std::string(filename) + std::string("' for saving");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initializing png structures and callbacks */
|
||||||
|
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNGUserError, NULL);
|
||||||
|
if (png_ptr == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
info_ptr = png_create_info_struct(png_ptr);
|
||||||
|
if (info_ptr == NULL)
|
||||||
|
{
|
||||||
|
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||||
|
PNG_ERROR = "png_create_info_struct() error!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||||
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_init_io(png_ptr, fp);
|
||||||
|
|
||||||
|
colortype = PNGColortypeFromSurface(surf);
|
||||||
|
png_set_IHDR(png_ptr, info_ptr, surf->w, surf->h, 8, colortype, PNG_INTERLACE_NONE,
|
||||||
|
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||||
|
|
||||||
|
/* Writing the image */
|
||||||
|
png_write_info(png_ptr, info_ptr);
|
||||||
|
png_set_packing(png_ptr);
|
||||||
|
|
||||||
|
row_pointers = (png_bytep*) malloc(sizeof(png_bytep)*surf->h);
|
||||||
|
for (i = 0; i < surf->h; i++)
|
||||||
|
row_pointers[i] = (png_bytep)(Uint8 *)surf->pixels + i*surf->pitch;
|
||||||
|
png_write_image(png_ptr, row_pointers);
|
||||||
|
png_write_end(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
/* Cleaning out... */
|
||||||
|
free(row_pointers);
|
||||||
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* <---------------------------------------------------------------> */
|
||||||
|
|
||||||
|
|
||||||
|
CImage::CImage()
|
||||||
|
{
|
||||||
|
m_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CImage::~CImage()
|
||||||
|
{
|
||||||
|
Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CImage::IsEmpty()
|
||||||
|
{
|
||||||
|
return m_data == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImage::Free()
|
||||||
|
{
|
||||||
|
if (m_data != NULL)
|
||||||
|
{
|
||||||
|
if (m_data->surface != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(m_data->surface);
|
||||||
|
m_data->surface = NULL;
|
||||||
|
}
|
||||||
|
delete m_data;
|
||||||
|
m_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageData* CImage::GetData()
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CImage::GetError()
|
||||||
|
{
|
||||||
|
return m_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CImage::Load(const std::string& fileName)
|
||||||
|
{
|
||||||
|
if (! IsEmpty() )
|
||||||
|
Free();
|
||||||
|
|
||||||
|
m_data = new ImageData();
|
||||||
|
|
||||||
|
m_error = "";
|
||||||
|
|
||||||
|
m_data->surface = IMG_Load(fileName.c_str());
|
||||||
|
if (m_data->surface == NULL)
|
||||||
|
{
|
||||||
|
delete m_data;
|
||||||
|
m_data = NULL;
|
||||||
|
|
||||||
|
m_error = std::string(IMG_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CImage::SavePNG(const std::string& fileName)
|
||||||
|
{
|
||||||
|
if (IsEmpty())
|
||||||
|
{
|
||||||
|
m_error = "Empty image!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_error = "";
|
||||||
|
|
||||||
|
if (! PNGSaveSurface(fileName.c_str(), m_data->surface) )
|
||||||
|
{
|
||||||
|
m_error = PNG_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
// * This file is part of the COLOBOT source code
|
||||||
|
// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
|
||||||
|
// *
|
||||||
|
// * 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/.
|
||||||
|
|
||||||
|
// image.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
// Forward declaration without including headers to clutter the code
|
||||||
|
struct SDL_Surface;
|
||||||
|
|
||||||
|
//! Implementation-specific image data
|
||||||
|
/** Note that the struct has no destructor and the surface
|
||||||
|
will not be freed at destruction. */
|
||||||
|
struct ImageData
|
||||||
|
{
|
||||||
|
//! SDL surface with image data
|
||||||
|
SDL_Surface* surface;
|
||||||
|
|
||||||
|
ImageData() { surface = NULL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\class CImage
|
||||||
|
\brief Image loaded from file
|
||||||
|
|
||||||
|
Wrapper around SDL_Image library to load images. Also contains
|
||||||
|
function for saving images to PNG.
|
||||||
|
*/
|
||||||
|
class CImage
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
//! Blocked!
|
||||||
|
CImage(const CImage &other) {}
|
||||||
|
//! Blocked!
|
||||||
|
void operator=(const CImage &other) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Constructs empty image (with NULL data)
|
||||||
|
CImage();
|
||||||
|
//! Destroys image, calling Free()
|
||||||
|
virtual ~CImage();
|
||||||
|
|
||||||
|
//! Frees the allocated image data
|
||||||
|
void Free();
|
||||||
|
|
||||||
|
//! Returns whether the image is empty (has NULL data)
|
||||||
|
bool IsEmpty();
|
||||||
|
|
||||||
|
//! Returns the image data; if empty - returns NULL
|
||||||
|
ImageData* GetData();
|
||||||
|
|
||||||
|
//! Loads an image from the specified file
|
||||||
|
bool Load(const std::string &fileName);
|
||||||
|
|
||||||
|
//! Saves the image to the specified file in PNG format
|
||||||
|
bool SavePNG(const std::string &fileName);
|
||||||
|
|
||||||
|
//! Returns the last error
|
||||||
|
std::string GetError();
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Last encountered error
|
||||||
|
std::string m_error;
|
||||||
|
//! Image data
|
||||||
|
ImageData* m_data;
|
||||||
|
};
|
|
@ -0,0 +1,6 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
set(CMAKE_BUILD_TYPE debug)
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0")
|
||||||
|
|
||||||
|
add_executable(image_test ../image.cpp image_test.cpp)
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "../image.h"
|
||||||
|
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* For now, just a simple test: loading a file from image
|
||||||
|
* and saving it to another in PNG. */
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (argc != 3)
|
||||||
|
{
|
||||||
|
printf("Usage: %s in_image out_image\n", argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CImage image;
|
||||||
|
|
||||||
|
if (! image.Load(argv[1]))
|
||||||
|
{
|
||||||
|
std::string err = image.GetError();
|
||||||
|
printf("Error loading '%s': %s\n", err.c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! image.SavePNG(argv[2]))
|
||||||
|
{
|
||||||
|
std::string err = image.GetError();
|
||||||
|
printf("Error saving PNG '%s': %s\n", err.c_str());
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -31,3 +31,20 @@ void Gfx::DeviceConfig::LoadDefault()
|
||||||
doubleBuf = true;
|
doubleBuf = true;
|
||||||
noFrame = false;
|
noFrame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx::TextureParams::LoadDefault()
|
||||||
|
{
|
||||||
|
minFilter = Gfx::TEX_MIN_FILTER_NEAREST;
|
||||||
|
magFilter = Gfx::TEX_MAG_FILTER_NEAREST;
|
||||||
|
|
||||||
|
wrapS = Gfx::TEX_WRAP_REPEAT;
|
||||||
|
wrapT = Gfx::TEX_WRAP_REPEAT;
|
||||||
|
|
||||||
|
colorOperation = Gfx::TEX_MIX_OPER_MODULATE;
|
||||||
|
colorArg1 = Gfx::TEX_MIX_ARG_CURRENT;
|
||||||
|
colorArg2 = Gfx::TEX_MIX_ARG_TEXTURE;
|
||||||
|
|
||||||
|
alphaOperation = Gfx::TEX_MIX_OPER_MODULATE;
|
||||||
|
alphaArg1 = Gfx::TEX_MIX_ARG_CURRENT;
|
||||||
|
alphaArg2 = Gfx::TEX_MIX_ARG_TEXTURE;
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
class CImage;
|
||||||
|
|
||||||
|
|
||||||
namespace Gfx {
|
namespace Gfx {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,6 +147,15 @@ enum CullMode
|
||||||
CULL_CCW
|
CULL_CCW
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\enum ShadeModel
|
||||||
|
\brief Shade model used in rendering */
|
||||||
|
enum ShadeModel
|
||||||
|
{
|
||||||
|
SHADE_FLAT,
|
||||||
|
SHADE_SMOOTH
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\enum FillMode
|
\enum FillMode
|
||||||
\brief Polygon fill mode */
|
\brief Polygon fill mode */
|
||||||
|
@ -169,6 +181,147 @@ enum PrimitiveType
|
||||||
PRIMITIVE_TRIANGLE_STRIP
|
PRIMITIVE_TRIANGLE_STRIP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\enum TexMinFilter
|
||||||
|
\brief Minification texture filter
|
||||||
|
|
||||||
|
Corresponds to OpenGL modes but should translate to DirectX too. */
|
||||||
|
enum TexMinFilter
|
||||||
|
{
|
||||||
|
TEX_MIN_FILTER_NEAREST,
|
||||||
|
TEX_MIN_FILTER_LINEAR,
|
||||||
|
TEX_MIN_FILTER_NEAREST_MIPMAP_NEAREST,
|
||||||
|
TEX_MIN_FILTER_LINEAR_MIPMAP_NEAREST,
|
||||||
|
TEX_MIN_FILTER_NEAREST_MIPMAP_LINEAR,
|
||||||
|
TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\enum TexMagFilter
|
||||||
|
\brief Magnification texture filter */
|
||||||
|
enum TexMagFilter
|
||||||
|
{
|
||||||
|
TEX_MAG_FILTER_NEAREST,
|
||||||
|
TEX_MAG_FILTER_LINEAR
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\enum TexWrapMode
|
||||||
|
\brief Wrapping mode for texture coords */
|
||||||
|
enum TexWrapMode
|
||||||
|
{
|
||||||
|
TEX_WRAP_CLAMP,
|
||||||
|
TEX_WRAP_REPEAT
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\enum TexMixOperation
|
||||||
|
\brief Multitexture mixing operation
|
||||||
|
*/
|
||||||
|
enum TexMixOperation
|
||||||
|
{
|
||||||
|
TEX_MIX_OPER_MODULATE,
|
||||||
|
TEX_MIX_OPER_ADD
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\enum TexMixArgument
|
||||||
|
\brief Multitexture mixing argument
|
||||||
|
*/
|
||||||
|
enum TexMixArgument
|
||||||
|
{
|
||||||
|
TEX_MIX_ARG_CURRENT,
|
||||||
|
TEX_MIX_ARG_TEXTURE,
|
||||||
|
TEX_MIX_ARG_DIFFUSE,
|
||||||
|
TEX_MIX_ARG_FACTOR
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\enum TextureParams
|
||||||
|
\brief Parameters for texture creation
|
||||||
|
*/
|
||||||
|
struct TextureParams
|
||||||
|
{
|
||||||
|
//! Minification filter
|
||||||
|
Gfx::TexMinFilter minFilter;
|
||||||
|
//! Magnification filter
|
||||||
|
Gfx::TexMagFilter magFilter;
|
||||||
|
//! Wrap S coord mode
|
||||||
|
Gfx::TexWrapMode wrapS;
|
||||||
|
//! Wrap T coord mode
|
||||||
|
Gfx::TexWrapMode wrapT;
|
||||||
|
//! Mixing operation done on color values
|
||||||
|
Gfx::TexMixOperation colorOperation;
|
||||||
|
//! 1st argument of color operations
|
||||||
|
Gfx::TexMixArgument colorArg1;
|
||||||
|
//! 2nd argument of color operations
|
||||||
|
Gfx::TexMixArgument colorArg2;
|
||||||
|
//! Mixing operation done on alpha values
|
||||||
|
Gfx::TexMixOperation alphaOperation;
|
||||||
|
//! 1st argument of alpha operations
|
||||||
|
Gfx::TexMixArgument alphaArg1;
|
||||||
|
//! 2nd argument of alpha operations
|
||||||
|
Gfx::TexMixArgument alphaArg2;
|
||||||
|
|
||||||
|
//! Constructor; calls LoadDefault()
|
||||||
|
TextureParams()
|
||||||
|
{ LoadDefault(); }
|
||||||
|
|
||||||
|
//! Loads the default values
|
||||||
|
void LoadDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Notes for rewriting DirectX code:
|
||||||
|
|
||||||
|
>> SetRenderState() translates to many functions depending on param
|
||||||
|
|
||||||
|
D3DRENDERSTATE_ALPHABLENDENABLE -> SetRenderState() with RENDER_STATE_BLENDING
|
||||||
|
D3DRENDERSTATE_ALPHAFUNC -> SetAlphaTestFunc() func
|
||||||
|
D3DRENDERSTATE_ALPHAREF -> SetAlphaTestFunc() ref
|
||||||
|
D3DRENDERSTATE_ALPHATESTENABLE -> SetRenderState() with RENDER_STATE_ALPHA_TEST
|
||||||
|
D3DRENDERSTATE_AMBIENT -> SetGlobalAmbient()
|
||||||
|
D3DRENDERSTATE_CULLMODE -> SetCullMode()
|
||||||
|
D3DRENDERSTATE_DESTBLEND -> SetBlendFunc() dest blending func
|
||||||
|
D3DRENDERSTATE_DITHERENABLE -> SetRenderState() with RENDER_STATE_DITHERING
|
||||||
|
D3DRENDERSTATE_FILLMODE -> SetFillMode()
|
||||||
|
D3DRENDERSTATE_FOGCOLOR -> SetFogParams()
|
||||||
|
D3DRENDERSTATE_FOGENABLE -> SetRenderState() with RENDER_STATE_FOG
|
||||||
|
D3DRENDERSTATE_FOGEND -> SetFogParams()
|
||||||
|
D3DRENDERSTATE_FOGSTART -> SetFogParams()
|
||||||
|
D3DRENDERSTATE_FOGVERTEXMODE -> SetFogParams() fog model
|
||||||
|
D3DRENDERSTATE_LIGHTING -> SetRenderState() with RENDER_STATE_LIGHTING
|
||||||
|
D3DRENDERSTATE_SHADEMODE -> SetShadeModel()
|
||||||
|
D3DRENDERSTATE_SPECULARENABLE -> doesn't matter (always enabled)
|
||||||
|
D3DRENDERSTATE_SRCBLEND -> SetBlendFunc() src blending func
|
||||||
|
D3DRENDERSTATE_TEXTUREFACTOR -> SetTextureFactor()
|
||||||
|
D3DRENDERSTATE_ZBIAS -> SetDepthBias()
|
||||||
|
D3DRENDERSTATE_ZENABLE -> SetRenderState() with RENDER_STATE_DEPTH_TEST
|
||||||
|
D3DRENDERSTATE_ZFUNC -> SetDepthTestFunc()
|
||||||
|
D3DRENDERSTATE_ZWRITEENABLE -> SetRenderState() with RENDER_STATE_DEPTH_WRITE
|
||||||
|
|
||||||
|
|
||||||
|
>> SetTextureStageState() translates to SetTextureParams()
|
||||||
|
|
||||||
|
Params from enum in struct TextureParams
|
||||||
|
D3DTSS_ADDRESS -> Gfx::TexWrapMode wrapS, wrapT
|
||||||
|
D3DTSS_ALPHAARG1 -> Gfx::TexMixArgument alphaArg1
|
||||||
|
D3DTSS_ALPHAARG2 -> Gfx::TexMixArgument alphaArg2
|
||||||
|
D3DTSS_ALPHAOP -> Gfx::TexMixOperation alphaOperation
|
||||||
|
D3DTSS_COLORARG1 -> Gfx::TexMixArgument colorArg1
|
||||||
|
D3DTSS_COLORARG2 -> Gfx::TexMixArgument colorArg2
|
||||||
|
D3DTSS_COLOROP -> Gfx::TexMixOperation colorOperation
|
||||||
|
D3DTSS_MAGFILTER -> Gfx::TexMagFilter magFilter
|
||||||
|
D3DTSS_MINFILTER -> Gfx::TexMinFilter minFilter
|
||||||
|
D3DTSS_TEXCOORDINDEX -> doesn't matter (texture coords are set explicitly by glMultiTexCoordARB*)
|
||||||
|
|
||||||
|
Note that D3DTSS_ALPHAOP or D3DTSS_COLOROP set to D3DTOP_DISABLE must translate to disabling the whole texture stage.
|
||||||
|
In DirectX, you shouldn't mix enabling one and disabling the other.
|
||||||
|
Also, if previous stage is disabled in DirectX, the later ones are disabled, too. In OpenGL, that is not the case.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\class CDevice
|
\class CDevice
|
||||||
\brief Abstract interface of graphics device
|
\brief Abstract interface of graphics device
|
||||||
|
@ -226,20 +379,33 @@ public:
|
||||||
//! Returns the current enable state of light at given index
|
//! Returns the current enable state of light at given index
|
||||||
virtual bool GetLightEnabled(int index) = 0;
|
virtual bool GetLightEnabled(int index) = 0;
|
||||||
|
|
||||||
// TODO:
|
//! Creates a texture from image; the image can be safely removed after that
|
||||||
// virtual Gfx::Texture* CreateTexture(CImage *image) = 0;
|
virtual Gfx::Texture* CreateTexture(CImage *image, bool alpha, bool mipMap) = 0;
|
||||||
// virtual void DestroyTexture(Gfx::Texture *texture) = 0;
|
//! Deletes a given texture, freeing it from video memory
|
||||||
|
virtual void DestroyTexture(Gfx::Texture *texture) = 0;
|
||||||
|
//! Deletes all textures created so far
|
||||||
|
virtual void DestroyAllTextures() = 0;
|
||||||
|
|
||||||
//! Returns the maximum number of multitexture units
|
//! Returns the maximum number of multitexture stages
|
||||||
virtual int GetMaxTextureCount() = 0;
|
virtual int GetMaxTextureCount() = 0;
|
||||||
//! Sets the (multi)texture at given index
|
//! Sets the (multi)texture at given index
|
||||||
virtual void SetTexture(int index, Gfx::Texture *texture) = 0;
|
virtual void SetTexture(int index, Gfx::Texture *texture) = 0;
|
||||||
//! Returns the (multi)texture at given index
|
//! Returns the (multi)texture at given index
|
||||||
virtual Gfx::Texture* GetTexture(int index) = 0;
|
virtual Gfx::Texture* GetTexture(int index) = 0;
|
||||||
|
//! Enables/disables the given texture stage
|
||||||
|
virtual void SetTextureEnabled(int index, bool enabled) = 0;
|
||||||
|
//! Returns the current enable state of given texture stage
|
||||||
|
virtual bool GetTextureEnabled(int index) = 0;
|
||||||
|
|
||||||
// TODO:
|
//! Sets the current params of texture with given index
|
||||||
// virtual void GetTextureStageState() = 0;
|
virtual void SetTextureParams(int index, const Gfx::TextureParams ¶ms) = 0;
|
||||||
// virtual void SetTextureStageState() = 0;
|
//! Returns the current params of texture with given index
|
||||||
|
virtual Gfx::TextureParams GetTextureParams(int index) = 0;
|
||||||
|
|
||||||
|
//! Sets the texture factor to the given color value
|
||||||
|
virtual void SetTextureFactor(Gfx::Color &color) = 0;
|
||||||
|
//! Returns the current texture factor
|
||||||
|
virtual Gfx::Color GetTextureFactor() = 0;
|
||||||
|
|
||||||
//! Renders primitive composed of vertices with single texture
|
//! Renders primitive composed of vertices with single texture
|
||||||
virtual void DrawPrimitive(Gfx::PrimitiveType type, Gfx::Vertex *vertices, int vertexCount) = 0;
|
virtual void DrawPrimitive(Gfx::PrimitiveType type, Gfx::Vertex *vertices, int vertexCount) = 0;
|
||||||
|
@ -297,6 +463,11 @@ public:
|
||||||
//! Returns the current cull mode
|
//! Returns the current cull mode
|
||||||
virtual Gfx::CullMode GetCullMode() = 0;
|
virtual Gfx::CullMode GetCullMode() = 0;
|
||||||
|
|
||||||
|
//! Sets the shade model
|
||||||
|
virtual void SetShadeModel(Gfx::ShadeModel model) = 0;
|
||||||
|
//! Returns the current shade model
|
||||||
|
virtual Gfx::ShadeModel GetShadeModel() = 0;
|
||||||
|
|
||||||
//! Sets the current fill mode
|
//! Sets the current fill mode
|
||||||
virtual void SetFillMode(Gfx::FillMode mode) = 0;
|
virtual void SetFillMode(Gfx::FillMode mode) = 0;
|
||||||
//! Returns the current fill mode
|
//! Returns the current fill mode
|
||||||
|
|
|
@ -20,9 +20,16 @@
|
||||||
|
|
||||||
namespace Gfx {
|
namespace Gfx {
|
||||||
|
|
||||||
|
/** \struct Texture*/
|
||||||
struct Texture
|
struct Texture
|
||||||
{
|
{
|
||||||
// TODO
|
//! Whether the texture was loaded
|
||||||
|
bool valid;
|
||||||
|
//! Id of the texture in graphics engine
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
|
Texture()
|
||||||
|
{ valid = false; id = 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace Gfx
|
}; // namespace Gfx
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
// gldevice.cpp
|
// gldevice.cpp
|
||||||
|
|
||||||
|
#include "common/image.h"
|
||||||
#include "graphics/opengl/gldevice.h"
|
#include "graphics/opengl/gldevice.h"
|
||||||
|
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
@ -30,21 +31,13 @@ namespace Gfx {
|
||||||
|
|
||||||
struct GLDevicePrivate
|
struct GLDevicePrivate
|
||||||
{
|
{
|
||||||
void (APIENTRY* glMultiTexCoord1fARB)(GLenum target, GLfloat s);
|
|
||||||
void (APIENTRY* glMultiTexCoord2fARB)(GLenum target, GLfloat s, GLfloat t);
|
void (APIENTRY* glMultiTexCoord2fARB)(GLenum target, GLfloat s, GLfloat t);
|
||||||
void (APIENTRY* glMultiTexCoord3fARB)(GLenum target, GLfloat s, GLfloat t, GLfloat r);
|
|
||||||
void (APIENTRY* glMultiTexCoord4fARB)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
|
|
||||||
void (APIENTRY* glActiveTextureARB)(GLenum texture);
|
void (APIENTRY* glActiveTextureARB)(GLenum texture);
|
||||||
void (APIENTRY* glClientActiveTextureARB)(GLenum texture);
|
|
||||||
|
|
||||||
GLDevicePrivate()
|
GLDevicePrivate()
|
||||||
{
|
{
|
||||||
glMultiTexCoord1fARB = NULL;
|
|
||||||
glMultiTexCoord2fARB = NULL;
|
glMultiTexCoord2fARB = NULL;
|
||||||
glMultiTexCoord3fARB = NULL;
|
|
||||||
glMultiTexCoord4fARB = NULL;
|
|
||||||
glActiveTextureARB = NULL;
|
glActiveTextureARB = NULL;
|
||||||
glClientActiveTextureARB = NULL;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -71,6 +64,7 @@ Gfx::CGLDevice::CGLDevice()
|
||||||
{
|
{
|
||||||
m_private = new Gfx::GLDevicePrivate();
|
m_private = new Gfx::GLDevicePrivate();
|
||||||
m_wasInit = false;
|
m_wasInit = false;
|
||||||
|
m_texturing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,18 +86,10 @@ std::string Gfx::CGLDevice::GetError()
|
||||||
|
|
||||||
bool Gfx::CGLDevice::Create()
|
bool Gfx::CGLDevice::Create()
|
||||||
{
|
{
|
||||||
m_wasInit = true;
|
/* First check for extensions
|
||||||
|
These should be available in standard OpenGL 1.3
|
||||||
// TODO: move to functions?
|
But every distribution is different
|
||||||
glShadeModel(GL_SMOOTH);
|
So we're loading them dynamically through SDL_GL_GetProcAddress() */
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
|
|
||||||
|
|
||||||
std::string extensions = std::string( (char*) glGetString(GL_EXTENSIONS));
|
std::string extensions = std::string( (char*) glGetString(GL_EXTENSIONS));
|
||||||
|
|
||||||
|
@ -119,37 +105,58 @@ bool Gfx::CGLDevice::Create()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_private->glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord2fARB");
|
||||||
|
m_private->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB");
|
||||||
|
|
||||||
|
if ((m_private->glMultiTexCoord2fARB == NULL) || (m_private->glActiveTextureARB == NULL))
|
||||||
|
{
|
||||||
|
m_error = "Could not load extension functions, even though they seem supported";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_wasInit = true;
|
||||||
|
|
||||||
|
// This is mostly done in all modern hardware by default
|
||||||
|
// DirectX doesn't even allow the option to turn off perspective correction anymore
|
||||||
|
// So turn it on permanently
|
||||||
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||||
|
|
||||||
|
// Set just to be sure
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
|
||||||
|
m_lights = std::vector<Gfx::Light>(GL_MAX_LIGHTS, Gfx::Light());
|
||||||
|
m_lightsEnabled = std::vector<bool> (GL_MAX_LIGHTS, false);
|
||||||
|
|
||||||
int maxTextures = 0;
|
int maxTextures = 0;
|
||||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextures);
|
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextures);
|
||||||
m_textures = std::vector<Gfx::Texture*>(maxTextures, NULL);
|
|
||||||
|
|
||||||
m_lights = std::vector<Gfx::Light>(GL_MAX_LIGHTS, Gfx::Light());
|
m_textures = std::vector<Gfx::Texture*> (maxTextures, NULL);
|
||||||
m_lightsEnabled = std::vector<bool>(GL_MAX_LIGHTS, false);
|
m_texturesEnabled = std::vector<bool> (maxTextures, false);
|
||||||
|
m_texturesParams = std::vector<Gfx::TextureParams>(maxTextures, Gfx::TextureParams());
|
||||||
m_private->glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord1fARB");
|
|
||||||
m_private->glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord2fARB");
|
|
||||||
m_private->glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord3fARB");
|
|
||||||
m_private->glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord4fARB");
|
|
||||||
m_private->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB");
|
|
||||||
m_private->glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glClientActiveTextureARB");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx::CGLDevice::Destroy()
|
void Gfx::CGLDevice::Destroy()
|
||||||
{
|
{
|
||||||
m_private->glMultiTexCoord1fARB = NULL;
|
|
||||||
m_private->glMultiTexCoord2fARB = NULL;
|
m_private->glMultiTexCoord2fARB = NULL;
|
||||||
m_private->glMultiTexCoord3fARB = NULL;
|
|
||||||
m_private->glMultiTexCoord4fARB = NULL;
|
|
||||||
m_private->glActiveTextureARB = NULL;
|
m_private->glActiveTextureARB = NULL;
|
||||||
m_private->glClientActiveTextureARB = NULL;
|
|
||||||
|
|
||||||
// Delete the remaining textures
|
// Delete the remaining textures
|
||||||
std::set<Gfx::Texture*>::iterator it;
|
// Should not be strictly necessary, but just in case
|
||||||
for (it = m_allTextures.begin(); it != m_allTextures.end(); ++it)
|
DestroyAllTextures();
|
||||||
delete *it;
|
|
||||||
m_allTextures.clear();
|
m_lights.clear();
|
||||||
|
m_lightsEnabled.clear();
|
||||||
|
|
||||||
|
m_textures.clear();
|
||||||
|
m_texturesEnabled.clear();
|
||||||
|
m_texturesParams.clear();
|
||||||
|
|
||||||
m_wasInit = false;
|
m_wasInit = false;
|
||||||
}
|
}
|
||||||
|
@ -177,7 +184,7 @@ void Gfx::CGLDevice::Clear()
|
||||||
|
|
||||||
void Gfx::CGLDevice::SetTransform(Gfx::TransformType type, const Math::Matrix &matrix)
|
void Gfx::CGLDevice::SetTransform(Gfx::TransformType type, const Math::Matrix &matrix)
|
||||||
{
|
{
|
||||||
if (type == Gfx::TRANSFORM_WORLD)
|
if (type == Gfx::TRANSFORM_WORLD)
|
||||||
{
|
{
|
||||||
m_worldMat = matrix;
|
m_worldMat = matrix;
|
||||||
m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat);
|
m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat);
|
||||||
|
@ -205,7 +212,7 @@ void Gfx::CGLDevice::SetTransform(Gfx::TransformType type, const Math::Matrix &m
|
||||||
|
|
||||||
const Math::Matrix& Gfx::CGLDevice::GetTransform(Gfx::TransformType type)
|
const Math::Matrix& Gfx::CGLDevice::GetTransform(Gfx::TransformType type)
|
||||||
{
|
{
|
||||||
if (type == Gfx::TRANSFORM_WORLD)
|
if (type == Gfx::TRANSFORM_WORLD)
|
||||||
return m_worldMat;
|
return m_worldMat;
|
||||||
else if (type == Gfx::TRANSFORM_VIEW)
|
else if (type == Gfx::TRANSFORM_VIEW)
|
||||||
return m_viewMat;
|
return m_viewMat;
|
||||||
|
@ -219,7 +226,7 @@ const Math::Matrix& Gfx::CGLDevice::GetTransform(Gfx::TransformType type)
|
||||||
|
|
||||||
void Gfx::CGLDevice::MultiplyTransform(Gfx::TransformType type, const Math::Matrix &matrix)
|
void Gfx::CGLDevice::MultiplyTransform(Gfx::TransformType type, const Math::Matrix &matrix)
|
||||||
{
|
{
|
||||||
if (type == Gfx::TRANSFORM_WORLD)
|
if (type == Gfx::TRANSFORM_WORLD)
|
||||||
{
|
{
|
||||||
m_worldMat = Math::MultiplyMatrices(m_worldMat, matrix);
|
m_worldMat = Math::MultiplyMatrices(m_worldMat, matrix);
|
||||||
m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat);
|
m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat);
|
||||||
|
@ -306,7 +313,7 @@ const Gfx::Light& Gfx::CGLDevice::GetLight(int index)
|
||||||
void Gfx::CGLDevice::SetLightEnabled(int index, bool enabled)
|
void Gfx::CGLDevice::SetLightEnabled(int index, bool enabled)
|
||||||
{
|
{
|
||||||
assert(index >= 0);
|
assert(index >= 0);
|
||||||
assert(index < (int)m_lightsEnabled.size());
|
assert(index < (int)m_lights.size());
|
||||||
|
|
||||||
m_lightsEnabled[index] = enabled;
|
m_lightsEnabled[index] = enabled;
|
||||||
|
|
||||||
|
@ -321,11 +328,102 @@ bool Gfx::CGLDevice::GetLightEnabled(int index)
|
||||||
return m_lightsEnabled[index];
|
return m_lightsEnabled[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Gfx::Texture* Gfx::CGLDevice::CreateTexture(CImage *image, bool alpha, bool mipMap)
|
||||||
|
{
|
||||||
|
Gfx::Texture *result = new Gfx::Texture();
|
||||||
|
|
||||||
|
// Texturing must be enabled, so enable 1st texture stage
|
||||||
|
m_private->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glGenTextures(1, &result->id);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, result->id);
|
||||||
|
|
||||||
|
GLenum sourceFormat = 0;
|
||||||
|
if (alpha)
|
||||||
|
sourceFormat = GL_RGBA;
|
||||||
|
else
|
||||||
|
sourceFormat = GL_RGB;
|
||||||
|
|
||||||
|
ImageData *data = image->GetData();
|
||||||
|
if (data == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (mipMap)
|
||||||
|
{
|
||||||
|
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, data->surface->w,
|
||||||
|
data->surface->h, sourceFormat, GL_UNSIGNED_BYTE,
|
||||||
|
data->surface->pixels);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data->surface->w, data->surface->h,
|
||||||
|
0, sourceFormat, GL_UNSIGNED_BYTE, data->surface->pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore previous setup of 1st texture stage
|
||||||
|
RestoreTextureStage(0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx::CGLDevice::DestroyTexture(Gfx::Texture *texture)
|
||||||
|
{
|
||||||
|
std::set<Gfx::Texture*>::iterator it = m_allTextures.find(texture);
|
||||||
|
if (it != m_allTextures.end())
|
||||||
|
m_allTextures.erase(it);
|
||||||
|
|
||||||
|
glDeleteTextures(1, &texture->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx::CGLDevice::DestroyAllTextures()
|
||||||
|
{
|
||||||
|
std::set<Gfx::Texture*> allCopy = m_allTextures;
|
||||||
|
std::set<Gfx::Texture*>::iterator it;
|
||||||
|
for (it = allCopy.begin(); it != allCopy.end(); ++it)
|
||||||
|
{
|
||||||
|
DestroyTexture(*it);
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int Gfx::CGLDevice::GetMaxTextureCount()
|
int Gfx::CGLDevice::GetMaxTextureCount()
|
||||||
{
|
{
|
||||||
return m_textures.size();
|
return m_textures.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
If \a texture is \c NULL or invalid, unbinds the given texture.
|
||||||
|
If valid, binds the texture and enables the given texture stage.
|
||||||
|
The setting is remembered, even if texturing is disabled at the moment. */
|
||||||
|
void Gfx::CGLDevice::SetTexture(int index, Gfx::Texture *texture)
|
||||||
|
{
|
||||||
|
assert(index >= 0);
|
||||||
|
assert(index < (int)m_textures.size());
|
||||||
|
|
||||||
|
// Enable the given texture stage
|
||||||
|
m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
if ((texture == NULL) || (! texture->valid))
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0); // unbind texture
|
||||||
|
m_textures[index] = NULL; // remember the changes
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture->id); // bind the texture
|
||||||
|
m_textures[index] = texture; // remember the changes
|
||||||
|
SetTextureParams(index, m_texturesParams[index]); // texture params need to be re-set for the new texture
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable the stage if it is set so
|
||||||
|
if ( (! m_texturing) || (! m_texturesEnabled[index]) )
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the previously assigned texture or \c NULL if the given stage is not enabled. */
|
||||||
Gfx::Texture* Gfx::CGLDevice::GetTexture(int index)
|
Gfx::Texture* Gfx::CGLDevice::GetTexture(int index)
|
||||||
{
|
{
|
||||||
assert(index >= 0);
|
assert(index >= 0);
|
||||||
|
@ -334,14 +432,224 @@ Gfx::Texture* Gfx::CGLDevice::GetTexture(int index)
|
||||||
return m_textures[index];
|
return m_textures[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx::CGLDevice::SetTexture(int index, Gfx::Texture *texture)
|
void Gfx::CGLDevice::SetTextureEnabled(int index, bool enabled)
|
||||||
{
|
{
|
||||||
assert(index >= 0);
|
assert(index >= 0);
|
||||||
assert(index < (int)m_textures.size());
|
assert(index < (int)m_textures.size());
|
||||||
|
|
||||||
m_textures[index] = texture;
|
m_texturesEnabled[index] = enabled;
|
||||||
|
|
||||||
// TODO
|
m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
|
||||||
|
if (enabled)
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
else
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Gfx::CGLDevice::GetTextureEnabled(int index)
|
||||||
|
{
|
||||||
|
assert(index >= 0);
|
||||||
|
assert(index < (int)m_textures.size());
|
||||||
|
|
||||||
|
return m_texturesEnabled[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the texture parameters for the given texture stage.
|
||||||
|
If the given texture was not set (bound) yet, nothing happens.
|
||||||
|
The settings are remembered, even if texturing is disabled at the moment. */
|
||||||
|
void Gfx::CGLDevice::SetTextureParams(int index, const Gfx::TextureParams ¶ms)
|
||||||
|
{
|
||||||
|
assert(index >= 0);
|
||||||
|
assert(index < (int)m_textures.size());
|
||||||
|
|
||||||
|
// Remember the settings
|
||||||
|
m_texturesParams[index] = params;
|
||||||
|
|
||||||
|
// Enable the given stage
|
||||||
|
m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
GLint minF = 0;
|
||||||
|
if (params.minFilter == Gfx::TEX_MIN_FILTER_NEAREST) minF = GL_NEAREST;
|
||||||
|
else if (params.minFilter == Gfx::TEX_MIN_FILTER_LINEAR) minF = GL_LINEAR;
|
||||||
|
else if (params.minFilter == Gfx::TEX_MIN_FILTER_NEAREST_MIPMAP_NEAREST) minF = GL_NEAREST_MIPMAP_NEAREST;
|
||||||
|
else if (params.minFilter == Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_NEAREST) minF = GL_LINEAR_MIPMAP_NEAREST;
|
||||||
|
else if (params.minFilter == Gfx::TEX_MIN_FILTER_NEAREST_MIPMAP_LINEAR) minF = GL_NEAREST_MIPMAP_LINEAR;
|
||||||
|
else if (params.minFilter == Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR) minF = GL_LINEAR_MIPMAP_LINEAR;
|
||||||
|
else assert(false);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minF);
|
||||||
|
|
||||||
|
GLint magF = 0;
|
||||||
|
if (params.magFilter == Gfx::TEX_MAG_FILTER_NEAREST) magF = GL_NEAREST;
|
||||||
|
else if (params.magFilter == Gfx::TEX_MAG_FILTER_LINEAR) magF = GL_LINEAR;
|
||||||
|
else assert(false);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magF);
|
||||||
|
|
||||||
|
if (params.wrapS == Gfx::TEX_WRAP_CLAMP)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||||
|
else if (params.wrapS == Gfx::TEX_WRAP_REPEAT)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
else assert(false);
|
||||||
|
|
||||||
|
if (params.wrapT == Gfx::TEX_WRAP_CLAMP)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||||
|
else if (params.wrapT == Gfx::TEX_WRAP_REPEAT)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
else assert(false);
|
||||||
|
|
||||||
|
|
||||||
|
// Selection of operation and arguments
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||||
|
|
||||||
|
// Color operation
|
||||||
|
if (params.colorOperation == Gfx::TEX_MIX_OPER_MODULATE)
|
||||||
|
glTexEnvi(GL_TEXTURE_2D, GL_COMBINE_RGB, GL_MODULATE);
|
||||||
|
else if (params.colorOperation == Gfx::TEX_MIX_OPER_ADD)
|
||||||
|
glTexEnvi(GL_TEXTURE_2D, GL_COMBINE_RGB, GL_ADD);
|
||||||
|
else assert(false);
|
||||||
|
|
||||||
|
// Color arg1
|
||||||
|
if (params.colorArg1 == Gfx::TEX_MIX_ARG_CURRENT)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); // that's right - stupid D3D enum values
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
|
||||||
|
}
|
||||||
|
else if (params.colorArg1 == Gfx::TEX_MIX_ARG_TEXTURE)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
|
||||||
|
}
|
||||||
|
else if (params.colorArg1 == Gfx::TEX_MIX_ARG_DIFFUSE)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR); // here as well
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
|
||||||
|
}
|
||||||
|
else assert(false);
|
||||||
|
|
||||||
|
// Color arg2
|
||||||
|
if (params.colorArg2 == Gfx::TEX_MIX_ARG_CURRENT)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
||||||
|
}
|
||||||
|
else if (params.colorArg2 == Gfx::TEX_MIX_ARG_TEXTURE)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
||||||
|
}
|
||||||
|
else if (params.colorArg2 == Gfx::TEX_MIX_ARG_DIFFUSE)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
||||||
|
}
|
||||||
|
else assert(false);
|
||||||
|
|
||||||
|
// Alpha operation
|
||||||
|
if (params.alphaOperation == Gfx::TEX_MIX_OPER_MODULATE)
|
||||||
|
glTexEnvi(GL_TEXTURE_2D, GL_COMBINE_ALPHA, GL_MODULATE);
|
||||||
|
else if (params.alphaOperation == Gfx::TEX_MIX_OPER_ADD)
|
||||||
|
glTexEnvi(GL_TEXTURE_2D, GL_COMBINE_ALPHA, GL_ADD);
|
||||||
|
else assert(false);
|
||||||
|
|
||||||
|
// Alpha arg1
|
||||||
|
if (params.alphaArg1 == Gfx::TEX_MIX_ARG_CURRENT)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
else if (params.alphaArg1 == Gfx::TEX_MIX_ARG_TEXTURE)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
else if (params.alphaArg1 == Gfx::TEX_MIX_ARG_DIFFUSE)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
else assert(false);
|
||||||
|
|
||||||
|
// Alpha arg2
|
||||||
|
if (params.alphaArg2 == Gfx::TEX_MIX_ARG_CURRENT)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
else if (params.alphaArg2 == Gfx::TEX_MIX_ARG_TEXTURE)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
else if (params.alphaArg2 == Gfx::TEX_MIX_ARG_DIFFUSE)
|
||||||
|
{
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PRIMARY_COLOR);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
else assert(false);
|
||||||
|
|
||||||
|
// Disable the stage if it is set so
|
||||||
|
if ( (! m_texturing) || (! m_texturesEnabled[index]) )
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx::TextureParams Gfx::CGLDevice::GetTextureParams(int index)
|
||||||
|
{
|
||||||
|
assert(index >= 0);
|
||||||
|
assert(index < (int)m_textures.size());
|
||||||
|
|
||||||
|
return m_texturesParams[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx::CGLDevice::SetTextureFactor(Gfx::Color &color)
|
||||||
|
{
|
||||||
|
// Needs to be set for all texture stages
|
||||||
|
for (int index = 0; index < (int)m_textures.size(); ++index)
|
||||||
|
{
|
||||||
|
// Activate stage
|
||||||
|
m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color.Array());
|
||||||
|
|
||||||
|
// Disable the stage if it is set so
|
||||||
|
if ( (! m_texturing) || (! m_texturesEnabled[index]) )
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx::Color Gfx::CGLDevice::GetTextureFactor()
|
||||||
|
{
|
||||||
|
// Get from 1st stage (should be the same for all stages)
|
||||||
|
m_private->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
GLfloat color[4] = { 0.0f };
|
||||||
|
glGetTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
|
||||||
|
|
||||||
|
// Disable the 1st stage if it is set so
|
||||||
|
if ( (! m_texturing) || (! m_texturesEnabled[0]) )
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
return Gfx::Color(color[0], color[1], color[2], color[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx::CGLDevice::RestoreTextureStage(int index)
|
||||||
|
{
|
||||||
|
// Ensure that we're working with the right stage
|
||||||
|
m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
if (m_textures[index] != NULL)
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_textures[index]->id); // bind to the previous texture
|
||||||
|
else
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0); // unbind
|
||||||
|
|
||||||
|
// Disable the stage if it is set so
|
||||||
|
if ( (! m_texturing) || (! m_texturesEnabled[index]) )
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, Vertex *vertices, int vertexCount)
|
void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, Vertex *vertices, int vertexCount)
|
||||||
|
@ -374,7 +682,7 @@ void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, Gfx::VertexCol *vert
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; ++i)
|
for (int i = 0; i < vertexCount; ++i)
|
||||||
{
|
{
|
||||||
// TODO: specular?
|
// TODO: specular through EXT_separate_specular_color?
|
||||||
glColor4fv((GLfloat*)vertices[i].color.Array());
|
glColor4fv((GLfloat*)vertices[i].color.Array());
|
||||||
glTexCoord2fv((GLfloat*)vertices[i].texCoord.Array());
|
glTexCoord2fv((GLfloat*)vertices[i].texCoord.Array());
|
||||||
glVertex3fv((GLfloat*)vertices[i].coord.Array());
|
glVertex3fv((GLfloat*)vertices[i].coord.Array());
|
||||||
|
@ -395,8 +703,8 @@ void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, VertexTex2 *vertices
|
||||||
for (int i = 0; i < vertexCount; ++i)
|
for (int i = 0; i < vertexCount; ++i)
|
||||||
{
|
{
|
||||||
glNormal3fv((GLfloat*) vertices[i].normal.Array());
|
glNormal3fv((GLfloat*) vertices[i].normal.Array());
|
||||||
// TODO glMultiTexCoord2fARB(GL_TEXTURE0_ARB, vertices[i].texCoord.x, vertices[i].texCoord.y);
|
m_private->glMultiTexCoord2fARB(GL_TEXTURE0_ARB, vertices[i].texCoord.x, vertices[i].texCoord.y);
|
||||||
// TODO glMultiTexCoord2fARB(GL_TEXTURE1_ARB, vertices[i].texCoord2.x, vertices[i].texCoord2.y);
|
m_private->glMultiTexCoord2fARB(GL_TEXTURE1_ARB, vertices[i].texCoord2.x, vertices[i].texCoord2.y);
|
||||||
glVertex3fv((GLfloat*) vertices[i].coord.Array());
|
glVertex3fv((GLfloat*) vertices[i].coord.Array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,14 +720,26 @@ void Gfx::CGLDevice::SetRenderState(Gfx::RenderState state, bool enabled)
|
||||||
}
|
}
|
||||||
else if (state == RENDER_STATE_TEXTURING)
|
else if (state == RENDER_STATE_TEXTURING)
|
||||||
{
|
{
|
||||||
|
m_texturing = enabled;
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
glEnable(GL_TEXTURE_2D);
|
// All enabled multitexture stages have to be enabled
|
||||||
// TODO multitexture
|
for (int index = 0; index < (int)m_textures.size(); ++index)
|
||||||
|
{
|
||||||
|
m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
|
||||||
|
if (m_texturesEnabled[index])
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glDisable(GL_TEXTURE_2D);
|
// All multitexture stages have to be disabled
|
||||||
|
for (int index = 0; index < (int)m_textures.size(); ++index)
|
||||||
|
{
|
||||||
|
m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -445,12 +765,14 @@ void Gfx::CGLDevice::SetRenderState(Gfx::RenderState state, bool enabled)
|
||||||
|
|
||||||
bool Gfx::CGLDevice::GetRenderState(Gfx::RenderState state)
|
bool Gfx::CGLDevice::GetRenderState(Gfx::RenderState state)
|
||||||
{
|
{
|
||||||
|
if (state == RENDER_STATE_TEXTURING)
|
||||||
|
return m_texturing;
|
||||||
|
|
||||||
GLenum flag = 0;
|
GLenum flag = 0;
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case Gfx::RENDER_STATE_DEPTH_WRITE: flag = GL_DEPTH_WRITEMASK; break;
|
case Gfx::RENDER_STATE_DEPTH_WRITE: flag = GL_DEPTH_WRITEMASK; break;
|
||||||
case Gfx::RENDER_STATE_TEXTURING: flag = GL_TEXTURE_2D; break;
|
|
||||||
case Gfx::RENDER_STATE_LIGHTING: flag = GL_DEPTH_WRITEMASK; break;
|
case Gfx::RENDER_STATE_LIGHTING: flag = GL_DEPTH_WRITEMASK; break;
|
||||||
case Gfx::RENDER_STATE_BLENDING: flag = GL_BLEND; break;
|
case Gfx::RENDER_STATE_BLENDING: flag = GL_BLEND; break;
|
||||||
case Gfx::RENDER_STATE_FOG: flag = GL_FOG; break;
|
case Gfx::RENDER_STATE_FOG: flag = GL_FOG; break;
|
||||||
|
@ -602,7 +924,7 @@ void Gfx::CGLDevice::SetClearColor(Gfx::Color color)
|
||||||
|
|
||||||
Gfx::Color Gfx::CGLDevice::GetClearColor()
|
Gfx::Color Gfx::CGLDevice::GetClearColor()
|
||||||
{
|
{
|
||||||
float color[4] = { 0.0f };
|
GLfloat color[4] = { 0.0f };
|
||||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, color);
|
glGetFloatv(GL_COLOR_CLEAR_VALUE, color);
|
||||||
return Gfx::Color(color[0], color[1], color[2], color[3]);
|
return Gfx::Color(color[0], color[1], color[2], color[3]);
|
||||||
}
|
}
|
||||||
|
@ -614,7 +936,7 @@ void Gfx::CGLDevice::SetGlobalAmbient(Gfx::Color color)
|
||||||
|
|
||||||
Gfx::Color Gfx::CGLDevice::GetGlobalAmbient()
|
Gfx::Color Gfx::CGLDevice::GetGlobalAmbient()
|
||||||
{
|
{
|
||||||
float color[4] = { 0.0f };
|
GLfloat color[4] = { 0.0f };
|
||||||
glGetFloatv(GL_LIGHT_MODEL_AMBIENT, color);
|
glGetFloatv(GL_LIGHT_MODEL_AMBIENT, color);
|
||||||
return Gfx::Color(color[0], color[1], color[2], color[3]);
|
return Gfx::Color(color[0], color[1], color[2], color[3]);
|
||||||
}
|
}
|
||||||
|
@ -662,6 +984,23 @@ Gfx::CullMode Gfx::CGLDevice::GetCullMode()
|
||||||
return Gfx::CULL_CW;
|
return Gfx::CULL_CW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx::CGLDevice::SetShadeModel(Gfx::ShadeModel model)
|
||||||
|
{
|
||||||
|
if (model == Gfx::SHADE_FLAT) glShadeModel(GL_FLAT);
|
||||||
|
else if (model == Gfx::SHADE_SMOOTH) glShadeModel(GL_SMOOTH);
|
||||||
|
else assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx::ShadeModel Gfx::CGLDevice::GetShadeModel()
|
||||||
|
{
|
||||||
|
GLenum flag = 0;
|
||||||
|
glGetIntegerv(GL_SHADE_MODEL, (GLint*)&flag);
|
||||||
|
if (flag == GL_FLAT) return Gfx::SHADE_FLAT;
|
||||||
|
else if (flag == GL_SMOOTH) return Gfx::SHADE_SMOOTH;
|
||||||
|
else assert(false);
|
||||||
|
return Gfx::SHADE_FLAT;
|
||||||
|
}
|
||||||
|
|
||||||
void Gfx::CGLDevice::SetFillMode(Gfx::FillMode mode)
|
void Gfx::CGLDevice::SetFillMode(Gfx::FillMode mode)
|
||||||
{
|
{
|
||||||
if (mode == Gfx::FILL_POINT) glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
|
if (mode == Gfx::FILL_POINT) glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
|
||||||
|
@ -677,6 +1016,6 @@ Gfx::FillMode Gfx::CGLDevice::GetFillMode()
|
||||||
if (flag == GL_POINT) return Gfx::FILL_POINT;
|
if (flag == GL_POINT) return Gfx::FILL_POINT;
|
||||||
else if (flag == GL_LINE) return Gfx::FILL_LINES;
|
else if (flag == GL_LINE) return Gfx::FILL_LINES;
|
||||||
else if (flag == GL_FILL) return Gfx::FILL_FILL;
|
else if (flag == GL_FILL) return Gfx::FILL_FILL;
|
||||||
else assert(false);
|
else assert(false);
|
||||||
return Gfx::FILL_POINT;
|
return Gfx::FILL_POINT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,9 +97,21 @@ public:
|
||||||
virtual void SetLightEnabled(int index, bool enabled);
|
virtual void SetLightEnabled(int index, bool enabled);
|
||||||
virtual bool GetLightEnabled(int index);
|
virtual bool GetLightEnabled(int index);
|
||||||
|
|
||||||
|
virtual Gfx::Texture* CreateTexture(CImage *image, bool alpha, bool mipMap);
|
||||||
|
virtual void DestroyTexture(Gfx::Texture *texture);
|
||||||
|
virtual void DestroyAllTextures();
|
||||||
|
|
||||||
virtual int GetMaxTextureCount();
|
virtual int GetMaxTextureCount();
|
||||||
virtual void SetTexture(int index, Gfx::Texture *texture);
|
virtual void SetTexture(int index, Gfx::Texture *texture);
|
||||||
virtual Gfx::Texture* GetTexture(int index);
|
virtual Gfx::Texture* GetTexture(int index);
|
||||||
|
virtual void SetTextureEnabled(int index, bool enabled);
|
||||||
|
virtual bool GetTextureEnabled(int index);
|
||||||
|
|
||||||
|
virtual void SetTextureParams(int index, const Gfx::TextureParams ¶ms);
|
||||||
|
virtual Gfx::TextureParams GetTextureParams(int index);
|
||||||
|
|
||||||
|
virtual void SetTextureFactor(Gfx::Color &color);
|
||||||
|
virtual Gfx::Color GetTextureFactor();
|
||||||
|
|
||||||
virtual void DrawPrimitive(Gfx::PrimitiveType type, Vertex *vertices, int vertexCount);
|
virtual void DrawPrimitive(Gfx::PrimitiveType type, Vertex *vertices, int vertexCount);
|
||||||
virtual void DrawPrimitive(Gfx::PrimitiveType type, Gfx::VertexCol *vertices, int vertexCount);
|
virtual void DrawPrimitive(Gfx::PrimitiveType type, Gfx::VertexCol *vertices, int vertexCount);
|
||||||
|
@ -133,6 +145,9 @@ public:
|
||||||
virtual void SetCullMode(Gfx::CullMode mode);
|
virtual void SetCullMode(Gfx::CullMode mode);
|
||||||
virtual Gfx::CullMode GetCullMode();
|
virtual Gfx::CullMode GetCullMode();
|
||||||
|
|
||||||
|
virtual void SetShadeModel(Gfx::ShadeModel model);
|
||||||
|
virtual Gfx::ShadeModel GetShadeModel();
|
||||||
|
|
||||||
virtual void SetFillMode(Gfx::FillMode mode) ;
|
virtual void SetFillMode(Gfx::FillMode mode) ;
|
||||||
virtual Gfx::FillMode GetFillMode();
|
virtual Gfx::FillMode GetFillMode();
|
||||||
|
|
||||||
|
@ -143,6 +158,7 @@ private:
|
||||||
bool m_wasInit;
|
bool m_wasInit;
|
||||||
//! Last encountered error
|
//! Last encountered error
|
||||||
std::string m_error;
|
std::string m_error;
|
||||||
|
|
||||||
//! Current world matrix
|
//! Current world matrix
|
||||||
Math::Matrix m_worldMat;
|
Math::Matrix m_worldMat;
|
||||||
//! Current view matrix
|
//! Current view matrix
|
||||||
|
@ -151,16 +167,29 @@ private:
|
||||||
Math::Matrix m_modelviewMat;
|
Math::Matrix m_modelviewMat;
|
||||||
//! Current projection matrix
|
//! Current projection matrix
|
||||||
Math::Matrix m_projectionMat;
|
Math::Matrix m_projectionMat;
|
||||||
|
|
||||||
//! The current material
|
//! The current material
|
||||||
Gfx::Material m_material;
|
Gfx::Material m_material;
|
||||||
|
|
||||||
//! Current lights
|
//! Current lights
|
||||||
std::vector<Gfx::Light> m_lights;
|
std::vector<Gfx::Light> m_lights;
|
||||||
//! Current lights enable status
|
//! Current lights enable status
|
||||||
std::vector<bool> m_lightsEnabled;
|
std::vector<bool> m_lightsEnabled;
|
||||||
//! Current textures
|
|
||||||
|
//! Whether texturing is enabled in general
|
||||||
|
bool m_texturing;
|
||||||
|
//! Current textures; \c NULL value means unassigned
|
||||||
std::vector<Gfx::Texture*> m_textures;
|
std::vector<Gfx::Texture*> m_textures;
|
||||||
|
//! Current texture stages enable status
|
||||||
|
std::vector<bool> m_texturesEnabled;
|
||||||
|
//! Current texture params
|
||||||
|
std::vector<Gfx::TextureParams> m_texturesParams;
|
||||||
|
|
||||||
//! Set of all created textures
|
//! Set of all created textures
|
||||||
std::set<Gfx::Texture*> m_allTextures;
|
std::set<Gfx::Texture*> m_allTextures;
|
||||||
|
|
||||||
|
//! Restores the state of given texture stage to the previously saved settings
|
||||||
|
void RestoreTextureStage(int index);
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace Gfx
|
}; // namespace Gfx
|
||||||
|
|
Loading…
Reference in New Issue