我对 OpenGL 完全陌生,无法弄清楚将纹理和着色器绑定到 VBO 的工作原理。
我正在使用 Cinder 的纹理和着色器类。这是我的绘制方法的一部分:
mShader.bind();
myImage.bind();
glPushMatrix();
glTranslated( scaledX, scaledY, scaledZ);
gl::draw(sphere.getVBO());
glPopMatrix();
glPushMatrix();
glTranslated( 0, 0, zshift - 200);
mDisc.draw();
glPopMatrix();
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,如果我注释掉对 mShader.bind() 的调用,我的球体 VBO 将显示纹理 (myImage)。我的着色器对于普通(无纹理)形状效果很好,但是当我在绘制任何带有包裹纹理的形状之前绑定着色器时,它会阻止纹理的显示。
这是我使用的着色器的问题,还是我不理解的其他问题?(……还有很多不明白的地方)
谢谢
编辑:
这是我正在使用的着色器:
(片段):
uniform sampler2DShadow depthTexture;
varying vec3 N, V, L;
varying vec4 q;
void main(void)
{
vec3 normal = normalize( N );
vec3 R = -normalize( reflect( L, normal ) );
vec4 ambient = gl_FrontLightProduct[0].ambient;
vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(dot( normal, L), 0.0);
vec4 …
Run Code Online (Sandbox Code Playgroud) 我目前正在尝试使用 JOGL 生成带纹理的多边形表面,但收到一条我不明白的错误消息。Eclipse 告诉我“java.lang.IndexOutOfBoundsException:缓冲区中需要 430233 个剩余字节,只有 428349”。据我所知,由 readTexture 方法生成的缓冲图像的大小不足以与 glTex2D() 方法一起使用。但是,我不确定如何解决该问题。代码的相关部分如下,任何帮助将不胜感激。
public void init(GLAutoDrawable drawable)
{
final GL2 gl = drawable.getGL().getGL2();
GLU glu = GLU.createGLU();
//Create the glu object which allows access to the GLU library\
gl.glShadeModel(GL2.GL_SMOOTH); // Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
gl.glClearDepth(1.0f); // Depth Buffer Setup
gl.glEnable(GL.GL_DEPTH_TEST); // Enables Depth Testing
gl.glDepthFunc(GL.GL_LEQUAL); // The Type Of Depth Testing To Do
gl.glEnable(GL.GL_TEXTURE_2D);
texture = genTexture(gl);
gl.glBindTexture(GL.GL_TEXTURE_2D, texture);
TextureReader.Texture texture = null;
try {
texture …
Run Code Online (Sandbox Code Playgroud) 因此,在 WebGL 中,我可以存储最多 2 维的纹理 - 并使用 texture2D(无论如何)在着色器中读取它;
如果我想存储一个 3 维纹理,以便我可以在着色器上读取 3 维数据,我该怎么做?
这是我的想法 - 我想知道我是否正确地接近它:
在 JavaScript 中:
var info = [];
for (var x = 0; x < 1; x+=.1) {
for (var y = 0; y < 1; y+=.1) {
for (var z = 0; z < 1; z+=.1) {
info.push (x*y*z);
info.push(0);
info.push(0);
info.push(0);
}
}
}
//bind texture here- whatever
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 10, 100, 0,
gl.RGBA, gl.FLOAT, data_on_shader);
//other texture stuff
Run Code Online (Sandbox Code Playgroud)
在着色器上:
uniform sampler …
Run Code Online (Sandbox Code Playgroud) 我正在 WPF 中编写一个程序。我正在使用 HelixToolkit 从文件加载模型(我需要从文件加载多个模型),如下所示:
var importer = new HelixToolkit.Wpf.ModelImporter();
Model3D triangle = importer.Load("hand.obj");
ModelVisual3D Model = new ModelVisual3D();
Model.Content = triangle;
MainViewPort.Children.Add(Model);
Run Code Online (Sandbox Code Playgroud)
我需要从 HelixToolkit 获取的整个 Model3D 来更改颜色(例如,它应该是红色或黑色)。我还需要实时进行。
我发现了这个:http://csharphelper.com/blog/2014/10/apply-textures-to-triangles-using-wpf-and-c/,但在这种情况下模型是在程序内部生成的,而我需要什么要做的就是对外部文件的模型执行相同的操作。
我怎样才能做到这一点?
如何使用 OES_texture_float 扩展?我不明白有必要指定函数 texImage2D 的参数。
var fb=gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
var rb=gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16,size[0],size[1]);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,gl.RENDERBUFFER, rb);
var texture=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1],0, gl.RGBA, ???, ???);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D, texture, 0);
Run Code Online (Sandbox Code Playgroud)
你需要写什么而不是“???”
我正在使用 2D 纹理数组来存储一些数据。由于我经常想要绑定这个 2D 纹理数组的单层,因此我为每个层创建单独的GL_TEXTURE_2D纹理视图:
for(int l(0); l < m_layers; l++)
{
QOpenGLTexture * view_texture = m_texture.createTextureView(QOpenGLTexture::Target::Target2D,
m_texture_format,
0,0,
l,l);
view_texture->setMinMagFilters(QOpenGLTexture::Filter::Linear, QOpenGLTexture::Filter::Linear);
view_texture->setWrapMode(QOpenGLTexture::WrapMode::MirroredRepeat);
assert(view_texture != 0);
m_texture_views.push_back(view_texture);
}
Run Code Online (Sandbox Code Playgroud)
这些 2D 纹理视图工作得很好。但是,如果我想使用该纹理视图从 GPU 端检索 2D 纹理数据,则它不起作用。
换句话说,以下代码不复制任何数据(但不会引发 GL 错误):
glGetTexImage(GL_TEXTURE_2D, 0, m_pixel_format, m_pixel_type, (GLvoid*) m_raw_data[layer] )
Run Code Online (Sandbox Code Playgroud)
但是,检索整个GL_TEXTURE_2D_ARRAY确实有效:
glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, m_pixel_format, m_pixel_type, (GLvoid*) data );
Run Code Online (Sandbox Code Playgroud)
当仅修改单个层的数据时,如果我需要在 2D 纹理数组的所有层之间进行复制,显然会造成性能损失。
有没有办法将 GPU->CPU 仅复制GL_TEXTURE_2D_ARRAY的单层?我知道有相反的情况(即CPU->GPU),所以如果没有的话我会感到惊讶。
是否有任何库能够按需将图像数据编码为 ASTC 纹理?我知道它是 CPU 密集型的,但无论如何都很感兴趣。
我已经使用自己的迷你管道(使用 mipmap)成功地在几何体上显示纹理,但我决定不使用 mip-map,因为我的软件实际上不需要对细节级别进行任何更改。它是 2d 的并且使用像素艺术。细节不应该改变。我要补充一点,我正在尝试在纹理图集中循环纹理,并且禁用 mip 映射可能会有助于避免问题。
但是,不调用glGenerateMipmap
会产生空白屏幕。调用它会产生正确的纹理。
是否还有另一个我必须调用的函数?
以下是我的纹理生成函数(我传递一个指向已创建的纹理 id 的指针。)
GLboolean GL_texture_load(Texture* texture_id, const char* const path, const GLboolean alpha, const GLint param_edge)
{
// load image
SDL_Surface* img = nullptr;
if (!(img = IMG_Load(path))) {
fprintf(stderr, "SDL_image could not be loaded %s, SDL_image Error: %s\n",
path, IMG_GetError());
return GL_FALSE;
}
glBindTexture(GL_TEXTURE_2D, *texture_id);
// image assignment
GLuint format = (alpha) ? GL_RGBA : GL_RGB;
glTexImage2D(GL_TEXTURE_2D, 0, format, img->w, img->h, 0, format, GL_UNSIGNED_BYTE, img->pixels);
glGenerateMipmap(GL_TEXTURE_2D); …
Run Code Online (Sandbox Code Playgroud) 我有几个 32 位(带 alpha 通道)位图图像,我将它们用作游戏中的基本信息。RGBA 值的微小变化会破坏一切,所以我不能使用像 S3TC 这样的有损压缩方法。
是否有任何可行的无损压缩算法可以与 OpenGL 一起使用?我正在使用片段着色器,我想使用glCompressedTexImage2D()方法来定义纹理。我还没有尝试过使用GL_COMPRESSED_RGBA参数用 OpenGL 压缩纹理,我有没有机会通过这种方式获得无损压缩?
compression opengl textures lossless-compression image-compression
我用 ThreeJS 创建了一个简单的模型查看器。我从 .mtl 和 .obj(带纹理)文件加载。除了纹理之外,一切都工作正常。如果我使用环境光,纹理就会显得褪色。如果我禁用环境光,则根本不会显示纹理。我在带有 WebView 的 Android 应用程序中运行它。
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 3;
scene = new THREE.Scene();
ambient = new THREE.AmbientLight(0x404040);
scene.add(ambient);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
window.addEventListener('resize', onWindowResize, false);
var mtlLoader = new THREE.MTLLoader();
mtlLoader.load('../foods_models/7/mtl.mtl', function (materials) {
materials.preload();
if (materials.materials.default != undefined) {
materials.materials.default.map.magFilter = THREE.NearestFilter;
materials.materials.default.map.minFilter = THREE.LinearFilter;
}
var objLoader …
Run Code Online (Sandbox Code Playgroud)