我想尝试用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_Surface
将loadImage
&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。
答案 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);