Has anyone got a C struct that has members describing the entire OpenGL ES 2.0 state? It would look something like that:
struct OpenGLES20State
{
int activeTexture;
bool scissorEnabled;
Rectangle scissorRectangle;
bool stencilEnabled;
int stencilFunc;
int stencilOpFail;
int stencilOpDFail;
int stencilOpDPass;
//
// and a lot more...
//
}
You can create this structure by carefully working with OpenGL ES 2 specification available from Khronos: http://www.khronos.org/opengles/2_X/
Also, interesting place to look for a similar implementation may be Mesa3D library source code.
Related
When you create a BLAS (bottom level acceleration structures) you specify any number of vertex/index buffers to be part of the structure. How does that end up interacting with the shader and get specified in the descriptor set? How should I link these structures with materials?
How is texture mapping usually done with raytracing? I saw some sort of "materials table" in Q2RTX but the documentation is non-existent and the code is sparsely commented.
A common approach is to use a material buffer in combination with a texture array that is addressed in the shaders where you require the texture data. You then pass the material id e.g. per-vertex or per-primitive and then use that to dynamically fetch the material, and with it the texture index. Due to the requirements for Vulkan ray tracing you can simplify this by using the VK_EXT_descriptor_indexing extension (Spec) that makes it possible to create a large and descriptor set containing all textures required to render your scene.
The relevant shader parts:
// Enable required extension
...
#extension GL_EXT_nonuniform_qualifier : enable
// Material definition
struct Material {
int albedoTextureIndex;
int normalTextureIndex;
...
};
// Bindings
layout(binding = 6, set = 0) readonly buffer Materials { Material materials[]; };
layout(binding = 7, set = 0) uniform sampler2D[] textures;
...
// Usage
void main()
{
Primitive primitive = unpackTriangle(gl_Primitive, ...);
Material material = materials[primitive.materialId];
vec4 color = texture(textures[nonuniformEXT(material.albedoTextureIndex)], uv);
...
}
In your application you then create a buffer that stores the materials generated on the host, and bind it to the binding point of the shader.
For the textures, you pass them as an array of textures. An array texture would be an option too, but isn't as flexible due to the same size per array slice limitation. Note that it does not have a size limitation in the above example, which is made possible by VK_EXT_descriptor_indexing and is only allowed for the final binding in a descriptor set. This adds some flexibility to your setup.
As for the passing the material index that you fetch the data from: The easiest approach is to pass that information along with your vertex data, which you'll have to access/unpack in your shaders anyway:
struct Vertex {
vec4 pos;
vec4 normal;
vec2 uv;
vec4 color;
int32_t materialIndex;
}
c++ : Run time error is happened with error message like this:
RevStrings1->Height of reading included in error: The property is write-protected.
RevStrings1->Height の読み込中のエラー : プロパティは書き込み禁止です.
I'm using c++ builder 3.
This source code can be successfully compiled
setting library, include path and etc.
But run time error is happened.
I guess that this problem is about property read & write.
How can I simplly fix the problem ?
A variable RevStrings1 is created by a class TRevStrings.
//---------------------------------------------------------------------------
#ifndef RevStringsH
#define RevStringsH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
class PACKAGE TRevStrings : public TStringGrid
{
private:
// void __fastcall SetWidth(int W);
// int __fastcall GetWidth(void);
// int FColCount ;
int FRowCount;
int FFixedCols ;
int FFixedRows ;
int FDefaultColWidth ;
int FDefaultRowHeight ;
int FHeight;
// int FWidth;
int FScrollBars;
int FMaxLength;
bool ColColors[24];
protected:
public:
__fastcall TRevStrings(TComponent* Owner);
void __fastcall DrawCellText(TRect ARect,int ALeft,String S);
virtual void __fastcall DrawCell(int ACol, int ARow,const Windows::TRect &ARect, TGridDrawState AState);
void __fastcall SetColor_Col(int Col,int Row);
void __fastcall SetColorFlag(int Col,bool flag);
bool __fastcall GetColorFlag(int Col);
void __fastcall SetEditText(int ACol, int ARow,const System::AnsiString Value);
void __fastcall Clear(bool ALLorONE,int Position);
void __fastcall DblClick(void);
__published:
// __property int ColCount = {read = FColCount};//FColCount};
__property int RowCount = {read=FRowCount};
__property int FixedCols = {read=FFixedCols};
__property int FixedRows = {read=FFixedRows};
__property int DefaultColWidth = {read=FDefaultColWidth};
__property int DefaultRowHeight = {read=FDefaultRowHeight};
__property int Height = {read=FHeight};
// __property int Width = {read=GetWidth,write=SetWidth};
__property int ScrollBars = {read=FScrollBars};
__property int MaxLength = {read=FMaxLength,write=FMaxLength};
/*
*/
};
//---------------------------------------------------------------------------
#endif
never heard of TRevStrings before
so it is either BCB 3 discontinued stuff (my BDS2006 does not have it at disposal) or you have some 3th party custom package installed but the header file suggest it is based on TStringGrid so if below text does not work for it then you can switch to TStringGrid instead.
in TStringGrid
size properties are accessible normaly:
StringGrid1->Height=256;
StringGrid1->Width=128;
if you want to have size-able col/rows then do not forget to open Options property and set goRowSizing,goColSizing to true and starting sizes are DefaultColWidth,DefaultRowHeight. Here example of usage
// resize the grid
StringGrid1->Height=128;
StringGrid1->Width=256;
// access to Cell AnsiStings
StringGrid1->Cells[0][0]="(0,0)";
StringGrid1->Cells[1][1]="(1,1)";
StringGrid1->Cells[1][2]="(1,2)";
StringGrid1->Cells[2][1]="(2,1)";
// resizing row/col
StringGrid1->RowHeights[0]=15;
StringGrid1->RowHeights[1]=20;
StringGrid1->ColWidths[0]=20;
StringGrid1->ColWidths[1]=15;
As your class is derived from this so this should work also for it if not the there are more possibilities:
you have unrelated bug somewhere
overwriting what you should not damaging the C++ engine your App is running on or have memory leak somewhere or your memory manager is invalidated see
bds 2006 C hidden memory manager conflicts
but that is probably not the case or you are calling VCL/Winapi visual stuff from threads.
To check for all this:
create empty application, add your TRevString and try to set its height on runtime. If no error occurs you have a bug somewhere if error occurs then:
this component is not able to resize on runtime this way
try to use functions like SetSize,SetBounds instead or place the component on some panel align to Client and resize panel
if even this does not help switch to standard TStringGrid
you can also try to cast you RevString to StringGrid first
((TStringGrid*)(RevString1))->Height=25;
Borland compilers sometimes get weird
few times (around 10) over the years I use BCB/BDS the compiler sometimes compile wrongly. The app is running but some code gets distorted or discarted so what helps?
close IDE or even restart Windows
delete all map,obj,tds temp files prior to compiling rebuilding
sometimes is needed that you add empty line of code or swap 2 lines of code
Identifiers/Names collisions
if you name your stuff in similar way to VCL functions then you ask for problems usual error is to name function Draw() ... (use draw() instead and you are fine)
for big projects
if you add your source code as new unit to project instead of just include it (it is present in Object Manager) then in big projects you will got big problems. It looks like units are compiled differently then normal included files in units are expected Formulars and other VCL stuff components so if you got your own non visual classes as units they sometimes stop working as expected creating weird behavior (even your error could be caused by it).
I observe this on BCB5 and BDS2006. In BCB3,BCB4 I did not make big enough projects to spot this and BCB6 is so buggy so its unusable with big projects anyway. By big projects I mean > 1 MB of pure C++ code
The error is self-explanatory - the Height property of the RevStrings1 object is not allowing its value to be assigned. This is evident by looking at the declaration of the Height property in the TRevStrings class:
__property int Height = {read=FHeight};
TRevStrings is going out of its way to make the Height property read-only, overriding the native read-write Height property that is inherited from TControl:
__property int Height = {read=FHeight, write=SetHeight, nodefault};
This is odd for TRevString to do, as it is a visual component that needs to be sizable. Unless it requires a specific height that the user cannot change (in which case declaring the Height property as read-only is not the correct way to handle that - the component should override the virtual SetBounds() method instead and just ignore any new Height value being assigned).
That being said, the reason you see the error at run-time is because the IDE is storing the design-time Height value of the RevStrings1 object in the parent Form's DFM resource at compile-time. That is why you are not finding any RevStrings1->Height in your code - it is coming from the Form Designer instead. The TRevStrings class is not overriding DFM behavior for the Height property, so when the VCL's DFM streaming system parses the Form's DFM resource at run-time, it sees the stored Height value and detects that the object's Height property is actually read-only, and so throws an exception to cancel DFM streaming (and thus the Form's construction).
This is a bug in the TRevStrings implementation. At the very least, if the author had wanted to prevent the Height from being streamed (thus preventing the run-time error), the Height property should have been declared like this instead:
__property Height = {read=FHeight, stored=false};
On a side note, most of the TRevStrings data members (FColCount, FRowCount, FFixedCols, FFixedRows, etc) should never have been declared at all, but instead should have been inherited from the base TStringGrid class.
Whoever wrote this component clearly did not know what they were doing.
It is possible to cast a managed array<Byte>^ to some non-managed struct only using pin_ptr, AFAIK, like:
void Example(array<Byte>^ bfr) {
pin_ptr<Byte> ptr = &bfr[0];
auto data = reinterpret_cast<NonManagedStruct*>(ptr);
data->Header = 7;
data->Length = sizeof(data);
data->CRC = CalculateCRC(data);
}
However, is with interior_ptr in any way?
I'd rather work on managed data the low-level-way (using unions, struct-bit-fields, and so on), without pinning data - I could be holding this data for quite a long time and don't want to harass the GC.
Clarification:
I do not want to copy managed-data to native and back (so the Marshaling way is not an option here...)
You likely won't harass the GC with pin_ptr - it's pretty lightweight unlike GCHandle.
GCHandle::Alloc(someObject, GCHandleType::Pinned) will actually register the object as being pinned in the GC. This lets you pin an object for extended periods of time and across function calls, but the GC has to track that object.
On the other hand, pin_ptr gets translated to a pinned local in IL code. The GC isn't notified about it, but it will get to see that the object is pinned only during a collection. That is, it will notice it's pinned status when looking for object references on the stack.
If you really want to, you can access stack memory in the following way:
[StructLayout(LayoutKind::Explicit, Size = 256)]
public value struct ManagedStruct
{
};
struct NativeStruct
{
char data[256];
};
static void DoSomething()
{
ManagedStruct managed;
auto nativePtr = reinterpret_cast<NativeStruct*>(&managed);
nativePtr->data[42] = 42;
}
There's no pinning at all here, but this is only due to the fact that the managed struct is stored on the stack, and therefore is not relocatable in the first place.
It's a convoluted example, because you could just write:
static void DoSomething()
{
NativeStruct native;
native.data[42] = 42;
}
...and the compiler would perform a similar trick under the covers for you.
I'm looking at the algorithm for breadth-first sorting of a binary search tree, and there is a symbol used that I cannot understand. Funny enough, Google returns zero results.
// levelorder()
// q = empty queue
// q.enqueue(root)
// while not q.empty do
// node := q.dequeue() //Referring to this
// visit(node)
// if node.left != null then
// q.enqueue(node.left)
// if node.right != null then
// q.enqueue(node.right)
What is the operation being used here? I'm quite confused by this line.
The code you posted is pseudo code, and is not intended to be valid C++.
In C++, the assignment operator is =.
In other languages such as Ada, BCPL, Cecil, Dylan, E, Eiffel, Maple, Mathematica, Modula-3, Pascal, Pliant, Sather, Simula, Smalltalk, SML, the assignment operator is :=.
GNU make also uses := for a way of assigning.
Since the code you posted is a comment, it is not intended to be valid C++.
Here is a closer representation of the code you posted in valid C++:
#include <iostream>
#include <string>
#include <queue>
//A node might look like this:
struct Node{
Node* left;
Node* right;
};
//somewhere you have a node and a root
Node* node = new Node;
Node* root = new Node;
//a visit function is called in the pseudo code you posted
void visit(Node* node){
// ... code ...
return;
}
//here is what valid C++ that is similar to the pseudo code:
void levelorder(){
//empty queue
std::queue<Node*> q;
//add the root to the queue
q.push(root);
do {
visit(node);
if (node->left != nullptr){
q.push(node->left);
}
if (node->left != nullptr){
q.push(node->right);
}
}while(!q.empty());
return;
}
//I just added this main function so the whole code snippet compiles successfully
int main(){}
:= is assignment in pseudocode.
Or ADA. But that's kinda like psuedocode anyway.
It's inside a comment (per // prefix)... it's not compilable code and doesn't mean anything in C++.
It's not a C++ operator. It is used in some languages such as Pascal to mean the same thing as what an assignment = does.
See: Assignment operator (Computer science)
This tutorial uses explicit OUT structures, e.g:
struct C3E1v_Output {
float4 position : POSITION;
float4 color : COLOR;
};
C3E1v_Output C3E1v_anyColor(float2 position : POSITION,
uniform float4 constantColor)
{
C3E1v_Output OUT;
OUT.position = float4(position, 0, 1);
OUT.color = constantColor; // Some RGBA color
return OUT;
}
But looking at one of my shaders I have explicit in/out parameters:
float4 slice_vp(
// Vertex Inputs
in float4 position : POSITION, // Vertex position in model space
out float4 oposition : POSITION,
// Model Level Inputs
uniform float4x4 worldViewProj) : TEXCOORD6
{
// Calculate output position
float4 p = mul(worldViewProj, position);
oposition=p;
return p;
}
I'm having some problems using HLSL2GLSL with this and wondered if my Cg format is to blame (even though it works fine as a Cg script). Is there a 'right' way or are the two simply different ways to the same end?
As you've seen, both ways work. However, I strongly endorse using structs -- especially for the output of vertex shaders (input of fragment shaders). The reasons are less to do with what the machine likes (it doesn't care), and more to do with creating code that can be safely re-used and shared between projects and people. The last thing you want to have to find and debug is a case where one programmer has assigned a value to TEXCOORD1 in some cases and is trying to read it from TEXCOORD2 in (some) other cases. Or any permutation of register mis-match. Use structs, your life will be better.