Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
opengl中四边形的非对称着色_Opengl - Fatal编程技术网

opengl中四边形的非对称着色

opengl中四边形的非对称着色,opengl,Opengl,我需要给由多个四边形组成的曲面的一些点上色。问题是颜色在点周围分布不对称,请参见图像,其中只有左方形的右下角是红色,而红色似乎被拉向右方形的右上角) 代码: 如果创建两个单独的四边形,并定义一个顺时针方向,另一个逆时针方向,则颜色将围绕点对称,但与相邻点周围的颜色分布不同(如果它们改为着色) 那么,如何使用对称的颜色分布为任意点着色呢 编辑: 例如,我想根据每个顶点的温度来可视化表面温度,如下图所示(黄色=0,橙色=0.5,红色=1): 默认情况下,OpenGL在每个三角形上使用重心线性插值。

我需要给由多个四边形组成的曲面的一些点上色。问题是颜色在点周围分布不对称,请参见图像,其中只有左方形的右下角是红色,而红色似乎被拉向右方形的右上角)

代码:

如果创建两个单独的四边形,并定义一个顺时针方向,另一个逆时针方向,则颜色将围绕点对称,但与相邻点周围的颜色分布不同(如果它们改为着色)

那么,如何使用对称的颜色分布为任意点着色呢

编辑:

例如,我想根据每个顶点的温度来可视化表面温度,如下图所示(黄色=0,橙色=0.5,红色=1):


默认情况下,OpenGL在每个三角形上使用重心线性插值。这正是你所看到的。最简单的解决方案是编写一组顶点和片段着色器,实现基于距离的渐变


细节取决于您的具体需求。

在datenwolf的大量帮助下,我最终选择了以下方法:

  • 制作节点标量的8位2D纹理(例如温度)
  • 在片段着色器中查找1D colormap纹理中的灰度级别
以及守则:

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import sys
from PIL import Image
import numpy as np
from OpenGL.GL import shaders

def LoadTexture():
    global ID
    arr = np.array([[0, 255, 0], [0, 0, 0]], dtype=np.int8)
    im = Image.fromarray(arr, "L")
    ix, iy, image = im.size[0], im.size[1], im.tobytes()
    ID = glGenTextures(1)

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, ID);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ix, iy, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)

    glEnable(GL_TEXTURE_2D)

def loadColorMap(imageName="jet.bmp"):
    im = Image.open(imageName)
    ix, _, image = im.size[0], im.size[1], im.tostring("raw", "RGBX", 0, -1)
    ID = glGenTextures(1)
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_1D, ID);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    glTexImage1D(GL_TEXTURE_1D, 0, 3, ix, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
    glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)  # avoids 1 => 0
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
    glEnable(GL_TEXTURE_1D)
    return ID



glutInit(sys.argv)
glutCreateWindow("")


VERTEX_SHADER = shaders.compileShader("""
void main() {
        gl_TexCoord[0] = gl_MultiTexCoord0;
        gl_Position = ftransform();
}""", GL_VERTEX_SHADER)

FRAGMENT_SHADER = shaders.compileShader("""

uniform sampler2D texture;
uniform sampler1D colormap;
void main() {
    float level = texture2D(texture, vec2(gl_TexCoord[0].s, gl_TexCoord[0].t)).r;
    gl_FragColor = texture1D(colormap, level);
}""", GL_FRAGMENT_SHADER)

LoadTexture()
loadColorMap()

shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)


shaders.glUseProgram(shader)
texloc = glGetUniformLocation(shader, 'texture');
glUniform1i(texloc, 0);
texloc = glGetUniformLocation(shader, "colormap");
glUniform1i(texloc, 1);

