瀏覽代碼

Error handling in GL2D::makeShaderProgram,
Gfx::PlettedBitmap class correction

paracelsus 12 年之前
父節點
當前提交
d96e7cae4a
共有 6 個文件被更改,包括 75 次插入62 次删除
  1. 23 29
      client/Gfx/Images.cpp
  2. 4 6
      client/Gfx/Images.h
  3. 1 1
      client/Gfx/ImgMakers.cpp
  4. 2 2
      client/Gfx/Manager.cpp
  5. 44 23
      client/UIFramework/GL2D.cpp
  6. 1 1
      config/artifacts.json

+ 23 - 29
client/Gfx/Images.cpp

@@ -232,13 +232,14 @@ void CBitmap32::putWithPlrColor(Point p, ColorRGBA c, float scale)
 
 CPalettedBitmap::CPalettedBitmap(ui32 w, ui32 h, CPaletteRGBA& pal, const ui8 pixBuff[]) :
 	CImage(w, h),
-	palette(pal)
+	palette(pal),
+	realWidth((w + 3) & ~3),
+	realHeight(h)
 {
-	const ui32 rowStride = (w + 3) & ~3;
-	const ui32 size = rowStride * h;
+	const ui32 size = realWidth * h;
 	buffer = new ui8[size];
 
-	if (rowStride == w)
+	if (realWidth == w)
 	{
 		memcpy(buffer, pixBuff, size);
 		return;
@@ -246,19 +247,19 @@ CPalettedBitmap::CPalettedBitmap(ui32 w, ui32 h, CPaletteRGBA& pal, const ui8 pi
 
 	for (ui32 y=0; y<h; ++y)
 	{
-		memset(&buffer[rowStride*(y+1)-4], 0, 4);
-		memcpy(&buffer[rowStride*y], &pixBuff[w*y], w);
+		memcpy(&buffer[realWidth*y], &pixBuff[w*y], w);
 	}
-	width = rowStride;
+	realWidth = w;
 }
 
 
 CPalettedBitmap::CPalettedBitmap(ui32 w, ui32 h, CPaletteRGBA& pal, const ui8 pixBuff[], ui32 format) :
 	CImage(w, h),
-	palette(pal)
+	palette(pal),
+	realWidth((w + 3) & ~3),
+	realHeight(h)
 {
-	const ui32 rowStride = (w + 3) & ~3;
-	buffer = new ui8[rowStride * h];
+	buffer = new ui8[realWidth * h];
 
 	switch (format)
 	{
@@ -269,7 +270,7 @@ CPalettedBitmap::CPalettedBitmap(ui32 w, ui32 h, CPaletteRGBA& pal, const ui8 pi
 			for (ui32 y=0; y<h; ++y)
 			{
 				const ui8*	srcRowPtr = pixBuff + SDL_SwapLE32(rowsOffsets[y]);
-				ui8*		dstRowPtr = buffer + (y * rowStride);
+				ui8*		dstRowPtr = buffer + (y * realWidth);
 
 				ui32 rowLength = 0;
 				do {
@@ -290,6 +291,8 @@ CPalettedBitmap::CPalettedBitmap(ui32 w, ui32 h, CPaletteRGBA& pal, const ui8 pi
 				}
 				while (rowLength < w);
 			}
+
+			realWidth = w;
 			return;
 		}
 	default:
@@ -307,7 +310,7 @@ CPalettedBitmap::~CPalettedBitmap()
 
 void CPalettedBitmap::textureTransfer()
 {
-	glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_R8UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, buffer);
+	glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_R8UI, realWidth, realHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, buffer);
 	palette.loadToVideoRAM();
 }
 
@@ -318,7 +321,7 @@ void CPalettedBitmap::putAt(Point p)
 	GL2D::assignTexture(GL_TEXTURE1, GL_TEXTURE_1D, palette.getTexHandle());
 	GL2D::assignTexture(GL_TEXTURE0, GL_TEXTURE_RECTANGLE, texHandle);
 	GL2D::usePaletteBitmapShader(p.x, p.y);
-	glRecti(p.x, p.y, p.x + width, p.y + height);
+	glRecti(p.x, p.y, p.x + realWidth, p.y + realHeight);
 }
 
 
@@ -334,7 +337,7 @@ void CPalettedBitmap::putAt(Point p, TransformFlags flags, float scale)
 	GL2D::assignTexture(GL_TEXTURE1, GL_TEXTURE_1D, palette.getTexHandle());
 	GL2D::assignTexture(GL_TEXTURE0, GL_TEXTURE_RECTANGLE, texHandle);
 	GL2D::usePaletteBitmapShader(p.x, p.y);
-	glRecti(p.x, p.y, p.x + (ui32)(width*scale), p.y + (ui32)(height*scale));
+	glRecti(p.x, p.y, p.x + (ui32)(realWidth*scale), p.y + (ui32)(realHeight*scale));
 }
 
 
@@ -371,26 +374,17 @@ void CPalettedBitmap::putWithPlrColor(Point p, ColorRGBA c, float scale)
 CPalBitmapWithMargin::CPalBitmapWithMargin(ui32 fw, ui32 fh, ui32 lm, ui32 tm, ui32 iw, ui32 ih,
 										   CPaletteRGBA& pal, const ui8 pixBuff[]) :
 	CPalettedBitmap(iw, ih, pal, pixBuff),
-	leftMargin(lm), topMargin(tm),
-	intWidth(iw), intHeight(ih)
+	leftMargin(lm), topMargin(tm)
 {
 	width = fw;
 	height = fh;
 }
 
 
-void CPalBitmapWithMargin::textureTransfer()
-{
-	glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_R8UI, intWidth, intHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, buffer);
-	palette.loadToVideoRAM();
-}
-
-
 CPalBitmapWithMargin::CPalBitmapWithMargin(ui32 fw, ui32 fh, ui32 lm, ui32 tm, ui32 iw, ui32 ih,
 										   CPaletteRGBA& pal, const ui8 pixBuff[], ui32 format) :
 	CPalettedBitmap(iw, ih, pal, pixBuff, format),
