- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对此感到非常困惑。我正在尝试渲染到屏幕外纹理,以便我可以执行一些后期处理,但甚至无法让该纹理未经修改地绘制到屏幕上。我目前在 iPhone 模拟器上以 OpenGL ES 2.0 为目标。
我已经将问题缩小到 GLSL 的 texture2D() 函数返回 vec4(0, 0, 0, 1) 因为,如果我用任何常量颜色替换该调用,屏幕将填充指定的颜色。纹理被创建,绑定(bind)到纹理单元 0,它的存储被分配,它的 min 和 mag 过滤器设置为 NEAREST,sampler2D uniform 设置为 0。
我已经尝试删除所有渲染到纹理代码并显式初始化其数据,我得到了相同的结果,如果直接将屏幕帧缓冲区作为目标,我会得到我期望的图像,所以我相当有信心纹理的数据都是在我尝试从中采样时定义的。
我已经尝试确保我的纹理在渲染时没有绑定(bind)到任何纹理单元,但这并没有什么不同。
我也试过 glEnable(GL_TEXTURE_2D) 但我的印象是它对 ES 2.0 不再重要了。无论如何它都没有帮助。
我实际上是在 OpenGL ES 2.0 周围使用我自己的精简 C++ 包装器库,但如果您非常了解 OpenGL ES 2.0,无论如何都应该清楚这段代码中发生的事情。对于代码不是普通的 OpenGL,我深表歉意;我的下一个调试步骤是在没有包装器库的情况下重写代码。我只是想知道我是否犯了任何无论如何都会跳出来的愚蠢错误。
但是,我在最后一个 drawArrays 调用我设置的所有状态变量之前添加了纯 OpenGL glGet*() 查询,并且一切都按预期设置。
代码中唯一不太明显的部分是 Smart<> 对象。它们只是包装 GL 对象引用和引用数组,并在它们的析构函数中调用它们关联的 glDelete*()。
#include <tsvl/vec.hpp>
using namespace tsvl;
#include <tsgl2/Context.hpp>
#include <tsgl2/Smart.hpp>
using namespace tsgl2;
#include <array>
#include <exception>
#include <string>
using namespace std;
#define SHADER_SOURCE(text) "#version 100\n" #text
namespace {
const AttributeLocation vertexPositionAttributeLocation(0);
const string vec2PassthroughVertexShaderSource = SHADER_SOURCE(
attribute vec2 vertexPosition;
void main() {
gl_Position = vec4(vertexPosition, 0, 1);
}
);
const string greenFragmentShaderSource = SHADER_SOURCE(
void main() {
gl_FragColor = vec4(0, 1, 0, 1);
}
);
const string combineTexturesFragmentShaderSource = SHADER_SOURCE(
precision highp float;
uniform vec2 screenSize;
uniform sampler2D samplers[1];
void main() {
vec2 texCoord = gl_FragCoord.xy / screenSize;
gl_FragColor = texture2D(samplers[0], texCoord);
}
);
const vec2 vertices[] = {
vec2(-0.9f, -0.9f),
vec2( 0.9f, -0.9f),
vec2( 0.0f, 0.9f),
};
const int vertexCount = sizeof(vertices) / sizeof(vertices[0]);
const vec2 screenCorners[] = {
vec2(-1.0f, -1.0f),
vec2( 1.0f, -1.0f),
vec2( 1.0f, 1.0f),
vec2(-1.0f, 1.0f),
};
const int screenCornerCount = sizeof(screenCorners) / sizeof(screenCorners[0]);
} // unnamed namespace
void drawDemoScene(int screenWidth, int screenHeight) {
FramebufferRef screenFramebuffer = Framebuffer::currentBinding();
//
Smart<array<TextureRef, 8>> renderTextures(Context::genTextures<8>());
Smart<array<FramebufferRef, 8>> renderFramebuffers(Context::genFramebuffers<8>());
Context::setActiveTextureUnit(TextureUnit(0)); // My wrapper translates this to GL_TEXTURE0
Texture2D::bind(renderTextures.get()[0]);
Texture2D::setStorage(TextureFormat::RGBA8, IntRect::Size(screenWidth, screenHeight));
Texture2D::setMinificationFilter(TextureMinificationFilter::NEAREST);
Texture2D::setMagnificationFilter(TextureMagnificationFilter::NEAREST);
Framebuffer::bind(renderFramebuffers.get()[0]);
Framebuffer::ColorAttachment::set(renderTextures.get()[0], FramebufferTextureTarget::TEXTURE_2D);
if (Framebuffer::status() != FramebufferStatus::COMPLETE)
throw exception();
//
vertexPositionAttributeLocation.enableAttributeArray();
Smart<ShaderRef> vec2PassthroughVertexShader(Context::createShader(ShaderType::VERTEX));
vec2PassthroughVertexShader->setSource(vec2PassthroughVertexShaderSource);
vec2PassthroughVertexShader->compile();
if (!vec2PassthroughVertexShader->compileWasSuccessful())
throw exception();
Smart<ShaderRef> greenFragmentShader(Context::createShader(ShaderType::FRAGMENT));
greenFragmentShader->setSource(greenFragmentShaderSource);
greenFragmentShader->compile();
if (!greenFragmentShader->compileWasSuccessful())
throw exception();
Smart<ShaderRef> combineTexturesFragmentShader(Context::createShader(ShaderType::FRAGMENT));
combineTexturesFragmentShader->setSource(combineTexturesFragmentShaderSource);
combineTexturesFragmentShader->compile();
if (!combineTexturesFragmentShader->compileWasSuccessful())
throw exception();
Smart<ProgramRef> vec2PassthroughGreenProgram(Context::createProgram());
vec2PassthroughGreenProgram->attach(*vec2PassthroughVertexShader);
vec2PassthroughGreenProgram->attach(*greenFragmentShader);
vec2PassthroughGreenProgram->bindAttributeToLocation(
"vertexPosition", vertexPositionAttributeLocation);
vec2PassthroughGreenProgram->link();
vec2PassthroughGreenProgram->validate();
if (!vec2PassthroughGreenProgram->validationWasSuccessful())
throw exception();
Smart<ProgramRef> combineTexturesProgram(Context::createProgram());
combineTexturesProgram->attach(*vec2PassthroughVertexShader);
combineTexturesProgram->attach(*combineTexturesFragmentShader);
combineTexturesProgram->bindAttributeToLocation(
"vertexPosition", vertexPositionAttributeLocation);
combineTexturesProgram->link();
combineTexturesProgram->validate();
if (!combineTexturesProgram->validationWasSuccessful())
throw exception();
UniformLocation screenSizeUniformLocation =
combineTexturesProgram->locationOfUniform("screenSize");
UniformLocation samplersUniformLocation =
combineTexturesProgram->locationOfUniform("samplers");
//
Context::setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Context::setLineWidth(2.0f);
Context::setViewport(IntRect(0, 0, screenWidth, screenHeight));
Context::useProgram(*vec2PassthroughGreenProgram);
Framebuffer::bind(renderFramebuffers.get()[0]);
vertexPositionAttributeLocation.setAttributeArrayPointerAndStride(
DONT_NORMALIZE, 2, AttributeLocation::ArrayDataType::FLOAT, vertices, 0);
Context::clear(CLEAR_COLOR_BUFFER);
Context::drawArrays(DrawMode::LINE_LOOP, 0, vertexCount);
//
Context::enableBlending();
Context::setBlendFuncs(SourceBlendFunc::SRC_ALPHA, DestBlendFunc::ONE_MINUS_SRC_ALPHA);
Context::setColorClearValue(1.0f, 1.0f, 1.0f, 1.0f);
Context::setViewport(IntRect(0, 0, screenWidth, screenHeight));
Context::useProgram(*combineTexturesProgram);
Framebuffer::bind(screenFramebuffer);
vertexPositionAttributeLocation.setAttributeArrayPointerAndStride(
DONT_NORMALIZE, 2, AttributeLocation::ArrayDataType::FLOAT, screenCorners, 0);
screenSizeUniformLocation.setUniformValue(vec2(screenWidth, screenHeight));
samplersUniformLocation.setUniformValue(TextureUnit(0)); // Even though setActiveTextureUnit()
// translated this to GL_TEXTURE0
// It stays plain int 0 here.
Context::clear(CLEAR_COLOR_BUFFER);
Context::drawArrays(DrawMode::TRIANGLE_FAN, 0, screenCornerCount);
}
您可以在此处查看我的包装器库是如何实现的:https://github.com/jbat-es/tsgl2
编辑:
好吧,我用普通 OpenGL 写了一个非常精简的版本,它有同样的问题:
void drawDemoScenePlainGL(int screenWidth, int screenHeight) {
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
int data[320][460];
memset(data, 0xFF, 320*460*sizeof(int));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenWidth, screenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
//
glEnableVertexAttribArray(0);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
const char* source = vec2PassthroughVertexShaderSource.c_str();
int sourceLength = vec2PassthroughVertexShaderSource.length();
glShaderSource(vertexShader, 1, &source, &sourceLength);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
source = combineTexturesFragmentShaderSource.c_str();
sourceLength = combineTexturesFragmentShaderSource.length();
glShaderSource(fragmentShader, 1, &source, &sourceLength);
glCompileShader(fragmentShader);
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glBindAttribLocation(program, 0, "vertexPosition");
glLinkProgram(program);
GLuint screenSizeUniformLocation = glGetUniformLocation(program, "screenSize");
GLuint samplersUniformLocation = glGetUniformLocation(program, "samplers");
//
glClearColor(1, 1, 1, 1);
glUseProgram(program);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, screenCorners);
glViewport(0, 0, screenWidth, screenHeight);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform2f(screenSizeUniformLocation, screenWidth, screenHeight);
glUniform1i(samplersUniformLocation, 0);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_FAN, 0, screenCornerCount);
}
最佳答案
纹理环绕模式默认为 GL_REPEAT,它只支持二次方纹理。简单地添加
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
解决问题。
关于opengl-es - GLSL texture2D() 总是返回 (0, 0, 0, 1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11993701/
我不明白 int 63823 为何比 double 1.0 占用更少的空间。在这个特定实例中,int 中是否没有存储更多信息? 最佳答案 I don't understand how an int 6
这可能不是一个直接的代码问题,但它是一个经常出现在 SO 上的问题,我发现阅读它非常有用。 App Store - Help answering “Missing Compliance” (using
我在我们的应用程序中使用 syncfusion 寻呼机和下拉列表请打开以下链接。 https://stackblitz.com/edit/angular-nv6myv?file=src%2Fapp%2
以便解释指针和引用in this question我写了这段代码。 MyClass& MyClass::MyInstance() { static MyClass & myLoca
在 C 和 C++ 中,assert 是一个非常 重量级例程,将错误写入 stdout 并终止程序。在我们的应用程序中,我们实现了一个更强大的 assert 替代品,并为其提供了自己的宏。已尽一切努力
我已经创建了一个 MVC webApi 项目,现在我想使用身份验证和授权。我想我已经实现了这种安全措施,但由于某种原因,有些事情变糟了,当我编写我的凭据并尝试调用一些 webApi 方法时,显示消息“
我发现自己使用一种奇怪的方式向我的函数添加回调函数,我想知道是否有更通用的方式向函数添加回调函数,最好的情况是我的所有函数都检查最后给定的作为函数的参数,如果是,则将其用作回调。 我以前是这样的: v
几乎从来没有我只想获取某个 Remote 的情况;我总是想要所有的 Remote 。我认为这将是一个足够常见的用例,git 会考虑它(与他们有 pull.rebase true 的方式相同)。 那么,
我正在尝试使用 inarray 但它总是返回 true?有任何想法吗? (所有 li 均已显示) $("#select-by-color-list li").hide(); // get the se
我正在尝试为我公司的开发环境设置过期网址。我们使用 lighttpd在此环境中提供上传的文件,我发现 these docs这似乎相当有希望。 问题是我似乎根本无法让它工作,而且我有点不知所措,试图找出
我无法让“文件夹”外部变量工作。我总是得到[:]。 我正在 Windows 下的 Grails 上进行开发(这就是为什么外部配置文件看起来像 file:C:\path\to/file)。 我在另一个项
这个问题是出于对 PL 如何工作的好奇,而不是其他任何事情。 (它实际上是在查看与 Haskell 不同的 SML 时想到的,因为前者使用按值调用 - 但我的问题是关于 Haskell。) Haske
我有一个高速缓存内存模块,我希望它是可字寻址的,但有字节的写使能信号。 always @ (posedge clk) begin //stuff... if(write) begin
我正在处理一些代码,其中一个对象“foo”正在创建另一个对象对象“bar”,并向其传递一个Callable。之后 foo 将返回bar,然后我希望 foo 变得无法访问(即:可用于垃圾收集)。 我最初
我已将我的程序与此方法相关联: public static void CreateFileAssociation(string extension, string key, string descri
所以我正在进行目录遍历,但我无法让 opendir 按照我想要的方式工作。它总是无法打开我发送的目录,它给出了一些未知的错误。我通常传入 argv[1],但我放弃了,只是开始硬编码路径。 char *
这个问题在这里已经有了答案: How do I compare strings in Java? (23 个回答) 关闭 9 年前。 出于某种原因,我的(基本)程序总是打印我为 else 语句保留的
我不想冒为此提出破解的风险,因为它涉及 datetime 对象。基本上,我想按如下方式进行转换: 2010-04-21 06:37:53 -> 2010-04-21 06:40:00 2010-08-
我正在用 C 语言玩文件 I/O。我正在尝试使用 fgets 从一个文件中读取数据并将其输出到另一个文件。问题是它总是返回 NULL,因此没有任何内容被复制到输出文件中。这是我的代码: #includ
class MyClass { // empty class with no base class }; int main() { MyClass* myClass = new MyC
我是一名优秀的程序员,十分优秀!