OpenGL与从SDL_Surface转换的纹理混合

时间:2018-03-09 23:28:56

标签: c++ opengl sdl

我想尝试用OpenGL和GLUT制作游戏,但事实证明,GLUT并不适合制作游戏。所以我转而使用SDL 1.2(这是为了某种竞争,所以我不能使用SDL 2)。当我看到我可以在SDL中使用OpenGL时,我决定这样做,因为我已经用OpenGL编写了大部分代码。现在,我在尝试将图像加载到import numpy as np import matplotlib.pyplot as plt from matplotlib import patches import pandas as pd def _plot_ellipse(grp, n_std, ax = None, return_ax = False, **kwargs): xdata = grp.x ydata = grp.y label = grp.name def _eigsorted(cov): vals, vecs = np.linalg.eigh(cov) order = vals.argsort()[::-1] return vals[order], vecs[:, order] points = np.stack([xdata, ydata], axis = 1) # Combine points to 2-column matrix center = points.mean(axis = 0) # Calculate mean for every column (x,y) # Calculate covariance matrix for coordinates (how correlated they are) cov = np.cov(points, rowvar = False) # rowvar = False because there are 2 variables, not nrows variables vals, vecs = _eigsorted(cov) angle = np.degrees(np.arctan2(*vecs[:,0][::-1])) width, height = 2 * n_std * np.sqrt(vals) in_out = _is_in_ellipse(label = label, xdata = xdata, ydata = ydata, center = center, width = width, height = height, angle = angle) # if return_ax: # ellip = patches.Ellipse(xy = center, width = width, height = height, angle = angle, **kwargs) # if ax is None: # ax = plt.gca() # ax.add_artist(ellip) # return ax, in_out # else: # return in_out grp.label = in_out return grp def _is_in_ellipse(label, xdata, ydata, center, width, height, angle): cos_angle = np.cos(np.radians(180-angle)) sin_angle = np.sin(np.radians(180-angle)) xc = xdata - center[0] yc = ydata - center[1] xct = xc * cos_angle - yc * sin_angle yct = xc * sin_angle + yc * cos_angle rad_cc = (xct**2/(width/2)**2) + (yct**2/(height/2)**2) # in_ellipse = [] # for r in rad_cc: # in_ellipse.append(True) if r <= 1. else in_ellipse.append(False) return pd.Series(rad_cc).apply(lambda r: label if r <= 1. else -1) # For a single label # x = np.random.normal(0, 1, 100) # y = np.random.normal(0, 1, 100) # labels = [1] * len(x) # # df = pd.DataFrame({"x" : x, "y" : y, "label" : labels}) # # ax, in_out = _plot_ellipse(df.x, df.y, 2, return_ax = True, alpha = 0.5) # ax.scatter(df.x, df.y, c = in_out) # plt.show() # For multiple labels x = np.random.normal(0, 1, 100) y = np.random.normal(0, 1, 100) labels1 = [1] * 50 labels2 = [2] * 50 labels = labels1 + labels2 df = pd.DataFrame({"x" : x, "y" : y, "label" : labels}) df = df.groupby("label").apply(_plot_ellipse, n_std = 1, return_ax = False) 然后将其转换为OpenGL纹理时遇到问题,并启用了OpenGL混合。以下是我使用的代码(SDL_SurfaceloadImage&amp; SDL_Surface加载到OpenGL纹理中):

loadTexture

我一直在网上搜索这个问题的解决方案,而且我找不到任何解决方案。这个代码实际上可以在我不SDL_Surface * Graphics::loadImage(const char * filename) { SDL_Surface *loaded = nullptr; SDL_Surface *optimized = nullptr; loaded = IMG_Load(filename); if (loaded) { optimized = SDL_DisplayFormat(loaded); SDL_FreeSurface(loaded); } return optimized; } GLuint Graphics::loadTexture(const char * filename, GLuint oldTexId) { //return SOIL_load_OGL_texture(filename, SOIL_LOAD_AUTO, oldTexId, SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA); GLuint texId = 0; SDL_Surface *s = loadImage(filename); if (!s) return 0; if (oldTexId) glDeleteTextures(1, &oldTexId); glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_2D, texId); int format; if (s->format->BytesPerPixel == 4) { if (s->format->Rmask == 0x000000ff) format = GL_RGBA; else format = GL_BGRA; } else if (s->format->BytesPerPixel == 3) { if (s->format->Rmask == 0x000000ff) format = GL_RGB; else format = GL_BGR; } glTexImage2D(GL_TEXTURE_2D, 0, s->format->BytesPerPixel, s->w, s->h, 0, format, GL_UNSIGNED_BYTE, s->pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); SDL_FreeSurface(s); return texId; } 时使用,但是当我启用它时,它不会再在屏幕上显示任何内容。我是OpenGL的新手,我不确定我是否正确使用glEnable(GL_BLEND)

我在转换为SDL之前加载图像的方式是使用SOIL库,当我用注释掉的第一行替换glTexImage2D函数体时,它实际上工作正常,但我和#39; d而是拥有更少的外部库,并使用SDL&amp; amp;的OpenGL。

1 个答案:

答案 0 :(得分:0)

glTexImage2D的第三个参数是错误的:

glTexImage2D(GL_TEXTURE_2D, 0, s->format->BytesPerPixel, s->w, s->h, 0, format, GL_UNSIGNED_BYTE, s->pixels);

第三个参数是internalFormat,必须是基本内部格式之一:

GL_DEPTH_COMPONENT
GL_DEPTH_STENCIL
GL_RED
GL_RG
GL_RGB
GL_RGBA

或其中一种大小的内部格式,指定每个通道的位数。

换句话说,你的第三个论点应该是:

GL_RGB 
GL_RGB8 
GL_RGBA 
GL_RGBA8 

如果你使用每通道8位纹理。

而第7个参数format可以是RGB或BGR(包括alpha版本),第三个参数,internalFormat只能是RGB而不是相反。

因此,在检查红色掩码并更改格式仍然适用于第7个参数的情况下,第三个参数(internalFormat)应该是GL_RGB或GL_RGBA。或者可选择尺寸版本GL_RGB8或GL_RGBA8。

glTexImage2D(GL_TEXTURE_2D, 0, /*GL_RGB or GL_RGBA*/, s->w, s->h, 0, format, GL_UNSIGNED_BYTE, s->pixels);

Docs