-	leftMargin(lm), topMargin(tm),
-	intWidth(iw), intHeight(ih)
+	leftMargin(lm), topMargin(tm)
 {
 	width = fw;
 	height = fh;
@@ -402,8 +396,8 @@ void CPalBitmapWithMargin::putAt(Point p)
 	loadToVideoRAM();
 	GL2D::assignTexture(GL_TEXTURE1, GL_TEXTURE_1D, palette.getTexHandle());
 	GL2D::assignTexture(GL_TEXTURE0, GL_TEXTURE_RECTANGLE, texHandle);
-	GL2D::usePaletteBitmapShader(p.x, p.y);
-	glRecti(p.x, p.y, p.x + intWidth, p.y + intHeight);
+	GL2D::usePaletteBitmapShader(p.x + leftMargin, p.y + topMargin);
+	glRecti(p.x + leftMargin, p.y + topMargin, p.x + realWidth, p.y + realHeight);
 }
 
 
@@ -430,8 +424,8 @@ void CPalBitmapWithMargin::putAt(Point p, TransformFlags flags, const ColorMatri
 	loadToVideoRAM();
 	GL2D::assignTexture(GL_TEXTURE1, GL_TEXTURE_1D, palette.getTexHandle());
 	GL2D::assignTexture(GL_TEXTURE0, GL_TEXTURE_RECTANGLE, texHandle);
-	GL2D::usePaletteBitmapShader(p.x, p.y, cm);
-	glRecti(p.x, p.y, p.x + width, p.y + height);
+	GL2D::usePaletteBitmapShader(p.x + leftMargin, p.y + topMargin);
+	glRecti(p.x + leftMargin, p.y + topMargin, p.x + realWidth, p.y + realHeight);
 }
 
 

+ 4 - 6
client/Gfx/Images.h

@@ -96,8 +96,8 @@ class CBitmap32 : public CImage
 	};
 
 protected:
