adding texture loading.
This commit is contained in:
parent
7eac02328d
commit
dfda49c027
7 changed files with 252 additions and 5 deletions
|
@ -6,10 +6,10 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
|||
function(setup_target NAME)
|
||||
set_property(TARGET ${NAME} PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET ${NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
#target_compile_options(${NAME} PRIVATE -Wall -Wextra)
|
||||
#target_compile_options(${NAME} PRIVATE -fdiagnostics-color=always)
|
||||
#target_compile_options(${NAME} PRIVATE $<$<CONFIG:DEBUG>:-ggdb -O2>)
|
||||
#target_compile_options(${NAME} PRIVATE $<$<CONFIG:RELEASE>:-O3 -NDEBUG>)
|
||||
target_compile_options(${NAME} PRIVATE -Wall -Wextra)
|
||||
target_compile_options(${NAME} PRIVATE -fdiagnostics-color=always)
|
||||
target_compile_options(${NAME} PRIVATE $<$<CONFIG:DEBUG>:-ggdb -O2>)
|
||||
target_compile_options(${NAME} PRIVATE $<$<CONFIG:RELEASE>:-O3 -NDEBUG>)
|
||||
endfunction(setup_target)
|
||||
|
||||
add_subdirectory(game)
|
||||
|
|
|
@ -4,6 +4,7 @@ find_package(OpenGL REQUIRED)
|
|||
find_package(epoxy REQUIRED)
|
||||
find_package(X11 REQUIRED)
|
||||
find_package(assimp REQUIRED)
|
||||
find_package(PNG REQUIRED)
|
||||
|
||||
set(GAME_SRC
|
||||
main.cpp
|
||||
|
@ -11,10 +12,14 @@ set(GAME_SRC
|
|||
glclasses.cpp
|
||||
game_window.cpp
|
||||
renderer.cpp
|
||||
|
||||
renderer_polygon_2d/renderer_polygon_2d.cpp
|
||||
|
||||
renderer_polygon_3d/renderer_polygon_3d.cpp
|
||||
renderer_polygon_3d/polygon_model.cpp
|
||||
renderer_polygon_3d/particle_batch.cpp
|
||||
renderer_polygon_3d/image_texture.cpp
|
||||
|
||||
renderer_ray_tracer/renderer_ray_tracer.cpp
|
||||
|
||||
network/session.cpp
|
||||
|
@ -45,6 +50,7 @@ set(GAME_SRC ${GAME_SRC} sound/dummy_sound.cpp)
|
|||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
include_directories(${PNG_INCLUDE_DIR})
|
||||
include_directories(${CMAKE_SOURCE_DIR}/libs/glm/)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/libs/asio/asio/include/)
|
||||
include_directories(${assimp_INCLUDE_DIRS})
|
||||
|
@ -52,4 +58,5 @@ include_directories(${assimp_INCLUDE_DIRS})
|
|||
add_executable(game ${GAME_SRC})
|
||||
setup_target(game)
|
||||
|
||||
target_link_libraries(game X11 epoxy pthread ${assimp_LIBRARIES} assimp ${SOUND_LIBRARIES})
|
||||
target_link_libraries(game X11 epoxy pthread ${assimp_LIBRARIES} assimp
|
||||
${SOUND_LIBRARIES} ${PNG_LIBRARIES})
|
||||
|
|
161
game/renderer_polygon_3d/image_texture.cpp
Normal file
161
game/renderer_polygon_3d/image_texture.cpp
Normal file
|
@ -0,0 +1,161 @@
|
|||
#include "image_texture.hpp"
|
||||
|
||||
#include <png.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace endofthejedi {
|
||||
|
||||
bool ImageTexture::loadPng()
|
||||
{
|
||||
m_valid = false;
|
||||
|
||||
//header for testing if it is a png
|
||||
png_byte header[8];
|
||||
|
||||
//open file as binary
|
||||
FILE *fp = fopen(m_path.c_str(), "rb");
|
||||
if (!fp) {
|
||||
printf("[image_texture] warning: could not open png file to load: %s\n", m_path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
//read the header
|
||||
fread(header, 1, 8, fp);
|
||||
|
||||
//test if png
|
||||
int is_png = !png_sig_cmp(header, 0, 8);
|
||||
if (!is_png) {
|
||||
puts("warning: image loader: file is not PNG!");
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
//create png struct
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr) {
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
//create png info struct
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
//create png info struct
|
||||
png_infop end_info = png_create_info_struct(png_ptr);
|
||||
if (!end_info) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
//png error stuff, not sure libpng man suggests this.
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
//init png reading
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
//let libpng know you already read the first 8 bytes
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
|
||||
// read all the info up to the image data
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
//variables to pass to get info
|
||||
int bit_depth, color_type;
|
||||
png_uint_32 twidth, theight;
|
||||
|
||||
// get info about png
|
||||
png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
//update width and height based on png info
|
||||
m_width = twidth;
|
||||
m_height = theight;
|
||||
|
||||
int pot_width = (int) pow(2, ceilf(log2f(m_width)));
|
||||
int pot_height = (int) pow(2, ceilf(log2f(m_height)));
|
||||
|
||||
m_uv_scale_x = m_width / (float) pot_width;
|
||||
m_uv_scale_y = m_height / (float) pot_height;
|
||||
|
||||
/*puts("#########################################");*/
|
||||
/*printf("# PNG: width=%d, height=%d\n", width, height);*/
|
||||
/*printf("# powers of two: w=%d, h=%d\n", pot_width, pot_height);*/
|
||||
/*puts("#########################################");*/
|
||||
|
||||
// Update the png info struct.
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
// Row size in bytes.
|
||||
int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
|
||||
int pot_rowbytes = 4 * (int) pow(2, ceilf(log2f(rowbytes/4)));
|
||||
/*printf("rowbytes: %d, pot_rowbytes=%d\n", rowbytes, pot_rowbytes);*/
|
||||
|
||||
// Allocate the image_data as a big block, to be given to opengl
|
||||
png_byte *image_data = (png_byte *) calloc(pot_rowbytes * pot_height, sizeof(png_byte));
|
||||
if (!image_data) {
|
||||
//clean up memory and close stuff
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
//row_pointers is for pointing to image_data for reading the png with libpng
|
||||
png_bytep *row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * m_height);
|
||||
if (!row_pointers) {
|
||||
//clean up memory and close stuff
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
free(image_data);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
// set the individual row_pointers to point at the correct offsets of image_data
|
||||
for (int i = 0; i < m_height; ++i) {
|
||||
row_pointers[m_height - 1 - i] = image_data + i * pot_rowbytes;
|
||||
}
|
||||
|
||||
//read the png into image_data through row_pointers
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
//Now generate the OpenGL texture object
|
||||
glGenTextures(1, &m_texture_id);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture_id);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA,
|
||||
pot_width,
|
||||
pot_height,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
(GLvoid*) image_data);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
// TODO: make selectable via switch!
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
|
||||
//clean up memory and close stuff
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
free(image_data);
|
||||
free(row_pointers);
|
||||
fclose(fp);
|
||||
|
||||
m_valid = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
65
game/renderer_polygon_3d/image_texture.hpp
Normal file
65
game/renderer_polygon_3d/image_texture.hpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
#pragma once
|
||||
|
||||
#include "glclasses.hpp"
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
// based on sources of knoc/chaqu
|
||||
|
||||
namespace endofthejedi {
|
||||
|
||||
/**
|
||||
* @brief This sprite struct stores all information needed to render an
|
||||
* arbitrary PNG texture to a quad.
|
||||
*
|
||||
* If the loaded texture dimensions have no powers of a bit more space is
|
||||
* allocated and extra padding is added.
|
||||
*/
|
||||
class ImageTexture {
|
||||
public:
|
||||
ImageTexture(const std::string &filename) : m_path(filename), m_valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
~ImageTexture()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to load a PNG image from file into an opengl texture.
|
||||
*
|
||||
* @param path Path of PNG file
|
||||
* @param texture The used texture id will be saved there.
|
||||
* @param width Width of the loaded texture in pixels.
|
||||
* @param height Height of the loaded texture in pixels.
|
||||
* @param uv_scale_x Horizontal portion of the screen which is padded to get
|
||||
* power-of-two texture.
|
||||
* @param uv_scale_y Vertical portion of the screen which is padded to get
|
||||
* power-of-two texture.
|
||||
*
|
||||
* Note: The current active texture unit should be bound (GL_TEXTURE0 etc...)
|
||||
* before calling this
|
||||
*
|
||||
* @return true if loading suceeded, false on errors.
|
||||
*/
|
||||
bool loadPng();
|
||||
|
||||
bool valid() const { return m_valid; }
|
||||
|
||||
glm::vec2 size() const { return glm::vec2(m_width, m_height); }
|
||||
glm::vec2 uvScale() const { return glm::vec2(m_uv_scale_x, m_uv_scale_y); }
|
||||
|
||||
GLuint textureId() const { return m_texture_id; }
|
||||
|
||||
public:
|
||||
std::string m_path; // path for the loaded texture is saved here
|
||||
int m_width; // used width of the pixels of the texture
|
||||
int m_height; // used height of the pixels of the texture
|
||||
float m_uv_scale_x; // factor to scale uv-coordinates to get rid of non-power-of-two padding
|
||||
float m_uv_scale_y; // factor to scale uv-coordinates to get rid of non-power-of-two padding
|
||||
|
||||
bool m_valid;
|
||||
|
||||
GLuint m_texture_id; // texture binding id
|
||||
};
|
||||
}
|
|
@ -33,6 +33,16 @@ namespace endofthejedi {
|
|||
addModel("../data/mesh/rocket.stl", &m_missileModel);
|
||||
addModel("../data/mesh/planet_128.stl", &m_planetModel);
|
||||
addModel("../data/mesh/ship_ufo.stl", &m_shipModel);
|
||||
|
||||
m_texture = new ImageTexture("../data/image/planet_mars.png");
|
||||
std::cout<<"texture loading: " << m_texture->valid() << std::endl;
|
||||
if (!m_texture->valid()) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
glm::vec2 s = m_texture->size();
|
||||
std::cout<<"texture size is " << s.x << " X " << s.y << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void RendererPolygon3d::render(const game::State *state)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "particle_batch.hpp"
|
||||
#include "polygon_model.hpp"
|
||||
#include "image_texture.hpp"
|
||||
|
||||
namespace endofthejedi {
|
||||
|
||||
|
@ -87,5 +88,7 @@ namespace endofthejedi {
|
|||
// TODO: put representation specialized for rendering in here
|
||||
std::list<const game::Missile*> m_missiles;
|
||||
std::list<const game::Ship*> m_ships;
|
||||
|
||||
ImageTexture *m_texture;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -121,6 +121,7 @@ namespace sound {
|
|||
|
||||
int numActiveSounds(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void deleteSound(SoundHandle *handle)
|
||||
|
|
Loading…
Reference in a new issue