glMatrixMode(GL_PROJECTION)
gluPerspective(45.0, 1, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()  # Reset The View
glTranslatef(0.0, 0.0, -3.0)  # Move Into The Screen

glBegin(GL_QUAD_STRIP)
glTexCoord2f(1. / 6, .25); glVertex3f(-1, 0, 0)
glTexCoord2f(1. / 6, .75); glVertex3f(-1, 1, 0)
glTexCoord2f(.5, .25);glVertex3f(0, 0, 0)
glTexCoord2f(.5, .75);glVertex3f(0, 1, 0)
glTexCoord2f(5. / 6, .25);glVertex3f(1, 0, 0)
glTexCoord2f(5. / 6, .75); glVertex3f(1, 1, 0)
glEnd()

glutSwapBuffers()

glutMainLoop()
生成此图像的:


我希望颜色是周围四个顶点的线性插值-这是可能的。我已经检查了几个例子和教程,但没有一个能够访问周围环境的位置或颜色vertices@MadsMPedersen:根据定义,线性插值仅适用于两个顶点之间。OpenGL的重心插值实际上非常接近于简单的线性插值。我建议你使用像Photoshop这样的工具,手工画出你想看到的东西。把它贴在这里,我会给你推荐一种如何在OpenGL中实现它的方法。@Madspedersen:好吧,对于这样的应用程序,我甚至不想费心巧妙地处理顶点和邻接列表。您的案例要求在GL_最近插值模式下使用纹理,该模式更易于实现,并且还受益于GPU的硬连线双线性插值器。@Madspedersen:我认为您的第二个四边形的纹理坐标是错误的,因此存在不对称性(请发布您的绘图代码,包括纹理坐标)。此外,您还应该研究“透视校正”,以便即使在不垂直的情况下,也能看到正确的效果。@madspedersen:从技术上讲,纹理是一组采样的插值支撑点。假设您要显示5×3的网格,那么您要做的是创建一个5×3的纹理,并为每个“像素”提供采样值。然后,通过将整个纹理映射到一个较大的四边形上,OpenGL光栅化器将为您完成所有双线性插值。
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import sys
from PIL import Image
import numpy as np
from OpenGL.GL import shaders

def LoadTexture():
    global ID
    arr = np.array([[0, 255, 0], [0, 0, 0]], dtype=np.int8)
    im = Image.fromarray(arr, "L")
    ix, iy, image = im.size[0], im.size[1], im.tobytes()
    ID = glGenTextures(1)

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, ID);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ix, iy, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)

    glEnable(GL_TEXTURE_2D)

def loadColorMap(imageName="jet.bmp"):
    im = Image.open(imageName)
    ix, _, image = im.size[0], im.size[1], im.tostring("raw", "RGBX", 0, -1)
    ID = glGenTextures(1)
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_1D, ID);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    glTexImage1D(GL_TEXTURE_1D, 0, 3, ix, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
    glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)  # avoids 1 => 0
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
    glEnable(GL_TEXTURE_1D)
    return ID



glutInit(sys.argv)
glutCreateWindow("")


VERTEX_SHADER = shaders.compileShader("""
void main() {
        gl_TexCoord[0] = gl_MultiTexCoord0;
        gl_Position = ftransform();
}""", GL_VERTEX_SHADER)

FRAGMENT_SHADER = shaders.compileShader("""

uniform sampler2D texture;
uniform sampler1D colormap;
void main() {
    float level = texture2D(texture, vec2(gl_TexCoord[0].s, gl_TexCoord[0].t)).r;
    gl_FragColor = texture1D(colormap, level);
}""", GL_FRAGMENT_SHADER)

LoadTexture()
loadColorMap()

shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)


shaders.glUseProgram(shader)
texloc = glGetUniformLocation(shader, 'texture');
glUniform1i(texloc, 0);
texloc = glGetUniformLocation(shader, "colormap");
glUniform1i(texloc, 1);

glMatrixMode(GL_PROJECTION)
gluPerspective(45.0, 1, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()  # Reset The View
glTranslatef(0.0, 0.0, -3.0)  # Move Into The Screen

glBegin(GL_QUAD_STRIP)
glTexCoord2f(1. / 6, .25); glVertex3f(-1, 0, 0)
glTexCoord2f(1. / 6, .75); glVertex3f(-1, 1, 0)
glTexCoord2f(.5, .25);glVertex3f(0, 0, 0)
glTexCoord2f(.5, .75);glVertex3f(0, 1, 0)
glTexCoord2f(5. / 6, .25);glVertex3f(1, 0, 0)
glTexCoord2f(5. / 6, .75); glVertex3f(1, 1, 0)
glEnd()

glutSwapBuffers()

glutMainLoop()