-	CBitmap32(ui32 w, ui32 h, const ColorRGB pixBuff[], bool bgra = true); // 24bit RGB source
-	CBitmap32(ui32 w, ui32 h, const ColorRGBA pixBuff[], bool bgra = true); // 32bit RGBA source
+	CBitmap32(ui32 w, ui32 h, const ColorRGB pixBuff[], bool bgra); // 24bit RGB source
+	CBitmap32(ui32 w, ui32 h, const ColorRGBA pixBuff[], bool bgra); // 32bit RGBA source
 	virtual void textureTransfer();
 
 public:
@@ -120,6 +120,8 @@ class CPalettedBitmap : public CImage
 protected:
 	CPaletteRGBA& palette;
 	ui8* buffer;
+	ui32 realWidth;
+	ui32 realHeight;
 
 	CPalettedBitmap(ui32 w, ui32 h, CPaletteRGBA& pal, const ui8 pixBuff[]);
 	CPalettedBitmap(ui32 w, ui32 h, CPaletteRGBA& pal, const ui8 pixBuff[], ui32 format);
@@ -143,16 +145,12 @@ class CPalBitmapWithMargin : public CPalettedBitmap
 	friend class CImage;
 	ui32 leftMargin;
 	ui32 topMargin;
-	ui32 intWidth;
-	ui32 intHeight;
 
 protected:
 	CPalBitmapWithMargin(ui32 fw, ui32 fh, ui32 lm, ui32 tm, ui32 iw, ui32 ih,
 						 CPaletteRGBA& pal, const ui8 pixBuff[]);
 	CPalBitmapWithMargin(ui32 fw, ui32 fh, ui32 lm, ui32 tm, ui32 iw, ui32 ih,
 						 CPaletteRGBA& pal, const ui8 pixBuff[], ui32 format);
-	virtual void textureTransfer();
-
 public:
 	virtual void putAt(Point p);
 	virtual void putAt(Point p, TransformFlags flags);

+ 1 - 1
client/Gfx/ImgMakers.cpp

@@ -67,7 +67,7 @@ CImage * CImage::makeFromPCX(const SH3PcxFile& pcx, size_t fileSize)
 	{
 		if (H3PCX_HEADER_SIZE + imgSize > fileSize) return nullptr;
 
-		return new CBitmap32(width, height, (ColorRGB*)pcx.data);
+		return new CBitmap32(width, height, (ColorRGB*)pcx.data, true);
 	}
 
 	return nullptr;

+ 2 - 2
client/Gfx/Manager.cpp

@@ -50,7 +50,7 @@ PImage CManager::getImage(const std::string& fname)
 
 		if (img_tmp == nullptr)
 		{
-			tlog1 << "Image " << fname << " not loaded!\n";
+			tlog1 << "Gfx: Image " << fname << " not loaded!\n";
 			return nullptr;
 		}
 	}
@@ -80,7 +80,7 @@ PAnimation CManager::getAnimation(const std::string& fname)
 	CAnimation* anim_tmp = CAnimation::makeFromDEF(*(SH3DefFile*)data.get(), (size_t)readSize);
 	if (anim_tmp == nullptr)
 	{
-		tlog1 << "Animation " << fname << " not loaded!\n";
+		tlog1 << "Gfx: Animation " << fname << " not loaded!\n";
 		return nullptr;
 	}
 

+ 44 - 23
client/UIFramework/GL2D.cpp

@@ -18,10 +18,13 @@ PFNGLACTIVETEXTUREPROC	glActiveTexture;
 // OpenGL 2.0 functions pointers
 PFNGLCREATEPROGRAMPROC	glCreateProgram;
 PFNGLCREATESHADERPROC	glCreateShader;
+PFNGLDELETESHADERPROC	glDeleteShader;
 PFNGLSHADERSOURCEPROC	glShaderSource;
 PFNGLCOMPILESHADERPROC	glCompileShader;
+PFNGLGETSHADERIVPROC	glGetShaderiv;
 PFNGLATTACHSHADERPROC	glAttachShader;
 PFNGLLINKPROGRAMPROC	glLinkProgram;
+PFNGLGETPROGRAMIVPROC	glGetProgramiv;
 PFNGLUSEPROGRAMPROC 	glUseProgram;
 PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
 PFNGLUNIFORM1IPROC		glUniform1i;
@@ -54,7 +57,7 @@ static GLint coord_uniform = -1;
 
 
 // Print out the information log for a shader object 
-void printInfoLog(PFNGLGETPROGRAMINFOLOGPROC logFunc, GLuint object)
+void printInfoLog(PFNGLGETPROGRAMINFOLOGPROC logFunc, GLuint object, GLint status)
 {
 	if (logFunc != nullptr)
 	{
@@ -62,7 +65,7 @@ void printInfoLog(PFNGLGETPROGRAMINFOLOGPROC logFunc, GLuint object)
 		GLchar infoLog[1024];
 		logFunc(object, sizeof(infoLog)-1, &infoLogLength, infoLog);
 
-		if (infoLogLength > 0) tlog1 << infoLog;
+		if (infoLogLength > 0) (status ? tlog0 : tlog1) << infoLog;
 	}
 }
 
@@ -71,21 +74,31 @@ GLuint makeShaderProgram(const char * frg_src)
 {
 	// Creating a fragment shader object
 	GLuint shader_object = glCreateShader(GL_FRAGMENT_SHADER);
+	if (shader_object == 0) return 0;
+
 	glShaderSource(shader_object, 1, &frg_src, nullptr); // assigning the shader source
-	// Compiling the shader
-	glCompileShader(shader_object);
-	printInfoLog(glGetShaderInfoLog, shader_object);
+	glCompileShader(shader_object); // Compiling the shader
+
+	GLint ret;
+	glGetShaderiv(shader_object, GL_COMPILE_STATUS, &ret);
+	printInfoLog(glGetShaderInfoLog, shader_object, ret);
 
-	// Creating a program object
-	GLuint program_object  = glCreateProgram();
-	// Attaching the shader into program
-	glAttachShader(program_object, shader_object); 
+	if (ret == GL_TRUE)
+	{
+		GLuint program_object  = glCreateProgram(); // Creating a program object
+		glAttachShader(program_object, shader_object); // Attaching the shader into program
 
-	// Link the shaders into a complete GLSL program.
-	glLinkProgram(program_object);
-	printInfoLog(glGetProgramInfoLog, program_object);
+		// Link the shaders into a complete GLSL program.
+		glLinkProgram(program_object);
 
-	return program_object;
+		glGetProgramiv(shader_object, GL_LINK_STATUS, &ret);
+		printInfoLog(glGetProgramInfoLog, program_object, ret);
+
+		if (ret == GL_TRUE) return program_object;
+	}
+
+	glDeleteShader(shader_object);
+	return 0;
 }
 
 
@@ -104,17 +117,20 @@ void initVideo(ui32 w, ui32 h, bool fullscreen)
 	SDL_GL_SwapBuffers();
 
 	// Dynamic-linked OpenGL 1.3 and 2.0 functions - required to 2D rendeing
-	if (	(glActiveTexture = (PFNGLACTIVETEXTUREPROC) SDL_GL_GetProcAddress("glActiveTexture")) == nullptr
-		||	(glCreateProgram = (PFNGLCREATEPROGRAMPROC) SDL_GL_GetProcAddress("glCreateProgram")) == nullptr
-		||	(glCreateShader = (PFNGLCREATESHADERPROC) SDL_GL_GetProcAddress("glCreateShader")) == nullptr
-		||	(glShaderSource = (PFNGLSHADERSOURCEPROC) SDL_GL_GetProcAddress("glShaderSource")) == nullptr
-		||	(glCompileShader = (PFNGLCOMPILESHADERPROC) SDL_GL_GetProcAddress("glCompileShader")) == nullptr
-		||	(glAttachShader = (PFNGLATTACHSHADERPROC) SDL_GL_GetProcAddress("glAttachShader")) == nullptr
-		||	(glLinkProgram = (PFNGLLINKPROGRAMPROC) SDL_GL_GetProcAddress("glLinkProgram")) == nullptr
-		||	(glUseProgram = (PFNGLUSEPROGRAMPROC) SDL_GL_GetProcAddress("glUseProgram")) == nullptr
+	if (	(glActiveTexture	= (PFNGLACTIVETEXTUREPROC)	SDL_GL_GetProcAddress("glActiveTexture")) == nullptr
+		||	(glCreateProgram	= (PFNGLCREATEPROGRAMPROC)	SDL_GL_GetProcAddress("glCreateProgram")) == nullptr
+		||	(glCreateShader 	= (PFNGLCREATESHADERPROC)	SDL_GL_GetProcAddress("glCreateShader")) == nullptr
+		||	(glDeleteShader		= (PFNGLDELETESHADERPROC)	SDL_GL_GetProcAddress("glDeleteShader")) == nullptr
+		||	(glShaderSource 	= (PFNGLSHADERSOURCEPROC)	SDL_GL_GetProcAddress("glShaderSource")) == nullptr
+		||	(glCompileShader	= (PFNGLCOMPILESHADERPROC)	SDL_GL_GetProcAddress("glCompileShader")) == nullptr
+		||	(glGetShaderiv		= (PFNGLGETSHADERIVPROC)	SDL_GL_GetProcAddress("glGetShaderiv")) == nullptr
+		||	(glAttachShader 	= (PFNGLATTACHSHADERPROC)	SDL_GL_GetProcAddress("glAttachShader")) == nullptr
+		||	(glLinkProgram		= (PFNGLLINKPROGRAMPROC)	SDL_GL_GetProcAddress("glLinkProgram")) == nullptr
+		||	(glGetProgramiv 	= (PFNGLGETPROGRAMIVPROC)	SDL_GL_GetProcAddress("glGetProgramiv")) == nullptr
+		||	(glUseProgram		= (PFNGLUSEPROGRAMPROC) 	SDL_GL_GetProcAddress("glUseProgram")) == nullptr
 		||	(glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) SDL_GL_GetProcAddress("glGetUniformLocation")) == nullptr
-		||	(glUniform1i = (PFNGLUNIFORM1IPROC) SDL_GL_GetProcAddress("glUniform1i")) == nullptr
-		||	(glUniform2i = (PFNGLUNIFORM2IPROC) SDL_GL_GetProcAddress("glUniform2i")) == nullptr
+		||	(glUniform1i		= (PFNGLUNIFORM1IPROC)		SDL_GL_GetProcAddress("glUniform1i")) == nullptr
+		||	(glUniform2i		= (PFNGLUNIFORM2IPROC)		SDL_GL_GetProcAddress("glUniform2i")) == nullptr
 		)
 	{
 		tlog1 << "Error: OpenGL2 Extenstions are not available\n";
@@ -133,6 +149,11 @@ void initVideo(ui32 w, ui32 h, bool fullscreen)
 	glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 
 	paletteBitmapProgram = makeShaderProgram(frag_palette_bitmap);
+	if (paletteBitmapProgram == 0)
+	{
+		throw std::runtime_error("OpenGL shader for palleted bitmaps is not compiled\n");
+	}
+
 	GLint bitmap_uniform = glGetUniformLocation(paletteBitmapProgram, "bitmap");
 	GLint palette_uniform = glGetUniformLocation(paletteBitmapProgram, "palette");
 	coord_uniform = glGetUniformLocation(paletteBitmapProgram, "coordOffs");

+ 1 - 1
config/artifacts.json

@@ -2159,7 +2159,7 @@
 				"everflowingCrystalCloak",
 				"ringOfInfiniteGems",
 				"everpouringVialOfMercury",
-				"inexhaustibleCartOfOre"
+				"eversmokingRingOfSulfur"
 			]
 		},
 		"magicWand":